1.在调用每个Magento模块(Modules)的时候,首先会返回Mage_Core_Model_Config 这个模型 它里面呈现了模块的一些常规配置,比如是否生效(enabled),版本(version)等等。Mage_Core_Model_Congif这个模型中有这么一个方法,来完成上面所说的功能。
/** * Get module config node * * @param string $moduleName * @return Varien_Simplexml_Object */ function getModuleConfig($moduleName='') { $modules = $this->getNode('modules'); if (''===$moduleName) { return $modules; } else { return $modules->$moduleName; } }这个方法有一个参数,就是模块名,返回的对象是Varien_Simplexml_Object2.调用每个模块的时候,它只是会建立一个基本的结构,并不会调用模块自身的配置情况。_loadDeclaredModules这个方法来帮助完成上面所说的需求。
/** * Load declared modules configuration * * @param null $mergeConfig depricated * @return Mage_Core_Model_Config */ protected function _loadDeclaredModules($mergeConfig = null) { $moduleFiles = $this->_getDeclaredModuleFiles(); if (!$moduleFiles) { return ; } Varien_Profiler::start('config/load-modules-declaration'); $unsortedConfig = new Mage_Core_Model_Config_Base(); $unsortedConfig->loadString(''); $fileConfig = new Mage_Core_Model_Config_Base(); // load modules declarations foreach ($moduleFiles as $file) { $fileConfig->loadFile($file); $unsortedConfig->extend($fileConfig); } $moduleDepends = array(); foreach ($unsortedConfig->getNode('modules')->children() as $moduleName => $moduleNode) { if (!$this->_isAllowedModule($moduleName)) { continue; } $depends = array(); if ($moduleNode->depends) { foreach ($moduleNode->depends->children() as $depend) { $depends[$depend->getName()] = true; } } $moduleDepends[$moduleName] = array( 'module' => $moduleName, 'depends' => $depends, 'active' => ('true' === (string)$moduleNode->active ? true : false), ); } // check and sort module dependence $moduleDepends = $this->_sortModuleDepends($moduleDepends); // create sorted config $sortedConfig = new Mage_Core_Model_Config_Base(); $sortedConfig->loadString(''); foreach ($unsortedConfig->getNode()->children() as $nodeName => $node) { if ($nodeName != 'modules') { $sortedConfig->getNode()->appendChild($node); } } foreach ($moduleDepends as $moduleProp) { $node = $unsortedConfig->getNode('modules/'.$moduleProp['module']); $sortedConfig->getNode('modules')->appendChild($node); } $this->extend($sortedConfig); Varien_Profiler::stop('config/load-modules-declaration'); return $this; }从foreach ($moduleDepends as $moduleProp) 开始的这段代码可以看出,程序是对app\etc\modules这段代码做xml的解析3.loadBase()这个方法会对系统的配置文件进行加载和解析,比如config.xml和local.xml
/** * Load base system configuration (config.xml and local.xml files) * * @return Mage_Core_Model_Config */ 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; } return $this; }4.此后加载模块自身的配置由loadModulesConfiguration这个function来完成
/** * Iterate all active modules "etc" folders and combine data from * specidied xml file name to one object * * @param string $fileName * @param null|Mage_Core_Model_Config_Base $mergeToObject * @return Mage_Core_Model_Config_Base */ public function loadModulesConfiguration($fileName, $mergeToObject = null, $mergeModel=null) { $disableLocalModules = !$this->_canUseLocalModules(); if ($mergeToObject === null) { $mergeToObject = clone $this->_prototype; $mergeToObject->loadString(''); } if ($mergeModel === null) { $mergeModel = clone $this->_prototype; } $modules = $this->getNode('modules')->children(); foreach ($modules as $modName=>$module) { if ($module->is('active')) { if ($disableLocalModules && ('local' === (string)$module->codePool)) { continue; } if (!is_array($fileName)) { $fileName = array($fileName); } foreach ($fileName as $configFile) { $configFile = $this->getModuleDir('etc', $modName).DS.$configFile; if ($mergeModel->loadFile($configFile)) { $mergeToObject->extend($mergeModel, true); } } } } return $mergeToObject; }5.最后的解析工作由loadFile来完成
/** * Imports XML file * * @param string $filePath * @return boolean */ public function loadFile($filePath) { if (!is_readable($filePath)) { //throw new Exception('Can not read xml file '.$filePath); return false; } $fileData = file_get_contents($filePath); $fileData = $this->processFileData($fileData); return $this->loadString($fileData, $this->_elementClass); }The End!