app/Plugin/TabaCMS2/Controller/AdminController.php line 263

Open in your IDE?
  1. <?php
  2. /*
  3.  * Copyright (C) SPREAD WORKS Inc. All Rights Reserved.
  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\TabaCMS2\Controller;
  9. use Eccube\Common\Constant;
  10. use Eccube\Controller\AbstractController;
  11. use Knp\Component\Pager\Paginator;
  12. use Knp\Component\Pager\PaginatorInterface;
  13. use Plugin\TabaCMS2\Common\Constants;
  14. use Plugin\TabaCMS2\Common\UserConfig;
  15. use Plugin\TabaCMS2\Entity\Category;
  16. use Plugin\TabaCMS2\Entity\Tag;
  17. use Plugin\TabaCMS2\Entity\PostTag;
  18. use Plugin\TabaCMS2\Entity\Post;
  19. use Plugin\TabaCMS2\Entity\Type;
  20. use Plugin\TabaCMS2\Form\Type\PostType;
  21. use Plugin\TabaCMS2\Form\Type\TypeType;
  22. use Plugin\TabaCMS2\Form\Type\CategoryType;
  23. use Plugin\TabaCMS2\Form\Type\TagType;
  24. use Plugin\TabaCMS2\Form\Type\PostSearchType;
  25. use Plugin\TabaCMS2\Repository\CategoryRepository;
  26. use Plugin\TabaCMS2\Repository\TagRepository;
  27. use Plugin\TabaCMS2\Repository\PostTagRepository;
  28. use Plugin\TabaCMS2\Repository\PostRepository;
  29. use Plugin\TabaCMS2\Repository\TypeRepository;
  30. use Plugin\TabaCMS2\Util\Util;
  31. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  32. use Symfony\Component\HttpFoundation\JsonResponse;
  33. use Symfony\Component\HttpFoundation\Request;
  34. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  35. use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
  36. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  37. use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;
  38. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  39. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  40. use Symfony\Component\Security\Csrf\CsrfToken;
  41. use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
  42. use Symfony\Component\Finder\Finder;
  43. use Symfony\Component\Filesystem\Filesystem;
  44. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
  45. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  46. /**
  47.  * 管理画面用コントローラー
  48.  *
  49.  * @Route(Plugin\TabaCMS2\Common\Constants::ADMIN_URI_PREFIX,name=Plugin\TabaCMS2\Common\Constants::ADMIN_BIND_PREFIX)
  50.  */
  51. class AdminController extends AbstractController
  52. {
  53.     /**
  54.      *
  55.      * @var TypeRepository
  56.      */
  57.     private $typeRepo;
  58.     /**
  59.      *
  60.      * @var PostRepository
  61.      */
  62.     private $postRepo;
  63.     /**
  64.      *
  65.      * @var CategoryRepository
  66.      */
  67.     private $categoryRepo;
  68.     /**
  69.      *
  70.      * @var CsrfTokenManagerInterface
  71.      */
  72.     private $csrfTokenManager;
  73.     /**
  74.      * @var AuthorizationCheckerInterface
  75.      */
  76.     private $authCheck;
  77.     /**
  78.      * @var TokenStorageInterface
  79.      */
  80.     protected $tokenStore;
  81.     /**
  82.      * @var TagRepository
  83.      */
  84.     protected $tagRepo;
  85.     /**
  86.      * @var PostTagRepository
  87.      */
  88.     protected $postTagRepo;
  89.     /**
  90.      * コンストラクタ
  91.      *
  92.      * @param TypeRepository $typeRepo
  93.      * @param PostRepository $postRepo
  94.      * @param CategoryRepository $categoryRepo
  95.      * @param CsrfTokenManagerInterface $csrfTokenManager
  96.      * @param AuthorizationCheckerInterface $authCheck
  97.      * @param TokenStorageInterface $tokenStore
  98.      */
  99.     public function __construct(
  100.         TypeRepository $typeRepo,
  101.         PostRepository $postRepo,
  102.         CategoryRepository $categoryRepo,
  103.         TagRepository $tagRepo,
  104.         PostTagRepository $postTagRepo,
  105.         CsrfTokenManagerInterface $csrfTokenManager,
  106.         AuthorizationCheckerInterface $authCheck,
  107.         TokenStorageInterface $tokenStore
  108.     ){
  109.         $this->typeRepo $typeRepo;
  110.         $this->postRepo $postRepo;
  111.         $this->categoryRepo $categoryRepo;
  112.         $this->tagRepo $tagRepo;
  113.         $this->postTagRepo $postTagRepo;
  114.         $this->csrfTokenManager $csrfTokenManager;
  115.         $this->authCheck $authCheck;
  116.         $this->tokenStore $tokenStore;
  117.     }
  118.     /**
  119.      * index
  120.      *
  121.      * @param Request $request
  122.      * @return \Symfony\Component\HttpFoundation\Response
  123.      *
  124.      * @Route("/",name="_index")
  125.      */
  126.     public function index(Request $request)
  127.     {
  128.         return $this->redirectToRoute(Constants::ADMIN_BIND_PREFIX '_type_list');
  129.     }
  130.     /**
  131.      * 投稿タイプ / リスト
  132.      *
  133.      * @param Request $request
  134.      * @return \Symfony\Component\HttpFoundation\Response
  135.      *
  136.      * @Route("/type_list",name="_type_list")
  137.      * @Template("@TabaCMS2/admin/type_list.twig")
  138.      */
  139.     public function type_list(Request $request)
  140.     {
  141.         // 投稿タイプリスト取得
  142.         $list $this->typeRepo->getList();
  143.         return [
  144.             'list' => $list
  145.         ];
  146.     }
  147.     /**
  148.      * 投稿タイプ / 新規登録・編集
  149.      *
  150.      * @param Request $request
  151.      * @param integer $type_id
  152.      * @return \Symfony\Component\HttpFoundation\Response
  153.      *
  154.      * @Route("/type_new",name="_type_new")
  155.      * @Route("/type_edit/{type_id}",name="_type_edit",requirements={"type_id" = "\d+"})
  156.      * @Template("@TabaCMS2/admin/type_edit.twig")
  157.      */
  158.     public function type_edit(Request $request$type_id null)
  159.     {
  160.         $oldDataKey null;
  161.         $oldPublicDiv null;
  162.         // 投稿タイプ操作オブジェクトの生成
  163.         $type null;
  164.         if ($type_id) {
  165.             if (! ($type $this->typeRepo->find($type_id))) {
  166.                 throw new NotFoundHttpException();
  167.             }
  168.             $oldDataKey $type->getDataKey();
  169.             $oldPublicDiv $type->getPublicDiv();
  170.         } else {
  171.             $type = new Type(true);
  172.         }
  173.         // フォームの生成
  174.         $builder $this->formFactory->createBuilder(TypeType::class, $type);
  175.         $form $builder->getForm();
  176.         // レイアウトのデフォルト値を設定
  177.         $form->get('pcLayout')->setData($type->getPcLayout());
  178.         $form->get('spLayout')->setData($type->getSpLayout());
  179.         // 登録・変更実行
  180.         if ('POST' === $request->getMethod()) {
  181.             $form->handleRequest($request);
  182.             if ($form->isValid()) {
  183.                 // レイアウト
  184.                 $type->setPcLayout($form->get('pcLayout')->getData());
  185.                 $type->setSpLayout($form->get('spLayout')->getData());
  186.                 if ($this->typeRepo->save($type)) {
  187.                     // 新規、データキーの変更、公開区分の変更があった場合にキャッシュクリアします
  188.                     if ($type_id == null || $oldDataKey != $type->getDataKey() || $oldPublicDiv != $type->getPublicDiv()) {
  189.                         $this->routingCacheClear();
  190.                     }
  191.                     $this->addSuccess('admin.common.save_complete''admin');
  192.                     return $this->redirectToRoute(Constants::ADMIN_BIND_PREFIX '_type_edit', ['type_id' => $type->getTypeId()]);
  193.                 } else {
  194.                     $this->addError('admin.common.save_error''admin');
  195.                 }
  196.             } else {
  197.                 $this->addError('admin.common.save_error''admin');
  198.             }
  199.         }
  200.         return [
  201.             'form' => $form->createView(),
  202.             'type' => $type
  203.         ];
  204.     }
  205.     /**
  206.      * 投稿タイプ / 削除
  207.      *
  208.      * @param Request $request
  209.      * @param integer $type_id
  210.      * @return \Symfony\Component\HttpFoundation\Response
  211.      *
  212.      * @Route("/type_delete/{type_id}",name="_type_delete",requirements={"type_id" = "\d+"})
  213.      */
  214.     public function type_delete(Request $request$type_id)
  215.     {
  216.         // 投稿タイプ操作オブジェクトの生成
  217.         $status false;
  218.         if (! empty($type_id) && ($type $this->typeRepo->find($type_id))) {
  219.             $status $this->typeRepo->delete($type);
  220.         } else {
  221.             throw new NotFoundHttpException();
  222.         }
  223.         if ($status) {
  224.             $this->routingCacheClear(); // キャッシュクリア
  225.             $this->addSuccess('admin.common.delete_complete''admin');
  226.         } else {
  227.             $this->addError('admin.common.delete_error''admin');
  228.         }
  229.         return $this->redirectToRoute(Constants::ADMIN_BIND_PREFIX '_type_list');
  230.     }
  231.     /**
  232.      * カテゴリー / リスト
  233.      *
  234.      * @param Request $request
  235.      * @param integer $type_id
  236.      * @return \Symfony\Component\HttpFoundation\Response
  237.      *
  238.      * @Route("/category_list/{type_id}",name="_category_list",requirements={"type_id" = "\d+"})
  239.      * @Template("@TabaCMS2/admin/category_list.twig")
  240.      */
  241.     public function category_list(Request $request$type_id null)
  242.     {
  243.         // 投稿タイプID
  244.         if (empty($type_id)) {
  245.             $path explode("/"$request->getRequestUri());
  246.             $type_id end($path);
  247.         }
  248.         // 投稿タイプ取得
  249.         $type null;
  250.         if (! ($type $this->typeRepo->find($type_id))) {
  251.             throw new NotFoundHttpException();
  252.         }
  253.         // カテゴリーリスト取得
  254.         $list $this->categoryRepo->getList(array(
  255.             'type_id' => $type_id
  256.         ));
  257.         return [
  258.             'csrf_token' => $this->csrfTokenManager->getToken(Constant::TOKEN_NAME)->getValue(), // CSRFトークン文字列
  259.             'type' => $type,
  260.             'list' => $list
  261.         ];
  262.     }
  263.     /**
  264.      * カテゴリー / 新規登録・編集
  265.      *
  266.      * @param Request $request
  267.      * @param integer $id
  268.      * @return \Symfony\Component\HttpFoundation\Response
  269.      *
  270.      * @Route("/category_new/{type_id}",name="_category_new",requirements={"type_id" = "\d+"})
  271.      * @Route("/category_edit/{type_id}/{category_id}",name="_category_edit",requirements={"type_id" = "\d+","category_id" = "\d+"})
  272.      * @Template("@TabaCMS2/admin/category_edit.twig")
  273.      */
  274.     public function category_edit(Request $request$type_id$category_id null)
  275.     {
  276.         // 投稿タイプ取得
  277.         $type null;
  278.         if (! ($type $this->typeRepo->find($type_id))) {
  279.             throw new NotFoundHttpException();
  280.         }
  281.         // カテゴリー操作オブジェクトの生成
  282.         $category null;
  283.         if ($category_id) {
  284.             if (! ($category $this->categoryRepo->find($category_id))) {
  285.                 throw new NotFoundHttpException();
  286.             }
  287.         } else {
  288.             $category = new Category(true);
  289.         }
  290.         $category->setTypeId($type_id);
  291.         $category->setType($type);
  292.         // フォームの生成
  293.         $builder $this->formFactory->createBuilder(CategoryType::class, $category);
  294.         $form $builder->getForm();
  295.         $imageEdited false// 画像編集済みかチェックするフラグ
  296.         $originThumbnail $category->getThumbnail();
  297.         // 登録・変更実行
  298.         if ($originThumbnail != $category->getThumbnail()) $imageEdited true;
  299.         if ('POST' === $request->getMethod()) {
  300.             $form->handleRequest($request);
  301.             if ($form->isValid()) {
  302.                 if ($this->categoryRepo->save($category)) {
  303.                     $this->addSuccess('admin.common.save_complete''admin');
  304.                     // 画像を移動
  305.                     if ($category->getThumbnail() !== null && file_exists($this->eccubeConfig['eccube_temp_image_dir'] . '/' $category->getThumbnail())) {
  306.                         rename($this->eccubeConfig['eccube_temp_image_dir'] . '/' $category->getThumbnail(), $this->eccubeConfig['eccube_save_image_dir'] . '/' $category->getThumbnail());
  307.                     }
  308.                     // 画像削除
  309.                     $oldPath $newPath null;
  310.                     if ($originThumbnail$oldPath $this->eccubeConfig['eccube_save_image_dir'] . '/' $originThumbnail;
  311.                     if ($category->getThumbnail()) $newPath $this->eccubeConfig['eccube_save_image_dir'] . '/' $category->getThumbnail();
  312.                     if (!$category->getThumbnail()) {
  313.                         if (file_exists($newPath)) unlink($newPath);
  314.                         if (file_exists($oldPath)) unlink($oldPath);
  315.                     } else if ($originThumbnail != $category->getThumbnail()) {
  316.                         if (file_exists($oldPath)) unlink($oldPath);
  317.                     }
  318.                     return $this->redirectToRoute(Constants::ADMIN_BIND_PREFIX '_category_edit', array(
  319.                         'type_id' => $type_id,
  320.                         'category_id' => $category->getCategoryId()
  321.                     ));
  322.                 } else {
  323.                     $this->addError('admin.common.save_error''admin');
  324.                 }
  325.             }
  326.         }
  327.         return [
  328.             'csrf_token' => $this->csrfTokenManager->getToken(Constant::TOKEN_NAME)->getValue(), // CSRFトークン文字列
  329.             'form' => $form->createView(),
  330.             'type' => $type,
  331.             'category' => $category,
  332.             'image_edited' => $imageEdited,
  333.         ];
  334.     }
  335.     /**
  336.      * カテゴリー / 削除
  337.      *
  338.      * @param Request $request
  339.      * @param
  340.      *            integer ,$category_id
  341.      * @return \Symfony\Component\HttpFoundation\Response
  342.      *
  343.      * @Route("/category_delete/{category_id}",name="_category_delete",requirements={"category_id" = "\d+"})
  344.      */
  345.     public function category_delete(Request $request$category_id)
  346.     {
  347.         // 投稿タイプ操作オブジェクトの生成
  348.         $status false;
  349.         $category $this->categoryRepo->find($category_id);
  350.         $type_id $category->getTypeId();
  351.         if (! empty($category)) {
  352.             $status $this->categoryRepo->delete($category);
  353.         } else {
  354.             throw new NotFoundHttpException();
  355.         }
  356.         if ($status) {
  357.             $this->addSuccess('admin.common.delete_complete''admin');
  358.         } else {
  359.             $this->addError('admin.common.delete_error''admin');
  360.         }
  361.         return $this->redirectToRoute(Constants::ADMIN_BIND_PREFIX '_category_list',['type_id' => $type_id]);
  362.     }
  363.     /**
  364.      * カテゴリー / ソート
  365.      *
  366.      * @param Request $request
  367.      * @param integer $type_id
  368.      * @return \Symfony\Component\HttpFoundation\Response
  369.      *
  370.      * @Route("/category_sort/{type_id}",name="_category_sort",requirements={"type_id" = "\d+"})
  371.      */
  372.     public function category_sort(Request $request$type_id)
  373.     {
  374.         // CSRF
  375.         if (! $this->csrfTokenManager->isTokenValid(new CsrfToken(Constant::TOKEN_NAME$request->get(Constant::TOKEN_NAME)))) {
  376.             throw new AccessDeniedHttpException('CSRF token is invalid.');
  377.         }
  378.         // XMLHttpRequest
  379.         if (! $request->isXmlHttpRequest()) {
  380.             throw new BadRequestHttpException('Request is invalid.');
  381.         }
  382.         $category_ids $_POST['category_ids'];
  383.         if (! empty($type_id) && $category_ids) {
  384.             // 投稿タイプ取得
  385.             if (! $this->typeRepo->find($type_id)) {
  386.                 throw new NotFoundHttpException();
  387.             }
  388.             $no 1;
  389.             foreach ($category_ids as $category_id) {
  390.                 if (($category $this->categoryRepo->find($category_id))) {
  391.                     $category->setOrderNo($no++);
  392.                     if (!$this->categoryRepo->save($category)) {
  393.                         log_debug("順番の更新が出来ませんでした");
  394.                     }
  395.                 }
  396.             }
  397.         } else {
  398.             throw new BadRequestHttpException('必要なパラメーターが取得できません');
  399.         }
  400.         return new JsonResponse([]);
  401.     }
  402.     /**
  403.      * タグ / リスト
  404.      *
  405.      * @param Request $request
  406.      * @param integer $type_id
  407.      * @return \Symfony\Component\HttpFoundation\Response
  408.      *
  409.      * @Route("/tag_list/{type_id}",name="_tag_list",requirements={"type_id" = "\d+"})
  410.      * @Template("@TabaCMS2/admin/tag_list.twig")
  411.      */
  412.     public function tag_list(Request $request$type_id null)
  413.     {
  414.         // 投稿タイプID
  415.         if (empty($type_id)) {
  416.             $path explode("/"$request->getRequestUri());
  417.             $type_id end($path);
  418.         }
  419.         // 投稿タイプ取得
  420.         $type null;
  421.         if (! ($type $this->typeRepo->find($type_id))) {
  422.             throw new NotFoundHttpException();
  423.         }
  424.         // タグリスト取得
  425.         $list $this->tagRepo->getList(array(
  426.             'type_id' => $type_id
  427.         ));
  428.         return [
  429.             'csrf_token' => $this->csrfTokenManager->getToken(Constant::TOKEN_NAME)->getValue(), // CSRFトークン文字列
  430.             'type' => $type,
  431.             'list' => $list
  432.         ];
  433.     }
  434.     /**
  435.      * タグ / 新規登録・編集
  436.      *
  437.      * @param Request $request
  438.      * @param integer $id
  439.      * @return \Symfony\Component\HttpFoundation\Response
  440.      *
  441.      * @Route("/tag_new/{type_id}",name="_tag_new",requirements={"type_id" = "\d+"})
  442.      * @Route("/tag_edit/{type_id}/{tag_id}",name="_tag_edit",requirements={"type_id" = "\d+", "tag_id" = "\d+"})
  443.      * @Template("@TabaCMS2/admin/tag_edit.twig")
  444.      */
  445.     public function tag_edit(Request $request$type_id$tag_id null)
  446.     {
  447.         // 投稿タイプ取得
  448.         $type null;
  449.         if (! ($type $this->typeRepo->find($type_id))) {
  450.             throw new NotFoundHttpException();
  451.         }
  452.         // タグ操作オブジェクトの生成
  453.         $tag null;
  454.         if ($tag_id) {
  455.             if (! ($tag $this->tagRepo->find($tag_id))) {
  456.                 throw new NotFoundHttpException();
  457.             }
  458.         } else {
  459.             $tag = new Tag(true);
  460.         }
  461.         $tag->setTypeId($type_id);
  462.         $tag->setType($type);
  463.         // フォームの生成
  464.         $builder $this->formFactory->createBuilder(TagType::class, $tag);
  465.         $form $builder->getForm();
  466.         // 登録・変更実行
  467.         if ('POST' === $request->getMethod()) {
  468.             $form->handleRequest($request);
  469.             if ($form->isValid()) {
  470.                 if ($this->tagRepo->save($tag)) {
  471.                     $this->addSuccess('admin.common.save_complete''admin');
  472.                     return $this->redirectToRoute(Constants::ADMIN_BIND_PREFIX '_tag_edit', array(
  473.                         'type_id' => $type_id,
  474.                         'tag_id' => $tag->getTagId()
  475.                     ));
  476.                 } else {
  477.                     $this->addError('admin.common.save_error''admin');
  478.                 }
  479.             }
  480.         }
  481.         return [
  482.             'csrf_token' => $this->csrfTokenManager->getToken(Constant::TOKEN_NAME)->getValue(), // CSRFトークン文字列
  483.             'form' => $form->createView(),
  484.             'type' => $type,
  485.             'tag' => $tag
  486.         ];
  487.     }
  488.     /**
  489.      * タグ / 削除
  490.      *
  491.      * @param Request $request
  492.      * @param
  493.      *            integer ,$tag_id
  494.      * @return \Symfony\Component\HttpFoundation\Response
  495.      *
  496.      * @Route("/tag_delete/{tag_id}",name="_tag_delete",requirements={"tag_id" = "\d+"})
  497.      */
  498.     public function tag_delete(Request $request$tag_id)
  499.     {
  500.         // 投稿タイプ操作オブジェクトの生成
  501.         $status false;
  502.         $tag $this->tagRepo->find($tag_id);
  503.         $type_id $tag->getTypeId();
  504.         if (! empty($tag)) {
  505.             $status $this->tagRepo->delete($tag);
  506.         } else {
  507.             throw new NotFoundHttpException();
  508.         }
  509.         if ($status) {
  510.             $this->addSuccess('admin.common.delete_complete''admin');
  511.         } else {
  512.             $this->addError('admin.common.delete_error''admin');
  513.         }
  514.         return $this->redirectToRoute(Constants::ADMIN_BIND_PREFIX '_tag_list',['type_id' => $type_id]);
  515.     }
  516.     /**
  517.      * タグ / ソート
  518.      *
  519.      * @param Request $request
  520.      * @param integer $type_id
  521.      * @return \Symfony\Component\HttpFoundation\Response
  522.      *
  523.      * @Route("/tag_sort/{type_id}",name="_tag_sort",requirements={"type_id" = "\d+"})
  524.      */
  525.     public function tag_sort(Request $request$type_id)
  526.     {
  527.         // CSRF
  528.         if (! $this->csrfTokenManager->isTokenValid(new CsrfToken(Constant::TOKEN_NAME$request->get(Constant::TOKEN_NAME)))) {
  529.             throw new AccessDeniedHttpException('CSRF token is invalid.');
  530.         }
  531.         // XMLHttpRequest
  532.         if (! $request->isXmlHttpRequest()) {
  533.             throw new BadRequestHttpException('Request is invalid.');
  534.         }
  535.         $tag_ids $_POST['tag_ids'];
  536.         if (! empty($type_id) && $tag_ids) {
  537.             // 投稿タイプ取得
  538.             if (! $this->typeRepo->find($type_id)) {
  539.                 throw new NotFoundHttpException();
  540.             }
  541.             $no 1;
  542.             foreach ($tag_ids as $tag_id) {
  543.                 if (($tag $this->tagRepo->find($tag_id))) {
  544.                     $tag->setOrderNo($no++);
  545.                     if (!$this->tagRepo->save($tag)) {
  546.                         log_debug("順番の更新が出来ませんでした");
  547.                     }
  548.                 }
  549.             }
  550.         } else {
  551.             throw new BadRequestHttpException('必要なパラメーターが取得できません');
  552.         }
  553.         return new JsonResponse([]);
  554.     }
  555.     /**
  556.      * 投稿 / リスト
  557.      *
  558.      * @param Request $request
  559.      * @return \Symfony\Component\HttpFoundation\Response
  560.      *
  561.      * @Route("/post_list",name="_post_list")
  562.      * @Template("@TabaCMS2/admin/post_list.twig")
  563.      */
  564.     public function post_list(Request $requestPaginatorInterface $paginator)
  565.     {
  566.         // パラメーターの取得
  567.         if ('POST' === $request->getMethod()) {
  568.             $params $request->request->all();
  569.         } else {
  570.             $params $request->query->all();
  571.         }
  572.         $type_id = (isset($params['type_id']) && $params['type_id'] ? $params['type_id'] : null);
  573.         $page_no = (isset($params['page_no']) && $params['page_no'] ? $params['page_no'] : 1);
  574.         // 投稿タイプID
  575.         if (empty($type_id)) {
  576.             throw new NotFoundHttpException();
  577.         }
  578.         // 投稿タイプ取得
  579.         $type null;
  580.         if (empty($type_id) || ! ($type $this->typeRepo->find($type_id))) {
  581.             throw new NotFoundHttpException();
  582.         }
  583.         // フォームの生成
  584.         $builder $this->formFactory->createBuilder(PostSearchType::class,['type_id' => $type_id]);
  585.         $searchForm $builder->getForm();
  586.         $searchForm->handleRequest($request);
  587.         $searchData $searchForm->getData();
  588.         // 投稿リスト取得
  589.         $list $paginator->paginate(
  590.             $this->postRepo->createListQueryBuilder($searchData),
  591.             $page_no,
  592.             Constants::DEFAULT_PAGE_COUNT,
  593.             ['wrap-queries' => true]
  594.         );
  595.         return [
  596.             'csrf_token' => $this->csrfTokenManager->getToken(Constant::TOKEN_NAME)->getValue(), // CSRFトークン文字列
  597.             'searchForm' => $searchForm->createView(),
  598.             'type' => $type,
  599.             'list' => $list
  600.         ];
  601.     }
  602.     /**
  603.      * 投稿 / 新規登録・編集
  604.      *
  605.      * @param Request $request
  606.      * @param integer $id
  607.      * @return \Symfony\Component\HttpFoundation\Response
  608.      *
  609.      * @Route("/post_new/{type_id}",name="_post_new",requirements={"type_id" = "\d+"})
  610.      * @Route("/post_edit/{type_id}/{post_id}",name="_post_edit",requirements={"type_id" = "\d+", "post_id" = "\d+"})
  611.      * @Template("@TabaCMS2/admin/post_edit.twig")
  612.      */
  613.     public function post_edit(Request $request,$type_id,$post_id null)
  614.     {
  615.         // 投稿タイプID
  616.         $type_id null;
  617.         // 設定ファイル
  618.         $userConfig UserConfig::getInstance();
  619.         // 投稿操作オブジェクトの生成
  620.         $post null;
  621.         if ($post_id) {
  622.             if (! ($post $this->postRepo->find($post_id))) {
  623.                 throw new NotFoundHttpException();
  624.             }
  625.             $type_id $post->getTypeId();
  626.                 // タグの正規化
  627.                 if ($post->getBody() != null) {
  628.                 // JS除去
  629.                 if ($userConfig->get("editor.tag.enable") == null || !is_array($userConfig->get("editor.tag.enable")) || !in_array('script',$userConfig->get("editor.tag.enable"))) {
  630.                     $post->setBody(Util::removeJS($post->getBody()));
  631.                 }
  632.                 // タグ除去
  633.                 if ($userConfig->get("editor.tag.disable") && is_array($userConfig->get("editor.tag.disable"))) {
  634.                     $tags $userConfig->get("editor.tag.disable");
  635.                     foreach ($tags as $tag) {
  636.                         $post->setBody(Util::removeTag($post->getBody(),$tag));
  637.                     }
  638.                 }
  639.             }
  640.         } else {
  641.             $post = new post(true);
  642.             $path explode("/"$request->getRequestUri());
  643.             $type_id end($path);
  644.         }
  645.         $imageEdited false// 画像編集済みかチェックするフラグ
  646.         $originThumbnail $post->getThumbnail();
  647.         // 投稿タイプ取得
  648.         $type null;
  649.         if (empty($type_id) || ! ($type $this->typeRepo->find($type_id))) {
  650.             throw new NotFoundHttpException();
  651.         }
  652.         $post->setTypeId($type_id);
  653.         $post->setType($type);
  654.         // フォームの生成
  655.         $builder $this->formFactory->createBuilder(PostType::class, $post);
  656.         $form $builder->getForm();
  657.         // 登録・変更実行
  658.         if ('POST' === $request->getMethod()) {
  659.             // データが入力されていない場合、初期値をセットします。
  660.             $params $request->request->all();
  661.             // 公開日
  662.             if (empty($params[$form->getName()]['public_date'])) {
  663.                 $params[$form->getName()]['public_date'] = date('Y-m-d H:i');
  664.             }
  665.             // データキー
  666.             if (empty($params[$form->getName()]['data_key'])) {
  667.                 $data_key $type->getDataKey() . "_" date('Ymd'strtotime($params[$form->getName()]['public_date']));
  668.                 if ($this->postRepo->getList(array(
  669.                     'data_key' => $data_key
  670.                 ))) {
  671.                     for ($i 1$i <= PHP_INT_MAX$i ++) {
  672.                         if (! $this->postRepo->getList(array(
  673.                             'data_key' => $data_key "_" $i
  674.                         ))) {
  675.                             $data_key $data_key "_" $i;
  676.                             break;
  677.                         }
  678.                     }
  679.                 }
  680.                 $params[$form->getName()]['data_key'] = $data_key;
  681.             }
  682.             // タグの正規化
  683.             if (!empty($params[$form->getName()]['body'])) {
  684.                 // JS除去
  685.                 if ($userConfig->get("editor.tag.enable") == null || !is_array($userConfig->get("editor.tag.enable")) || !in_array('script',$userConfig->get("editor.tag.enable"))) {
  686.                     $params[$form->getName()]['body'] = Util::removeJS($params[$form->getName()]['body']);
  687.                 }
  688.                 // タグ除去
  689.                 if ($userConfig->get("editor.tag.disable") && is_array($userConfig->get("editor.tag.disable"))) {
  690.                     $tags $userConfig->get("editor.tag.disable");
  691.                     foreach ($tags as $tag) {
  692.                         $params[$form->getName()]['body'] = Util::removeTag($params[$form->getName()]['body'],$tag);
  693.                     }
  694.                 }
  695.             }
  696.             $request->request->replace($params);
  697.             $form->handleRequest($request);
  698.             if ($originThumbnail != $post->getThumbnail()) $imageEdited true;
  699.             if ($form->isValid()) {
  700.                 // データ作成者
  701.                 if ($this->tokenStore && $this->tokenStore->getToken() && ($user $this->tokenStore->getToken()->getUser()) && is_object($user)) {
  702.                     $post->setMember($user);
  703.                 }
  704.                 // 画像を移動
  705.                 if ($post->getThumbnail() !== null && file_exists($this->eccubeConfig['eccube_temp_image_dir'] . '/' $post->getThumbnail())) {
  706.                     rename($this->eccubeConfig['eccube_temp_image_dir'] . '/' $post->getThumbnail(), $this->eccubeConfig['eccube_save_image_dir'] . '/' $post->getThumbnail());
  707.                 }
  708.                 // 画像削除
  709.                 $oldPath $newPath null;
  710.                 if ($originThumbnail$oldPath $this->eccubeConfig['eccube_save_image_dir'] . '/' $originThumbnail;
  711.                 if ($post->getThumbnail()) $newPath $this->eccubeConfig['eccube_save_image_dir'] . '/' $post->getThumbnail();
  712.                 if (!$post->getThumbnail()) {
  713.                     if (file_exists($newPath)) unlink($newPath);
  714.                     if (file_exists($oldPath)) unlink($oldPath);
  715.                 } else if ($originThumbnail != $post->getThumbnail()) {
  716.                     if (file_exists($oldPath)) unlink($oldPath);
  717.                 }
  718.                 // データ保存
  719.                 if ($this->postRepo->save($post)) {
  720.                     // タグ
  721.                     if ($this->postTagRepo->set($post,$form->get('postTagIds')->getData())) {
  722.                         $this->addSuccess('admin.common.save_complete''admin');
  723.                     } else {
  724.                         $this->addError('admin.common.save_error''admin');
  725.                     }
  726.                     return $this->redirectToRoute(Constants::ADMIN_BIND_PREFIX '_post_edit',['type_id' => $type_id,'post_id' => $post->getPostId()]);
  727.                 } else {
  728.                     $this->addError('admin.common.save_error''admin');
  729.                 }
  730.             }
  731.         }
  732.         return [
  733.             'csrf_token' => $this->csrfTokenManager->getToken(Constant::TOKEN_NAME)->getValue(), // CSRFトークン文字列
  734.             'form' => $form->createView(),
  735.             'type' => $type,
  736.             'post' => $post,
  737.             'image_edited' => $imageEdited,
  738.         ];
  739.     }
  740.     /**
  741.      * 投稿 / 削除
  742.      *
  743.      * @param Request $request
  744.      * @param integer $post_id
  745.      * @return \Symfony\Component\HttpFoundation\Response
  746.      *
  747.      * @Route("/post_delete/{post_id}",name="_post_delete",requirements={"post_id" = "\d+"})
  748.      */
  749.     public function post_delete(Request $request$post_id)
  750.     {
  751.         // 投稿タイプ操作オブジェクトの生成
  752.         $status false;
  753.         $post $this->postRepo->find($post_id);
  754.         $type_id null;
  755.         if (! empty($post)) {
  756.             $status $this->postRepo->delete($post);
  757.             $type_id $post->getTypeId();
  758.         } else {
  759.             throw new NotFoundHttpException();
  760.         }
  761.         if ($status) {
  762.             $this->addSuccess('admin.common.delete_complete''admin');
  763.         } else {
  764.             $this->addError('admin.common.delete_error''admin');
  765.         }
  766.         return $this->redirectToRoute(Constants::ADMIN_BIND_PREFIX '_post_list',['type_id' => $type_id]);
  767.     }
  768.     /**
  769.      * 投稿 / アイキャッチ画像アップロード
  770.      *
  771.      * @param Request $request
  772.      * @throws BadRequestHttpException
  773.      * @throws UnsupportedMediaTypeHttpException
  774.      * @return \Symfony\Component\HttpFoundation\Response
  775.      *
  776.      * @Route("/post_thumbnail_upload",name="_post_thumbnail_upload")
  777.      */
  778.     public function post_thumbnail_upload(Request $request)
  779.     {
  780.         // CSRF
  781.         if (! $this->csrfTokenManager->isTokenValid(new CsrfToken(Constant::TOKEN_NAME$request->get(Constant::TOKEN_NAME)))) {
  782.             throw new AccessDeniedHttpException('CSRF token is invalid.');
  783.         }
  784.         // XMLHttpRequest
  785.         if (! $request->isXmlHttpRequest()) {
  786.             throw new BadRequestHttpException('Request is invalid.');
  787.         }
  788.         $files $request->files->get(Constants::PLUGIN_CODE_LC '_post');
  789.         $file_name null;
  790.         if (count($files) > 0) {
  791.             foreach ($files as $file) {
  792.                 log_debug("[FILE OBJECT] " print_r($filetrue));
  793.                 if (!== strpos($file->getMimeType(), 'image')) {
  794.                     throw new UnsupportedMediaTypeHttpException('File format is invalid.');
  795.                 }
  796.                 $extension $file->getClientOriginalExtension();
  797.                 $file_name date('mdHis') . uniqid('_') . '.' $extension;
  798.                 $file->move($this->eccubeConfig['eccube_temp_image_dir'], $file_name);
  799.                 break;
  800.             }
  801.         }
  802.         return new JsonResponse([
  803.             'file' => $file_name
  804.         ], 200);
  805.     }
  806.     /**
  807.      * カテゴリー / 画像アップロード
  808.      *
  809.      * @param Request $request
  810.      * @throws BadRequestHttpException
  811.      * @throws UnsupportedMediaTypeHttpException
  812.      * @return \Symfony\Component\HttpFoundation\Response
  813.      *
  814.      * @Route("/category_thumbnail_upload",name="_category_thumbnail_upload")
  815.      */
  816.     public function category_thumbnail_upload(Request $request)
  817.     {
  818.         // CSRF
  819.         if (! $this->csrfTokenManager->isTokenValid(new CsrfToken(Constant::TOKEN_NAME$request->get(Constant::TOKEN_NAME)))) {
  820.             throw new AccessDeniedHttpException('CSRF token is invalid.');
  821.         }
  822.         // XMLHttpRequest
  823.         if (! $request->isXmlHttpRequest()) {
  824.             throw new BadRequestHttpException('Request is invalid.');
  825.         }
  826.         $files $request->files->get(Constants::PLUGIN_CODE_LC '_category');
  827.         $file_name null;
  828.         if (count($files) > 0) {
  829.             foreach ($files as $file) {
  830.                 log_debug("[FILE OBJECT] " print_r($filetrue));
  831.                 if (!== strpos($file->getMimeType(), 'image')) {
  832.                     throw new UnsupportedMediaTypeHttpException('File format is invalid.');
  833.                 }
  834.                 $extension $file->getClientOriginalExtension();
  835.                 $file_name date('mdHis') . uniqid('_') . '.' $extension;
  836.                 $file->move($this->eccubeConfig['eccube_temp_image_dir'], $file_name);
  837.                 break;
  838.             }
  839.         }
  840.         return new JsonResponse([
  841.             'file' => $file_name
  842.         ], 200);
  843.     }
  844.     /**
  845.      * 各種ファイルを出力します。
  846.      *
  847.      * @param Request $request
  848.      * @param string $file
  849.      * @throws NotFoundHttpException
  850.      * @return BinaryFileResponse
  851.      *
  852.      * @Route("/assets/{file}",name="_assets",requirements={"file"="[a-zA-Z0-9-_/\s.]+"})
  853.      */
  854.     public function assets(Request $request,$file) {
  855.         if ($this->container->has('profiler')) $this->container->get('profiler')->disable();
  856.         if (strpos($file,'..')) {
  857.             log_critical("ディレクトリトラバーサル攻撃の可能性があります。 [FILE] " $file);
  858.             throw new NotFoundHttpException();
  859.         }
  860.         $file Constants::TEMPLATE_PATH DIRECTORY_SEPARATOR .  "admin" DIRECTORY_SEPARATOR "assets" .  DIRECTORY_SEPARATOR $file;
  861.         if (file_exists($this->eccubeConfig['plugin_realdir'] . DIRECTORY_SEPARATOR $file)) {
  862.             log_debug("[ASSETS] [FILE] " $file);
  863.             // 拡張子によりMIMEを設定します。
  864.             $suffixes explode(".",$file);
  865.             $suffix end($suffixes);
  866.             $suffix_def = array(
  867.                 "jpeg" => "image/jpg",
  868.                 "jpg" => "image/jpg",
  869.                 "gif" => "image/gif",
  870.                 "png" => "image/png",
  871.                 "svg" => "image/svg+xml",
  872.                 "webp" => "image/webp",
  873.                 "js" => "application/x-javascript",
  874.                 "css" => "text/css",
  875.                 "html" => "text/html",
  876.                 "map" => "application/json",
  877.             );
  878.             if (in_array($suffix,array_keys($suffix_def))) {
  879.                 $fileObject = new \SplFileInfo($this->eccubeConfig['plugin_realdir'] . DIRECTORY_SEPARATOR $file);
  880.                 $response = new BinaryFileResponse($fileObject);
  881.                 $response->headers->set('Content-Type',$suffix_def[$suffix]);
  882.                 // キャッシュするヘッダーを出力する設定をします
  883.                 if ($this->container->has(Constants::CONTAINER_KEY_NAME)) {
  884.                     $this->container->get(Constants::CONTAINER_KEY_NAME)->set(Constants::HTTP_CACHE_STATUS,true);
  885.                 }
  886.                 return $response;
  887.             } else {
  888.                 throw new NotFoundHttpException();
  889.             }
  890.         } else {
  891.             throw new NotFoundHttpException();
  892.         }
  893.     }
  894.     /**
  895.      * ルーティング関連のキャッシュを削除します。
  896.      */
  897.     private function routingCacheClear() {
  898.         try {
  899.             $cacheDir $this->getParameter("kernel.cache_dir");
  900.             $filesystem = new Filesystem();
  901.             $finder = new Finder();
  902.             foreach ($finder->files()->depth('== 0')->in($cacheDir) as $file) {
  903.                 if (preg_match('/UrlGenerator|UrlMatcher|url_generating_routes|url_matching_routes/'$file->getFilename()) == 1) {
  904.                     $filesystem->remove($file->getRealpath());
  905.                 }
  906.             }  
  907.         } catch (\Exception $e) {
  908.             log_error('キャッシュファイルの削除に失敗しました。 ' $e->getMessage());
  909.         }
  910.         //$this->router->warmUp($cacheDir);
  911.     }
  912. }