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 }

ユーザーを設定するフォームを指定したくないため、これが正しいアプローチであるかどうかはわかりません。(これは、すべてのフォームでユーザーを設定したいでしょう?)

さらに調査すると、次のような Event Subscriber を使用する必要があるようです: 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 に必要な例は本当に見つかりませんでした。

私はすべての助けに感謝しています! よろしくお願いします...

4

3 に答える 3

5

試してみてください$formMapper->getFormBuilder()->addEventSubscriber($subscriber);

于 2012-10-16T19:56:52.193 に答える
1

結局、私は自分の問題に対して2つの可能な解決策を見つけました。見つけるものがそれほど多くないので、ここでこれらの可能性について説明したいと思います。

Call as serviceのインスタンスのクエリを使用するイベントリスナー:

   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);

        }
    }
}

2番目の方法(そしておそらくもっと簡単な方法)は、SonataAdminBundleのAdminクラスで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

Event Dispatcher を挿入することで、管理者クラスにイベントを追加することを解決しました。

    <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 に答える