Symfony覆盖第三方实体存储库

时间:2017-11-15 17:14:17

标签: symfony doctrine repository override

我正在使用带有自定义doctrine实体存储库的第三方包。它包括一个我想覆盖的功能,以根据我的需要定制它。 有没有人这样做过?我找不到有关覆盖实体存储库的任何文档。 为什么我需要这样做:来自该第三方捆绑的服务调用此存储库功能并执行它。但是我想改变它的一部分。

我尝试了什么: 创建一个自己的Entity存储库类:

namespace NotificationBundle\Entity;

use Doctrine\ORM\EntityRepository;
use Citrax\Bundle\DatabaseSwiftMailerBundle\Entity\Email;
use Citrax\Bundle\DatabaseSwiftMailerBundle\Entity\EmailRepository as BaseRepository;

class EmailRepository extends BaseRepository
{

    public function markCompleteSending(Email $email)
    {
        $email->setStatus(Email::STATUS_COMPLETE);
        $email->setSentAt(new \DateTime());
        $email->setErrorMessage('');
        $em = $this->getEntityManager();
        $em->remove($email);
        $em->flush();
    }
}

它扩展了父存储库并仅覆盖了这个函数,其余的我没有触及。然后我将该存储库注册为服务。 无论如何它不起作用! 还有什么需要吗?请告诉我!我会很高兴得到一些帮助。

在哪里调用functino:

public function flushQueue(Swift_Transport $transport, &$failedRecipients = null)
{
    if (!$transport->isStarted())
    {
        $transport->start();
    }

    $count = 0;
    $emails = $this->repository->getEmailQueue($this->getMessageLimit());

    foreach($emails as $email){
        /*@var $message \Swift_Mime_Message */
        $message = $email->getMessage();
        try{
            $count_= $transport->send($message, $failedRecipients);
            if($count_ > 0){
                $this->repository->markCompleteSending($email);
                $count += $count_;
            }else{
                throw new \Swift_SwiftException('The email was not sent.');
            }
        }catch(\Swift_SwiftException $ex){
            $this->repository->markFailedSending($email, $ex);
        }
    }

    return $count;
}

这是 DatabaseSpool 类,它被注册为我的swiftmailer的假脱机服务。

1 个答案:

答案 0 :(得分:0)

要覆盖DatabaseSwiftMailerBundle的回购,我可以看到(on git)供应商已将Citrax\Bundle\DatabaseSwiftMailerBundle\Entity\EmailRepository定义为名为repository.email的服务,您可以使用symfony' s覆盖服务CompilerPassInterface。在DependencyInjection文件夹下的捆绑包中,通过定义应扩展供应商回购的仓库来创建编译器密码并覆盖repository.email服务。

namespace Your\Bundle\DependencyInjection\Compiler;

use NotificationBundle\Entity\EmailRepository;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class OverrideServiceCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        $definition = $container->getDefinition('repository.email');
        $definition->setClass(EmailRepository::class);
    }
}
  

根据官方文件

     

如果要修改另一个包的服务定义,可以使用编译器传递来更改服务的类或修改方法调用。在以下示例中,original-service-id的实现类更改为Acme \ DemoBundle \ YourService。

有关详细信息,请查看Services & Configuration