Commit 9751dfd2 authored by Tino Goratsch's avatar Tino Goratsch

Merge branch 'release/v4.1.30'

parents 7c77b9a9 41ead35f
......@@ -48,9 +48,11 @@ deploy:
on:
tags: true
condition: "$TRAVIS_PHP_VERSION = '7.0'"
after_deploy:
- ./build/travis/update_version_check.sh ${TRAVIS_PHP_VERSION} ${TRAVIS_TAG}
- provider: script
script: ./build/travis/update_version_check.sh ${TRAVIS_TAG}
on:
tags: true
condition: "$TRAVIS_PHP_VERSION = '7.0'"
cache:
directories:
......
......@@ -14,7 +14,7 @@ interface BootstrapInterface extends HttpKernelInterface
/**
* Contains the current ACP3 version string
*/
const VERSION = '4.1.29';
const VERSION = '4.1.30';
/**
* Performs some startup checks
......
......@@ -7,7 +7,8 @@
namespace ACP3\Core\Cache;
use ACP3\Core\Environment\ApplicationMode;
use ACP3\Modules\ACP3\Users\Model\UserModel;
use ACP3\Core\Settings\SettingsInterface;
use ACP3\Modules\ACP3\System\Installer\Schema;
use Symfony\Component\HttpFoundation\Response;
/**
......@@ -16,11 +17,6 @@ use Symfony\Component\HttpFoundation\Response;
*/
trait CacheResponseTrait
{
/**
* @return UserModel
*/
abstract protected function getUser();
/**
* @return Response
*/
......@@ -31,6 +27,11 @@ trait CacheResponseTrait
*/
abstract protected function getApplicationMode();
/**
* @return SettingsInterface
*/
abstract protected function getSettings();
/**
* @param int $lifetime
*/
......@@ -38,15 +39,27 @@ trait CacheResponseTrait
{
$response = $this->getResponse();
if ($this->getApplicationMode() === ApplicationMode::DEVELOPMENT) {
if ($this->disallowPageCache()) {
$response->setPrivate();
$lifetime = null;
} else {
$response->setPublic();
}
$response
->setVary('X-User-Context-Hash')
->setPublic()
->setMaxAge($lifetime)
->setSharedMaxAge($lifetime);
}
/**
* @return bool
*/
protected function disallowPageCache()
{
$systemSettings = $this->getSettings()->getSettings(Schema::MODULE_NAME);
return $this->getApplicationMode() === ApplicationMode::DEVELOPMENT
|| $systemSettings['page_cache_is_enabled'] == 0;
}
}
......@@ -139,19 +139,19 @@ abstract class AbstractWidgetAction implements ActionInterface
}
/**
* @return \ACP3\Modules\ACP3\Users\Model\UserModel
* @return \ACP3\Core\View
*/
protected function getUser()
protected function getView()
{
return $this->user;
return $this->view;
}
/**
* @return \ACP3\Core\View
* @return Core\Settings\SettingsInterface
*/
protected function getView()
protected function getSettings()
{
return $this->view;
return $this->config;
}
/**
......
......@@ -2,7 +2,6 @@
namespace ACP3\Core\Helpers\Formatter;
use ACP3\Core;
use ACP3\Modules\ACP3\Seo\Validation\ValidationRules\UriAliasValidationRule;
/**
* Class RewriteInternalUri
......@@ -27,31 +26,31 @@ class RewriteInternalUri
*/
protected $router;
/**
* @var \ACP3\Modules\ACP3\Seo\Validation\ValidationRules\UriAliasValidationRule
* @var Core\Validation\ValidationRules\InternalUriValidationRule
*/
protected $uriAliasValidationRule;
private $internalUriValidationRule;
/**
* RewriteInternalUri constructor.
*
* @param \ACP3\Core\Environment\ApplicationPath $appPath
* @param \ACP3\Core\Modules\Helper\ControllerActionExists $controllerActionExists
* @param \ACP3\Core\Http\RequestInterface $request
* @param \ACP3\Core\Router\RouterInterface $router
* @param \ACP3\Modules\ACP3\Seo\Validation\ValidationRules\UriAliasValidationRule $uriAliasValidationRule
* @param \ACP3\Core\Environment\ApplicationPath $appPath
* @param \ACP3\Core\Modules\Helper\ControllerActionExists $controllerActionExists
* @param \ACP3\Core\Http\RequestInterface $request
* @param \ACP3\Core\Router\RouterInterface $router
* @param Core\Validation\ValidationRules\InternalUriValidationRule $internalUriValidationRule
*/
public function __construct(
Core\Environment\ApplicationPath $appPath,
Core\Modules\Helper\ControllerActionExists $controllerActionExists,
Core\Http\RequestInterface $request,
Core\Router\RouterInterface $router,
UriAliasValidationRule $uriAliasValidationRule
Core\Validation\ValidationRules\InternalUriValidationRule $internalUriValidationRule
) {
$this->appPath = $appPath;
$this->controllerActionExists = $controllerActionExists;
$this->request = $request;
$this->router = $router;
$this->uriAliasValidationRule = $uriAliasValidationRule;
$this->internalUriValidationRule = $internalUriValidationRule;
}
/**
......@@ -79,7 +78,7 @@ class RewriteInternalUri
*/
private function rewriteInternalUriCallback(array $matches)
{
if ($this->uriAliasValidationRule->isValid($matches[7]) !== true) {
if ($this->internalUriValidationRule->isValid($matches[7]) === true) {
$resourceParts = explode('/', $matches[7]);
$path = $this->getResourcePath($resourceParts);
if ($this->controllerActionExists->controllerActionExists($path) === true) {
......
......@@ -11,8 +11,8 @@ use ACP3\Core\Environment\ApplicationPath;
use ACP3\Core\Helpers\Formatter\RewriteInternalUri;
use ACP3\Core\Http\Request;
use ACP3\Core\Modules\Helper\ControllerActionExists;
use ACP3\Core\Validation\ValidationRules\InternalUriValidationRule;
use ACP3\Modules\ACP3\Seo\Core\Router\Router;
use ACP3\Modules\ACP3\Seo\Validation\ValidationRules\UriAliasValidationRule;
use Symfony\Component\HttpFoundation\ServerBag;
class RewriteInternalUriTest extends \PHPUnit_Framework_TestCase
......@@ -40,7 +40,7 @@ class RewriteInternalUriTest extends \PHPUnit_Framework_TestCase
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $uriAliasValidationRuleMock;
private $internalUriValidationRule;
protected function setUp()
{
......@@ -51,7 +51,7 @@ class RewriteInternalUriTest extends \PHPUnit_Framework_TestCase
$this->controllerActionExistsMock,
$this->requestMock,
$this->routerMock,
$this->uriAliasValidationRuleMock
$this->internalUriValidationRule
);
}
......@@ -69,7 +69,7 @@ class RewriteInternalUriTest extends \PHPUnit_Framework_TestCase
$this->routerMock = $this->getMockBuilder(Router::class)
->disableOriginalConstructor()
->getMock();
$this->uriAliasValidationRuleMock = $this->getMockBuilder(UriAliasValidationRule::class)
$this->internalUriValidationRule = $this->getMockBuilder(InternalUriValidationRule::class)
->disableOriginalConstructor()
->getMock();
}
......@@ -94,7 +94,7 @@ HTML;
{
$this->setUpAppPathExpectations();
$this->setUpRequestMockExpectations();
$this->setUpValidationRuleMockExpectations(1, 'foo/bar/baz/', false);
$this->setUpValidationRuleMockExpectations(1, 'foo/bar/baz/', true);
$this->setUpControllerActionExistsMockExpectations(1, 'frontend/foo/bar/baz', false);
$this->setUpRouterMockExpectations(0, '', '');
......@@ -110,7 +110,7 @@ HTML;
{
$this->setUpAppPathExpectations();
$this->setUpRequestMockExpectations();
$this->setUpValidationRuleMockExpectations(1, 'foo/bar/baz/', false);
$this->setUpValidationRuleMockExpectations(1, 'foo/bar/baz/', true);
$this->setUpControllerActionExistsMockExpectations(1, 'frontend/foo/bar/baz', true);
$this->setUpRouterMockExpectations(1, 'foo/bar/baz/', '/foo-bar/');
......@@ -153,7 +153,7 @@ HTML;
*/
private function setUpValidationRuleMockExpectations($callCount, $uri, $isValid)
{
$this->uriAliasValidationRuleMock->expects($this->exactly($callCount))
$this->internalUriValidationRule->expects($this->exactly($callCount))
->method('isValid')
->with($uri)
->willReturn($isValid);
......
......@@ -13,6 +13,7 @@ use ACP3\Core\Session\SessionHandlerInterface;
use ACP3\Core\Validation\Exceptions\ValidationFailedException;
use ACP3\Core\Validation\ValidationRules\FormTokenValidationRule;
use ACP3\Core\Validation\Validator;
use Symfony\Component\EventDispatcher\EventDispatcher;
/**
* Class AbstractFormValidationTest
......@@ -26,6 +27,10 @@ abstract class AbstractFormValidationTest extends \PHPUnit_Framework_TestCase
* @var \ACP3\Core\Validation\AbstractFormValidation
*/
protected $formValidation;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
protected $eventDispatcherMock;
/**
* @var Translator|\PHPUnit_Framework_MockObject_MockObject
*/
......@@ -53,7 +58,10 @@ abstract class AbstractFormValidationTest extends \PHPUnit_Framework_TestCase
->disableOriginalConstructor()
->setMethods(['t'])
->getMock();
$this->validator = new Validator();
$this->eventDispatcherMock = $this->getMockBuilder(EventDispatcher::class)
->getMock();
$this->validator = new Validator($this->eventDispatcherMock);
}
/**
......
......@@ -19,6 +19,7 @@ abstract class AbstractValidationRuleTest extends \PHPUnit_Framework_TestCase
$this->validator = $this
->getMockBuilder(\ACP3\Core\Validation\Validator::class)
->disableOriginalConstructor()
->getMock();
$this->validator->registerValidationRule($this->validationRule);
......
......@@ -4,9 +4,14 @@ namespace ACP3\Core\Test\Validation\ValidationRules;
use ACP3\Core\Validation\Exceptions\ValidationFailedException;
use ACP3\Core\Validation\ValidationRules\EmailValidationRule;
use ACP3\Core\Validation\Validator;
use Symfony\Component\EventDispatcher\EventDispatcher;
class ValidatorTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
protected $eventDispatcherMock;
/**
* @var Validator
*/
......@@ -16,7 +21,10 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase
{
parent::setUp();
$this->validator = new Validator();
$this->eventDispatcherMock = $this->getMockBuilder(EventDispatcher::class)
->getMock();
$this->validator = new Validator($this->eventDispatcherMock);
}
public function testValidateValidValidationRuleWithValidValue()
......
<?php
/**
* Copyright (c) 2016 by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Core\Validation\Event;
use ACP3\Core\Validation\Validator;
use Symfony\Component\EventDispatcher\Event;
class FormValidationEvent extends Event
{
/**
* @var Validator
*/
private $validator;
/**
* @var array
*/
private $formData;
/**
* @var array
*/
private $extra;
/**
* FormValidationEvent constructor.
* @param Validator $validator
* @param array $formData
* @param array $extra
*/
public function __construct(
Validator $validator,
array $formData,
array $extra = []
) {
$this->validator = $validator;
$this->formData = $formData;
$this->extra = $extra;
}
/**
* @return Validator
*/
public function getValidator()
{
return $this->validator;
}
/**
* @return array
*/
public function getFormData()
{
return $this->formData;
}
/**
* @return array
*/
public function getExtra()
{
return $this->extra;
}
}
<?php
namespace ACP3\Core\Validation;
use ACP3\Core\Validation\Event\FormValidationEvent;
use ACP3\Core\Validation\Exceptions\ValidationFailedException;
use ACP3\Core\Validation\Exceptions\ValidationRuleNotFoundException;
use ACP3\Core\Validation\ValidationRules\ValidationRuleInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* Class Validator
......@@ -11,6 +13,10 @@ use ACP3\Core\Validation\ValidationRules\ValidationRuleInterface;
*/
class Validator
{
/**
* @var EventDispatcherInterface
*/
protected $eventDispatcher;
/**
* @var \ACP3\Core\Validation\ValidationRules\ValidationRuleInterface[]
*/
......@@ -24,6 +30,15 @@ class Validator
*/
protected $constraints = [];
/**
* Validator constructor.
* @param EventDispatcherInterface $eventDispatcher
*/
public function __construct(EventDispatcherInterface $eventDispatcher)
{
$this->eventDispatcher = $eventDispatcher;
}
/**
* @param \ACP3\Core\Validation\ValidationRules\ValidationRuleInterface $validationRule
*
......@@ -97,6 +112,22 @@ class Validator
return str_replace('_', '-', $field);
}
/**
* @param string $eventName
* @param array $formData
* @param array $extra
*/
public function dispatchValidationEvent($eventName, array $formData, array $extra = [])
{
$this->eventDispatcher->dispatch($eventName, new FormValidationEvent($this, $formData, $extra));
}
/**
* Validates a form
*
* @throws ValidationFailedException
* @throws ValidationRuleNotFoundException
*/
public function validate()
{
$this->errors = [];
......
......@@ -11,5 +11,5 @@ services:
core.breadcrumb.title:
class: ACP3\Core\Breadcrumb\Title
arguments:
- '@core.event_dispatcher'
- '@core.breadcrumb'
- '@core.event_dispatcher'
......@@ -93,7 +93,7 @@ services:
- '@core.modules.helper.controllerActionExists'
- '@core.http.request'
- '@core.router'
- '@seo.validation.validation_rules.uri_alias_validation_rule'
- '@core.validation.validation_rules.internal_uri_validation_rule'
slugify:
class: Cocur\Slugify\Slugify
services:
core.validator:
class: ACP3\Core\Validation\Validator
arguments:
- '@core.event_dispatcher'
core.validation.validation_rules.birthday_validation_rule:
class: ACP3\Core\Validation\ValidationRules\BirthdayValidationRule
......
......@@ -4,6 +4,7 @@ imports:
- { resource: components/application.yml }
- { resource: components/assets.yml }
- { resource: components/authentication.yml }
- { resource: components/breadcrumb.yml }
- { resource: components/controller.yml }
- { resource: components/database.yml }
- { resource: components/datagrid.yml }
......@@ -17,7 +18,6 @@ imports:
- { resource: components/view.yml }
- { resource: components/wysiwyg.yml }
- { resource: ../../Modules/ACP3/Permissions/Resources/config/services.yml }
- { resource: ../../Modules/ACP3/Seo/Resources/config/services.yml }
- { resource: ../../Modules/ACP3/System/Resources/config/services.yml }
- { resource: ../../Modules/ACP3/Users/Resources/config/services.yml }
......
......@@ -17,12 +17,12 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "*",
"acp3/core": "^4.1.29",
"acp3/setup": "^4.1.29",
"acp3/module-errors": "^4.1.29",
"acp3/module-permissions": "^4.1.29",
"acp3/module-system": "^4.1.29",
"acp3/module-users": "^4.1.29"
"acp3/core": "^4.1.30",
"acp3/setup": "^4.1.30",
"acp3/module-errors": "^4.1.30",
"acp3/module-permissions": "^4.1.30",
"acp3/module-system": "^4.1.30",
"acp3/module-users": "^4.1.30"
},
"autoload": {
"psr-4": {
......
......@@ -5,7 +5,6 @@
<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">
......@@ -19,9 +18,7 @@
{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>
{event name="seo.layout.render_form_fields" SEO_FORM_FIELDS=$SEO_FORM_FIELDS}
</div>
</div>
{include file="asset:System/Partials/form_group.submit.tpl" form_token=$form_token back_url={uri args="acp/articles"}}
......
......@@ -8,7 +8,6 @@
<dependencies>
<module>permissions</module>
<module>system</module>
<module>seo</module>
</dependencies>
</info>
</module>
......@@ -8,7 +8,6 @@ namespace ACP3\Modules\ACP3\Articles\Validation;
use ACP3\Core;
use ACP3\Modules\ACP3\Menus;
use ACP3\Modules\ACP3\Seo\Validation\ValidationRules\UriAliasValidationRule;
/**
* Class AdminFormValidation
......@@ -87,21 +86,18 @@ class AdminFormValidation extends Core\Validation\AbstractFormValidation
'extra' => [
'length' => 3
]
])
->addConstraint(
UriAliasValidationRule::class,
[
'data' => $formData,
'field' => 'alias',
'message' => $this->translator->t('seo', 'alias_unallowed_characters_or_exists'),
'extra' => [
'path' => $this->uriAlias
]
]);
if ($this->acl->hasPermission('admin/menus/items/create') === true && isset($formData['create']) === true) {
$this->validateMenuItem($formData);
}
$this->validator->dispatchValidationEvent(
'seo.validation.validate_uri_alias',
$formData,
['path' => $this->uriAlias]
);
$this->validator->validate();
}
......
......@@ -17,13 +17,13 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "*",
"acp3/core": "^4.1.29",
"acp3/setup": "^4.1.29",
"acp3/module-errors": "^4.1.29",
"acp3/module-permissions": "^4.1.29",
"acp3/module-seo": "^4.1.29",
"acp3/module-system": "^4.1.29",
"acp3/module-users": "^4.1.29"
"acp3/core": "^4.1.30",
"acp3/setup": "^4.1.30",
"acp3/module-errors": "^4.1.30",
"acp3/module-permissions": "^4.1.30",
"acp3/module-seo": "^4.1.30",
"acp3/module-system": "^4.1.30",
"acp3/module-users": "^4.1.30"
},
"autoload": {
"psr-4": {
......
......@@ -17,12 +17,12 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "*",
"acp3/core": "^4.1.29",
"acp3/setup": "^4.1.29",
"acp3/module-errors": "^4.1.29",
"acp3/module-permissions": "^4.1.29",
"acp3/module-system": "^4.1.29",
"acp3/module-users": "^4.1.29"
"acp3/core": "^4.1.30",
"acp3/setup": "^4.1.30",
"acp3/module-errors": "^4.1.30",
"acp3/module-permissions": "^4.1.30",
"acp3/module-system": "^4.1.30",
"acp3/module-users": "^4.1.30"
},
"autoload": {
"psr-4": {
......
......@@ -17,12 +17,12 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "*",
"acp3/core": "^4.1.29",
"acp3/setup": "^4.1.29",
"acp3/module-errors": "^4.1.29",
"acp3/module-permissions": "^4.1.29",
"acp3/module-system": "^4.1.29",
"acp3/module-users": "^4.1.29"
"acp3/core": "^4.1.30",
"acp3/setup": "^4.1.30",
"acp3/module-errors": "^4.1.30",
"acp3/module-permissions": "^4.1.30",
"acp3/module-system": "^4.1.30",
"acp3/module-users": "^4.1.30"
},
"autoload": {
"psr-4": {
......
......@@ -17,12 +17,12 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "*",
"acp3/core": "^4.1.29",
"acp3/setup": "^4.1.29",
"acp3/module-errors": "^4.1.29",
"acp3/module-permissions": "^4.1.29",
"acp3/module-system": "^4.1.29",
"acp3/module-users": "^4.1.29"
"acp3/core": "^4.1.30",
"acp3/setup": "^4.1.30",
"acp3/module-errors": "^4.1.30",
"acp3/module-permissions": "^4.1.30",
"acp3/module-system": "^4.1.30",
"acp3/module-users": "^4.1.30"
},
"autoload": {
"psr-4": {
......
......@@ -17,13 +17,13 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "*",
"acp3/core": "^4.1.29",
"acp3/setup": "^4.1.29",
"acp3/module-errors": "^4.1.29",
"acp3/module-permissions": "^4.1.29",
"acp3/module-seo": "^4.1.29",
"acp3/module-system": "^4.1.29",
"acp3/module-users": "^4.1.29"
"acp3/core": "^4.1.30",
"acp3/setup": "^4.1.30",
"acp3/module-errors": "^4.1.30",
"acp3/module-permissions": "^4.1.30",
"acp3/module-seo": "^4.1.30",
"acp3/module-system": "^4.1.30",
"acp3/module-users": "^4.1.30"
},
"autoload": {
"psr-4": {
......
......@@ -17,12 +17,12 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "*",
"acp3/core": "^4.1.29",
"acp3/setup": "^4.1.29",
"acp3/module-errors": "^4.1.29",
"acp3/module-permissions": "^4.1.29",
"acp3/module-system": "^4.1.29",
"acp3/module-users": "^4.1.29"
"acp3/core": "^4.1.30",
"acp3/setup": "^4.1.30",
"acp3/module-errors": "^4.1.30",
"acp3/module-permissions": "^4.1.30",
"acp3/module-system": "^4.1.30",
"acp3/module-users": "^4.1.30"
},
"autoload": {
"psr-4": {
......