[FEATURE] Allow nested GET-parameters for config.linkVars 96/54496/6
authorMarkus Klein <markus.klein@typo3.org>
Sun, 29 Oct 2017 18:35:21 +0000 (19:35 +0100)
committerSusanne Moog <susanne.moog@typo3.org>
Tue, 28 Nov 2017 10:34:36 +0000 (11:34 +0100)
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>
typo3/sysext/core/Documentation/Changelog/master/Feature-22439-AllowNestedGET-paramsInConfiglinkVars.rst [new file with mode: 0644]
typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
typo3/sysext/frontend/Tests/Unit/Controller/TypoScriptFrontendControllerTest.php

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 (file)
index 0000000..9dcbc69
--- /dev/null
@@ -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
index 130be8e..1aa5aee 100644 (file)
@@ -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;
         }
     }
 
index 9b93c7d..250019f 100644 (file)
@@ -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'
+            ],
+        ];
+    }
 }