$value) { switch (strtolower($key)) { case 'allow_modifications': case 'allowmodifications': $allowModifications = (bool) $value; break; case 'skip_extends': case 'skipextends': $this->_skipExtends = (bool) $value; break; case 'ignore_constants': case 'ignoreconstants': $this->_ignoreConstants = (bool) $value; break; default: break; } } } set_error_handler(array($this, '_loadFileErrorHandler')); // Warnings and errors are suppressed if ($json[0] != '{') { $json = file_get_contents($json); } restore_error_handler(); // Check if there was a error while loading file if ($this->_loadFileErrorStr !== null) { require_once 'Zend/Config/Exception.php'; throw new Zend_Config_Exception($this->_loadFileErrorStr); } // Replace constants if (!$this->_ignoreConstants) { $json = $this->_replaceConstants($json); } // Parse/decode try { $config = Zend_Json::decode($json); } catch (Zend_Json_Exception $e) { // decode failed require_once 'Zend/Config/Exception.php'; throw new Zend_Config_Exception("Error parsing JSON data"); } if ($section === null) { $dataArray = array(); foreach ($config as $sectionName => $sectionData) { $dataArray[$sectionName] = $this->_processExtends($config, $sectionName); } parent::__construct($dataArray, $allowModifications); } elseif (is_array($section)) { $dataArray = array(); foreach ($section as $sectionName) { if (!isset($config[$sectionName])) { require_once 'Zend/Config/Exception.php'; throw new Zend_Config_Exception(sprintf('Section "%s" cannot be found', $sectionName)); } $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(sprintf('Section "%s" cannot be found', $section)); } $dataArray = $this->_processExtends($config, $section); if (!is_array($dataArray)) { // Section in the JSON data 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 array $data Data array 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(array $data, $section, array $config = array()) { if (!isset($data[$section])) { require_once 'Zend/Config/Exception.php'; throw new Zend_Config_Exception(sprintf('Section "%s" cannot be found', $section)); } $thisSection = $data[$section]; if (is_array($thisSection) && isset($thisSection[self::EXTENDS_NAME])) { if (is_array($thisSection[self::EXTENDS_NAME])) { require_once 'Zend/Config/Exception.php'; throw new Zend_Config_Exception('Invalid extends clause: must be a string; array received'); } $this->_assertValidExtend($section, $thisSection[self::EXTENDS_NAME]); if (!$this->_skipExtends) { $config = $this->_processExtends($data, $thisSection[self::EXTENDS_NAME], $config); } unset($thisSection[self::EXTENDS_NAME]); } $config = $this->_arrayMergeRecursive($config, $thisSection); return $config; } /** * Replace any constants referenced in a string with their values * * @param string $value * @return string */ protected function _replaceConstants($value) { foreach ($this->_getConstants() as $constant) { if (strstr($value, $constant)) { // handle backslashes that may represent windows path names for instance $replacement = str_replace('\\', '\\\\', constant($constant)); $value = str_replace($constant, $replacement, $value); } } return $value; } /** * Get (reverse) sorted list of defined constant names * * @return array */ protected function _getConstants() { $constants = array_keys(get_defined_constants()); rsort($constants, SORT_STRING); return $constants; } }