<?php 
/** 
 * Copyright(c) 2019 SYSTEM_KD 
 * Date: 2019/06/23 
 */ 
 
namespace Plugin\PointExDx\EventSubscriber; 
 
 
use Eccube\Entity\Product; 
use Eccube\Event\TemplateEvent; 
use Plugin\PointExDx\Service\FormViewHelper; 
use Plugin\PointExDx\Service\PointExDxHelper; 
use Plugin\PointExDx\Service\TwigRenderService\TwigRenderService; 
use Symfony\Component\EventDispatcher\EventSubscriberInterface; 
use Symfony\Component\Form\FormView; 
 
class AdminProductEventSubscriber implements EventSubscriberInterface 
{ 
 
    /** @var TwigRenderService */ 
    protected $twigRenderService; 
 
    /** @var FormViewHelper */ 
    protected $formViewHelper; 
 
    protected $pointExHelper; 
 
    public function __construct( 
        TwigRenderService $twigRenderService, 
        FormViewHelper $formViewHelper, 
        PointExDxHelper $pointExHelper 
    ) 
    { 
        $this->twigRenderService = $twigRenderService; 
        $this->formViewHelper = $formViewHelper; 
        $this->pointExHelper = $pointExHelper; 
    } 
 
    /** 
     * 商品登録 
     * 
     * @param TemplateEvent $event 
     */ 
    public function onTemplateProductProduct(TemplateEvent $event) 
    { 
 
        if (!$this->pointExHelper->isPointUse()) { 
            // ポイント利用が無効の場合は追加しない 
            return; 
        } 
 
        $this->twigRenderService->initRenderService($event); 
 
        /** @var Product $Product */ 
        $Product = $event->getParameter('Product'); 
 
        if ($Product->hasProductClass()) { 
            // 規格あり商品 
        } else { 
            // 規格なし商品 
            $this->twigRenderService 
                ->insertBuilder() 
                ->find('.c-primaryCol > div') 
                ->eq(0) 
                ->setTemplate('@PointExDx/admin/Product/point_ex_area.twig') 
                ->setTargetId('plugin_point_ex_block') 
                ->setInsertModeAfter(); 
 
            $this->twigRenderService->addSupportSnippet(); 
        } 
    } 
 
    /** 
     * 商品規格登録 
     * 
     * @param TemplateEvent $event 
     */ 
    public function onTemplateProductClassEdit(TemplateEvent $event) 
    { 
 
        if (!$this->pointExHelper->isPointUse()) { 
            // ポイント利用が無効の場合は追加しない 
            return; 
        } 
 
        $this->twigRenderService->initRenderService($event); 
 
        /** @var FormView $form */ 
        $form = $event->getParameter('form'); 
 
        // エラー状態の判定 
        $formProductClasses = $form['product_classes']; 
 
        $list = []; 
 
        /** @var FormView $formRow */ 
        foreach ($formProductClasses as $formRow) { 
            $this->formViewHelper->validList($list, $formRow); 
        } 
 
        $pointExInputValidOther = true; 
        $pointExInputValid = true; 
 
        foreach ($list as $item) { 
 
            if ('PointExDxProductClasses' == 
                $this->formViewHelper->getParentName($item)) { 
                $pointExInputValid = false; 
            } else { 
                $pointExInputValidOther = false; 
            } 
        } 
 
        $event->setParameter('pointExInputValidOther', $pointExInputValidOther); 
        $event->setParameter('pointExInputValid', $pointExInputValid); 
 
        /** @var Product $Product */ 
        $Product = $event->getParameter('Product'); 
 
        // 切り替えボタン 
        $this->twigRenderService 
            ->insertBuilder() 
            ->find('form') 
            ->find('.justify-content-between') 
            ->find('div > span') 
            ->eq(0) 
            ->setTargetId('point_ex_change') 
            ->setInsertModeAppend(); 
 
        if (!$pointExInputValidOther 
            && !$pointExInputValid) { 
 
            // エラーメッセージ 
            $this->twigRenderService 
                ->insertBuilder() 
                ->find('form') 
                ->find('.justify-content-between') 
                ->find('div') 
                ->eq(0) 
                ->setTargetId('point_ex_msg') 
                ->setInsertModeAppend(); 
        } 
 
        // タイトル 
        $this->twigRenderService 
            ->insertBuilder() 
            ->find('#ex-product_class > table > thead') 
            ->eq(0) 
            ->setTargetId('point_ex_thead') 
            ->setInsertModeAfter(); 
 
        // リスト 
        $eachChild = $this->twigRenderService->eachChildBuilder(); 
        $eachChild 
            ->findAndDataKey('#ex-product_class-', 'point_ex_product_class_name') 
            ->targetFindThis() 
            ->setInsertModeAfter(); 
 
        $this->twigRenderService 
            ->eachBuilder() 
            ->find('.product_class_point_ex_target') 
            ->each($eachChild->build()); 
 
        $this->twigRenderService->addSupportSnippetSlow( 
            '@PointExDx/admin/Product/point_ex_product_class.twig', 
            '@PointExDx/admin/Product/point_ex_product_class_js.twig' 
        ); 
 
    } 
 
    /** 
     * 商品一覧テンプレート 
     * 
     * @param TemplateEvent $event 
     */ 
    public function onTemplateProductIndex(TemplateEvent $event) 
    { 
 
        $this->twigRenderService->initRenderService($event); 
 
        $child = $this->twigRenderService 
            ->eachChildBuilder() 
            ->findAndDataKey('#ex-product-', 'point_ex_product_id') 
            ->find('td') 
            ->eq(5) 
            ->targetFindThis() 
            ->setInsertModeAppend(); 
 
        $this->twigRenderService 
            ->eachBuilder() 
            ->find('.point_ex_bonus') 
            ->each($child->build()); 
 
        $this->twigRenderService->addSupportSnippet( 
            '@PointExDx/admin/Product/index_add.twig' 
        ); 
    } 
 
    /** 
     * Returns an array of event names this subscriber wants to listen to. 
     * 
     * The array keys are event names and the value can be: 
     * 
     *  * The method name to call (priority defaults to 0) 
     *  * An array composed of the method name to call and the priority 
     *  * An array of arrays composed of the method names to call and respective 
     *    priorities, or 0 if unset 
     * 
     * For instance: 
     * 
     *  * ['eventName' => 'methodName'] 
     *  * ['eventName' => ['methodName', $priority]] 
     *  * ['eventName' => [['methodName1', $priority], ['methodName2']]] 
     * 
     * @return array The event names to listen to 
     */ 
    public static function getSubscribedEvents() 
    { 
        return [ 
            // 商品詳細 
            '@admin/Product/product.twig' => ['onTemplateProductProduct'], 
            // 規格登録 
            '@admin/Product/product_class.twig' => ['onTemplateProductClassEdit', -10], 
            // 商品一覧 
            '@admin/Product/index.twig' => ['onTemplateProductIndex', 10], 
        ]; 
    } 
}