<?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\Twig\Extension;
use Plugin\TabaCMS2\Common\Constants;
use Plugin\TabaCMS2\Common\DataHolder;
use Plugin\TabaCMS2\Util\Util;
use Plugin\TabaCMS2\Repository\TypeRepository;
use Plugin\TabaCMS2\Repository\PostRepository;
use Plugin\TabaCMS2\Repository\CategoryRepository;
use Plugin\TabaCMS2\Repository\TagRepository;
use Plugin\TabaCMS2\Form\Type\FrontPostSearchType;
use Eccube\Request\Context;
use Eccube\Common\EccubeConfig;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Asset\Packages;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Form\FormFactoryInterface;
use Knp\Component\Pager\Paginator;
use Knp\Component\Pager\PaginatorInterface;
use Twig\Extension\AbstractExtension;
use Twig\Environment;
use Twig\TwigFunction;
class TwigExtension extends AbstractExtension
{
/**
* @var ContainerInterface
*/
private $container;
/**
* @var RequestStack
*/
private $requestStack;
/**
* @var Paginator
*/
private $paginator;
/**
* @var array
*/
private $cached;
/**
* @var Context
*/
private $requestContext;
/**
* @var TypeRepository
*/
private $typeRepo;
/**
* @var PostRepository
*/
private $postRepo;
/**
* @var CategoryRepository
*/
private $categoryRepo;
/**
* @var TagRepository
*/
private $tagRepo;
/**
* @var Packages
*/
private $assetPackage;
/**
* @var Environment
*/
private $twig;
/**
* @var CsrfTokenManagerInterface
*/
private $csrfTokenManager;
/**
* @var EccubeConfig
*/
private $eccubeConfig;
/**
* @var RouterInterface
*/
private $router;
/**
* @var FormFactoryInterface
*/
private $formFactory;
/**
* コンストラクタ
*
* @param ContainerInterface $container
* @param Environment $twig
* @param RequestStack $requestStack
* @param PaginatorInterface $paginator
* @param Context $requestContext
* @param TypeRepository $typeRepo
* @param PostRepository $postRepo
* @param CategoryRepository $categoryRepo
* @param Packages $assetPackages
* @param CsrfTokenManagerInterface $csrfTokenManager
* @param EccubeConfig $eccubeConfig
* @param RouterInterface $router
*/
public function __construct(
ContainerInterface $container,
Environment $twig,
RequestStack $requestStack,
PaginatorInterface $paginator,
Context $requestContext,
TypeRepository $typeRepo,
PostRepository $postRepo,
CategoryRepository $categoryRepo,
TagRepository $tagRepo,
Packages $assetPackages,
CsrfTokenManagerInterface $csrfTokenManager,
EccubeConfig $eccubeConfig,
// UrlGeneratorInterface $router
RouterInterface $router,
FormFactoryInterface $formFactory
) {
$this->container = $container;
$this->twig = $twig;
$this->requestStack = $requestStack;
$this->paginator = $paginator;
$this->requestContext = $requestContext;
$this->typeRepo = $typeRepo;
$this->postRepo = $postRepo;
$this->categoryRepo = $categoryRepo;
$this->tagRepo = $tagRepo;
$this->assetPackage = $assetPackages;
$this->csrfTokenManager = $csrfTokenManager;
$this->eccubeConfig = $eccubeConfig;
$this->router = $router;
$this->formFactory = $formFactory;
// $this->twig->addGlobal(Constants::PLUGIN_CODE.'Constants', new Constants());
$this->twig->addGlobal(Constants::PLUGIN_CATEGORY_NAME.'Status', new Constants());
}
/**
* Returns a list of functions to add to the existing list.
*
* @return array An array of functions
*/
public function getFunctions()
{
return array(
new TwigFunction(Constants::PLUGIN_NAME . 'Type', array($this, 'type')),
new TwigFunction(Constants::PLUGIN_NAME . 'Post', array($this, 'post')),
new TwigFunction(Constants::PLUGIN_NAME . 'PostList', array($this, 'postList')),
new TwigFunction(Constants::PLUGIN_NAME . 'Category', array($this, 'category')),
new TwigFunction(Constants::PLUGIN_NAME . 'CategoryList', array($this, 'categoryList')),
new TwigFunction(Constants::PLUGIN_NAME . 'Asset', array($this, 'asset')),
new TwigFunction(Constants::PLUGIN_NAME . 'IsAssetLoad', array($this, 'isAssetLoad')),
new TwigFunction(Constants::PLUGIN_NAME . 'Widget', array($this, 'widget')),
);
}
/**
* Name of this extension
*
* @return string
*/
public function getName()
{
return Constants::PLUGIN_CODE_LC;
}
/**
* ウィジェットを出力します。
*
* @param unknown $widget_name
* @param array $options
* @return void|string
*/
public function widget($widget_name,$options = array()) {
$data_holder = DataHolder::getInstance();
// オプション
$options = array_merge(array(
'type_data_key' => $data_holder->getData(Constants::DATA_HOLDER_KEY_TYPE_DK),
),$options);
//
// カテゴリーリスト
//
if ($widget_name == "category") {
// 投稿タイプの取得
$type = null;
if (!$options['type_data_key'] || !($type = $this->typeRepo->get($options['type_data_key']))) {
return;
}
// カテゴリーリストの取得
$conditions = array();
$conditions['is_public'] = true;
if (!empty($type)) $conditions['type_id'] = $type->getTypeId();
$category_list = $this->categoryRepo->getList($conditions);
$file_name = 'widget_' . $widget_name . '.twig';
return $this->twig->render(Util::getTemplatePath($file_name,[$options['type_data_key']],$this->container),array(
'type' => $type,
'options' => $options,
'category_list' => $category_list,
));
}
//
// タグリスト
//
if ($widget_name == "tag") {
// 投稿タイプの取得
$type = null;
if (!$options['type_data_key'] || !($type = $this->typeRepo->get($options['type_data_key']))) {
return;
}
// タグリストの取得
$conditions = array();
$conditions['is_public'] = true;
if (!empty($type)) $conditions['type_id'] = $type->getTypeId();
$tag_list = $this->tagRepo->getList($conditions);
$file_name = 'widget_' . $widget_name . '.twig';
return $this->twig->render(Util::getTemplatePath($file_name,[$options['type_data_key']],$this->container),array(
'type' => $type,
'options' => $options,
'tag_list' => $tag_list,
));
}
//
// 検索フォーム
//
else if ($widget_name == "search") {
// 投稿タイプの取得
$type = null;
if (!$options['type_data_key'] || !($type = $this->typeRepo->get($options['type_data_key']))) {
return;
}
// フォームの生成
$builder = $this->formFactory->createBuilder(FrontPostSearchType::class,['type_id' => $type->getTypeId()]);
$post_search_form = $builder->getForm();
$post_search_form->handleRequest($this->requestStack->getCurrentRequest());
$file_name = 'widget_' . $widget_name . '.twig';
return $this->twig->render(Util::getTemplatePath($file_name,[$options['type_data_key']],$this->container),array(
'type' => $type,
'options' => $options,
'post_search_form' => $post_search_form->createView(),
));
}
//
// 投稿リスト , 投稿
//
else if ($widget_name == "list") {
// 投稿タイプの取得
$type = null;
if (!$options['type_data_key'] || !($type = $this->typeRepo->get($options['type_data_key']))) {
return;
}
$file_name = 'widget_' . $widget_name . '.twig';
return $this->twig->render(Util::getTemplatePath($file_name,[$options['type_data_key']],$this->container),array(
'type' => $type,
'options' => $options,
));
}
}
public function isAssetLoad($key) {
$data_holder = DataHolder::getInstance();
if ($data_holder->getData("IS_LOADED_" . $key)) {
return true;
} else {
$data_holder->setData("IS_LOADED_" . $key,true);
return false;
}
}
/**
*
* @param string $file_name
* @param string $asset_type script|style|img
* @param boolean $once
* @param array $attributes tag attribute
* @return string|NULL
*/
public function asset($file_name,$asset_type = null,$once = true,$attributes = []) {
if (!$once || ($once && !$this->isAssetLoad($file_name))) {
$uri = $this->router->generate(Constants::FRONT_BIND_PREFIX . '_assets',['file' => $file_name]);
if ($asset_type == "script") {
return '<script src="' . $uri . '"></script>';
} else if ($asset_type == "style") {
return '<link rel="stylesheet" href="' . $uri . '">';
} else if ($asset_type == "img") {
return '<img src="' . $uri . '">';
} else {
return $uri;
}
} else {
return null;
}
}
/**
* カテゴリーを取得します。
*
* @param array $options
* @return Post
*/
public function category($options = array()) {
$data_holder = DataHolder::getInstance();
// オプション
$options = array_merge(array(
'type_data_key' => $data_holder->getData(Constants::DATA_HOLDER_KEY_TYPE_DK),
'data_key' => $data_holder->getData(Constants::DATA_HOLDER_KEY_CATEGORY_DK),
),$options);
// 投稿タイプの取得
$type = null;
if (!$options['type_data_key'] || !($type = $this->typeRepo->get($options['type_data_key']))) {
return;
}
// カテゴリーデータ
$category = $this->categoryRepo->get([
'type_id' => $type->getTypeId(),
'data_key' => $options['data_key']
]);
return $category;
}
/**
* カテゴリーリストを取得します。
*
* @param array $options
* @return Post
*/
public function categoryList($options = array()) {
$data_holder = DataHolder::getInstance();
$options = array_merge(array(
'type_data_key' => $data_holder->getData(Constants::DATA_HOLDER_KEY_TYPE_DK),
'data_key' => $data_holder->getData(Constants::DATA_HOLDER_KEY_CATEGORY_DK),
),$options);
// 投稿タイプの取得
$type = null;
if (!$options['type_data_key'] || !($type = $this->typeRepo->get($options['type_data_key']))) {
return;
}
// カテゴリーリストの取得
$conditions = array();
$conditions['is_public'] = true;
if (!empty($type)) $conditions['type_id'] = $type->getTypeId();
$category_list = $this->categoryRepo->getList($conditions);
return $category_list;
}
/**
* 投稿タイプを取得します。
*
* @param array $options
* @return Post
*/
public function type($options = array()) {
$data_holder = DataHolder::getInstance();
// オプション
if ($data_holder) {
$options = array_merge(array(
'type_data_key' => $data_holder->getData(Constants::DATA_HOLDER_KEY_TYPE_DK),
),$options);
}
// 投稿タイプ
$type = $this->typeRepo->get($options['type_data_key']);
if ($type && $type->getPublicDiv()) {
return $type;
}
return null;
}
/**
* 投稿データを取得します。
*
* @param array $options
* @return Post
*/
public function post($options = array()) {
$data_holder = DataHolder::getInstance();
// プレビュー
if ($data_holder->getData(Constants::DATA_HOLDER_KEY_PREVIEW)) {
$post = $data_holder->getData(Constants::DATA_HOLDER_KEY_POST);
}
// 通常
else {
// オプション
$options = array_merge(array(
'type_data_key' => $data_holder->getData(Constants::DATA_HOLDER_KEY_TYPE_DK),
'data_key' => $data_holder->getData(Constants::DATA_HOLDER_KEY_POST_DK),
),$options);
// 投稿データ
$post = $this->postRepo->get([
"data_key" => $options['data_key'],
"is_public" => true
]);
}
return $post;
}
/**
* 投稿リストを取得します。
*
* @param array $options
* @return void|\Knp\Component\Pager\Pagination\PaginationInterface
*/
public function postList($options = array()) {
$data_holder = DataHolder::getInstance();
if (!$options || !isset($options['overwrite_query']) || $options['overwrite_query'] !== false) {
$params = $this->requestStack->getCurrentRequest()->query->all();
$options = array_merge($params,$options);
}
$options = array_merge(array(
'type_data_key' => $data_holder->getData(Constants::DATA_HOLDER_KEY_TYPE_DK),
'page_count' => Constants::DEFAULT_PAGE_COUNT,
'pageno' => 1,
),$options);
// 投稿タイプの取得
$type = null;
if (!$options['type_data_key'] || !($type = $this->typeRepo->get($options['type_data_key']))) {
return;
}
//
// 抽出条件
//
$where = array(
"type_id" => $type->getTypeId(),
"is_public" => true,
);
// カテゴリー
if (isset($options["category_data_key"]) && !empty($options["category_data_key"])) {
$category = $this->categoryRepo->findOneBy(['type' => $type,'dataKey' => $options["category_data_key"]]);
if ($category) {
$where['category_id'] = $category->getCategoryId();
} else {
$where['category_id'] = -1;
}
} else if (isset($options["category_id"]) && !empty($options["category_id"])) {
$where['category_id'] = $options["category_id"];
}
// タグ
if (isset($options["tag_data_key"]) && !empty($options["tag_data_key"])) {
if (is_array($options["tag_data_key"])) {
$tags = $this->tagRepo->findBy(['type' => $type,'dataKey' => $options["tag_data_key"]]);
foreach ($tags as $tag) {
$where['tag_id'][] = $tag->getTagId();
}
} else {
$tag = $this->tagRepo->findOneBy(['type' => $type,'dataKey' => $options["tag_data_key"]]);
if ($tag) $where['tag_id'] = $tag->getTagId();
}
} else if (isset($options["tag_id"]) && !empty($options["tag_id"])) {
$where['tag_id'] = $options["tag_id"];
}
// キーワード
if (isset($options["keyword"])) {
$where['keyword'] = $options["keyword"];
}
// 投稿リストの取得
$qb_post_list = $this->postRepo->createListQueryBuilder($where);
// ページネーション
$post_list = $this->paginator->paginate(
$qb_post_list,
$options['pageno'],
$options['page_count'],
array('wrap-queries' => true)
);
return $post_list;
}
}