<?php
namespace Virgin\LeadManager\Storefront\Controller;
use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
use Shopware\Core\Checkout\Customer\SalesChannel\AbstractLogoutRoute;
use Shopware\Core\Content\Category\SalesChannel\AbstractCategoryRoute;
use Shopware\Core\Content\Cms\Exception\PageNotFoundException;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Shopware\Core\Framework\Routing\Exception\MissingRequestParameterException;
use Shopware\Storefront\Page\GenericPageLoader;
use Symfony\Component\HttpFoundation\Response;
use Monolog\Logger;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Symfony\Component\Routing\Annotation\Route;
use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
use Shopware\Core\Framework\Validation\DataValidationDefinition;
use Shopware\Core\Framework\Validation\Exception\ConstraintViolationException;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Controller\StorefrontController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Validator\Constraints\Email;
use Virgin\LeadManager\Service\AccountRegistrationServiceDecorator;
use Virgin\LeadManager\Utils\Services\LeadGenerationService;
use Virgin\LeadManager\Utils\UserActivationHelper;
use Virgin\SystemIntegration\Services\RestApiClient;
use Virgin\SystemIntegration\Services\VirginUser\VirginUser;
/**
* @Route(defaults={"_routeScope"={"storefront"}})
*/
class VirginRegisterController extends StorefrontController
{
/**
* @var AccountRegistrationServiceDecorator
*/
private AccountRegistrationServiceDecorator $accountRegistrationService;
/**
* @var EntityRepository
*/
private EntityRepository $customerRepository;
/**
* @var Logger
*/
private Logger $logger;
/**
* @var GenericPageLoader
*/
private $genericLoader;
/**
* @var EntityRepository
*/
private EntityRepository $clubRepository;
/**
* @var AbstractLogoutRoute
*/
private AbstractLogoutRoute $logoutRoute;
/**
* @var VirginUser
*/
private VirginUser $virginUser;
/**
* @var AbstractCategoryRoute
*/
private AbstractCategoryRoute $categoryRoute;
/**
* @var EntityRepository
*/
private EntityRepository $categoryRepository;
/**
* @var RestApiClient
*/
private RestApiClient $restApiClient;
/**
* @var RouterInterface
*/
private RouterInterface $router;
/**
* @var CartService
*/
private CartService $cartService;
public function __construct(
AccountRegistrationServiceDecorator $accountRegistrationService,
EntityRepository $customerRepository,
Logger $logger,
GenericPageLoader $genericLoader,
EntityRepository $clubRepository,
VirginUser $virginUser,
AbstractCategoryRoute $categoryRoute,
EntityRepository $categoryRepository,
RestApiClient $restApiClient,
AbstractLogoutRoute $logoutRoute,
RouterInterface $router,
CartService $cartService
)
{
$this->accountRegistrationService = $accountRegistrationService;
$this->customerRepository = $customerRepository;
$this->logger = $logger;
$this->genericLoader = $genericLoader;
$this->clubRepository = $clubRepository;
$this->virginUser = $virginUser;
$this->categoryRoute = $categoryRoute;
$this->categoryRepository = $categoryRepository;
$this->restApiClient = $restApiClient;
$this->logoutRoute = $logoutRoute;
$this->router = $router;
$this->cartService = $cartService;
}
/**
* @Route("/account/register", name="frontend.account.register.page", methods={"GET"})
*/
public function showRegisterPage(Request $request, RequestDataBag $data, SalesChannelContext $context)
{
$this->logger->log(Logger::DEBUG, 'Contact form request - print data');
$customer = $context->getCustomer();
if (isset($customer)) {
if (isset($customer->getCustomFields()['lead_implicit_registration'])) {
return $this->redirectToRoute('frontend.home.page');
}
}
$page = $this->genericLoader->load($request, $context);
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('visible', true));
$criteria->addSorting(new FieldSorting('club.name', FieldSorting::ASCENDING));
$clubs = $this->container->get('club.repository')->search($criteria, $context->getContext())->getEntities()->getElements();
return $this->renderStorefront('@Storefront/storefront/page/virgin-login-registration.html.twig', [
'clubs' => $clubs,
'page' => $page,
'loginError' => (bool)$request->get('loginError'),
'errorSnippet' => $request->get('errorSnippet'),
'successSnippet' => $request->get('successSnippet'),
'warningSnippet' => $request->get('warningSnippet') ?? $request->getSession()->get('warningSnippet'),
]);
}
/**
* @Route("/account/register", name="frontend.account.register.save", methods={"POST"})
* @throws \DateMalformedStringException
*/
public function virginRegister(Request $request, RequestDataBag $data, SalesChannelContext $context)
{
$this->logger->log(Logger::DEBUG, 'Registration form submit data: ' . serialize($data));
$page = $this->genericLoader->load($request, $context);
$firstname = $data->get('name');
$lastname = $data->get('lastname');
$phonePrefix = $data->get('intlPrefix');
$phone = $data->get('phone');
$email = $data->get('email');
$club = $data->get('club');
$privacy = $data->get('privacy');
$zipcode = $data->get('zipcode');
$route = $request->getPathInfo();
$validation = new DataValidationDefinition('customer.email');
$validation->add('email', new Email());
// ------ Validation Form ------------
$redirectObject = $this->virginUser->CheckFormParamsToStorefront($data, $page, '@Storefront/storefront/page/virgin-login-registration.html.twig');
if ($redirectObject != null) {
if ($data->get('isComingFromVirginCustomRegistrationForm')) {
return $this->json(
[
'errorSnippet' => $this->trans($redirectObject['errorSnippet']),
'status' => 'ko'
]
);
} else {
return $this->redirectToRoute('frontend.account.register.page', [
'loginError' => true,
'errorSnippet' => $this->trans($redirectObject['errorSnippet']),
]);
}
}
setcookie(LeadGenerationService::ECOMMERCE_COOKIE_NAME, '', time() - 3600);
$contactFormParams['route'] = $request->getPathInfo();
$contactFormParams['email'] = $email;
$contactFormParams['firstName'] = $firstname;
$contactFormParams['lastName'] = $lastname;
$contactFormParams['phone'] = $phone;
$contactFormParams['privacy'] = $privacy;
$contactFormParams['club'] = $club;
$contactFormParams['page'] = $page;
$contactFormParams['zipcode'] = $zipcode ?? null;
$this->virginUser->checkPerson($email);
$redirectObject = $this->virginUser->handlePerson($contactFormParams, $context, VirginUser::FORM_REGISTER);
if ($redirectObject['errorSnippet'] != 'lead-manager.form.message.successRegistration' && !isset($redirectObject['implicit']) && !isset($redirectObject['active'])) {
$redirectObject['params']['errorSnippet'] = $this->trans($redirectObject['errorSnippet']);
if ($data->get('isComingFromVirginCustomRegistrationForm')) {
return $this->json(
[
'errorSnippet' => $redirectObject['params']['errorSnippet'],
'status' => 'ko'
]
);
}
if (isset($redirectObject['renderStorefront']) && $redirectObject['renderStorefront']) {
return $this->renderStorefront($redirectObject['route'], $redirectObject['params']);
}
return $this->redirectToRoute($redirectObject['route'], $redirectObject['params']);
}
//registration from landing page
if ($data->get('isComingFromVirginCustomRegistrationForm')) {
return $this->json(
[
'status' => 'ok',
'clubName' => $this->getClubNameForPromoLandingPage($club),
]
);
}
if (isset($club)) {
return $this->redirectToRoute('frontend.configurator');
} else {
$digitalCategoryCriteria = new Criteria();
$digitalCategoryCriteria->addFilter(new EqualsFilter('category.tags.name', 'digitale'));
$navigationId = $this->categoryRepository->searchIds($digitalCategoryCriteria,
Context::createDefaultContext())->firstId();
if (!$navigationId) {
throw new MissingRequestParameterException('Parameter navigationId missing');
}
$category = $this->categoryRoute->load($navigationId, $request, $context)->getCategory();
if (!$category->getCmsPageId()) {
throw new PageNotFoundException('');
}
return $this->redirectToRoute('frontend.navigation.page', ['navigationId' => $navigationId]);
}
}
/**
* @Route("/account/accountActivation", name="frontend.account.activation.account.page", methods={"GET"})
*/
public function accountActivationPage(Request $request, RequestDataBag $data, SalesChannelContext $context)
{
$email = $request->get('email');
$activationCode = $request->get('activationCode');
$redirectTo = $request->get('redirectTo');
$redirectUrl = $request->get('redirectUrl');
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('customer.email', $email));
$criteria->addFilter(new EqualsFilter('customer.active', false));
/** @var CustomerEntity $customerEntity */
$customerEntity = $this->customerRepository->search($criteria, $context->getContext())->first();
if (!is_null($customerEntity) && $customerEntity->getCustomFields()['activationCode'] == $activationCode) {
UserActivationHelper::activateccount($context, $this->customerRepository, $customerEntity->getId());
return $this->redirectToRoute('frontend.account.login.page', [
'loginError' => false,
'successSnippet' => $this->trans('lead-manager.form.message.confirmationAccountSuccess'),
]);
}
return $this->redirectToRoute('frontend.account.login.page', [
'loginError' => true,
'errorSnippet' => $this->trans('lead-manager.form.message.confirmationAccountFailed'),
]);
}
/**
* @Route("/account/login", name="frontend.account.login.page", methods={"GET"})
*/
public function showLoginPage(Request $request, RequestDataBag $data, SalesChannelContext $context)
{
$customer = $context->getCustomer();
if (isset($customer)) {
return $this->redirectToRoute('frontend.configurator');
}
$page = $this->genericLoader->load($request, $context);
return $this->renderStorefront('@Storefront/storefront/page/login.html.twig', [
'page' => $page,
'loginError' => (bool)$request->get('loginError'),
'errorSnippet' => $request->get('errorSnippet'),
'successSnippet' => $request->get('successSnippet'),
'warningSnippet' => $request->get('warningSnippet') ?? $request->getSession()->get('warningSnippet'),
]);
}
/**
* @Route("/account/login", name="frontend.account.login", methods={"POST"}, defaults={"XmlHttpRequest" = true})
*/
public function login(Request $request, RequestDataBag $data, SalesChannelContext $context): \Symfony\Component\HttpFoundation\Response
{
if (isset($_SESSION['accountLoginRequestDataBag'])) {
unset($_SESSION['accountLoginRequestDataBag']);
}
$email = $data->get('username');
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('customer.email', $email));
$response = $this->virginUser->LoginManager($data, $context);
$this->cartService->deleteCart($context);
if ($response) {
if($response['login']) {
switch($response['personType']) {
case VirginUser::PERSONTYPE_EXSOCIO:
if (isset($_SESSION['destination'])) {
$this->addRedirectsForDestination($request);
} else {
$request->getSession()->remove('warningSnippet');
$request->request->add(['redirectTo' => 'frontend.configurator']);
}
break;
case VirginUser::PERSONTYPE_INSOLUTO:
if (isset($_SESSION['destination'])) {
$this->addRedirectsForDestination($request);
} else {
$request->request->add(['redirectTo' => 'frontend.insoluto']);
}
break;
case VirginUser::PERSONTYPE_BLACKLIST:
$request->request->add(['redirectTo' => 'frontend.blacklist']);
break;
case VirginUser::PERSONTYPE_SOCIO:
if (isset($_SESSION['destination'])) {
$this->addRedirectsForDestination($request);
} else {
$request->request->add(['redirectTo' => 'frontend.account.subscription.page']);
}
break;
case VirginUser::PERSONTYPE_DROPECCEZ:
case VirginUser::PERSONTYPE_NN:
$request->request->add(['redirectTo' => 'frontend.account.profile.page']);
break;
}
return $this->createActionResponse($request);
} else {
return $this->forwardToRoute(
'frontend.account.login.page',
[
'loginError' => true,
'errorSnippet' => $response['errorMessage'],
]
);
}
} else {
return $this->forwardToRoute(
'frontend.account.login.page',
[
'loginError' => true,
'errorSnippet' => $errorSnippet ?? null,
]
);
}
}
/**
* @Route("/account/logout", name="frontend.account.logout.page", methods={"GET"})
*/
public function logout(Request $request, SalesChannelContext $context): Response
{
$request->getSession()->clear();
if (isset($_SESSION['accountLoginRequestDataBag'])) {
unset($_SESSION['accountLoginRequestDataBag']);
unset($_SESSION['forcedLoginAttempt']);
unset($_SESSION['customerEntity']);
}
if ($context->getCustomer() === null) {
return $this->redirectToRoute('frontend.account.login.page');
}
try {
$this->cartService->deleteCart($context);
$this->logoutRoute->logout($context);
$this->addFlash('success', $this->trans('account.logoutSucceeded'));
if (isset($_COOKIE[LeadGenerationService::ECOMMERCE_COOKIE_NAME])) {
unset($_COOKIE[LeadGenerationService::ECOMMERCE_COOKIE_NAME]);
setcookie(LeadGenerationService::ECOMMERCE_COOKIE_NAME, '', time() - 3600, '/'); // empty value and old timestamp
}
$parameters = [];
} catch (ConstraintViolationException $formViolations) {
$parameters = ['formViolations' => $formViolations];
}
if(!empty($_SESSION['mc_code'])) {
unset($_SESSION['mc_code']);
}
return $this->redirectToRoute('frontend.account.login.page', $parameters);
}
/**
* @Route("/noscript", name="frontend.noscript", methods={"GET"})
*/
public function noscript(Request $request, SalesChannelContext $context): Response
{
return new Response("
<html>
<head></head>
<body>
Please enable javascript in order to use the website and refresh this page -
Per favore abilitare il javascript per poter utilizzare il sito e ricaricare la pagina
</body>
<script>
window.location.href = '/';
</script>
</html>
");
}
/**
* @param Request $request
*/
private function addRedirectsForDestination(Request $request)
{
if (AccountVantaggiSociController::VANTAGGI_INDEX_PAGE === $_SESSION['destination']) {
$request->request->add(
[
'redirectTo' => 'frontend.account.vantaggi.page',
]
);
unset($_SESSION['destination']);
} else {
$request->request->add(
[
'redirectTo' => 'frontend.account.vantaggi.detail.page',
'redirectParameters' => ['partner' => $_SESSION['sociPartnerName']]
]
);
unset($_SESSION['destination'], $_SESSION['sociPartnerName']);
}
}
/**
* @return string
*/
private function getClubNameForPromoLandingPage(string $clubId)
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('club.id', $clubId));
$club = $this->clubRepository->search($criteria, Context::createDefaultContext())->first();
return str_replace(" ", "-", strtolower(trim($club->getName())));
}
}