app/Plugin/TabaCMS2/Controller/FrontController.php line 300

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 Plugin\TabaCMS2\Common\Constants;
  10. use Plugin\TabaCMS2\Common\DataHolder;
  11. use Plugin\TabaCMS2\Common\UserConfig;
  12. use Plugin\TabaCMS2\Util\Util;
  13. use Plugin\TabaCMS2\Repository\TypeRepository;
  14. use Plugin\TabaCMS2\Repository\PostRepository;
  15. use Plugin\TabaCMS2\Repository\CategoryRepository;
  16. use Plugin\TabaCMS2\Entity\Type;
  17. use Plugin\TabaCMS2\Entity\Post;
  18. use Plugin\TabaCMS2\Form\Type\PostType;
  19. use Eccube\Common\Constant;
  20. use Eccube\Controller\AbstractController;
  21. use Eccube\Repository\PageRepository;
  22. use Eccube\Repository\LayoutRepository;
  23. use Symfony\Component\DependencyInjection\ContainerInterface;
  24. use Symfony\Component\HttpFoundation\Request;
  25. use Symfony\Component\HttpFoundation\Response;
  26. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  27. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  28. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  29. use Symfony\Component\Asset\Packages;
  30. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
  31. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  32. use Detection\MobileDetect;
  33. /**
  34.  *  @Route(Plugin\TabaCMS2\Common\Constants::FRONT_URI_PREFIX,name=Plugin\TabaCMS2\Common\Constants::FRONT_BIND_PREFIX)
  35.  */
  36. class FrontController extends AbstractController
  37. {
  38.     /**
  39.      *
  40.      * @var TypeRepository
  41.      */
  42.     private $typeRepo;
  43.     /**
  44.      *
  45.      * @var PostRepository
  46.      */
  47.     private $postRepo;
  48.     /**
  49.      * @var CategoryRepository
  50.      */
  51.     private $categoryRepo;
  52.     /**
  53.      * @var PageRepository
  54.      */
  55.     private $pageRepo;
  56.     /**
  57.      * @var LayoutRepository
  58.      */
  59.     private $layoutRepo;
  60.     /**
  61.      * @var MobileDetector
  62.      */
  63.     private $mobileDetector;
  64.     /**
  65.      * @var Packages
  66.      */
  67.     private $packages;
  68.     /**
  69.      * @var ContainerInterface
  70.      */
  71.     private $containerForParam;
  72.     /**
  73.      * コンストラクタ
  74.      *
  75.      * @param TypeRepository $typeRepo
  76.      * @param PostRepository $postRepo
  77.      */
  78.     public function __construct(
  79.         TypeRepository $typeRepo,
  80.         PostRepository $postRepo,
  81.         CategoryRepository $categoryRepo,
  82.         PageRepository $pageRepo,
  83.         LayoutRepository $layoutRepo,
  84.         MobileDetect $mobileDetector,
  85.         Packages $packages,
  86.         ContainerInterface $container
  87.     ) {
  88.         $this->typeRepo $typeRepo;
  89.         $this->postRepo $postRepo;
  90.         $this->categoryRepo $categoryRepo;
  91.         $this->pageRepo $pageRepo;
  92.         $this->layoutRepo $layoutRepo;
  93.         $this->mobileDetector $mobileDetector;
  94.         $this->packages $packages;
  95.         $this->containerForParam $container;
  96.     }
  97.     /**
  98.      * index
  99.      *
  100.      * @param Request $request
  101.      * @return Response
  102.      */
  103.     public function index(Request $request) {
  104.     }
  105.     /**
  106.      * リストページと詳細ページの振り分けをします。
  107.      *
  108.      * @param Request $request
  109.      * @param string $data_key
  110.      */
  111.     public function prepare(Request $request$data_key null,$category_data_key null,$tag_data_key null)
  112.     {
  113.         // URI取得
  114.         $uri $request->getPathInfo();
  115.         if ($front_uri_prefix UserConfig::getInstance()->get("front_uri_prefix")) {
  116.               $uri =  preg_replace("{^" $front_uri_prefix "}",'',$uri);
  117.         }
  118.         // 投稿タイプのデータキー
  119.         $type_data_key null;
  120.         if (($path explode("/",$uri)) && is_array($path) && count($path) > 1) {
  121.             $type_data_key $path[1];
  122.         } else {
  123.             throw new NotFoundHttpException();
  124.         }
  125.         // 投稿タイプ
  126.         $type $this->typeRepo->get($type_data_key);
  127.         if (!$type) {
  128.             throw new NotFoundHttpException();
  129.         }
  130.         //
  131.         // カテゴリー
  132.         //
  133.         if (!empty($category_data_key)) {
  134.             // カテゴリーののデータキーを保存
  135.             DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_CATEGORY_DK$category_data_key);
  136.             // カテゴリーEntityを取得
  137.             $category $this->categoryRepo->findOneBy(['type' => $type,'dataKey' => $category_data_key]);
  138.             if (!$category) {
  139.                 throw new NotFoundHttpException();
  140.             }
  141.             $options['category'] = $category;
  142.             $dataKeys = [$type_data_key,$type_data_key "_"  $category_data_key];
  143.             // テンプレートファイル
  144.             $template_file Util::getTemplatePath('category.twig',$dataKeys,$this->containerForParam);
  145.             if (!$template_file) {
  146.                 $template_file Util::getTemplatePath('list.twig',$dataKeys,$this->containerForParam);
  147.             }
  148.             // ページタイトル
  149.             $options['subtitle'] = $type->getTypeName() . ' - ' $category->getCategoryName();
  150.             return $this->postList($request,$type,$template_file,$options);
  151.         }
  152.         //
  153.         // リスト or アーカイブ
  154.         //
  155.         elseif (empty($data_key) || $data_key == 'archive') {
  156.             // アーカイブ
  157.             if (strrpos($uri,'/archive') === strlen($uri) - strlen('/archive')) {
  158.                 $template_file Util::getTemplatePath('archive.twig',[$type->getDataKey()],$this->containerForParam);
  159.                 return $this->postList($request,$type,$template_file);
  160.             }
  161.             // リスト
  162.             else {
  163.                 $template_file Util::getTemplatePath('list.twig',[$type->getDataKey()],$this->containerForParam);
  164.                 return $this->postList($request,$type,$template_file);
  165.             }
  166.         }
  167.         // 投稿
  168.         else {
  169.             return $this->postDetail($request$data_key);
  170.         }
  171.     }
  172.     /**
  173.      * 投稿リストページ
  174.      *
  175.      * @param Request $request
  176.      */
  177.     public function postList(Request $request,$type,$template_file,$options = [])
  178.     {
  179.         // listページを実行中であることを保存
  180.         DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_PAGEConstants::PAGE_LIST);
  181.         if (!$type) {
  182.             throw new NotFoundHttpException();
  183.         }
  184.         // 投稿タイプのデータキーを保存
  185.         DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_TYPE_DK$type->getDataKey());
  186.         // ページオブジェクト生成
  187.         $page $this->pageRepo->newPage();
  188.         $page->setEditType(\Eccube\Entity\Page::EDIT_TYPE_PREVIEW);
  189.         // ページレイアウト生成
  190.         // モバイル
  191.         if ($this->mobileDetector->isMobile() && ($type->getSpLayoutId() != null && $type->getSpLayoutId() != 0)) {
  192.             $layout $type->getSpLayout();
  193.         }
  194.         // PC
  195.         else if ($type->getPcLayoutId() != null && $type->getPcLayoutId() != 0) {
  196.             $layout $type->getPcLayout();
  197.         }
  198.         // デフォルト
  199.         else {
  200.             $layout $this->layoutRepo->find(Type::DEFAULT_LAYOUT_ID);
  201.         }
  202.         // ページタイトル
  203.         if (!isset($options['subtitle'])) {
  204.             $options['subtitle'] = $type->getTypeName();
  205.             if ($request->get("category_id") && ($category $this->categoryRepo->find($request->get("category_id")))) {
  206.                 $options['subtitle'] .= " - ";
  207.                 $options['subtitle'] .= $category->getCategoryName();
  208.             }
  209.         }
  210.         return $this->render($template_file,array_merge([
  211.             'Layout' => $layout,
  212.             'Page' => $page,
  213.             'type' => $type,
  214.         ],$options));
  215.     }
  216.     /**
  217.      * 投稿ページ
  218.      *
  219.      * @param Request $request
  220.      */
  221.     public function postDetail(Request $request$data_key)
  222.     {
  223.         // postページを実行中であることを保存
  224.         DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_PAGEConstants::PAGE_POST);
  225.         // 投稿データ取得
  226.         $post null;
  227.         if (! $data_key || ! ($post $this->postRepo->get(array(
  228.             "data_key" => $data_key,
  229.             "is_public" => true
  230.         )))) {
  231.             throw new NotFoundHttpException();
  232.         }
  233.         // 投稿タイプのデータキー取得
  234.         $type $post->getType();
  235.         $type_data_key $type->getDataKey();
  236.         // 投稿タイプ、投稿のデータキーを保存
  237.         DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_TYPE_DK$type_data_key);
  238.         DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_POST_DK$data_key);
  239.         // テンプレートファイル
  240.         $template_file Util::getTemplatePath('post.twig',[$type_data_key,$data_key,$type_data_key.'_'.$data_key],$this->containerForParam);
  241.         // ページオブジェクト生成
  242.         $page $this->pageRepo->newPage();
  243.         $page->setAuthor($post->getMetaAuthor());
  244.         $page->setDescription($post->getMetaDescription());
  245.         $page->setKeyword($post->getMetaKeyword());
  246.         $page->setMetaRobots($post->getMetaRobots());
  247.         $page->setMetaTags($post->getMetaTags());
  248.         $page->setEditType(1);
  249.         // ページレイアウト生成
  250.         // モバイル
  251.         if ($this->mobileDetector->isMobile() && ($type->getSpLayoutId() != null && $type->getSpLayoutId() != 0)) {
  252.             $layout $type->getSpLayout();
  253.         }
  254.         // PC
  255.         else if ($type->getPcLayoutId() != null && $type->getPcLayoutId() != 0) {
  256.             $layout $type->getPcLayout();
  257.         }
  258.         // デフォルト
  259.         else {
  260.             $layout $this->layoutRepo->find(Type::DEFAULT_LAYOUT_ID);
  261.         }
  262.         return $this->render($template_file, [
  263.             'Layout' => $layout,
  264.             'Page' => $page,
  265.             'subtitle' => strip_tags($post->getTitle()),
  266.             'type' => $post->getType()
  267.         ]);
  268.     }
  269.     /**
  270.      * 投稿ページ / プレビュー
  271.      *
  272.      * @Route("/preview/{type_data_key}/{post_data_key}",name="_preview",methods={"POST"})
  273.      * @param Request $request
  274.      */
  275.     public function postPreview(Request $request$type_data_key,$post_data_key null)
  276.     {
  277.         // postページを実行中であることを保存
  278.         DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_PAGEConstants::PAGE_POST);
  279.         // 投稿タイプ取得
  280.         $type null;
  281.         if (!$type_data_key || !($type $this->typeRepo->get($type_data_key))) {
  282.             throw new NotFoundHttpException();
  283.         }
  284.        $post = new Post(true);
  285.        $post->setType($type);
  286.         // フォームの生成
  287.         $builder $this->formFactory->createBuilder(PostType::class, $post);
  288.         $form $builder->getForm();
  289.         $form->handleRequest($request);
  290.         // EC-CUBE 4.1 対応
  291.         // サニタイズでHTMLタグが全角に変換されるため入力値に戻す
  292.         $params $request->request->all()[$form->getName()];
  293.         if ($form->get('body') != $params['body']) {
  294.             $post->setBody($params['body']);
  295.         }
  296.         // CSRFエラーの場合のみ例外エラーにする
  297.         if (!$form->isValid() && ($errors $form->getErrors()) && count($errors) > 0) {
  298.             throw new AccessDeniedHttpException($errors[0]->getMessage());
  299.         }
  300.         // 投稿タイプ、投稿データを保存
  301.         DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_TYPE_DK$type_data_key);
  302.         DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_POST_DK$post->getDataKey());
  303.         DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_POST$post);
  304.         DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_PREVIEW,true);
  305.         // テンプレートファイル
  306.         $template_file Util::getTemplatePath('post.twig',[$type_data_key,$post->getDataKey()],$this->containerForParam);
  307.         // ページオブジェクト生成
  308.         $page $this->pageRepo->newPage();
  309.         $page->setAuthor($post->getMetaAuthor());
  310.         $page->setDescription($post->getMetaDescription());
  311.         $page->setKeyword($post->getMetaKeyword());
  312.         $page->setMetaRobots($post->getMetaRobots());
  313.         $page->setMetaTags($post->getMetaTags());
  314.         $page->setEditType(\Eccube\Entity\Page::EDIT_TYPE_PREVIEW);
  315.         // ページレイアウト生成
  316.         // モバイル
  317.         if ($this->mobileDetector->isMobile() && ($type->getSpLayoutId() != null && $type->getSpLayoutId() != 0)) {
  318.             $layout $type->getSpLayout();
  319.         }
  320.         // PC
  321.         else if ($type->getPcLayoutId() != null && $type->getPcLayoutId() != 0) {
  322.             $layout $type->getPcLayout();
  323.         }
  324.         // デフォルト
  325.         else {
  326.             $layout $this->layoutRepo->find(Type::DEFAULT_LAYOUT_ID);
  327.         }
  328.         $response $this->render($template_file, [
  329.             'Layout' => $layout,
  330.             'Page' => $page,
  331.             'subtitle' => strip_tags($post->getTitle()),
  332.             'type' => $type,
  333.             'post' => $post
  334.         ]);
  335.         //
  336.         // サムネイルが更新されていたら画像パスを置換する
  337.         //
  338.         if ($post->getThumbnail()) {
  339.             $isThumbnailReplace false;
  340.             // 更新
  341.             if ($post_data_key) {
  342.                 $originPost $this->postRepo->get(["data_key" => $post_data_key]);
  343.                 if (($originPost->getThumbnail() && $originPost->getThumbnail() != $post->getThumbnail()) || !$originPost->getThumbnail()) {
  344.                     $isThumbnailReplace true;
  345.                 }
  346.             }
  347.             // 新規
  348.             else {
  349.                 $isThumbnailReplace true;
  350.             }
  351.             if ($isThumbnailReplace) {
  352.                 // $fromPath = $this->get('assets.packages')->getUrl($post->getThumbnail(),"save_image");
  353.                 // $toPath = $this->get('assets.packages')->getUrl($post->getThumbnail(),"temp_image");
  354.                 $fromPath $this->packages->getUrl($post->getThumbnail(),"save_image");
  355.                 $toPath $this->packages->getUrl($post->getThumbnail(),"temp_image");
  356.                 $response->setContent(str_replace($fromPath,$toPath,$response->getContent()));
  357.             }
  358.         }
  359.         return $response;
  360.     }
  361.     /**
  362.      * JS,CSS,画像などを出力します。
  363.      *
  364.      * @param Request $request
  365.      */
  366.     public function assets(Request $request$file)
  367.     {
  368.         $file Util::getTemplatePath($file,array(),$this->containerForParam,true);
  369.         if (file_exists($file)) {
  370.             log_debug("[ASSETS] [FILE] " $file);
  371.             // 拡張子によりMIMEを設定します。
  372.             $suffixes explode(".",$file);
  373.             $suffix end($suffixes);
  374.             $suffix_def = array(
  375.                 "jpeg" => "image/jpg",
  376.                 "jpg" => "image/jpg",
  377.                 "gif" => "image/gif",
  378.                 "png" => "image/png",
  379.                 "svg" => "image/svg+xml",
  380.                 "webp" => "image/webp",
  381.                 "js" => "application/x-javascript",
  382.                 "css" => "text/css",
  383.             );
  384.             if (in_array($suffix,array_keys($suffix_def))) {
  385.                 $response = new BinaryFileResponse($file);
  386.                 $response->headers->set('Content-Type',$suffix_def[$suffix]);
  387.                 // キャッシュするヘッダーを出力する設定をします
  388.                 if ($this->container->has(Constants::CONTAINER_KEY_NAME)) {
  389.                     $this->container->get(Constants::CONTAINER_KEY_NAME)->set(Constants::HTTP_CACHE_STATUS,true);
  390.                 }
  391.                 return $response;
  392.             } else {
  393.                 throw new NotFoundHttpException();
  394.             }
  395.         } else {
  396.             throw new NotFoundHttpException();
  397.         }
  398.     }
  399. }