diff --git a/CHANGELOG-WIP.md b/CHANGELOG-WIP.md index a547181e6f3..8b5f5ab8076 100644 --- a/CHANGELOG-WIP.md +++ b/CHANGELOG-WIP.md @@ -7,6 +7,7 @@ ### Development - Added the `encodeUrl()` Twig function. ([#15838](https://github.com/craftcms/cms/issues/15838)) - Added support for passing aliased field handles into element queries’ `select()`/`addSelect()` methods. ([#15827](https://github.com/craftcms/cms/issues/15827)) +- Added support for appending subpaths to environment variable names in environmental settings (e.g. `$PRIMARY_SITE_URL/uploads`). ### Extensibility - Added `craft\base\RequestTrait::getIsWebRequest()`. ([#15690](https://github.com/craftcms/cms/pull/15690)) diff --git a/src/helpers/App.php b/src/helpers/App.php index 2ec83f1c2ee..d10f5acfdcd 100644 --- a/src/helpers/App.php +++ b/src/helpers/App.php @@ -194,7 +194,7 @@ public static function parseEnv(?string $value): bool|string|null return null; } - if (preg_match('/^\$(\w+)$/', $value, $matches)) { + if (preg_match('/^\$(\w+)(\/.*)?/', $value, $matches)) { $env = static::env($matches[1]); if ($env === null) { @@ -202,7 +202,7 @@ public static function parseEnv(?string $value): bool|string|null return $value; } - $value = $env; + $value = $env . ($matches[2] ?? ''); } if (is_string($value) && str_starts_with($value, '@')) { diff --git a/src/helpers/Cp.php b/src/helpers/Cp.php index f0f791c41fa..f7f7eb8b70b 100644 --- a/src/helpers/Cp.php +++ b/src/helpers/Cp.php @@ -1102,9 +1102,9 @@ public static function autosuggestFieldHtml(array $config): string $value = $config['value'] ?? ''; if (!isset($config['tip']) && (!isset($value[0]) || !in_array($value[0], ['$', '@']))) { if ($config['suggestAliases'] ?? false) { - $config['tip'] = Craft::t('app', 'This can be set to an environment variable, or begin with an alias.'); + $config['tip'] = Craft::t('app', 'This can begin with an environment variable or alias.'); } else { - $config['tip'] = Craft::t('app', 'This can be set to an environment variable.'); + $config['tip'] = Craft::t('app', 'This can begin with an environment variable.'); } $config['tip'] .= ' ' . Html::a(Craft::t('app', 'Learn more'), 'https://craftcms.com/docs/4.x/config#control-panel-settings', [ diff --git a/src/templates/_includes/forms.twig b/src/templates/_includes/forms.twig index c22f7b215cc..4be3c09036d 100644 --- a/src/templates/_includes/forms.twig +++ b/src/templates/_includes/forms.twig @@ -232,7 +232,7 @@ {% set config = config|merge({ tip: (config.allowedEnvValues is not defined) ? 'This can be set to an environment variable matching one of the option values.'|t('app') - : 'This can be set to an environment variable.'|t('app'), + : 'This can begin with an environment variable.'|t('app'), }) %} {% endif %} {{ _self.field(config, 'template:_includes/forms/selectize') }} @@ -324,8 +324,8 @@ {% if config.tip is not defined and value[0:1] not in ['$', '@'] %} {% set config = config|merge({ tip: ((config.suggestAliases ?? false) - ? 'This can be set to an environment variable, or begin with an alias.'|t('app') - : 'This can be set to an environment variable.'|t('app')) ~ ' ' ~ tag('a', { + ? 'This can begin with an environment variable or alias.'|t('app') + : 'This can begin with an environment variable.'|t('app')) ~ ' ' ~ tag('a', { href: 'https://craftcms.com/docs/4.x/config/#control-panel-settings', class: 'go', text: 'Learn more'|t('app'), diff --git a/src/translations/en/app.php b/src/translations/en/app.php index 39af1f38b2d..1c3477bdf03 100644 --- a/src/translations/en/app.php +++ b/src/translations/en/app.php @@ -1547,8 +1547,8 @@ 'This can be set to an environment variable with a boolean value ({examples}).' => 'This can be set to an environment variable with a boolean value ({examples}).', 'This can be set to an environment variable with a value of a [supported time zone]({url}).' => 'This can be set to an environment variable with a value of a [supported time zone]({url}).', 'This can be set to an environment variable, or a Twig template that outputs an ID.' => 'This can be set to an environment variable, or a Twig template that outputs an ID.', - 'This can be set to an environment variable, or begin with an alias.' => 'This can be set to an environment variable, or begin with an alias.', - 'This can be set to an environment variable.' => 'This can be set to an environment variable.', + 'This can begin with an environment variable or alias.' => 'This can begin with an environment variable or alias.', + 'This can begin with an environment variable.' => 'This can begin with an environment variable.', 'This element is conditional' => 'This element is conditional', 'This field has been modified.' => 'This field has been modified.', 'This field is conditional' => 'This field is conditional', diff --git a/tests/unit/helpers/AppHelperTest.php b/tests/unit/helpers/AppHelperTest.php index 2ad35323915..5e996fffbf9 100644 --- a/tests/unit/helpers/AppHelperTest.php +++ b/tests/unit/helpers/AppHelperTest.php @@ -93,9 +93,10 @@ public function testParseEnv(): void { self::assertNull(App::parseEnv(null)); self::assertSame(CRAFT_TESTS_PATH, App::parseEnv('$CRAFT_TESTS_PATH')); + self::assertSame(CRAFT_TESTS_PATH . '/foo/bar', App::parseEnv('$CRAFT_TESTS_PATH/foo/bar')); self::assertSame('CRAFT_TESTS_PATH', App::parseEnv('CRAFT_TESTS_PATH')); self::assertSame('$TEST_MISSING', App::parseEnv('$TEST_MISSING')); - self::assertSame(Craft::getAlias('@vendor/foo'), App::parseEnv('@vendor/foo')); + self::assertSame(Craft::getAlias('@vendor/foo/bar'), App::parseEnv('@vendor/foo/bar')); } /**