app/Plugin/TabaBannerManager2/Controller/AdminController.php line 515

Open in your IDE?
  1. <?php
  2. /*
  3.  * Copyright (C) 2018 SPREAD WORKS Inc.
  4.  *
  5.  * For the full copyright and license information, please view the LICENSE
  6.  * file that was distributed with this source code.
  7.  */
  8. namespace Plugin\TabaBannerManager2\Controller;
  9. use Eccube\Application;
  10. use Eccube\Controller\AbstractController;
  11. use Eccube\Common\Constant;
  12. use Plugin\TabaBannerManager2\Common\Constants;
  13. use Plugin\TabaBannerManager2\Entity\Area;
  14. use Plugin\TabaBannerManager2\Entity\Banner;
  15. use Plugin\TabaBannerManager2\Repository\AreaRepository;
  16. use Plugin\TabaBannerManager2\Repository\BannerRepository;
  17. use Plugin\TabaBannerManager2\Form\Type\AreaType;
  18. use Plugin\TabaBannerManager2\Form\Type\BannerType;
  19. use Symfony\Component\HttpFoundation\Request;
  20. use Symfony\Component\HttpFoundation\JsonResponse;
  21. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  22. use Symfony\Component\Security\Csrf\CsrfToken;
  23. use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
  24. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  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 Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  30. /**
  31.  * 管理画面用コントローラー
  32.  *
  33.  * @Route(Plugin\TabaBannerManager2\Common\Constants::ADMIN_URI_PREFIX,name=Plugin\TabaBannerManager2\Common\Constants::ADMIN_BIND_PREFIX)
  34.  */
  35. class AdminController extends AbstractController
  36. {
  37.     /**
  38.      * @var AreaRepository
  39.      */
  40.     private $areaRepo;
  41.     /**
  42.      * @var BannerRepository
  43.      */
  44.     private $bannerRepo;
  45.     /**
  46.      * @var CsrfTokenManagerInterface
  47.      */
  48.     protected $csrfTokenManager;
  49.     /**
  50.      *
  51.      * @param AreaRepository $areaRepo
  52.      * @param BannerRepository $bannerRepo
  53.      * @param CsrfTokenManagerInterface $csrfTokenManager
  54.      */
  55.     public function __construct(AreaRepository $areaRepoBannerRepository $bannerRepoCsrfTokenManagerInterface $csrfTokenManager)
  56.     {
  57.         $this->areaRepo $areaRepo;
  58.         $this->bannerRepo $bannerRepo;
  59.         $this->csrfTokenManager $csrfTokenManager;
  60.     }
  61.     /**
  62.      * index
  63.      *
  64.      * @param Request $request
  65.      * @return \Symfony\Component\HttpFoundation\Response
  66.      *
  67.      * @Route("/",name="_index")
  68.      */
  69.     public function index(Request $request)
  70.     {
  71.         return $this->redirectToRoute(Constants::ADMIN_BIND_PREFIX '_area_list');
  72.     }
  73.     /**
  74.      * バナーエリア / リスト
  75.      *
  76.      * @param Request $request
  77.      * @return \Symfony\Component\HttpFoundation\Response
  78.      *
  79.      * @Route("/area_list",name="_area_list")
  80.      * @Template("@TabaBannerManager2/admin/area_list.twig")
  81.      */
  82.     public function area_list(Request $request)
  83.     {
  84.         $list $this->areaRepo->getList();
  85.         return [
  86.             'list' => $list
  87.         ];
  88.     }
  89.     /**
  90.      * バナーエリア / 新規登録・編集
  91.      *
  92.      * @param Request $request
  93.      * @param integer $area_id
  94.      * @return \Symfony\Component\HttpFoundation\Response
  95.      *
  96.      * @Route("/area_edit",name="_area_new")
  97.      * @Route("/area_edit/{area_id}",name="_area_edit",requirements={"area_id" = "\d+"})
  98.      * @Template("@TabaBannerManager2/admin/area_edit.twig")
  99.      */
  100.     public function area_edit(Request $request$area_id null)
  101.     {
  102.         $area null;
  103.         if ($area_id) {
  104.             if (! ($area $this->areaRepo->find($area_id))) {
  105.                 throw new NotFoundHttpException();
  106.             }
  107.         } else {
  108.             $area = new Area(true);
  109.         }
  110.         // フォームの生成
  111.         $builder $this->formFactory->createBuilder(AreaType::class, $area);
  112.         $form $builder->getForm();
  113.         // 登録・変更実行
  114.         if ('POST' === $request->getMethod()) {
  115.             // データキーが入力されていない場合
  116.             // 値を生成しリクエスト値にセットします。
  117.             $params $request->request->all();
  118.             if (empty($params[$form->getName()]['data_key'])) {
  119.                 $data_key "area";
  120.                 $id $this->areaRepo->getMaxAreaId() + 1;
  121.                 for ($i $id$i <= 1000 $id$i) {
  122.                     if (! $this->areaRepo->getList(array(
  123.                         'data_key' => $data_key "_" $i
  124.                     ))) {
  125.                         $data_key $data_key "_" $i;
  126.                         break;
  127.                     }
  128.                 }
  129.                 $params[$form->getName()]['data_key'] = $data_key;
  130.                 $request->request->replace($params);
  131.             }
  132.             $form->handleRequest($request);
  133.             if ($form->isValid()) {
  134.                 // $data = $form->getData();
  135.                 if ($this->areaRepo->save($area)) {
  136.                     $this->addSuccess('admin.common.save_complete''admin');
  137.                     return $this->redirectToRoute(Constants::ADMIN_BIND_PREFIX '_area_edit', array(
  138.                         'area_id' => $area->getAreaId()
  139.                     ));
  140.                 } else {
  141.                     $this->addError('admin.common.save_error''admin');
  142.                 }
  143.             } else {
  144.                 $this->addError('admin.common.save_error''admin');
  145.             }
  146.         }
  147.         return [
  148.             'form' => $form->createView(),
  149.             'area' => $area
  150.         ];
  151.     }
  152.     /**
  153.      * バナーエリア / 削除
  154.      *
  155.      * @param Application $app
  156.      * @param Request $request
  157.      * @param integer $area_id
  158.      * @return \Symfony\Component\HttpFoundation\Response
  159.      *
  160.      * @Route("/area_delete/{area_id}",name="_area_delete",requirements={"area_id" = "\d+"})
  161.      */
  162.     public function area_delete(Request $request$area_id)
  163.     {
  164.         // バナーエリア操作オブジェクトの生成
  165.         $status false;
  166.         if (! empty($area_id) && ($area $this->areaRepo->find($area_id))) {
  167.             $status $this->areaRepo->delete($area);
  168.         } else {
  169.             throw new NotFoundHttpException();
  170.         }
  171.         if ($status) {
  172.             $this->addSuccess('admin.common.delete_complete''admin');
  173.         } else {
  174.             $this->addError('admin.common.delete_error''admin');
  175.         }
  176.         return $this->redirectToRoute(Constants::ADMIN_BIND_PREFIX '_area_list');
  177.     }
  178.     /**
  179.      * バナー / リスト
  180.      *
  181.      * @param Application $app
  182.      * @param Request $request
  183.      * @return \Symfony\Component\HttpFoundation\Response
  184.      *
  185.      * @Route("/banner_list/{area_id}",name="_banner_list",requirements={"area_id" = "\d+"})
  186.      * @Template("@TabaBannerManager2/admin/banner_list.twig")
  187.      */
  188.     public function banner_list(Request $request$area_id)
  189.     {
  190.         // バナーエリア取得
  191.         $area null;
  192.         if (! ($area $this->areaRepo->find($area_id))) {
  193.             throw new NotFoundHttpException();
  194.         }
  195.         // バナーリスト取得
  196.         $list $this->bannerRepo->getList($area_id);
  197.         return [
  198.             'csrf_token' => $this->csrfTokenManager->getToken(Constant::TOKEN_NAME)->getValue(),
  199.             'area' => $area,
  200.             'list' => $list
  201.         ];
  202.     }
  203.     /**
  204.      * バナー / 新規登録・編集
  205.      *
  206.      * @param Application $app
  207.      * @param Request $request
  208.      * @param integer $id
  209.      * @return \Symfony\Component\HttpFoundation\Response
  210.      *
  211.      * @Route("/banner_edit/{area_id}",name="_banner_new",requirements={"area_id" = "\d+"})
  212.      * @Route("/banner_edit/{area_id}/{banner_id}",name="_banner_edit",requirements={"area_id" = "\d+","banner_id" = "\d+"})
  213.      * @Template("@TabaBannerManager2/admin/banner_edit.twig")
  214.      */
  215.     public function banner_edit(Request $request$area_id$banner_id null)
  216.     {
  217.         // バナーエリア取得
  218.         $area null;
  219.         if (! ($area $this->areaRepo->find($area_id))) {
  220.             throw new NotFoundHttpException();
  221.         }
  222.         // バナー操作オブジェクトの生成
  223.         $banner null;
  224.         if ($banner_id) {
  225.             if (! ($banner $this->bannerRepo->find($banner_id))) {
  226.                 throw new NotFoundHttpException();
  227.             }
  228.         } else {
  229.             $banner = new Banner(true);
  230.         }
  231.         $banner->setArea($area);
  232.         $originBannerFileName $banner->getBannerFileName();
  233.         $originBannerFileName2 $banner->getBannerFileName2();
  234.         $originBannerFileName3 $banner->getBannerFileName3();
  235.         $originBannerFileName4 $banner->getBannerFileName4();
  236.         $originBannerFileName5 $banner->getBannerFileName5();
  237.         $imageEdited false// 画像編集済みかチェックするフラグ
  238.         // フォームの生成
  239.         $builder $this->formFactory->createBuilder(BannerType::class, $banner);
  240.         $form $builder->getForm();
  241.         // 登録・変更実行
  242.         if ('POST' === $request->getMethod()) {
  243.             $form->handleRequest($request);
  244.             //
  245.             // 画像 1
  246.             //
  247.             if ($originBannerFileName != $banner->getBannerFileName()) $imageEdited true;
  248.             if ($form->isValid()) {
  249.                 $imageEdited false;
  250.                 if ($this->bannerRepo->save($banner)) {
  251.                     //
  252.                     // 画像 1
  253.                     //
  254.                     // 画像を移動
  255.                     if (!empty($banner->getBannerFileName()) && file_exists($this->eccubeConfig['eccube_temp_image_dir'] . '/' $banner->getBannerFileName())) {
  256.                         rename($this->eccubeConfig['eccube_temp_image_dir'] . '/' $banner->getBannerFileName(), $this->eccubeConfig['eccube_save_image_dir'] . '/' $banner->getBannerFileName());
  257.                     }
  258.                     // 画像削除
  259.                     $oldPath $newPath null;
  260.                     if ($originBannerFileName$oldPath $this->eccubeConfig['eccube_save_image_dir'] . '/' $originBannerFileName;
  261.                     if ($banner->getBannerFileName()) $newPath $this->eccubeConfig['eccube_save_image_dir'] . '/' $banner->getBannerFileName();
  262.                     if (!$banner->getBannerFileName()) {
  263.                         if (file_exists($newPath)) unlink($newPath);
  264.                         if (file_exists($oldPath)) unlink($oldPath);
  265.                     } else if ($originBannerFileName != $banner->getBannerFileName()) {
  266.                         if (file_exists($oldPath)) unlink($oldPath);
  267.                     }
  268.                     //
  269.                     // 画像 2
  270.                     //
  271.                     // 画像を移動
  272.                     if (!empty($banner->getBannerFileName2()) && file_exists($this->eccubeConfig['eccube_temp_image_dir'] . '/' $banner->getBannerFileName2())) {
  273.                         rename($this->eccubeConfig['eccube_temp_image_dir'] . '/' $banner->getBannerFileName2(), $this->eccubeConfig['eccube_save_image_dir'] . '/' $banner->getBannerFileName2());
  274.                     }
  275.                     // 画像削除
  276.                     $oldPath $newPath null;
  277.                     if ($originBannerFileName2$oldPath $this->eccubeConfig['eccube_save_image_dir'] . '/' $originBannerFileName2;
  278.                     if ($banner->getBannerFileName2()) $newPath $this->eccubeConfig['eccube_save_image_dir'] . '/' $banner->getBannerFileName2();
  279.                     if (!$banner->getBannerFileName2()) {
  280.                         if (file_exists($newPath)) unlink($newPath);
  281.                         if (file_exists($oldPath)) unlink($oldPath);
  282.                     } else if ($originBannerFileName2 != $banner->getBannerFileName2()) {
  283.                         if (file_exists($oldPath)) unlink($oldPath);
  284.                     }
  285.                     //
  286.                     // 画像 3
  287.                     //
  288.                     // 画像を移動
  289.                     if (!empty($banner->getBannerFileName3()) && file_exists($this->eccubeConfig['eccube_temp_image_dir'] . '/' $banner->getBannerFileName3())) {
  290.                         rename($this->eccubeConfig['eccube_temp_image_dir'] . '/' $banner->getBannerFileName3(), $this->eccubeConfig['eccube_save_image_dir'] . '/' $banner->getBannerFileName3());
  291.                     }
  292.                     // 画像削除
  293.                     $oldPath $newPath null;
  294.                     if ($originBannerFileName3$oldPath $this->eccubeConfig['eccube_save_image_dir'] . '/' $originBannerFileName3;
  295.                     if ($banner->getBannerFileName3()) $newPath $this->eccubeConfig['eccube_save_image_dir'] . '/' $banner->getBannerFileName3();
  296.                     if (!$banner->getBannerFileName3()) {
  297.                         if (file_exists($newPath)) unlink($newPath);
  298.                         if (file_exists($oldPath)) unlink($oldPath);
  299.                     } else if ($originBannerFileName3 != $banner->getBannerFileName3()) {
  300.                         if (file_exists($oldPath)) unlink($oldPath);
  301.                     }
  302.                     //
  303.                     // 画像 4
  304.                     //
  305.                     // 画像を移動
  306.                     if (!empty($banner->getBannerFileName4()) && file_exists($this->eccubeConfig['eccube_temp_image_dir'] . '/' $banner->getBannerFileName4())) {
  307.                         rename($this->eccubeConfig['eccube_temp_image_dir'] . '/' $banner->getBannerFileName4(), $this->eccubeConfig['eccube_save_image_dir'] . '/' $banner->getBannerFileName4());
  308.                     }
  309.                     // 画像削除
  310.                     $oldPath $newPath null;
  311.                     if ($originBannerFileName4$oldPath $this->eccubeConfig['eccube_save_image_dir'] . '/' $originBannerFileName4;
  312.                     if ($banner->getBannerFileName4()) $newPath $this->eccubeConfig['eccube_save_image_dir'] . '/' $banner->getBannerFileName4();
  313.                     if (!$banner->getBannerFileName4()) {
  314.                         if (file_exists($newPath)) unlink($newPath);
  315.                         if (file_exists($oldPath)) unlink($oldPath);
  316.                     } else if ($originBannerFileName4 != $banner->getBannerFileName4()) {
  317.                         if (file_exists($oldPath)) unlink($oldPath);
  318.                     }
  319.                     //
  320.                     // 画像 5
  321.                     //
  322.                     // 画像を移動
  323.                     if (!empty($banner->getBannerFileName5()) && file_exists($this->eccubeConfig['eccube_temp_image_dir'] . '/' $banner->getBannerFileName5())) {
  324.                         rename($this->eccubeConfig['eccube_temp_image_dir'] . '/' $banner->getBannerFileName5(), $this->eccubeConfig['eccube_save_image_dir'] . '/' $banner->getBannerFileName5());
  325.                     }
  326.                     // 画像削除
  327.                     $oldPath $newPath null;
  328.                     if ($originBannerFileName5$oldPath $this->eccubeConfig['eccube_save_image_dir'] . '/' $originBannerFileName5;
  329.                     if ($banner->getBannerFileName5()) $newPath $this->eccubeConfig['eccube_save_image_dir'] . '/' $banner->getBannerFileName5();
  330.                     if (!$banner->getBannerFileName5()) {
  331.                         if (file_exists($newPath)) unlink($newPath);
  332.                         if (file_exists($oldPath)) unlink($oldPath);
  333.                     } else if ($originBannerFileName5 != $banner->getBannerFileName5()) {
  334.                         if (file_exists($oldPath)) unlink($oldPath);
  335.                     }
  336.                     $this->addSuccess('admin.common.save_complete''admin');
  337.                     return $this->redirectToRoute(Constants::ADMIN_BIND_PREFIX '_banner_edit', [
  338.                         'area_id' => $area_id,
  339.                         'banner_id' => $banner->getBannerId()
  340.                     ]);
  341.                 } else {
  342.                     $this->addError('admin.common.save_error''admin');
  343.                 }
  344.             }
  345.         }
  346.         return [
  347.             'csrf_token' => $this->csrfTokenManager->getToken(Constant::TOKEN_NAME)->getValue(),
  348.             'form' => $form->createView(),
  349.             'area' => $area,
  350.             'banner' => $banner,
  351.             'image_edited' => $imageEdited,
  352.         ];
  353.     }
  354.     /**
  355.      * バナー / 削除
  356.      *
  357.      * @param Application $app
  358.      * @param Request $request
  359.      * @param integer $banner_id
  360.      * @return \Symfony\Component\HttpFoundation\Response
  361.      *
  362.      * @Route("/banner_delete/{banner_id}",name="_banner_delete",requirements={"banner_id" = "\d+"})
  363.      */
  364.     public function banner_delete(Request $request$banner_id null)
  365.     {
  366.         // バナーエリア操作オブジェクトの生成
  367.         $status false;
  368.         $banner $this->bannerRepo->find($banner_id);
  369.         $area_id $banner->getAreaId();
  370.         if (! empty($banner)) {
  371.             $status $this->bannerRepo->delete($banner);
  372.         } else {
  373.             throw new NotFoundHttpException();
  374.         }
  375.         if ($status) {
  376.             $this->addSuccess('admin.common.delete_complete''admin');
  377.         } else {
  378.             $this->addError('admin.common.delete_error''admin');
  379.         }
  380.         return $this->redirectToRoute(Constants::ADMIN_BIND_PREFIX '_banner_list', [
  381.             'area_id' => $area_id
  382.         ]);
  383.     }
  384.     /**
  385.      * バナー画像アップロード
  386.      *
  387.      * @param Request $request
  388.      * @throws BadRequestHttpException
  389.      * @throws UnsupportedMediaTypeHttpException
  390.      * @return \Symfony\Component\HttpFoundation\Response
  391.      *
  392.      * @Route("/banner_upload",name="_banner_upload")
  393.      */
  394.     public function banner_upload(Request $request)
  395.     {
  396.         // CSRF
  397.         if (!$this->csrfTokenManager->isTokenValid(new CsrfToken(Constant::TOKEN_NAME$request->get(Constant::TOKEN_NAME)))) {
  398.             throw new AccessDeniedHttpException('CSRF token is invalid.');
  399.         }
  400.         // XMLHttpRequest
  401.         if (! $request->isXmlHttpRequest()) {
  402.             throw new BadRequestHttpException('Request is invalid.');
  403.         }
  404.         $files $request->files->get(Constants::PLUGIN_CODE_LC '_banner');
  405.         $file_name null;
  406.         if (count($files) > 0) {
  407.             foreach ($files as $file) {
  408. //                 log_debug("[FILE OBJECT] " . print_r($file, true));
  409.                 if (!== strpos($file->getMimeType(), 'image')) {
  410.                     throw new UnsupportedMediaTypeHttpException('File format is invalid.');
  411.                 }
  412.                 $extension $file->getClientOriginalExtension();
  413.                 $file_name date('mdHis') . uniqid('_') . '.' $extension;
  414.                 $file->move($this->eccubeConfig['eccube_temp_image_dir'], $file_name);
  415.                 break;
  416.             }
  417.         }
  418.         return new JsonResponse(array(
  419.             'file' => $file_name
  420.         ));
  421.     }
  422.     /**
  423.      * バナー / ソート
  424.      *
  425.      * @param Request $request
  426.      * @param integer $area_id
  427.      * @return \Symfony\Component\HttpFoundation\Response
  428.      *
  429.      * @Route("/banner_sort/{area_id}",name="_banner_sort",requirements={"area_id" = "\d+"})
  430.      */
  431.     public function banner_sort(Request $request$area_id)
  432.     {
  433.         // CSRF
  434.         if (! $this->csrfTokenManager->isTokenValid(new CsrfToken(Constant::TOKEN_NAME$request->get(Constant::TOKEN_NAME)))) {
  435.             throw new AccessDeniedHttpException('CSRF token is invalid.');
  436.         }
  437.         // XMLHttpRequest
  438.         if (! $request->isXmlHttpRequest()) {
  439.             throw new BadRequestHttpException('Request is invalid.');
  440.         }
  441.         $params $request->request->all();
  442.         if (!empty($area_id) && isset($params['banner_ids']) && is_array($params['banner_ids'])) {
  443.             if (! ($this->areaRepo->find($area_id))) {
  444.                 throw new NotFoundHttpException();
  445.             }
  446.             $no 1;
  447.             foreach ($params['banner_ids'] as $banner_id) {
  448.                 $banner $this->bannerRepo->find($banner_id);
  449.                 $banner->setOrderNo($no ++);
  450.                 if (! ($this->bannerRepo->save($banner))) {
  451.                     log_debug("順番の更新が出来ませんでした");
  452.                 }
  453.             }
  454.         } else {
  455.             throw new BadRequestHttpException('必要なパラメーターが取得できません');
  456.         }
  457.         return new JsonResponse([]);
  458.     }
  459.     /**
  460.      * 各種ファイルを出力します。
  461.      *
  462.      * @param Request $request
  463.      * @param string $file
  464.      * @throws NotFoundHttpException
  465.      * @return BinaryFileResponse
  466.      *
  467.      * @Route("/assets/{file}",name="_assets",requirements={"file" = "[a-zA-Z0-9-_/\s.]+"})
  468.      */
  469.     public function assets(Request $request,$file) {
  470.         if (strpos($file,'..')) {
  471.             log_critical("ディレクトリトラバーサル攻撃の可能性があります。 [FILE] " $file);
  472.             throw new NotFoundHttpException();
  473.         }
  474.         $file Constants::TEMPLATE_PATH DIRECTORY_SEPARATOR .  "admin" DIRECTORY_SEPARATOR "assets" .  DIRECTORY_SEPARATOR $file;
  475.         if (file_exists($this->eccubeConfig['plugin_realdir'] . DIRECTORY_SEPARATOR $file)) {
  476.             log_debug("[ASSETS] [FILE] " $file);
  477.             // 拡張子によりMIMEを設定します。
  478.             $suffixes explode(".",$file);
  479.             $suffix end($suffixes);
  480.             $suffix_def = array(
  481.                 "jpeg" => "image/jpg",
  482.                 "jpg" => "image/jpg",
  483.                 "gif" => "image/gif",
  484.                 "png" => "image/png",
  485.                 "svg" => "image/svg+xml",
  486.                 "js" => "application/x-javascript",
  487.                 "css" => "text/css",
  488.             );
  489.             if (in_array($suffix,array_keys($suffix_def))) {
  490.                 $response = new BinaryFileResponse($this->eccubeConfig['plugin_realdir'] . DIRECTORY_SEPARATOR $file);
  491.                 $response->headers->set('Content-Type',$suffix_def[$suffix]);
  492.                 return $response;
  493.             } else {
  494.                 throw new NotFoundHttpException();
  495.             }
  496.         } else {
  497.             throw new NotFoundHttpException();
  498.         }
  499.     }
  500. }