【问题标题】:call Symfony events only in certain cases仅在某些情况下调用 Symfony 事件
【发布时间】:2017-05-05 21:55:21
【问题描述】:

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

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

我对 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 事件?

【问题讨论】:

  • 检查工作单元,查看变更集是什么,确定是否运行代码..
  • 那么在这种情况下,我不会使用任何监听器?
  • 是的,你会的,但是在这个监听器中,你可以检查你的用户实体中到底发生了什么变化,并且只运行设置器,并坚持和刷新,如果任何相关的东西发生了变化..或者我我误解了这个问题?
  • 重要的不是我的实体发生了什么变化,而是在什么情况下持续发生(与用户实体无关)我只想在特定条件下更改此用户名/密码。但我不知道如何在这样的监听器中传递参数:为了简单起见:只有在$isRegularUser == true 的情况下才能运行这个 postPersist。你有我可以看的链接或例子吗?谢谢
  • 您可能不想将教义事件用于此类业务逻辑。似乎您可以在控制器中实现此权利,但如果没有,请使用 Symfony 事件系统。

标签: php symfony doctrine-orm


【解决方案1】:

我的建议是不要在侦听器中对这种情况使用这种类型的逻辑,这是一种特殊情况,当尝试在其他地方创建用户时可能会混淆。

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

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进行更新。此逻辑在事务中执行,以避免在第二次刷新失败时使用随机名称的用户。

【讨论】:

    猜你喜欢
    • 2015-05-02
    • 1970-01-01
    • 1970-01-01
    • 2014-01-17
    • 2020-06-20
    • 2022-11-25
    • 1970-01-01
    • 2013-12-05
    • 1970-01-01
    相关资源
    最近更新 更多