2016-08-23 14 views
1

私は複雑なアクセス制御が必要なアプリケーションを持っています。そして、コントローラレベルで決定するために必要なものはVotersです。 しかし、私は別の方法で別のユーザーのためのフォームを構築する必要があります。 例:Admin(ROLE_ADMIN)とUser(ROLE_USER)があります。フィールドが含まれている投稿があり:Sf2/3さまざまな役割(ユーザー)に応じて異なるフォームを表示

  • 著者
  • 司会

管理者が任意のポストのすべてのフィールドを編集することができなければならないタイムスタンプを発行しました。 ユーザーのみの特定のフィールド:published、body。 (ベイ・ウェイ、これはこの投稿の作者である場合に限りますが、これは有権者によって決定されます)。

可能な解決策は、dynamic form modificationです。しかし、もっと複雑なものが必要な場合、例えば投稿はブログに属し、ブログは著者に属します。そして投稿はブログの直接の著者と作者によって編集することができます。 ブログの作者はpostedAtフィールドを編集することもできますが、投稿の直接作成者はできません。

PRE_BINDリスナーにログインする必要があります。

多分、そのような状況のための一般的な習慣があるか、誰かが自分の例を示すことができます。

+1

symfonyのバージョンは、使用します:

<?php use Symfony\Component\Form\AbstractTypeExtension; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvents; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Security\Core\SecurityContextInterface; class SecurityTypeExtension extends AbstractTypeExtension { /** * The security context * @var SecurityContextInterface */ private $securityContext; /** * Object constructor */ public function __construct(SecurityContextInterface $securityContext) { $this->securityContext = $securityContext; } /** * {@inheritdoc} */ public function buildForm(FormBuilderInterface $builder, array $options) { $grant = $options['is_granted']; if (null === $grant || $this->securityContext->isGranted($grant)) { return; } $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) { $form = $event->getForm(); if ($form->isRoot()) { return; } $form->getParent()->remove($form->getName()); }); } /** * {@inheritdoc} */ public function configureOptions(OptionsResolver $resolver) { $resolver->setDefined(array('is_granted' => null)); } /** * {@inheritdoc} */ public function getExtendedType() { return 'form'; } } 

は最後に、あなただけのサービスとして拡張を保存する必要がありますか? symfony 2と3であなたの質問をタグ付けしました。あなたは古いバージョン2.3へのリンクと最新の3.1へのリンクを提供しました。 –

+0

私は個人的に2つの異なるフォームを持つ方が簡単です。私はあなたがコードを繰り返さないようにしたいと思っていますが、時にはコピー/ペーストが必要なだけです。あるいは、2つのフォームから始め、重複する箇所を正確に知ったら、それらを再びマージすることができます。 – Cerad

+0

@dragoste 2。8、すぐに3.1 – ZloyPotroh

答えて

3

あなたはROLE_ADMINが許可されている場合にのみ、フィールドを表示するフォームの種類を想像してみてform type extension

を作成し、これを行うことができます。そのためにあなたは、単に解釈されるように、このパラメータのフィールド(この例では、「著者」)

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder 
     ->add('published', 'text') 
     ->add('moderated', 'text') 
     ->add('author', 'text', [ 
      'is_granted' => 'ROLE_ADMIN', 
     ]) 
    ; 
} 

に新しいプロパティを追加することができ、あなたは権利を確保するためにSecurityContextのSymfonyを注入することによって、フォームタイプの拡張機能を作成する必要がありますログオンしたユーザーの

services: 
    yourbundle.security_type_extension: 
     class: YourProject\Bundle\ForumBundle\Form\Extension\SecurityTypeExtension 
     arguments: 
      - @security.context 
     tags: 
      - { name: form.type_extension, alias: form } 
+0

@DOS Youtは私と同じように考える。それは私の場合には非常に役に立つようです。これは奇妙です、私はこの解決策を見つけることはありません。 – ZloyPotroh

1

ダイナミックフォームの変更は不要です。ユーザーがログインすると、役割は変わるべきではありません。

フォームタイプにsecurity.authorization_checkerサービスを挿入し、buildFormメソッドでそれを使用して、フォームにフィールドを条件付きで追加することができます。どのくらいフォームが異なるかによっては、if文が多すぎると面倒なことがあります。その場合、私は別のフォームタイプを書くことをお勧めします(おそらく繰り返しフォームのために基本フォームタイプを拡張します)。

+0

私はそのオプションを想定しました。おそらくそれが唯一の正しい選択だろう。 – ZloyPotroh

関連する問題