src/Component/Core/Shop/Controller/Contact/ContactController.php line 44

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace BitBag\OpenMarketplace\Component\Core\Shop\Controller\Contact;
  4. use BitBag\OpenMarketplace\Component\Brevo\Exporter\ContactExporter;
  5. use BitBag\OpenMarketplace\Component\Channel\Entity\ChannelInterface;
  6. use BitBag\OpenMarketplace\Component\Core\Common\Encrypter\EncrypterInterface;
  7. use BitBag\OpenMarketplace\Component\Core\Shop\Email\ContactEmailManagerInterface;
  8. use BitBag\OpenMarketplace\Component\Core\Shop\Enum\ContactTypes;
  9. use BitBag\OpenMarketplace\Component\Core\Shop\Form\Type\Contact\ContactType;
  10. use BitBag\OpenMarketplace\Component\Customer\Entity\Customer;
  11. use BitBag\SyliusB2BPlugin\Entity\CustomerInterface;
  12. use Sylius\Component\Channel\Context\ChannelContextInterface;
  13. use Sylius\Component\Locale\Context\LocaleContextInterface;
  14. use Symfony\Component\Form\FormFactoryInterface;
  15. use Symfony\Component\HttpFoundation\RedirectResponse;
  16. use Symfony\Component\HttpFoundation\Request;
  17. use Symfony\Component\HttpFoundation\Response;
  18. use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
  19. use Symfony\Component\Routing\RouterInterface;
  20. use Symfony\Component\Templating\EngineInterface;
  21. use Twig\Environment;
  22. use Webmozart\Assert\Assert;
  23. final class ContactController
  24. {
  25.     private const NEWSLETTER_TOKEN_KEY_STORAGE_PREFIX 'newsletter_token:';
  26.     public function __construct(
  27.         private RouterInterface $router,
  28.         private FormFactoryInterface $formFactory,
  29.         private EngineInterface|Environment $templatingEngine,
  30.         private ChannelContextInterface $channelContext,
  31.         private LocaleContextInterface $localeContext,
  32.         private ContactEmailManagerInterface $contactEmailManager,
  33.         private EncrypterInterface $encrypter,
  34.         private ContactExporter $contactExporter,
  35.         private \Redis $redis
  36.     ) {
  37.     }
  38.     public function requestAction(Request $request): Response
  39.     {
  40.         $contactType $this->getSyliusAttribute($request'type'null);
  41.         Assert::inArray($contactTypeContactTypes::ALL_TYPES'Invalid contact request type');
  42.         Assert::notNull($contactType'Invalid contact request type');
  43.         $formType $this->getSyliusAttribute($request'form'ContactType::class);
  44.         Assert::string($formType'Form type must be a string');
  45.         $form $this->formFactory->create($formTypenull$this->getFormOptions($contactType));
  46.         if ($request->isMethod('POST') && $form->handleRequest($request)->isValid()) {
  47.             $data $form->getData();
  48.             Assert::inArray($contactTypeContactTypes::ALL_TYPES'Invalid contact request type');
  49.             $channel $this->channelContext->getChannel();
  50.             Assert::isInstanceOf($channelChannelInterface::class);
  51.             $contactEmail $channel->getContactEmail();
  52.             if (null === $contactEmail) {
  53.                 return $this->prepareRedirectOnMissingContactEmail($request);
  54.             }
  55.             $localeCode $this->localeContext->getLocaleCode();
  56.             if (ContactTypes::NEWSLETTER_TYPE === $contactType) {
  57.                 $encryptedString $this->encrypter->encrypt($data);
  58.                 $data array_merge($data, [
  59.                     'localeCode' => $localeCode,
  60.                     'url' => $this->router->generate(
  61.                         'app_newsletter_confirm',
  62.                         [
  63.                             'token' => urlencode($encryptedString),
  64.                         ],
  65.                         RouterInterface::ABSOLUTE_URL
  66.                     ),
  67.                 ]);
  68.                 $this->contactEmailManager->sendNewsletterConfirmationEmail($data);
  69.             } else {
  70.                 $this->contactEmailManager->sendContactRequest($data, [$contactEmail], $channel$localeCode);
  71.             }
  72.             $successMessage $this->getSyliusAttribute(
  73.                 $request,
  74.                 'success_flash',
  75.                 'sylius.contact.request_success',
  76.             );
  77.             /** @var FlashBagInterface $flashBag */
  78.             $flashBag $request->getSession()->getBag('flashes');
  79.             $flashBag->add('success'$successMessage);
  80.             $redirectRoute $this->getSyliusAttribute($request'redirect'null);
  81.             return new RedirectResponse(null === $redirectRoute
  82.                 $request->headers->get('referer') ?? '/'
  83.                 $this->router->generate($redirectRoute))
  84.             ;
  85.         }
  86.         if ($form->isSubmitted() && !$form->isValid()) {
  87.             /** @var FlashBagInterface $flashBag */
  88.             $flashBag $request->getSession()->getBag('flashes');
  89.             $flashBag->add('error''open_marketplace.contact.form_invalid');
  90.         }
  91.         $template $this->getSyliusAttribute($request'template'$this->resolveTemplate($contactType));
  92.         Assert::notNull($template'Invalid template');
  93.         return new Response($this->templatingEngine->render($template, ['form' => $form->createView()]));
  94.     }
  95.     public function newsletterConfirmAction(Request $request): Response
  96.     {
  97.         $token = (string) $request->get('token');
  98.         if ($this->redis->get(self::NEWSLETTER_TOKEN_KEY_STORAGE_PREFIX $token)) {
  99.             return new RedirectResponse($this->router->generate('sylius_shop_homepage'));
  100.         }
  101.         $channel $this->channelContext->getChannel();
  102.         Assert::isInstanceOf($channelChannelInterface::class);
  103.         $contactEmail $channel->getContactEmail();
  104.         if (null === $contactEmail) {
  105.             return $this->prepareRedirectOnMissingContactEmail($request);
  106.         }
  107.         $localeCode $this->localeContext->getLocaleCode();
  108.         $data $this->encrypter->decrypt($token);
  109.         $this->contactExporter->export($this->createCustomer($data));
  110.         $this->contactEmailManager->sendContactRequest($data, [$contactEmail], $channel$localeCode);
  111.         $successMessage $this->getSyliusAttribute(
  112.             $request,
  113.             'success_flash',
  114.             'sylius.contact.request_success',
  115.         );
  116.         /** @var FlashBagInterface $flashBag */
  117.         $flashBag $request->getSession()->getBag('flashes');
  118.         $flashBag->add('success'$successMessage);
  119.         $this->redis->set(self::NEWSLETTER_TOKEN_KEY_STORAGE_PREFIX $tokentrue);
  120.         return new RedirectResponse($this->router->generate('sylius_shop_homepage'));
  121.     }
  122.     private function getSyliusAttribute(
  123.         Request $request,
  124.         string $attributeName,
  125.         ?string $default
  126.     ): ?string {
  127.         $attributes $request->attributes->get('_sylius');
  128.         return $attributes[$attributeName] ?? $default;
  129.     }
  130.     private function getFormOptions(string $type): array
  131.     {
  132.         return [
  133.             ContactType::CONTACT_TYPE => $type,
  134.             'validation_groups' => $type,
  135.         ];
  136.     }
  137.     private function resolveTemplate(mixed $contactType): string
  138.     {
  139.         if (ContactTypes::TECH_ADVISORY_TYPE === $contactType) {
  140.             return 'Context/TechAdvisory/index.html.twig';
  141.         }
  142.         if (ContactTypes::NEWSLETTER_TYPE === $contactType) {
  143.             return 'Context/Newsletter/index.html.twig';
  144.         }
  145.         return '@SyliusShop/Contact/request.html.twig';
  146.     }
  147.     private function prepareRedirectOnMissingContactEmail(Request $request): RedirectResponse
  148.     {
  149.         $errorMessage $this->getSyliusAttribute(
  150.             $request,
  151.             'error_flash',
  152.             'sylius.contact.request_error',
  153.         );
  154.         /** @var FlashBagInterface $flashBag */
  155.         $flashBag $request->getSession()->getBag('flashes');
  156.         $flashBag->add('error'$errorMessage);
  157.         return new RedirectResponse($request->headers->get('referer') ?? '/');
  158.     }
  159.     private function createCustomer(array $data): CustomerInterface
  160.     {
  161.         $customer = new Customer();
  162.         $customer->setEmail($data['email']);
  163.         $customer->setFirstName($data['firstName']);
  164.         $customer->setLastName($data['lastName']);
  165.         $customer->setPhoneNumber($data['phoneNumber']);
  166.         return $customer;
  167.     }
  168. }