2016-02-16 70 views
7

根據請求用戶的角色,是否有正確的方式來定製表單?如何根據Symfony2/3中的用戶角色自定義表單域?

我的場景很簡單:如果用戶沒有授予ROLE_ADMIN,我需要隱藏一些字段。我試圖避免在Twig上進行現場顯示,但

{% if is_granted('ROLE_ADMIN') %} 
       {{form_row(form.field)}} 
    {% endif %} 

不起作用,因爲表單生成器會繞過此檢查。

Symfony的版本:2.8.2

編輯

得益於@Rooneyl suggestion我已經找到了解決辦法:

首先,你需要添加「角色'選項參數的關鍵。所以,在配置選項()$options['role']總是ROLE_USER

/** 
* @param OptionsResolver $resolver 
*/ 
public function configureOptions(OptionsResolver $resolver) 
{ 
    $resolver->setDefaults(array(
     'data_class' => 'MyBundle\Entity\Ticket', 
     'role' => 'ROLE_USER' 
    )); 
} 

然後在控制器,你必須通過getRoles()陣列:

$user_roles = $this->getUser()->getRoles(); 
$form = $this->createForm('MyBundle\Form\TicketType', $ticket, array('role' => $user_roles)); 
+0

已經更新了代碼 – Rooneyl

回答

4

您可以使用傳遞給表單構建器的選項來說明生成了哪些元素。
這樣,您可以更改完成的內容和驗證(使用validation_groups)。例如,你的控制器(假設角色是一個數組);
you controller;

$form = $this->createForm(new MyType(), $user, ['role' => $this->getUser()->getRoles()]); 

而且你的形式:

<?php 
namespace AppBundle\Form\Entity; 

use AppBundle\Entity\UserRepository; 
use Symfony\Component\Form\AbstractType, 
    Symfony\Component\Form\FormBuilderInterface, 
    Symfony\Component\OptionsResolver\OptionsResolver; 

class MyType extends AbstractType 
{ 
    /** 
    * @param OptionsResolver $resolver 
    */ 
    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'AppBundle\Entity\User', 
      'validation_groups' => ['create'], 
      'role' => ['ROLE_USER'] 
     )); 
    } 

    /** 
    * @param FormBuilderInterface $builder 
    * @param array $options 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     // dump($options['roles']); 
     if (in_array('ROLE_ADMIN', $options['role'])) { 
      // do as you want if admin 
      $builder 
       ->add('name', 'text'); 
     } else { 
      $builder 
       ->add('supername', 'text'); 
     } 
    } 

    /** 
    * @return string 
    */ 
    public function getName() 
    { 
     return 'appbundle_my_form'; 
    } 

} 
+0

當我嘗試使用選項參數時,Symfony返回這個錯誤:'選項「角色」不存在。爲什麼? – sentenza

+0

我認爲'$ options ['role']'必須是'getUser() - > getRoles()'。 – sentenza

+0

代碼可能不完整,我現在手機無法測試。我會運行它,並提供一個完整的解決方案,但理論上它是健全的。 – Rooneyl

8

你可以在你的形式。

撥打服務爲您的表單

app.form.type.task: 
    class: AppBundle\Form\FormType 
    arguments: ["@security.authorization_checker"] 
    tags: 
     - { name: form.type } 

在你的FormType,添加一個構造函數來獲得你的服務。

private $authorization; 
public function __construct(AuthorizationChecker $authorizationChecker) 
{ 
    $this->authorization = $authorizationChecker; 
} 

然後,在你的建設者,你將能夠檢查用戶權限

$builder->add('foo'); 
if($this->authorization->isGranted('ROLE_ADMIN')) 
{ 
    $builder->add('bar'); 
} 

然後,最後,你可以使你的表單

{% if form.formbar is defined %} 
    {{ form_row(form.formbar) }} 
{% endif %} 

請注意,這意味着您的字段可能爲空。因爲也許你想看到其中一些用戶可以看到它們,而另一些則不可以。

否則,您可以在您的實體構造方法中設置一個默認值,以確保如果用戶沒有/不能填充它,則值不會爲空。

+0

簡直太棒了。謝謝 –

相關問題