Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Environment based local.xml merging #41

Closed
wants to merge 1 commit into from

3 participants

@Vinai

Support merging an additional local.xml file based on the value of
the MAGE_APPLICATION_ENV environment variable.
The name of the file will be built as follows:

'app/etc/local.' . $_SERVER['MAGE_APPLICATION_ENV'] . '.xml'

The value of the variable is checked to contain only letters,
characters, underscores and dashes.
The file will be merged after the regular local.xml file.

The background idea is described by Matthias Zeis at
#7

@Vinai Vinai Environment based local.xml merging
Support merging an additional local.xml file based on the value of
the MAGE_APPLICATION_ENV environment variable.
The name of the file will be built as follows:

'app/etc/local.' . $_SERVER['MAGE_APPLICATION_ENV'] . '.xml'

The value of the variable is checked to contain only letters,
characters, underscores and dashes.
The file will be merged after the regular local.xml file.

The background idea is described by Matthias Zeis at
magento/magento2#7
a60099d
@mzeis

Thanks Vinai for the implementation.

I tested these scenarios successfully:

  • use a different adminhtml frontName
  • use a different database name

If somebody wants to try this, follow these steps:

  • clone Vinais repository (https://github.com/Vinai/magento2.git) and checkout branch local.xml-override
  • install Magento
  • disable caches (this one is important as the config will be cached)
  • add MAGE_APPLICATION_ENV to your vHost config or .htaccess
    • e.g. SetEnv MAGE_APPLICATION_ENV dev
    • If you use .htaccess, edit the file in the Magento root directory, not pub/.htaccess
  • add your environment local.xml (e.g. local.dev.xml) and override the settings you want to test
@mage2-team
Collaborator

Instead of applying the proposed patch, we have implemented it in different way.

Most of modifications will be concentrated in loadBase() method. New algorithm:
1. Scan app/etc directory for all files with .xml extension
2. Merge all the found files, except local.xml, in alphabetical order
3. If the local.xml is found – merge it after all the files
4. If the configuration option (Mage_Core_Model_Config_Options) "local_config" is provided (originates from MAGE_LOCAL_CONFIG environment variable), assess if it matches pattern and load additional file:

  • Pattern: alphanumeric or dash or underscore, then "/", then again alphanumeric or dash or underscore, then ".xml"
  • The file will be loaded only if local.xml has been loaded. If local.xml doesn't exist, the file will not be loaded.
  • If the declared file not found, it will be skipped.

This change will be rolled out in one of next updates.
Thank you for the idea and actual suggested implementation.

@mage2-team mage2-team closed this
@Vinai

Thank you for the detailed answer!
The patch isn't in the current version of github yet, is it?
I like the idea of MAGE_LOCAL_CONFIG to configure config options, but is it possible to specify an php array using, lets say apache mod_env?

@mage2-team mage2-team referenced this pull request from a commit
@mage2-team mage2-team Update as of 8/1/2012
* Refactored ACL for the backend
  * ACL resources
    * Strict configuration format, validated by XSD schema
    * ACL configuration relocation from `app/code/<pool>/<namespace>/<module>/etc/adminhtml.xml` to `app/code/<pool>/<namespace>/<module>/etc/adminhtml/acl.xml`
    * Renamed ACL resource identifiers according to the format `<namespace>_<module>::<resource>` throughout the system
      * Backend menu configuration requires to specify ACL resource identifier in the new format
      * Explicit declaration of ACL resources in `app/code/<pool>/<namespace>/<module>/etc/system.xml` instead of implicit relation by XPath
    * Migration tool `dev/tools/migration/acl.php` to convert ACL configuration from 1.x to 2.x
  * Declaration of ACL resource/role/rule loaders through the area configuration
    * Module `Mage_Backend` declares loader for ACL resources in backend area
    * Module `Mage_User` declares loaders for ACL roles and rules (relations between roles and resources) in backend area
  * Implemented integrity and legacy tests for ACL
* Fixed issues:
  * Losing qty and visibility information when importing products
  * Impossibility to reload captcha on backend
  * Temporary excluded from execution integration test `Mage_Review_Model_Resource_Review_Product_CollectionTest::testGetResultingIds()` and corresponding fixture script, which cause occasional `segmentation fault` (exit code 139)
* Refactored methods with high cyclomatic complexity:
  * `Mage_Adminhtml_Block_System_Store_Edit_Form::_prepareForm()`
  * `Mage_Adminhtml_Block_System_Config_Form::initForm()`
  * `Mage_Adminhtml_Block_System_Config_Form::initFields()`
* GitHub requests:
  * [#32](#32) -- fixed declaration of localization CSV files
  * [#35](#35) -- removed non-used `Mage_Core_Block_Flush` block
  * [#41](#41) -- implemented ability to extends `app/etc/local.xml` by specifying additional config file via `MAGE_LOCAL_CONFIG` environment variable
7fec10a
@mage2-team mage2-team referenced this pull request from a commit
@mage2-team mage2-team Update as of 8/2/2012
* Refactored ACL for the backend
  * ACL resources
    * Strict configuration format, validated by XSD schema
    * ACL configuration relocation from `app/code/<pool>/<namespace>/<module>/etc/adminhtml.xml` to `app/code/<pool>/<namespace>/<module>/etc/adminhtml/acl.xml`
    * Renamed ACL resource identifiers according to the format `<namespace>_<module>::<resource>` throughout the system
      * Backend menu configuration requires to specify ACL resource identifier in the new format
      * Explicit declaration of ACL resources in `app/code/<pool>/<namespace>/<module>/etc/system.xml` instead of implicit relation by XPath
    * Migration tool `dev/tools/migration/acl.php` to convert ACL configuration from 1.x to 2.x
  * Declaration of ACL resource/role/rule loaders through the area configuration
    * Module `Mage_Backend` declares loader for ACL resources in backend area
    * Module `Mage_User` declares loaders for ACL roles and rules (relations between roles and resources) in backend area
  * Implemented integrity and legacy tests for ACL
* Fixed issues:
  * Losing qty and visibility information when importing products
  * Impossibility to reload captcha on backend
  * Temporary excluded from execution integration test `Mage_Review_Model_Resource_Review_Product_CollectionTest::testGetResultingIds()` and corresponding fixture script, which cause occasional `segmentation fault` (exit code 139)
* Refactored methods with high cyclomatic complexity:
  * `Mage_Adminhtml_Block_System_Store_Edit_Form::_prepareForm()`
  * `Mage_Adminhtml_Block_System_Config_Form::initForm()`
  * `Mage_Adminhtml_Block_System_Config_Form::initFields()`
* GitHub requests:
  * [#32](#32) -- fixed declaration of localization CSV files
  * [#35](#35) -- removed non-used `Mage_Core_Block_Flush` block
  * [#41](#41) -- implemented ability to extends `app/etc/local.xml` by specifying additional config file via `MAGE_LOCAL_CONFIG` environment variable
b370593
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 11, 2012
  1. @Vinai

    Environment based local.xml merging

    Vinai authored
    Support merging an additional local.xml file based on the value of
    the MAGE_APPLICATION_ENV environment variable.
    The name of the file will be built as follows:
    
    'app/etc/local.' . $_SERVER['MAGE_APPLICATION_ENV'] . '.xml'
    
    The value of the variable is checked to contain only letters,
    characters, underscores and dashes.
    The file will be merged after the regular local.xml file.
    
    The background idea is described by Matthias Zeis at
    magento/magento2#7
This page is out of date. Refresh to see the latest.
Showing with 112 additions and 18 deletions.
  1. +112 −18 app/code/core/Mage/Core/Model/Config.php
View
130 app/code/core/Mage/Core/Model/Config.php
@@ -48,7 +48,7 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
* array(
* $sectionName => $recursionLevel
* )
- * Recursion level provide availability cache subnodes separatly
+ * Recursion level provide availability cache subnodes separately
*
* @var array
*/
@@ -147,7 +147,7 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
protected $_cachePartsForSave = array();
/**
- * Empty configuration object for loading and megring configuration parts
+ * Empty configuration object for loading and merging configuration parts
*
* @var Mage_Core_Model_Config_Base
*/
@@ -161,6 +161,20 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
protected $_isLocalConfigLoaded = false;
/**
+ * Ordered list of config files loaded as the local configuration
+ *
+ * @var array
+ */
+ protected $_localConfigFiles = null;
+
+ /**
+ * Temporary model cache to avoid multiple parsing of local.xml files.
+ *
+ * @var Mage_Core_Model_Config_Base
+ */
+ protected $_localConfigMergeCache = null;
+
+ /**
* Flag which allow to use modules from local code pool
*
* @var bool
@@ -253,11 +267,13 @@ public function init($options=array())
$cacheLoad = $this->loadModulesCache();
if ($cacheLoad) {
+ $this->_cleanLoadCache();
return $this;
}
$this->loadModules();
$this->loadDb();
$this->saveCache();
+ $this->_cleanLoadCache();
return $this;
}
@@ -269,16 +285,29 @@ public function init($options=array())
public function loadBase()
{
$etcDir = $this->getOptions()->getEtcDir();
- $files = glob($etcDir.DS.'*.xml');
- $this->loadFile(current($files));
- while ($file = next($files)) {
- $merge = clone $this->_prototype;
- $merge->loadFile($file);
- $this->extend($merge);
- }
- if (in_array($etcDir.DS.'local.xml', $files)) {
- $this->_isLocalConfigLoaded = true;
- }
+ $localConfigs = $this->_getLocalConfigFiles();
+
+ $files = glob($etcDir . DS . '*.xml');
+ $file = current($files);
+ do {
+ // Skip local.xml config files initially
+ if (in_array($file, $localConfigs)) {
+ continue;
+ }
+ if ($this->getNode()) {
+ // Extend current XML with following files
+ $merge = clone $this->_prototype;
+ $merge->loadFile($file);
+ $this->extend($merge);
+ } else {
+ // Load the first file directly
+ $this->loadFile($file);
+ }
+ } while ($file = next($files));
+
+ // Load local.xml configuration files last so they have a higher priority
+ $this->loadLocalConfig();
+
return $this;
}
@@ -315,16 +344,12 @@ public function loadModules()
$this->_loadDeclaredModules();
$resourceConfig = sprintf('config.%s.xml', $this->_getResourceConnectionModel('core'));
- $this->loadModulesConfiguration(array('config.xml',$resourceConfig), $this);
+ $this->loadModulesConfiguration(array('config.xml', $resourceConfig), $this);
/**
* Prevent local.xml directives overwriting
*/
- $mergeConfig = clone $this->_prototype;
- $this->_isLocalConfigLoaded = $mergeConfig->loadFile($this->getOptions()->getEtcDir().DS.'local.xml');
- if ($this->_isLocalConfigLoaded) {
- $this->extend($mergeConfig);
- }
+ $this->loadLocalConfig();
$this->applyExtends();
Magento_Profiler::stop('load_modules');
@@ -333,6 +358,75 @@ public function loadModules()
}
/**
+ * Return a list of local.xml config files
+ *
+ * The environment dependant local configuration file can be specified
+ * using the environment variable $_SERVER['MAGE_APPLICATION_ENV'];
+ *
+ * @return array
+ */
+ protected function _getLocalConfigFiles()
+ {
+ if (!isset($this->_localConfigFiles)) {
+ $this->_localConfigFiles = array($this->getOptions()->getEtcDir() . DS . 'local.xml');
+ $env = false;
+ if (isset($_SERVER) && is_array($_SERVER) && isset($_SERVER['MAGE_APPLICATION_ENV'])) {
+ $env = $_SERVER['MAGE_APPLICATION_ENV'];
+ }
+ if (isset($env) && is_string($env)) {
+ if (preg_match('/^[a-z0-9_-]+$/', $env)) {
+ $file = $this->getOptions()->getEtcDir() . DS . 'local.' . $env . '.xml';
+ if (file_exists($file)) {
+ $this->_localConfigFiles[] = $file;
+ }
+ }
+ }
+ }
+ return $this->_localConfigFiles;
+ }
+
+ /**
+ * Load the local.xml file, followed by a local.$env.xml file if configured
+ *
+ * @return Mage_Core_Model_Config
+ */
+ public function loadLocalConfig()
+ {
+ if (is_null($this->_localConfigMergeCache)) {
+ $this->_localConfigMergeCache = clone $this->_prototype;
+ foreach ($this->_getLocalConfigFiles() as $file) {
+ if ($this->_localConfigMergeCache->getNode()) {
+ $mergeConfig = clone $this->_prototype;
+ $result = $mergeConfig->loadFile($file);
+ if ($result) {
+ $this->_localConfigMergeCache->extend($mergeConfig);
+ }
+ } else {
+ $result = $this->_localConfigMergeCache->loadFile($file);
+ }
+ // At least one local.xml config file needs to be loaded
+ $this->_isLocalConfigLoaded = $this->_isLocalConfigLoaded || $result;
+ }
+ }
+ if ($this->_isLocalConfigLoaded) {
+ $this->extend($this->_localConfigMergeCache);
+ }
+ return $this;
+ }
+
+ /**
+ * Unset the local config merge cache instance
+ *
+ * @return Mage_Core_Model_Config
+ * @see self::loadLocalConfig()
+ */
+ protected function _cleanLoadCache()
+ {
+ $this->_localConfigMergeCache = null;
+ return $this;
+ }
+
+ /**
* Check if local configuration (DB connection, etc) is loaded
*
* @return bool
Something went wrong with that request. Please try again.