app/Plugin/ApgRichCategory42/Event.php line 226

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$matchesPREG_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$matchesPREG_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$matchesPREG_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. }