app/Customize/EventSubscriber/ProductHistoryEventSubscriber.php line 140

Open in your IDE?
  1. <?php
  2. namespace Customize\EventSubscriber;
  3. use Customize\Service\ProductHistory\ProductCollection;
  4. use Eccube\Common\EccubeConfig;
  5. use Eccube\Event\TemplateEvent;
  6. use Eccube\Repository\ProductRepository;
  7. use Eccube\Request\Context;
  8. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  9. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  10. use Symfony\Component\HttpFoundation\Cookie;
  11. use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
  12. use Symfony\Component\HttpKernel\Event\ResponseEvent;
  13. use Symfony\Component\HttpKernel\Event\KernelEvent;
  14. use Symfony\Component\HttpKernel\KernelEvents;
  15. /**
  16.  * Class ProductHistoryEventSubscriber
  17.  * @package Customize\EventSubscriber
  18.  */
  19. class ProductHistoryEventSubscriber implements EventSubscriberInterface
  20. {
  21.     const COOKIE_NAME 'product_history';
  22.     /**
  23.      * @var ProductRepository
  24.      */
  25.     private $productRepository;
  26.     /**
  27.      * @var EccubeConfig
  28.      */
  29.     private $eccubeConfig;
  30.     /**
  31.      * @var Context
  32.      */
  33.     private $context;
  34.     /**
  35.      * @var EventDispatcherInterface
  36.      */
  37.     private $eventDispatcher;
  38.     public function __construct(
  39.         ProductRepository $productRepository,
  40.         EccubeConfig $eccubeConfig,
  41.         Context $context,
  42.         EventDispatcherInterface $eventDispatcher
  43.     )
  44.     {
  45.         $this->productRepository $productRepository;
  46.         $this->eccubeConfig $eccubeConfig;
  47.         $this->context $context;
  48.         $this->eventDispatcher $eventDispatcher;
  49.     }
  50.     /**
  51.      * @return array
  52.      */
  53.     public static function getSubscribedEvents(): array
  54.     {
  55.         return [
  56.             KernelEvents::RESPONSE => 'onKernelResponse',
  57.             KernelEvents::CONTROLLER_ARGUMENTS => 'onKernelControllerArguments'
  58.         ];
  59.     }
  60.     /**
  61.      * 商品詳細ページにアクセスしたら商品IDをCookieに保存
  62.      *
  63.      * @param ResponseEvent $event
  64.      * @throws \Exception
  65.      */
  66.     public function onKernelResponse(ResponseEvent $event): void
  67.     {
  68.         if (false === $event->isMasterRequest()) {
  69.             return;
  70.         }
  71.         if ($event->getRequest()->get('_route') !== 'product_detail') {
  72.             return;
  73.         }
  74.         if ($product_id $event->getRequest()->get('id')) {
  75.             $product $this->productRepository->find($product_id);
  76.             if (null === $product) {
  77.                 return;
  78.             }
  79.             $cookie $this->getCookie($event);
  80.             // 商品IDを追加
  81.             $products = new ProductCollection($cookie5);
  82.             $products->addProduct($product);
  83.             // Cookie作成・更新
  84.             $cookie $this->createCookie($products);
  85.             $response $event->getResponse();
  86.             $response->headers->setCookie($cookie);
  87.         }
  88.     }
  89.     /**
  90.      * Cookie取得
  91.      *
  92.      * @param KernelEvent $event
  93.      * @return array
  94.      */
  95.     private function getCookie(KernelEvent $event): array
  96.     {
  97.         $cookie $event->getRequest()->cookies->get(self::COOKIE_NAME);
  98.         return json_decode($cookietrue) ?? [];
  99.     }
  100.     /**
  101.      * Cookie作成・更新
  102.      *
  103.      * @param ProductCollection $productCollection
  104.      * @return Cookie
  105.      * @throws \Exception
  106.      */
  107.     private function createCookie(ProductCollection $productCollection): Cookie
  108.     {
  109.         return new Cookie(
  110.             self::COOKIE_NAME,
  111.             json_encode($productCollection->toArray()),
  112.             (new \DateTime())->modify('1 month'),
  113.             $this->eccubeConfig['env(ECCUBE_COOKIE_PATH)']
  114.         );
  115.     }
  116.     /**
  117.      * チェックした商品をフロント側のすべてのTwigテンプレートにセット
  118.      *
  119.      * @param ControllerArgumentsEvent $event
  120.      */
  121.     public function onKernelControllerArguments(ControllerArgumentsEvent $event): void
  122.     {
  123.         if ($this->context->isAdmin()) {
  124.             return;
  125.         }
  126.         if ($event->getRequest()->attributes->has('_template')) {
  127.             $cookie $this->getCookie($event);
  128.             $template $event->getRequest()->attributes->get('_template');
  129.             $this->eventDispatcher->addListener($template->getTemplate(), function (TemplateEvent $templateEvent) use ($cookie) {
  130.                 $productHistory = [];
  131.                 $products = new ProductCollection($cookie);
  132.                 if ($products->count() > 0) {
  133.                     foreach ($products as $product) {
  134.                         if ($product $this->productRepository->find($product)) {
  135.                             $productHistory[] = $product;
  136.                         }
  137.                     }
  138.                 }
  139.                 $templateEvent->setParameter('productHistory'$productHistory);
  140.             });
  141.         }
  142.     }
  143. }