Symfony 3 获取实体内的当前用户
Symfony 3 get current user inside entity
我想知道是否有一种方法可以用 FOSUserBundle 的实体用户初始化 属性 所有者,以便它包含创建 Post
的用户
我想在构造函数中执行此操作,如下所示。
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="post")
* @ORM\Entity(repositoryClass="AppBundle\Repository\PostRepository")
*/
class Post
{
/* here are defined some attributs */
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="posts")
* @ORM\JoinColumn(name="owner", referencedColumnName="id")
*/
private $owner;
public function __construct()
{
$this->owner = /* get current user */ ;
}
}
有没有办法通过用某些东西替换构造函数中的注释来做到这一点?
感谢您的回答
不,没有。 [*]
至少有两种方法可以解决这个问题:
通过填充的工厂服务创建您的 Post 实体
owner
属性:
namespace My\Bundle\EntityFactory;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use My\Bundle\Entity\Post;
class PostFactory
{
private $tokenStorage;
public function __construct(TokenStorageInterface $tokenStorage)
{
$this->tokenStorage = $tokenStorage;
}
public function createPost()
{
$user = $this->tokenStorage()->getToken()->getUser();
$post = new Post($user);
}
}
(对于此示例,您必须将 Post
构造函数修改为
接受所有者作为参数)
在services.yml中:
services:
post_factory:
class: My\Bundle\EntityFactory\PostFactory
arguments: [@security.token_storage]
从您的控制器创建实体:
$post = $this->container->get('post_factory')->createPost();
如果你能容忍只有你坚持了才会设置所有者
实体,您可以使用学说事件侦听器:
namespace My\Bundle\EventListener;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use My\Bundle\Entity\Post;
class PostOwnerAssignmentListener
{
private $tokenStorage;
public function __construct(TokenStorageInterface $tokenStorage)
{
$this->tokenStorage = $tokenStorage;
}
public function prePersist(LifecycleEventArgs $event)
{
$entity = $event->getEntity();
if ($entity instanceof Post && !$entity->getOwner()) {
$entity->setOwner($this->tokenStorage->getToken()->getUser());
}
}
}
在services.yml中:
services:
post_owner_assignment_listener:
class: My\Bundle\EventListener\PostOwnerAssignmentListener
arguments: [@security.token_storage]
tags:
- { name: doctrine.event_listener, event: prePersit }
这里的优点是所有者无论以何种方式和地点得到分配
Post
已创建。
[*]:好吧,从技术上讲,使用默认 app.php
您可以访问
通过在你的构造函数中声明 global $kernel;
并从那里开始,
然而,非常 强烈建议不要这样做,并且可能会以奇怪和微妙的方式中断
方式.
我认为您 over-complicating 解决了这个问题。当您在控制器中创建新的 Post 时,在控制器或存储库中执行如下操作:
use AppBundle\Entity\Post; //at top of controller
$em = $this->getDoctrine()->getManager();
$user = $this->container->get('security.token_storage')->getToken()->getUser();
$post = new Post();
$em->persist( $post );
$post->setOwner( $user );
// set other fields in your post entity
$em->flush();
对于带有自动装配和实体事件侦听器的 Symfony 4+:
在/EventListener/PostPrePersistListener.php:
namespace App\EventListener;
use App\Entity\Post;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
class PostPrePersistListener
{
private $tokenStorage;
public function __construct(TokenStorageInterface $tokenStorage)
{
$this->tokenStorage = $tokenStorage;
}
public function prePersist(Post $post, LifecycleEventArgs $event)
{
$post->setOwner($this->tokenStorage->getToken()->getUser());
}
}
在services.yaml中:
services:
App\EventListener\PostPrePersistListener:
autowire: true
tags:
- { name: doctrine.orm.entity_listener, entity: 'App\Entity\Post', event: prePersist }
需要修改 services.yaml,因为 Symfony 无法知道此自定义服务被标记为挂钩 doctrine.event_listener
这按要求在实体级别工作,以确保控制器不处理 owner 值。
我想知道是否有一种方法可以用 FOSUserBundle 的实体用户初始化 属性 所有者,以便它包含创建 Post
的用户我想在构造函数中执行此操作,如下所示。
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="post")
* @ORM\Entity(repositoryClass="AppBundle\Repository\PostRepository")
*/
class Post
{
/* here are defined some attributs */
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="posts")
* @ORM\JoinColumn(name="owner", referencedColumnName="id")
*/
private $owner;
public function __construct()
{
$this->owner = /* get current user */ ;
}
}
有没有办法通过用某些东西替换构造函数中的注释来做到这一点?
感谢您的回答
不,没有。 [*]
至少有两种方法可以解决这个问题:
通过填充的工厂服务创建您的 Post 实体
owner
属性:namespace My\Bundle\EntityFactory; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use My\Bundle\Entity\Post; class PostFactory { private $tokenStorage; public function __construct(TokenStorageInterface $tokenStorage) { $this->tokenStorage = $tokenStorage; } public function createPost() { $user = $this->tokenStorage()->getToken()->getUser(); $post = new Post($user); } }
(对于此示例,您必须将
Post
构造函数修改为 接受所有者作为参数)在services.yml中:
services: post_factory: class: My\Bundle\EntityFactory\PostFactory arguments: [@security.token_storage]
从您的控制器创建实体:
$post = $this->container->get('post_factory')->createPost();
如果你能容忍只有你坚持了才会设置所有者 实体,您可以使用学说事件侦听器:
namespace My\Bundle\EventListener; use Doctrine\ORM\Event\LifecycleEventArgs; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use My\Bundle\Entity\Post; class PostOwnerAssignmentListener { private $tokenStorage; public function __construct(TokenStorageInterface $tokenStorage) { $this->tokenStorage = $tokenStorage; } public function prePersist(LifecycleEventArgs $event) { $entity = $event->getEntity(); if ($entity instanceof Post && !$entity->getOwner()) { $entity->setOwner($this->tokenStorage->getToken()->getUser()); } } }
在services.yml中:
services: post_owner_assignment_listener: class: My\Bundle\EventListener\PostOwnerAssignmentListener arguments: [@security.token_storage] tags: - { name: doctrine.event_listener, event: prePersit }
这里的优点是所有者无论以何种方式和地点得到分配
Post
已创建。
[*]:好吧,从技术上讲,使用默认 app.php
您可以访问
通过在你的构造函数中声明 global $kernel;
并从那里开始,
然而,非常 强烈建议不要这样做,并且可能会以奇怪和微妙的方式中断
方式.
我认为您 over-complicating 解决了这个问题。当您在控制器中创建新的 Post 时,在控制器或存储库中执行如下操作:
use AppBundle\Entity\Post; //at top of controller
$em = $this->getDoctrine()->getManager();
$user = $this->container->get('security.token_storage')->getToken()->getUser();
$post = new Post();
$em->persist( $post );
$post->setOwner( $user );
// set other fields in your post entity
$em->flush();
对于带有自动装配和实体事件侦听器的 Symfony 4+:
在/EventListener/PostPrePersistListener.php:
namespace App\EventListener;
use App\Entity\Post;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
class PostPrePersistListener
{
private $tokenStorage;
public function __construct(TokenStorageInterface $tokenStorage)
{
$this->tokenStorage = $tokenStorage;
}
public function prePersist(Post $post, LifecycleEventArgs $event)
{
$post->setOwner($this->tokenStorage->getToken()->getUser());
}
}
在services.yaml中:
services:
App\EventListener\PostPrePersistListener:
autowire: true
tags:
- { name: doctrine.orm.entity_listener, entity: 'App\Entity\Post', event: prePersist }
需要修改 services.yaml,因为 Symfony 无法知道此自定义服务被标记为挂钩 doctrine.event_listener
这按要求在实体级别工作,以确保控制器不处理 owner 值。