app/Customize/EventSubscriber/ProductHistoryEventSubscriber.php line 139

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