_allowModifications = (boolean) $allowModifications; $this->_loadedSection = null; $this->_index = 0; $this->_data = array(); foreach ($array as $key => $value) { if (is_array($value)) { $this->_data[$key] = new self($value, $this->_allowModifications); } else { $this->_data[$key] = $value; } } $this->_count = count($this->_data); } /** * Retrieve a value and return $default if there is no element set. * * @param string $name * @param mixed $default * @return mixed */ public function get($name, $default = null) { $result = $default; if (array_key_exists($name, $this->_data)) { $result = $this->_data[$name]; } return $result; } /** * Magic function so that $obj->value will work. * * @param string $name * @return mixed */ public function __get($name) { return $this->get($name); } /** * Only allow setting of a property if $allowModifications * was set to true on construction. Otherwise, throw an exception. * * @param string $name * @param mixed $value * @throws Zend_Config_Exception * @return void */ public function __set($name, $value) { if ($this->_allowModifications) { if (is_array($value)) { $this->_data[$name] = new self($value, true); } else { $this->_data[$name] = $value; } $this->_count = count($this->_data); } else { /** @see Zend_Config_Exception */ require_once 'Zend/Config/Exception.php'; throw new Zend_Config_Exception('Zend_Config is read only'); } } /** * Deep clone of this instance to ensure that nested Zend_Configs * are also cloned. * * @return void */ public function __clone() { $array = array(); foreach ($this->_data as $key => $value) { if ($value instanceof Zend_Config) { $array[$key] = clone $value; } else { $array[$key] = $value; } } $this->_data = $array; } /** * Return an associative array of the stored data. * * @return array */ public function toArray() { $array = array(); $data = $this->_data; foreach ($data as $key => $value) { if ($value instanceof Zend_Config) { $array[$key] = $value->toArray(); } else { $array[$key] = $value; } } return $array; } /** * Support isset() overloading on PHP 5.1 * * @param string $name * @return boolean */ public function __isset($name) { return isset($this->_data[$name]); } /** * Support unset() overloading on PHP 5.1 * * @param string $name * @throws Zend_Config_Exception * @return void */ public function __unset($name) { if ($this->_allowModifications) { unset($this->_data[$name]); $this->_count = count($this->_data); $this->_skipNextIteration = true; } else { /** @see Zend_Config_Exception */ require_once 'Zend/Config/Exception.php'; throw new Zend_Config_Exception('Zend_Config is read only'); } } /** * Defined by Countable interface * * @return int */ public function count() { return $this->_count; } /** * Defined by Iterator interface * * @return mixed */ public function current() { $this->_skipNextIteration = false; return current($this->_data); } /** * Defined by Iterator interface * * @return mixed */ public function key() { return key($this->_data); } /** * Defined by Iterator interface * */ public function next() { if ($this->_skipNextIteration) { $this->_skipNextIteration = false; return; } next($this->_data); $this->_index++; } /** * Defined by Iterator interface * */ public function rewind() { $this->_skipNextIteration = false; reset($this->_data); $this->_index = 0; } /** * Defined by Iterator interface * * @return boolean */ public function valid() { return $this->_index < $this->_count; } /** * Returns the section name(s) loaded. * * @return mixed */ public function getSectionName() { if(is_array($this->_loadedSection) && count($this->_loadedSection) == 1) { $this->_loadedSection = $this->_loadedSection[0]; } return $this->_loadedSection; } /** * Returns true if all sections were loaded * * @return boolean */ public function areAllSectionsLoaded() { return $this->_loadedSection === null; } /** * Merge another Zend_Config with this one. The items * in $merge will override the same named items in * the current config. * * @param Zend_Config $merge * @return Zend_Config */ public function merge(Zend_Config $merge) { foreach($merge as $key => $item) { if(array_key_exists($key, $this->_data)) { if($item instanceof Zend_Config && $this->$key instanceof Zend_Config) { $this->$key = $this->$key->merge(new Zend_Config($item->toArray(), !$this->readOnly())); } else { $this->$key = $item; } } else { if($item instanceof Zend_Config) { $this->$key = new Zend_Config($item->toArray(), !$this->readOnly()); } else { $this->$key = $item; } } } return $this; } /** * Prevent any more modifications being made to this instance. Useful * after merge() has been used to merge multiple Zend_Config objects * into one object which should then not be modified again. * */ public function setReadOnly() { $this->_allowModifications = false; foreach ($this->_data as $key => $value) { if ($value instanceof Zend_Config) { $value->setReadOnly(); } } } /** * Returns if this Zend_Config object is read only or not. * * @return boolean */ public function readOnly() { return !$this->_allowModifications; } /** * Get the current extends * * @return array */ public function getExtends() { return $this->_extends; } /** * Set an extend for Zend_Config_Writer * * @param string $extendingSection * @param string $extendedSection * @return void */ public function setExtend($extendingSection, $extendedSection = null) { if ($extendedSection === null && isset($this->_extends[$extendingSection])) { unset($this->_extends[$extendingSection]); } else if ($extendedSection !== null) { $this->_extends[$extendingSection] = $extendedSection; } } /** * Throws an exception if $extendingSection may not extend $extendedSection, * and tracks the section extension if it is valid. * * @param string $extendingSection * @param string $extendedSection * @throws Zend_Config_Exception * @return void */ protected function _assertValidExtend($extendingSection, $extendedSection) { // detect circular section inheritance $extendedSectionCurrent = $extendedSection; while (array_key_exists($extendedSectionCurrent, $this->_extends)) { if ($this->_extends[$extendedSectionCurrent] == $extendingSection) { /** @see Zend_Config_Exception */ require_once 'Zend/Config/Exception.php'; throw new Zend_Config_Exception('Illegal circular inheritance detected'); } $extendedSectionCurrent = $this->_extends[$extendedSectionCurrent]; } // remember that this section extends another section $this->_extends[$extendingSection] = $extendedSection; } /** * Handle any errors from simplexml_load_file or parse_ini_file * * @param integer $errno * @param string $errstr * @param string $errfile * @param integer $errline */ protected function _loadFileErrorHandler($errno, $errstr, $errfile, $errline) { if ($this->_loadFileErrorStr === null) { $this->_loadFileErrorStr = $errstr; } else { $this->_loadFileErrorStr .= (PHP_EOL . $errstr); } } /** * Merge two arrays recursively, overwriting keys of the same name * in $firstArray with the value in $secondArray. * * @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 { if($key === 0) { $firstArray= array(0=>$this->_arrayMergeRecursive($firstArray, $value)); } else { $firstArray[$key] = $value; } } } } else { $firstArray = $secondArray; } return $firstArray; } }