【问题标题】:Symfony2 Listener vs DataFixturesSymfony2 监听器与 DataFixtures
【发布时间】:2012-05-25 23:56:04
【问题描述】:

我已将以下侦听器注册为服务。这将保存登录用户。它完美地工作。保存实体后,用户 ID 位于 createdBy 和 updatedBy 中。好的一个小问题:命令“php app/console原则:fixtures:load”抛出错误“调用非对象上的成员函数getUser()。 这是可以理解的。只有现在我必须在之前的每次服务中禁用?您还有其他解决方案吗?

类 UserListener 实现 EventSubscriber { 受保护的$容器; 公共函数 __construct(ContainerInterface $container) { $this->container = $container; } 公共函数 getSubscribedEvents() { 返回数组( 事件::prePersist, 事件::更新前 ); } 公共函数 prePersist(LifecycleEventArgs $args) { $entity = $args->getEntity(); if ($entity instanceof Post) { $user = $this->container->get('security.context')->getToken()->getUser(); if (!is_object($user) || !$user instanceof User) { 抛出新的 AccessDeniedException(); } $entity->setCreatedBy($user); $entity->setUpdatedBy($user); } } /** * @param PreUpdateEventArgs $args */ 公共函数 preUpdate(PreUpdateEventArgs $args) { $entity = $args->getEntity(); $em = $args->getEntityManager(); if ($entity instanceof Post) { $user = $this->container->get('security.context')->getToken()->getUser(); if (!is_object($user) || !$user instanceof User) { 抛出新的 AccessDeniedException(); } $entity->setUpdatedBy($user); $uow = $em->getUnitOfWork(); $meta = $em->getClassMetadata(get_class($entity)); $uow->recomputeSingleEntityChangeSet($meta, $entity); } } }

【问题讨论】:

    标签: symfony listener fixtures


    【解决方案1】:

    当你调用命令 load-fixtures 时,你并没有登录。也许$this->container->get('security.context')->getToken() 返回 null ?

    【讨论】:

    • 顺便说一句,请改用$this->container->get('security.authorization_checker')(2.6 中的新功能)
    【解决方案2】:

    我有一个类似的侦听器,并试图保存一个(模拟)实体(在您的情况下为“Post”)。当然,从控制台启动命令时我没有登录。

    我给监听器加了一个条件:

    if ($entity instanceof Post) {
        if (null !== $entity->getUser() {
            return;
        }
    }
    

    现在我可以在我的装置内的 Post 实体上设置一个(模拟)用户:

    $user = $em->getReference('Application\Sonata\UserBundle\Entity\User', 1);
    $post = new Post();
    $post->setUser($user);
    

    仍然不确定在实体侦听器中设置用户是否是好的做法。

    我想目前大多数人会建议使用 ValueObject 来“发布”,或者至少是一个需要设置的构造函数,例如一个“名称”和一个“用户”。

    【讨论】:

      【解决方案3】:

      我的最终代码(Symfony 2.6):

      1) 监听器:

      <?php
      
      namespace AppBundle\Listener;
      
      use AppBundle\Entity\Post;
      use AppBundle\Entity\Comment;
      
      use Doctrine\ORM\Event\LifecycleEventArgs;
      use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
      
      /**
       * Class BlameableListener
       *
       * @package AppBundle\Listener
       */
      class BlameableListener
      {
          private $tokenStorage;
      
          public function __construct(TokenStorageInterface $tokenStorage)
          {
              $this->tokenStorage = $tokenStorage;
          }
      
          public function prePersist(LifeCycleEventArgs $args)
          {
              $entity = $args->getEntity();
      
              if ($entity instanceof Post || $entity instanceof Comment) {
                  // is authentication information available?
                  if (null !== $this->tokenStorage->getToken()) {
                      // get User
                      $user = $this->tokenStorage->getToken()->getUser();
                      if (is_object($user)) {
                          $entity->setAuthorEmail($user->getEmail());
                      }
                  }
              }
          }
      }
      

      2) 配置为服务

      services:
          app.blameable.listener:
              class: AppBundle\Listener\BlameableListener
              arguments:
                  - "@security.token_storage"
              tags:
                  - { name: doctrine.event_listener, event: prePersist }
      

      【讨论】:

        猜你喜欢
        • 2012-12-13
        • 1970-01-01
        • 2012-10-25
        • 1970-01-01
        • 1970-01-01
        • 2016-11-30
        • 2021-07-24
        • 2016-02-11
        • 2013-07-01
        相关资源
        最近更新 更多