仅在某些情况下调用Symfony事件

时间:2017-05-05 09:38:44

标签: php symfony doctrine-orm

在我的项目中,我管理用户,并且用户名和密码都是强制性的(因为我使用FOSUserBundle),我可以通过两种方式处理它们:

  • 如果用户有权访问管理区域,则应通过用户注册设置用户名和密码(例如:myusername / mYpAsSwOrD)
  • 如果用户不能访问管理区域,则默认定义此用户名和密码(例如user123,pass123,其中123是userID)

对于symfony中的eventListener / dispatcher的子集,我并不完全放心。

为了有这样的行为,我创建了一个监听器:

use Doctrine\ORM\Event\LifecycleEventArgs;

use MyBundle\Entity\User;

class UserListener
{
    public function postPersist(LifecycleEventArgs $args)
    {
        $entity     = $args->getEntity();
        $em         = $args->getEntityManager();

        if ($entity instanceof User) {
            $entity->setUsername('user'.$entity->getId());
            $entity->setPassword('user'.$entity->getId());
            $entity->setEmail('user'.$entity->getId());

            $em->persist($entity);
            $em->flush();
        }
    }
}

提供服务:

mybundle.user_listener:
    class: MyBundle\EventListener\UserListener
    tags:
        - { name: doctrine.event_listener, event: postPersist }

但是这种做法并不成功:因为这是一项服务,所以每当我添加更新用户时它都适用。

我的问题是: 我怎样才能在需要时应用此侦听器:?

  • 仅在插入时(不在更新时)
  • 只有在控制器中“我要求它”

=> 也许我错了,但我无法将参数从控制器传递到postPersist事件?

1 个答案:

答案 0 :(得分:0)

我的建议是不要在侦听器中使用这种类型的逻辑,这是一个特殊情况,后者在尝试在其他地方创建用户时可能会感到困惑。

可以在您的控制器或存储库中实现此逻辑,例如:

class UserRepository extends EntityRepository
{
    public function saveUser(User $user, $autoGenerated = false)
    {
        $this->_em->beginTransaction();

        if ($autoGenerated) {
            $user->setUsername('user'.time());
            $user->setPlainPassword('user'.time());
            $user->setEmail('user'.time().'@example.com');
        }
        $this->_em->persist($user);
        $this->_em->flush($user);

        $this->_em->refresh($user);

        if ($autoGenerated) {
            $user->setUsername('user'.$user->getId());
            $user->setPlainPassword('user'.$user->getId());
            $user->setEmail('user'.$user->getId().'@example.com');
        }

        $this->_em->flush($user);

        $this->_em->commit();

        return $user;
    }
}

首先,用随机名称保存用户,并使用其他刷新中的真实ID进行更新。如果第二次刷新失败,则在事务中执行此逻辑以避免使用随机名称的用户。