app/Plugin/ApgRichCategory42/Event.php line 98

Open in your IDE?
  1. <?php
  2. namespace Plugin\ApgRichCategory42;
  3. use Detection\MobileDetect;
  4. use Doctrine\ORM\EntityManagerInterface;
  5. use Eccube\Entity\Category;
  6. use Eccube\Entity\Layout;
  7. use Eccube\Entity\Master\DeviceType;
  8. use Eccube\Entity\Page;
  9. use Eccube\Entity\PageLayout;
  10. use Eccube\Event\EccubeEvents;
  11. use Eccube\Event\EventArgs;
  12. use Eccube\Event\TemplateEvent;
  13. use Eccube\Repository\CategoryRepository;
  14. use Eccube\Repository\LayoutRepository;
  15. use Eccube\Repository\PageRepository;
  16. use Eccube\Repository\ProductCategoryRepository;
  17. use Eccube\Util\CacheUtil;
  18. use Plugin\ApgRichCategory42\Domain\InsertContentType;
  19. use Plugin\ApgRichCategory42\Domain\UrlType;
  20. use Plugin\ApgRichCategory42\Entity\Config;
  21. use Plugin\ApgRichCategory42\Repository\ConfigRepository;
  22. use Plugin\ApgRichCategory42\Util\Paths;
  23. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  24. use Symfony\Component\Filesystem\Filesystem;
  25. use Symfony\Component\Form\FormInterface;
  26. use Symfony\Component\Form\FormView;
  27. use Symfony\Component\HttpFoundation\File\UploadedFile;
  28. use Symfony\Component\HttpFoundation\Request;
  29. use Symfony\Component\Routing\Router;
  30. use Symfony\Component\Routing\RouterInterface;
  31. use Twig\Environment;
  32. class Event implements EventSubscriberInterface
  33. {
  34.     const TEMPLATE_NAMESPACE = '@ApgRichCategory42';
  35.     /** @var ConfigRepository */
  36.     protected $Config;
  37.     /** @var ProductCategoryRepository */
  38.     protected $ProductCategory;
  39.     /** @var EntityManagerInterface */
  40.     protected $em;
  41.     /** @var \Twig_Environment */
  42.     protected $twig;
  43.     /** @var Paths */
  44.     protected $path;
  45.     /** @var Router */
  46.     protected $router;
  47.     /** @var MobileDetect */
  48.     protected $mobileDetector;
  49.     /** @var CacheUtil */
  50.     protected $cacheUtil;
  51.     public function __construct(
  52.         ConfigRepository          $configRepository,
  53.         ProductCategoryRepository $productCategoryRepository,
  54.         EntityManagerInterface    $em,
  55.         Environment               $twig,
  56.         Paths                     $path,
  57.         RouterInterface           $router,
  58.         CacheUtil                 $cacheUtil,
  59.         MobileDetect              $mobileDetector
  60.     )
  61.     {
  62.         $this->Config = $configRepository;
  63.         $this->ProductCategory = $productCategoryRepository;
  64.         $this->em = $em;
  65.         $this->twig = $twig;
  66.         $this->path = $path;
  67.         $this->cacheUtil = $cacheUtil;
  68.         $this->router = $router;
  69.         $this->mobileDetector = $mobileDetector;
  70.     }
  71.     /**
  72.      * @return array
  73.      */
  74.     public static function getSubscribedEvents()
  75.     {
  76.         return [
  77.             '@admin/Product/category.twig' => 'onAdminProductCategoryRender',
  78.             EccubeEvents::ADMIN_PRODUCT_CATEGORY_INDEX_COMPLETE => 'onAdminProductCategoryIndexComplete',
  79.             EccubeEvents::ADMIN_PRODUCT_CATEGORY_DELETE_COMPLETE => 'onAdminProductCategoryDeleteComplete',
  80.             EccubeEvents::FRONT_PRODUCT_INDEX_INITIALIZE => 'onFrontProductIndexInitialize',
  81.             'Product/list.twig' => 'onFrontProductListRender',
  82. //            'kernel.request' => 'onKernelRequest',    // @TODO
  83.         ];
  84.     }
  85.     /**
  86.      * @param TemplateEvent $event
  87.      * @throws \Twig_Error_Loader
  88.      */
  89.     public function onAdminProductCategoryRender(TemplateEvent $event)
  90.     {
  91.         $source = $event->getSource();
  92.         $parameters = $event->getParameters();
  93.         $forms = $parameters['forms'];
  94.         /** @var FormView $form */
  95.         foreach ($forms as $form) {
  96.             /** @var FormView $childForm */
  97.             foreach ($form->children as $childForm) {
  98.                 if (
  99.                     $childForm->vars['name'] === 'file_name'
  100.                     || $childForm->vars['name'] === 'file_delete_flag'
  101.                     || $childForm->vars['name'] === 'logo_file_name'
  102.                     || $childForm->vars['name'] === 'logo_file_delete_flag'
  103.                 ) {
  104.                     if (!empty($childForm->vars['eccube_form_options']['auto_render'])) {
  105.                         $childForm->vars['eccube_form_options']['auto_render'] = false;
  106.                     }
  107.                 }
  108.             }
  109.         }
  110.         $parameters['forms'] = $forms;
  111.         $prefixPattern = preg_quote('{% for f in forms[Category.id]|filter(f => f.vars.eccube_form_options.auto_render) %}');
  112.         $suffixPattern = preg_quote('{% endfor %}');
  113.         $pattern = '|' . $prefixPattern . '(.*?)' . $suffixPattern . '|s';
  114.         $addRow = $this->twig->getLoader()->getSourceContext(self::TEMPLATE_NAMESPACE . '/admin/product_category_edit.twig')->getCode();
  115.         if (preg_match($pattern, $source, $matches, PREG_OFFSET_CAPTURE)) {
  116.             $replacement = $matches[0][0] . $addRow;
  117.             $source = preg_replace($pattern, $replacement, $source);
  118.         }
  119.         $event->setSource($source);
  120.         $event->setParameters($parameters);
  121. //        $event->addSnippet(self::TEMPLATE_NAMESPACE . '/admin/upload_file_js.twig');
  122.     }
  123.     /**
  124.      * @param Event $event
  125.      */
  126.     public function onAdminProductCategoryIndexComplete(EventArgs $event)
  127.     {
  128.         /** @var FormInterface $form */
  129.         $form = $event->getArgument('form');
  130.         /** @var Category $Category */
  131.         $Category = $event->getArgument('TargetCategory');
  132.         $imageFile = null;
  133.         $fileDeleteFlag = false;
  134.         $slug = $Category->getSlug();
  135.         if (!empty($slug)) {
  136.             $slug = ltrim($slug, "/");
  137.         }
  138.         $Category->setSlug($slug);
  139.         // @FIXME EC-CUBEコアのバグで、正しくform情報を渡してくれないので$_FILEから取得する
  140.         if (isset($_FILES['admin_category'])) {
  141.             /** @var UploadedFile $imageFile */
  142.             $imageFile = $form->get('upload_file')->getData();
  143.         } elseif (!empty($_FILES)) {
  144.             $values = array_values($_FILES);
  145.             $v = $values[0];
  146.             $prop = 'upload_file';
  147.             $imageFile = new UploadedFile($v['tmp_name'][$prop], $v['name'][$prop], $v['type'][$prop], $v['error'][$prop]);
  148.             $fileDeleteFlag = !empty($Category->getFileDeleteFlag());
  149.         }
  150.         $orgImageFileName = $Category->getFileName();
  151.         if (empty($fileDeleteFlag) && !empty($imageFile) && $imageFile->getSize() > 0) {
  152.             $extension = $imageFile->getClientOriginalExtension();
  153.             $fileName = date('mdHis') . uniqid('_') . '.' . $extension;
  154.         } elseif (!empty($fileDeleteFlag)) {
  155.             $fileName = null;
  156.         } else {
  157.             $fileName = $orgImageFileName;
  158.         }
  159.         $baseFilePath = $this->path->getBasePath();
  160.         $filePath = $this->path->categoryImagesRealPath();
  161.         if (empty($fileDeleteFlag)) {
  162.             if (!empty($imageFile) && $imageFile->getSize() > 0) {
  163.                 $imageFile->move($baseFilePath . $filePath, $fileName);
  164.             }
  165.         } elseif (!empty($orgImageFileName)) {
  166.             @unlink($baseFilePath . $filePath . $orgImageFileName);
  167.         }
  168.         $Category->setFileName($fileName);
  169.         //ロゴ画像
  170.         if (isset($_FILES['admin_category'])) {
  171.             /** @var UploadedFile $logoImageFile */
  172.             $logoImageFile = $form->get('logo_upload_file')->getData();
  173.         } elseif (!empty($_FILES)) {
  174.             $values = array_values($_FILES);
  175.             $v = $values[0];
  176.             $prop = 'logo_upload_file';
  177.             $logoImageFile = new UploadedFile($v['tmp_name'][$prop], $v['name'][$prop], $v['type'][$prop], $v['error'][$prop]);
  178.             $logoFileDeleteFlag = !empty($Category->getLogoFileDeleteFlag());
  179.         }
  180.         $orgLogoImageFileName = $Category->getLogoFileName();
  181.         if (empty($logofileDeleteFlag) && !empty($logoImageFile) && $logoImageFile->getSize() > 0) {
  182.             $extension = $logoImageFile->getClientOriginalExtension();
  183.             $logoFileName = date('mdHis') . uniqid('_') . '.' . $extension;
  184.         } elseif (!empty($logoFileDeleteFlag)) {
  185.             $logoFileName = null;
  186.         } else {
  187.             $logoFileName = $orgLogoImageFileName;
  188.         }
  189.         $baseFilePath = $this->path->getBasePath();
  190.         $filePath = $this->path->categoryImagesRealPath();
  191.         if (empty($logoFileDeleteFlag)) {
  192.             if (!empty($logoImageFile) && $logoImageFile->getSize() > 0) {
  193.                 $logoImageFile->move($baseFilePath . $filePath, $logoFileName);
  194.             }
  195.         } elseif (!empty($orgLogoImageFileName)) {
  196.             @unlink($baseFilePath . $filePath . $orgLogoImageFileName);
  197.         }
  198.         $Category->setLogoFileName($logoFileName);
  199.         $this->ProductCategory->save($Category);
  200.         $this->em->flush($Category);
  201.     }
  202.     public function onAdminProductCategoryDeleteComplete(EventArgs $event)
  203.     {
  204.         /** @var Category $Category */
  205.         $Category = $event->getArgument('TargetCategory');
  206.         if (!empty($Category->getFileName())) {
  207.             $baseFilePath = $this->path->getBasePath();
  208.             $filePath = $this->path->categoryImagesRealPath();
  209.             $fileSystem = new Filesystem();
  210.             $fileSystem->remove($baseFilePath . $filePath . $Category->getFileName());
  211.         }
  212.         if (!empty($Category->getLogoFileName())) {
  213.             $baseFilePath = $this->path->getBasePath();
  214.             $filePath = $this->path->categoryImagesRealPath();
  215.             $fileSystem = new Filesystem();
  216.             $fileSystem->remove($baseFilePath . $filePath . $Category->getLogoFileName());
  217.         }
  218.     }
  219.     public function onFrontProductIndexInitialize(EventArgs $event)
  220.     {
  221.         /** @var Request $request */
  222.         $request = $event->getRequest();
  223.         /** @var ConfigRepository $configRepository */
  224.         $configRepository = $this->em->getRepository(Config::class);
  225.         $config = $configRepository->getOrNew();
  226.         if ($config->getUrlType() === UrlType::SLUG) {
  227.             /** @var CategoryRepository $categoryRepository */
  228.             $categoryRepository = $this->em->getRepository(Category::class);
  229.             $pathInfo = $request->getPathInfo();
  230.             $path = ltrim($pathInfo, "/");
  231.             /** @var Category $Category */
  232.             $Category = $categoryRepository->findOneBy([
  233.                 'slug' => $path
  234.             ]);
  235.             if (!empty($Category)) {
  236.                 $request->query->add(['category_id' => $Category->getId()]);
  237.                 $this->setPageLayout();
  238.             }
  239.         } elseif ($config->getUrlType() === UrlType::ID) {
  240.             $categoryId = $request->attributes->get('category_id');
  241.             if (!empty($categoryId)) {
  242.                 $request->query->add(['category_id' => $categoryId]);
  243.                 $this->setPageLayout();
  244.             }
  245.         }
  246.     }
  247.     protected function setPageLayout()
  248.     {
  249.         // PageLayout の設定
  250.         $route = 'product_list';
  251.         $type = DeviceType::DEVICE_TYPE_PC;
  252.         if ($this->mobileDetector->isMobile()) {
  253.             $type = DeviceType::DEVICE_TYPE_MB;
  254.         }
  255.         // URLからPageを取得
  256.         /** @var PageRepository $pageRepository */
  257.         $pageRepository = $this->em->getRepository(Page::class);
  258.         $Page = $pageRepository->getPageByRoute($route);
  259.         if (!empty($Page)) {
  260.             /** @var PageLayout[] $PageLayouts */
  261.             $PageLayouts = $Page->getPageLayouts();
  262.             // Pageに紐づくLayoutからDeviceTypeが一致するLayoutを探す
  263.             $Layout = null;
  264.             foreach ($PageLayouts as $PageLayout) {
  265.                 if ($PageLayout->getDeviceTypeId() == $type) {
  266.                     $Layout = $PageLayout->getLayout();
  267.                     break;
  268.                 }
  269.             }
  270.             // Pageに紐づくLayoutにDeviceTypeが一致するLayoutがない場合はPCのレイアウトを探す
  271.             if (!$Layout) {
  272.                 log_info('fallback to PC layout');
  273.                 foreach ($PageLayouts as $PageLayout) {
  274.                     if ($PageLayout->getDeviceTypeId() == DeviceType::DEVICE_TYPE_PC) {
  275.                         $Layout = $PageLayout->getLayout();
  276.                         break;
  277.                     }
  278.                 }
  279.             }
  280.             if ($Layout) {
  281.                 // lazy loadを制御するため, Layoutを取得しなおす.
  282.                 /** @var LayoutRepository $layoutRepository */
  283.                 $layoutRepository = $this->em->getRepository(Layout::class);
  284.                 $Layout = $layoutRepository->get($Layout->getId());
  285.                 $this->twig->addGlobal('Layout', $Layout);
  286.             }
  287.             $this->twig->addGlobal('Page', $Page);
  288.             $this->twig->addGlobal('title', $Page->getName());
  289.         }
  290.     }
  291.     /**
  292.      * @param TemplateEvent $event
  293.      * @throws \Twig_Error_Loader
  294.      */
  295.     public function onFrontProductListRender(TemplateEvent $event)
  296.     {
  297.         $source = $event->getSource();
  298.         $parameters = $event->getParameters();
  299.         if (!empty($parameters['Category'])) {
  300.             /** @var Category $Category */
  301.             $Category = $parameters['Category'];
  302.             /** @var Config $config */
  303.             $config = $this->Config->getOrNew();
  304.             if (!empty($Category->getMetaDescription())) {
  305.                 /** @var \Twig_Environment $twig */
  306.                 $globals = $this->twig->mergeGlobals(array());
  307.                 if (isset($globals['Page'])) {
  308.                     /** @var Page $page */
  309.                     $page = $globals['Page'];
  310.                     $page->setDescription($Category->getMetaDescription());
  311.                 }
  312.             }
  313.             // data
  314.             $insertContentType = $config->getInsertContentType();
  315.             if ($insertContentType === InsertContentType::UPPER) {
  316.                 $pattern = '|<div class="ec-searchnavRole__topicpath">|';
  317.                 $addRow = $this->twig->getLoader()->getSourceContext('ApgRichCategory42/Resource/template/front/insert_content.twig')->getCode();
  318.                 if (preg_match($pattern, $source, $matches, PREG_OFFSET_CAPTURE)) {
  319.                     $replacement = $addRow . $matches[0][0];
  320.                     $source = preg_replace($pattern, $replacement, $source);
  321.                 }
  322.             } elseif ($insertContentType === InsertContentType::BOTTOM) {
  323.                 $pattern = '{% block main %}';
  324.                 $pattern2 = '|{% endblock %}|';
  325.                 $addRow = $this->twig->getLoader()->getSourceContext('ApgRichCategory42/Resource/template/front/insert_content.twig')->getCode();
  326.                 if ($pos = strpos($source, $pattern)) {
  327.                     $splitContent = substr($source, $pos);
  328.                     if (preg_match($pattern2, $splitContent, $matches, PREG_OFFSET_CAPTURE)) {
  329.                         $replacement = $addRow . $matches[0][0];
  330.                         $replaceContent = preg_replace($pattern2, $replacement, $splitContent);
  331.                         $source = str_replace($splitContent, $replaceContent, $source);
  332.                     }
  333.                 }
  334.             }
  335.         }
  336.         $event->setParameters($parameters);
  337.         $event->setSource($source);
  338.         $event->addAsset(self::TEMPLATE_NAMESPACE . '/front/render_product_list_css.twig');
  339.     }
  340. }