<?php declare(strict_types=1);
namespace Samson\Controller;
/***
*
* This file is part of the "SAMSON Shop" project.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* (c) 2021
*
***/
use Exception;
use Samson\Exception\CustomerNeedsPasswordChangeException;
use Samson\Pages\NE53Newsletter\NE53NewsletterPage;
use Samson\Pages\NE53Newsletter\NE53NewsletterPageLoader;
use Samson\Route\NE53Newsletter\AbstractNE53NewsletterChangeRoute;
use Samson\Route\NE53Newsletter\AbstractNE53NewsletterConfirmRoute;
use Samson\Route\NE53Newsletter\AbstractNE53NewsletterSubscribeRoute;
use Samson\Route\NE53Newsletter\AbstractNE53NewsletterUnsubscribeRoute;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\Content\Newsletter\Exception\NewsletterRecipientNotFoundException;
use Shopware\Core\Content\Newsletter\SalesChannel\AbstractNewsletterConfirmRoute;
use Shopware\Core\Content\Newsletter\SalesChannel\AbstractNewsletterSubscribeRoute;
use Shopware\Core\Content\Newsletter\SalesChannel\AbstractNewsletterUnsubscribeRoute;
use Shopware\Core\Content\Newsletter\SalesChannel\NewsletterSubscribeRoute;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
use Shopware\Core\Framework\Validation\DataBag\QueryDataBag;
use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
use Shopware\Core\Framework\Validation\Exception\ConstraintViolationException;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Framework\Routing\RequestTransformer;
use Shopware\Storefront\Page\Newsletter\Subscribe\NewsletterSubscribePageLoader;
use Shopware\Storefront\Pagelet\Newsletter\Account\NewsletterAccountPageletLoader;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Samson\Annotation\CustomerNeedsPasswordChange;
use Shopware\Core\Framework\Routing\Annotation\Since;
use Shopware\Core\Framework\Routing\Annotation\LoginRequired;
use Shopware\Storefront\Controller\NewsletterController as ShopwareNewsletterController;
use Throwable;
use function Sentry\captureException;
/**
* @RouteScope(scopes={"storefront"})
*/
class NewsletterController extends ShopwareNewsletterController
{
private AbstractNE53NewsletterConfirmRoute $NE53NewsletterConfirmRoute;
private NewsletterSubscribePageLoader $newsletterConfirmRegisterPageLoader;
private AbstractNE53NewsletterSubscribeRoute $NE53NewsletterSubscribeRoute;
private AbstractNE53NewsletterUnsubscribeRoute $NE53NewsletterUnsubscribeRoute;
private NE53NewsletterPageLoader $NE53NewsletterPageLoader;
private AbstractNE53NewsletterChangeRoute $NE53NewsletterChangeRoute;
public function __construct(NewsletterSubscribePageLoader $newsletterConfirmRegisterPageLoader,
EntityRepositoryInterface $customerRepository,
AbstractNewsletterSubscribeRoute $newsletterSubscribeRoute,
AbstractNewsletterConfirmRoute $newsletterConfirmRoute,
AbstractNewsletterUnsubscribeRoute $newsletterUnsubscribeRoute,
NewsletterAccountPageletLoader $newsletterAccountPageletLoader,
AbstractNE53NewsletterConfirmRoute $NE53NewsletterConfirmRoute,
AbstractNE53NewsletterSubscribeRoute $NE53NewsletterSubscribeRoute,
AbstractNE53NewsletterUnsubscribeRoute $NE53NewsletterUnsubscribeRoute,
NE53NewsletterPageLoader $NE53NewsletterPageLoader,
AbstractNE53NewsletterChangeRoute $NE53NewsletterChangeRoute)
{
parent::__construct($newsletterConfirmRegisterPageLoader,
$customerRepository,
$newsletterSubscribeRoute,
$newsletterConfirmRoute,
$newsletterUnsubscribeRoute,
$newsletterAccountPageletLoader);
$this->NE53NewsletterConfirmRoute = $NE53NewsletterConfirmRoute;
$this->newsletterConfirmRegisterPageLoader = $newsletterConfirmRegisterPageLoader;
$this->NE53NewsletterSubscribeRoute = $NE53NewsletterSubscribeRoute;
$this->NE53NewsletterUnsubscribeRoute = $NE53NewsletterUnsubscribeRoute;
$this->NE53NewsletterPageLoader = $NE53NewsletterPageLoader;
$this->NE53NewsletterChangeRoute = $NE53NewsletterChangeRoute;
}
/**
* @Since("6.0.0.0")
* @CustomerNeedsPasswordChange()
* @Route("/newsletter-subscribe", name="frontend.newsletter.subscribe", methods={"GET"})
* @throws Exception
* @throws CustomerNeedsPasswordChangeException
*/
public function subscribeMail(SalesChannelContext $context, Request $request, QueryDataBag $queryDataBag): Response
{
return parent::subscribeMail($context, $request, $queryDataBag);
}
/**
* @Since("6.0.0.0")
* @LoginRequired()
* @CustomerNeedsPasswordChange()
* @Route("/widgets/account/newsletter", name="frontend.account.newsletter", methods={"POST"}, defaults={"XmlHttpRequest"=true})
*
* @throws CustomerNeedsPasswordChangeException
*/
public function subscribeCustomer(Request $request, RequestDataBag $dataBag, SalesChannelContext $context, CustomerEntity $customer): Response
{
return parent::subscribeCustomer($request, $dataBag, $context, $customer);
}
/**
* @Route("/newsletter/ne53/register", name="frontend.newsletter.ne53.register.handle", options={"seo"="false"}, methods={"POST"}, defaults={"XmlHttpRequest"=true})
*/
public function handleNE53Newsletter(RequestDataBag $data, Request $request, SalesChannelContext $salesChannelContext): Response
{
$subscribe = $data->get('option') === NewsletterSubscribeRoute::OPTION_SUBSCRIBE;
if ($subscribe) {
$response = $this->handleNE53Subscribe($request, $data, $salesChannelContext);
} else {
$response = $this->handleNE53Unsubscribe($data, $salesChannelContext);
}
return new JsonResponse($response);
}
/**
* @Route("/newsletter/ne53/form/unsubscribe", name="frontend.newsletter.ne53.form.unsubscribe", options={"seo"="false"}, methods={"GET"}, defaults={"XmlHttpRequest"=true})
* @Route("/newsletter/ne53/form/change", name="frontend.newsletter.ne53.form.change", options={"seo"="false"}, methods={"GET"}, defaults={"XmlHttpRequest"=true})
*/
public function showNE53NewsletterFormType(Request $request, SalesChannelContext $salesChannelContext): Response
{
$unsubscribe = $request->get('unsubscribe');
$changeForm = $request->get('changeForm');
/** @var NE53NewsletterPage $page */
try {
$page = $this->NE53NewsletterPageLoader->load($request, $salesChannelContext);
} catch (Exception $exception) {
captureException($exception);
$this->addFlash(self::DANGER, $this->trans('samson.ne53-newsletter.error.an-error-occurred'));
return $this->forwardToRoute('frontend.home.page');
}
return $this->renderStorefront('@Storefront/storefront/page/ne53-newsletter/index.html.twig',
[
'page' => $page,
'unsubscribe' => $unsubscribe,
'changeForm' => $changeForm
]);
}
/**
* @Route("/newsletter/ne53/form/change", name="frontend.newsletter.ne53.change.handle", options={"seo"="false"}, methods={"POST"}, defaults={"XmlHttpRequest"=true})
*/
public function handleNE53NewsletterChangeForm(Request $request, SalesChannelContext $salesChannelContext): Response
{
$page = $this->NE53NewsletterPageLoader->load($request, $salesChannelContext);
/** @var NE53NewsletterPage $page */
try {
$page = $this->NE53NewsletterPageLoader->loadNewsletterData($request, $salesChannelContext);
} catch (NewsletterRecipientNotFoundException $exception) {
captureException($exception);
$this->addFlash(self::DANGER, $this->trans('samson.ne53-newsletter.error.email-address-not-found'));
return $this->renderStorefront('@Storefront/storefront/page/ne53-newsletter/index.html.twig',
[
'page' => $page,
'unsubscribe' => false,
'changeForm' => true
]);
} catch (Exception $exception) {
captureException($exception);
$this->addFlash(self::DANGER, $this->trans('samson.ne53-newsletter.error.an-error-occurred'));
return $this->renderStorefront('@Storefront/storefront/page/ne53-newsletter/index.html.twig',
[
'page' => $page,
'unsubscribe' => false,
'changeForm' => true
]);
}
return $this->renderStorefront('@Storefront/storefront/page/ne53-newsletter/index.html.twig',
[
'page' => $page,
'change' => true
]);
}
/**
* @Route("/newsletter/ne53/change", name="frontend.newsletter.ne53.change", options={"seo"="false"}, methods={"POST"}, defaults={"XmlHttpRequest"=true})
*/
public function changeNE53Newsletter(Request $request, SalesChannelContext $salesChannelContext): Response
{
try {
$this->NE53NewsletterChangeRoute->change($request, $salesChannelContext);
$response[] = [
'type' => 'info',
'alert' => $this->renderView('@Storefront/storefront/utilities/alert.html.twig', [
'type' => 'info',
'list' => [$this->trans('samson.ne53-newsletter.change.information')],
])];
} catch (Exception $e) {
captureException($e);
$response[] = [
'type' => 'danger',
'alert' => $this->renderView('@Storefront/storefront/utilities/alert.html.twig', [
'type' => 'danger',
'list' => [$this->trans('error.message-default')],
]),
];
}
return new JsonResponse($response);
}
/**
* @Route("/newsletter-ne53-subscribe", name="frontend.newsletter.ne53.subscribe", methods={"GET"})
* @throws Exception
*/
public function subscribeNE53Mail(SalesChannelContext $context, Request $request, QueryDataBag $queryDataBag): Response
{
try {
$this->NE53NewsletterConfirmRoute->confirm($queryDataBag->toRequestDataBag(), $context);
} catch (Throwable $throwable) {
$this->addFlash(self::DANGER, $this->trans('newsletter.subscriptionConfirmationFailed'));
throw new Exception($throwable->getMessage(), $throwable->getCode(), $throwable);
}
$page = $this->newsletterConfirmRegisterPageLoader->load($request, $context);
return $this->renderStorefront('@Storefront/storefront/page/newsletter/confirm-subscribe.html.twig', ['page' => $page]);
}
/**
* @Route("/newsletter/off-canvas/subscription", name="frontend.newsletter.off-canvas.subscription", options={"seo"="false"}, methods={"GET"}, defaults={"XmlHttpRequest"=true})
* @param SalesChannelContext $context
* @return Response
*/
public function subscription(SalesChannelContext $context): Response
{
$customer = $context->getCustomer();
$newsletter = false;
return $this->renderStorefront(
'@SamsonCustomer/storefront/module/newsletter/subscription.html.twig',
[
'customer' => $customer,
'newsletter' => $newsletter
]
);
}
private function handleNE53Subscribe(Request $request, RequestDataBag $data, SalesChannelContext $context): array
{
try {
$data->set('storefrontUrl', $request->attributes->get(RequestTransformer::STOREFRONT_URL));
$this->NE53NewsletterSubscribeRoute->subscribe($data, $context, false);
$response[] = [
'type' => 'info',
'alert' => $this->renderView('@Storefront/storefront/utilities/alert.html.twig', [
'type' => 'info',
'list' => [$this->trans('samson.newsletter.subscriptionPersistedInfo')],
]),
];
} catch (ConstraintViolationException $exception) {
$errors = [];
foreach ($exception->getViolations() as $error) {
$errors[] = $error->getMessage();
}
$response[] = [
'type' => 'danger',
'alert' => $this->renderView('@Storefront/storefront/utilities/alert.html.twig', [
'type' => 'danger',
'list' => $errors,
]),
];
} catch (Exception $exception) {
captureException($exception);
$response[] = [
'type' => 'danger',
'alert' => $this->renderView('@Storefront/storefront/utilities/alert.html.twig', [
'type' => 'danger',
'list' => [$this->trans('error.message-default')],
]),
];
}
return $response;
}
private function handleNE53Unsubscribe(RequestDataBag $data, SalesChannelContext $context): array
{
try {
$this->NE53NewsletterUnsubscribeRoute->unsubscribe($data, $context);
$response[] = [
'type' => 'success',
'alert' => $this->trans('newsletter.subscriptionRevokeSuccess'),
];
} catch (ConstraintViolationException $exception) {
$errors = [];
foreach ($exception->getViolations() as $error) {
$errors[] = $error->getMessage();
}
$response[] = [
'type' => 'danger',
'alert' => $this->renderView('@Storefront/storefront/utilities/alert.html.twig', [
'type' => 'danger',
'list' => $errors,
]),
];
} catch (Exception $exception) {
captureException($exception);
$response = [];
}
return $response;
}
}