Commit 4f12e25e authored by Oliver Hader's avatar Oliver Hader Committed by Benni Mack
Browse files

[BUGFIX] Set default controller name in ExtbasePluginEnhancer

The `defaultController` setting is only applied if both `action` and
`controller` parameters are empty. In Extbase context it happens that
only `action` is defined, but `controller` is empty (since linking to
the very same controller, just changing the action).

The behavior now is the following:
* set `action` and `controller` parameters to default if not given
* set `controller` parameter to default if not given

Resolves: #87337
Releases: master, 9.5
Change-Id: I3ee730f6bc665808c59cc07907467aa98c2de21a
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/59659

Tested-by: default avatarTYPO3com <noreply@typo3.com>
Tested-by: Susanne Moog's avatarSusanne Moog <look@susi.dev>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: default avatarJörg Bösche <typo3@joergboesche.de>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: Susanne Moog's avatarSusanne Moog <look@susi.dev>
parent 3e2758d1
......@@ -116,7 +116,8 @@ class ExtbasePluginEnhancer extends PluginEnhancer
) {
$this->applyControllerActionValues(
$this->configuration['defaultController'],
$originalParameters[$this->namespace]
$originalParameters[$this->namespace],
true
);
}
......@@ -165,7 +166,8 @@ class ExtbasePluginEnhancer extends PluginEnhancer
}
$this->applyControllerActionValues(
$internals['_controller'],
$parameters[$this->namespace]
$parameters[$this->namespace],
false
);
return $parameters;
}
......@@ -195,7 +197,6 @@ class ExtbasePluginEnhancer extends PluginEnhancer
}
return true;
}
/**
* Check if action and controller are not empty.
*
......@@ -211,15 +212,25 @@ class ExtbasePluginEnhancer extends PluginEnhancer
* Add controller and action parameters so they can be used later-on.
*
* @param string $controllerActionValue
* @param array $target
* @param array $target Reference to target array to be modified
* @param bool $tryUpdate Try updating action value - but only if controller value matches
*/
protected function applyControllerActionValues(string $controllerActionValue, array &$target)
protected function applyControllerActionValues(string $controllerActionValue, array &$target, bool $tryUpdate = false)
{
if (strpos($controllerActionValue, '::') === false) {
return;
}
list($controllerName, $actionName) = explode('::', $controllerActionValue, 2);
$target['controller'] = $controllerName;
$target['action'] = $actionName;
// use default action name if controller matches
if ($tryUpdate && empty($target['action']) && $controllerName === ($target['controller'] ?? null)) {
$target['action'] = $actionName;
// use default controller name if action is defined (implies: non-default-controllers must be given)
} elseif ($tryUpdate && empty($target['controller']) && !empty($target['action'])) {
$target['controller'] = $controllerName;
// fallback and override
} else {
$target['controller'] = $controllerName;
$target['action'] = $actionName;
}
}
}
......@@ -691,4 +691,88 @@ class EnhancerLinkGeneratorTest extends AbstractTestCase
self::assertStringStartsWith($expectation, (string)$response->getBody());
}
/**
* @return array
*/
public function defaultExtbaseControllerActionNamesAreAppliedDataProvider(): array
{
return [
'*::*' => [
'&tx_testing_link[value]=1',
'https://acme.us/welcome/link/index/one'
],
'*::list' => [
'&tx_testing_link[action]=list&tx_testing_link[value]=1',
'https://acme.us/welcome/link/list/one'
],
'Link::*' => [
// correctly falling back to defaultController here
'&tx_testing_link[controller]=Link&tx_testing_link[value]=1',
'https://acme.us/welcome/link/index/one'
],
'Page::*' => [
// correctly falling back to defaultController here
'&tx_testing_link[controller]=Page&tx_testing_link[value]=1',
'https://acme.us/welcome/link/index/one'
],
'Page::show' => [
'&tx_testing_link[controller]=Page&tx_testing_link[action]=show&tx_testing_link[value]=1',
'https://acme.us/welcome/page/show/one'
],
];
}
/**
* Tests whether ExtbasePluginEnhancer applies `defaultController` values correctly.
*
* @param string $additionalParameters
* @param string $expectation
*
* @test
* @dataProvider defaultExtbaseControllerActionNamesAreAppliedDataProvider
*/
public function defaultExtbaseControllerActionNamesAreApplied(string $additionalParameters, string $expectation)
{
$targetLanguageId = 0;
$this->mergeSiteConfiguration('acme-com', [
'routeEnhancers' => [
'Enhancer' => [
'type' => 'Extbase',
'routes' => [
['routePath' => '/link/index/{value}', '_controller' => 'Link::index'],
['routePath' => '/link/list/{value}', '_controller' => 'Link::list'],
['routePath' => '/page/show/{value}', '_controller' => 'Page::show'],
],
'defaultController' => 'Link::index',
'extension' => 'testing',
'plugin' => 'link',
'aspects' => [
'value' => [
'type' => 'StaticValueMapper',
'map' => [
'one' => 1,
],
],
],
]
]
]);
$response = $this->executeFrontendRequest(
(new InternalRequest('https://acme.us/'))
->withPageId(1100)
->withInstructions([
$this->createTypoLinkUrlInstruction([
'parameter' => 1100,
'language' => $targetLanguageId,
'additionalParams' => $additionalParameters,
'forceAbsoluteUrl' => 1,
])
]),
$this->internalRequestContext
);
static::assertSame($expectation, (string)$response->getBody());
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment