Quantcast
Channel: Grafikart | Derniers Sujets du forum
Viewing all articles
Browse latest Browse all 1542

Enregistrer une collection imbriquée dans une autre collection

$
0
0

Bonjour,

Voila je rencontre un petit problème avec mon code.

J'ai un formulaire de prestataires dans lequel je souhaite intégrer une collection de prestations et pour chaque prestation y intégrer une collection de expériences.
J'ai donc un formulaire avec un ArrayColllection qui lui contient un autre ArrayCollection.

Ce que j'ai fait

J'ai donc créé les entités Prestataire, Prestation et Expérience :

<?php
namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\PrestataireRepository")
 */
class Prestataire
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $name;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Prestation", mappedBy="prestataire", cascade={"persist"}, orphanRemoval=true)
     */
    private $prestations;

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

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(?string $name): self
    {
        $this->name = $name;
        return $this;
    }

    /**
     * @return Collection|Prestation[]
     */
    public function getPrestations(): Collection
    {
        return $this->prestations;
    }

    public function addPrestation(Prestation $prestation): self
    {
        if (!$this->prestations->contains($prestation)) {
            $this->prestations[] = $prestation;
            $prestation->setPrestataire($this);
        }
        return $this;
    }

    public function removePrestation(Prestation $prestation): self
    {
        if ($this->prestations->contains($prestation)) {
            $this->prestations->removeElement($prestation);
            // set the owning side to null (unless already changed)
            if ($prestation->getPrestataire() === $this) {
                $prestation->setPrestataire(null);
            }
        }
        return $this;
    }
}
<?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\PrestationRepository")
 */
class Prestation
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="text", nullable=true)
     */
    private $descriptif;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Prestataire", inversedBy="prestations")
     */
    private $prestataire;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Experience", mappedBy="prestation", cascade={"persist"}, orphanRemoval=true)
     */
    private $experiences;

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

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getDescriptif(): ?string
    {
        return $this->descriptif;
    }

    public function setDescriptif(?string $descriptif): self
    {
        $this->descriptif = $descriptif;
        return $this;
    }

    public function getPrestataire(): ?Prestataire
    {
        return $this->prestataire;
    }

    public function setPrestataireLogistique(?Prestataire $prestataire): self
    {
        $this->prestataire = $prestataire;

        return $this;
    }

    /**
     * @return Collection|Experience[]
     */
    public function getExperience(): Collection
    {
        return $this->experiences;
    }

    public function addExperience(Experience $experience): self
    {
        if (!$this->experiencesCinema->contains($experience)) {
            $this->experiences[] = $experience;
            $experience->setPrestation($this);
        }
        return $this;
    }

    public function removeExperience(Experience $experience): self
    {
        if ($this->experiences->contains($experience)) {
            $this->experiences->removeElement($experience);
            // set the owning side to null (unless already changed)
            if ($experience->getPrestation() === $this) {
                $experience->setPrestation(null);
            }
        }
        return $this;
    } 
}
<?php
namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\ExperienceRepository")
 */
class Experience
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $titre;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Prestation", inversedBy="experiences")
     * @ORM\JoinColumn(nullable=false)
     */
    private $prestation;

    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 getPrestation(): ?Prestation
    {
        return $this->prestation;
    }

    public function setPrestation(?Prestation $prestation): self
    {
        $this->prestation = $prestation;
        return $this;
    }
}

Voici les Forms correspondants à ces entités

<?php
namespace App\Form;

use App\Entity\Prestataire;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class PrestataireType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('prestations', CollectionType::class, [
                'entry_type' => PrestationType::class,
                'entry_options' => [
                    'label' => false,
                ],
                'allow_add' => true,
                'allow_delete' => true,
                'required' => false,
                'by_reference' => false,
                'prototype' => true,
                'prototype_name' => 'prestation'
            ])
            ->add('save', SubmitType::class, [
                'attr' => [
                    'class' => 'btn btn-primary',
                ]
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Prestataire::class,
        ]);
    }
}
<?php
namespace App\Form;

use App\Entity\Catering;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class PresdtationType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('descriptif', TextareaType::class, [
                'label' => " Descriptif de l’activité et du service proposé",
            ])
            ->add('experiences', CollectionType::class, [
                'entry_type' => ExperienceType::class,
                'entry_options' => [
                    'label' => false,
                ],
                'allow_add' => true,
                'allow_delete' => true,
                'required' => false,
                'by_reference' => true,
                'prototype' => true,
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Prestation::class,
        ]);
    }
}
<?php
namespace App\Form;

use App\Entity\Travaux;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class TravauxType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('titre', TextType::class, [
                'label' => false,
            ])
        ;
    }

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

Et voici la fonction de mon controller

/**
* @Route("/prestataire/new", name="prestataire_create")
* @Route("/prestataire/edit", name="prestataire_edit")
*/
public function editionform(PrestataireRepository $repository, Request $request, ObjectManager $manager)
    {
        $user = $this->getUser();

        $prestataire = $repository->findOneByUser($user);

        if(!$prestataire){
            $prestataire = new Prestataire();
        }

        $form = $this->createForm(PrestataireType::class, $prestataire);
        $form->handleRequest($request);

        if($form->isSubmitted() && $form->isValid()){
            //Je boucle l'ArrayCollection de Prestation
            foreach($prestataire->getPrestations() as $prestation){
                $prestation->setPrestataire($prestation);
                $manager->persist($prestation);
                //Je flush le $manager afin d'obtenir l'id  de la Prestation
                $manager->flush();

                foreach ($catering->getExperience() as $experience){
                    $experience->setPrestation($prestation);
                    $manager->persist($experience);
                }

                 //Enfin je flush de nouveau le $manager d'enregistrer les expériences
                $manager->flush();   
           }

            return $this->redirectToRoute('dashboard_user');
        }

        return $this->render('recensement/prestataire.html.twig', [
            'form' => $form->createView(),
        ]);
    }

Ce que je veux

Je voudrais que pour chaque prestation, l'ensemble des expériences soit enregsitré.

Ce que j'obtiens

Could not determine access type for property "experiences" in class "App\Entity\Prestation": Neither the property "experiences" nor one of the methods "addExperienceson()"/"removeExperienceson()", "addExperiencesum()"/"removeExperiencesum()", "setExperiences()", "experiences()", "__set()" or "__call()" exist and have public access in class "App\Entity\Prestation".

J'ai tente depuis plusieurs de trouver une solution mais toute mes recherches sont infructueuses donc si quelq'un peut me donner une solution ça sera avec un immense plaisir.

Merci


Viewing all articles
Browse latest Browse all 1542

Trending Articles