Bonjour tout le monde,
J'ai suivis le tutoriel sur les champs imbriqués. Mais malheureusement j'ai une petite erreur qui m'empèche d'avancer.

Ce que je fais

J'ai trois entités liées entre elles.
Category, Subcategory et Source.

<?php

namespace App\Form;

use App\Entity\Source;
use App\Entity\Ticket;
use App\Entity\Category;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;

class TicketType extends AbstractType {
    public function buildForm( FormBuilderInterface $builder, array $options ) {

        $builder->add( 'category', EntityType::class, [
            'class'       => 'App\Entity\Category',
            'placeholder' => 'Sélectionnez votre catégorie',
            'mapped'      => false,
            'attr' => [
                'class' => 'form-control form-control-sm col-12'
            ],
            'required'    => false
        ] );

        $builder
        ->get( 'category' )->addEventListener(
            FormEvents::POST_SUBMIT,

            function ( FormEvent $event ) {
                $form = $event->getForm();
                $this->addSubcategory( $form->getParent(), $form->getData() );
            }
        );

        $builder->addEventListener(
            FormEvents::POST_SET_DATA,

            function ( FormEvent $event ) {
                $data = $event->getData();
                $source = $data->getSource();
                $form = $event->getForm();
                if ( $source ) {
                    $subcategory = $source->getSubcategory();
                    $category = $subcategory->getCategory();
                    $this->addSubcategory( $form, $category );
                    $this->addSource( $form, $subcategory );
                    $form->get( 'category' )->setData( $category );
                    $form->get( 'subcategory' )->setData( $subcategory );
                } else {
                    $this->addSubcategory( $form, null );
                    $this->addSource( $form, null );
                }
            }
        );

    }

    private function addSubcategory( FormInterface $form, ?Category $category ) {
        $builder = $form->getConfig()->getFormFactory()->createNamedBuilder(
            'subcategory',
            EntityType::class,
            null,
            [
                'class'           => 'App\Entity\Subcategory',
                'placeholder'     => $category ? 'Sélectionnez votre sous-catégorie' : 'Sélectionnez votre catégorie',
                'mapped'          => false,
                'required'        => false,
                'auto_initialize' => false,
                'attr' => [
                    'class' => 'form-control form-control-sm col-12'
                ],
                'choices'         => $category ? $category->getSubcategories() : []
            ]
        );
        $builder->addEventListener(
            FormEvents::POST_SUBMIT,

            function ( FormEvent $event ) {
                $form = $event->getForm();
                $this->addSource( $form->getParent(), $form->getData() );
            }
        );
        $form->add( $builder->getForm() );
    }

    private function addSource( FormInterface $form, ?Subcategory $subcategory ) {
        $form->add( 'source', EntityType::class, [
            'class'       => 'App\Entity\Source',
            'required'    => false,
            'placeholder' => $subcategory ? 'Sélectionnez votre Source' : 'Sélectionnez votre sous-catégorie',
            'attr' => [
                'class' => 'form-control form-control-sm col-12'
            ],
            'choices'     => $subcategory ? $subcategory->getSources() : []
        ] );
    }

    public function configureOptions( OptionsResolver $resolver ) {
        $resolver->setDefaults( [
            'data_class' => Ticket::class,
        ] );
    }
}

Ce que je veux

J'aimerais que lorsque l'utilisateur sélectionne une catégorie, le select "subcategory" reprenne les options correspondantes à la catégorie choisie et lorsque l'on choisit une sous-caatégorie, le champ "source" affiche les sources relatives à la sous-catégories

Ce que j'obtiens

La liaison des champs entre "catégory" et "subcategory" fonctionne, malheureusement, le champ source lui n'interrragit pas avec le champ "subcategory".
Je reçois cette erreur :

Argument 2 passed to App\Form\TicketType::addSource() must be an instance of App\Form\Subcategory or null, instance of App\Entity\Subcategory given

J'ai beau repasser la vidéo du tuto en boucle et relire encore et encore l'explicatif je ne vois pas ce que je fais de travers, je dois passer à coté d'une petite chose si vous pouviez m'éclairer ce serait topissime :-)
D'avance merci

1 réponse


De quel tuto parle tu ?
J'ai l'impresion que tu complique la vie.