<?php
/*
* Copyright (C) SPREAD WORKS Inc. All Rights Reserved.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Plugin\TabaCMS2\Controller;
use Plugin\TabaCMS2\Common\Constants;
use Plugin\TabaCMS2\Common\DataHolder;
use Plugin\TabaCMS2\Common\UserConfig;
use Plugin\TabaCMS2\Util\Util;
use Plugin\TabaCMS2\Repository\TypeRepository;
use Plugin\TabaCMS2\Repository\PostRepository;
use Plugin\TabaCMS2\Repository\CategoryRepository;
use Plugin\TabaCMS2\Entity\Type;
use Plugin\TabaCMS2\Entity\Post;
use Plugin\TabaCMS2\Form\Type\PostType;
use Eccube\Common\Constant;
use Eccube\Controller\AbstractController;
use Eccube\Repository\PageRepository;
use Eccube\Repository\LayoutRepository;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Asset\Packages;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Detection\MobileDetect;
/**
* @Route(Plugin\TabaCMS2\Common\Constants::FRONT_URI_PREFIX,name=Plugin\TabaCMS2\Common\Constants::FRONT_BIND_PREFIX)
*/
class FrontController extends AbstractController
{
/**
*
* @var TypeRepository
*/
private $typeRepo;
/**
*
* @var PostRepository
*/
private $postRepo;
/**
* @var CategoryRepository
*/
private $categoryRepo;
/**
* @var PageRepository
*/
private $pageRepo;
/**
* @var LayoutRepository
*/
private $layoutRepo;
/**
* @var MobileDetector
*/
private $mobileDetector;
/**
* @var Packages
*/
private $packages;
/**
* @var ContainerInterface
*/
private $containerForParam;
/**
* コンストラクタ
*
* @param TypeRepository $typeRepo
* @param PostRepository $postRepo
*/
public function __construct(
TypeRepository $typeRepo,
PostRepository $postRepo,
CategoryRepository $categoryRepo,
PageRepository $pageRepo,
LayoutRepository $layoutRepo,
MobileDetect $mobileDetector,
Packages $packages,
ContainerInterface $container
) {
$this->typeRepo = $typeRepo;
$this->postRepo = $postRepo;
$this->categoryRepo = $categoryRepo;
$this->pageRepo = $pageRepo;
$this->layoutRepo = $layoutRepo;
$this->mobileDetector = $mobileDetector;
$this->packages = $packages;
$this->containerForParam = $container;
}
/**
* index
*
* @param Request $request
* @return Response
*/
public function index(Request $request) {
}
/**
* リストページと詳細ページの振り分けをします。
*
* @param Request $request
* @param string $data_key
*/
public function prepare(Request $request, $data_key = null,$category_data_key = null,$tag_data_key = null)
{
// URI取得
$uri = $request->getPathInfo();
if ($front_uri_prefix = UserConfig::getInstance()->get("front_uri_prefix")) {
$uri = preg_replace("{^" . $front_uri_prefix . "}",'',$uri);
}
// 投稿タイプのデータキー
$type_data_key = null;
if (($path = explode("/",$uri)) && is_array($path) && count($path) > 1) {
$type_data_key = $path[1];
} else {
throw new NotFoundHttpException();
}
// 投稿タイプ
$type = $this->typeRepo->get($type_data_key);
if (!$type) {
throw new NotFoundHttpException();
}
//
// カテゴリー
//
if (!empty($category_data_key)) {
// カテゴリーののデータキーを保存
DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_CATEGORY_DK, $category_data_key);
// カテゴリーEntityを取得
$category = $this->categoryRepo->findOneBy(['type' => $type,'dataKey' => $category_data_key]);
if (!$category) {
throw new NotFoundHttpException();
}
$options['category'] = $category;
$dataKeys = [$type_data_key,$type_data_key . "_" . $category_data_key];
// テンプレートファイル
$template_file = Util::getTemplatePath('category.twig',$dataKeys,$this->containerForParam);
if (!$template_file) {
$template_file = Util::getTemplatePath('list.twig',$dataKeys,$this->containerForParam);
}
// ページタイトル
$options['subtitle'] = $type->getTypeName() . ' - ' . $category->getCategoryName();
return $this->postList($request,$type,$template_file,$options);
}
//
// リスト or アーカイブ
//
elseif (empty($data_key) || $data_key == 'archive') {
// アーカイブ
if (strrpos($uri,'/archive') === strlen($uri) - strlen('/archive')) {
$template_file = Util::getTemplatePath('archive.twig',[$type->getDataKey()],$this->containerForParam);
return $this->postList($request,$type,$template_file);
}
// リスト
else {
$template_file = Util::getTemplatePath('list.twig',[$type->getDataKey()],$this->containerForParam);
return $this->postList($request,$type,$template_file);
}
}
// 投稿
else {
return $this->postDetail($request, $data_key);
}
}
/**
* 投稿リストページ
*
* @param Request $request
*/
public function postList(Request $request,$type,$template_file,$options = [])
{
// listページを実行中であることを保存
DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_PAGE, Constants::PAGE_LIST);
if (!$type) {
throw new NotFoundHttpException();
}
// 投稿タイプのデータキーを保存
DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_TYPE_DK, $type->getDataKey());
// ページオブジェクト生成
$page = $this->pageRepo->newPage();
$page->setEditType(\Eccube\Entity\Page::EDIT_TYPE_PREVIEW);
// ページレイアウト生成
// モバイル
if ($this->mobileDetector->isMobile() && ($type->getSpLayoutId() != null && $type->getSpLayoutId() != 0)) {
$layout = $type->getSpLayout();
}
// PC
else if ($type->getPcLayoutId() != null && $type->getPcLayoutId() != 0) {
$layout = $type->getPcLayout();
}
// デフォルト
else {
$layout = $this->layoutRepo->find(Type::DEFAULT_LAYOUT_ID);
}
// ページタイトル
if (!isset($options['subtitle'])) {
$options['subtitle'] = $type->getTypeName();
if ($request->get("category_id") && ($category = $this->categoryRepo->find($request->get("category_id")))) {
$options['subtitle'] .= " - ";
$options['subtitle'] .= $category->getCategoryName();
}
}
return $this->render($template_file,array_merge([
'Layout' => $layout,
'Page' => $page,
'type' => $type,
],$options));
}
/**
* 投稿ページ
*
* @param Request $request
*/
public function postDetail(Request $request, $data_key)
{
// postページを実行中であることを保存
DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_PAGE, Constants::PAGE_POST);
// 投稿データ取得
$post = null;
if (! $data_key || ! ($post = $this->postRepo->get(array(
"data_key" => $data_key,
"is_public" => true
)))) {
throw new NotFoundHttpException();
}
// 投稿タイプのデータキー取得
$type = $post->getType();
$type_data_key = $type->getDataKey();
// 投稿タイプ、投稿のデータキーを保存
DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_TYPE_DK, $type_data_key);
DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_POST_DK, $data_key);
// テンプレートファイル
$template_file = Util::getTemplatePath('post.twig',[$type_data_key,$data_key,$type_data_key.'_'.$data_key],$this->containerForParam);
// ページオブジェクト生成
$page = $this->pageRepo->newPage();
$page->setAuthor($post->getMetaAuthor());
$page->setDescription($post->getMetaDescription());
$page->setKeyword($post->getMetaKeyword());
$page->setMetaRobots($post->getMetaRobots());
$page->setMetaTags($post->getMetaTags());
$page->setEditType(1);
// ページレイアウト生成
// モバイル
if ($this->mobileDetector->isMobile() && ($type->getSpLayoutId() != null && $type->getSpLayoutId() != 0)) {
$layout = $type->getSpLayout();
}
// PC
else if ($type->getPcLayoutId() != null && $type->getPcLayoutId() != 0) {
$layout = $type->getPcLayout();
}
// デフォルト
else {
$layout = $this->layoutRepo->find(Type::DEFAULT_LAYOUT_ID);
}
return $this->render($template_file, [
'Layout' => $layout,
'Page' => $page,
'subtitle' => strip_tags($post->getTitle()),
'type' => $post->getType()
]);
}
/**
* 投稿ページ / プレビュー
*
* @Route("/preview/{type_data_key}/{post_data_key}",name="_preview",methods={"POST"})
* @param Request $request
*/
public function postPreview(Request $request, $type_data_key,$post_data_key = null)
{
// postページを実行中であることを保存
DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_PAGE, Constants::PAGE_POST);
// 投稿タイプ取得
$type = null;
if (!$type_data_key || !($type = $this->typeRepo->get($type_data_key))) {
throw new NotFoundHttpException();
}
$post = new Post(true);
$post->setType($type);
// フォームの生成
$builder = $this->formFactory->createBuilder(PostType::class, $post);
$form = $builder->getForm();
$form->handleRequest($request);
// EC-CUBE 4.1 対応
// サニタイズでHTMLタグが全角に変換されるため入力値に戻す
$params = $request->request->all()[$form->getName()];
if ($form->get('body') != $params['body']) {
$post->setBody($params['body']);
}
// CSRFエラーの場合のみ例外エラーにする
if (!$form->isValid() && ($errors = $form->getErrors()) && count($errors) > 0) {
throw new AccessDeniedHttpException($errors[0]->getMessage());
}
// 投稿タイプ、投稿データを保存
DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_TYPE_DK, $type_data_key);
DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_POST_DK, $post->getDataKey());
DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_POST, $post);
DataHolder::getInstance()->setData(Constants::DATA_HOLDER_KEY_PREVIEW,true);
// テンプレートファイル
$template_file = Util::getTemplatePath('post.twig',[$type_data_key,$post->getDataKey()],$this->containerForParam);
// ページオブジェクト生成
$page = $this->pageRepo->newPage();
$page->setAuthor($post->getMetaAuthor());
$page->setDescription($post->getMetaDescription());
$page->setKeyword($post->getMetaKeyword());
$page->setMetaRobots($post->getMetaRobots());
$page->setMetaTags($post->getMetaTags());
$page->setEditType(\Eccube\Entity\Page::EDIT_TYPE_PREVIEW);
// ページレイアウト生成
// モバイル
if ($this->mobileDetector->isMobile() && ($type->getSpLayoutId() != null && $type->getSpLayoutId() != 0)) {
$layout = $type->getSpLayout();
}
// PC
else if ($type->getPcLayoutId() != null && $type->getPcLayoutId() != 0) {
$layout = $type->getPcLayout();
}
// デフォルト
else {
$layout = $this->layoutRepo->find(Type::DEFAULT_LAYOUT_ID);
}
$response = $this->render($template_file, [
'Layout' => $layout,
'Page' => $page,
'subtitle' => strip_tags($post->getTitle()),
'type' => $type,
'post' => $post
]);
//
// サムネイルが更新されていたら画像パスを置換する
//
if ($post->getThumbnail()) {
$isThumbnailReplace = false;
// 更新
if ($post_data_key) {
$originPost = $this->postRepo->get(["data_key" => $post_data_key]);
if (($originPost->getThumbnail() && $originPost->getThumbnail() != $post->getThumbnail()) || !$originPost->getThumbnail()) {
$isThumbnailReplace = true;
}
}
// 新規
else {
$isThumbnailReplace = true;
}
if ($isThumbnailReplace) {
// $fromPath = $this->get('assets.packages')->getUrl($post->getThumbnail(),"save_image");
// $toPath = $this->get('assets.packages')->getUrl($post->getThumbnail(),"temp_image");
$fromPath = $this->packages->getUrl($post->getThumbnail(),"save_image");
$toPath = $this->packages->getUrl($post->getThumbnail(),"temp_image");
$response->setContent(str_replace($fromPath,$toPath,$response->getContent()));
}
}
return $response;
}
/**
* JS,CSS,画像などを出力します。
*
* @param Request $request
*/
public function assets(Request $request, $file)
{
$file = Util::getTemplatePath($file,array(),$this->containerForParam,true);
if (file_exists($file)) {
log_debug("[ASSETS] [FILE] " . $file);
// 拡張子によりMIMEを設定します。
$suffixes = explode(".",$file);
$suffix = end($suffixes);
$suffix_def = array(
"jpeg" => "image/jpg",
"jpg" => "image/jpg",
"gif" => "image/gif",
"png" => "image/png",
"svg" => "image/svg+xml",
"webp" => "image/webp",
"js" => "application/x-javascript",
"css" => "text/css",
);
if (in_array($suffix,array_keys($suffix_def))) {
$response = new BinaryFileResponse($file);
$response->headers->set('Content-Type',$suffix_def[$suffix]);
// キャッシュするヘッダーを出力する設定をします
if ($this->container->has(Constants::CONTAINER_KEY_NAME)) {
$this->container->get(Constants::CONTAINER_KEY_NAME)->set(Constants::HTTP_CACHE_STATUS,true);
}
return $response;
} else {
throw new NotFoundHttpException();
}
} else {
throw new NotFoundHttpException();
}
}
}