[FEATURE] Add getEnv value modifier to TS parser 15/57115/4
authorFelix Althaus <felix.althaus@undkonsorten.com>
Sun, 3 Jun 2018 14:07:52 +0000 (16:07 +0200)
committerAndreas Wolf <andreas.wolf@typo3.org>
Wed, 18 Jul 2018 17:46:58 +0000 (19:46 +0200)
Use :=getEnv() in TypoScript to read values from environment variables.

Resolves: #85146
Releases: master
Change-Id: I6c480627e4b07f76f4d8887df0db9d95fd75e6d9
Reviewed-on: https://review.typo3.org/57115
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Hannes Lau <office@hanneslau.de>
Tested-by: Hannes Lau <office@hanneslau.de>
Reviewed-by: Jörg Bösche <typo3@joergboesche.de>
Tested-by: Jörg Bösche <typo3@joergboesche.de>
Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: Andreas Wolf <andreas.wolf@typo3.org>
Tested-by: Andreas Wolf <andreas.wolf@typo3.org>
typo3/sysext/core/Classes/TypoScript/Parser/TypoScriptParser.php
typo3/sysext/core/Documentation/Changelog/master/Feature-85146-ReadEnvironmentVariablesInTypoScript.rst [new file with mode: 0644]
typo3/sysext/core/Tests/Unit/TypoScript/Parser/TypoScriptParserTest.php

index 3efe7f8..f58422e 100644 (file)
@@ -527,7 +527,7 @@ class TypoScriptParser
      * @param string $modifierName TypoScript function called
      * @param string $modifierArgument Function arguments; In case of multiple arguments, the method must split on its own
      * @param string $currentValue Current TypoScript value
-     * @return string Modification result
+     * @return string|null Modified result or null for no modification
      */
     protected function executeValueModifier($modifierName, $modifierArgument = null, $currentValue = null)
     {
@@ -589,6 +589,12 @@ class TypoScriptParser
                 }
                 $newValue = implode(',', $elements);
                 break;
+            case 'getEnv':
+                $environmentValue = getenv(trim($modifierArgument));
+                if ($environmentValue !== false) {
+                    $newValue = $environmentValue;
+                }
+                break;
             default:
                 if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsparser.php']['preParseFunc'][$modifierName])) {
                     $hookMethod = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsparser.php']['preParseFunc'][$modifierName];
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-85146-ReadEnvironmentVariablesInTypoScript.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-85146-ReadEnvironmentVariablesInTypoScript.rst
new file mode 100644 (file)
index 0000000..cf3c4e9
--- /dev/null
@@ -0,0 +1,35 @@
+.. include:: ../../Includes.txt
+
+==========================================================
+Feature: #85146 - Read environment variables in TypoScript
+==========================================================
+
+See :issue:`85146`
+
+Description
+===========
+
+There is a new TypoScript value modifier `getEnv()`. The modifier checks if the variable given as its argument is set
+and reads the value if so, overriding any existing value. If the environment variable is not set, the variable given on
+the left-hand side of the expression is not changed.
+
+
+Impact
+======
+
+Write a TypoScript statement like this to use environment values in your TypoScript:
+
+.. code-block:: typoscript
+
+    # Define default value
+    myConstant = defaultValue
+    # Enable overriding by environment variable
+    myConstant := getEnv(TS_MYCONSTANT)
+
+To have a value actually inserted, your PHP execution environment (webserver, PHP-FPM) needs to have these variables
+set, or you need a mechanism like dotenv to set them in your running TYPO3.
+
+As it is a syntax feature you can use it in both constants and setup plus it gets cached, as opposed to the getText
+`getenv` feature.
+
+.. index:: TypoScript, ext:core
index a76f240..c922b68 100644 (file)
@@ -261,6 +261,77 @@ class TypoScriptParserTest extends UnitTestCase
         $this->assertEquals($expected, $actualValue);
     }
 
+    public function executeGetEnvModifierDataProvider(): array
+    {
+        return [
+            'environment variable not set' => [
+                [],
+                'bar',
+                'FOO',
+                null,
+            ],
+            'empty environment variable' => [
+                ['FOO' => ''],
+                'bar',
+                'FOO',
+                '',
+            ],
+            'empty current value' => [
+                ['FOO' => 'baz'],
+                null,
+                'FOO',
+                'baz',
+            ],
+            'environment variable and current value set' => [
+                ['FOO' => 'baz'],
+                'bar',
+                'FOO',
+                'baz',
+            ],
+            'neither environment variable nor current value set' => [
+                [],
+                null,
+                'FOO',
+                null,
+            ],
+            'empty environment variable name' => [
+                ['FOO' => 'baz'],
+                'bar',
+                '',
+                null,
+            ],
+        ];
+    }
+
+    /**
+     * @test
+     * @dataProvider executeGetEnvModifierDataProvider
+     * @param string $modifierName
+     * @param string $currentValue
+     * @param string $modifierArgument
+     * @param string $expected
+     */
+    public function executeGetEnvModifierReturnsModifiedResult(
+        array $environmentVariables,
+        ?string $currentValue,
+        string $modifierArgument,
+        ?string $expected
+    ): void {
+        foreach ($environmentVariables as $environmentVariable => $value) {
+            putenv($environmentVariable . '=' . $value);
+        }
+        $actualValue = $this->typoScriptParser->_call(
+            'executeValueModifier',
+            'getEnv',
+            $modifierArgument,
+            $currentValue
+        );
+        $this->assertEquals($expected, $actualValue);
+        foreach ($environmentVariables as $environmentVariable => $_) {
+            putenv($environmentVariable);
+        }
+    }
+
     /**
      * Data provider for executeValueModifierThrowsException
      *