<?php
namespace Kobizo\Bundle\CoreBundle\EventSubscriber;
use Doctrine\ORM\EntityManagerInterface;
use Kobizo\Bundle\ECommerceBundle\Repository\ViewedProductRepository;
use Kobizo\Component\Configuration\Site\ViewedProductsFeatureFlag;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
class BeforeActionSubscriber implements EventSubscriberInterface
{
private EntityManagerInterface $entityManager;
private ViewedProductRepository $viewedProductRepository;
private ViewedProductsFeatureFlag $viewedProductsFeatureFlag;
public function __construct(
EntityManagerInterface $entityManager,
ViewedProductRepository $viewedProductRepository,
ViewedProductsFeatureFlag $viewedProductsFeatureFlag
) {
$this->entityManager = $entityManager;
$this->viewedProductRepository = $viewedProductRepository;
$this->viewedProductsFeatureFlag = $viewedProductsFeatureFlag;
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::CONTROLLER => 'convertJsonStringToArray',
SecurityEvents::INTERACTIVE_LOGIN => 'onLogin'
];
}
public function convertJsonStringToArray(ControllerEvent $event)
{
$request = $event->getRequest();
if ('json' != $request->getContentType() || !$request->getContent()) {
return;
}
$data = json_decode($request->getContent(), true);
if (JSON_ERROR_NONE !== json_last_error()) {
throw new BadRequestHttpException('invalid json body: '.json_last_error_msg());
}
$request->request->replace(is_array($data) ? $data : []);
}
public function onLogin(InteractiveLoginEvent $event): void
{
if ($event->getAuthenticationToken()->isAuthenticated() && $this->viewedProductsFeatureFlag->isEnabled()) {
$guestViewedProducts = $this->viewedProductRepository->findBy(['sessionId' => $event->getRequest()->getSession()->get("previousId")]);
foreach ($guestViewedProducts as $viewedProduct) {
$userViewedProduct = $this->viewedProductRepository->findOneBy(['customer' => $event->getAuthenticationToken()->getUser(), 'product' => $viewedProduct->getProduct()]);
if ($userViewedProduct !== null) {
$userViewedProduct->setCount($userViewedProduct->getCount()+$viewedProduct->getCount());
$userViewedProduct->setAddedAt($viewedProduct->getAddedAt());
$this->entityManager->remove($viewedProduct);
} else {
$viewedProduct->setCustomer($event->getAuthenticationToken()->getUser());
$viewedProduct->setSessionId($event->getRequest()->getSession()->getId());
}
$this->entityManager->flush();
}
}
}
}