Commit 973bd8cc authored by Tino Goratsch's avatar Tino Goratsch

Merge branch 'release/v4.14.0'

parents 1d9a1ac6 807568b9
......@@ -14,7 +14,7 @@ interface BootstrapInterface extends HttpKernelInterface
/**
* Contains the current ACP3 version string
*/
const VERSION = '4.13.1';
const VERSION = '4.14.0';
/**
* Performs some startup checks
......
......@@ -119,13 +119,15 @@ class StepsTest extends \PHPUnit_Framework_TestCase
$this->requestMock->expects($this->any())
->method('getModuleAndController')
->willReturn(
($area === AreaEnum::AREA_ADMIN ? 'acp/' : '') . $moduleName . '/' . $controller
($area === AreaEnum::AREA_ADMIN ? 'acp/' : '') . $moduleName . '/' . $controller . '/'
);
$this->requestMock->expects($this->any())
->method('getFullPath')
->willReturn(
($area === AreaEnum::AREA_ADMIN ? 'acp/' : '') . $moduleName . '/' . $controller . '/' . $action
($area === AreaEnum::AREA_ADMIN ? 'acp/' : '') . $moduleName . '/' . $controller . '/' . $action . '/'
);
$parameters .= preg_match('=/$=', $parameters) ? '' : '/';
$this->requestMock->expects($this->any())
->method('getQuery')
->willReturn($moduleName . '/' . $controller . '/' . $action . '/' . $parameters);
......
......@@ -17,12 +17,12 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "^1.0",
"acp3/core": "^4.13.1",
"acp3/setup": "^4.13.1",
"acp3/module-errors": "^4.13.1",
"acp3/module-permissions": "^4.13.1",
"acp3/module-system": "^4.13.1",
"acp3/module-users": "^4.13.1"
"acp3/core": "^4.14.0",
"acp3/setup": "^4.14.0",
"acp3/module-errors": "^4.14.0",
"acp3/module-permissions": "^4.14.0",
"acp3/module-system": "^4.14.0",
"acp3/module-users": "^4.14.0"
},
"autoload": {
"psr-4": {
......
......@@ -17,12 +17,12 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "^1.0",
"acp3/core": "^4.13.1",
"acp3/setup": "^4.13.1",
"acp3/module-errors": "^4.13.1",
"acp3/module-permissions": "^4.13.1",
"acp3/module-system": "^4.13.1",
"acp3/module-users": "^4.13.1"
"acp3/core": "^4.14.0",
"acp3/setup": "^4.14.0",
"acp3/module-errors": "^4.14.0",
"acp3/module-permissions": "^4.14.0",
"acp3/module-system": "^4.14.0",
"acp3/module-users": "^4.14.0"
},
"suggest": {
"acp3/module-seo": "Provides additional SEO capabilities"
......
......@@ -17,12 +17,12 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "^1.0",
"acp3/core": "^4.13.1",
"acp3/setup": "^4.13.1",
"acp3/module-errors": "^4.13.1",
"acp3/module-permissions": "^4.13.1",
"acp3/module-system": "^4.13.1",
"acp3/module-users": "^4.13.1",
"acp3/core": "^4.14.0",
"acp3/setup": "^4.14.0",
"acp3/module-errors": "^4.14.0",
"acp3/module-permissions": "^4.14.0",
"acp3/module-system": "^4.14.0",
"acp3/module-users": "^4.14.0",
"google/recaptcha": "^1.1.0"
},
"autoload": {
......
......@@ -17,12 +17,12 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "^1.0",
"acp3/core": "^4.13.1",
"acp3/setup": "^4.13.1",
"acp3/module-errors": "^4.13.1",
"acp3/module-permissions": "^4.13.1",
"acp3/module-system": "^4.13.1",
"acp3/module-users": "^4.13.1"
"acp3/core": "^4.14.0",
"acp3/setup": "^4.14.0",
"acp3/module-errors": "^4.14.0",
"acp3/module-permissions": "^4.14.0",
"acp3/module-system": "^4.14.0",
"acp3/module-users": "^4.14.0"
},
"autoload": {
"psr-4": {
......
......@@ -17,12 +17,12 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "^1.0",
"acp3/core": "^4.13.1",
"acp3/setup": "^4.13.1",
"acp3/module-errors": "^4.13.1",
"acp3/module-permissions": "^4.13.1",
"acp3/module-system": "^4.13.1",
"acp3/module-users": "^4.13.1"
"acp3/core": "^4.14.0",
"acp3/setup": "^4.14.0",
"acp3/module-errors": "^4.14.0",
"acp3/module-permissions": "^4.14.0",
"acp3/module-system": "^4.14.0",
"acp3/module-users": "^4.14.0"
},
"suggest": {
"acp3/module-captcha": "Provides basic protection against spam bots."
......
......@@ -25,6 +25,8 @@ class Imprint extends Core\Controller\AbstractFrontendAction
{
$this->setCacheResponseCacheable($this->config->getSettings(Schema::MODULE_NAME)['cache_lifetime']);
$this->breadcrumb->append($this->translator->t('contact', 'frontend_index_imprint'));
return [
'imprint' => $this->config->getSettings(Contact\Installer\Schema::MODULE_NAME),
'powered_by' => $this->translator->t(
......
......@@ -17,12 +17,12 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "^1.0",
"acp3/core": "^4.13.1",
"acp3/setup": "^4.13.1",
"acp3/module-errors": "^4.13.1",
"acp3/module-permissions": "^4.13.1",
"acp3/module-system": "^4.13.1",
"acp3/module-users": "^4.13.1"
"acp3/core": "^4.14.0",
"acp3/setup": "^4.14.0",
"acp3/module-errors": "^4.14.0",
"acp3/module-permissions": "^4.14.0",
"acp3/module-system": "^4.14.0",
"acp3/module-users": "^4.14.0"
},
"suggest": {
"acp3/module-captcha": "Provides basic protection against spam bots."
......
......@@ -17,12 +17,12 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "^1.0",
"acp3/core": "^4.13.1",
"acp3/setup": "^4.13.1",
"acp3/module-errors": "^4.13.1",
"acp3/module-permissions": "^4.13.1",
"acp3/module-system": "^4.13.1",
"acp3/module-users": "^4.13.1"
"acp3/core": "^4.14.0",
"acp3/setup": "^4.14.0",
"acp3/module-errors": "^4.14.0",
"acp3/module-permissions": "^4.14.0",
"acp3/module-system": "^4.14.0",
"acp3/module-users": "^4.14.0"
},
"autoload": {
"psr-4": {
......
......@@ -17,11 +17,11 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "^1.0",
"acp3/core": "^4.13.1",
"acp3/setup": "^4.13.1",
"acp3/module-permissions": "^4.13.1",
"acp3/module-system": "^4.13.1",
"acp3/module-users": "^4.13.1"
"acp3/core": "^4.14.0",
"acp3/setup": "^4.14.0",
"acp3/module-permissions": "^4.14.0",
"acp3/module-system": "^4.14.0",
"acp3/module-users": "^4.14.0"
},
"autoload": {
"psr-4": {
......
......@@ -17,12 +17,12 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "^1.0",
"acp3/core": "^4.13.1",
"acp3/setup": "^4.13.1",
"acp3/module-errors": "^4.13.1",
"acp3/module-permissions": "^4.13.1",
"acp3/module-system": "^4.13.1",
"acp3/module-users": "^4.13.1",
"acp3/core": "^4.14.0",
"acp3/setup": "^4.14.0",
"acp3/module-errors": "^4.14.0",
"acp3/module-permissions": "^4.14.0",
"acp3/module-system": "^4.14.0",
"acp3/module-users": "^4.14.0",
"mibe/feedwriter": "^1.0"
},
"autoload": {
......
......@@ -17,12 +17,12 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "^1.0",
"acp3/core": "^4.13.1",
"acp3/setup": "^4.13.1",
"acp3/module-errors": "^4.13.1",
"acp3/module-permissions": "^4.13.1",
"acp3/module-system": "^4.13.1",
"acp3/module-users": "^4.13.1"
"acp3/core": "^4.14.0",
"acp3/setup": "^4.14.0",
"acp3/module-errors": "^4.14.0",
"acp3/module-permissions": "^4.14.0",
"acp3/module-system": "^4.14.0",
"acp3/module-users": "^4.14.0"
},
"autoload": {
"psr-4": {
......
......@@ -17,13 +17,13 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "^1.0",
"acp3/core": "^4.13.1",
"acp3/setup": "^4.13.1",
"acp3/module-errors": "^4.13.1",
"acp3/module-permissions": "^4.13.1",
"acp3/module-system": "^4.13.1",
"acp3/module-users": "^4.13.1",
"acp3/module-categories": "^4.13.1"
"acp3/core": "^4.14.0",
"acp3/setup": "^4.14.0",
"acp3/module-errors": "^4.14.0",
"acp3/module-permissions": "^4.14.0",
"acp3/module-system": "^4.14.0",
"acp3/module-users": "^4.14.0",
"acp3/module-categories": "^4.14.0"
},
"suggest": {
"acp3/module-seo": "Provides additional SEO capabilities"
......
......@@ -17,12 +17,12 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "^1.0",
"acp3/core": "^4.13.1",
"acp3/setup": "^4.13.1",
"acp3/module-errors": "^4.13.1",
"acp3/module-permissions": "^4.13.1",
"acp3/module-system": "^4.13.1",
"acp3/module-users": "^4.13.1"
"acp3/core": "^4.14.0",
"acp3/setup": "^4.14.0",
"acp3/module-errors": "^4.14.0",
"acp3/module-permissions": "^4.14.0",
"acp3/module-system": "^4.14.0",
"acp3/module-users": "^4.14.0"
},
"suggest": {
"acp3/module-seo": "Provides additional SEO capabilities"
......
......@@ -17,12 +17,12 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "^1.0",
"acp3/core": "^4.13.1",
"acp3/setup": "^4.13.1",
"acp3/module-errors": "^4.13.1",
"acp3/module-permissions": "^4.13.1",
"acp3/module-system": "^4.13.1",
"acp3/module-users": "^4.13.1"
"acp3/core": "^4.14.0",
"acp3/setup": "^4.14.0",
"acp3/module-errors": "^4.14.0",
"acp3/module-permissions": "^4.14.0",
"acp3/module-system": "^4.14.0",
"acp3/module-users": "^4.14.0"
},
"suggest": {
"acp3/module-captcha": "Provides basic protection against spam bots."
......
......@@ -75,12 +75,17 @@ class Steps extends Core\Breadcrumb\Steps
}
if (!empty($this->stepsFromDb)) {
$this->breadcrumbCache = $this->stepsFromDb;
$lastDbStepUri = $this->stepsFromDb[count($this->stepsFromDb) - 1]['uri'];
if ($this->breadcrumbCache[count($this->breadcrumbCache) - 1]['uri'] === $this->steps[0]['uri']) {
$steps = $this->steps;
unset($steps[0]);
$this->breadcrumbCache = array_merge($this->breadcrumbCache, $steps);
if (count($this->steps) === 1 && empty($this->steps[0]['uri'])) {
$this->copyTitleFromFirstStepToLastDbStep();
$this->steps[0]['uri'] = $lastDbStepUri;
}
if ($lastDbStepUri === $this->steps[0]['uri']) {
$this->copyTitleFromFirstStepToLastDbStep();
$this->breadcrumbCache = array_merge($this->stepsFromDb, array_slice($this->steps, 1));
}
}
}
......@@ -90,7 +95,7 @@ class Steps extends Core\Breadcrumb\Steps
*/
private function prePopulate()
{
$items = $this->menuItemRepository->getMenuItemsByUri($this->possibleMatchedRoutes());
$items = $this->menuItemRepository->getMenuItemsByUri($this->getPossiblyMatchingRoutes());
$matches = $this->findRestrictionInRoutes($items);
if (!empty($matches)) {
......@@ -104,7 +109,7 @@ class Steps extends Core\Breadcrumb\Steps
}
}
private function possibleMatchedRoutes() {
private function getPossiblyMatchingRoutes() {
return [
$this->request->getQuery(),
$this->request->getUriWithoutPages(),
......@@ -122,7 +127,7 @@ class Steps extends Core\Breadcrumb\Steps
{
rsort($items);
foreach ($items as $index => $item) {
if (in_array($item['uri'], $this->possibleMatchedRoutes())) {
if (in_array($item['uri'], $this->getPossiblyMatchingRoutes())) {
return [
$item['left_id'],
$item['right_id'],
......@@ -147,4 +152,9 @@ class Steps extends Core\Breadcrumb\Steps
return $this;
}
private function copyTitleFromFirstStepToLastDbStep()
{
$this->stepsFromDb[count($this->stepsFromDb) - 1]['title'] = $this->steps[0]['title'];
}
}
......@@ -69,7 +69,7 @@ class StepsTest extends \ACP3\Core\Test\Breadcrumb\StepsTest
$expected = [
[
'title' => 'News',
'title' => '{NEWS_NEWS}',
'uri' => '/news/',
'last' => true
]
......@@ -108,7 +108,7 @@ class StepsTest extends \ACP3\Core\Test\Breadcrumb\StepsTest
'uri' => '/news/',
],
[
'title' => 'Newsletter',
'title' => '{NEWSLETTER_NEWSLETTER}',
'uri' => '/newsletter/',
'last' => true
],
......@@ -147,7 +147,7 @@ class StepsTest extends \ACP3\Core\Test\Breadcrumb\StepsTest
'uri' => '/news/',
],
[
'title' => 'Newsletter',
'title' => '{NEWSLETTER_NEWSLETTER}',
'uri' => '/newsletter/',
],
[
......@@ -180,7 +180,7 @@ class StepsTest extends \ACP3\Core\Test\Breadcrumb\StepsTest
$this->setUpTranslatorMockExpectations(0);
$this->steps->append('News', 'news');
$this->steps->append('Category', 'news/index/index/cat_' . 1);
$this->steps->append('Category', 'news/index/index/cat_1');
$this->steps->append('News-Title');
$expected = [
......@@ -190,7 +190,7 @@ class StepsTest extends \ACP3\Core\Test\Breadcrumb\StepsTest
],
[
'title' => 'Category',
'uri' => '/news/index/index/cat_' . 1 . '/',
'uri' => '/news/index/index/cat_1/',
],
[
'title' => 'News-Title',
......@@ -201,6 +201,70 @@ class StepsTest extends \ACP3\Core\Test\Breadcrumb\StepsTest
$this->assertEquals($expected, $this->steps->getBreadcrumb());
}
public function testGetBreadcrumbLastStepTitleShouldTakePrecedence()
{
$this->setUpMenuItemRepositoryExpectations([
[
'title' => 'FooBar',
'uri' => 'articles/index/details/id_1/',
'left_id' => 1,
'right_id' => 2
]
]);
$this->setUpRequestMockExpectations(
AreaEnum::AREA_FRONTEND,
'articles',
'index',
'details',
'id_1'
);
$this->setUpRouterMockExpectations();
$this->setUpTranslatorMockExpectations(0);
$this->steps->append('Lorem Ipsum Dolor', 'articles/index/details/id_1');
$expected = [
[
'title' => 'Lorem Ipsum Dolor',
'uri' => '/articles/index/details/id_1/',
'last' => true
],
];
$this->assertEquals($expected, $this->steps->getBreadcrumb());
}
public function testGetBreadcrumbLastStepTitleShouldTakePrecedenceWithEmptyUri()
{
$this->setUpMenuItemRepositoryExpectations([
[
'title' => 'FooBar',
'uri' => 'articles/index/details/id_1/',
'left_id' => 1,
'right_id' => 2
]
]);
$this->setUpRequestMockExpectations(
AreaEnum::AREA_FRONTEND,
'articles',
'index',
'details',
'id_1'
);
$this->setUpRouterMockExpectations();
$this->setUpTranslatorMockExpectations(0);
$this->steps->append('Lorem Ipsum Dolor');
$expected = [
[
'title' => 'Lorem Ipsum Dolor',
'uri' => '/articles/index/details/id_1/',
'last' => true
],
];
$this->assertEquals($expected, $this->steps->getBreadcrumb());
}
public function testGetBreadcrumbForFrontendControllerIndex()
{
$this->setUpMenuItemRepositoryExpectations();
......
......@@ -17,12 +17,12 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "^1.0",
"acp3/core": "^4.13.1",
"acp3/setup": "^4.13.1",
"acp3/module-errors": "^4.13.1",
"acp3/module-permissions": "^4.13.1",
"acp3/module-system": "^4.13.1",
"acp3/module-users": "^4.13.1"
"acp3/core": "^4.14.0",
"acp3/setup": "^4.14.0",
"acp3/module-errors": "^4.14.0",
"acp3/module-permissions": "^4.14.0",
"acp3/module-system": "^4.14.0",
"acp3/module-users": "^4.14.0"
},
"autoload": {
"psr-4": {
......
......@@ -17,13 +17,13 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "^1.0",
"acp3/core": "^4.13.1",
"acp3/setup": "^4.13.1",
"acp3/module-errors": "^4.13.1",
"acp3/module-permissions": "^4.13.1",
"acp3/module-system": "^4.13.1",
"acp3/module-users": "^4.13.1",
"acp3/module-categories": "^4.13.1"
"acp3/core": "^4.14.0",
"acp3/setup": "^4.14.0",
"acp3/module-errors": "^4.14.0",
"acp3/module-permissions": "^4.14.0",
"acp3/module-system": "^4.14.0",
"acp3/module-users": "^4.14.0",
"acp3/module-categories": "^4.14.0"
},
"suggest": {
"acp3/module-seo": "Provides additional SEO capabilities"
......
......@@ -17,12 +17,12 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "^1.0",
"acp3/core": "^4.13.1",
"acp3/setup": "^4.13.1",
"acp3/module-errors": "^4.13.1",
"acp3/module-permissions": "^4.13.1",
"acp3/module-system": "^4.13.1",
"acp3/module-users": "^4.13.1"
"acp3/core": "^4.14.0",
"acp3/setup": "^4.14.0",
"acp3/module-errors": "^4.14.0",
"acp3/module-permissions": "^4.14.0",
"acp3/module-system": "^4.14.0",
"acp3/module-users": "^4.14.0"
},
"suggest": {
"acp3/module-captcha": "Provides basic protection against spam bots."
......
......@@ -17,11 +17,11 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "^1.0",
"acp3/core": "^4.13.1",
"acp3/setup": "^4.13.1",
"acp3/module-errors": "^4.13.1",
"acp3/module-system": "^4.13.1",
"acp3/module-users": "^4.13.1"
"acp3/core": "^4.14.0",
"acp3/setup": "^4.14.0",
"acp3/module-errors": "^4.14.0",
"acp3/module-system": "^4.14.0",
"acp3/module-users": "^4.14.0"
},
"autoload": {
"psr-4": {
......
......@@ -17,12 +17,12 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "^1.0",
"acp3/core": "^4.13.1",
"acp3/setup": "^4.13.1",
"acp3/module-errors": "^4.13.1",
"acp3/module-permissions": "^4.13.1",
"acp3/module-system": "^4.13.1",
"acp3/module-users": "^4.13.1"
"acp3/core": "^4.14.0",
"acp3/setup": "^4.14.0",
"acp3/module-errors": "^4.14.0",
"acp3/module-permissions": "^4.14.0",
"acp3/module-system": "^4.14.0",
"acp3/module-users": "^4.14.0"
},
"autoload": {
"psr-4": {
......
......@@ -17,12 +17,12 @@
"prefer-stable": true,
"require": {
"acp3/composer-installer": "^1.0",
"acp3/core": "^4.13.1",
"acp3/setup": "^4.13.1",
"acp3/module-errors": "^4.13.1",
"acp3/module-permissions": "^4.13.1",
"acp3/module-system": "^4.13.1",
"acp3/module-users": "^4.13.1"
"acp3/core": "^4.14.0",
"acp3/setup": "^4.14.0",
"acp3/module-errors": "^4.14.0",
"acp3/module-permissions": "^4.14.0",
"acp3/module-system": "^4.14.0",
"acp3/module-users": "^4.14.0"
},
"autoload": {
"psr-4": {
......
......@@ -8,6 +8,7 @@ namespace ACP3\Modules\ACP3\Seo\Event\Listener;
use ACP3\Core\Application\Event\ControllerActionBeforeDispatchEvent;
use ACP3\Core\Controller\AreaEnum;
use ACP3\Core\Environment\ApplicationPath;
use ACP3\Core\Http\RequestInterface;
use ACP3\Core\Router\RouterInterface;
use ACP3\Modules\ACP3\Seo\Core\Router\Aliases;
......@@ -35,16 +36,22 @@ class OnControllerActionBeforeDispatchListener
* @var \ACP3\Modules\ACP3\Seo\Helper\MetaStatements
*/
protected $metaStatements;
/**
* @var ApplicationPath
*/
private $applicationPath;
/**
* OnFrontControllerBeforeDispatchListener constructor.
*
* @param ApplicationPath $applicationPath
* @param \ACP3\Core\Http\RequestInterface $request
* @param \ACP3\Core\Router\RouterInterface $router
* @param \ACP3\Modules\ACP3\Seo\Core\Router\Aliases $aliases
* @param \ACP3\Modules\ACP3\Seo\Helper\MetaStatements $metaStatements
*/
public function __construct(
ApplicationPath $applicationPath,
RequestInterface $request,
RouterInterface $router,
Aliases $aliases,
......@@ -54,6 +61,16 @@ class OnControllerActionBeforeDispatchListener
$this->router = $router;
$this->aliases = $aliases;
$this->metaStatements = $metaStatements;
$this->applicationPath = $applicationPath;
}
/**
* @param \ACP3\Core\Application\Event\ControllerActionBeforeDispatchEvent $event
*/
public function onBeforeDispatch(ControllerActionBeforeDispatchEvent $event)
{
$this->setCanonicalForExistingUriAlias($event);
$this->setCanonicalForHomepage();
}
/**
......@@ -61,7 +78,7 @@ class OnControllerActionBeforeDispatchListener
*
* @param \ACP3\Core\Application\Event\ControllerActionBeforeDispatchEvent $event
*/
public function onBeforeDispatch(ControllerActionBeforeDispatchEvent $event)
private function setCanonicalForExistingUriAlias(ControllerActionBeforeDispatchEvent $event)
{
if ($this->isInFrontend($event) && $this->uriAliasExists()) {
$this->metaStatements->setCanonicalUri($this->router->route($this->request->getQuery()));
......@@ -87,4 +104,14 @@ class OnControllerActionBeforeDispatchListener
return $this->aliases->uriAliasExists($this->request->getQuery()) === true
&& $this->request->getPathInfo() !== $this->aliases->getUriAlias($this->request->getQuery()) . '/';
}
/**
* If we are currently displaying the homepage, set the canonical URL to the website root
*/
private function setCanonicalForHomepage()
{
if ($this->request->isHomepage()) {
$this->metaStatements->setCanonicalUri($this->applicationPath->getWebRoot());
}
}
}
......@@ -56,6 +56,10 @@ class MetaStatements
* @var string
*/
private $metaRobots = '';
/**
* @var bool
*/
private $isActive;
/**
* MetaStatements constructor.
......@@ -91,7 +95,7 @@ class MetaStatements
/**
* Returns the meta tags of the current page
*
* @return string
* @return array
*/
public function getMetaTags()
{
......
......@@ -2,6 +2,7 @@ services:
seo.event.on_controller_action_before_dispatch_listener:
class: ACP3\Modules\ACP3\Seo\Event\Listener\OnControllerActionBeforeDispatchListener
arguments: