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

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