<?php
namespace AppBundle\Controller;
use AppBundle\Component\PageBuilder\PageBuilder;
use AppBundle\Component\Util\ParameterCollection;
use AppBundle\Event\PageBuilderFormLoadedEvent;
use AppBundle\Event\PageBuilderInitializedEvent;
use Doctrine\ORM\Query\FilterCollection;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
class BaseController extends Controller
{
/** @var EventDispatcher */
protected $dispatcher;
/** @var ParameterCollection */
protected $view_params;
public function before(FilterControllerEvent $event)
{
$request = $event->getRequest();
$this->dispatcher = $this->get('event_dispatcher');
$em = $this->getDoctrine()->getManager();
$em->getFilters()->enable('public');
$lang = $request->attributes->get('_locale', null);
if ($lang) {
$em = $this->getDoctrine()->getManager();
$filter = $em->getFilters()->enable('language');
$filter->setParameter('language', $lang);
$this->view_params->set('cms__lang', $lang);
} else {
$this->view_params->set('cms__lang', null);
}
$mediaManager = $this->container->get('app.media_manager');
$mediaManager->setBaseUrl($request->getSchemeAndHttpHost() . $request->getBasePath());
}
public function __construct()
{
$this->view_params = new ParameterCollection();
}
protected function render($view, array $parameters = array(), Response $response = null)
{
$parameters = array_merge($this->view_params->all(), $parameters);
return parent::render($view, $parameters, $response);
}
// ルート直下の php テンプレートを表示する
public function renderFront($template, $data=array())
{
$rootDir = $this->get('kernel')->getRootDir();
$file = realpath($rootDir . '/../../../') . '/' . ltrim($template, '/');
if (CMS__IS_FRONT_ROUTING){
return array_merge($this->view_params->all(), $data);
} else {
return $this->render($file, $data);
}
}
/**
* 項目を取得する
*
* @param Request $request
* @param string $class
* @param array $criteria
* @return mixed
*/
protected function findItemBy(Request $request, $class, $criteria=[])
{
$repository = $this->getDoctrine()->getRepository($class);
$em = $this->getDoctrine()->getManager();
$mode = '';
$queryToken = '';
$previewTarget = $request->query->get('preview_target');
if(defined($class . '::NAME')) {
$entityName = constant($class . '::NAME');
} else {
$entityName = null;
}
if(!empty($previewTarget) && $previewTarget !== $entityName){
$mode = 'default';
} elseif (!is_null($request)) {
$mode = $request->query->get('cms_mode', 'default');
$queryToken = $request->query->get('cms_token');
}
if(!empty($queryToken)){
$criteria['access_token'] = $queryToken;
}
// 無関係のプレビューは無視
if($entityName !== $request->query->get('preview_target')){
$mode = 'default';
}
if ('preview' === $mode) {
// 非公開制限を無視して取得
/** @var FilterCollection $filters */
$filters = $em->getFilters();
$filters->disable('public');
$filters->disable('post_type');
$languageFilter = ($filters->isEnabled('language')) ? $filters->getFilter('language') : null;
if($languageFilter) {
$languageFilterState = $languageFilter->isActive();
$languageFilter->deactivate();
} else {
$languageFilterState = false;
}
$item = $repository->findOneBy($criteria, ['id' => 'DESC']);
$filters->enable('public');
$filters->enable('post_type');
if ($languageFilter && $languageFilterState) {
$languageFilter->activate();
}
if(empty($item->getAccessToken()) || $queryToken !== $item->getAccessToken()) {
throw new AccessDeniedHttpException('Access token does not match.');
}
} elseif ('tmp_preview' === $mode) {
// 編集画面から一時的プレビュー画面
$id = $request->query->get('preview_id');
$item = $this->getPreviewBy(['id' => $id], $class);
if (empty($item->getAccessToken()) || $queryToken !== $item->getAccessToken()) {
throw new AccessDeniedHttpException('Access token does not match.');
}
} else {
$item = $repository->findOneBy($criteria);
}
return $item;
}
public function paginate($query, $page = 1, $limit = 5)
{
$paginator = $this->container->get('knp_paginator');
$pagination = $paginator->paginate(
$query, $page, $limit
);
return $pagination;
}
/**
* @param string $form
* @param null $entity
* @param array $options
* @return PageBuilder
*/
protected function createPageBuilder($form, $entity = null, $options=[])
{
$builder = new PageBuilder($this->container);
$language = isset($options['language']) ? $options['language'] : null;
$this->dispatcher->dispatch(PageBuilderInitializedEvent::NAME, new PageBuilderInitializedEvent($builder, ['language' => $language]));
$builder->loadForm($form, $options);
$this->dispatcher->dispatch(PageBuilderFormLoadedEvent::NAME, new PageBuilderFormLoadedEvent($builder, ['language' => $language]));
if($entity){
$builder->readEntityData($entity);
}
$builder->setThemeDirectory('CustomBundle:Default:page-builder/themes');
return $builder;
}
protected function getDefaultParameter($name)
{
$container = $this->container;
if ($container->hasParameter($name)) {
return $container->getParameter($name);
}
return [];
}
protected function getPaginationParams($paginator, $options = [])
{
$data = $paginator->getPaginationData();
$total = $data['totalCount'];
$page = $data['current'];
$limit = $data['numItemsPerPage'];
$offset = ($page - 1) * $limit;
$pages = $data['pageCount'];
$start = $data['firstPageInRange'];
$end = $data['lastPageInRange'];
$from = $data['firstItemNumber'];
$to = $data['lastItemNumber'];
$params = [
'total' => $total,
'per_page' => $limit,
'current_page' => $page,
'last_page' => $pages,
'page_start' => $start,
'page_end' => $end,
'from' => $from,
'to' => $to,
];
return $params;
}
}