草庐IT

php - 循环引用 Doctrine - Twig

coder 2024-01-03 原文

我在应用程序中做用户注册,我想在注册时收到邮件通知。我为此服务创建了:

app.mail_service:
    class: AppBundle\Mail\MailService
    arguments: ["@mailer", "@templating"]

app.listener.user:
    class: AppBundle\EventListener\UserSubscriber
    arguments: ["@app.mail_service"]
    tags:
        - { name: doctrine.event_subscriber, connection: default }

模板 - TwigEngine

邮件服务类:

class MailService
{
private $mailer;

private $renderer;

public function __construct(Swift_Mailer $mailer, EngineInterface $renderer)
{
    $this->mailer = $mailer;
    $this->renderer = $renderer;
}

/**
 * @return Swift_Mailer
 */
public function getMailer()
{
    return $this->mailer;
}

/**
 * @return EngineInterface
 */
public function getRenderer()
{
    return $this->renderer;
}

public function sendRegistrationMail(User $user)
{
    /** @var \Swift_Message $message */
    $message = $this->getMailer()
        ->createMessage();

    $message->setSubject('You successful register in website')
        ->addTo($user->getEmail())
        ->setBody($this->getRenderer()->render('AppBundle:Mail:register.html.twig', array(
            'user' => $user
        )), 'text/html', 'UTF-8');

    return $this->getMailer()->send($message);
}
}

和用户订阅监听器:

class UserSubscriber implements EventSubscriber
{
/**
 * @var MailService
 */
private $mailService;

public function __construct(MailService $mailService)
{
    $this->mailService = $mailService;
}

public function postPersist(LifecycleEventArgs $args)
{
    $entity = $args->getEntity();
    if ($entity instanceof User) {
        $this->mailService->sendRegistrationMail($entity);
    }
}

/**
 * Returns an array of events this subscriber wants to listen to.
 *
 * @return array
 */
public function getSubscribedEvents()
{
    return array(
        'postPersist',
    );
}
}

当我尝试添加新用户时,出现异常:

Circular reference detected for service "security.authorization_checker", path: "sensio_framework_extra.security.listener -> security.authorization_checker -> security.authentication.manager -> security.user.provider.concrete.entity_provider -> doctrine.orm.default_entity_manager -> doctrine.dbal.default_connection -> app.listener.user -> app.mail_service -> templating -> twig -> security.context".

据我了解,错误的发生是由于 Twig 尝试使用 EntityManager 进行安全检查。

this文章中,作者使用了一个简单的scheme,不过在Twig中也使用了Doctrine EventListener。那不是抛出异常。

最佳答案

我想说避免循环引用的最简洁的方法是将事件调度程序注入(inject)您的学说监听器。然后在 doctrine listener 中发送一个用户注册的事件,然后会有一个 Symfony 内核监听器可以发送电子邮件。

学说订阅者

class UserSubscriber implements EventSubscriber
{
    /**
     * @var EventDispatcherInterface
     */
    private $dispatcher;

    public function __construct(EventDispatcherInterface $dispatcher)
    {
        $this->dispatcher = $dispatcher;
    }

    public function postPersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();

        if ($entity instanceof User) {
            $dispatcher->dispatch('acme.user.registered', new UserEvent($user));
        }
    }

    /**
     * Returns an array of events this subscriber wants to listen to.
     *
     * @return array
     */
    public function getSubscribedEvents()
    {
        return array(
            'postPersist',
        );
    }
}

用户事件

class UserEvent extends GenericEvent
{
    public function __construct(User $user, array $arguments = array())
    {
        parent::__construct($user, $arguments);
    }

    /**
     * @return User
     */
    public function getUser()
    {
        return $this->getSubject();
    }
}

Symfony 订阅者

class UserRegistrationMailSubscriber implements EventSubscriberInterface
{
    /**
     * @var MailService
     */
    private $mailService;

    public function __construct(MailService $mailService)
    {
        $this->mailService = $mailService;
    }

    /**
     * {@inheritdoc}
     */
    public static function getSubscribedEvents()
    {
        return array(
            'acme.user.registered'  => 'sendRegistrationMail',
        );
    }

    /**
     * @param UserEvent $event
     */
    public function sendRegistrationMail(UserEvent $event)
    {
        $this->mailService->sendRegistrationMail($event->getUser());
    }
}

服务

app.mail_service:
    class: AppBundle\Mail\MailService
    arguments: ["@mailer", "@templating"]

app.doctrine.listener.user:
    class: AppBundle\EventListener\UserSubscriber
    arguments: ["@event_dispatcher"]
    tags:
        - { name: doctrine.event_subscriber, connection: default }

app.kernel.listener.user_registartion_mail:
   class: AppBundle\EventListener\UserRegistrationMailSubscriber
   arguments: ["@app.mail_service"}
   tags:
        - { name: kernel.event_subscriber }

关于php - 循环引用 Doctrine - Twig,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30138193/

有关php - 循环引用 Doctrine - Twig的更多相关文章

  1. ruby - 树顶语法无限循环 - 2

    我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He

  2. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  3. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  4. ruby - 一个 YAML 对象可以引用另一个吗? - 2

    我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的ruby​​yaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir

  5. ruby - Ruby 中的闭包和 for 循环 - 2

    我是Ruby的新手,有些闭包逻辑让我感到困惑。考虑这段代码:array=[]foriin(1..5)array[5,5,5,5,5]这对我来说很有意义,因为i被绑定(bind)在循环之外,所以每次循环都会捕获相同的变量。使用每个block可以解决这个问题对我来说也很有意义:array=[](1..5).each{|i|array[1,2,3,4,5]...因为现在每次通过时都单独声明i。但现在我迷路了:为什么我不能通过引入一个中间变量来修复它?array=[]foriin1..5j=iarray[5,5,5,5,5]因为j每次循环都是新的,我认为每次循环都会捕获不同的变量。例如,这绝对

  6. ruby - Chef LW 资源属性默认值如何引用另一个属性? - 2

    我正在尝试将一个资源属性的默认值设置为另一个属性的值。我正在为我正在构建的tomcat说明书定义一个资源,其中包含以下定义。我想要可以独立设置的“名称”和“服务名称”属性。当未设置服务名称时,我希望它默认为为“名称”提供的任何内容。以下不符合我的预期:attribute:name,:kind_of=>String,:required=>true,:name_attribute=>trueattribute:service_name,:kind_of=>String,:default=>:name注意第二行末尾的“:default=>:name”。当我在Recipe的新block中引用我

  7. ruby - 在 Ruby 中,为什么 Array.new(size, object) 创建一个由对同一对象的多个引用组成的数组? - 2

    如thisanswer中所述,Array.new(size,object)创建一个数组,其中size引用相同的object。hash=Hash.newa=Array.new(2,hash)a[0]['cat']='feline'a#=>[{"cat"=>"feline"},{"cat"=>"feline"}]a[1]['cat']='Felix'a#=>[{"cat"=>"Felix"},{"cat"=>"Felix"}]为什么Ruby会这样做,而不是对object进行dup或clone? 最佳答案 因为那是thedocumenta

  8. ruby - 引用具有指定索引的枚举器值 - 2

    假设我有一个可枚举对象enum,现在我想获取第三个项目。我知道一种通用方法是转换成数组,然后使用索引访问,如:enum.to_a[2]但这种方式会创建一个临时数组,效率可能很低。现在我使用:enum.each_with_index{|v,i|breakvifi==2}但这非常丑陋和多余。执行此操作最有效的方法是什么? 最佳答案 你可以使用take剥离前三个元素,然后剥离last从take给你的数组中获取第三个元素:third=enum.take(3).last如果您根本不想生成任何数组,那么也许:#Ifenumisn'tanEnum

  9. Ruby:数组中的下一个/上一个值,循环数组,数组位置 - 2

    假设我有一个没有特定顺序的随机数数组。假设这些是参加马拉松比赛的人的ID#,他们按照完成的顺序添加到数组中,例如:race1=[8,102,67,58,91,16,27]race2=[51,31,7,15,99,58,22]这是一个简化且有些做作的示例,但我认为它传达了基本思想。现在有几个问题:首先,我如何获得特定条目之前和之后的ID?假设我正在查看运行者58,我想知道谁在他之前和之后完成了比赛。race1,runner58:previousfinisher=67,nextfinisher=91race2,runner58:previousfinisher=99,nextfinishe

  10. ruby - 奇怪的 ruby​​ for 循环行为(为什么这样做有效) - 2

    defreverse(ary)result=[]forresult[0,0]inaryendresultendassert_equal["baz","bar","foo"],reverse(["foo","bar","baz"])这行得通,我想了解原因。有什么解释吗? 最佳答案 如果我使用each而不是for/in重写它,它看起来像这样:defreverse(ary)result=[]#forresult[0,0]inaryary.eachdo|item|result[0,0]=itemendresultendforainb基本上就

随机推荐