From bffeb737025a4c20b8f837106e82e95466615b36 Mon Sep 17 00:00:00 2001 From: Markus Klein <markus.klein@typo3.org> Date: Sun, 29 Oct 2017 19:35:21 +0100 Subject: [PATCH] [FEATURE] Allow nested GET-parameters for config.linkVars Resolves: #22439 Releases: master Change-Id: I013d455c2024caede7897551240a0c4fe5c6e1e1 Reviewed-on: https://review.typo3.org/54496 Tested-by: TYPO3com <no-reply@typo3.com> Reviewed-by: Sebastian Hofer <sebastian.hofer@marit.ag> Tested-by: Sebastian Hofer <sebastian.hofer@marit.ag> Reviewed-by: Susanne Moog <susanne.moog@typo3.org> Tested-by: Susanne Moog <susanne.moog@typo3.org> --- ...-AllowNestedGET-paramsInConfiglinkVars.rst | 29 ++++++++++ .../TypoScriptFrontendController.php | 48 ++++++++++++----- .../TypoScriptFrontendControllerTest.php | 54 +++++++++++++++++++ 3 files changed, 117 insertions(+), 14 deletions(-) create mode 100644 typo3/sysext/core/Documentation/Changelog/master/Feature-22439-AllowNestedGET-paramsInConfiglinkVars.rst diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-22439-AllowNestedGET-paramsInConfiglinkVars.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-22439-AllowNestedGET-paramsInConfiglinkVars.rst new file mode 100644 index 000000000000..9dcbc692558c --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Feature-22439-AllowNestedGET-paramsInConfiglinkVars.rst @@ -0,0 +1,29 @@ +.. include:: ../../Includes.txt + +============================================================ +Feature: #22439 - Allow nested GET-params in config.linkVars +============================================================ + +See :issue:`22439` + +Description +=========== + +TypoScript setting :ts:`config.linkVars` configures which parameters should be passed on with links in TYPO3. +It is now possible to specify nested GET parameters there. + +Example: + +.. code-block:: typoscript + + config.linkVars = L(0-2),tracking|green(0-5) + +With the above configuration the following example GET parameters will be kept: + +&L=1&tracking[green]=3 + +But a get parameter like tracking[blue] will not be kept. + +The value constraint in round brackets works in the same way as for not nested GET parameters. + +.. index:: Frontend, TypoScript, NotScanned diff --git a/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php b/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php index 130be8e37afe..1aa5aeea8a0b 100644 --- a/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php +++ b/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php @@ -2801,29 +2801,49 @@ class TypoScriptFrontendController implements LoggerAwareInterface } $getData = GeneralUtility::_GET(); foreach ($linkVars as $linkVar) { - $test = ($value = ''); + $test = $value = ''; if (preg_match('/^(.*)\\((.+)\\)$/', $linkVar, $match)) { $linkVar = trim($match[1]); $test = trim($match[2]); } - if ($linkVar === '' || !isset($getData[$linkVar])) { + + $keys = explode('|', $linkVar); + $numberOfLevels = count($keys); + $rootKey = trim($keys[0]); + if (!isset($getData[$rootKey])) { continue; } - if (!is_array($getData[$linkVar])) { - $temp = rawurlencode($getData[$linkVar]); - if ($test !== '' && !PageGenerator::isAllowedLinkVarValue($temp, $test)) { - // Error: This value was not allowed for this key - continue; + $value = $getData[$rootKey]; + for ($i = 1; $i < $numberOfLevels; $i++) { + $currentKey = trim($keys[$i]); + if (isset($value[$currentKey])) { + $value = $value[$currentKey]; + } else { + $value = false; + break; } - $value = '&' . $linkVar . '=' . $temp; - } else { - if ($test !== '' && $test !== 'array') { - // Error: This key must not be an array! - continue; + } + if ($value !== false) { + $parameterName = $keys[0]; + for ($i = 1; $i < $numberOfLevels; $i++) { + $parameterName .= '[' . $keys[$i] . ']'; + } + if (!is_array($value)) { + $temp = rawurlencode($value); + if ($test !== '' && !PageGenerator::isAllowedLinkVarValue($temp, $test)) { + // Error: This value was not allowed for this key + continue; + } + $value = '&' . $parameterName . '=' . $temp; + } else { + if ($test !== '' && $test !== 'array') { + // Error: This key must not be an array! + continue; + } + $value = GeneralUtility::implodeArrayForUrl($parameterName, $value); } - $value = GeneralUtility::implodeArrayForUrl($linkVar, $getData[$linkVar]); + $this->linkVars .= $value; } - $this->linkVars .= $value; } } diff --git a/typo3/sysext/frontend/Tests/Unit/Controller/TypoScriptFrontendControllerTest.php b/typo3/sysext/frontend/Tests/Unit/Controller/TypoScriptFrontendControllerTest.php index 9b93c7d55003..250019f06b7f 100644 --- a/typo3/sysext/frontend/Tests/Unit/Controller/TypoScriptFrontendControllerTest.php +++ b/typo3/sysext/frontend/Tests/Unit/Controller/TypoScriptFrontendControllerTest.php @@ -408,4 +408,58 @@ class TypoScriptFrontendControllerTest extends \TYPO3\TestingFramework\Core\Unit ] ]; } + + /** + * @test + * @dataProvider calculateLinkVarsDataProvider + * @param string $linkVars + * @param array $getVars + * @param string $expected + */ + public function calculateLinkVarsConsidersCorrectVariables(string $linkVars, array $getVars, string $expected) + { + $_GET = $getVars; + $this->subject->config['config']['linkVars'] = $linkVars; + $this->subject->calculateLinkVars(); + $this->assertEquals($expected, $this->subject->linkVars); + } + + public function calculateLinkVarsDataProvider() : array + { + return [ + 'simple variable' => [ + 'L', + [ + 'L' => 1 + ], + '&L=1' + ], + 'missing variable' => [ + 'L', + [ + ], + '' + ], + 'restricted variables' => [ + 'L(1-3),bar(3),foo(array),blub(array)', + [ + 'L' => 1, + 'bar' => 2, + 'foo' => [ 1, 2, 'f' => [ 4, 5 ] ], + 'blub' => 123 + ], + '&L=1&foo[0]=1&foo[1]=2&foo[f][0]=4&foo[f][1]=5' + ], + 'nested variables' => [ + 'bar|foo(1-2)', + [ + 'bar' => [ + 'foo' => 1, + 'unused' => 'never' + ] + ], + '&bar[foo]=1' + ], + ]; + } } -- GitLab