<?php 
 
/* 
 * Plugin Name: JoolenCheckedItemBlock4 
 * 
 * Copyright(c) joolen inc. All Rights Reserved. 
 * 
 * https://www.joolen.co.jp/ 
 * 
 * For the full copyright and license information, please view the LICENSE 
 * file that was distributed with this source code. 
 */ 
 
namespace Plugin\JoolenCheckedItemBlock4; 
 
use Eccube\Entity\Product; 
use Plugin\JoolenCheckedItemBlock4\Entity\Config; 
use Plugin\JoolenCheckedItemBlock4\Repository\ConfigRepository; 
use Symfony\Component\EventDispatcher\EventSubscriberInterface; 
use Symfony\Component\HttpFoundation\Cookie; 
use Symfony\Component\HttpKernel\Event\KernelEvent; 
use Symfony\Component\HttpKernel\KernelEvents; 
 
class Event implements EventSubscriberInterface 
{ 
    public const COOKIE_NAME = 'joolen_checked_item_cookie'; 
 
    /** 
     * @var Config 
     */ 
    protected $Config; 
 
    public function __construct(ConfigRepository $configRepository) 
    { 
        $this->Config = $configRepository->getOneOrDefault(); 
    } 
 
    /** 
     * @return array 
     */ 
    public static function getSubscribedEvents(): array 
    { 
        return [ 
            KernelEvents::RESPONSE => 'onKernelResponse' 
        ]; 
    } 
 
    public function onKernelResponse(KernelEvent $event) 
    { 
        $request = $event->getRequest(); 
        $pathInfo = $request->getPathInfo(); 
 
        // 閲覧履歴の保存 
        if (preg_match('/.*\/products\/detail\/.*/', $pathInfo) === 1) { 
 
            /** @var Product $Product */ 
            $Product = $event->getRequest()->get('Product'); 
            $product_id = $Product->getId(); 
 
            // クッキーから閲覧した商品情報を取得 
            $checkedItems = json_decode($request->cookies->get(self::COOKIE_NAME), true) ?? []; 
            $key = array_search($product_id, $checkedItems); 
 
            // MEMO: すでに閲覧している場合、削除する 
            if ($key !== false) { 
                unset($checkedItems[$key]); 
                $checkedItems = array_values($checkedItems);    // 削除するとIndexずれるので前詰め 
            } 
 
            $checkedItems[] = $product_id; 
 
            // MEMO: 
            //  【重要】設定の表示件数=保存件数なので設定値が変わっている可能性があるため、現在の保存件数が表示件数を 
            //  上回ってる場合、古い方から削除する 
            if (!empty($checkedItems) && count($checkedItems) > $this->Config->getDisplayNumber()) { 
 
                // 削除する件数 
                $deleteNumber = count($checkedItems) - $this->Config->getDisplayNumber(); 
 
                // 古い方から削除 
                for($i = 0; $i < $deleteNumber; ++$i) { 
                    unset($checkedItems[$i]); 
                } 
                $checkedItems = array_values($checkedItems);    // 削除するとIndexずれるので前詰め 
            } 
 
            $response = $event->getResponse(); 
            $response->headers->setCookie( 
                new Cookie( 
                    self::COOKIE_NAME, 
                    json_encode($checkedItems), 
                    2147483647, 
                    '/', 
                    null, 
                    $this->Config->isCookieSecure()) 
            ); 
            $event->setResponse($response); 
 
            return; 
        } 
 
        // 閲覧履歴の削除 
        if (preg_match('/.*\/joolen_checked_item\/remove.*/', $pathInfo) === 1) { 
            $response = $event->getResponse(); 
            $response->headers->clearCookie(Event::COOKIE_NAME, '/', null); 
            $event->setResponse($response); 
        } 
    } 
}