app/Plugin/GtmGaEEc42/Event.php line 304

Open in your IDE?
  1. <?php
  2. /*
  3.  * GtmGaEEc42: GTM版 Google Analytics eコマース/拡張eコマース対応プラグイン
  4.  * Copyright (C) 2017-2022 Freischtide Inc. All Rights Reserved.
  5.  * http://freischtide.tumblr.com/
  6.  *
  7.  * License: see LICENSE.txt
  8.  */
  9. namespace Plugin\GtmGaEEc42;
  10. use Eccube\Common\EccubeConfig;
  11. use Eccube\Event\TemplateEvent;
  12. use Eccube\Entity\Category;
  13. use Eccube\Entity\Order;
  14. use Eccube\Entity\OrderItem;
  15. use Eccube\Entity\ItemHolderInterface;
  16. use Eccube\Entity\ProductClass;
  17. use Eccube\Entity\TaxRule;
  18. use Eccube\Service\TaxRuleService;
  19. use Plugin\GtmGaEEc42\Entity\GtmGaEEc;
  20. use Plugin\GtmGaEEc42\Repository\GtmGaEEcRepository;
  21. use Symfony\Component\DependencyInjection\ContainerInterface;
  22. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  23. use Symfony\Component\HttpFoundation\RequestStack;
  24. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  25. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  26. use Symfony\Component\Finder\Finder;
  27. use Plugin\Coupon42\Entity\Coupon;
  28. use Plugin\Coupon42\Entity\CouponOrder;
  29. class Event implements EventSubscriberInterface
  30. {
  31.     /**
  32.      * @var GtmEEcRepository
  33.      */
  34.     private $repo;
  35.     /**
  36.      * @var EccubeConfig
  37.      */
  38.     private $eccubeConfig;
  39.     /**
  40.      * @var TokenStorageInterface
  41.      */
  42.     private $tokenStorage;
  43.     /**
  44.      * @var AuthorizationCheckerInterface
  45.      */
  46.     private $authorizationChecker;
  47.     /**
  48.      * @var RequestStack
  49.      */
  50.     private $requestStack;
  51.     /**
  52.      * @var ContainerInterface
  53.      */
  54.     private $container;
  55.     /**
  56.      * @var GtmGaEEc
  57.      */
  58.     private $gtmgaeec;
  59.     private $gtmgaeec_tag_rendered false;
  60.     /**
  61.      * Event constructor.
  62.      * @param GtmGaEEcRepository $repo
  63.      * @param EccubeConfig $eccubeConfig
  64.      * @param TokenStorageInterface $tokenStorage
  65.      * @param AuthorizationCheckerInterface $authorizationChecker
  66.      * @param RequestStack $requestStack
  67.      * @param ContainerInterface $container
  68.      * @param \Twig_Environment $environment
  69.      */
  70.     public function __construct(
  71.         GtmGaEEcRepository $repo,
  72.         EccubeConfig $eccubeConfig,
  73.         TokenStorageInterface $tokenStorage,
  74.         AuthorizationCheckerInterface $authorizationChecker,
  75.         RequestStack $requestStack,
  76.         ContainerInterface $container
  77.     ) {
  78.         $this->repo $repo;
  79.         $this->eccubeConfig $eccubeConfig;
  80.         $this->tokenStorage $tokenStorage;
  81.         $this->authorizationChecker $authorizationChecker;
  82.         $this->requestStack $requestStack;
  83.         $this->container $container;
  84.         $this->gtmgaeec $this->repo->get();
  85.     }
  86.     /**
  87.      * @return array
  88.      */
  89.     public static function getSubscribedEvents()
  90.     {
  91.         $template_path __DIR__ '/../../../src/Eccube/Resource/template/default/';
  92.         $subscribed_events = [];
  93.         foreach ((new Finder())->in($template_path)->name('*.twig')->files() as $fileinfo) {
  94.             $subscribed_events[str_replace($template_path''$fileinfo->getPathname())] = 'all';
  95.         }
  96.         $subscribed_events['Product/list.twig']       = 'productList';
  97.         $subscribed_events['Mypage/favorite.twig']    = 'mypageFavorite';
  98.         $subscribed_events['Product/detail.twig']     = 'productDetail';
  99.         $subscribed_events['Cart/index.twig']         = 'cart';
  100.         $subscribed_events['Entry/index.twig']        = 'entry';
  101.         $subscribed_events['Entry/confirm.twig']      = 'entry_confirm';
  102.         $subscribed_events['Entry/complete.twig']     = 'entry_complete';
  103.         $subscribed_events['Mypage/index.twig']       = 'mypage';
  104.         $subscribed_events['Mypage/login.twig']       = 'mypage_login';
  105.         $subscribed_events['Shopping/login.twig']     = 'shopping_login';
  106.         $subscribed_events['Shopping/nonmember.twig'] = 'shopping_nonmember';
  107.         $subscribed_events['Shopping/index.twig']     = 'shopping';
  108.         $subscribed_events['Shopping/confirm.twig']   = 'shopping';
  109.         $subscribed_events['Shopping/complete.twig']  = 'shoppingComplete';
  110.         return $subscribed_events;
  111.     }
  112.     private function setVars(&$parameters)
  113.     {
  114.         if ($this->gtmgaeec->getTrackUserId() == GtmGaEEc::GTMGAEEC_OP_INCLUDE_USER_ID) {
  115.             if (!is_null($this->tokenStorage->getToken()) &&
  116.                 $this->authorizationChecker->isGranted('ROLE_USER')) {
  117.                 $customer_id $this->tokenStorage->getToken()->getUser()->getId();
  118.                 $parameters['user_id'] = $this->getUuid5($this->eccubeConfig->get('GTMGAEEC_UUID'),
  119.                                                          $this->gtmgaeec->getTid(),
  120.                                                          $customer_id);
  121.             }
  122.         }
  123.         $pid $this->requestStack->getCurrentRequest()->get('ugep_id');
  124.         $pname $this->requestStack->getCurrentRequest()->get('ugep_name');
  125.         if ($pid && $pname) {
  126.             $promo['id'] = addslashes($pid);
  127.             $promo['name'] = addslashes($pname);
  128.             $promo['creative'] = addslashes($this->requestStack->getCurrentRequest()->get('ugep_creative'));
  129.             $promo['position'] = addslashes($this->requestStack->getCurrentRequest()->get('ugep_position'));
  130.             $parameters['promo'] = $promo;
  131.         }
  132.     }
  133.     public function all(TemplateEvent $event)
  134.     {
  135.         $tid $this->gtmgaeec->getTid();
  136.         if (empty($tid)) {
  137.             return;
  138.         }
  139.         if ($this->gtmgaeec_tag_rendered) {
  140.             return;
  141.         }
  142.         $parameters $event->getParameters();
  143.         $this->setVars($parameters);
  144.         $parameters['gtmgaeec'] = $this->gtmgaeec;
  145.         $event->setParameters($parameters);
  146.         $this->addAsset($event);
  147.     }
  148.     public function productList(TemplateEvent $event)
  149.     {
  150.         $tid $this->gtmgaeec->getTid();
  151.         if (empty($tid)) {
  152.             return;
  153.         }
  154.         $parameters $event->getParameters();
  155.         $this->setVars($parameters);
  156.         $name $this->requestStack->getCurrentRequest()->get('name');
  157.         if (!empty($name)) {
  158.             $list 'Search Results';
  159.         } else {
  160.             $list 'Category List';
  161.         }
  162.         $items $parameters['pagination']->getItems();
  163.         $impressions = [];
  164.         if ($this->gtmgaeec->getImpTrack() == GtmGaEEc::GTMGAEEC_OP_WITH_IMP_TRACK) {
  165.             if ($this->gtmgaeec->getCategory() == GtmGaEEc::GTMGAEEC_OP_CATEGORY_ON &&
  166.                 is_object($parameters['Category'])) {
  167.                 $category $parameters['Category']->getName();
  168.             } else {
  169.                 $category '';
  170.             }
  171.             foreach ($items as $item) {
  172.                 $impressions[] = $this->buildEcImpression($item$list$category);
  173.             }
  174.         }
  175.         $parameters['gtmgaeec'] = $this->gtmgaeec;
  176.         $parameters['impressions'] = $impressions;
  177.         $parameters['list_name'] = $list;
  178.         $event->setParameters($parameters);
  179.         $this->addAsset($event);
  180.     }
  181.     public function mypageFavorite(TemplateEvent $event)
  182.     {
  183.         $tid $this->gtmgaeec->getTid();
  184.         if (empty($tid)) {
  185.             return;
  186.         }
  187.         $parameters $event->getParameters();
  188.         $this->setVars($parameters);
  189.         $list 'Favorite List';
  190.         $items $parameters['pagination']->getItems();
  191.         $impressions = [];
  192.         if ($this->gtmgaeec->getImpTrack() == GtmGaEEc::GTMGAEEC_OP_WITH_IMP_TRACK) {
  193.             foreach ($items as $item) {
  194.                 // CustomerFavoriteProduct => Product
  195.                 $product $item->getProduct($item->getId());
  196.                 $category $this->getCategory($product);
  197.                 $impressions[] = $this->buildEcImpression($product$list$category);
  198.             }
  199.         }
  200.         $parameters['gtmgaeec'] = $this->gtmgaeec;
  201.         $parameters['impressions'] = $impressions;
  202.         $parameters['list_name'] = $list;
  203.         $event->setParameters($parameters);
  204.         $this->addAsset($event);
  205.     }
  206.     public function productDetail(TemplateEvent $event)
  207.     {
  208.         $tid $this->gtmgaeec->getTid();
  209.         if (empty($tid)) {
  210.             return;
  211.         }
  212.         $parameters $event->getParameters();
  213.         $this->setVars($parameters);
  214.         $list 'Item Detail';
  215.         $product $parameters['Product'];
  216.         $category $this->getCategory($product);
  217.         $products = [$this->buildEcProduct($product$category)];
  218.         $action  = ['action' => 'detail''option' => ''];
  219.         $clickFrom $this->decideList($_SERVER);
  220.         $impressions = [$this->buildEcImpression($product$list$category)];
  221.         $ga4Impressions = [];
  222.         if ($this->gtmgaeec->getImpTrack() == GtmGaEEc::GTMGAEEC_OP_WITH_IMP_TRACK) {
  223.             // related product from RelatedProduct plugin by EC-CUBE
  224.             // https://github.com/EC-CUBE/related-product-plugin
  225.             if (class_exists('Plugin\RelatedProduct4\Entity\RelatedProduct')) {
  226.                 $relatedProductPlugin false;
  227.                 $enabledPlugins $this->container->getParameter('eccube.plugins.enabled');
  228.                 foreach ($enabledPlugins as $plugin) {
  229.                     if ($plugin == 'RelatedProduct4') {
  230.                         $relatedProductPlugin true;
  231.                         break;
  232.                     }
  233.                 }
  234.                 if ($relatedProductPlugin) {
  235.                     foreach ($product->getRelatedProducts() as $relatedProduct) {
  236.                         $childProduct $relatedProduct->getChildProduct();
  237.                         if ($childProduct->getStatus()->getId() == \Eccube\Entity\Master\ProductStatus::DISPLAY_SHOW) {
  238.                             $childCategory $this->getCategory($childProduct);
  239.                             $impressions[] = $this->buildEcImpression($childProduct'Related Item'$childCategory);
  240.                             $ga4Impressions[] = $this->buildEcImpression($childProduct'Related Item'$childCategory);
  241.                         }
  242.                     }
  243.                 }
  244.             }
  245.         }
  246.         $parameters['gtmgaeec'] = $this->gtmgaeec;
  247.         $parameters['impressions'] = $impressions;
  248.         $parameters['ga4_impressions'] = $ga4Impressions;
  249.         $parameters['products'] = $products;
  250.         $parameters['action'] = $action;
  251.         $parameters['list_name'] = $clickFrom;
  252.         $event->setParameters($parameters);
  253.         $this->addAsset($event);
  254.     }
  255.     public function cart(TemplateEvent $event)
  256.     {
  257.         $tid $this->gtmgaeec->getTid();
  258.         if (empty($tid)) {
  259.             return;
  260.         }
  261.         $parameters $event->getParameters();
  262.         $this->setVars($parameters);
  263.         $carts $parameters['Carts'];
  264.         $products = array();
  265.         foreach ($carts as $cart) {
  266.             foreach ($cart->getCartItems() as $cartItem) {
  267.                 $productClass $cartItem->getProductClass();
  268.                 $product $productClass->getProduct();
  269.                 $category $this->getCategory($product);
  270.                 $variant $this->getVariant($productClass);
  271.                 $products[] = $this->buildEcProduct($product,
  272.                                                     $category,
  273.                                                     $cartItem->getPrice(),
  274.                                                     $cartItem->getQuantity(),
  275.                                                     $variant);
  276.             }
  277.         }
  278.         $action  = ['action' => 'add''option' => ''];
  279.         $parameters['gtmgaeec'] = $this->gtmgaeec;
  280.         $parameters['products'] = $products;
  281.         $parameters['action'] = $action;
  282.         $event->setParameters($parameters);
  283.         $this->addAsset($event);
  284.     }
  285.     // 会員登録
  286.     public function entry(TemplateEvent $event)
  287.     {
  288.         $tid $this->gtmgaeec->getTid();
  289.         if (empty($tid)) {
  290.             return;
  291.         }
  292.         $parameters $event->getParameters();
  293.         $this->setVars($parameters);
  294.         $parameters['gtmgaeec'] = $this->gtmgaeec;
  295.         $parameters['event_name'] = 'sign_up_initiated';
  296.         $event->setParameters($parameters);
  297.         $this->addAsset($event);
  298.     }
  299.     // 会員登録 確認
  300.     public function entry_confirm(TemplateEvent $event)
  301.     {
  302.         $tid $this->gtmgaeec->getTid();
  303.         if (empty($tid)) {
  304.             return;
  305.         }
  306.         $parameters $event->getParameters();
  307.         $this->setVars($parameters);
  308.         $parameters['gtmgaeec'] = $this->gtmgaeec;
  309.         $parameters['event_name'] = 'sign_up_confirm';
  310.         $event->setParameters($parameters);
  311.         $this->addAsset($event);
  312.     }
  313.     // 会員登録 完了
  314.     public function entry_complete(TemplateEvent $event)
  315.     {
  316.         $tid $this->gtmgaeec->getTid();
  317.         if (empty($tid)) {
  318.             return;
  319.         }
  320.         $parameters $event->getParameters();
  321.         $this->setVars($parameters);
  322.         $parameters['gtmgaeec'] = $this->gtmgaeec;
  323.         $parameters['event_name'] = 'sign_up';
  324.         $event->setParameters($parameters);
  325.         $this->addAsset($event);
  326.     }
  327.     // マイページ
  328.     public function mypage(TemplateEvent $event)
  329.     {
  330.         $tid $this->gtmgaeec->getTid();
  331.         if (empty($tid)) {
  332.             return;
  333.         }
  334.         $parameters $event->getParameters();
  335.         $this->setVars($parameters);
  336.         $parameters['gtmgaeec'] = $this->gtmgaeec;
  337.         $parameters['event_name'] = 'mypage';
  338.         $event->setParameters($parameters);
  339.         $this->addAsset($event);
  340.     }
  341.     // 通常時のログイン
  342.     public function mypage_login(TemplateEvent $event)
  343.     {
  344.         $tid $this->gtmgaeec->getTid();
  345.         if (empty($tid)) {
  346.             return;
  347.         }
  348.         $parameters $event->getParameters();
  349.         $this->setVars($parameters);
  350.         $parameters['gtmgaeec'] = $this->gtmgaeec;
  351.         $parameters['event_name'] = 'mypage_login';
  352.         $event->setParameters($parameters);
  353.         $this->addAsset($event);
  354.     }
  355.     // 買い物時のログイン
  356.     public function shopping_login(TemplateEvent $event)
  357.     {
  358.         $tid $this->gtmgaeec->getTid();
  359.         if (empty($tid)) {
  360.             return;
  361.         }
  362.         $parameters $event->getParameters();
  363.         $this->setVars($parameters);
  364.         $parameters['gtmgaeec'] = $this->gtmgaeec;
  365.         $parameters['event_name'] = 'shopping_login';
  366.         $event->setParameters($parameters);
  367.         $this->addAsset($event);
  368.     }
  369.     // お客様情報
  370.     public function shopping_nonmember(TemplateEvent $event)
  371.     {
  372.         $tid $this->gtmgaeec->getTid();
  373.         if (empty($tid)) {
  374.             return;
  375.         }
  376.         $parameters $event->getParameters();
  377.         $this->setVars($parameters);
  378.         $parameters['gtmgaeec'] = $this->gtmgaeec;
  379.         $parameters['event_name'] = 'shopping_nonmember';
  380.         $event->setParameters($parameters);
  381.         $this->addAsset($event);
  382.     }
  383.     // step 1: ご注文手続き(GET), step 2: ご注文内容確認(POST)
  384.     public function shopping(TemplateEvent $event)
  385.     {
  386.         $tid $this->gtmgaeec->getTid();
  387.         if (empty($tid)) {
  388.             return;
  389.         }
  390.         $parameters $event->getParameters();
  391.         $this->setVars($parameters);
  392.         // order id を一時的に保持(ペイジェント等の外部決済システムが order id を返さないため)
  393.         $order $parameters['Order'];
  394.         $cookie $this->getGtmGaEEcCookie();
  395.         if ($order->getId()) {
  396.             $this->setGtmGaEEcCookie($cookie, array('orderId' => $order->getId()));
  397.         }
  398.         $couponCode null;
  399.         $couponDiscounts = [];
  400.         if (isset($parameters['CouponOrder'])) {
  401.             $couponOrder $parameters['CouponOrder'];
  402.             if ($couponOrder) {
  403.                 if ($this->requestStack->getCurrentRequest()->getMethod() == 'POST' && $this->gtmgaeec->getConfirmationAsPurchase() == GtmGaEEc::GTMGAEEC_OP_CONFIRMATION_AS_PURCHASE) {
  404.                     list($couponCode$couponDiscounts) = $this->getCouponDiscounts($order$couponOrder->getId());
  405.                 } else {
  406.                     $this->setGtmGaEEcCookie($cookie, array('couponOrderId' => $couponOrder->getId()));
  407.                 }
  408.             }
  409.         }
  410.         $orderDetails $order->getOrderItems();
  411.         $products $this->getProducts($orderDetails$couponDiscounts);
  412.         $action = ['action' => 'checkout''option' => $this->getOptionsStr([
  413.             'step' => $this->requestStack->getCurrentRequest()->getMethod() == 'POST' 1
  414.         ])];
  415.         $parameters['gtmgaeec'] = $this->gtmgaeec;
  416.         $parameters['products'] = $products;
  417.         $parameters['action'] = $action;
  418.         $parameters['event'] = $this->requestStack->getCurrentRequest()->getMethod() == 'POST' 'checkout_progress' 'begin_checkout';
  419.         $parameters['checkout_step'] = $this->requestStack->getCurrentRequest()->getMethod() == 'POST' 1;
  420.         if ($this->requestStack->getCurrentRequest()->getMethod() == 'POST' && $this->gtmgaeec->getConfirmationAsPurchase() == GtmGaEEc::GTMGAEEC_OP_CONFIRMATION_AS_PURCHASE) {
  421.             $parameters['transaction'] = $this->getTransaction($order);
  422.             $parameters['coupon_code'] = $couponCode;
  423.         }
  424.         $event->setParameters($parameters);
  425.         $this->addAsset($event);
  426.     }
  427.     public function shoppingComplete(TemplateEvent $event)
  428.     {
  429.         $tid $this->gtmgaeec->getTid();
  430.         if (empty($tid)) {
  431.             return;
  432.         }
  433.         if ($this->gtmgaeec->getConfirmationAsPurchase() == GtmGaEEc::GTMGAEEC_OP_CONFIRMATION_AS_PURCHASE) {
  434.             return;
  435.         }
  436.         $parameters $event->getParameters();
  437.         $this->setVars($parameters);
  438.         // 必要に応じて cookie より order id を復元
  439.         $order $parameters['Order'];
  440.         $cookie $this->getGtmGaEEcCookie();
  441.         if (empty($order)) {
  442.             if (isset($cookie['orderId'])) {
  443.                 $orderId $cookie['orderId'];
  444.                 $entityManager $this->container->get('doctrine')->getManager();
  445.                 $orderRepository $entityManager->getRepository(Order::class);
  446.                 $order $orderRepository->find($orderId);
  447.                 $this->setGtmGaEEcCookie($cookie, array('orderId' => null));
  448.             } else {
  449.                 return;
  450.             }
  451.         }
  452.         $orderDetails $order->getOrderItems();
  453.         $couponCode null;
  454.         $couponDiscounts = [];
  455.         if (isset($cookie['couponOrderId'])) {
  456.             list($couponCode$couponDiscounts) = $this->getCouponDiscounts($order$cookie['couponOrderId']);
  457.             $this->setGtmGaEEcCookie($cookie, array('couponOrderId' => null));
  458.         }
  459.         $products $this->getProducts($orderDetails$couponDiscounts);
  460.         $transaction $this->getTransaction($order);
  461.         $action = ['action' => 'purchase''option' => $this->getOptionsStr($transaction)];
  462.         $parameters['gtmgaeec'] = $this->gtmgaeec;
  463.         $parameters['products'] = $products;
  464.         $parameters['action'] = $action;
  465.         $parameters['transaction'] = $transaction;
  466.         $parameters['coupon_code'] = $couponCode;
  467.         $parameters['order'] = $order;
  468.         $event->setParameters($parameters);
  469.         $this->addAsset($event);
  470.     }
  471.     private function addAsset($event)
  472.     {
  473.         if ($this->gtmgaeec->getTagVersion() & GtmGaEEc::GTMGAEEC_TAG_UA) {
  474.             $event->addAsset('@GtmGaEEc42/default/gtmgaeec_ua.twig');
  475.         }
  476.         if ($this->gtmgaeec->getTagVersion() & GtmGaEEc::GTMGAEEC_TAG_GA4) {
  477.             $event->addAsset('@GtmGaEEc42/default/gtmgaeec_ga4.twig');
  478.         }
  479.         if ($this->gtmgaeec->getTag() == GtmGaEEc::GTMGAEEC_USE_GTM_TAG) {
  480.             $event->addAsset('@GtmGaEEc42/default/gtmgaeec_tag.twig');
  481.         }
  482.         $event->addSnippet('@GtmGaEEc42/default/gtmgaeec_noscript.twig');
  483.         $this->gtmgaeec_tag_rendered true;
  484.     }
  485.     private function getCategory($product)
  486.     {
  487.         $category '';
  488.         if ($this->gtmgaeec->getCategory() == GtmGaEEc::GTMGAEEC_OP_CATEGORY_ON) {
  489.             $productCategories $product->getProductCategories();
  490.             $categories = array();
  491.             foreach ($productCategories as $productCategory) {
  492.                 if (empty($productCategory['Category']->getParents())) {
  493.                     $categories[] = implode('/'$productCategory['Category']->getSelfAndDescendants());
  494.                 }
  495.             }
  496.             $category implode(', '$categories);
  497.         }
  498.         return $category;
  499.     }
  500.     private function getVariant($productClass)
  501.     {
  502.         $variants = array();
  503.         if ($productClass->hasClassCategory1()) {
  504.             $variants[] = $productClass->getClassCategory1()->getName();
  505.         }
  506.         if ($productClass->hasClassCategory2()) {
  507.             $variants[] = $productClass->getClassCategory2()->getName();
  508.         }
  509.         return implode('/'$variants);
  510.     }
  511.     private function getOptionsStr($options)
  512.     {
  513.         $results = array();
  514.         foreach ($options as $k => $v) {
  515.             $results[] = "'" $k "': " $v;
  516.         }
  517.         return implode(', '$results);
  518.     }
  519.     private function decideList($serverEnv)
  520.     {
  521.         if(!empty($serverEnv['HTTP_REFERER'])) {
  522.             $referrer $serverEnv['HTTP_REFERER'];
  523.         } else {
  524.             return 'Direct Access';
  525.         }
  526.         $url parse_url($referrer);
  527.         if ($url['host'] == $serverEnv['SERVER_NAME']) {
  528.             switch (true) {
  529.             case $url['path'] == '/':
  530.                 return 'TOP';
  531.             case stristr($url['path'], '/mypage/favorite'):
  532.                 return 'Favorite List';
  533.             case stristr($url['path'], '/products/list'):
  534.                 $name $this->requestStack->getCurrentRequest()->get('name');
  535.                 if (!empty($name)) {
  536.                     return 'Search Results';
  537.                 } else {
  538.                     return 'Category List';
  539.                 }
  540.             case stristr($url['path'], '/products/detail'):
  541.                 return 'Item Detail';
  542.             default:
  543.                 return 'Internal Site';
  544.             }
  545.         } else {
  546.             if ($this->gtmgaeec->getUseCustomReferrer() == GtmGaEEc::GTMGAEEC_OP_USE_CUSTOM_REFERRER) {
  547.                 foreach ($this->gtmgaeec->getCustomReferrers() as $customer_referrer) {
  548.                     if (!empty($customer_referrer[0]) && stristr($referrer$customer_referrer[0])) {
  549.                         return addslashes($customer_referrer[1]);
  550.                     }
  551.                 }
  552.             }
  553.             return 'External Site';
  554.         }
  555.     }
  556.     private function setGtmGaEEcCookie($cookie$values)
  557.     {
  558.         foreach ($values as $k => $v) {
  559.             if (is_null($v)) {
  560.                 unset($cookie[$k]);
  561.             } else {
  562.                 $cookie[$k] = $v;
  563.             }
  564.         }
  565.         setcookie('eccube_gtmgaeec'json_encode($cookie), time()+60*60'/');
  566.     }
  567.     private function getGtmGaEEcCookie()
  568.     {
  569.         return isset($_COOKIE['eccube_gtmgaeec']) ? json_decode($_COOKIE['eccube_gtmgaeec'], true) : [];
  570.     }
  571.     private function getProducts($orderDetails$couponDiscounts = [])
  572.     {
  573.         $products = [];
  574.         foreach ($orderDetails as $orderDetail) {
  575.             if (!$orderDetail->isProduct()) {
  576.                 continue;
  577.             }
  578.             $product $orderDetail->getProduct();
  579.             $category $this->getCategory($product);
  580.             $variant $this->getVariant($orderDetail->getProductClass());
  581.             $products[] = $this->buildEcProduct(
  582.                 $product,
  583.                 $category,
  584.                 $orderDetail->getPriceIncTax(),
  585.                 $orderDetail->getQuantity(),
  586.                 $variant,
  587.                 isset($couponDiscounts[$orderDetail->getProductClass()->getId()]) ? $couponDiscounts[$orderDetail->getProductClass()->getId()] : null
  588.             );
  589.         }
  590.         return $products;
  591.     }
  592.     private function getTransaction($order)
  593.     {
  594.         $transaction = [
  595.             'id'       => "'" $order['id'] . "'",
  596.             'revenue'  => "'" $order['total'] . "'",
  597.             'tax'      => "'" $order['tax'] . "'",
  598.             'shipping' => "'" $order['delivery_fee_total'] . "'"
  599.         ];
  600.         return $transaction;
  601.     }
  602.     private function getUuid5($namespace_id$ga_tid$customer_id)
  603.     {
  604.         $customer_hash sha1($namespace_id $ga_tid $customer_id);
  605.         $time_low            substr($customer_hash,  0,  8);
  606.         $time_mid            substr($customer_hash,  8,  4);
  607.         $time_hi_and_version substr($customer_hash12,  4);
  608.         $time_hi_and_version sprintf('%04x', (intval('0x' $time_hi_and_version16) & 0x0fff) | 0x3000);
  609.         $clk_seq_hi_res      substr($customer_hash16,  2);
  610.         $clk_seq_hi_res      sprintf('%02x', (intval('0x' $clk_seq_hi_res16) & 0x3f) | 0x80);
  611.         $clk_seq_low         substr($customer_hash18,  2);
  612.         $node                substr($customer_hash2012);
  613.         return sprintf('%8s-%4s-%4s-%2s%2s-%12s'$time_low$time_mid$time_hi_and_version$clk_seq_hi_res$clk_seq_low$node);
  614.     }
  615.     private function buildEcImpression($item$list$category)
  616.     {
  617.         return array('id'       => $item->getId(),
  618.                      'name'     => addslashes($item->getName()),
  619.                      'list'     => $list,
  620.                      'category' => addslashes($category),
  621.                      'price'    => $item->getPrice02IncTaxMax());
  622.     }
  623.     private function buildEcProduct($product$category$price null$quantity 0$variant ''$discount null)
  624.     {
  625.         return array('id'       => $product->getId(),
  626.                      'name'     => addslashes($product->getName()),
  627.                      'price'    => $price == null $product->getPrice02IncTaxMax() : $price,
  628.                      'quantity' => $quantity,
  629.                      'variant'  => $variant,
  630.                      'category' => addslashes($category),
  631.                      'discount' => $discount);
  632.     }
  633.     /**
  634.      * クーポンコードと ProductClass ごとの discount を返す
  635.      *
  636.      * @param ItemHolderInterface $order
  637.      * @param couponOrderId $couponOrderId
  638.      * @return array $couponCode, $couponDiscounts クーポンコードと ProductClass::id をキーにした discount
  639.      */
  640.     private function getCouponDiscounts($order$couponOrderId)
  641.     {
  642.         $entityManager $this->container->get('doctrine')->getManager();
  643.         $couponOrderRepository $entityManager->getRepository(CouponOrder::class);
  644.         $couponRepository $entityManager->getRepository(Coupon::class);
  645.         $couponOrder $couponOrderRepository->find($couponOrderId);
  646.         $couponCode $couponOrder->getCouponCd();
  647.         $coupon $couponRepository->findActiveCoupon($couponCode);
  648.         $couponProducts $this->existsCouponProduct($coupon$order);
  649.         $couponDiscounts $this->couponDiscounts($coupon$couponProducts);
  650.         return [$couponCode$couponDiscounts];
  651.     }
  652.     /**
  653.      * 注文にクーポン対象商品が含まれているか確認する.
  654.      *
  655.      * @param Coupon $Coupon
  656.      * @param ItemHolderInterface  $Order
  657.      *
  658.      * @return array
  659.      */
  660.     private function existsCouponProduct(Coupon $CouponItemHolderInterface $Order)
  661.     {
  662.         $couponProducts = [];
  663.         if (!is_null($Coupon)) {
  664.             // 対象商品の存在確認
  665.             if ($Coupon->getCouponType() == Coupon::PRODUCT) {
  666.                 // 商品の場合
  667.                 $couponProducts $this->containsProduct($Coupon$Order);
  668.             } elseif ($Coupon->getCouponType() == Coupon::CATEGORY) {
  669.                 // カテゴリの場合
  670.                 $couponProducts $this->containsCategory($Coupon$Order);
  671.             } elseif ($Coupon->getCouponType() == Coupon::ALL) {
  672.                 // all product
  673.                 // 一致する商品IDがあればtrueを返す
  674.                 /** @var OrderItem $detail */
  675.                 foreach ($Order->getItems()->getProductClasses() as $detail) {
  676.                     $couponProducts $this->getCouponProducts($detail$couponProducts);
  677.                 }
  678.             }
  679.         }
  680.         return $couponProducts;
  681.     }
  682.     /**
  683.      * 合計、値引きを再計算する.
  684.      *
  685.      * 税率が 0 以下の場合は、TaxRule から取得し直して再計算する
  686.      *
  687.      * @param Coupon $Coupon
  688.      * @param array $couponProducts ProductClass::id をキーにした単価, 数量, 税率の連想配列
  689.      * @return array $couponDiscounts ProductClass::id をキーにした discount
  690.      */
  691.     public function couponDiscounts(Coupon $Coupon$couponProducts)
  692.     {
  693.         $couponDiscounts = [];
  694.         // クーポンコードが存在する場合カートに入っている商品の値引き額を設定する
  695.         if ($Coupon) {
  696.             // 対象商品の存在確認.
  697.             // 割引対象商品が存在する場合は値引き額を取得し、クーポンの対象となる ProductClass の数で値引き額を割る
  698.             // 割引対象商品がある場合は値引き額を ProductClass ごとに計算する
  699.             if ($Coupon->getDiscountType() == Coupon::DISCOUNT_PRICE) {
  700.                 $discount $Coupon->getDiscountPrice();
  701.                 foreach ($couponProducts as $productClassId => $value) {
  702.                     $couponDiscounts[$productClassId] = $discount count($couponProducts);
  703.                 }
  704.             } else {
  705.                 $entityManager $this->container->get('doctrine')->getManager();
  706.                 $productClassRepository $entityManager->getRepository(ProductClass::class);
  707.                 $taxRuleRepository $entityManager->getRepository(TaxRule::class);
  708.                 $taxRuleService $this->container->get(TaxRuleService::class);
  709.                 // 値引き前の金額で割引率を算出する
  710.                 // /** @var TaxRule $DefaultTaxRule */
  711.                 $DefaultTaxRule $taxRuleRepository->getByRule();
  712.                 // include tax
  713.                 foreach ($couponProducts as $productClassId => $value) {
  714.                     if ($value['tax_rate'] < || $value['rounding_type_id'] === null) {
  715.                         $ProductClass $productClassRepository->find($productClassId);
  716.                         $TaxRule $taxRuleRepository->getByRule($ProductClass->getProduct(), $ProductClass);
  717.                         $value['tax_rate'] = $TaxRule->getTaxRate();
  718.                         $value['rounding_type_id'] = $TaxRule->getRoundingType()->getId();
  719.                     }
  720.                     $subTotal = ($value['price'] + $taxRuleService->calcTax($value['price'], $value['tax_rate'], $value['rounding_type_id'])) * $value['quantity'];
  721.                     // // 丸め規則はデフォルトの課税規則に従う
  722.                     $discount $taxRuleService->calcTax(
  723.                         $subTotal,
  724.                         $Coupon->getDiscountRate(),
  725.                         $DefaultTaxRule->getRoundingType()->getId(),
  726.                         $DefaultTaxRule->getTaxAdjust()
  727.                     );
  728.                     $couponDiscounts[$productClassId] = $discount;
  729.                 }
  730.             }
  731.         }
  732.         return $couponDiscounts;
  733.     }
  734.     /**
  735.      * 商品がクーポン適用の対象か調査する.
  736.      *
  737.      * @param Coupon $Coupon
  738.      * @param ItemHolderInterface  $Order
  739.      *
  740.      * @return array
  741.      */
  742.     private function containsProduct(Coupon $CouponItemHolderInterface $Order)
  743.     {
  744.         // クーポンの対象商品IDを配列にする
  745.         $targetProductIds = [];
  746.         $couponProducts = [];
  747.         foreach ($Coupon->getCouponDetails() as $detail) {
  748.             $targetProductIds[] = $detail->getProduct()->getId();
  749.         }
  750.         // 一致する商品IDがあればtrueを返す
  751.         /* @var $detail OrderItem */
  752.         foreach ($Order->getProductOrderItems() as $detail) {
  753.             if (in_array($detail->getProduct()->getId(), $targetProductIds)) {
  754.                 $couponProducts $this->getCouponProducts($detail$couponProducts);
  755.             }
  756.         }
  757.         return $couponProducts;
  758.     }
  759.     /**
  760.      * カテゴリがクーポン適用の対象か調査する.
  761.      * 下位のカテゴリから上位のカテゴリに向けて検索する.
  762.      *
  763.      * @param Coupon $Coupon
  764.      * @param ItemHolderInterface  $Order
  765.      *
  766.      * @return array
  767.      */
  768.     private function containsCategory(Coupon $CouponItemHolderInterface $Order)
  769.     {
  770.         // クーポンの対象カテゴリIDを配列にする
  771.         $targetCategoryIds = [];
  772.         $couponProducts = [];
  773.         foreach ($Coupon->getCouponDetails() as $detail) {
  774.             $targetCategoryIds[] = $detail->getCategory()->getId();
  775.         }
  776.         // 受注データからカテゴリIDを取得する
  777.         /* @var $orderDetail OrderItem */
  778.         foreach ($Order->getProductOrderItems() as $orderDetail) {
  779.             foreach ($orderDetail->getProduct()->getProductCategories() as $productCategory) {
  780.                 if ($this->existsDepthCategory($targetCategoryIds$productCategory->getCategory())) {
  781.                     $couponProducts $this->getCouponProducts($orderDetail$couponProducts);
  782.                     break;
  783.                 }
  784.             }
  785.         }
  786.         return $couponProducts;
  787.     }
  788.     /**
  789.      * クーポン対象のカテゴリが存在するか確認にする.
  790.      *
  791.      * @param array      $targetCategoryIds
  792.      * @param Category $Category
  793.      *
  794.      * @return bool
  795.      */
  796.     private function existsDepthCategory(&$targetCategoryIdsCategory $Category)
  797.     {
  798.         // Categoryがnullならfalse
  799.         if (is_null($Category)) {
  800.             return false;
  801.         }
  802.         // 対象カテゴリか確認
  803.         if (in_array($Category->getId(), $targetCategoryIds)) {
  804.             return true;
  805.         }
  806.         // Categoryをテーブルから取得
  807.         if (is_null($Category->getParent())) {
  808.             return false;
  809.         }
  810.         // 親カテゴリをテーブルから取得
  811.         /** @var Category $ParentCategory */
  812.         $entityManager $this->container->get('doctrine')->getManager();
  813.         $categoryRepository $entityManager->getRepository(Category::class);
  814.         $ParentCategory $categoryRepository->find($Category->getParent());
  815.         if ($ParentCategory) {
  816.             return false;
  817.         }
  818.         return $this->existsDepthCategory($targetCategoryIds$ParentCategory);
  819.     }
  820.     /**
  821.      * @param OrderItem $orderItem
  822.      * @param array $couponProducts
  823.      *
  824.      * @return mixed
  825.      */
  826.     private function getCouponProducts(OrderItem $orderItem, array $couponProducts = [])
  827.     {
  828.         if (array_key_exists($orderItem->getProductClass()->getId(), $couponProducts)) {
  829.             $couponProducts[$orderItem->getProductClass()->getId()]['quantity'] += $orderItem->getQuantity();
  830.         } else {
  831.             $couponProducts[$orderItem->getProductClass()->getId()] = [
  832.                 'price' => $orderItem->getPrice(),
  833.                 'quantity' => $orderItem->getQuantity(),
  834.                 'tax_rate' => $orderItem->getTaxRate(),
  835.                 'rounding_type_id' => $orderItem->getRoundingType() ? $orderItem->getRoundingType()->getId() : null,
  836.             ];
  837.         }
  838.         return $couponProducts;
  839.     }
  840. }