<?php
declare(strict_types=1);
namespace NetInventors\NetiNextAccessManager\Subscriber;
use NetInventors\NetiNextAccessManager\Constants\ConfigConstants;
use NetInventors\NetiNextAccessManager\Extension\Content\Customer\Aggregate\CustomerAttribute\CustomerAttributeEntity;
use NetInventors\NetiNextAccessManager\Service\PluginConfig;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\Checkout\Customer\Event\CustomerLoginEvent;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\RouterInterface;
class LoginSubscriber implements EventSubscriberInterface
{
/**
* @var bool
*/
private $allowlogin;
/**
* @var bool
*/
private $afterLogin = false;
/**
* @var RouterInterface
*/
protected $router;
/**
* @var EntityRepositoryInterface
*/
protected $customerRepository;
/**
* @var PluginConfig
*/
protected $pluginConfig;
/**
* LoginSubscriber constructor.
*
* @param RouterInterface $router
* @param EntityRepositoryInterface $customerRepository
* @param PluginConfig $pluginConfig
*/
public function __construct(
RouterInterface $router,
EntityRepositoryInterface $customerRepository,
PluginConfig $pluginConfig
) {
$this->router = $router;
$this->customerRepository = $customerRepository;
$this->pluginConfig = $pluginConfig;
}
public static function getSubscribedEvents(): array
{
return [
CustomerLoginEvent::class => 'onCustomerLogin',
KernelEvents::RESPONSE => 'onResponse',
];
}
/**
* @param CustomerLoginEvent $event
*/
public function onCustomerLogin(CustomerLoginEvent $event): void
{
if (!$this->pluginConfig->isActive()) {
return;
}
$customerId = $event->getCustomer()->getId();
//The customer from the event has a not updated Attribute so we have to get an updated Customer
$customer = $this->getUpdatedCustomer($customerId, $event->getContext());
/** @var CustomerAttributeEntity $amAttribute */
$amAttribute = $customer->getExtension('netiAccessManagerCustomerAttribute');
$this->allowlogin = $amAttribute->isActivated();
$this->afterLogin = true;
}
public function onResponse(ResponseEvent $event): void
{
if (!$this->pluginConfig->isActive()) {
return;
}
if (false === $this->allowlogin) {
$response = new RedirectResponse(
$this->router->generate('frontend.access_manager.logout')
);
$event->setResponse($response);
}
if ($this->pluginConfig->getLoginRedirectType() === ConfigConstants::CONFIG_REDIRECT_TYPE_DEFAULT) {
return;
}
if ($this->pluginConfig->getLoginRedirectType() === ConfigConstants::CONFIG_REDIRECT_TYPE_REFERER) {
if ($this->afterLogin === true) {
$redirect = $event->getRequest()->getSession()->get('neti-access-manager-referer');
if ($redirect['route'] === 'frontend.account.logout.page') {
return;
}
$response = new RedirectResponse(
$this->router->generate($redirect['route'], $redirect['routeParams'])
);
$event->setResponse($response);
return;
}
$referer['route'] = $event->getRequest()->attributes->get('_route');
$referer['routeParams'] = $event->getRequest()->attributes->get('_route_params');
if ($referer['route'] !== 'frontend.account.login.page' && $referer['route'] !== 'frontend.checkout.info') {
$event->getRequest()->getSession()->set('neti-access-manager-referer', $referer);
}
}
if ($this->afterLogin === false) {
return;
}
if (
$this->pluginConfig->getLoginRedirectType() === ConfigConstants::CONFIG_REDIRECT_TYPE_CATEGORY
&& $this->pluginConfig->getLoginRedirectCategory() !== ''
) {
$response = new RedirectResponse(
$this->router->generate(
'frontend.navigation.page',
[ 'navigationId' => $this->pluginConfig->getLoginRedirectCategory() ]
)
);
$event->setResponse($response);
return;
}
if (
$this->pluginConfig->getLoginRedirectType() === ConfigConstants::CONFIG_REDIRECT_TYPE_LANDING_PAGE
&& $this->pluginConfig->getLoginRedirectLandingPage() !== ''
) {
$response = new RedirectResponse(
$this->router->generate(
'frontend.landing.page',
[ 'landingPageId' => $this->pluginConfig->getLoginRedirectLandingPage() ]
)
);
$event->setResponse($response);
}
}
/**
* @param string $customerId
* @param Context $context
*
* @return CustomerEntity
*/
private function getUpdatedCustomer(string $customerId, Context $context): CustomerEntity
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('id', $customerId));
return $this->customerRepository->search($criteria, $context)->first();
}
}