<?php
namespace App\Controller\Shop;
use App\Entity\ContactRequest;
use App\Entity\User\AdminUser;
use Doctrine\ORM\EntityManagerInterface;
use Sylius\Bundle\CoreBundle\Form\Type\ContactType;
use Sylius\Component\Channel\Context\ChannelContextInterface;
use Sylius\Component\Core\Model\ChannelInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mailer\Mailer;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;
use Twig\Environment;
use Twig\Error\LoaderError;
use Twig\Error\RuntimeError;
use Twig\Error\SyntaxError;
use Webmozart\Assert\Assert;
final class ContactController extends AbstractController
{
/** @var EngineInterface|Environment */
private Environment $templatingEngine;
/** @var ChannelContextInterface */
private ChannelContextInterface $channelContext;
/** @var EntityManagerInterface */
private EntityManagerInterface $em;
/** @var Mailer */
private MailerInterface $mailer;
/**
* @param Environment $templatingEngine
* @param ChannelContextInterface $channelContext
* @param EntityManagerInterface $em
* @param MailerInterface $mailer
*/
public function __construct(Environment $templatingEngine, ChannelContextInterface $channelContext, EntityManagerInterface $em, MailerInterface $mailer)
{
$this->templatingEngine = $templatingEngine;
$this->channelContext = $channelContext;
$this->em = $em;
$this->mailer = $mailer;
}
/**
* @param Request $request
* @return Response
* @throws LoaderError
* @throws RuntimeError
* @throws SyntaxError
* @throws TransportExceptionInterface
*/
public function requestAction(Request $request): Response
{
$form = $this->createForm(ContactType::class, new ContactRequest());
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$contactRequest = $form->getData();
$channel = $this->channelContext->getChannel();
/** @var ChannelInterface $channel */
Assert::isInstanceOf($channel, ChannelInterface::class);
$admins = $this->em->getRepository(AdminUser::class)->findAll();
foreach ($admins as $admin) {
$adminEmails[] = $admin->getEmail();
}
$this->em->persist($contactRequest);
$this->em->flush();
if (empty($adminEmails)) {
$errorMessage = $this->getSyliusAttribute(
$request,
'error_flash',
'sylius.contact.request_error'
);
/** @var FlashBagInterface $flashBag */
$flashBag = $request->getSession()->getBag('flashes');
$flashBag->add('error', $errorMessage);
return new RedirectResponse($request->headers->get('referer'));
}
$this->sendContactRequestMail($adminEmails, $contactRequest->getSubject(), $contactRequest->getMessage());
$successMessage = $this->getSyliusAttribute(
$request,
'success_flash',
'sylius.contact.request_success'
);
/** @var FlashBagInterface $flashBag */
$flashBag = $request->getSession()->getBag('flashes');
$flashBag->add('success', $successMessage);
return new RedirectResponse($request->headers->get('referer'));
}
$template = $this->getSyliusAttribute($request, 'template', '@SyliusShop/Contact/request.html.twig');
return new Response($this->templatingEngine->render($template, ['form' => $form->createView()]));
}
/**
* @param Request $request
* @param string $attributeName
* @param string|null $default
* @return string|null
*/
private function getSyliusAttribute(Request $request, string $attributeName, ?string $default): ?string
{
$attributes = $request->attributes->get('_sylius');
return $attributes[$attributeName] ?? $default;
}
/**
* @param array $adminEmails
* @param string $subject
* @param string $message
* @return void
* @throws TransportExceptionInterface
*/
public function sendContactRequestMail(array $adminEmails, string $subject, string $message): void
{
foreach ($adminEmails as $adminEmail) {
$email = (new Email)
->to($adminEmail)
->subject($subject)
->text('Nouvelle demande de contact: ' . $message)
;
$this->mailer->send($email);
}
}
}