app/Plugin/ApgRichCategory42/Event.php line 200

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.                 ) {
  102.                     if (!empty($childForm->vars['eccube_form_options']['auto_render'])) {
  103.                         $childForm->vars['eccube_form_options']['auto_render'] = false;
  104.                     }
  105.                 }
  106.             }
  107.         }
  108.         $parameters['forms'] = $forms;
  109.         $prefixPattern preg_quote('{% for f in forms[Category.id]|filter(f => f.vars.eccube_form_options.auto_render) %}');
  110.         $suffixPattern preg_quote('{% endfor %}');
  111.         $pattern '|' $prefixPattern '(.*?)' $suffixPattern '|s';
  112.         $addRow $this->twig->getLoader()->getSourceContext(self::TEMPLATE_NAMESPACE '/admin/product_category_edit.twig')->getCode();
  113.         if (preg_match($pattern$source$matchesPREG_OFFSET_CAPTURE)) {
  114.             $replacement $matches[0][0] . $addRow;
  115.             $source preg_replace($pattern$replacement$source);
  116.         }
  117.         $event->setSource($source);
  118.         $event->setParameters($parameters);
  119. //        $event->addSnippet(self::TEMPLATE_NAMESPACE . '/admin/upload_file_js.twig');
  120.     }
  121.     /**
  122.      * @param Event $event
  123.      */
  124.     public function onAdminProductCategoryIndexComplete(EventArgs $event)
  125.     {
  126.         /** @var FormInterface $form */
  127.         $form $event->getArgument('form');
  128.         /** @var Category $Category */
  129.         $Category $event->getArgument('TargetCategory');
  130.         $imageFile null;
  131.         $fileDeleteFlag false;
  132.         $slug $Category->getSlug();
  133.         if (!empty($slug)) {
  134.             $slug ltrim($slug"/");
  135.         }
  136.         $Category->setSlug($slug);
  137.         // @FIXME EC-CUBEコアのバグで、正しくform情報を渡してくれないので$_FILEから取得する
  138.         if (isset($_FILES['admin_category'])) {
  139.             /** @var UploadedFile $imageFile */
  140.             $imageFile $form->get('upload_file')->getData();
  141.         } elseif (!empty($_FILES)) {
  142.             $values array_values($_FILES);
  143.             $v $values[0];
  144.             $prop 'upload_file';
  145.             $imageFile = new UploadedFile($v['tmp_name'][$prop], $v['name'][$prop], $v['type'][$prop], $v['error'][$prop]);
  146.             $fileDeleteFlag = !empty($Category->getFileDeleteFlag());
  147.         }
  148.         $orgImageFileName $Category->getFileName();
  149.         if (empty($fileDeleteFlag) && !empty($imageFile) && $imageFile->getSize() > 0) {
  150.             $extension $imageFile->getClientOriginalExtension();
  151.             $fileName date('mdHis') . uniqid('_') . '.' $extension;
  152.         } elseif (!empty($fileDeleteFlag)) {
  153.             $fileName null;
  154.         } else {
  155.             $fileName $orgImageFileName;
  156.         }
  157.         $baseFilePath $this->path->getBasePath();
  158.         $filePath $this->path->categoryImagesRealPath();
  159.         if (empty($fileDeleteFlag)) {
  160.             if (!empty($imageFile) && $imageFile->getSize() > 0) {
  161.                 $imageFile->move($baseFilePath $filePath$fileName);
  162.             }
  163.         } elseif (!empty($orgImageFileName)) {
  164.             @unlink($baseFilePath $filePath $orgImageFileName);
  165.         }
  166.         $Category->setFileName($fileName);
  167.         $this->ProductCategory->save($Category);
  168.         $this->em->flush($Category);
  169.     }
  170.     public function onAdminProductCategoryDeleteComplete(EventArgs $event)
  171.     {
  172.         /** @var Category $Category */
  173.         $Category $event->getArgument('TargetCategory');
  174.         if (!empty($Category->getFileName())) {
  175.             $baseFilePath $this->path->getBasePath();
  176.             $filePath $this->path->categoryImagesRealPath();
  177.             $fileSystem = new Filesystem();
  178.             $fileSystem->remove($baseFilePath $filePath $Category->getFileName());
  179.         }
  180.     }
  181.     public function onFrontProductIndexInitialize(EventArgs $event)
  182.     {
  183.         /** @var Request $request */
  184.         $request $event->getRequest();
  185.         /** @var ConfigRepository $configRepository */
  186.         $configRepository $this->em->getRepository(Config::class);
  187.         $config $configRepository->getOrNew();
  188.         if ($config->getUrlType() === UrlType::SLUG) {
  189.             /** @var CategoryRepository $categoryRepository */
  190.             $categoryRepository $this->em->getRepository(Category::class);
  191.             $pathInfo $request->getPathInfo();
  192.             $path ltrim($pathInfo"/");
  193.             /** @var Category $Category */
  194.             $Category $categoryRepository->findOneBy([
  195.                 'slug' => $path
  196.             ]);
  197.             if (!empty($Category)) {
  198.                 $request->query->add(['category_id' => $Category->getId()]);
  199.                 $this->setPageLayout();
  200.             }
  201.         } elseif ($config->getUrlType() === UrlType::ID) {
  202.             $categoryId $request->attributes->get('category_id');
  203.             if (!empty($categoryId)) {
  204.                 $request->query->add(['category_id' => $categoryId]);
  205.                 $this->setPageLayout();
  206.             }
  207.         }
  208.     }
  209.     protected function setPageLayout()
  210.     {
  211.         // PageLayout の設定
  212.         $route 'product_list';
  213.         $type DeviceType::DEVICE_TYPE_PC;
  214.         if ($this->mobileDetector->isMobile()) {
  215.             $type DeviceType::DEVICE_TYPE_MB;
  216.         }
  217.         // URLからPageを取得
  218.         /** @var PageRepository $pageRepository */
  219.         $pageRepository $this->em->getRepository(Page::class);
  220.         $Page $pageRepository->getPageByRoute($route);
  221.         if (!empty($Page)) {
  222.             /** @var PageLayout[] $PageLayouts */
  223.             $PageLayouts $Page->getPageLayouts();
  224.             // Pageに紐づくLayoutからDeviceTypeが一致するLayoutを探す
  225.             $Layout null;
  226.             foreach ($PageLayouts as $PageLayout) {
  227.                 if ($PageLayout->getDeviceTypeId() == $type) {
  228.                     $Layout $PageLayout->getLayout();
  229.                     break;
  230.                 }
  231.             }
  232.             // Pageに紐づくLayoutにDeviceTypeが一致するLayoutがない場合はPCのレイアウトを探す
  233.             if (!$Layout) {
  234.                 log_info('fallback to PC layout');
  235.                 foreach ($PageLayouts as $PageLayout) {
  236.                     if ($PageLayout->getDeviceTypeId() == DeviceType::DEVICE_TYPE_PC) {
  237.                         $Layout $PageLayout->getLayout();
  238.                         break;
  239.                     }
  240.                 }
  241.             }
  242.             if ($Layout) {
  243.                 // lazy loadを制御するため, Layoutを取得しなおす.
  244.                 /** @var LayoutRepository $layoutRepository */
  245.                 $layoutRepository $this->em->getRepository(Layout::class);
  246.                 $Layout $layoutRepository->get($Layout->getId());
  247.                 $this->twig->addGlobal('Layout'$Layout);
  248.             }
  249.             $this->twig->addGlobal('Page'$Page);
  250.             $this->twig->addGlobal('title'$Page->getName());
  251.         }
  252.     }
  253.     /**
  254.      * @param TemplateEvent $event
  255.      * @throws \Twig_Error_Loader
  256.      */
  257.     public function onFrontProductListRender(TemplateEvent $event)
  258.     {
  259.         $source $event->getSource();
  260.         $parameters $event->getParameters();
  261.         if (!empty($parameters['Category'])) {
  262.             /** @var Category $Category */
  263.             $Category $parameters['Category'];
  264.             /** @var Config $config */
  265.             $config $this->Config->getOrNew();
  266.             if (!empty($Category->getMetaDescription())) {
  267.                 /** @var \Twig_Environment $twig */
  268.                 $globals $this->twig->mergeGlobals(array());
  269.                 if (isset($globals['Page'])) {
  270.                     /** @var Page $page */
  271.                     $page $globals['Page'];
  272.                     $page->setDescription($Category->getMetaDescription());
  273.                 }
  274.             }
  275.             // data
  276.             $insertContentType $config->getInsertContentType();
  277.             if ($insertContentType === InsertContentType::UPPER) {
  278.                 $pattern '|<div class="ec-searchnavRole__topicpath">|';
  279.                 $addRow $this->twig->getLoader()->getSourceContext('ApgRichCategory42/Resource/template/front/insert_content.twig')->getCode();
  280.                 if (preg_match($pattern$source$matchesPREG_OFFSET_CAPTURE)) {
  281.                     $replacement $addRow $matches[0][0];
  282.                     $source preg_replace($pattern$replacement$source);
  283.                 }
  284.             } elseif ($insertContentType === InsertContentType::BOTTOM) {
  285.                 $pattern '{% block main %}';
  286.                 $pattern2 '|{% endblock %}|';
  287.                 $addRow $this->twig->getLoader()->getSourceContext('ApgRichCategory42/Resource/template/front/insert_content.twig')->getCode();
  288.                 if ($pos strpos($source$pattern)) {
  289.                     $splitContent substr($source$pos);
  290.                     if (preg_match($pattern2$splitContent$matchesPREG_OFFSET_CAPTURE)) {
  291.                         $replacement $addRow $matches[0][0];
  292.                         $replaceContent preg_replace($pattern2$replacement$splitContent);
  293.                         $source str_replace($splitContent$replaceContent$source);
  294.                     }
  295.                 }
  296.             }
  297.         }
  298.         $event->setParameters($parameters);
  299.         $event->setSource($source);
  300.         $event->addAsset(self::TEMPLATE_NAMESPACE '/front/render_product_list_css.twig');
  301.     }
  302. }