Modifier le query_builder d'un formulaire

Par Gaylord.P, il y a 10 ans


Bonjour à tous,

J'ai déjà posé la question sur Developpez, sur OpenClassRoom et même sur Stack Overflow, et personne ne semble pouvoir me répondre ; pourtant, ce problème est vraiment banal puisque ce que je cherche à faire est un "cas d'école".

J'ai tout simplement une entité (Module) qui possède un "OneToMany" vers une autre entité (ModuleControle). Dans ce dernier, il n'y a simplement qu'un textarea : un module possède donc X textarea.

Voici ce que j'ai fait actuellement :

ModuleType.php :

class ModuleType extends AbstractType { /** * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('point', 'textarea', array( 'label' => 'Point(s) à observer', 'required' => false, 'attr' => array( 'rows' => 5 ) )) ->add('controles', 'collection', array( 'label' => false, 'type' => new ModuleControleType(), 'allow_add' => true, 'allow_delete' => true, 'by_reference' => false )) ; }

Et ModuleControleType.php :

class ModuleControleType extends AbstractType { use Description; /** * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('description', 'textarea', array( 'label' => 'Description', 'required' => false, 'attr' => array( 'rows' => $rows ) )) ; } /** * @param OptionsResolverInterface $resolver */ public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'data_class' => 'AdministrationBundle\Entity\ModuleControle', 'intention' => $this->getName() . '_token' )); } /** * @return string */ public function getName() { return 'administration_module_controle_form'; } }

Jusque la, pas de soucis, c'est un cas d'école et tout fonctionne : l'ajout, la modifcation, la suppression.

Cependant, lors de la modification, Symfony 2 va chercher tout seul les éléments précédemments enregistrés ; mais je souhaite personnaliser la requête afin d'y mettre un Where.

Or et d'après la documentation, l'option "query_builder" n'est disponible que pour les types de formulaires "Entity" et moi, c'est un type "Collection".

Si quelqu'un a une idée, je bloque sur ce problème depuis 6 jours ... merci d'avance :)

4 réponses

Gaylord.P, il y a 10 ans

Salut et merci de ta réponse,

Voici le controller, il est vraiment basique : il récupère le module effectivement, mais pas les éléments du module (la requête se faisant seul) :

public function indexAction(Request $request, $page = 1) { $module_repository = $this->get('administration_module_repository'); $modules = $module_repository->getModules(); return array( 'modules' => $modules ); }

A titre informatif, voici getModules() qui, lui aussi, est basique (bien que ce soit une requête faîtes à la main) :

public function getModules() { $rsm = new ResultSetMappingBuilder($this->_em); $rsm->addRootEntityFromClassMetadata('AdministrationBundle:Module', 'm'); $query = $this->_em->createNativeQuery(' SELECT m.* FROM administration_module m WHERE m.date_suppression IS NULL ORDER BY m.libelle ASC ', $rsm); return $query->getResult(); }

Encore merci :)

skp, il y a 10 ans

Bonjour, pourrais-tu montrer ton controller ? Mais, je pense que c'est dans ton controller quand tu récupères ton "Module" que tu dois adapter ta requête.

skp, il y a 10 ans

Je pense qu'il faut que tu récupères directement tes modules avec les éléments. Par conséquent, tu ajoutes une jointure à ta requête et appliques ton « where ». De cette façon, tu n’auras qu’une seule requête et normalement ta collection devrait contenir les bons éléments.

Exemple requête :

SELECT m.*, mc.* FROM administration_module m INNER JOIN administration_module_controle mc WHERE m.date_suppression IS NULL AND mc.date_suppression IS NULL ORDER BY m.libelle ASC
Gaylord.P, il y a 10 ans

Merci beaucoup de ton aide c'est parfait, ça fonctionne ! :)
Pour ceux qui se posent la question, voici la requête finale envoyée au formulaire, je précise qu'il s'agit volontairement d'une requête manuelle :

public function getModule($module_id) { $rsm = new ResultSetMappingBuilder($this->_em); $rsm->addRootEntityFromClassMetadata('AdministrationBundle:Module', 'm'); $rsm->addJoinedEntityFromClassMetadata('AdministrationBundle\Entity\ModuleControle', 'mc', 'm', 'controles', array( 'id' => 'mc_id', 'description' => 'mc_description', 'date_creation' => 'mc_date_creation', 'date_modification' => 'mc_date_modification', 'date_suppression' => 'mc_date_suppression' )); $query = $this->_em->createNativeQuery(' SELECT mc.*, mc.id AS mc_id, mc.description AS mc_description, mc.date_creation AS mc_date_creation, mc.date_modification AS mc_date_modification, mc.date_suppression AS mc_date_suppression, m.* FROM administration_module m INNER JOIN administration_module_controle mc ON m.id = mc.module_id WHERE m.date_suppression IS NULL AND m.id = :module_id AND mc.date_suppression IS NULL ', $rsm); $query->setParameter('module_id', $module_id); return $query->getResult(); //return $query->getOneOrNullResult(); }