J'utilise la liste de choix des entités dans mon formulaire. Je veux utiliser uniquement des entités spécifiques (dans l'exemple: seuls les groupes auxquels l'utilisateur appartient) Donc, dans le contrôleur, je reçois ces groupes et j'essaie de les transmettre à formBuider
.
Manette:
/.../
$groups = $em->getRepository('VendorMyBundle:Group')->getUserGroups($user);
$form = $this->createForm(new Message($groups), $message);
/.../
alors quoi maintenant? comment l'utiliser dans formBuilder? Comment changer cette ligne pour utiliser le tableau passé de groupes?
->add('group','entity',array('class' => 'Vendor\MyBundle\Entity\Group', 'label'=>'Group:'))
ou dans l'autre sens:
class MessageType
{
/.../
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('group','entity',
array(
'class' => 'Vendor\MyBundle\Entity\Group',
'property' => 'name',
'query_builder' => function ($repository) {
$qb = $repository->createQueryBuilder('group');
$qb->add('where', 'group.administrator = :user');
$qb->setParameter('user', $user->getId());
return $qb;
},
'label' => 'Group'
)
)
// Continue adding fields
;
}
/.../
}
alors, comment puis-je obtenir l'objet $ user à utiliser dans le générateur de formulaire? ($ user représente l'utilisateur actuellement connecté)
Vous pouvez donner l'objet que vous voulez utiliser dans la méthode __construct ().
Par exemple :
$form = $this
->get('form.factory')
->create(new ApplyStepOneFormType($this->company, $this->ad), $applicant);
Dans votre type de formulaire:
function __construct(\Your\Bundle\Entity\Company $company, \DYB\ConnectBundle\Entity\Ad $ad) {
$this->company = $company;
$this->ad = $ad;
}
Et puis dans votre type de formulaire dans la méthode buildForm:
$company = $this->company;
$builder->add('ad', 'entity', array(
'class' => '\Your\Bundle\Entity\Ad',
'query_builder' => function(\Your\Bundle\Repository\AdRepository $er) use ($company) {
return $er->getActiveAdsQueryBuilder($company);
},
));
//In controller pass the value which you want to use in builder form in array like
$object = new Question();
$form->create(new QuestionType() , $object , array('sqtname'=>2,'question_type'=>2));
//In Form type class
public function buildForm(FormBuilderInterface $builder , array $options)
{
//for setting data field dynamically
if (array_key_exists('question_type', $options) && $options['question_type'] != '') {
$data = $em->getReference("RecrutOnlineStandardBundle:StdQuestionType",$options['question_type']->getId());
} else {
$data = "";
}
$builder->add('StdQuestionType', 'entity', array(
'class' => 'TestStandardBundle:StdQuestionType',
'property' => 'name',
'empty_value' => 'Sélectionner un question type',
'required' => true,
'data' => $data,
'query_builder' => function(EntityRepository $er ) use ( $options ) {
if (isset($options['sqtname']) && $options['sqtname'] != '') {
return $er->createQueryBuilder('sqt')
->where("sqt.name!= ".$options['sqtname']);
} else{
return $er->createQueryBuilder('sqt');
}
}
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Test\QuestionBundle\Entity\Question',
'required' => false,
'sqtname' => '',
'question_type' =>''
));
}
La solution pour les bactéries IS N'EST PAS bonne. Par exemple, si vous déclarez votre type en tant que service, il est impossible de passer un objet au constructeur.
Les options sont une solution parfaite: il suffit de passer les données en option pour créer un générateur.
Si vous souhaitez utiliser une requête personnalisée, vous devez définir l'option query_builder
comme suit:
use Doctrine\ORM\EntityRepository;
...
$message = new Message();
$form = $this->createFormBuilder($message)
->add('group', 'entity', array(
'class' => 'Vendor\MyBundle\Entity\Group',
'label'=>'Group:',
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('g')
->... // whatever you want to do
}
))
->getForm();
Vous trouverez plus d’informations sur le générateur de requêtes dans Manuel Doctrine et sur les options pour entity
dans Manuel Symfony2 .
La solution bactérienne est vraiment une bonne solution. Juste une note pour sauver le mal de tête à un autre gars comme moi :)
Dans cette partie, puis-je signaler la partie use ($company)
. Elle était cachée par le cadre et bien sûr, rien ne fonctionnait correctement sans elle.
$builder->add('ad', 'entity', array(
'class' =>
'\Your\Bundle\Entity\Ad',
'query_builder' =>
function(\Your\Bundle\Repository\AdRepository $er) use ($company) {
return $er->getActiveAdsQueryBuilder($company);
},
)
);
La meilleure façon (à mon avis) est de donner à votre formulaire entityManager et de sélectionner tout ce dont vous avez besoin. Mais n'oubliez pas de déclarer une clé vide dans setDefaults (), sinon les données ne seront pas transmises à votre constructeur.
Quelque chose comme celui-ci
public function buildForm(FormBuilderInterface $builder, array $options)
{
$options['em']->getRepository(''); // select all you need
$builder->add('title', 'text')
->add('content', 'textarea');
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Main\BlogBundle\Entity\Post',
'validation_groups' => array('post'),
'required' => false,
'em' => null // this var is for your entityManager
));
}
Appliquer EM comme simple option ...