app/Plugin/PiaProductRestock/EventSubscriber/ProductRestockEventSubscriber.php line 60

Open in your IDE?
  1. <?php
  2. namespace Plugin\PiaProductRestock\EventSubscriber;
  3. use Eccube\Event\TemplateEvent;
  4. use Eccube\Repository\ProductRepository;
  5. use Plugin\PiaProductRestock\Repository\ProductRestockRepository;
  6. use Plugin\PiaProductRestock\Repository\ProductRestockCustomerRepository;
  7. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  8. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  9. class ProductRestockEventSubscriber implements EventSubscriberInterface
  10. {
  11.     /**
  12.      * @var ProductRestockRepository
  13.      */
  14.     private $productRestockRepository;
  15.     /**
  16.      * @var ProductRestockCustomerRepository
  17.      */
  18.     private $productRestockCustomerRepository;
  19.     /**
  20.      * @var ProductRepository
  21.      */
  22.     private $productRepository;
  23.     /**
  24.      * @var TokenStorageInterface
  25.      */
  26.     private $tokenStorage;
  27.     public function __construct(
  28.         ProductRestockRepository $productRestockRepository,
  29.         ProductRestockCustomerRepository $productRestockCustomerRepository,
  30.         ProductRepository $productRepository,
  31.         TokenStorageInterface $tokenStorage
  32.     ) {
  33.         $this->productRestockRepository $productRestockRepository;
  34.         $this->productRestockCustomerRepository $productRestockCustomerRepository;
  35.         $this->productRepository $productRepository;
  36.         $this->tokenStorage $tokenStorage;
  37.     }
  38.     /**
  39.      * @return array
  40.      */
  41.     public static function getSubscribedEvents()
  42.     {
  43.         return [
  44.             'Product/detail.twig' => 'onProductDetail',
  45.             '@admin/Product/product.twig' => 'onAdminProductEdit',
  46.         ];
  47.     }
  48.     /**
  49.      * 商品詳細ページに再入荷ボタンを追加
  50.      */
  51.     public function onProductDetail(TemplateEvent $event)
  52.     {
  53.         $parameters $event->getParameters();
  54.         $product $parameters['Product'];
  55.         
  56.         if (!$product) {
  57.             return;
  58.         }
  59.         $productId $product->getId();
  60.         
  61.         // 再入荷情報を取得
  62.         $restock $this->productRestockRepository->findByProductId($productId);
  63.         $dispFlg $restock $restock->getDispFlg() : 0;
  64.         
  65.         // 在庫が0の場合は強制的に非表示
  66.         $stock 0;
  67.         foreach ($product->getProductClasses() as $productClass) {
  68.             if ($productClass->isVisible()) {
  69.                 $stock += $productClass->getStock();
  70.             }
  71.         }
  72.         
  73.         if ($stock 0) {
  74.             $dispFlg 0// 在庫がある場合は非表示
  75.         }
  76.         $parameters['product_restock_disp_flg'] = $dispFlg;
  77.         // ログインユーザーの登録状況
  78.         $registFlg 2// 未登録
  79.         $token $this->tokenStorage->getToken();
  80.         if ($token && $token->getUser() && method_exists($token->getUser(), 'getId')) {
  81.             $customer $token->getUser();
  82.             if ($restock) {
  83.                 $isRegistered $this->productRestockCustomerRepository->isRegistered(
  84.                     $restock->getId(), 
  85.                     $customer->getId()
  86.                 );
  87.                 $registFlg $isRegistered 2;
  88.             }
  89.         }
  90.         $parameters['product_restock_regist_flg'] = $registFlg;
  91.         $parameters['product_restock_id'] = $productId;
  92.         $event->setParameters($parameters);
  93.         // 再入荷ボタンを指定位置に追加
  94.         if ($dispFlg == 1) {
  95.             $source $event->getSource();
  96.             
  97.             // 指定されたHTMLの上に再入荷ボタンを挿入
  98.             $search '/<p class="btm_txt"><a href="(.*)">ご利用方法の詳細はこちら<\/a><\/p>/';
  99.             if (preg_match($search$source$result)) {
  100.                 $searchText $result[0];
  101.                 $replace "{{ include('@PiaProductRestock/front/Product/restock_button.twig') }}" $searchText;
  102.                 $source str_replace($searchText$replace$source);
  103.                 $event->setSource($source);
  104.             }
  105.         }
  106.     }
  107.     /**
  108.      * 管理画面商品編集ページに再入荷ボタンを追加
  109.      */
  110.     public function onAdminProductEdit(TemplateEvent $event)
  111.     {
  112.         $parameters $event->getParameters();
  113.         $product $parameters['Product'];
  114.         
  115.         if (!$product || !$product->getId()) {
  116.             return;
  117.         }
  118.         $productId $product->getId();
  119.         $restock $this->productRestockRepository->findByProductId($productId);
  120.         
  121.         $buttonText '再入荷に登録';
  122.         $actionType 1;
  123.         $statusText '再入荷未登録';
  124.         $isRegistered false;
  125.         if ($restock && $restock->getDispFlg() == 1) {
  126.             $buttonText '再入荷から解除';
  127.             $actionType 0;
  128.             $statusText '再入荷登録中';
  129.             $isRegistered true;
  130.         }
  131.         $parameters['product_restock_button_text'] = $buttonText;
  132.         $parameters['product_restock_action_type'] = $actionType;
  133.         $parameters['product_restock_status_text'] = $statusText;
  134.         $parameters['product_restock_product_id'] = $productId;
  135.         $parameters['product_restock_is_registered'] = $isRegistered;
  136.         $event->setParameters($parameters);
  137.         // テンプレートソースを取得して再入荷項目を追加
  138.         $source $event->getSource();
  139.         
  140.         // ProductPlusと同じように、フォーム要素の前に挿入
  141.         if (preg_match("/\{\%\sfor\sf\sin\sform(\s if|\|filter\(f\s\=\>)\sf\.vars\.eccube\_form\_options\.auto\_render/"$source$result)) {
  142.             $search $result[0];
  143.             $replace "{{ include('@PiaProductRestock/admin/Product/restock_edit.twig') }}" $search;
  144.             $source str_replace($search$replace$source);
  145.         }
  146.         $event->setSource($source);
  147.     }
  148.     /**
  149.      * 商品詳細ページ用のスニペット
  150.      */
  151.     private function getProductDetailSnippet($productId$registFlg$dispFlg)
  152.     {
  153.         if ($dispFlg != 1) {
  154.             return '';
  155.         }
  156.         $buttonText $registFlg == '再入荷通知を解除' '再入荷通知を登録';
  157.         $buttonClass $registFlg == 'btn-secondary' 'btn-primary';
  158.         $actionType $registFlg == 1;
  159.         return sprintf('
  160.             <script>
  161.             $(function() {
  162.                 var restockHtml = `
  163.                     <div class="ec-productRole__btn mt-3">
  164.                         <button type="button" class="btn %s btn-block" onclick="handleRestockAction(%d, %d)">
  165.                             %s
  166.                         </button>
  167.                     </div>
  168.                 `;
  169.                 $(".ec-productRole__btn").last().after(restockHtml);
  170.             });
  171.             function handleRestockAction(productId, type) {
  172.                 if (confirm("再入荷通知を" + (type === 1 ? "登録" : "解除") + "しますか?")) {
  173.                     location.href = "/product_restock/" + productId + "?type=" + type;
  174.                 }
  175.             }
  176.             </script>
  177.         '$buttonClass$productId$actionType$buttonText);
  178.     }
  179.     /**
  180.      * 管理画面商品編集ページ用のスニペット
  181.      */
  182.     private function getAdminProductEditSnippet($productId$buttonText$actionType$statusText)
  183.     {
  184.         return sprintf('
  185.             <script>
  186.             $(function() {
  187.                 var restockHtml = `
  188.                     <div class="row mb-2">
  189.                         <div class="col-3">
  190.                             <span class="badge badge-primary">再入荷管理</span>
  191.                         </div>
  192.                         <div class="col-9">
  193.                             <div class="mb-2">%s</div>
  194.                             <button type="button" class="btn btn-sm btn-outline-secondary" onclick="handleAdminRestockAction(%d, %d)">
  195.                                 %s
  196.                             </button>
  197.                         </div>
  198.                     </div>
  199.                 `;
  200.                 $(".c-container .row").first().after(restockHtml);
  201.             });
  202.             function handleAdminRestockAction(productId, type) {
  203.                 var action = type === 1 ? "登録" : "解除";
  204.                 if (confirm("再入荷商品「" + action + "」しますか?")) {
  205.                     location.href = "/admin/product_restock/regist/" + productId + "?type=" + type;
  206.                 }
  207.             }
  208.             </script>
  209.         '$statusText$productId$actionType$buttonText);
  210.     }
  211. }