首页 > 解决方案 > Symfony 5 - 在 Trait 中返回当前用户数据不起作用

问题描述

我创建了一个特征来在每个实体中添加两个属性/列“user_created”和“user_updated”(与 Web 上的“Timestamptable”特征具有相同的理念)

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface\UserInterface;

trait UserTrack
{
    /**
        * @ORM\ManyToOne(targetEntity=User::class)
    */      
    private $createdUser;
    
    /**
        * @ORM\ManyToOne(targetEntity=User::class)
    */  
    private $updatedUser;
    
    private $security;
    private $me;
    

    public function __construct(Security $security, UserInterface $user)
    {
        $this->security = $security;
        // $this->me = $this->getUser()->getId();  //ERROR
        // $this->me = $this->security->getUser()->getId();  //ERROR
        // $this->me = $user->getId(); //ERROR
    }       
    
    
    
    /**
        * @ORM\PrePersist
    */
    public function setCreatedUserAutomatically()
    {
        if ($this->getCreatedUser() === null) {
            $this->setCreatedUser($this->me);
        }
    }
    
    /**
        * @ORM\PreUpdate
    */
    public function setUpdatedUserAutomatically()
    {
        $this->setUpdatedUser($this->me);
    }
}       

如您所见,我添加了一个“构造”方法,试图获取我的用户对象,但它不起作用..

你可以帮帮我吗 ?

谢谢 !

标签: phpsymfony

解决方案


感谢 Jakumi 和 Julien B,下面的代码完成了这项工作:

EventListener\EntityListener.php

<?php
namespace App\EventListener;

use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

class EntityListener
{
    private $tokenStorage;
    
    public function __construct(TokenStorageInterface $tokenStorage = null) 
    {
        $this->tokenStorage = $tokenStorage;
    }
    
    public function prePersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();
        if (null !== $currentUser = $this->getUser()) {
            $entity->setCreatedUser($currentUser);
        }
    }       
    
    public function preUpdate(LifecycleEventArgs $args)
    {       
        $entity = $args->getEntity();
        if (null !== $currentUser = $this->getUser()) {
            $entity->setUpdatedUser($currentUser);
        }
    }
    
    public function getUser()
    {
        if (!$this->tokenStorage) {
            throw new \LogicException('The SecurityBundle is not registered in your application.');
        }
        
        if (null === $token = $this->tokenStorage->getToken()) {
            return;
        }
        
        if (!is_object($user = $token->getUser())) {
            // e.g. anonymous authentication
            return;
        }
        
        return $user;
    }
}   

配置/服务.yaml

my.listener:
    class: App\EventListener\EntityListener
    arguments: ['@security.token_storage']
    tags:
        - { name: doctrine.event_listener, event: prePersist }    
        - { name: doctrine.event_listener, event: preUpdate }

    

推荐阅读