Partage
  • Partager sur Facebook
  • Partager sur Twitter

plusieurs entity dans un même repository

Symfony 5

    26 janvier 2020 à 22:14:08

    Bonsoir,

    Il est impossible d'appeler plusieurs entity dans le même repository

    mais je voudrais vos conseils pour mon problème suivant :

    J'ai 3 entity Annonce, Animal et Espece

    J'ai créé une entity Search pour travailler un filtre de mes annonces.

    Comme vous pouvez le supposer, dans mon annonce j'ai des informations propre à elle-même mais aussi j'ai fais appel à une relation avec Animal

    qui cette dernière est aussi en relation avec Espece.

    Donc par la suite, j'ai créé un form de Search qui s'injecte dans une route du Controller Annonce et du coup mes filtres sont dans le Repository Annonce

    j'ai pu faire des filtres sur les infos de l'entity annonce, mais je ne peux informer les champs de ma class Animal

        public function findAllWithPagination(Search $search) : Query{
            $req = $this->createQueryBuilder('a');
    
            if($search->getMinDate()){
                $req = $req->andWhere('a.dateStart >= :min')
                           ->setParameter(':min', $search->getMinDate());
            }
    
            if($search->getMaxDate()){
                $req = $req->andWhere('a.dateEnd <= :max')
                           ->setParameter(':max', $search->getMaxDate());
            }
    
            if($search->getSexe()){
                $req = $req
                            ->select('animalEntity.sexe AS animal')
                            ->leftJoin('a.animal', 'animalEntity')
                            ->andWhere('a.animal = :max')
                            ->setParameter(':max', $search->getSexe());
            }
    
    
    
            return $req->getQuery();
        }


    (pour info : createQueryBuilder('a') le "a" pour annonce)

    Je voudrais pour commencer savoir si tout se passe uniquement sur le repository ?

    Pour le moment je recherche à proposer le choix du sexe donc dans le form Search j'ai mis :

    ->add('sexe', EntityType::class,[
                    'class' => Animal::class,
                    'required' => false,
                    'choice_label' => 'sexe'
                ])



    l'erreur retournée est :

    [Semantical Error] line 0, col 147 near 'animal = :ma': Error: Invalid PathExpression. StateFieldPathExpression or SingleValuedAssociationField expected.

    Pourriez-vous me donner des conseils ou des pistes svp

    Merci

    • Partager sur Facebook
    • Partager sur Twitter

    la chance sourit aux audacieux

      27 janvier 2020 à 16:18:28

      Je ne comprends pas tout
      Mais je pense que tu dois écrire ca à la place

      $req = $req
      ->select('animalEntity.sexe AS animal')
      ->leftJoin('a.animal', 'animalEntity')
       ------------------------------------------------------
      ->andWhere('animalEntity.sexe = :max')
       ------------------------------------------------------
      ->setParameter(':max', $search->getSexe());

      -
      Edité par cretthie 27 janvier 2020 à 16:19:01

      • Partager sur Facebook
      • Partager sur Twitter
        27 janvier 2020 à 18:12:29

        Bonjour,

        et merci pour ta réponse, malheureusement non ça ne fonctionne pas.

        En fait pour schématiser mon projet, une personne créée la fiche de son animal (nom, âge, sexe, poids, espèce) Espèce a sa propre entity, ils sont donc en relation.

        Ensuite quand une personne créée une annonce, ils mentionnent des infos de l'entity annonce (titre description, dates et l'animal sélectionne) donc Annonce et Animal sont en relation.

        Maintenant pour les filtres j'ai créé une entity Search où je définis des critères, pour les infos de l'annonce, aucun problème, je vais dans le Repository de l'annonce, sauf que là où je bloque c'est comment par le biais de l'annonce rechercher les champs de l'animal, forcément une jointure mais je n'y arrive pas.

        est ce que déjà dans mon form l'appelle du sexe est bien écrite ? :

        ->add('sexe', EntityType::class,[
                        'class' => Animal::class,
                        'required' => false,
                        'choice_label' => 'sexe'
                    ])

        pour info, avec cet add, m'affiche sur la navigateur tous les sexes des animaux en bdd

        • Partager sur Facebook
        • Partager sur Twitter

        la chance sourit aux audacieux

          28 janvier 2020 à 11:13:08

          Pour ton form, je ne sais pas comment est formé ton entité Search.

          Ta jointure, tu l'as faite avec "->leftJoin('a.animal', 'animalEntity')", de fait, ensuite, pour ajouter un where sur ton entité animal, tu dois utiliser animalentity.sexe = :(identifiant_de_sexe)

          Si ca ne marche pas Peux tu mettre ton entité Search, Annonce, Animal et Sexe avec ton formulaire search.

          • Partager sur Facebook
          • Partager sur Twitter
            28 janvier 2020 à 12:45:20

            Bonjour, je te montre

            Entity Annonce 

            <?php
            
            namespace App\Entity;
            
            use Doctrine\Common\Collections\ArrayCollection;
            use Doctrine\Common\Collections\Collection;
            use Doctrine\ORM\Mapping as ORM;
            use Symfony\Component\Validator\Constraints as Assert;
            
            /**
             * @ORM\Entity(repositoryClass="App\Repository\AnnonceRepository")
             */
            class Annonce
            {
                /**
                 * @ORM\Id()
                 * @ORM\GeneratedValue()
                 * @ORM\Column(type="integer")
                 */
                private $id;
            
                /**
                 * @ORM\Column(type="string", length=255)
                 * @Assert\NotBlank(message="Veuillez renseigner un titre à l'annonce")
            	 * @Assert\Length(
            	 *	min=5,
            	 *	max=53,
            	 *  minMessage="Veuillez renseigner un titre de plus de 5 caractères",
            	 *  maxMessage="Veuillez renseigner un titre de moins de 53 caractères maximum"
            	 * )
                 */
                private $titre;
            
                /**
                 * @ORM\Column(type="date")
                 */
                private $dateStart;
            
                /**
                 * @ORM\Column(type="date")
                 */
                private $dateEnd;
            
                /**
                 * @ORM\Column(type="datetime")
                 */
                private $date_at;
            
                /**
                 * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="annonces")
                 * @ORM\JoinColumn(nullable=false)
                 */
                private $user;
            
                /**
                 * @ORM\ManyToMany(targetEntity="App\Entity\Animal", inversedBy="annonces")
                 */
                private $animal;
            
                /**
                 * @ORM\Column(type="text")
                 */
                private $description;
            
                public function __construct()
                {
                    $this->animal = new ArrayCollection();
                }
            
                public function getId(): ?int
                {
                    return $this->id;
                }
            
                public function getTitre(): ?string
                {
                    return $this->titre;
                }
            
                public function setTitre(string $titre): self
                {
                    $this->titre = $titre;
            
                    return $this;
                }
            
                public function getDateStart(): ?\DateTimeInterface
                {
                    return $this->dateStart;
                }
            
                public function setDateStart(\DateTimeInterface $dateStart): self
                {
                    $this->dateStart = $dateStart;
            
                    return $this;
                }
            
                public function getDateEnd(): ?\DateTimeInterface
                {
                    return $this->dateEnd;
                }
            
                public function setDateEnd(\DateTimeInterface $dateEnd): self
                {
                    $this->dateEnd = $dateEnd;
            
                    return $this;
                }
            
                public function getDateAt(): ?\DateTimeInterface
                {
                    return $this->date_at;
                }
            
                public function setDateAt(\DateTimeInterface $date_at): self
                {
                    $this->date_at = $date_at;
            
                    return $this;
                }
            
                public function getUser(): ?User
                {
                    return $this->user;
                }
            
                public function setUser(?User $user): self
                {
                    $this->user = $user;
            
                    return $this;
                }
            
                /**
                 * @return Collection|animal[]
                 */
                public function getAnimal(): Collection
                {
                    return $this->animal;
                }
            
                public function addAnimal(animal $animal): self
                {
                    if (!$this->animal->contains($animal)) {
                        $this->animal[] = $animal;
                        $animal->addAnnonce($this);
                    }
            
                    return $this;
                }
            
                public function removeAnimal(animal $animal): self
                {
                    if ($this->animal->contains($animal)) {
                        $this->animal->removeElement($animal);
                        $animal->addAnnonce($this);
                    }
            
                    return $this;
                }
            
                public function getDescription(): ?string
                {
                    return $this->description;
                }
            
                public function setDescription(string $description): self
                {
                    $this->description = $description;
            
                    return $this;
                }
            }
            

            Entity Animal

            <?php
            
            namespace App\Entity;
            
            use Doctrine\Common\Collections\ArrayCollection;
            use Doctrine\Common\Collections\Collection;
            use Doctrine\ORM\Mapping as ORM;
            use Symfony\Component\HttpFoundation\File\File;
            use Vich\UploaderBundle\Mapping\Annotation as Vich;
            use Symfony\Component\HttpFoundation\File\UploadedFile;
            
            /**
             * @ORM\Entity(repositoryClass="App\Repository\AnimalRepository")
             * @Vich\Uploadable
             */
            class Animal
            {
            
            
                const SEXE = [
                    0 => 'Mâle',
                    1 => 'Femelle'
                ];
            
            
                /**
                 * @ORM\Id()
                 * @ORM\GeneratedValue()
                 * @ORM\Column(type="integer")
                 */
                private $id;
            
                /**
                 * @ORM\Column(type="string", length=255)
                 */
                private $nom;
            
                /**
                 * @ORM\Column(type="string")
                 */
                private $age;
            
                /**
                 * @ORM\Column(type="boolean")
                 */
                private $sexe;
            
                /**
                 * @ORM\Column(type="string")
                 */
                private $poids;
            
                /**
                 * @ORM\Column(type="text")
                 */
                private $description;
            
                /**
                 * @ORM\Column(type="string", length=255)
                 */
                private $image;
            
            
                /**
                 * @Vich\UploadableField(mapping="animaux_image", fileNameProperty="image")
                 */
                
                private $imageFile;
            
            
            
                /**
                 * @ORM\Column(type="datetime")
                 */
                private $updated_at;
            
                /**
                 * @ORM\ManyToOne(targetEntity="App\Entity\Espece", inversedBy="animal")
                 */
                private $espece;
            
                /**
                 * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="animal")
                 * @ORM\JoinColumn(nullable=false)
                 */
                private $proprietaire;
            
                /**
                 * @ORM\ManyToMany(targetEntity="App\Entity\Annonce", mappedBy="animal")
                 */
                private $annonces;
            
                public function __construct()
                {
                    $this->annonces = new ArrayCollection();
                }
            
            
            
            
            
            
            
                public function getId(): ?int
                {
                    return $this->id;
                }
            
                public function getNom(): ?string
                {
                    return $this->nom;
                }
            
                public function setNom(string $nom): self
                {
                    $this->nom = $nom;
            
                    return $this;
                }
            
                public function getAge(): ?string
                {
                    return $this->age;
                }
            
                public function setAge(string $age): self
                {
                    $this->age = $age;
            
                    return $this;
                }
            
                public function getSexe(): ?bool
                {
                    return $this->sexe;
                }
            
                public function setSexe(bool $sexe): self
                {
                    $this->sexe = $sexe;
            
                    return $this;
                }
            
                public function getSexeType(): string
                {
                    return self::SEXE[$this->sexe];
                }
            
                public function getPoids(): ?string
                {
                    return $this->poids;
                }
            
                public function setPoids(string $poids): self
                {
                    $this->poids = $poids;
            
                    return $this;
                }
            
                public function getDescription(): ?string
                {
                    return $this->description;
                }
            
                public function setDescription(string $description): self
                {
                    $this->description = $description;
            
                    return $this;
                }
            
                public function getImage(): ?string
                {
                    return $this->image;
                }
            
                public function setImage(?string $image): self
                {
                    $this->image = $image;
            
                    return $this;
                }
            
                public function getImageFile(): ?File
                {
                    return $this->imageFile;
                }
            
            
                public function setImageFile(?File $imageFile = null): self
                {
                    $this->imageFile = $imageFile;
                    
                    if($this->imageFile instanceof UploadedFile){
                        $this->updated_at = new \DateTime('now');
                    }
                    return $this;
                }
            
            
            
                public function getUpdatedAt(): ?\DateTimeInterface
                {
                    return $this->updated_at;
                }
            
                public function setUpdatedAt(\DateTimeInterface $updated_at): self
                {
                    $this->updated_at = $updated_at;
            
                    return $this;
                }
            
                public function getEspece(): ?Espece
                {
                    return $this->espece;
                }
            
                public function setEspece(?Espece $espece): self
                {
                    $this->espece = $espece;
            
                    return $this;
                }
            
                public function getProprietaire(): ?User
                {
                    return $this->proprietaire;
                }
            
                public function setProprietaire(?User $proprietaire): self
                {
                    $this->proprietaire = $proprietaire;
            
                    return $this;
                }
            
                /**
                 * @return Collection|Annonce[]
                 */
                public function getAnnonces(): Collection
                {
                    return $this->annonces;
                }
            
                public function addAnnonce(Annonce $annonce): self
                {
                    if (!$this->annonces->contains($annonce)) {
                        $this->annonces[] = $annonce;
                        $annonce->addAnimal($this);
                    }
            
                    return $this;
                }
            
                public function removeAnnonce(Annonce $annonce): self
                {
                    if ($this->annonces->contains($annonce)) {
                        $this->annonces->removeElement($annonce);
                        $annonce->removeAnimal($this);
                    }
            
                    return $this;
                }
            
            }
            

            Entity Search

            <?php
            
            namespace App\Entity;
            
            use Doctrine\Common\Collections\ArrayCollection;
            use Symfony\Component\Validator\Constraints as Assert;
            
            class Search {
            
            
            
            private $minDate;
            
            private $maxDate;
            
            private $espece;
            
            private $sexe;
            
            
            
            public function getMinDate()
            {
                return $this->minDate;
            }
            public function setMinDate( $minDate) 
            {
                $this->minDate = $minDate;
                return $this;
            }
            
            
            
            
            public function getMaxDate()
            {
                return $this->maxDate;
            }
            public function setMaxDate($maxDate)
            {
                $this->maxDate = $maxDate;
                return $this;
            }
            
            
            
            public function getEspece()
            {
                return $this->espece;
            }
            public function setEspece($espece)
            {
                $this->espece = $espece;
                return $this;
            }
            
            public function getSexe()
            {
                return $this->sexe;
            }
            public function setSexe($sexe)
            {
                $this->sexe = $sexe;
                return $this;
            }
            
            
            
            
            }

            Form SearchTYpe

            <?php
            
            namespace App\Form;
            
            use App\Entity\Animal;
            use App\Entity\Search;
            use Symfony\Component\Form\AbstractType;
            use Symfony\Component\Form\FormBuilderInterface;
            use Symfony\Bridge\Doctrine\Form\Type\EntityType;
            use Symfony\Component\OptionsResolver\OptionsResolver;
            use Symfony\Component\Form\Extension\Core\Type\DateType;
            
            class SearchType extends AbstractType
            {
                public function buildForm(FormBuilderInterface $builder, array $options)
                {
            
                  
            
                    $builder
                        ->add('minDate', DateType::class, [
                            'required' => false,
                            'label' => false,
                            'widget' => 'single_text',
                            'attr' => [
                                'placeholder' => 'Date de départ'
                            ]
                        ])
            
                        ->add('maxDate', DateType::class, [
                            'required' => false,
                            'label' => false,
                            'widget' => 'single_text',
                            'attr' => [
                                'placeholder' => 'Date de retour'
                            ]
                        ])
            
            
                        ->add('sexe', EntityType::class,[
                            'class' => Animal::class,
                            'required' => false,
                            'choice_label' => 'sexe'
                        ])
            
            
            
            
                    ;
                }
            
                public function configureOptions(OptionsResolver $resolver)
                {
                    $resolver->setDefaults([
                        'data_class' => Search::class,
                        'method' => 'get',
                        'csrf_protection' => false,
                    ]);
                }
            
                public function getBlockPrefix()
                {
                    return '';
                }
            }
            







            • Partager sur Facebook
            • Partager sur Twitter

            la chance sourit aux audacieux

              28 janvier 2020 à 14:03:53

              Ok, merci.

              Donc, dans ton entity Animal, tu as :

              /**
              * @ORM\Column(type="boolean")
              */
              private $sexe;
              Et dans ton formulaire, tu utilises
              ->add('sexe', EntityType::class,[
              'class' => Animal::class,
              'required' => false,
              'choice_label' => 'sexe'
              ])
              Ca veut déjà dire que tu auras autant de choix de sexe que tu as de nombre d'animaux, non ? Donc, si tu as 20 animaux dans ta base, tu auras le choix de 20 sexe différents, non ? c'est pas très logique, non ?
              Je pense qu'il serait déjà mieux de creer une entité Sexe jointe à animal avec dedans mal et femelle. c'est mon avis, mais d'autres te dirons surement que ça demande trop de ressources pour les requêtes.
              As-tu essayé ca :
              if($search->getSexe()){
              $req = $req
              ->select('animalEntity.sexe AS animal')
              ->leftJoin('a.animal', 'animalEntity')
              ->andWhere('animalEntity.sexe = :sexe')
              ->setParameter(':sexe', false);
              }
              ou ca :
              if($search->getSexe()){
              $req = $req
              ->leftJoin('a.animal', 'animalEntity')
              ->addSelect('animalEntity')
              ->andWhere('animalEntity.sexe = 0');
              }
               et ensuite ca :
                          return $req->getQuery()
                          ->getResult();

              -
              Edité par cretthie 28 janvier 2020 à 14:05:20

              • Partager sur Facebook
              • Partager sur Twitter
                28 janvier 2020 à 14:42:21

                Pour le sexe, j'ai une CONST j'ai donc créée :

                ->add('sexe', ChoiceType::class, [
                                'label' => "Sexe",
                                'choices' => $this->getChoices()
                            ])
                    private function getChoices()
                    {
                        $choices = Animal::SEXE;
                        $output = [];
                        foreach($choices as $k => $v)
                        {
                            $output[$v] = $k;
                        }
                        return $output;
                    }




                 et dans le repo 

                if($search->getSexe()){
                            $req = $req
                                ->leftJoin('a.animal', 'animalEntity')
                                ->andWhere('animalEntity.sexe = :sexe')
                                ->setParameter(':sexe', $search->getSexe());
                        }

                Mais ça ne fonctionne pas partout, ça me revient j'ai déjà eu ce problème il y a quelques mois,

                à sexe=0 (mâle) je vois les mâles et femelles mais ) sexe=1 je vois bien que les femelles

                Mais pour le reste poids âge, j'ai crée dans le form animal des choices 

                Je pense comme pour le sexe, avoir la bonne appellation dans la form pour que le repo fonctionne

                -
                Edité par PierreRichard78 28 janvier 2020 à 15:36:20

                • Partager sur Facebook
                • Partager sur Twitter

                la chance sourit aux audacieux

                  28 janvier 2020 à 20:37:27

                  oui,

                  0 = false et 1 = true

                  Donc, ca fonctionne ?

                  Et l'escargot hermaphrodite ? :p

                  -
                  Edité par cretthie 28 janvier 2020 à 20:38:35

                  • Partager sur Facebook
                  • Partager sur Twitter
                    28 janvier 2020 à 21:02:18

                    les escargots sont dans la page dégustation ^^

                    J'ai fais quelques rajouts depuis tout à l'heure,

                       $builder
                                ->add('minDate', DateType::class, [
                                    'required' => false,
                                    'label' => false,
                                    'widget' => 'single_text',
                                    'attr' => [
                                        'placeholder' => 'Date de départ'
                                    ]
                                ])
                    
                                ->add('maxDate', DateType::class, [
                                    'required' => false,
                                    'label' => false,
                                    'widget' => 'single_text',
                                    'attr' => [
                                        'placeholder' => 'Date de retour'
                                    ]
                                ])
                    
                    
                                ->add('sexe', ChoiceType::class, [
                                    'label' => "Sexe",
                                    'required' => false,
                                    'choices' => $this->getChoices()
                                ])
                    
                    
                    
                                 ->add('espece', EntityType::class,[
                                    'class' => Espece::class,
                                    'required' => false,
                                    'choice_label' => 'nom'
                                ])
                    
                    
                                ->add('age', EntityType::class,[
                                    'class' => Animal::class,
                                    'required' => false,
                                    'choice_label' => 'age',
                                    'query_builder' => function (AnimalRepository $er){
                                        return $er->createQueryBuilder('a')
                                        ->groupBy('a.age');
                                        }
                                ])
                    
                    
                                ->add('poids', EntityType::class,[
                                    'class' => Animal::class,
                                    'required' => false,
                                    'choice_label' => 'poids',
                                    'query_builder' => function (AnimalRepository $er){
                                       
                                        return $er->createQueryBuilder('a')
                                        ->groupBy('a.poids');
                                        }
                                ])
                     public function findAllWithPagination(Search $search) : Query{
                            $req = $this->createQueryBuilder('a')
                            ->orderBy('a.date_at','DESC');
                    
                            if($search->getMinDate()){
                                $req = $req->andWhere('a.dateStart >= :min')
                                           ->setParameter(':min', $search->getMinDate());
                            }
                    
                            if($search->getMaxDate()){
                                $req = $req->andWhere('a.dateEnd <= :max')
                                           ->setParameter(':max', $search->getMaxDate());
                            }
                    
                            if($search->getDateCreatedCroissant()){
                                $req = $req->orderBy('a.date_at','ASC');
                            }
                    
                            if($search->getDateCreatedDecroissant()){
                                $req = $req->orderBy('a.date_at','DESC');
                            }
                    
                            if($search->getSexe()){
                                $req = $req
                                    ->leftJoin('a.animal', 'animalEntity')
                                    ->andWhere('animalEntity.sexe = :sexe')
                                    ->setParameter(':sexe', $search->getSexe());
                            }
                    
                            if($search->getEspece()){
                                $req = $req
                                    ->leftJoin('a.animal', 'animal')
                                    ->leftJoin('animal.espece', 'especeEntity')
                                    ->andWhere('especeEntity.nom = :espece')
                                    ->setParameter(':espece', $search->getEspece());
                            }
                    
                            if($search->getAge()){
                                $req = $req
                                    ->leftJoin('a.animal', 'animalEntity')
                                    ->andWhere('animalEntity.age = :age')
                                    ->setParameter(':age', $search->getAge());
                            }
                    
                    
                    
                         
                            
                            return $req->getQuery();
                        }
                    


                    pas d'erreurs, les champs de filtres sont présents, apparaissent bien les différentes sélections mais quand j'en choisis un, il n'y a rien qui s'affiche, je ne vois pas où est le problème

                    • Partager sur Facebook
                    • Partager sur Twitter

                    la chance sourit aux audacieux

                    plusieurs entity dans un même repository

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown