<?php
namespace App\Form;
use App\Entity\Token;
use App\Entity\Reservation;
use App\Entity\Privatisation;
use App\Service\ExtraService;
use App\Entity\ExtraReservation;
use App\Entity\InterfaceReservation;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\AbstractType;
use App\Form\OptionSelectReservationType;
use Symfony\Component\Form\FormInterface;
use App\Service\OptionReservationService;
use App\Form\OptionQuantityReservationType;
use App\Form\OptionReservationCollectionType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
class ExtraReservationType extends AbstractType
{
public function __construct(
private ExtraService $extraService,
private OptionReservationService $optionReservationService
)
{}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
// Sert à ajouter les types des extra
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
/** @var ExtraReservation $extraReservation */
$extraReservation = $event->getData();
if($extraReservation) {
$form = $event->getForm();
$this->addExtraReservationFields($form, $extraReservation);
}
});
$builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) {
/** @var ExtraReservation $extraReservation */
$extraReservation = $event->getData();
$form = $event->getForm();
$reservation = $form->getConfig()->getOption('reservation');
if ($extraReservation) {
switch (get_class($reservation)) {
case Privatisation::class:
$extraReservation->setPrivatisation($reservation);
break;
case Token::class:
$extraReservation->setToken($reservation);
break;
case Reservation::class:
$extraReservation->setReservation($reservation);
break;
default:
throw new \InvalidArgumentException('Type de réservation inconnu');
}
}
if(!$extraReservation) {
// Principalement utilisé pour ajouter les types des extraReservations single object
$extraData = $form->getExtraData();
if(isset($extraData['idExtra'])) {
$extra = $this->extraService->getExtraById($extraData['idExtra']);
$extraReservation = new ExtraReservation;
$extraReservation->setExtra($extra);
$this->optionReservationService->generateOptionReservation($extraReservation);
foreach($extraReservation->getOptionQuantityReservations() as $index => $optionQuantityReservation) {
if(isset($extraData['optionQuantityReservations'][$index])) {
$optionQuantityReservation->setQuantity(intval($extraData['optionQuantityReservations'][$index]['quantity']));
}
}
foreach($extraReservation->getOptionSelectReservations() as $index => $optionSelectReservation) {
if(isset($extraData['optionSelectReservations'][$index])) {
$idOptionSelectItem = $extraData['optionSelectReservations'][$index]['optionSelectItem'];
$optionSelectItem = $this->optionReservationService->getOptionSelectItemById($idOptionSelectItem);
$optionSelectReservation->setOptionSelectItem($optionSelectItem);
}
}
if(isset($extraData['commentary'])) {
$extraReservation->setCommentary($extraData['commentary']);
}
$event->setData($extraReservation);
}
}
});
}
public function buildView(FormView $view, FormInterface $form, array $options)
{
/** @var ExtraReservation $extraReservation */
$extraReservation = $form->getData();
$parentFullName = $view->parent->vars['full_name'];
if ($extraReservation instanceof ExtraReservation && $extraReservation->getExtra()->isSingleObject()) {
if(is_null($extraReservation->getId())) {
$namePlaceholder = '__name__';
$parentFullName = $view->parent->vars['full_name'];
$id = sprintf('%s_%s', $view->parent->vars['id'], $namePlaceholder);
$fullName = sprintf('%s[%s]', $parentFullName, $namePlaceholder);
$view->vars['name'] = $view->vars['name'] * 1000;
$view->vars['full_name'] = $fullName;
$view->vars['id'] = $id;
}
}
if($extraReservation) {
$view->vars['price'] = $this->extraService->getPriceExtra($extraReservation);
}
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setRequired(
['reservation']
);
$resolver->setAllowedTypes('reservation', InterfaceReservation::class);
$resolver->setDefaults([
'data_class' => ExtraReservation::class,
'allow_extra_fields' => true,
]);
}
private function addExtraReservationFields(FormInterface $form, ExtraReservation $extraReservation): void
{
if(!$extraReservation->getOptionQuantityReservations()->isEmpty()) {
$form->add('optionQuantityReservations', OptionReservationCollectionType::class, [
'entry_type' => OptionQuantityReservationType::class,
'allow_add' => true,
'allow_extra_fields' => true,
'entry_options' => [
'with_total_quantities' => $extraReservation->getExtra()->isSingleObject() ? false : true
],
]);
}
if(!$extraReservation->getOptionSelectReservations()->isEmpty()) {
$form->add('optionSelectReservations', OptionReservationCollectionType::class, [
'entry_type' => OptionSelectReservationType::class,
'allow_add' => true,
'allow_extra_fields' => true,
]);
}
if($extraReservation->getExtra()->getPlaceholderCommentary()) {
$form->add('commentary', TextareaType::class, [
'attr' => [
'placeholder' => $extraReservation->getExtra()->getPlaceholderCommentary(),
],
]);
}
}
}