web-dev-qa-db-fra.com

Symfony 2 - comment passer des données à formBuilder?

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

36
jacobmaster

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);
    },
));
28
Bacteries
//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' =>'' 
       ));
     }
11
user3335780

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.

3
nick4fake

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 .

2
Ondrej Slinták

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);
      },
    )
);
2
FGREZE

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 ... 

0
user1954544