Commit 59b01c20 authored by Tino Goratsch's avatar Tino Goratsch

Merge branch 'release/v4.1.0'

parents 9c2a4838 e50d15fa
......@@ -20,3 +20,9 @@
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
.codeclimate.yml export.ignore
.coveralls.yml export.ignore
.eslintignore.yml export.ignore
.eslintrc export.ignore
.travis.yml export.ignore
......@@ -14,7 +14,7 @@ interface BootstrapInterface extends HttpKernelInterface
/**
* Contains the current ACP3 version string
*/
const VERSION = '4.0.4';
const VERSION = '4.1.0';
/**
* Performs some startup checks
......
......@@ -39,6 +39,8 @@ abstract class AbstractAdminAction extends Core\Controller\AbstractFrontendActio
throw new Core\Authentication\Exception\UnauthorizedAccessException();
}
return parent::preDispatch();
parent::preDispatch();
return $this;
}
}
......@@ -82,13 +82,18 @@ abstract class AbstractFrontendAction extends Core\Controller\AbstractWidgetActi
'LANG' => $this->translator->getShortIsoCode(),
]);
return parent::preDispatch();
parent::preDispatch();
return $this;
}
/**
* @inheritdoc
*/
protected function addCustomTemplateVarsBeforeOutput()
{
$this->view->assign('BREADCRUMB', $this->breadcrumb->getBreadcrumb());
$this->view->assign('LAYOUT', $this->request->isXmlHttpRequest() ? 'system/ajax.tpl' : $this->getLayout());
$this->view->assign('LAYOUT', $this->fetchLayoutViaInheritance());
$this->eventDispatcher->dispatch(
'core.controller.custom_template_variable',
......@@ -96,6 +101,55 @@ abstract class AbstractFrontendAction extends Core\Controller\AbstractWidgetActi
);
}
/**
* @return string
*/
protected function fetchLayoutViaInheritance()
{
if ($this->request->isXmlHttpRequest()) {
$paths = $this->fetchLayoutPaths('layout.ajax', 'System/layout.ajax.tpl');
} else {
$paths = $this->fetchLayoutPaths('layout', 'layout.tpl');
}
$this->iterateOverLayoutPaths($paths);
return $this->getLayout();
}
/**
* @param string $layoutFileName
* @param string $defaultLayoutName
* @return array
*/
private function fetchLayoutPaths($layoutFileName, $defaultLayoutName)
{
return [
$this->request->getModule() . '/' . $this->request->getArea() . '/' . $layoutFileName . '.' . $this->request->getController() . '.' . $this->request->getAction() . '.tpl',
$this->request->getModule() . '/' . $this->request->getArea() . '/' . $layoutFileName . '.' . $this->request->getController() . '.tpl',
$this->request->getModule() . '/' . $this->request->getArea() . '/' . $layoutFileName . '.tpl',
$this->request->getModule() . '/' . $layoutFileName . '.tpl',
$defaultLayoutName
];
}
/**
* @param $paths
*/
private function iterateOverLayoutPaths($paths)
{
if ($this->getLayout() !== 'layout.tpl') {
return;
}
foreach ($paths as $path) {
if ($this->view->templateExists($path)) {
$this->setLayout($path);
break;
}
}
}
/**
* @return string
*/
......
......@@ -116,6 +116,9 @@ abstract class AbstractWidgetAction implements ActionInterface
return $this->request->getModule() . '/' . ucfirst($this->request->getArea()) . '/' . $this->request->getController() . '.' . $this->request->getAction() . '.tpl';
}
/**
* @inheritdoc
*/
protected function addCustomTemplateVarsBeforeOutput()
{
}
......
......@@ -43,18 +43,19 @@ trait DisplayActionTrait
}
if (empty($this->getContent()) && $this->getContent() !== false) {
// Set the template automatically
if ($this->getTemplate() === '') {
$this->setTemplate($this->applyTemplateAutomatically());
}
$this->addCustomTemplateVarsBeforeOutput();
$this->getResponse()->setContent($this->getView()->fetchTemplate($this->getTemplate()));
$content = $this->getView()->fetchTemplate($this->getTemplate());
} else {
$this->getResponse()->setContent($this->getContent() === false ? '' : $this->getContent());
$content = $this->getContent() === false ? '' : $this->getContent();
}
$this->getResponse()->setContent($content);
return $this->getResponse();
}
......
<?php
namespace ACP3\Core\Helpers;
use ACP3\Core\Http\Request;
use ACP3\Core\Http\RequestInterface;
use ACP3\Core\I18n\Translator;
use ACP3\Core\Validation\ValidationRules\DateValidationRule;
......@@ -84,7 +83,7 @@ class Date
foreach ($values as $row) {
unset($timeZones[$key][$i]);
$timeZones[$key][$row]['selected'] = $this->formsHelper->selectEntry(
'date_time_zone',
'date_time_zone',
$row,
$currentValue
);
......
......@@ -4,10 +4,6 @@ namespace ACP3\Core;
use ACP3\Core\View\Renderer\RendererInterface;
/**
* Klasse für die Ausgabe der Seite
* @package ACP3\Core
*/
class View
{
/**
......@@ -41,28 +37,22 @@ class View
* Fetches a template and outputs its contents
*
* @param string $template
* @param mixed $cacheId
* @param mixed $compileId
* @param object|null $parent
*/
public function displayTemplate($template, $cacheId = null, $compileId = null, $parent = null)
public function displayTemplate($template)
{
$this->renderer->display('asset:' . $template, $cacheId, $compileId, $parent);
$this->renderer->display('asset:' . $template);
}
/**
* Fetches a template and returns its contents
*
* @param string $template
* @param mixed $cacheId
* @param mixed $compileId
* @param object|null $parent
*
* @return string
*/
public function fetchTemplate($template, $cacheId = null, $compileId = null, $parent = null)
public function fetchTemplate($template)
{
return $this->renderer->fetch('asset:' . $template, $cacheId, $compileId, $parent);
return $this->renderer->fetch('asset:' . $template);
}
/**
......@@ -88,7 +78,7 @@ class View
*/
public function templateExists($template)
{
return $this->renderer->templateExists($template);
return $this->renderer->templateExists('asset:' . $template);
}
/**
......@@ -97,10 +87,12 @@ class View
* @param string|array $name
* @param mixed $value
*
* @return boolean
* @return $this
*/
public function assign($name, $value = null)
{
return $this->renderer->assign($name, $value);
$this->renderer->assign($name, $value);
return $this;
}
}
......@@ -2,10 +2,6 @@
namespace ACP3\Core\View\Renderer;
/**
* Interface RendererInterface
* @package ACP3\Core\View
*/
interface RendererInterface
{
/**
......@@ -18,6 +14,8 @@ interface RendererInterface
/**
* @param string|array $name
* @param null $value
*
* @return $this
*/
public function assign($name, $value = null);
......
......@@ -10,8 +10,12 @@ use ACP3\Core\Environment\ApplicationPath;
*
* @package ACP3\Core\View\Renderer
*/
class Smarty extends \Smarty implements RendererInterface
class Smarty implements RendererInterface
{
/**
* @var \Smarty
*/
protected $smarty;
/**
* @var \ACP3\Core\Environment\ApplicationPath
*/
......@@ -24,13 +28,16 @@ class Smarty extends \Smarty implements RendererInterface
/**
* Smarty constructor.
*
* @param \Smarty $smarty
* @param \ACP3\Core\Environment\ApplicationPath $appPath
* @param string $environment
* @param string $environment
*/
public function __construct(ApplicationPath $appPath, $environment)
public function __construct(
\Smarty $smarty,
ApplicationPath $appPath,
$environment)
{
parent::__construct();
$this->smarty = $smarty;
$this->appPath = $appPath;
$this->environment = $environment;
}
......@@ -42,11 +49,11 @@ class Smarty extends \Smarty implements RendererInterface
*/
public function configure(array $params = [])
{
$this->setErrorReporting($this->isDevOrInstall() ? E_ALL : 0);
$this->setCompileId(!empty($params['compile_id']) ? $params['compile_id'] : $this->environment);
$this->setCompileCheck($this->isDevOrInstall());
$this->setCompileDir($this->appPath->getCacheDir() . 'tpl_compiled/');
$this->setCacheDir($this->appPath->getCacheDir() . 'tpl_cached/');
$this->smarty->setErrorReporting($this->isDevOrInstall() ? E_ALL : 0);
$this->smarty->setCompileId(!empty($params['compile_id']) ? $params['compile_id'] : $this->environment);
$this->smarty->setCompileCheck($this->isDevOrInstall());
$this->smarty->setCompileDir($this->appPath->getCacheDir() . 'tpl_compiled/');
$this->smarty->setCacheDir($this->appPath->getCacheDir() . 'tpl_cached/');
}
/**
......@@ -63,6 +70,40 @@ class Smarty extends \Smarty implements RendererInterface
*/
public function registerSmartyPlugin(Smarty\PluginInterface $plugin)
{
$plugin->register($this);
$plugin->register($this->smarty);
}
/**
* @inheritdoc
*/
public function assign($name, $value = null)
{
$this->smarty->assign($name, $value);
return $this;
}
/**
* @inheritdoc
*/
public function fetch($template, $cacheId = null, $compileId = null, $parent = null)
{
return $this->smarty->fetch($template, $cacheId, $compileId, $parent);
}
/**
* @inheritdoc
*/
public function display($template, $cacheId = null, $compileId = null, $parent = null)
{
return $this->smarty->display($template, $cacheId, $compileId, $parent);
}
/**
* @inheritdoc
*/
public function templateExists($template)
{
return $this->smarty->templateExists($template);
}
}
......@@ -33,6 +33,8 @@ class Datepicker extends AbstractFunction
public function process(array $params, \Smarty_Internal_Template $smarty)
{
$params = $this->mergeParameters($params);
$smarty->smarty->assign('label', $params['label']);
$smarty->smarty->assign('datepicker', $this->dateHelper->datepicker(
$params['name'],
$params['value'],
......@@ -49,7 +51,8 @@ class Datepicker extends AbstractFunction
'name' => '',
'value' => '',
'withTime' => true,
'inputFieldOnly' => false
'inputFieldOnly' => false,
'label' => ''
];
return array_merge($defaults, $params);
}
......
......@@ -42,13 +42,20 @@ class Event extends AbstractFunction
* @param array $params
* @param \Smarty_Internal_Template $smarty
*
* @return mixed
* @return string
*/
public function process(array $params, \Smarty_Internal_Template $smarty)
{
if (isset($params['name'])) {
ob_start();
$this->eventDispatcher->dispatch($params['name'], new TemplateEvent($this->parseArguments($params)));
$result = ob_get_contents();
ob_end_clean();
return $result;
}
return '';
}
/**
......
......@@ -47,7 +47,8 @@ class SmartyRendererFactory
*/
public function create()
{
$renderer = new Smarty($this->appPath, $this->environment);
$smarty = new \Smarty();
$renderer = new Smarty($smarty, $this->appPath, $this->environment);
$renderer->configure(['compile_id' => $this->config->getSettings(Schema::MODULE_NAME)['design']]);
return $renderer;
}
......
......@@ -17,12 +17,12 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "*",
"acp3/core": "4.0.4",
"acp3/setup": "4.0.4",
"acp3/module-errors": "4.0.4",
"acp3/module-permissions": "4.0.4",
"acp3/module-system": "4.0.4",
"acp3/module-users": "4.0.4"
"acp3/core": "4.1.0",
"acp3/setup": "4.1.0",
"acp3/module-errors": "4.1.0",
"acp3/module-permissions": "4.1.0",
"acp3/module-system": "4.1.0",
"acp3/module-users": "4.1.0"
},
"autoload": {
"psr-4": {
......
{extends file="asset:`$LAYOUT`"}
{extends file="asset:System/layout.ajax-form.tpl"}
{block CONTENT}
{if isset($error_msg)}
{$error_msg}
{/if}
<form action="{$REQUEST_URI}" method="post" accept-charset="UTF-8" class="form-horizontal" data-ajax-form="true" data-ajax-form-loading-text="{lang t="system|loading_please_wait"}">
<div class="tabbable">
<ul class="nav nav-tabs">
<li class="active"><a href="#tab-1" data-toggle="tab">{lang t="system|publication_period"}</a></li>
<li><a href="#tab-2" data-toggle="tab">{lang t="articles|page_statements"}</a></li>
<li><a href="#tab-3" data-toggle="tab">{lang t="seo|seo"}</a></li>
</ul>
<div class="tab-content">
<div id="tab-1" class="tab-pane fade in active">
{datepicker name=['start', 'end'] value=[$form.start, $form.end]}
</div>
<div id="tab-2" class="tab-pane fade">
<div class="form-group">
<label for="title" class="col-sm-2 control-label required">{lang t="articles|title"}</label>
<div class="col-sm-10">
<input class="form-control"
type="text"
name="title"
id="title"
value="{$form.title}"
maxlength="120"
data-seo-slug-base="true"
required>
</div>
</div>
<div class="form-group">
<label for="text" class="col-sm-2 control-label required">{lang t="articles|text"}</label>
<div class="col-sm-10">{wysiwyg name="text" value="`$form.text`" height="250" advanced="1"}</div>
</div>
{if !empty($options)}
{include file="asset:System/Partials/form_group.checkbox.tpl" label={lang t="system|options"}}
{include file="asset:Menus/Partials/create_menu_item.tpl"}
{/if}
</div>
<div id="tab-3" class="tab-pane fade">
{include file="asset:Seo/Partials/seo_fields.tpl" seo=$SEO_FORM_FIELDS}
</div>
{block CONTENT_AJAX_FORM}
<div class="tabbable">
<ul class="nav nav-tabs">
<li class="active"><a href="#tab-1" data-toggle="tab">{lang t="system|publication_period"}</a></li>
<li><a href="#tab-2" data-toggle="tab">{lang t="articles|page_statements"}</a></li>
<li><a href="#tab-3" data-toggle="tab">{lang t="seo|seo"}</a></li>
</ul>
<div class="tab-content">
<div id="tab-1" class="tab-pane fade in active">
{datepicker name=['start', 'end'] value=[$form.start, $form.end]}
</div>
<div id="tab-2" class="tab-pane fade">
{include file="asset:System/Partials/form_group.input_text.tpl" name="title" value=$form.title required=true maxlength=120 data_attributes=['seo-slug-base' => 'true'] label={lang t="articles|title"}}
{include file="asset:System/Partials/form_group.wysiwyg.tpl" name="text" value=$form.text required=true advanced=true label={lang t="articles|text"}}
{if !empty($options)}
{include file="asset:System/Partials/form_group.checkbox.tpl" label={lang t="system|options"}}
{include file="asset:Menus/Partials/create_menu_item.tpl"}
{/if}
</div>
<div id="tab-3" class="tab-pane fade">
{include file="asset:Seo/Partials/seo_fields.tpl" seo=$SEO_FORM_FIELDS}
</div>
</div>
{include file="asset:System/Partials/form_group.submit.tpl" form_token=$form_token back_url={uri args="acp/articles"}}
</form>
</div>
{include file="asset:System/Partials/form_group.submit.tpl" form_token=$form_token back_url={uri args="acp/articles"}}
{javascripts}
{include_js module="articles" file="admin/acp"}
{include_js module="system" file="ajax-form"}
{/javascripts}
{/block}
{extends file="asset:`$LAYOUT`"}
{extends file="asset:System/layout.admin-grid.tpl"}
{block CONTENT}
<form action="{uri args="acp/articles/index/delete"}" method="post">
<nav id="adm-list" class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex2-collapse">
<span class="sr-only">{lang t="system|toggle_navigation"}</span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<span class="navbar-brand">{lang t="system|overview"}</span>
</div>
<div class="collapse navbar-collapse navbar-ex2-collapse">
<div class="navbar-text pull-right">
{check_access mode="link" path="acp/articles/index/create" class="glyphicon glyphicon-plus text-success"}
{if $show_mass_delete_button}
{check_access mode="button" path="acp/articles/index/delete" class="glyphicon glyphicon-remove text-danger" lang="system|delete_marked"}
{/if}
</div>
</div>
</nav>
{redirect_message}
{include file="asset:System/Partials/datagrid.tpl" dataTable=$grid}
</form>
{$DELETE_ROUTE={uri args="acp/articles/index/delete"}}
{block HEADER_BAR_OPTIONS}
{check_access mode="link" path="acp/articles/index/create" class="glyphicon glyphicon-plus text-success"}
{if $show_mass_delete_button}
{check_access mode="button" path="acp/articles/index/delete" class="glyphicon glyphicon-remove text-danger" lang="system|delete_marked"}
{/if}
{/block}
{block ADMIN_GRID_CONTENT}
{include file="asset:System/Partials/datagrid.tpl" dataTable=$grid}
{/block}
......@@ -15,8 +15,8 @@
<item key="page_statements">Seitenangaben</item>
<item key="select_create_menu_item">Bitte wählen Sie aus, ob für diesen Artikel ein Menüpunkt erstellt werden soll oder nicht.</item>
<item key="text">Text</item>
<item key="text_to_short">Der Text sollte mindestens 3 Zeichen lang sein.</item>
<item key="text_to_short">Der Text darf nicht leer sein.</item>
<item key="title">Titel</item>
<item key="title_to_short">Der Titel sollte mindestens 3 Zeichen lang sein.</item>
<item key="title_to_short">Der Titel darf nicht leer sein.</item>
</keys>
</language>
......@@ -15,8 +15,8 @@
<item key="page_statements">Page statements</item>
<item key="select_create_menu_item">Please select, whether you want to create am menu item for this article or not.</item>
<item key="text">Text</item>
<item key="text_to_short">The text should be at least 3 characters long.</item>
<item key="text_to_short">The text should not be empty.</item>
<item key="title">Title</item>
<item key="title_to_short">The title should be at least 3 characters long.</item>
<item key="title_to_short">The title should not be empty.</item>
</keys>
</language>
......@@ -17,13 +17,13 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "*",
"acp3/core": "4.0.4",
"acp3/setup": "4.0.4",
"acp3/module-errors": "4.0.4",
"acp3/module-permissions": "4.0.4",
"acp3/module-seo": "4.0.4",
"acp3/module-system": "4.0.4",
"acp3/module-users": "4.0.4"
"acp3/core": "4.1.0",
"acp3/setup": "4.1.0",
"acp3/module-errors": "4.1.0",
"acp3/module-permissions": "4.1.0",
"acp3/module-seo": "4.1.0",
"acp3/module-system": "4.1.0",
"acp3/module-users": "4.1.0"
},
"autoload": {
"psr-4": {
......