0

我尝试在 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:这是正确的方法吗?,我真的没有找到任何像我需要的奏鸣曲管理员的例子。

我感谢每一个帮助!最好的祝福...

4

3 回答 3

5

尝试$formMapper->getFormBuilder()->addEventSubscriber($subscriber);

于 2012-10-16T19:56:52.193 回答
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);
    }

}
于 2012-10-28T20:53:06.490 回答
0

我通过注入事件调度程序解决了向管理类添加事件的问题:

    <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]]
于 2014-12-08T15:11:15.030 回答