我已将以下侦听器注册为服务。这样可以保存登录用户。它完美地运作。保存实体后,user-id在createdBy和updatedBy中。好一点问题:命令" php app / console doctrine:fixtures:load"抛出错误"在非对象上调用成员函数getUser()。 这是可以理解的。只有现在我必须在每次服务之前禁用?你有其他解决方案吗?
class UserListener implements EventSubscriber { protected $container; public function __construct(ContainerInterface $container) { $this->container = $container; } public function getSubscribedEvents() { return array( Events::prePersist, Events::preUpdate ); } public function 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) { throw new AccessDeniedException(); } $entity->setCreatedBy($user); $entity->setUpdatedBy($user); } } /** * @param PreUpdateEventArgs $args */ public function 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) { throw new AccessDeniedException(); } $entity->setUpdatedBy($user); $uow = $em->getUnitOfWork(); $meta = $em->getClassMetadata(get_class($entity)); $uow->recomputeSingleEntityChangeSet($meta, $entity); } } }
答案 0 :(得分:1)
当你调用命令load-fixtures时,你没有登录。也许$this->container->get('security.context')->getToken()
返回null?
答案 1 :(得分:0)
我有一个类似的听众,并试图保存一个(模拟)实体(" 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 for" Post"或者至少是需要设置的构造函数,例如a"名称"和"用户"。
答案 2 :(得分:0)
我的最终代码(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 }