_loadFileErrorStr !== null) { require_once 'Zend/Config/Exception.php'; throw new Zend_Config_Exception($this->_loadFileErrorStr); } if ($section === null) { $dataArray = array(); foreach ($config as $sectionName => $sectionData) { $dataArray[$sectionName] = $this->_processExtends($config, $sectionName); } parent::__construct($dataArray, $allowModifications); } else if (is_array($section)) { $dataArray = array(); foreach ($section as $sectionName) { if (!isset($config->$sectionName)) { require_once 'Zend/Config/Exception.php'; throw new Zend_Config_Exception("Section '$sectionName' cannot be found in $filename"); } $dataArray = array_merge($this->_processExtends($config, $sectionName), $dataArray); } parent::__construct($dataArray, $allowModifications); } else { if (!isset($config->$section)) { require_once 'Zend/Config/Exception.php'; throw new Zend_Config_Exception("Section '$section' cannot be found in $filename"); } $dataArray = $this->_processExtends($config, $section); if (!is_array($dataArray)) { // Section in the XML file contains just one top level string $dataArray = array($section => $dataArray); } parent::__construct($dataArray, $allowModifications); } $this->_loadedSection = $section; } /** * Helper function to process each element in the section and handle * the "extends" inheritance attribute. * * @param SimpleXMLElement $element XML Element to process * @param string $section Section to process * @param array $config Configuration which was parsed yet * @throws Zend_Config_Exception When $section cannot be found * @return array */ protected function _processExtends(SimpleXMLElement $element, $section, array $config = array()) { if (!isset($element->$section)) { require_once 'Zend/Config/Exception.php'; throw new Zend_Config_Exception("Section '$section' cannot be found"); } $thisSection = $element->$section; if (isset($thisSection['extends'])) { $extendedSection = (string) $thisSection['extends']; $this->_assertValidExtend($section, $extendedSection); $config = $this->_processExtends($element, $extendedSection, $config); } $config = $this->_arrayMergeRecursive($config, $this->_toArray($thisSection)); return $config; } /** * Returns a string or an associative and possibly multidimensional array from * a SimpleXMLElement. * * @param SimpleXMLElement $xmlObject Convert a SimpleXMLElement into an array * @return array|string */ protected function _toArray(SimpleXMLElement $xmlObject) { $config = array(); // Search for parent node values if (count($xmlObject->attributes()) > 0) { foreach ($xmlObject->attributes() as $key => $value) { if ($key === 'extends') { continue; } $value = (string) $value; if (array_key_exists($key, $config)) { if (!is_array($config[$key])) { $config[$key] = array($config[$key]); } $config[$key][] = $value; } else { $config[$key] = $value; } } } // Search for children if (count($xmlObject->children()) > 0) { foreach ($xmlObject->children() as $key => $value) { if (count($value->children()) > 0) { $value = $this->_toArray($value); } else if (count($value->attributes()) > 0) { $attributes = $value->attributes(); if (isset($attributes['value'])) { $value = (string) $attributes['value']; } else { $value = $this->_toArray($value); } } else { $value = (string) $value; } if (array_key_exists($key, $config)) { if (!is_array($config[$key]) || !array_key_exists(0, $config[$key])) { $config[$key] = array($config[$key]); } $config[$key][] = $value; } else { $config[$key] = $value; } } } else if (!isset($xmlObject['extends']) && (count($config) === 0)) { // Object has no children nor attributes and doesn't use the extends // attribute: it's a string $config = (string) $xmlObject; } return $config; } /** * Merge two arrays recursively, overwriting keys of the same name * in $array1 with the value in $array2. * * @param mixed $firstArray First array * @param mixed $secondArray Second array to merge into first array * @return array */ protected function _arrayMergeRecursive($firstArray, $secondArray) { if (is_array($firstArray) && is_array($secondArray)) { foreach ($secondArray as $key => $value) { if (isset($firstArray[$key])) { $firstArray[$key] = $this->_arrayMergeRecursive($firstArray[$key], $value); } else { $firstArray[$key] = $value; } } } else { $firstArray = $secondArray; } return $firstArray; } }