Home > Enterprise >  Can't get a way to read the property "member" in class "App\Entity\Invoice&quo
Can't get a way to read the property "member" in class "App\Entity\Invoice&quo

Time:07-07

I have an error when I use CollectionType:

https://symfony.com/doc/current/form/form_collections.html

I followed the documentation but I got the following error:

Can't get a way to read the property "member" in class "App\Entity\Invoice".

My controller:


#[Route('/subscription/{id}/new-invoice', name: 'new_invoice')]
    public function newInvoice(Event $event,Request $request):Response
    {

        $options['responsibleAdult'] = $this->getUser()->getId();
        $options['event'] = $event->getId();

        $listEventOption = $this->entityManager->getRepository(EventOption::class)->findBy(['event' => $event->getId()]);
        $resultListEventOption = [];
        $i=1;

        foreach($listEventOption as $value){
            $resultListEventOption[$value->getName()] = $i; 
            $i  ;
        }

        $options['eventOptions'] = $resultListEventOption;
        $invoice = new Invoice();

        $form = $this->createForm(InvoiceType::class, $invoice, $options);

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {

            $invoice = $form->getData();

            //...
        }
        

        return $this->render('subscription/new-invoice.html.twig', [
            'event' => $event,
            'subscriptionId' => $event->getId(),
            'form' => $form->createView(),
        ]);
    }


My InvoiceType:


class InvoiceType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder->add('eventSubscriptions', CollectionType::class, [
            'entry_type' => MemberEventSubscriptionType::class,
            'label' =>false,
            'entry_options' => $options,
            'allow_add' => true,
            'by_reference' => false,
            'allow_delete' => true,
        ]);
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => Invoice::class,
            'responsibleAdult' => "",
            'event' =>"",
            'eventOptions' => []
        ]);
    }
}


My MemberEventSubscriptionType:


class MemberEventSubscriptionType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('member', EntityType::class, [
                'class' => Member::class,
                'label' => false,
                'query_builder' => function (MemberRepository $mr) use($options) {
                    return $mr->findForEventSubscription($options);
                },
            ])
            ->add('eventRate', EntityType::class, [
                'class' => EventRate::class,
                'label' => false,
                'query_builder' => function (EventRateRepository $evr) {
                    return $evr->createQueryBuilder('er')
                        ->orderBy('er.amount', 'ASC');
                },
            ])
            ->add('eventOption', ChoiceType::class, [
                'label' => false,
                'expanded' => true,
                'multiple' => true,
                'choices' => $options['eventOptions']
            ])
            ->add('submit', SubmitType::class, [
                'label' => 'Valider l\'inscription',
                'attr' => [
                    'class' => 'btn-block btn-dark'
                ]
            ])
        ;
        
    }


    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => EventSubscription::class,
            'csrf_protection' => false,
            'responsibleAdult' => "",
            'event' =>"",
            'eventOptions' => []
        ]);
    }



My Invoice:


<?php

namespace App\Entity;

use App\Repository\InvoiceRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass=InvoiceRepository::class)
 */
class Invoice
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @var Collection|EventSubscription[] 
     * @ORM\OneToMany(targetEntity=EventSubscription::class, mappedBy="invoice")
     * @ORM\JoinTable(name="event_subscription_invoice")
     */
    protected Collection $eventSubscriptions;

    /**
     * @ORM\Column(type="boolean")
     */
    private $isPaid;

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

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

    /** @return EventSubscription[] */
    public function getEventSubscriptions(): Collection
    {
        return $this->eventSubscriptions;
    }

    public function isIsPaid(): ?bool
    {
        return $this->isPaid;
    }

    public function setIsPaid(bool $isPaid): self
    {
        $this->isPaid = $isPaid;

        return $this;
    }

    public function addEventSubscription(EventSubscription $eventSubscription): void
    {
        $this->eventSubscriptions->add($eventSubscription);
    }

    public function removeEventSubscription(EventSubscription $eventSubscription): self
    {
        if ($this->invoice->contains($eventSubscription)) {
            $this->invoice->removeElement($eventSubscription);
        }

        return $this;
    }
}

My EventSubscription:


<?php

namespace App\Entity;

use App\Repository\EventSubscriptionRepository;
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=EventSubscriptionRepository::class)
 */
class EventSubscription
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity=Event::class, inversedBy="eventSubscriptions")
     * @ORM\JoinColumn(nullable=false)
     */
    private Event $event;

    /**
     * @ORM\ManyToOne(targetEntity=Member::class, inversedBy="eventSubscriptions")
     * @ORM\JoinColumn(nullable=false)
     */
    private Member $member;

    /**
     * @ORM\ManyToOne(targetEntity=User::class, inversedBy="eventSubscriptions")
     * @ORM\JoinColumn(nullable=false)
     */
    private User $user;

    /**
     * @ORM\ManyToOne(targetEntity=EventRate::class, inversedBy="eventSubscriptions")
     * @ORM\JoinColumn(nullable=false)
     */
    private EventRate $eventRate;

    /**
     * @ORM\ManyToMany(targetEntity=EventOption::class, inversedBy="eventSubscriptions")
     * @ORM\JoinTable(name="event_subscription_event_option")
     */
    private Collection $eventOptions;

    /**
     * @Assert\Choice({"en attente de pièces", "résiliée", "ok"})
     * @ORM\Column(type="string", length=255)
     */
    private ?string $status;

    /**
     * @ORM\ManyToOne(targetEntity=Payment::class, inversedBy="eventSubscriptions", cascade={"persist"})
     * @ORM\JoinColumn(nullable=false)
     */
    private Payment $payment;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     * @Assert\File(mimeTypes={"image/gif", "image/jpeg", "image/png", "image/pdf"})
     */
    private ?string $medicalCertificateName;

    /**
     * @ORM\Column(type="string", length=5000, nullable=true)
     */
    private ?string $comment;

    /**
     * @ORM\Column(type="boolean")
     */
    private $isPaid = false;

    /**
     * @ORM\ManyToOne(targetEntity=Invoice::class, inversedBy="eventSubscriptions", cascade={"persist"})
     * @ORM\JoinColumn(nullable=false)
     */
    private Invoice $invoice;

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

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

    public function getEvent(): Event
    {
        return $this->event;
    }

    public function setEvent(Event $event): self
    {
        $this->event = $event;

        return $this;
    }

    public function getMember(): Member
    {
        return $this->member;
    }

    public function setMember(Member $member): self
    {
        $this->member = $member;

        return $this;
    }

    public function getUser(): User
    {
        return $this->user;
    }

    public function setUser(User $user): self
    {
        $this->user = $user;

        return $this;
    }

    public function getEventRate(): EventRate
    {
        return $this->eventRate;
    }

    public function setEventRate(EventRate $eventRate): self
    {
        $this->eventRate = $eventRate;

        return $this;
    }

    /**
     * @return Collection<int, EventOption>
     */
    public function getEventOptions(): Collection
    {
        return $this->eventOptions;
    }

    public function addEventOption(EventOption $eventOption): self
    {
        if (!$this->eventOptions->contains($eventOption)) {
            $this->eventOptions[] = $eventOption;
        }

        return $this;
    }

    public function removeEventOption(EventOption $eventOption): self
    {
        $this->eventOptions->removeElement($eventOption);

        return $this;
    }

    public function getStatus(): ?string
    {
        return $this->status;
    }

    public function setStatus(string $status): self
    {
        $this->status = $status;

        return $this;
    }

    public function getPayment(): Payment
    {
        return $this->payment;
    }

    public function setPayment(Payment $payment): self
    {
        $this->payment = $payment;

        return $this;
    }

    public function getMedicalCertificateName(): ?string
    {
        return $this->medicalCertificateName;
    }

    public function setMedicalCertificateName(string $medicalCertificateName): self
    {
        $this->medicalCertificateName = $medicalCertificateName;

        return $this;
    }

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

    /**
     * @param string|null $comment
     */
    public function setComment(?string $comment): void
    {
        $this->comment = $comment;
    }

    public function isIsPaid(): ?bool
    {
        return $this->isPaid;
    }

    public function setIsPaid(bool $isPaid): self
    {
        $this->isPaid = $isPaid;

        return $this;
    }


    public function getInvoice(): Invoice
    {
        return $this->invoice;
    }

    public function setInvoice(Invoice $invoice): self
    {
        $this->invoice = $invoice;

        return $this;
    }

}


HTML:


<button type="button"  data-collection-holder->Ajouter un membre</button>
                {{ form_start(form) }}
                    <ul 
                        data-index="{{ form.eventSubscriptions|length > 0 ? form.eventSubscriptions|last.vars.name   1 : 0 }}"
                        data-prototype="{{ form_widget(form.eventSubscriptions.vars.prototype)|e('html_attr') }}"
                    ></ul>
                {{ form_end(form) }}

JS:


const addFormToCollection = (e) => {
            const collectionHolder = document.querySelector('.'   e.currentTarget.dataset.collectionHolderClass);

            const item = document.createElement('div');

            item.innerHTML = collectionHolder
                .dataset
                .prototype
                .replace(
                /__name__/g,
                collectionHolder.dataset.index
                );

            collectionHolder.appendChild(item);

            collectionHolder.dataset.index  ;
        };

Have you a solution?

The error appears on:

$form = $this->createForm(InvoiceType::class, $invoice, $options);

PS:

Mapped false doesn't work, because it create other problems.

I have tested :

$form = $this->createForm(InvoiceType::class, null, $options);

but when I submit I have the same error.

CodePudding user response:

So I found the solution:

I have change my entry_options in my InvoiceType:

'entry_options' => [
                "responsibleAdult" => $options['responsibleAdult'],
                "event" => $options['event'],
                "eventOptions" => $options['eventOptions'],
            ],
  • Related