<?php
declare(strict_types=1);
namespace BitBag\OpenMarketplace\Component\Inquiry\Form\Type;
use BitBag\OpenMarketplace\Component\Addressing\Entity\Country;
use BitBag\OpenMarketplace\Component\Addressing\Form\Resolver\AllowedCountriesResolverInterface;
use BitBag\OpenMarketplace\Component\Customer\Model\CustomerInterface;
use BitBag\OpenMarketplace\Component\Inquiry\Entity\InquiryInterface;
use BitBag\OpenMarketplace\Component\Inquiry\Entity\MessageInterface;
use BitBag\OpenMarketplace\Component\Inquiry\Factory\MessageFactoryInterface;
use BitBag\OpenMarketplace\Component\Organization\Entity\OrganizationInterface;
use BitBag\OpenMarketplace\Component\Organization\Form\Type\CustomerType;
use Doctrine\Common\Collections\ArrayCollection;
use EWZ\Bundle\RecaptchaBundle\Form\Type\EWZRecaptchaV3Type;
use Sylius\Bundle\AddressingBundle\Form\Type\CountryChoiceType;
use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
use Sylius\Component\Core\Context\ShopperContextInterface;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
final class InquiryType extends AbstractResourceType
{
public function __construct(
protected string $dataClass,
private ShopperContextInterface $shopperContext,
private MessageFactoryInterface $messageFactory,
private AllowedCountriesResolverInterface $allowedCountriesResolver,
private SessionInterface $session,
) {
parent::__construct($this->dataClass);
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$sessionData = $this->session->get('inquiry_form_data', []);
$sessionInquiryData = $sessionData['app_inquiry'] ?? [];
$sessionInquiryMessage = new ArrayCollection(
array_map(function ($messageData) {
$messageText = $messageData['message'] ?? '';
if (!empty($messageText)) {
/** @var MessageInterface $message */
$message = $this->messageFactory->createNew();
$message->setMessage($messageText);
return $message;
}
return null;
}, $sessionInquiryData['messages'] ?? [])
);
$sessionInquiryMessage = $sessionInquiryMessage->filter(fn ($msg) => null !== $msg);
if ($sessionInquiryMessage->isEmpty()) {
/** @var MessageInterface $defaultMessage */
$defaultMessage = $this->messageFactory->createNew();
$defaultMessage->setMessage('');
$sessionInquiryMessage->add($defaultMessage);
}
$builder
->add('country', CountryChoiceType::class, [
'label' => 'sylius.ui.country',
'required' => true,
'multiple' => false,
'expanded' => false,
'choices' => $this->allowedCountriesResolver->resolveForInquiry($options['data']),
'data' => $this->getSelectedCountryEntity($sessionInquiryData['country'] ?? null, $this->allowedCountriesResolver->resolveForInquiry($options['data'])),
])
->add('messages', CollectionType::class, [
'entry_type' => MessageType::class,
'required' => false,
'prototype' => true,
'allow_add' => false,
'allow_delete' => false,
'by_reference' => false,
'label' => false,
'data' => $sessionInquiryMessage,
])
->add('subject', TextType::class, [
'required' => false,
'label' => 'sylius.ui.subject',
'empty_data' => 'Inquiry request',
])
->add('termsAccepted', CheckboxType::class, [
'required' => true,
'label' => false,
'help' => 'app.form.inquiry.terms',
])
->add('customer', CustomerType::class)
->add('recaptcha', EWZRecaptchaV3Type::class, [
'label' => false,
'error_bubbling' => true,
'mapped' => true,
])
;
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
/** @var InquiryInterface $inquiry */
$inquiry = $event->getData();
if (false === $inquiry->getMessages()->isEmpty()) {
return;
}
/** @var ?CustomerInterface $customer */
$customer = $this->shopperContext->getCustomer();
$organization = $customer?->getOrganization();
if (!$organization instanceof OrganizationInterface) {
/** @var MessageInterface $message */
$message = $this->messageFactory->createNew();
$inquiry->addMessage($message);
return;
}
$form = $event->getForm();
$form
->add('customer', CustomerType::class, [
'data' => $customer,
'disabled' => true,
]);
$message = $this->messageFactory->createForCustomer($customer);
$inquiry->setBuyer($organization);
$inquiry->addMessage($message);
});
}
public function getBlockPrefix(): string
{
return 'app_inquiry';
}
private function getSelectedCountryEntity(?string $countryCode, array $allowedCountries): ?Country
{
if (!$countryCode) {
return null;
}
foreach ($allowedCountries as $country) {
if ($country->getCode() === $countryCode) {
return $country;
}
}
return null;
}
}