app/Plugin/ProductOption42/Controller/Admin/OptionCategoryController.php line 72

Open in your IDE?
  1. <?php
  2. /*
  3. * Plugin Name : ProductOption
  4. *
  5. * Copyright (C) BraTech Co., Ltd. All Rights Reserved.
  6. * http://www.bratech.co.jp/
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. namespace Plugin\ProductOption42\Controller\Admin;
  12. use Eccube\Controller\AbstractController;
  13. use Plugin\ProductOption42\Entity\OptionCategory;
  14. use Plugin\ProductOption42\Entity\OptionImage;
  15. use Plugin\ProductOption42\Form\Type\Admin\OptionCategoryType;
  16. use Plugin\ProductOption42\Form\Type\Admin\OptionTextCategoryType;
  17. use Plugin\ProductOption42\Repository\OptionCategoryRepository;
  18. use Plugin\ProductOption42\Repository\OptionImageRepository;
  19. use Plugin\ProductOption42\Repository\OptionRepository;
  20. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  21. use Symfony\Component\Filesystem\Filesystem;
  22. use Symfony\Component\HttpFoundation\File\File;
  23. use Symfony\Component\HttpFoundation\Request;
  24. use Symfony\Component\HttpFoundation\Response;
  25. use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
  26. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  27. use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;
  28. use Symfony\Component\Routing\Annotation\Route;
  29. use Symfony\Component\Routing\RouterInterface;
  30. class OptionCategoryController extends AbstractController
  31. {
  32.     /**
  33.      * @var OptionRepository
  34.      */
  35.     private $optionRepository;
  36.     /**
  37.      * @var OptionCategoryRepository
  38.      */
  39.     private $optionCategoryRepository;
  40.     private $optionImageRepository;
  41.     protected $router;
  42.     /**
  43.      * OptionController constructor.
  44.      * @param OptionRepository $optionRepository
  45.      */
  46.     public function __construct(
  47.             OptionRepository $optionRepository,
  48.             OptionCategoryRepository $optionCategoryRepository,
  49.             OptionImageRepository $optionImageRepository,
  50.             RouterInterface $router
  51.             )
  52.     {
  53.         $this->optionRepository $optionRepository;
  54.         $this->optionCategoryRepository $optionCategoryRepository;
  55.         $this->optionImageRepository $optionImageRepository;
  56.         $this->router $router;
  57.     }
  58.     /**
  59.      * @Route("/%eccube_admin_route%/product/option_category/{option_id}", requirements={"option_id" = "\d+"}, name="admin_product_option_category")
  60.      * @Route("/%eccube_admin_route%/product/option_category/{option_id}/new", requirements={"option_id" = "\d+"}, name="admin_product_option_category_new")
  61.      * @Route("/%eccube_admin_route%/product/option_category/{option_id}/{id}/edit", requirements={"id" = "\d+", "option_id" = "\d+"}, name="admin_product_option_category_edit")
  62.      * @Template("@ProductOption42/admin/Product/option_category.twig")
  63.      */
  64.     public function index(Request $request$option_id$id null)
  65.     {
  66.         //
  67.         $Option $this->optionRepository->find($option_id);
  68.         if (!$Option) {
  69.             throw new NotFoundHttpException();
  70.         }
  71.         if ($id) {
  72.             $TargetOptionCategory $this->optionCategoryRepository->find($id);
  73.             if (!$TargetOptionCategory || $TargetOptionCategory->getOption() != $Option) {
  74.                 throw new NotFoundHttpException();
  75.             }
  76.         } else {
  77.             $TargetOptionCategory = new OptionCategory();
  78.             $TargetOptionCategory->setOption($Option);
  79.         }
  80.         //
  81.         $form $this->formFactory
  82.                 ->createBuilder(OptionCategoryType::class, $TargetOptionCategory)
  83.                 ->getForm();
  84.         // ファイルの登録
  85.         $images = [];
  86.         $OptionImages $TargetOptionCategory->getOptionImages();
  87.         foreach ($OptionImages as $OptionImage) {
  88.             $images[] = $OptionImage->getFileName();
  89.         }
  90.         $form['images']->setData($images);
  91.         if ($request->getMethod() === 'POST') {
  92.             $form->handleRequest($request);
  93.             if ($form->isSubmitted() && $form->isValid()) {
  94.                 // 画像の登録
  95.                 $add_images $form->get('add_images')->getData();
  96.                 foreach ($add_images as $add_image) {
  97.                     $OptionImage = new OptionImage();
  98.                     $OptionImage
  99.                         ->setFileName($add_image)
  100.                         ->setOptionCategory($TargetOptionCategory)
  101.                         ->setSortNo(1);
  102.                     $TargetOptionCategory->addOptionImage($OptionImage);
  103.                     $this->entityManager->persist($OptionImage);
  104.                     // 移動
  105.                     $file = new File($this->eccubeConfig['eccube_temp_image_dir'].'/'.$add_image);
  106.                     $file->move($this->eccubeConfig['eccube_save_image_dir']);
  107.                 }
  108.                 // 画像の削除
  109.                 $delete_images $form->get('delete_images')->getData();
  110.                 $fs = new Filesystem();
  111.                 foreach ($delete_images as $delete_image) {
  112.                     $OptionImage $this->optionImageRepository
  113.                         ->findOneBy(['file_name' => $delete_image]);
  114.                     // 追加してすぐに削除した画像は、Entityに追加されない
  115.                     if ($OptionImage instanceof \Plugin\ProductOption42\Entity\OptionImage) {
  116.                         $TargetOptionCategory->removeOptionImage($OptionImage);
  117.                         $this->entityManager->remove($OptionImage);
  118.                         $this->entityManager->flush();
  119.                         // 他に同じ画像を参照する商品がなければ画像ファイルを削除
  120.                         if (!$this->optionImageRepository->findOneBy(['file_name' => $delete_image])) {
  121.                             $fs->remove($this->eccubeConfig['eccube_save_image_dir'].'/'.$delete_image);
  122.                         }
  123.                     }else{
  124.                         // 追加してすぐに削除した画像は、Entityに追加されない
  125.                         $fs->remove($this->eccubeConfig['eccube_temp_image_dir'].'/'.$delete_image);
  126.                     }
  127.                 }
  128.                 if ($option_image $request->request->all()['admin_option_category']['option_image'] ?? []) {
  129.                     foreach ($option_image as $sortNo => $filename) {
  130.                         $OptionImage $this->optionImageRepository
  131.                             ->findOneBy([
  132.                                 'file_name' => pathinfo($filenamePATHINFO_BASENAME),
  133.                             ]);
  134.                         if ($OptionImage !== null) {
  135.                             $OptionImage->setSortNo($sortNo);
  136.                             $this->entityManager->persist($OptionImage);
  137.                         }
  138.                     }
  139.                     $this->entityManager->flush();
  140.                 }
  141.                 $status $this->optionCategoryRepository->saveCategory($TargetOptionCategory);
  142.                 if ($status) {
  143.                     $this->addSuccess('admin.product.option_category.save.complete''admin');
  144.                     if ($returnLink $form->get('return_link')->getData()) {
  145.                         try {
  146.                             // $returnLinkはpathの形式で渡される. pathが存在するかをルータでチェックする.
  147.                             $pattern '/^'.preg_quote($request->getBasePath(), '/').'/';
  148.                             $returnLink preg_replace($pattern''$returnLink);
  149.                             $result $this->router->match($returnLink);
  150.                             // パラメータのみ抽出
  151.                             $params array_filter($result, function ($key) {
  152.                                 return !== \strpos($key'_');
  153.                             }, ARRAY_FILTER_USE_KEY);
  154.                             // pathからurlを再構築してリダイレクト.
  155.                             return $this->redirectToRoute($result['_route'], $params);
  156.                         } catch (\Exception $e) {
  157.                             // マッチしない場合はログ出力してスキップ.
  158.                             log_warning('URLの形式が不正です。');
  159.                         }
  160.                     }
  161.                     return $this->redirectToRoute('admin_product_option_category', ['option_id' => $Option->getId()]);
  162.                 } else {
  163.                     $this->addError('admin.product.option_category.save.error''admin');
  164.                 }
  165.             }
  166.         }
  167.         $OptionCategories $this->optionCategoryRepository->getList($Option);
  168.         return [
  169.                     'form' => $form->createView(),
  170.                     'Option' => $Option,
  171.                     'OptionCategories' => $OptionCategories,
  172.                     'TargetOptionCategory' => $TargetOptionCategory,
  173.         ];
  174.     }
  175.     /**
  176.      * @Route("/%eccube_admin_route%/product/option_text_category/{option_id}", requirements={"option_id" = "\d+"}, name="admin_product_option_text_category")
  177.      * @Template("@ProductOption42/admin/Product/option_text_category.twig")
  178.      */
  179.     public function textCategory(Request $request$option_id)
  180.     {
  181.         $Option $this->optionRepository->find($option_id);
  182.         if (!$Option) {
  183.             throw new NotFoundHttpException();
  184.         }
  185.         $OptionCategories $Option->getOptionCategories();
  186.         if(count($OptionCategories) > 0){
  187.             $TargetOptionCategory $OptionCategories[0];
  188.         }else{
  189.             $TargetOptionCategory = new OptionCategory();
  190.             $TargetOptionCategory->setOption($Option);
  191.         }
  192.         //
  193.         $form $this->formFactory
  194.                 ->createBuilder(OptionTextCategoryType::class, $TargetOptionCategory)
  195.                 ->getForm();
  196.         // ファイルの登録
  197.         $images = [];
  198.         $OptionImages $TargetOptionCategory->getOptionImages();
  199.         foreach ($OptionImages as $OptionImage) {
  200.             $images[] = $OptionImage->getFileName();
  201.         }
  202.         $form['images']->setData($images);
  203.         if ($request->getMethod() === 'POST') {
  204.             $form->handleRequest($request);
  205.             if ($form->isSubmitted() && $form->isValid()) {
  206.                 // 画像の登録
  207.                 $add_images $form->get('add_images')->getData();
  208.                 foreach ($add_images as $add_image) {
  209.                     $OptionImage = new OptionImage();
  210.                     $OptionImage
  211.                         ->setFileName($add_image)
  212.                         ->setOptionCategory($TargetOptionCategory)
  213.                         ->setSortNo(1);
  214.                     $TargetOptionCategory->addOptionImage($OptionImage);
  215.                     $this->entityManager->persist($OptionImage);
  216.                     // 移動
  217.                     $file = new File($this->eccubeConfig['eccube_temp_image_dir'].'/'.$add_image);
  218.                     $file->move($this->eccubeConfig['eccube_save_image_dir']);
  219.                 }
  220.                 // 画像の削除
  221.                 $delete_images $form->get('delete_images')->getData();
  222.                 $fs = new Filesystem();
  223.                 foreach ($delete_images as $delete_image) {
  224.                     $OptionImage $this->optionImageRepository
  225.                         ->findOneBy(['file_name' => $delete_image]);
  226.                     // 追加してすぐに削除した画像は、Entityに追加されない
  227.                     if ($OptionImage instanceof \Plugin\ProductOption42\Entity\OptionImage) {
  228.                         $TargetOptionCategory->removeOptionImage($OptionImage);
  229.                         $this->entityManager->remove($OptionImage);
  230.                         // 他に同じ画像を参照する商品がなければ画像ファイルを削除
  231.                         if (!$this->optionImageRepository->findOneBy(['file_name' => $delete_image])) {
  232.                             $fs->remove($this->eccubeConfig['eccube_save_image_dir'].'/'.$delete_image);
  233.                         }
  234.                     }else{
  235.                         // 追加してすぐに削除した画像は、Entityに追加されない
  236.                         $fs->remove($this->eccubeConfig['eccube_temp_image_dir'].'/'.$delete_image);
  237.                     }
  238.                 }
  239.                 if ($option_image $request->request->all()['admin_option_text_category']['option_image'] ?? []) {
  240.                     foreach ($option_image as $sortNo => $filename) {
  241.                         $OptionImage $this->optionImageRepository
  242.                             ->findOneBy([
  243.                                 'file_name' => pathinfo($filenamePATHINFO_BASENAME),
  244.                             ]);
  245.                         if ($OptionImage !== null) {
  246.                             $OptionImage->setSortNo($sortNo);
  247.                             $this->entityManager->persist($OptionImage);
  248.                         }
  249.                     }
  250.                     $this->entityManager->flush();
  251.                 }
  252.                 $status $this->optionCategoryRepository->saveCategory($TargetOptionCategory);
  253.                 if ($status) {
  254.                     $this->addSuccess('admin.product.option_text_category.save.complete''admin');
  255.                     if ($returnLink $form->get('return_link')->getData()) {
  256.                         try {
  257.                             // $returnLinkはpathの形式で渡される. pathが存在するかをルータでチェックする.
  258.                             $pattern '/^'.preg_quote($request->getBasePath(), '/').'/';
  259.                             $returnLink preg_replace($pattern''$returnLink);
  260.                             $result $this->router->match($returnLink);
  261.                             // パラメータのみ抽出
  262.                             $params array_filter($result, function ($key) {
  263.                                 return !== \strpos($key'_');
  264.                             }, ARRAY_FILTER_USE_KEY);
  265.                             // pathからurlを再構築してリダイレクト.
  266.                             return $this->redirectToRoute($result['_route'], $params);
  267.                         } catch (\Exception $e) {
  268.                             // マッチしない場合はログ出力してスキップ.
  269.                             log_warning('URLの形式が不正です。');
  270.                         }
  271.                     }
  272.                     return $this->redirectToRoute('admin_product_option_text_category', ['option_id' => $Option->getId()]);
  273.                 } else {
  274.                     $this->addError('admin.product.option_text_category.save.error''admin');
  275.                 }
  276.             }
  277.         }
  278.         return [
  279.                     'form' => $form->createView(),
  280.                     'Option' => $Option,
  281.                     'TargetOptionCategory' => $TargetOptionCategory,
  282.         ];
  283.     }
  284.     /**
  285.      * @Route("/%eccube_admin_route%/product/option_category/{option_id}/{id}/delete", requirements={"option_id" = "\d+","id" = "\d+"}, name="admin_product_option_category_delete", methods={"DELETE"})
  286.      */
  287.     public function delete(Request $request$option_id$id)
  288.     {
  289.         $this->isTokenValid();
  290.         $Option $this->optionRepository->find($option_id);
  291.         if (!$Option) {
  292.             throw new NotFoundHttpException();
  293.         }
  294.         $OptionCategory $this->optionCategoryRepository->find($id);
  295.         if (!$OptionCategory || $OptionCategory->getOption() != $Option) {
  296.             throw new NotFoundHttpException();
  297.         }
  298.         //
  299.         $status false;
  300.         $status $this->optionCategoryRepository->deleteCategory($OptionCategory);
  301.         if ($status === true) {
  302.             $this->addSuccess('admin.product.option_category.delete.complete''admin');
  303.         } else {
  304.             $this->addError('admin.product.option_category.delete.error''admin');
  305.         }
  306.         return $this->redirectToRoute('admin_product_option_category', ['option_id' => $Option->getId()]);
  307.     }
  308.     /**
  309.      * @Route("/%eccube_admin_route%/product/option_category/sort_no/move", name="admin_product_option_category_sort_no_move",methods={"POST"})
  310.      */
  311.     public function moveSortNo(Request $request)
  312.     {
  313.         if ($request->isXmlHttpRequest()) {
  314.             $sortNos $request->request->all();
  315.             foreach ($sortNos as $optionCategoryId => $sortNo) {
  316.                 $OptionCategory $this->optionCategoryRepository
  317.                         ->find($optionCategoryId);
  318.                 $OptionCategory->setSortNo($sortNo);
  319.                 $this->entityManager->persist($OptionCategory);
  320.             }
  321.             $this->entityManager->flush();
  322.         }
  323.         return new Response();
  324.     }
  325.     /**
  326.      * @Route("/%eccube_admin_route%/product/option_category/image/process", name="admin_product_option_category_image_process", methods={"POST"})
  327.      */
  328.     public function imageProcess(Request $request)
  329.     {
  330.         if (!$request->isXmlHttpRequest() && $this->isTokenValid()) {
  331.             throw new BadRequestHttpException();
  332.         }
  333.         $images $request->files->get('admin_option_category');
  334.         $allowExtensions = ['gif''jpg''jpeg''png'];
  335.         $files = [];
  336.         if (count($images) > 0) {
  337.             foreach ($images as $img) {
  338.                 foreach ($img as $image) {
  339.                     //ファイルフォーマット検証
  340.                     $mimeType $image->getMimeType();
  341.                     if (!== strpos($mimeType'image')) {
  342.                         throw new UnsupportedMediaTypeHttpException();
  343.                     }
  344.                     // 拡張子
  345.                     $extension $image->getClientOriginalExtension();
  346.                     if (!in_array(strtolower($extension), $allowExtensions)) {
  347.                         throw new UnsupportedMediaTypeHttpException();
  348.                     }
  349.                     $filename date('mdHis').uniqid('_').'.'.$extension;
  350.                     $image->move($this->eccubeConfig['eccube_temp_image_dir'], $filename);
  351.                     $files[] = $filename;
  352.                 }
  353.             }
  354.         }
  355.         return new Response(array_shift($files));
  356.     }
  357.     /**
  358.      * @Route("/%eccube_admin_route%/product/option_text_category/image/process", name="admin_product_option_text_category_image_process", methods={"POST"})
  359.      */
  360.     public function imageTextProcess(Request $request)
  361.     {
  362.         if (!$request->isXmlHttpRequest() && $this->isTokenValid()) {
  363.             throw new BadRequestHttpException();
  364.         }
  365.         $images $request->files->get('admin_option_text_category');
  366.         $allowExtensions = ['gif''jpg''jpeg''png'];
  367.         $files = [];
  368.         if (count($images) > 0) {
  369.             foreach ($images as $img) {
  370.                 foreach ($img as $image) {
  371.                     //ファイルフォーマット検証
  372.                     $mimeType $image->getMimeType();
  373.                     if (!== strpos($mimeType'image')) {
  374.                         throw new UnsupportedMediaTypeHttpException();
  375.                     }
  376.                     // 拡張子
  377.                     $extension $image->getClientOriginalExtension();
  378.                     if (!in_array(strtolower($extension), $allowExtensions)) {
  379.                         throw new UnsupportedMediaTypeHttpException();
  380.                     }
  381.                     $filename date('mdHis').uniqid('_').'.'.$extension;
  382.                     $image->move($this->eccubeConfig['eccube_temp_image_dir'], $filename);
  383.                     $files[] = $filename;
  384.                 }
  385.             }
  386.         }
  387.         return new Response(array_shift($files));
  388.     }
  389.     /**
  390.      * アップロード画像を取得する際にコールされるメソッド.
  391.      *
  392.      * @Route("/%eccube_admin_route%/product/option_category/image/load", name="admin_product_option_category_image_load", methods={"GET"})
  393.      */
  394.     public function imageLoad(Request $request)
  395.     {
  396.         if (!$request->isXmlHttpRequest()) {
  397.             throw new BadRequestHttpException();
  398.         }
  399.         $image $this->getParameter('eccube_save_image_dir').'/'.$request->query->get('source');
  400.         if(!file_exists($image))$image $this->getParameter('eccube_temp_image_dir').'/'.$request->query->get('source');
  401.         if (file_exists($image)
  402.             && (stripos(realpath($image), $this->eccubeConfig['eccube_save_image_dir']) === 0
  403.                 || stripos(realpath($image), $this->eccubeConfig['eccube_temp_image_dir']) === 0)) {
  404.             $file = new \SplFileObject($image);
  405.             return $this->file($file$file->getBasename());
  406.         }
  407.         throw new NotFoundHttpException();
  408.     }
  409.     /**
  410.      * アップロード画像をすぐ削除する際にコールされるメソッド.
  411.      *
  412.      * @Route("/%eccube_admin_route%/product/option_category/image/revert", name="admin_product_option_category_image_revert", methods={"DELETE"})
  413.      */
  414.     public function imageRevert(Request $request)
  415.     {
  416.         if (!$request->isXmlHttpRequest() && $this->isTokenValid()) {
  417.             throw new BadRequestHttpException();
  418.         }
  419.         $tempFile $this->eccubeConfig['eccube_temp_image_dir'].'/'.$request->getContent();
  420.         if (is_file($tempFile) && stripos(realpath($tempFile), $this->eccubeConfig['eccube_temp_image_dir']) === 0) {
  421.             $fs = new Filesystem();
  422.             $fs->remove($tempFile);
  423.             return new Response(nullResponse::HTTP_NO_CONTENT);
  424.         }
  425.         throw new NotFoundHttpException();
  426.     }
  427. }