app/Plugin/ApgRichCategory/Event.php line 194

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