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

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