src/Component/RFQ/Form/Type/RFQType.php line 30

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace BitBag\OpenMarketplace\Component\RFQ\Form\Type;
  4. use BitBag\OpenMarketplace\Component\Addressing\Entity\Country;
  5. use BitBag\OpenMarketplace\Component\Addressing\Form\Resolver\AllowedCountriesResolverInterface;
  6. use BitBag\OpenMarketplace\Component\Customer\Model\CustomerInterface;
  7. use BitBag\OpenMarketplace\Component\Organization\Entity\OrganizationInterface;
  8. use BitBag\OpenMarketplace\Component\Organization\Form\Type\CustomerType;
  9. use BitBag\OpenMarketplace\Component\RFQ\Entity\MessageInterface;
  10. use BitBag\OpenMarketplace\Component\RFQ\Entity\RFQInterface;
  11. use BitBag\OpenMarketplace\Component\RFQ\Factory\MessageFactoryInterface;
  12. use Doctrine\Common\Collections\ArrayCollection;
  13. use EWZ\Bundle\RecaptchaBundle\Form\Type\EWZRecaptchaV3Type;
  14. use EWZ\Bundle\RecaptchaBundle\Validator\Constraints\IsTrueV3 as RecaptchaIsTrueV3;
  15. use Sylius\Bundle\AddressingBundle\Form\Type\CountryChoiceType;
  16. use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
  17. use Sylius\Component\Core\Context\ShopperContextInterface;
  18. use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
  19. use Symfony\Component\Form\Extension\Core\Type\CollectionType;
  20. use Symfony\Component\Form\Extension\Core\Type\IntegerType;
  21. use Symfony\Component\Form\Extension\Core\Type\TextType;
  22. use Symfony\Component\Form\FormBuilderInterface;
  23. use Symfony\Component\Form\FormEvent;
  24. use Symfony\Component\Form\FormEvents;
  25. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  26. final class RFQType extends AbstractResourceType
  27. {
  28.     public function __construct(
  29.         protected string $dataClass,
  30.         private ShopperContextInterface $shopperContext,
  31.         private MessageFactoryInterface $messageFactory,
  32.         private AllowedCountriesResolverInterface $allowedCountriesResolver,
  33.         private SessionInterface $session,
  34.         ) {
  35.         parent::__construct($this->dataClass);
  36.     }
  37.     public function buildForm(FormBuilderInterface $builder, array $options): void
  38.     {
  39.         $sessionData $this->session->get('rfq_form_data', []);
  40.         $sessionRFQData $sessionData['app_rfq'] ?? [];
  41.         /** @var CustomerInterface|null $customer */
  42.         $customer $this->shopperContext->getCustomer();
  43.         $sessionRFQMessage = new ArrayCollection(
  44.             array_map(function ($messageData) use ($customer) {
  45.                 $messageText $messageData['message'] ?? '';
  46.                 if (!empty($messageText)) {
  47.                     /** @var MessageInterface $message */
  48.                     $message $this->messageFactory->createForCustomer($customer);
  49.                     $message->setMessage($messageText);
  50.                     return $message;
  51.                 }
  52.                 return null;
  53.             }, $sessionRFQData['messages'] ?? [])
  54.         );
  55.         $sessionRFQMessage $sessionRFQMessage->filter(fn ($msg) => null !== $msg);
  56.         if ($sessionRFQMessage->isEmpty()) {
  57.             /** @var MessageInterface $defaultMessage */
  58.             $defaultMessage $this->messageFactory->createForCustomer($customer);
  59.             $defaultMessage->setMessage('');
  60.             $sessionRFQMessage->add($defaultMessage);
  61.         }
  62.         $builder
  63.             ->add('country'CountryChoiceType::class, [
  64.                 'label' => 'sylius.ui.country',
  65.                 'required' => true,
  66.                 'multiple' => false,
  67.                 'expanded' => false,
  68.                 'choices' => $this->allowedCountriesResolver->resolveForRfq($options['data']),
  69.                 'data' => $this->getSelectedCountryEntity($sessionRFQData['country'] ?? null$this->allowedCountriesResolver->resolveForRfq($options['data'])),
  70.             ])
  71.             ->add('quantity'IntegerType::class, [
  72.                 'label' => 'sylius.ui.quantity',
  73.                 'required' => true,
  74.                 'attr' => [
  75.                     'min' => 1,
  76.                     'step' => 1,
  77.                 ],
  78.                 'data' => $sessionRFQData['quantity'] ?? null,
  79.             ])
  80.             ->add('messages'CollectionType::class, [
  81.                 'entry_type' => MessageType::class,
  82.                 'required' => false,
  83.                 'prototype' => true,
  84.                 'allow_add' => false,
  85.                 'allow_delete' => false,
  86.                 'by_reference' => false,
  87.                 'label' => false,
  88.                 'data' => $sessionRFQMessage,
  89.             ])
  90.             ->add('subject'TextType::class, [
  91.                 'required' => false,
  92.                 'label' => 'sylius.ui.subject',
  93.                 'empty_data' => 'Request for quote',
  94.             ])
  95.             ->add('termsAccepted'CheckboxType::class, [
  96.                 'required' => true,
  97.                 'label' => false,
  98.                 'help' => 'app.form.inquiry.terms',
  99.             ])
  100.             ->add('customer'CustomerType::class)
  101.             ->add('recaptcha'EWZRecaptchaV3Type::class, [
  102.                 'label' => false,
  103.                 'error_bubbling' => true,
  104.                 'mapped' => true,
  105.                 'constraints' => [
  106.                     new RecaptchaIsTrueV3([
  107.                         'message' => 'validator.message.recaptcha_invalid',
  108.                         'groups' => $this->validationGroups,
  109.                     ]),
  110.                 ],
  111.             ])
  112.         ;
  113.         $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
  114.             /** @var RFQInterface $rfq */
  115.             $rfq $event->getData();
  116.             if (false === $rfq->getMessages()->isEmpty()) {
  117.                 return;
  118.             }
  119.             /** @var ?CustomerInterface $customer */
  120.             $customer $this->shopperContext->getCustomer();
  121.             $organization $customer?->getOrganization();
  122.             if (!$organization instanceof OrganizationInterface) {
  123.                 /** @var MessageInterface $message */
  124.                 $message $this->messageFactory->createForCustomer($customer);
  125.                 $rfq->addMessage($message);
  126.                 return;
  127.             }
  128.             $form $event->getForm();
  129.             $form
  130.                 ->add('customer'CustomerType::class, [
  131.                     'data' => $customer,
  132.                     'disabled' => true,
  133.                 ]);
  134.             $message $this->messageFactory->createForCustomer($customer);
  135.             $rfq->setBuyer($organization);
  136.             $rfq->addMessage($message);
  137.         });
  138.     }
  139.     public function getBlockPrefix(): string
  140.     {
  141.         return 'app_rfq';
  142.     }
  143.     private function getSelectedCountryEntity(?string $countryCode, array $allowedCountries): ?Country
  144.     {
  145.         if (!$countryCode) {
  146.             return null;
  147.         }
  148.         foreach ($allowedCountries as $country) {
  149.             if ($country->getCode() === $countryCode) {
  150.                 return $country;
  151.             }
  152.         }
  153.         return null;
  154.     }
  155. }