<?php
declare(strict_types=1);
namespace App\Module\Account\Subscriber;
use App\Module\Account\Repository\CustomerRepository;
use Commercetools\Core\Model\Customer\Customer;
use Commercetools\Core\Model\CustomerGroup\CustomerGroupReference;
use Denios\SharedConstant\Cookie\Key;
use Denios\SharedConstant\CustomerGroup\GroupKey;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
/**
* @package App\Module\Account\Subscriber
*/
class ExcludeVatSubscriber implements EventSubscriberInterface
{
private CustomerRepository $customerRepository;
private SessionInterface $session;
private const BTB_NAME = 'b2b';
/**
* @param CustomerRepository $customerRepository
* @param SessionInterface $session
*/
public function __construct(CustomerRepository $customerRepository, SessionInterface $session)
{
$this->customerRepository = $customerRepository;
$this->session = $session;
}
/**
* @return array
*/
public static function getSubscribedEvents(): array
{
return [
// make sure this is executed BEFORE routing where products are loaded
KernelEvents::REQUEST => [['checkForVatParameter', 64]],
SecurityEvents::INTERACTIVE_LOGIN => ['addVatCookieBasedOnCustomerGroupOnLogin'],
KernelEvents::RESPONSE => ['addVatCookieBasedOnCustomerGroupToResponse']
];
}
/**
* Check for vat parameter and add it as request attribute
*
* @param RequestEvent $event
*
* @return void
*/
public function checkForVatParameter(RequestEvent $event): void
{
$request = $event->getRequest();
// default is B2b customer --> exclude vat from prices
$request->attributes->set(Key::EXCLUDE_VAT, true);
if ($request->cookies->has(Key::EXCLUDE_VAT)) {
$request->attributes->set(Key::EXCLUDE_VAT, $request->cookies->getBoolean(Key::EXCLUDE_VAT));
}
//only fallback because Google do not want to have exclude_vat param
if ($request->query->has(self::BTB_NAME)) {
$request->attributes->set(Key::EXCLUDE_VAT, $request->query->getBoolean(self::BTB_NAME));
}
if ($request->query->has(Key::EXCLUDE_VAT)) {
$request->attributes->set(Key::EXCLUDE_VAT, $request->query->getBoolean(Key::EXCLUDE_VAT));
}
}
/**
* @param InteractiveLoginEvent $event
*
* @return void
*/
public function addVatCookieBasedOnCustomerGroupOnLogin(InteractiveLoginEvent $event): void
{
/** @var UserInterface $user */
$user = $event
->getAuthenticationToken()
->getUser();
$userEmail = $user->getUsername();
/** @var Customer|null $customer */
$customer = $this->customerRepository
->setExpands(['customerGroup'])
->findOneBy(['email = "' . $userEmail . '"']);
if ($customer !== null) {
/** @var CustomerGroupReference|null $customerGroup */
$customerGroup = $customer->getCustomerGroup();
if ($customerGroup !== null) {
$event->getRequest()->attributes->set(Key::EXCLUDE_VAT, $customerGroup->getObj()->getKey() === GroupKey::BUSINESS_KEY);
}
}
}
/**
* @param ResponseEvent $event
*
* @return void
*/
public function addVatCookieBasedOnCustomerGroupToResponse(ResponseEvent $event): void
{
if ($event->getRequest()->attributes->has(Key::EXCLUDE_VAT)) {
$event->getResponse()->headers->setCookie(
Cookie::create(
Key::EXCLUDE_VAT,
$event->getRequest()->attributes->get(Key::EXCLUDE_VAT)
? 'true'
: 'false',
0,
'/',
null,
null,
false,
false,
'None'
)
);
}
}
}