-
-
Notifications
You must be signed in to change notification settings - Fork 436
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
27 changed files
with
1,195 additions
and
271 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
158 changes: 158 additions & 0 deletions
158
app/code/core/Mage/Core/Helper/EnvironmentConfigLoader.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
<?php | ||
/** | ||
* OpenMage | ||
* | ||
* This source file is subject to the Open Software License (OSL 3.0) | ||
* that is bundled with this package in the file LICENSE.txt. | ||
* It is also available at https://opensource.org/license/osl-3-0-php | ||
* | ||
* @category Mage | ||
* @package Mage_Core | ||
* @copyright Copyright (c) 2024 The OpenMage Contributors (https://www.openmage.org) | ||
* @license https://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) | ||
*/ | ||
|
||
/** | ||
* Core Environment helper | ||
* | ||
* @category Mage | ||
* @package Mage_Core | ||
*/ | ||
class Mage_Core_Helper_EnvironmentConfigLoader extends Mage_Core_Helper_Abstract | ||
{ | ||
protected const ENV_STARTS_WITH = 'OPENMAGE_CONFIG'; | ||
protected const ENV_KEY_SEPARATOR = '__'; | ||
protected const CONFIG_KEY_DEFAULT = 'DEFAULT'; | ||
protected const CONFIG_KEY_WEBSITES = 'WEBSITES'; | ||
protected const CONFIG_KEY_STORES = 'STORES'; | ||
/** | ||
* To be used as regex condition | ||
*/ | ||
protected const ALLOWED_CHARS = ['A-Z', '-', '_']; | ||
protected $_moduleName = 'Mage_Core'; | ||
protected array $envStore = []; | ||
|
||
/** | ||
* Load configuration values from ENV variables into xml config object | ||
* | ||
* Environment variables work on this schema: | ||
* | ||
* self::ENV_STARTS_WITH . self::ENV_KEY_SEPARATOR (OPENMAGE_CONFIG__) | ||
* ^ Prefix (required) | ||
* <SCOPE>__ | ||
* ^ Where scope is DEFAULT, WEBSITES__<WEBSITE_CODE> or STORES__<STORE_CODE> | ||
* <SYSTEM_VARIABLE_NAME> | ||
* ^ Where GROUP, SECTION and FIELD are separated by self::ENV_KEY_SEPARATOR | ||
* | ||
* Each example will override the 'general/store_information/name' value. | ||
* Override from the default configuration: | ||
* @example OPENMAGE_CONFIG__DEFAULT__GENERAL__STORE_INFORMATION__NAME=default | ||
* Override the website 'base' configuration: | ||
* @example OPENMAGE_CONFIG__WEBSITES__BASE__GENERAL__STORE_INFORMATION__NAME=website | ||
* Override the store 'german' configuration: | ||
* @example OPENMAGE_CONFIG__STORES__GERMAN__GENERAL__STORE_INFORMATION__NAME=store_german | ||
* | ||
* @param Varien_Simplexml_Config $xmlConfig | ||
* @return void | ||
*/ | ||
public function overrideEnvironment(Varien_Simplexml_Config $xmlConfig) | ||
{ | ||
$env = $this->getEnv(); | ||
|
||
foreach ($env as $configKey => $value) { | ||
if (!$this->isConfigKeyValid($configKey)) { | ||
continue; | ||
} | ||
|
||
list($configKeyParts, $scope) = $this->getConfigKey($configKey); | ||
|
||
switch ($scope) { | ||
case static::CONFIG_KEY_DEFAULT: | ||
list($_, $_, $section, $group, $field) = $configKeyParts; | ||
$path = $this->buildPath($section, $group, $field); | ||
$xmlConfig->setNode($this->buildNodePath($scope, $path), $value); | ||
break; | ||
|
||
case static::CONFIG_KEY_WEBSITES: | ||
case static::CONFIG_KEY_STORES: | ||
list($_, $_, $code, $section, $group, $field) = $configKeyParts; | ||
$path = $this->buildPath($section, $group, $field); | ||
$nodePath = sprintf('%s/%s/%s', strtolower($scope), strtolower($code), $path); | ||
$xmlConfig->setNode($nodePath, $value); | ||
break; | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @internal method mostly for mocking | ||
*/ | ||
public function setEnvStore(array $envStorage): void | ||
{ | ||
$this->envStore = $envStorage; | ||
} | ||
|
||
public function getEnv(): array | ||
{ | ||
if (empty($this->envStore)) { | ||
$this->envStore = getenv(); | ||
} | ||
return $this->envStore; | ||
} | ||
|
||
protected function getConfigKey(string $configKey): array | ||
{ | ||
$configKeyParts = array_filter( | ||
explode( | ||
static::ENV_KEY_SEPARATOR, | ||
$configKey | ||
), | ||
'trim' | ||
); | ||
list($_, $scope) = $configKeyParts; | ||
return array($configKeyParts, $scope); | ||
} | ||
|
||
protected function isConfigKeyValid(string $configKey): bool | ||
{ | ||
if (!str_starts_with($configKey, static::ENV_STARTS_WITH)) { | ||
return false; | ||
} | ||
|
||
$sectionGroupFieldRegexp = sprintf('([%s]*)', implode('', static::ALLOWED_CHARS)); | ||
$allowedChars = sprintf('[%s]', implode('', static::ALLOWED_CHARS)); | ||
$regexp = '/' . static::ENV_STARTS_WITH . static::ENV_KEY_SEPARATOR . '(WEBSITES' . static::ENV_KEY_SEPARATOR | ||
. $allowedChars . '+|DEFAULT|STORES' . static::ENV_KEY_SEPARATOR . $allowedChars . '+)' | ||
. static::ENV_KEY_SEPARATOR . $sectionGroupFieldRegexp | ||
. static::ENV_KEY_SEPARATOR . $sectionGroupFieldRegexp | ||
. static::ENV_KEY_SEPARATOR . $sectionGroupFieldRegexp . '/'; | ||
// /OPENMAGE_CONFIG__(WEBSITES__[A-Z-_]+|DEFAULT|STORES__[A-Z-_]+)__([A-Z-_]*)__([A-Z-_]*)__([A-Z-_]*)/ | ||
|
||
return preg_match($regexp, $configKey); | ||
} | ||
|
||
/** | ||
* Build configuration path. | ||
* | ||
* @param string $section | ||
* @param string $group | ||
* @param string $field | ||
* @return string | ||
*/ | ||
protected function buildPath(string $section, string $group, string $field): string | ||
{ | ||
return strtolower(implode('/', [$section, $group, $field])); | ||
} | ||
|
||
/** | ||
* Build configuration node path. | ||
* | ||
* @param string $scope | ||
* @param string $path | ||
* @return string | ||
*/ | ||
protected function buildNodePath(string $scope, string $path): string | ||
{ | ||
return strtolower($scope) . '/' . $path; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.