Bonjour,

Je travaille sur un annuaire d'événements sur Symfony 6 et j'ai donc une page événements avec un formulaire de recherche (j'ai suivi le tuto de Grafikart "Créer un filtre produit sur Symfony"). Ces événements sont filtrables par catégorie et pays (relations avec mon entité Events).

J'ai donc deux EntityType pour mes 2 filtres (pays et catégorie) mais ça ne s'affiche pas comme je l'imagine c'est une liste mais je voudrais un "vrai" select avec une valeur par défaut et la liste déroulante quand on clique dessus. Je sais que le "multiple => true" donne une liste mais si j'enlève ça j'ai une erreur.

Symfony\Bridge\Doctrine\Form\ChoiceList\IdReader::getIdValue(): Argument #1 ($object) must be of type ?object, array given

Ce que j'obtiens

Si quelqu'un pouvait m'aider je lui en serais très reconnaissant, j'ai beaucoup cherché mais rien trouvé. Merci d'avance.

Mon SearchForm:

<?php

namespace App\Data;

use App\Entity\Category;
use App\Entity\Country;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class SearchForm extends AbstractType
{
    public $manager;

    public function __construct(EntityManagerInterface $manager)
    {
        $this->manager = $manager;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('keyword', TextType::class, [
                'label' => false,
                'required' => false,
                'attr' => [
                    'placeholder' => 'Search for an event..',
                    'class' => 'form-control border-0 text-white'
                ]
            ])
            ->add('categories', EntityType::class, [
                'class' => Category::class,
                'placeholder' => 'Select a category',
                'label' => false,
                'multiple' => true,
                'required' => false,
                'attr' => [
                    'class' => 'form-control border-0 rounded-2 text-muted py-2 px-2 w-100',
                ]
            ])
            ->add('countries', EntityType::class, [
                'class' => Country::class,
                'placeholder' => 'Select a country',
                'label' => false,
                'multiple' => true,
                'required' => false,
                'attr' => [
                    'class' => 'form-control border-0 rounded-2 text-muted py-2 px-2 w-100',
                ]
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => SearchData::class,
            'method' => 'GET',
            'csrf_protection' =>  false
        ]);
    }

    /**
     * @return string
     */
    public function getBlockPrefix(): string
    {
        return '';
    }
}

Mon SearchData:

<?php

namespace App\Data;

use App\Entity\Category;
use App\Entity\Country;

class SearchData
{
    /**
     * @var int
     */
    public $page = 1;

    /**
     * @var string
     */
    public $keyword = '';

    /**
     * @var array
     */
    public $categories = [];

    /**
     * @var array
     */
    public $countries = [];
}

Mon entité Events:

<?php

namespace App\Entity;

use App\Repository\EventsRepository;
use DateTime;
use App\Entity\User;
use DateTimeInterface;
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\Uploadable;
use Vich\UploaderBundle\Mapping\Annotation\UploadableField;

#[ORM\Entity(repositoryClass: EventsRepository::class)]
#[Uploadable]
class Events
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    private int $id;

    #[ORM\Column(type: 'string', length: 255)]
    private string $name;

    #[ORM\Column(type: 'datetime')]
    private $startDate;

    #[ORM\Column(type: 'datetime')]
    private $endDate;

    #[ORM\Column(type: 'datetime')]
    private $createdAt;

    #[ORM\Column(type: 'boolean')]
    private $isPublished;

    #[ORM\Column(type: 'string', length: 120)]
    private $image;

    #[UploadableField(mapping: 'event_image', fileNameProperty: 'image')]
    private ?File $file = null;

    #[ORM\Column(type: 'string', length: 255)]
    private string $location;

    #[ORM\ManyToOne(targetEntity: Category::class, inversedBy: 'events')]
    #[ORM\JoinColumn(nullable: false)]
    private $category;

    #[ORM\Column(type: 'string', length: 255)]
    private string $slug;

    #[ORM\Column(type: 'string', length: 255)]
    private string $tickets;

    #[ORM\Column(type: 'datetime')]
    private $updatedAt;

    #[ORM\ManyToOne(targetEntity: Country::class, inversedBy: 'events')]
    #[ORM\JoinColumn(nullable: false)]
    private $country;

    #[ORM\OneToMany(mappedBy: 'event', targetEntity: EventLike::class)]
    private $likes;

    #[ORM\ManyToMany(targetEntity: Tags::class, mappedBy: 'events')]
    private $tags;

    public function __construct()
    {
        $this->likes = new ArrayCollection();
        $this->tags = new ArrayCollection();
    }

    /**
     * @return int|null
     */
    public function getId(): ?int
    {
        return $this->id;
    }

    /**
     * @return string|null
     */
    public function getName(): ?string
    {
        return $this->name;
    }

    /**
     * @param string $name
     * @return $this
     */
    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    /**
     * @return DateTime|null
     */
    public function getStartDate(): ?DateTime
    {
        return $this->startDate;
    }

    /**
     * @param DateTime $startDate
     * @return $this
     */
    public function setStartDate(DateTime $startDate): self
    {
        $this->startDate = $startDate;

        return $this;
    }

    /**
     * @return DateTime|null
     */
    public function getEndDate(): ?DateTime
    {
        return $this->endDate;
    }

    /**
     * @param DateTime $endDate
     * @return $this
     */
    public function setEndDate(DateTime $endDate): self
    {
        $this->endDate = $endDate;

        return $this;
    }

    /**
     * @return DateTime|null
     */
    public function getCreatedAt(): ?DateTime
    {
        return $this->createdAt;
    }

    /**
     * @param DateTime $createdAt
     * @return $this
     */
    public function setCreatedAt(DateTime $createdAt): self
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    /**
     * @return bool|null
     */
    public function getIsPublished(): ?bool
    {
        return $this->isPublished;
    }

    /**
     * @param bool $isPublished
     * @return $this
     */
    public function setIsPublished(bool $isPublished): self
    {
        $this->isPublished = $isPublished;

        return $this;
    }

    /**
     * @return string|null
     */
    public function getImage(): ?string
    {
        return $this->image;
    }

    /**
     * @param string|null $image
     * @return $this
     */
    public function setImage(?string $image): self
    {
        $this->image = $image;

        return $this;
    }

    /**
     * @return string|null
     */
    public function getLocation(): ?string
    {
        return $this->location;
    }

    /**
     * @param string $location
     * @return $this
     */
    public function setLocation(string $location): self
    {
        $this->location = $location;

        return $this;
    }

    /**
     * @return Category|null
     */
    public function getCategory(): ?Category
    {
        return $this->category;
    }

    /**
     * @param Category|null $category
     * @return $this
     */
    public function setCategory(?Category $category): self
    {
        $this->category = $category;

        return $this;
    }

    /**
     * @return string|null
     */
    public function getSlug(): ?string
    {
        return $this->slug;
    }

    /**
     * @param string $slug
     * @return $this
     */
    public function setSlug(string $slug): self
    {
        $this->slug = $slug;

        return $this;
    }

    /**
     * @return string|null
     */
    public function getTickets(): ?string
    {
        return $this->tickets;
    }

    /**
     * @param string $tickets
     * @return $this
     */
    public function setTickets(string $tickets): self
    {
        $this->tickets = $tickets;

        return $this;
    }

    /**
     * @return DateTimeInterface|null
     */
    public function getUpdatedAt(): ?DateTimeInterface
    {
        return $this->updatedAt;
    }

    /**
     * @param DateTimeInterface $updatedAt
     * @return $this
     */
    public function setUpdatedAt(DateTimeInterface $updatedAt): self
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }

    /**
     * @return File|null
     */
    public function getFile(): ?File
    {
        return $this->file;
    }

    /**
     * @param File|null $file
     */
    public function setFile(?File $file): void
    {
        $this->file = $file;
    }

    public function __toString(){
        return $this->name;
    }

    public function getCountry(): ?Country
    {
        return $this->country;
    }

    public function setCountry(?Country $country): self
    {
        $this->country = $country;

        return $this;
    }

    /**
     * @return Collection<int, EventLike>
     */
    public function getLikes(): Collection
    {
        return $this->likes;
    }

    public function addLike(EventLike $like): self
    {
        if (!$this->likes->contains($like)) {
            $this->likes[] = $like;
            $like->setEvent($this);
        }

        return $this;
    }

    public function removeLike(EventLike $like): self
    {
        if ($this->likes->removeElement($like)) {
            // set the owning side to null (unless already changed)
            if ($like->getEvent() === $this) {
                $like->setEvent(null);
            }
        }

        return $this;
    }

    /**
     * Is this event liked by an user?
     *
     * @param User $user
     * @return bool
     */
    public function isLikedByUser(User $user): bool
    {
        foreach($this->likes as $like) {
            if($like->getUser() === $user) return true;
        }
        return false;
    }

    /**
     * @return Collection<int, Tags>
     */
    public function getTags(): Collection
    {
        return $this->tags;
    }

    public function addTag(Tags $tag): self
    {
        if (!$this->tags->contains($tag)) {
            $this->tags[] = $tag;
            $tag->addEvent($this);
        }

        return $this;
    }

    public function removeTag(Tags $tag): self
    {
        if ($this->tags->removeElement($tag)) {
            $tag->removeEvent($this);
        }

        return $this;
    }
}

2 réponses


Bonjour,

Je suppose que tu y a déjà penssé... mais est-ce que tu a essayé de mettre "'multiple' => false plutôt que de le retirer ?

Sinon "getIdValue()" plante car la valeur de l'argument 1 qu'on lui fourni est de type "array" plutôt que d'être un "object", il faudrait remonter la pile d'appels pour trouver ce qui provoque ça.

stylax
Auteur

Bonjour,

Merci pour ta réponse. Malheureusement le "'multiple' => false" n'y change rien. Que veux-tu dire par remonter la pile d'appels? Je suis encore novice avec Symfony et le développement web en général.