我尝试在SonataAdminBundle表单中设置当前经过身份验证的用户:
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('title')
->add('content')
->add('slug')
//->add('user')
;
}
由于我不希望用户选择/选择自己的用户,我想我想在用户发送表单的过程中设置用户名(没有任何用户)用户对象)。 (注意:我想以几种形式使用它,所以我需要一个通用的解决方案。)
我现在所做的是在我读完这篇文章之后设置一个EventListener:http://symfony.com/doc/current/cookbook/service_container/event_listener.html
class PostListener
{
protected $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function prePersist(LifeCycleEventArgs $args)
{
$entity = $args->getEntity();
//Get user
$securityContext = $this->container->get('security.context');
$user = $securityContext->getToken()->getUser();
//Set authenticated user as autor
$entity->setUser($user);
}
}
包括服务:
post.listener:
class: Backender\BlogBundle\Listener\PostListener
calls:
- [ setContainer, [ @service_container ] ]
tags:
- { name: doctrine.event_listener, event: prePersist }
现在不确定,如果这是正确的方法,因为我不想指定我想要设置用户的表单。 (这个人想要在每个表格上设置用户吗?)
通过更多研究,似乎我可以像这样使用事件订阅者:http://symfony.com/doc/2.0/cookbook/form/dynamic_form_generation.html 在这个例子中,他们使用FormEvents :: PRE_SET_DATA,我想在我的情况下我必须使用POST_SET_DATA。
我在这里遇到了一些问题!:
1:我对SonataAdminBundle很陌生,在那里我们使用受保护的函数configureFormFields(FormMapper $ formMapper)...其中->addEventSubscriber()
不可用?
2:这是正确的方法吗?我真的没有找到像sonata-admin那样的例子。
我感谢你的每一个帮助! 最好的问候......
答案 0 :(得分:5)
尝试使用$formMapper->getFormBuilder()->addEventSubscriber($subscriber);
答案 1 :(得分:1)
最后,我找到了两个可能解决我问题的方法。我想在这里描述这些可能性,因为找不到那么多东西。
查询实例的事件侦听器 呼叫服务:
blog.post.listener:
class: Acme\BlogBundle\Listener\PostListener
arguments: ['@service_container']
tags:
- { name: doctrine.event_listener, event: prePersist }
听众类:
class PostListener
{
protected $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function prePersist(LifeCycleEventArgs $args)
{
$entity = $args->getEntity();
//Get user
$securityContext = $this->container->get('security.context');
$user = $securityContext->getToken()->getUser();
if ($entity instanceof Post) {
//Set authenticated user as autor
$entity->setUser($user);
}
}
}
第二种方式(也许更容易)是在SonataAdminBundle的管理类中使用prePersist
作为服务调用(使用服务容器或安全上下文作为参数):
blog.admin.post:
class: Acme\BlogBundle\Admin\PostAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: Article Handling, label: Posts }
arguments: [null, Acme\BlogBundle\Entity\Post, SonataAdminBundle:CRUD, @service_container]
PostAdmin: (注意,我使用容器,因为我将来需要更多东西)
class PostAdmin extends Admin
{
protected $securityContext;
public function __construct($code, $class, $baseControllerName, ContainerInterface $container)
{
parent::__construct($code, $class, $baseControllerName);
$this->container = $container;
}
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('title')
->add('content')
;
}
public function prePersist($post)
{
$user = $this->container->get('security.context')->getToken()->getUser();
$post->setUser($user);
}
}
答案 2 :(得分:0)
我通过注入Event Dispatcher解决了向Admin Class添加事件的问题:
<service id="acme.listener.contract"
class="Acme\AppBundle\Event\ContractListener">
<argument type="service" id="twig"></argument>
<argument type="service" id="mailer"></argument>
<tag name="kernel.event_listener" event="contract.created" method="onContractCreated" />
</service>
然后在我的管理类中,我将事件添加到现有方法中:
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Security\Core\SecurityContextInterface;
class ContractAdmin extends Admin
{
protected $dispatcher;
/**
* Security Context
* @var \Symfony\Component\Security\Core\SecurityContextInterface
*/
protected $securityContext;
public function setEventDispatcher(EventDispatcherInterface $dispatcher)
{
$this->dispatcher = $dispatcher;
}
public function setSecurityContext(SecurityContextInterface $securityContext)
{
$this->securityContext = $securityContext;
}
public function prePersist($contract)
{
$user = $this->securityContext->getToken()->getUser();
$contract->setUser($user);
$event = new ContractEvent($contract);
$dispatcher = $this->dispatcher;
$dispatcher->dispatch(
ContractEvents::CONTRACT_CREATED,
$event
);
}
这允许我在其他地方添加我在我的应用程序中共享的额外事件。
在您的情况下,您只需注入安全上下文:
sonata.admin.contract:
class: Acme\AppBundle\Admin\ContractAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: "Contracts", label_catalogue: "messages", label: "Auftragsübersicht" }
arguments:
- ~
- Acme\AppBundle\Entity\Contract
- ~
calls:
- [ setSecurityContext, [@security.context]]
- [ setEventDispatcher, [@event_dispatcher]]