Bonjour,

J'ai un formulaire de recherche basé sur des critères complétés par l'utilisateur. Dans ces critères, il y en a qui correspondent à des équipements qui peuvent être de deux sortes : ceux liés à la cellule et ceux liés au porteur.

Lors du chargement du formulaire, voici l'erreur que j'obtiens :

"Entity of type "App\Entity\Equipment" passed to the choice field must be managed. Maybe you forget to persist it in the entity manager?"

Pour effectuer la recherche, j'ai créé une entité "AdvertSearch.php" qui est hydratée par le formulaire de recherche.

Voici le code correspondant aux champs liés à l'équipement dans mon formulaire :


...
        $builder 
...
            ->add('cellEquipments', EntityType::class, ['required' => false,
                                                        'label' => false,
                                                        'class' => 'App\Entity\Equipment',
                                                        'choice_label' => 'equipment',
                                                        'multiple' => true, 
                                                        'query_builder' => function(EquipmentRepository $er) use ($belongingCell) {
                                                                                return $er->queryFindByBelonging($belongingCell);
                                                                           }
                                                       ]
                 )
            ->add('carrierEquipments', EntityType::class, ['required' => false,
                                                           'label' => false,
                                                           'class' => 'App\Entity\Equipment',
                                                           'choice_label' => 'equipment',
                                                           'multiple' => true,
                                                           'query_builder' => function(EquipmentRepository $er) use ($belongingCarrier) {
                                                                                   return $er->queryFindByBelonging($belongingCarrier);
                                                                              }
                                                          ]
                 )
...

Dans mon entité 'AdvertSearch.php", voici les propriétés , setters et getters liés :


...
    /**
     * @var ArrayCollection
     */
    private $cellEquipments;

    /**
     * @var ArrayCollection
     */
    private $carrierEquipments;
...
    public function __construct()
    {

        $this->cellEquipments = new ArrayCollection();
        $this->carrierEquipments = new ArrayCollection();

    }
...
    /**
     * @param ArrayCollection $cellEquipments
     */
    public function setCellEquipments(ArrayCollection $cellEquipments): void
    {

        $this->cellEquipments = $cellEquipments;

    }

    /**
     * @return ArrayCollection 
     */
    public function getCellEquipments(): ArrayCollection
    {

        return $this->cellEquipments;

    }

    /**
     * @param ArrayCollection $carrierEquipments
     */
    public function setCarrierEquipments(ArrayCollection $carrierEquipments): void
    {

        $this->carrierEquipments = $carrierEquipments;

    }

    /**
     * @return ArrayCollection 
     */
    public function getCarrierEquipments(): ArrayCollection
    {

        return $this->carrierEquipments;

    }
...

Voici le code correspondant à la tenue en compte de ces critères dans ma fonction de recherche dans le repository :


...
        $cellEquipments = $search->getCellEquipments();

        if ($cellEquipments->count() > 0)
        {

            $k = 0;

            foreach ($cellEquipments as $k => $cellEquipment) 
            {

                $k++;

                $query = $query->andWhere(":cellEquipment$k MEMBER OF v.cellEquipments")
                               ->setParameter("cellEquipment$k", $cellEquipment)
                ;

            }

        }

        $carrierEquipments = $search->getCarrierEquipments();

        if ($carrierEquipments->count() > 0)
        {

            $l = 0;

            foreach ($carrierEquipments as $l => $carrierEquipment) 
            {

                $l++;

                $query = $query->andWhere(":carrierEquipment$l MEMBER OF v.carrierEquipments")
                               ->setParameter("carrierEquipment$l", $carrierEquipment)
                ;

            }

        }
...

Quelqu'un aurait une idée sur la manière de résoudre ce problème?

Merci d'avance pour votre aide.

9 réponses


dubitoph
Auteur
Réponse acceptée

Problème résolu en supprimant la variable de session après l'avoir récupérée dans le controller.

Salut si je comprend tu veux effectuer une recherche sur l'entite equipement est-ce exacte ?

Bonjour.
Pour ma part, j'aimerais comprendre quelle est l'utilité de :

$k = 0; // Ceci
foreach ($cellEquipments as $k => $cellEquipment)
{
    $k++; // Et ceci, car : ↑

Car dans ta boucle foreach, tu as déjà un index qui s'incrémente déja tout seul.

dubitoph
Auteur

Merci beaucoup pour vos interventions.

Pour répondre à la première : la recherche peut de faire, entre autres, sur le prix, sur la distance à laquelle se situe le véhicule ou encore sur les équipements dont celui-ci dispose. Au niveau de la structure, une entité annonce est entre autres composée d'une entité véhicule elle-même compsée de deux collections d'équipements (une collection liée au porteur, l'autre à la cellule). Une entité véhicule est également composée d'une entité adresse (propriété qui est nommée situation).

Pour répondre à la seconde, de fait, cela me paraissait érange mais, dans le tutoriel que j'avais suivi (cf. https://www.grafikart.fr/tutoriels/filtre-1071), il est indiqué qu'il est préférable d'agir de la sorte pour des questions de sécurité.

J'ai eu beau visonner à plusieurs reprises la vidéo correspondant au lien que tu as indiqué, et il ne fait à aucun moment de boucle dans un repository.

dubitoph
Auteur

Tu as raison, je me suis trompé de lien. La bonne vidéo est la suivante : https://www.grafikart.fr/tutoriels/options-many-to-many-1072 et la boucle est expliquée à partir de la 27ième minute et 20 secondes.

Sauf qu'il enlève l'index de la boucle, alors que toi tu le laisse.
Tu devrais donc remplacer :

$k = 0;
foreach ($cellEquipments as $k => $cellEquipment)
{
    $k++;

Par :

$k = 0;
foreach ($cellEquipments as $cellEquipment)
{
    $k++;

Et il te faut faire la même chose également pour ta seconde boucle.

dubitoph
Auteur

Bien vu, merci ;)

Cependant, je ne parviens tout de même pas à résoudre l'erreur "Entity of type "App\Entity\Equipment" passed to the choice field must be managed. Maybe you forget to persist it in the entity manager?".

dubitoph
Auteur

Bon, en continuant à effectuer mes recherches quant à l'origine de l'erreur, j'ai remarqué que celle-ci ne survient que lorsque j'effectue pour la seconde fois une recherche avec un critèred'équipement.

Un peiti exemple de flux :

  1. J'effectue une recherche sans critère lié à l'équipement : tout est ok
  2. Je relance une recherche avec un critère lié à l'équipement : tout est ok
  3. Je relance une recherche avec un critère lié à l'équipement : erreur ci-dessus décrite