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\Form\Type\Admin\OptionCategoryType;
  15. use Plugin\ProductOption42\Form\Type\Admin\OptionTextCategoryType;
  16. use Plugin\ProductOption42\Repository\OptionCategoryRepository;
  17. use Plugin\ProductOption42\Repository\OptionImageRepository;
  18. use Plugin\ProductOption42\Repository\OptionRepository;
  19. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  20. use Symfony\Component\Filesystem\Filesystem;
  21. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  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.     private $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 \Plugin\ProductOption42\Entity\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 (array_key_exists('option_image'$request->request->get('admin_option_category'))) {
  129.                     $option_image $request->request->get('admin_option_category')['option_image'];
  130.                     foreach ($option_image as $sortNo => $filename) {
  131.                         $OptionImage $this->optionImageRepository
  132.                             ->findOneBy([
  133.                                 'file_name' => pathinfo($filenamePATHINFO_BASENAME),
  134.                             ]);
  135.                         if ($OptionImage !== null) {
  136.                             $OptionImage->setSortNo($sortNo);
  137.                             $this->entityManager->persist($OptionImage);
  138.                             $this->entityManager->flush($OptionImage);
  139.                         }
  140.                     }
  141.                 }
  142.                 $status $this->optionCategoryRepository->save($TargetOptionCategory);
  143.                 if ($status) {
  144.                     $this->addSuccess('admin.product.option_category.save.complete''admin');
  145.                     if ($returnLink $form->get('return_link')->getData()) {
  146.                         try {
  147.                             // $returnLinkはpathの形式で渡される. pathが存在するかをルータでチェックする.
  148.                             $pattern '/^'.preg_quote($request->getBasePath(), '/').'/';
  149.                             $returnLink preg_replace($pattern''$returnLink);
  150.                             $result $this->router->match($returnLink);
  151.                             // パラメータのみ抽出
  152.                             $params array_filter($result, function ($key) {
  153.                                 return !== \strpos($key'_');
  154.                             }, ARRAY_FILTER_USE_KEY);
  155.                             // pathからurlを再構築してリダイレクト.
  156.                             return $this->redirectToRoute($result['_route'], $params);
  157.                         } catch (\Exception $e) {
  158.                             // マッチしない場合はログ出力してスキップ.
  159.                             log_warning('URLの形式が不正です。');
  160.                         }
  161.                     }
  162.                     return $this->redirectToRoute('admin_product_option_category', ['option_id' => $Option->getId()]);
  163.                 } else {
  164.                     $this->addError('admin.product.option_category.save.error''admin');
  165.                 }
  166.             }
  167.         }
  168.         $OptionCategories $this->optionCategoryRepository->getList($Option);
  169.         return [
  170.                     'form' => $form->createView(),
  171.                     'Option' => $Option,
  172.                     'OptionCategories' => $OptionCategories,
  173.                     'TargetOptionCategory' => $TargetOptionCategory,
  174.         ];
  175.     }
  176.     /**
  177.      * @Route("/%eccube_admin_route%/product/option_text_category/{option_id}", requirements={"option_id" = "\d+"}, name="admin_product_option_text_category")
  178.      * @Template("@ProductOption42/admin/Product/option_text_category.twig")
  179.      */
  180.     public function textCategory(Request $request$option_id)
  181.     {
  182.         $Option $this->optionRepository->find($option_id);
  183.         if (!$Option) {
  184.             throw new NotFoundHttpException();
  185.         }
  186.         $OptionCategories $Option->getOptionCategories();
  187.         if(count($OptionCategories) > 0){
  188.             $TargetOptionCategory $OptionCategories[0];
  189.         }else{
  190.             $TargetOptionCategory = new OptionCategory();
  191.             $TargetOptionCategory->setOption($Option);
  192.         }
  193.         //
  194.         $form $this->formFactory
  195.                 ->createBuilder(OptionTextCategoryType::class, $TargetOptionCategory)
  196.                 ->getForm();
  197.         // ファイルの登録
  198.         $images = [];
  199.         $OptionImages $TargetOptionCategory->getOptionImages();
  200.         foreach ($OptionImages as $OptionImage) {
  201.             $images[] = $OptionImage->getFileName();
  202.         }
  203.         $form['images']->setData($images);
  204.         if ($request->getMethod() === 'POST') {
  205.             $form->handleRequest($request);
  206.             if ($form->isSubmitted() && $form->isValid()) {
  207.                 // 画像の登録
  208.                 $add_images $form->get('add_images')->getData();
  209.                 foreach ($add_images as $add_image) {
  210.                     $OptionImage = new \Plugin\ProductOption42\Entity\OptionImage();
  211.                     $OptionImage
  212.                         ->setFileName($add_image)
  213.                         ->setOptionCategory($TargetOptionCategory)
  214.                         ->setSortNo(1);
  215.                     $TargetOptionCategory->addOptionImage($OptionImage);
  216.                     $this->entityManager->persist($OptionImage);
  217.                     // 移動
  218.                     $file = new File($this->eccubeConfig['eccube_temp_image_dir'].'/'.$add_image);
  219.                     $file->move($this->eccubeConfig['eccube_save_image_dir']);
  220.                 }
  221.                 // 画像の削除
  222.                 $delete_images $form->get('delete_images')->getData();
  223.                 $fs = new Filesystem();
  224.                 foreach ($delete_images as $delete_image) {
  225.                     $OptionImage $this->optionImageRepository
  226.                         ->findOneBy(['file_name' => $delete_image]);
  227.                     // 追加してすぐに削除した画像は、Entityに追加されない
  228.                     if ($OptionImage instanceof \Plugin\ProductOption42\Entity\OptionImage) {
  229.                         $TargetOptionCategory->removeOptionImage($OptionImage);
  230.                         $this->entityManager->remove($OptionImage);
  231.                         // 他に同じ画像を参照する商品がなければ画像ファイルを削除
  232.                         if (!$this->optionImageRepository->findOneBy(['file_name' => $delete_image])) {
  233.                             $fs->remove($this->eccubeConfig['eccube_save_image_dir'].'/'.$delete_image);
  234.                         }
  235.                     }else{
  236.                         // 追加してすぐに削除した画像は、Entityに追加されない
  237.                         $fs->remove($this->eccubeConfig['eccube_temp_image_dir'].'/'.$delete_image);
  238.                     }
  239.                 }
  240.                 if (array_key_exists('option_image'$request->request->get('admin_option_text_category'))) {
  241.                     $option_image $request->request->get('admin_option_text_category')['option_image'];
  242.                     foreach ($option_image as $sortNo => $filename) {
  243.                         $OptionImage $this->optionImageRepository
  244.                             ->findOneBy([
  245.                                 'file_name' => pathinfo($filenamePATHINFO_BASENAME),
  246.                             ]);
  247.                         if ($OptionImage !== null) {
  248.                             $OptionImage->setSortNo($sortNo);
  249.                             $this->entityManager->persist($OptionImage);
  250.                             $this->entityManager->flush($OptionImage);
  251.                         }
  252.                     }
  253.                 }
  254.                 $status $this->optionCategoryRepository->save($TargetOptionCategory);
  255.                 if ($status) {
  256.                     $this->addSuccess('admin.product.option_text_category.save.complete''admin');
  257.                     if ($returnLink $form->get('return_link')->getData()) {
  258.                         try {
  259.                             // $returnLinkはpathの形式で渡される. pathが存在するかをルータでチェックする.
  260.                             $pattern '/^'.preg_quote($request->getBasePath(), '/').'/';
  261.                             $returnLink preg_replace($pattern''$returnLink);
  262.                             $result $this->router->match($returnLink);
  263.                             // パラメータのみ抽出
  264.                             $params array_filter($result, function ($key) {
  265.                                 return !== \strpos($key'_');
  266.                             }, ARRAY_FILTER_USE_KEY);
  267.                             // pathからurlを再構築してリダイレクト.
  268.                             return $this->redirectToRoute($result['_route'], $params);
  269.                         } catch (\Exception $e) {
  270.                             // マッチしない場合はログ出力してスキップ.
  271.                             log_warning('URLの形式が不正です。');
  272.                         }
  273.                     }
  274.                     return $this->redirectToRoute('admin_product_option_text_category', ['option_id' => $Option->getId()]);
  275.                 } else {
  276.                     $this->addError('admin.product.option_text_category.save.error''admin');
  277.                 }
  278.             }
  279.         }
  280.         return [
  281.                     'form' => $form->createView(),
  282.                     'Option' => $Option,
  283.                     'TargetOptionCategory' => $TargetOptionCategory,
  284.         ];
  285.     }
  286.     /**
  287.      * @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"})
  288.      */
  289.     public function delete(Request $request$option_id$id)
  290.     {
  291.         $this->isTokenValid();
  292.         $Option $this->optionRepository->find($option_id);
  293.         if (!$Option) {
  294.             throw new NotFoundHttpException();
  295.         }
  296.         $OptionCategory $this->optionCategoryRepository->find($id);
  297.         if (!$OptionCategory || $OptionCategory->getOption() != $Option) {
  298.             throw new NotFoundHttpException();
  299.         }
  300.         //
  301.         $status false;
  302.         $status $this->optionCategoryRepository->delete($OptionCategory);
  303.         if ($status === true) {
  304.             $this->addSuccess('admin.product.option_category.delete.complete''admin');
  305.         } else {
  306.             $this->addError('admin.product.option_category.delete.error''admin');
  307.         }
  308.         return $this->redirectToRoute('admin_product_option_category', ['option_id' => $Option->getId()]);
  309.     }
  310.     /**
  311.      * @Route("/%eccube_admin_route%/product/option_category/sort_no/move", name="admin_product_option_category_sort_no_move",methods={"POST"})
  312.      */
  313.     public function moveSortNo(Request $request)
  314.     {
  315.         if ($request->isXmlHttpRequest()) {
  316.             $sortNos $request->request->all();
  317.             foreach ($sortNos as $optionCategoryId => $sortNo) {
  318.                 $OptionCategory $this->optionCategoryRepository
  319.                         ->find($optionCategoryId);
  320.                 $OptionCategory->setSortNo($sortNo);
  321.                 $this->entityManager->persist($OptionCategory);
  322.             }
  323.             $this->entityManager->flush();
  324.         }
  325.         return new Response();
  326.     }
  327.     /**
  328.      * @Route("/%eccube_admin_route%/product/option_category/image/process", name="admin_product_option_category_image_process", methods={"POST"})
  329.      */
  330.     public function imageProcess(Request $request)
  331.     {
  332.         if (!$request->isXmlHttpRequest() && $this->isTokenValid()) {
  333.             throw new BadRequestHttpException();
  334.         }
  335.         $images $request->files->get('admin_option_category');
  336.         $allowExtensions = ['gif''jpg''jpeg''png'];
  337.         $files = [];
  338.         if (count($images) > 0) {
  339.             foreach ($images as $img) {
  340.                 foreach ($img as $image) {
  341.                     //ファイルフォーマット検証
  342.                     $mimeType $image->getMimeType();
  343.                     if (!== strpos($mimeType'image')) {
  344.                         throw new UnsupportedMediaTypeHttpException();
  345.                     }
  346.                     // 拡張子
  347.                     $extension $image->getClientOriginalExtension();
  348.                     if (!in_array(strtolower($extension), $allowExtensions)) {
  349.                         throw new UnsupportedMediaTypeHttpException();
  350.                     }
  351.                     $filename date('mdHis').uniqid('_').'.'.$extension;
  352.                     $image->move($this->eccubeConfig['eccube_temp_image_dir'], $filename);
  353.                     $files[] = $filename;
  354.                 }
  355.             }
  356.         }
  357.         return new Response(array_shift($files));
  358.     }
  359.     /**
  360.      * @Route("/%eccube_admin_route%/product/option_text_category/image/process", name="admin_product_option_text_category_image_process", methods={"POST"})
  361.      */
  362.     public function imageTextProcess(Request $request)
  363.     {
  364.         if (!$request->isXmlHttpRequest() && $this->isTokenValid()) {
  365.             throw new BadRequestHttpException();
  366.         }
  367.         $images $request->files->get('admin_option_text_category');
  368.         $allowExtensions = ['gif''jpg''jpeg''png'];
  369.         $files = [];
  370.         if (count($images) > 0) {
  371.             foreach ($images as $img) {
  372.                 foreach ($img as $image) {
  373.                     //ファイルフォーマット検証
  374.                     $mimeType $image->getMimeType();
  375.                     if (!== strpos($mimeType'image')) {
  376.                         throw new UnsupportedMediaTypeHttpException();
  377.                     }
  378.                     // 拡張子
  379.                     $extension $image->getClientOriginalExtension();
  380.                     if (!in_array(strtolower($extension), $allowExtensions)) {
  381.                         throw new UnsupportedMediaTypeHttpException();
  382.                     }
  383.                     $filename date('mdHis').uniqid('_').'.'.$extension;
  384.                     $image->move($this->eccubeConfig['eccube_temp_image_dir'], $filename);
  385.                     $files[] = $filename;
  386.                 }
  387.             }
  388.         }
  389.         return new Response(array_shift($files));
  390.     }
  391.     /**
  392.      * アップロード画像を取得する際にコールされるメソッド.
  393.      *
  394.      * @Route("/%eccube_admin_route%/product/option_category/image/load", name="admin_product_option_category_image_load", methods={"GET"})
  395.      */
  396.     public function imageLoad(Request $request)
  397.     {
  398.         if (!$request->isXmlHttpRequest()) {
  399.             throw new BadRequestHttpException();
  400.         }
  401.         $image $this->getParameter('eccube_save_image_dir').'/'.$request->query->get('source');
  402.         if(!file_exists($image))$image $this->getParameter('eccube_temp_image_dir').'/'.$request->query->get('source');
  403.         if (file_exists($image)
  404.             && (stripos(realpath($image), $this->eccubeConfig['eccube_save_image_dir']) === 0
  405.                 || stripos(realpath($image), $this->eccubeConfig['eccube_temp_image_dir']) === 0)) {
  406.             $file = new \SplFileObject($image);
  407.             return $this->file($file$file->getBasename());
  408.         }
  409.         throw new NotFoundHttpException();
  410.     }
  411.     /**
  412.      * アップロード画像をすぐ削除する際にコールされるメソッド.
  413.      *
  414.      * @Route("/%eccube_admin_route%/product/option_category/image/revert", name="admin_product_option_category_image_revert", methods={"DELETE"})
  415.      */
  416.     public function imageRevert(Request $request)
  417.     {
  418.         if (!$request->isXmlHttpRequest() && $this->isTokenValid()) {
  419.             throw new BadRequestHttpException();
  420.         }
  421.         $tempFile $this->eccubeConfig['eccube_temp_image_dir'].'/'.$request->getContent();
  422.         if (is_file($tempFile) && stripos(realpath($tempFile), $this->eccubeConfig['eccube_temp_image_dir']) === 0) {
  423.             $fs = new Filesystem();
  424.             $fs->remove($tempFile);
  425.             return new Response(nullResponse::HTTP_NO_CONTENT);
  426.         }
  427.         throw new NotFoundHttpException();
  428.     }
  429. }