You have to check the role in the form builder too, and you have 2 solutions to do that.
Solution 1
The most elegant is to create a custom form type as a service, depending on the security context:
class ArticleType extends AbstractType
{
private $securityContext;
public function __construct(SecurityContext $securityContext)
{
$this->securityContext = $securityContext;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name', 'text');
// If the user is granted
if($this->securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED'))
{
$builder->add('status', 'choice', array(
'choices' => array(
'A' => 'A',
'B' => 'B',
'C' => 'C',
),
'required' => true
));
}
// ...
}
// ...
}
Mark the form type as a service :
services:
form.type.article:
class: Foo\BarBundle\Form\Type\ArticleType
arguments: ["@security.context"]
tags:
- { name: form.type, alias: article_type }
Now, instead of calling new ArticleType()
in your controller, call this new service :
$form = $this->createForm($this->get('form.type.article'), $data);
Solution 2
The second solution is to pass the security context to the ArticleType
, no need to create a service. In your controller :
$form = $this->createForm(new ArticleType($this->get('security.context')->isGranted('IS_AUTHENTICATED_REMEMBERED')), $article);
And in your form type :
class ArticleType extends AbstractType
{
private $isGranted;
public function __construct($isGranted)
{
$this->isGranted = $isGranted;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name', 'text');
// If the user is granted
if($this->isGranted)
{
$builder->add('status', 'choice', array(
'choices' => array(
'A' => 'A',
'B' => 'B',
'C' => 'C',
),
'required' => true
));
}
// ...
}
// ...
}