Skip to content

Commit

Permalink
[BUGFIX] Set default controller name in ExtbasePluginEnhancer
Browse files Browse the repository at this point in the history
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: TYPO3com <noreply@typo3.com>
Tested-by: Susanne Moog <look@susi.dev>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Jörg Bösche <typo3@joergboesche.de>
Reviewed-by: Benni Mack <benni@typo3.org>
Reviewed-by: Susanne Moog <look@susi.dev>
  • Loading branch information
ohader authored and bmack committed Nov 9, 2019
1 parent 3e2758d commit 4f12e25
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 7 deletions.
25 changes: 18 additions & 7 deletions typo3/sysext/extbase/Classes/Routing/ExtbasePluginEnhancer.php
Expand Up @@ -116,7 +116,8 @@ public function enhanceForGeneration(RouteCollection $collection, array $origina
) {
$this->applyControllerActionValues(
$this->configuration['defaultController'],
$originalParameters[$this->namespace]
$originalParameters[$this->namespace],
true
);
}

Expand Down Expand Up @@ -165,7 +166,8 @@ protected function inflateParameters(array $parameters, array $internals = []):
}
$this->applyControllerActionValues(
$internals['_controller'],
$parameters[$this->namespace]
$parameters[$this->namespace],
false
);
return $parameters;
}
Expand Down Expand Up @@ -195,7 +197,6 @@ protected function verifyRequiredParameters(Route $route, array $parameters): bo
}
return true;
}

/**
* Check if action and controller are not empty.
*
Expand All @@ -211,15 +212,25 @@ protected function hasControllerActionValues(array $target): bool
* 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;
}
}
}
Expand Up @@ -691,4 +691,88 @@ public function pageTypeDecoratorIsApplied(array $enhancer, string $additionalPa

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());
}
}

0 comments on commit 4f12e25

Please sign in to comment.