Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion .github/workflows/cypress.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,17 @@ jobs:
autostart: false

# install DDEV configuration
- run: ddev config --project-type=magento --php-version=8.1 --webserver-type=${{ matrix.webserver }} --web-environment="MAGE_IS_DEVELOPER_MODE=1"
- run: ddev config \
--project-type=magento \
--php-version=8.1 \
--webserver-type=${{ matrix.webserver }} \
--web-environment="\
MAGE_IS_DEVELOPER_MODE=1,\
OPENMAGE_CONFIG_OVERRIDE_ALLOWED=1,\
OPENMAGE_CONFIG__DEFAULT__GENERAL__STORE_INFORMATION__NAME=ENV name default,\
OPENMAGE_CONFIG__WEBSITES__BASE__GENERAL__STORE_INFORMATION__PHONE=ENV phone website,\
OPENMAGE_CONFIG__STORES__GERMAN__GENERAL__STORE_INFORMATION__ADDRESS=ENV address store\
"

# install composer dependencies
- run: ddev composer install
Expand Down
18 changes: 13 additions & 5 deletions app/code/core/Mage/Adminhtml/Block/System/Config/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class Mage_Adminhtml_Block_System_Config_Form extends Mage_Adminhtml_Block_Widge

public const SCOPE_STORES = 'stores';

public const SCOPE_ENV = 'env';
public const SCOPE_ENV = 'env';

/**
* Config data array
Expand Down Expand Up @@ -663,14 +663,22 @@ public function isOverwrittenByEnvVariable(string $path): bool
{
/** @var Mage_Core_Helper_EnvironmentConfigLoader $environmentConfigLoaderHelper */
$environmentConfigLoaderHelper = Mage::helper('core/environmentConfigLoader');
$store = Mage::app()->getRequest()->getParam('store');
if ($store) {
$scope = $this->getScope();

$scope = $this->getScope();
$store = Mage::app()->getRequest()->getParam('store');
$website = Mage::app()->getRequest()->getParam('website');

if ($store && $website) {
$path = "$scope/$store/$path";
return $environmentConfigLoaderHelper->hasPath($path);
}

$path = "default/$path";
if ($website) {
$path = "$scope/$website/$path";
return $environmentConfigLoaderHelper->hasPath($path);
}

$path = "$scope/$path";
return $environmentConfigLoaderHelper->hasPath($path);
}

Expand Down
198 changes: 134 additions & 64 deletions app/code/core/Mage/Core/Helper/EnvironmentConfigLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,8 @@ class Mage_Core_Helper_EnvironmentConfigLoader extends Mage_Core_Helper_Abstract
* @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
*
* @return void
* @throws Mage_Core_Exception
*/
public function overrideEnvironment(Varien_Simplexml_Config $xmlConfig)
public function overrideEnvironment(Varien_Simplexml_Config $xmlConfig): void
{
$data = Mage::registry(self::REGISTRY_KEY);
if ($data) {
Expand All @@ -77,20 +74,27 @@ public function overrideEnvironment(Varien_Simplexml_Config $xmlConfig)
continue;
}

[$configKeyParts, $scope] = $this->getConfigKey($configKey);
$override = $this->getConfigKey($configKey);
$scope = $override->getScope();
$storeCode = $override->getStoreCode();

$path = $this->buildPath($override->getSection(), $override->getGroup(), $override->getField());

switch ($scope) {
case self::CONFIG_KEY_DEFAULT:
[$section, $group, $field] = $configKeyParts;
$path = $this->buildPath($section, $group, $field);
$nodePath = $this->buildNodePath($scope, $path);
$xmlConfig->setNode($nodePath, $value);
try {
foreach (['0', 'admin'] as $store) {
$store = Mage::app()->getStore($store);
if ($store instanceof Mage_Core_Model_Store) {
$this->setCache($store, $value, $path);
}
$store = Mage::app()->getStore(Mage_Core_Model_Store::ADMIN_CODE);
if ($store instanceof Mage_Core_Model_Store) {
$nodePath = $this->buildNodePath($scope, $path, $storeCode);
$xmlConfig->setNode($nodePath, $value);
$this->setCache($store, $value, $path);
}

$stores = Mage::app()->getStores(withDefault: true);
foreach ($stores as $store) {
$nodePath = $this->buildNodePath(self::CONFIG_KEY_STORES, $path, $store->getCode());
$xmlConfig->setNode($nodePath, $value);
$this->setCache($store, $value, $path);
}
} catch (Throwable) {
// invalid store, intentionally empty
Expand All @@ -99,18 +103,21 @@ public function overrideEnvironment(Varien_Simplexml_Config $xmlConfig)
break;

case self::CONFIG_KEY_WEBSITES:
case self::CONFIG_KEY_STORES:
[$storeCode, $section, $group, $field] = $configKeyParts;
$path = $this->buildPath($section, $group, $field);
$storeCode = strtolower($storeCode);
$scope = strtolower($scope);
$nodePath = sprintf('%s/%s/%s', $scope, $storeCode, $path);
$xmlConfig->setNode($nodePath, $value);
try {
if (!str_contains($nodePath, 'websites')) {
foreach ([$storeCode, 'admin'] as $store) {
$store = Mage::app()->getStore($store);
if ($store instanceof Mage_Core_Model_Store) {
$websites = Mage::app()->getWebsites();
foreach ($websites as $website) {
if (strtolower($website->getCode()) !== strtolower($storeCode)) {
continue;
}

$nodePath = $this->buildNodePath($scope, $path, $storeCode);
$xmlConfig->setNode($nodePath, $value);

$stores = $website->getStores();
foreach ($stores as $store) {
if ($store instanceof Mage_Core_Model_Store && $store->getId()) {
$nodePath = $this->buildNodePath(self::CONFIG_KEY_STORES, $path, $store->getCode());
$xmlConfig->setNode($nodePath, $value);
$this->setCache($store, $value, $path);
}
}
Expand All @@ -119,16 +126,35 @@ public function overrideEnvironment(Varien_Simplexml_Config $xmlConfig)
// invalid store, intentionally empty
}

break;

case self::CONFIG_KEY_STORES:
try {
$stores = Mage::app()->getStores();
foreach ($stores as $store) {
if (strtolower($store->getCode()) !== strtolower($storeCode)) {
continue;
}

$nodePath = $this->buildNodePath($scope, $path, $store->getCode());
$xmlConfig->setNode($nodePath, $value);
$this->setCache($store, $value, $path);
}
} catch (Throwable) {
// invalid store, intentionally empty
}

break;
}
}

Mage::register(self::REGISTRY_KEY, true, true);
try {
Mage::register(self::REGISTRY_KEY, true, true);
} catch (Mage_Core_Exception $mageCoreException) {
Mage::logException($mageCoreException);
}
}

/**
* @throws Mage_Core_Exception
*/
public function hasPath(string $wantedPath): bool
{
/** @var bool|null $data */
Expand All @@ -145,36 +171,78 @@ public function hasPath(string $wantedPath): bool
continue;
}

[$configKeyParts, $scope] = $this->getConfigKey($configKey);
$override = $this->getConfigKey($configKey);
$scope = $override->getScope();
$path = $this->buildPath($override->getSection(), $override->getGroup(), $override->getField());

switch ($scope) {
case self::CONFIG_KEY_DEFAULT:
[$section, $group, $field] = $configKeyParts;
$path = $this->buildPath($section, $group, $field);
$nodePath = $this->buildNodePath($scope, $path);
$config[$nodePath] = $value;

try {
$websites = Mage::app()->getWebsites();
foreach ($websites as $website) {
$nodePath = $this->buildNodePath(self::CONFIG_KEY_WEBSITES, $path, $website->getCode());
$config[$nodePath] = $value;
}

$stores = Mage::app()->getStores(withDefault: true);
foreach ($stores as $store) {
$nodePath = $this->buildNodePath(self::CONFIG_KEY_STORES, $path, $store->getCode());
$config[$nodePath] = $value;
}
} catch (Throwable) {
// invalid store, intentionally empty
}

break;

case self::CONFIG_KEY_WEBSITES:
try {
$websites = Mage::app()->getWebsites();
foreach ($websites as $website) {
if (strtolower($website->getCode()) !== strtolower($override->getStoreCode())) {
continue;
}

$nodePath = $this->buildNodePath($scope, $path, $website->getCode());
$config[$nodePath] = $value;

$stores = $website->getStores();
foreach ($stores as $store) {
if ($store instanceof Mage_Core_Model_Store && $store->getId()) {
$nodePath = $this->buildNodePath(self::CONFIG_KEY_STORES, $path, $store->getCode());
$config[$nodePath] = $value;
}
}
}
} catch (Throwable) {
// invalid store, intentionally empty
}

break;
case self::CONFIG_KEY_STORES:
[$storeCode, $section, $group, $field] = $configKeyParts;
$path = $this->buildPath($section, $group, $field);
$storeCode = strtolower($storeCode);
$scope = strtolower($scope);
$nodePath = sprintf('%s/%s/%s', $scope, $storeCode, $path);
$nodePath = $this->buildNodePath($scope, $path, $override->getStoreCode());
$config[$nodePath] = $value;

break;
}
}

$hasConfig = array_key_exists($wantedPath, $config);
Mage::register("config_env_has_path_$wantedPath", $hasConfig);

try {
Mage::register("config_env_has_path_$wantedPath", $hasConfig);
} catch (Mage_Core_Exception $mageCoreException) {
Mage::logException($mageCoreException);
}

return $hasConfig;
}

/**
* @return array<string, string>
* @throws Mage_Core_Exception
*/
public function getAsArray(string $wantedStore): array
{
Expand All @@ -196,28 +264,30 @@ public function getAsArray(string $wantedStore): array
continue;
}

[$configKeyParts, $scope] = $this->getConfigKey($configKey);
$override = $this->getConfigKey($configKey);
$path = $this->buildPath($override->getSection(), $override->getGroup(), $override->getField());

switch ($scope) {
switch ($override->getScope()) {
case self::CONFIG_KEY_DEFAULT:
[$section, $group, $field] = $configKeyParts;
$path = $this->buildPath($section, $group, $field);
$config[$path] = $value;
break;
case self::CONFIG_KEY_WEBSITES:
case self::CONFIG_KEY_STORES:
[$storeCode, $section, $group, $field] = $configKeyParts;
if (strtolower($storeCode) !== strtolower($wantedStore)) {
if (strtolower($override->getStoreCode()) !== strtolower($wantedStore)) {
break;
}

$path = $this->buildPath($section, $group, $field);
$config[$path] = $value;
break;
}
}

Mage::register("config_env_array_$wantedStore", $config);
try {
Mage::register("config_env_array_$wantedStore", $config);
} catch (Mage_Core_Exception $mageCoreException) {
Mage::logException($mageCoreException);
}

return $config;
}

Expand Down Expand Up @@ -257,7 +327,6 @@ protected function setCache(Mage_Core_Model_Store $store, string $value, string
{
$refObject = new ReflectionObject($store);
$refProperty = $refObject->getProperty('_configCache');
$refProperty->setAccessible(true);

$configCache = $refProperty->getValue($store);
if (!is_array($configCache)) {
Expand All @@ -268,11 +337,7 @@ protected function setCache(Mage_Core_Model_Store $store, string $value, string
$store->setConfigCache($configCache);
}

/**
* @return array{array<int, string>, string}
* @throws Mage_Core_Exception
*/
protected function getConfigKey(string $configKey): array
protected function getConfigKey(string $configKey): Mage_Core_Helper_EnvironmentConfigLoader_Override
{
$configKeyParts = array_filter(
explode(
Expand All @@ -282,17 +347,22 @@ protected function getConfigKey(string $configKey): array
trim(...),
);

unset($configKeyParts[0]);

/** @var string $scope */
$scope = array_shift($configKeyParts);

return [$configKeyParts, $scope];
$scope = $configKeyParts[1];
$isDefault = $scope === self::CONFIG_KEY_DEFAULT;
$storeCode = $isDefault ? '' : $configKeyParts[2];
$section = $isDefault ? $configKeyParts[2] : $configKeyParts[3];
$group = $isDefault ? $configKeyParts[3] : $configKeyParts[4];
$field = $isDefault ? $configKeyParts[4] : $configKeyParts[5];

return new Mage_Core_Helper_EnvironmentConfigLoader_Override(
scope: $scope,
section: $section,
group: $group,
field: $field,
storeCode: $storeCode,
);
}

/**
* @throws Mage_Core_Exception
*/
protected function isConfigKeyValid(string $configKey): bool
{
$sectionGroupFieldRegexp = sprintf('([%s]*)', implode('', self::ALLOWED_CHARS));
Expand All @@ -318,8 +388,8 @@ protected function buildPath(string $section, string $group, string $field): str
/**
* Build configuration node path.
*/
protected function buildNodePath(string $scope, string $path): string
protected function buildNodePath(string $scope, string $path, string $storeCode = ''): string
{
return strtolower($scope) . '/' . $path;
return strtolower($scope) . ($storeCode ? '/' . strtolower($storeCode) : '') . '/' . $path;
}
}
Loading
Loading