Commit c24f6d21efedb18796c8cfdc294752afcab61058
1 parent
662c5dc4
Import PEAR Config 1.10.4
git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/trunk@3466 c91229c3-7414-0410-bfa2-8a42b809f60b
Showing
9 changed files
with
2477 additions
and
0 deletions
thirdparty/pear/Config.php
0 → 100644
| 1 | +<?php | |
| 2 | +// +----------------------------------------------------------------------+ | |
| 3 | +// | PHP Version 4 | | |
| 4 | +// +----------------------------------------------------------------------+ | |
| 5 | +// | Copyright (c) 1997-2003 The PHP Group | | |
| 6 | +// +----------------------------------------------------------------------+ | |
| 7 | +// | This source file is subject to version 2.0 of the PHP license, | | |
| 8 | +// | that is bundled with this package in the file LICENSE, and is | | |
| 9 | +// | available at through the world-wide-web at | | |
| 10 | +// | http://www.php.net/license/2_02.txt. | | |
| 11 | +// | If you did not receive a copy of the PHP license and are unable to | | |
| 12 | +// | obtain it through the world-wide-web, please send a note to | | |
| 13 | +// | license@php.net so we can mail you a copy immediately. | | |
| 14 | +// +----------------------------------------------------------------------+ | |
| 15 | +// | Author: Bertrand Mansion <bmansion@mamasam.com> | | |
| 16 | +// +----------------------------------------------------------------------+ | |
| 17 | +// | |
| 18 | +// $Id$ | |
| 19 | + | |
| 20 | +require_once('PEAR.php'); | |
| 21 | +require_once('Config/Container.php'); | |
| 22 | + | |
| 23 | +$GLOBALS['CONFIG_TYPES'] = | |
| 24 | + array( | |
| 25 | + 'apache' =>array('Config/Container/Apache.php','Config_Container_Apache'), | |
| 26 | + 'genericconf' =>array('Config/Container/GenericConf.php','Config_Container_GenericConf'), | |
| 27 | + 'inifile' =>array('Config/Container/IniFile.php','Config_Container_IniFile'), | |
| 28 | + 'inicommented' =>array('Config/Container/IniCommented.php','Config_Container_IniCommented'), | |
| 29 | + 'phparray' =>array('Config/Container/PHPArray.php','Config_Container_PHPArray'), | |
| 30 | + 'xml' =>array('Config/Container/XML.php','Config_Container_XML') | |
| 31 | + ); | |
| 32 | + | |
| 33 | +/** | |
| 34 | +* Config | |
| 35 | +* | |
| 36 | +* This class allows for parsing and editing of configuration datasources. | |
| 37 | +* Do not use this class only to read datasources because of the overhead | |
| 38 | +* it creates to keep track of the configuration structure. | |
| 39 | +* | |
| 40 | +* @author Bertrand Mansion <bmansion@mamasam.com> | |
| 41 | +* @package Config | |
| 42 | +*/ | |
| 43 | +class Config { | |
| 44 | + | |
| 45 | + /** | |
| 46 | + * Datasource | |
| 47 | + * Can be a file url, a dsn, an object... | |
| 48 | + * @var mixed | |
| 49 | + */ | |
| 50 | + var $datasrc; | |
| 51 | + | |
| 52 | + /** | |
| 53 | + * Type of datasource for config | |
| 54 | + * Ex: IniCommented, Apache... | |
| 55 | + * @var string | |
| 56 | + */ | |
| 57 | + var $configType = ''; | |
| 58 | + | |
| 59 | + /** | |
| 60 | + * Options for parser | |
| 61 | + * @var string | |
| 62 | + */ | |
| 63 | + var $parserOptions = array(); | |
| 64 | + | |
| 65 | + /** | |
| 66 | + * Container object | |
| 67 | + * @var object | |
| 68 | + */ | |
| 69 | + var $container; | |
| 70 | + | |
| 71 | + /** | |
| 72 | + * Constructor | |
| 73 | + * Creates a root container | |
| 74 | + * | |
| 75 | + * @access public | |
| 76 | + */ | |
| 77 | + function Config() | |
| 78 | + { | |
| 79 | + $this->container =& new Config_Container('section', 'root'); | |
| 80 | + } // end constructor | |
| 81 | + | |
| 82 | + /** | |
| 83 | + * Returns true if container is registered | |
| 84 | + * | |
| 85 | + * @param string $configType Type of config | |
| 86 | + * @access public | |
| 87 | + * @return bool | |
| 88 | + */ | |
| 89 | + function isConfigTypeRegistered($configType) | |
| 90 | + { | |
| 91 | + return isset($GLOBALS['CONFIG_TYPES'][strtolower($configType)]); | |
| 92 | + } // end func isConfigTypeRegistered | |
| 93 | + | |
| 94 | + /** | |
| 95 | + * Register a new container | |
| 96 | + * | |
| 97 | + * @param string $configType Type of config | |
| 98 | + * @param array|false $configInfo Array of format: | |
| 99 | + * array('path/to/Name.php', | |
| 100 | + * 'Config_Container_Class_Name'). | |
| 101 | + * | |
| 102 | + * If left false, defaults to: | |
| 103 | + * array('Config/Container/$configType.php', | |
| 104 | + * 'Config_Container_$configType') | |
| 105 | + * @access public | |
| 106 | + * @static | |
| 107 | + * @author Greg Beaver <cellog@users.sourceforge.net> | |
| 108 | + * @return true|PEAR_Error true on success | |
| 109 | + */ | |
| 110 | + function registerConfigType($configType, $configInfo = false) | |
| 111 | + { | |
| 112 | + if (Config::isConfigTypeRegistered($configType)) { | |
| 113 | + $info = $GLOBALS['CONFIG_TYPES'][strtolower($configType)]; | |
| 114 | + if ($info[0] == $configInfo[0] && | |
| 115 | + $info[1] == $configInfo[1]) { | |
| 116 | + return true; | |
| 117 | + } else { | |
| 118 | + return PEAR::raiseError("Config::registerConfigType registration of existing $configType failed.", null, PEAR_ERROR_RETURN); | |
| 119 | + } | |
| 120 | + } | |
| 121 | + if (!is_array($configInfo)) { | |
| 122 | + // make the normal assumption, that this is a standard config container added in at runtime | |
| 123 | + $configInfo = array('Config/Container/' . $configType . '.php', | |
| 124 | + 'Config_Container_'. $configType); | |
| 125 | + } | |
| 126 | + $file_exists = @include_once($configInfo[0]); | |
| 127 | + if ($file_exists) { | |
| 128 | + if (!class_exists($configInfo[1])) { | |
| 129 | + return PEAR::raiseError("Config::registerConfigType class '$configInfo[1]' not found in $configInfo[0]", null, PEAR_ERROR_RETURN); | |
| 130 | + } | |
| 131 | + } else { | |
| 132 | + return PEAR::raiseError("Config::registerConfigType file $configInfo[0] not found", null, PEAR_ERROR_RETURN); | |
| 133 | + } | |
| 134 | + $GLOBALS['CONFIG_TYPES'][strtolower($configType)] = $configInfo; | |
| 135 | + return true; | |
| 136 | + } // end func registerConfigType | |
| 137 | + | |
| 138 | + /** | |
| 139 | + * Returns the root container for this config object | |
| 140 | + * | |
| 141 | + * @access public | |
| 142 | + * @return object reference to config's root container object | |
| 143 | + */ | |
| 144 | + function &getRoot() | |
| 145 | + { | |
| 146 | + return $this->container; | |
| 147 | + } // end func getRoot | |
| 148 | + | |
| 149 | + /** | |
| 150 | + * Sets the content of the root Config_container object. | |
| 151 | + * | |
| 152 | + * This method will replace the current child of the root | |
| 153 | + * Config_Container object by the given object. | |
| 154 | + * | |
| 155 | + * @param object $rootContainer container to be used as the first child to root | |
| 156 | + * @access public | |
| 157 | + * @return mixed true on success or PEAR_Error | |
| 158 | + */ | |
| 159 | + function setRoot(&$rootContainer) | |
| 160 | + { | |
| 161 | + if (is_object($rootContainer) && strtolower(get_class($rootContainer)) === 'config_container') { | |
| 162 | + if ($rootContainer->getName() === 'root' && $rootContainer->getType() === 'section') { | |
| 163 | + $this->container =& $rootContainer; | |
| 164 | + } else { | |
| 165 | + $this->container =& new Config_Container('section', 'root'); | |
| 166 | + $this->container->addItem($rootContainer); | |
| 167 | + } | |
| 168 | + return true; | |
| 169 | + } else { | |
| 170 | + return PEAR::raiseError("Config::setRoot only accepts object of Config_Container type.", null, PEAR_ERROR_RETURN); | |
| 171 | + } | |
| 172 | + } // end func setRoot | |
| 173 | + | |
| 174 | + /** | |
| 175 | + * Parses the datasource contents | |
| 176 | + * | |
| 177 | + * This method will parse the datasource given and fill the root | |
| 178 | + * Config_Container object with other Config_Container objects. | |
| 179 | + * | |
| 180 | + * @param mixed $datasrc Datasource to parse | |
| 181 | + * @param string $configType Type of configuration | |
| 182 | + * @param array $options Options for the parser | |
| 183 | + * @access public | |
| 184 | + * @return mixed PEAR_Error on error or Config_Container object | |
| 185 | + */ | |
| 186 | + function &parseConfig($datasrc, $configType, $options = array()) | |
| 187 | + { | |
| 188 | + $configType = strtolower($configType); | |
| 189 | + if (!$this->isConfigTypeRegistered($configType)) { | |
| 190 | + return PEAR::raiseError("Configuration type '$configType' is not registered in Config::parseConfig.", null, PEAR_ERROR_RETURN); | |
| 191 | + } | |
| 192 | + $includeFile = $GLOBALS['CONFIG_TYPES'][$configType][0]; | |
| 193 | + $className = $GLOBALS['CONFIG_TYPES'][$configType][1]; | |
| 194 | + include_once($includeFile); | |
| 195 | + | |
| 196 | + $parser = new $className($options); | |
| 197 | + $error = $parser->parseDatasrc($datasrc, $this); | |
| 198 | + if ($error !== true) { | |
| 199 | + return $error; | |
| 200 | + } | |
| 201 | + $this->parserOptions = $parser->options; | |
| 202 | + $this->datasrc = $datasrc; | |
| 203 | + $this->configType = $configType; | |
| 204 | + return $this->container; | |
| 205 | + } // end func &parseConfig | |
| 206 | + | |
| 207 | + /** | |
| 208 | + * Writes the container contents to the datasource. | |
| 209 | + * | |
| 210 | + * @param mixed $datasrc Datasource to write to | |
| 211 | + * @param string $configType Type of configuration | |
| 212 | + * @param array $options Options for config container | |
| 213 | + * @access public | |
| 214 | + * @return mixed PEAR_Error on error or true if ok | |
| 215 | + */ | |
| 216 | + function writeConfig($datasrc = null, $configType = null, $options = array()) | |
| 217 | + { | |
| 218 | + if (empty($datasrc)) { | |
| 219 | + $datasrc = $this->datasrc; | |
| 220 | + } | |
| 221 | + if (empty($configType)) { | |
| 222 | + $configType = $this->configType; | |
| 223 | + } | |
| 224 | + if (empty($options)) { | |
| 225 | + $options = $this->parserOptions; | |
| 226 | + } | |
| 227 | + return $this->container->writeDatasrc($datasrc, $configType, $options); | |
| 228 | + } // end func writeConfig | |
| 229 | +} // end class Config | |
| 230 | +?> | |
| 0 | 231 | \ No newline at end of file | ... | ... |
thirdparty/pear/Config/Container.php
0 → 100644
| 1 | +<?php | |
| 2 | +// +---------------------------------------------------------------------+ | |
| 3 | +// | PHP Version 4 | | |
| 4 | +// +---------------------------------------------------------------------+ | |
| 5 | +// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | | |
| 6 | +// +---------------------------------------------------------------------+ | |
| 7 | +// | This source file is subject to version 2.0 of the PHP license, | | |
| 8 | +// | that is bundled with this package in the file LICENSE, and is | | |
| 9 | +// | available at through the world-wide-web at | | |
| 10 | +// | http://www.php.net/license/2_02.txt. | | |
| 11 | +// | If you did not receive a copy of the PHP license and are unable to | | |
| 12 | +// | obtain it through the world-wide-web, please send a note to | | |
| 13 | +// | license@php.net so we can mail you a copy immediately. | | |
| 14 | +// +---------------------------------------------------------------------+ | |
| 15 | +// | Author: Bertrand Mansion <bmansion@mamasam.com> | | |
| 16 | +// +---------------------------------------------------------------------+ | |
| 17 | +// | |
| 18 | +// $Id$ | |
| 19 | + | |
| 20 | +require_once 'Config.php'; | |
| 21 | + | |
| 22 | +/** | |
| 23 | +* Interface for Config containers | |
| 24 | +* | |
| 25 | +* @author Bertrand Mansion <bmansion@mamasam.com> | |
| 26 | +* @package Config | |
| 27 | +*/ | |
| 28 | +class Config_Container { | |
| 29 | + | |
| 30 | + /** | |
| 31 | + * Container object type | |
| 32 | + * Ex: section, directive, comment, blank | |
| 33 | + * @var string | |
| 34 | + */ | |
| 35 | + var $type; | |
| 36 | + | |
| 37 | + /** | |
| 38 | + * Container object name | |
| 39 | + * @var string | |
| 40 | + */ | |
| 41 | + var $name = ''; | |
| 42 | + | |
| 43 | + /** | |
| 44 | + * Container object content | |
| 45 | + * @var string | |
| 46 | + */ | |
| 47 | + var $content = ''; | |
| 48 | + | |
| 49 | + /** | |
| 50 | + * Container object children | |
| 51 | + * @var array | |
| 52 | + */ | |
| 53 | + var $children = array(); | |
| 54 | + | |
| 55 | + /** | |
| 56 | + * Reference to container object's parent | |
| 57 | + * @var object | |
| 58 | + */ | |
| 59 | + var $parent; | |
| 60 | + | |
| 61 | + /** | |
| 62 | + * Array of attributes for this item | |
| 63 | + * @var array | |
| 64 | + */ | |
| 65 | + var $attributes; | |
| 66 | + | |
| 67 | + /** | |
| 68 | + * Unique id to differenciate nodes | |
| 69 | + * | |
| 70 | + * This is used to compare nodes | |
| 71 | + * Will not be needed anymore when this class will use ZendEngine 2 | |
| 72 | + * | |
| 73 | + * @var int | |
| 74 | + */ | |
| 75 | + var $_id; | |
| 76 | + | |
| 77 | + /** | |
| 78 | + * Constructor | |
| 79 | + * | |
| 80 | + * @param string $type Type of container object | |
| 81 | + * @param string $name Name of container object | |
| 82 | + * @param string $content Content of container object | |
| 83 | + * @param array $attributes Array of attributes for container object | |
| 84 | + */ | |
| 85 | + function Config_Container($type = 'section', $name = '', $content = '', $attributes = null) | |
| 86 | + { | |
| 87 | + $this->type = $type; | |
| 88 | + $this->name = $name; | |
| 89 | + $this->content = $content; | |
| 90 | + $this->attributes = $attributes; | |
| 91 | + $this->parent = null; | |
| 92 | + $this->_id = uniqid($name.$type, true); | |
| 93 | + } // end constructor | |
| 94 | + | |
| 95 | + /** | |
| 96 | + * Create a child for this item. | |
| 97 | + * @param string $type type of item: directive, section, comment, blank... | |
| 98 | + * @param mixed $item item name | |
| 99 | + * @param string $content item content | |
| 100 | + * @param array $attributes item attributes | |
| 101 | + * @param string $where choose a position 'bottom', 'top', 'after', 'before' | |
| 102 | + * @param object $target needed if you choose 'before' or 'after' for where | |
| 103 | + * @return object reference to new item or Pear_Error | |
| 104 | + */ | |
| 105 | + function &createItem($type, $name, $content, $attributes = null, $where = 'bottom', $target = null) | |
| 106 | + { | |
| 107 | + $item =& new Config_Container($type, $name, $content, $attributes); | |
| 108 | + $result =& $this->addItem($item, $where, $target); | |
| 109 | + return $result; | |
| 110 | + } // end func &createItem | |
| 111 | + | |
| 112 | + /** | |
| 113 | + * Adds an item to this item. | |
| 114 | + * @param object $item a container object | |
| 115 | + * @param string $where choose a position 'bottom', 'top', 'after', 'before' | |
| 116 | + * @param object $target needed if you choose 'before' or 'after' in $where | |
| 117 | + * @return mixed reference to added container on success, Pear_Error on error | |
| 118 | + */ | |
| 119 | + function &addItem(&$item, $where = 'bottom', $target = null) | |
| 120 | + { | |
| 121 | + if ($this->type != 'section') { | |
| 122 | + return PEAR::raiseError('Config_Container::addItem must be called on a section type object.', null, PEAR_ERROR_RETURN); | |
| 123 | + } | |
| 124 | + if (is_null($target)) { | |
| 125 | + $target =& $this; | |
| 126 | + } | |
| 127 | + if (strtolower(get_class($target)) != 'config_container') { | |
| 128 | + return PEAR::raiseError('Target must be a Config_Container object in Config_Container::addItem.', null, PEAR_ERROR_RETURN); | |
| 129 | + } | |
| 130 | + | |
| 131 | + switch ($where) { | |
| 132 | + case 'before': | |
| 133 | + $index = $target->getItemIndex(); | |
| 134 | + break; | |
| 135 | + case 'after': | |
| 136 | + $index = $target->getItemIndex()+1; | |
| 137 | + break; | |
| 138 | + case 'top': | |
| 139 | + $index = 0; | |
| 140 | + break; | |
| 141 | + case 'bottom': | |
| 142 | + $index = -1; | |
| 143 | + break; | |
| 144 | + default: | |
| 145 | + return PEAR::raiseError('Use only top, bottom, before or after in Config_Container::addItem.', null, PEAR_ERROR_RETURN); | |
| 146 | + } | |
| 147 | + if (isset($index) && $index >= 0) { | |
| 148 | + array_splice($this->children, $index, 0, 'tmp'); | |
| 149 | + } else { | |
| 150 | + $index = count($this->children); | |
| 151 | + } | |
| 152 | + $this->children[$index] =& $item; | |
| 153 | + $this->children[$index]->parent =& $this; | |
| 154 | + | |
| 155 | + return $item; | |
| 156 | + } // end func addItem | |
| 157 | + | |
| 158 | + /** | |
| 159 | + * Adds a comment to this item. | |
| 160 | + * This is a helper method that calls createItem | |
| 161 | + * | |
| 162 | + * @param string $content Object content | |
| 163 | + * @param string $where Position : 'top', 'bottom', 'before', 'after' | |
| 164 | + * @param object $target Needed when $where is 'before' or 'after' | |
| 165 | + * @return object reference to new item or Pear_Error | |
| 166 | + */ | |
| 167 | + function &createComment($content = '', $where = 'bottom', $target = null) | |
| 168 | + { | |
| 169 | + return $this->createItem('comment', null, $content, null, $where, $target); | |
| 170 | + } // end func &createComment | |
| 171 | + | |
| 172 | + /** | |
| 173 | + * Adds a blank line to this item. | |
| 174 | + * This is a helper method that calls createItem | |
| 175 | + * | |
| 176 | + * @return object reference to new item or Pear_Error | |
| 177 | + */ | |
| 178 | + function &createBlank($where = 'bottom', $target = null) | |
| 179 | + { | |
| 180 | + return $this->createItem('blank', null, null, null, $where, $target); | |
| 181 | + } // end func &createBlank | |
| 182 | + | |
| 183 | + /** | |
| 184 | + * Adds a directive to this item. | |
| 185 | + * This is a helper method that calls createItem | |
| 186 | + * | |
| 187 | + * @param string $name Name of new directive | |
| 188 | + * @param string $content Content of new directive | |
| 189 | + * @param mixed $attributes Directive attributes | |
| 190 | + * @param string $where Position : 'top', 'bottom', 'before', 'after' | |
| 191 | + * @param object $target Needed when $where is 'before' or 'after' | |
| 192 | + * @return object reference to new item or Pear_Error | |
| 193 | + */ | |
| 194 | + function &createDirective($name, $content, $attributes = null, $where = 'bottom', $target = null) | |
| 195 | + { | |
| 196 | + return $this->createItem('directive', $name, $content, $attributes, $where, $target); | |
| 197 | + } // end func &createDirective | |
| 198 | + | |
| 199 | + /** | |
| 200 | + * Adds a section to this item. | |
| 201 | + * | |
| 202 | + * This is a helper method that calls createItem | |
| 203 | + * If the section already exists, it won't create a new one. | |
| 204 | + * It will return reference to existing item. | |
| 205 | + * | |
| 206 | + * @param string $name Name of new section | |
| 207 | + * @param array $attributes Section attributes | |
| 208 | + * @param string $where Position : 'top', 'bottom', 'before', 'after' | |
| 209 | + * @param object $target Needed when $where is 'before' or 'after' | |
| 210 | + * @return object reference to new item or Pear_Error | |
| 211 | + */ | |
| 212 | + function &createSection($name, $attributes = null, $where = 'bottom', $target = null) | |
| 213 | + { | |
| 214 | + return $this->createItem('section', $name, null, $attributes, $where, $target); | |
| 215 | + } // end func &createSection | |
| 216 | + | |
| 217 | + /** | |
| 218 | + * Tries to find the specified item(s) and returns the objects. | |
| 219 | + * | |
| 220 | + * Examples: | |
| 221 | + * $directives =& $obj->getItem('directive'); | |
| 222 | + * $directive_bar_4 =& $obj->getItem('directive', 'bar', null, 4); | |
| 223 | + * $section_foo =& $obj->getItem('section', 'foo'); | |
| 224 | + * | |
| 225 | + * This method can only be called on an object of type 'section'. | |
| 226 | + * Note that root is a section. | |
| 227 | + * This method is not recursive and tries to keep the current structure. | |
| 228 | + * For a deeper search, use searchPath() | |
| 229 | + * | |
| 230 | + * @param string $type Type of item: directive, section, comment, blank... | |
| 231 | + * @param mixed $name Item name | |
| 232 | + * @param mixed $content Find item with this content | |
| 233 | + * @param array $attributes Find item with attribute set to the given value | |
| 234 | + * @param int $index Index of the item in the returned object list. If it is not set, will try to return the last item with this name. | |
| 235 | + * @return mixed reference to item found or false when not found | |
| 236 | + * @see &searchPath() | |
| 237 | + */ | |
| 238 | + function &getItem($type = null, $name = null, $content = null, $attributes = null, $index = -1) | |
| 239 | + { | |
| 240 | + if ($this->type != 'section') { | |
| 241 | + return PEAR::raiseError('Config_Container::getItem must be called on a section type object.', null, PEAR_ERROR_RETURN); | |
| 242 | + } | |
| 243 | + if (!is_null($type)) { | |
| 244 | + $testFields[] = 'type'; | |
| 245 | + } | |
| 246 | + if (!is_null($name)) { | |
| 247 | + $testFields[] = 'name'; | |
| 248 | + } | |
| 249 | + if (!is_null($content)) { | |
| 250 | + $testFields[] = 'content'; | |
| 251 | + } | |
| 252 | + if (!is_null($attributes) && is_array($attributes)) { | |
| 253 | + $testFields[] = 'attributes'; | |
| 254 | + } | |
| 255 | + | |
| 256 | + $itemsArr = array(); | |
| 257 | + $fieldsToMatch = count($testFields); | |
| 258 | + for ($i = 0, $count = count($this->children); $i < $count; $i++) { | |
| 259 | + $match = 0; | |
| 260 | + reset($testFields); | |
| 261 | + foreach ($testFields as $field) { | |
| 262 | + if ($field != 'attributes') { | |
| 263 | + if ($this->children[$i]->$field == ${$field}) { | |
| 264 | + $match++; | |
| 265 | + } | |
| 266 | + } else { | |
| 267 | + // Look for attributes in array | |
| 268 | + $attrToMatch = count($attributes); | |
| 269 | + $attrMatch = 0; | |
| 270 | + foreach ($attributes as $key => $value) { | |
| 271 | + if (isset($this->children[$i]->attributes[$key]) && | |
| 272 | + $this->children[$i]->attributes[$key] == $value) { | |
| 273 | + $attrMatch++; | |
| 274 | + } | |
| 275 | + } | |
| 276 | + if ($attrMatch == $attrToMatch) { | |
| 277 | + $match++; | |
| 278 | + } | |
| 279 | + } | |
| 280 | + } | |
| 281 | + if ($match == $fieldsToMatch) { | |
| 282 | + $itemsArr[] =& $this->children[$i]; | |
| 283 | + } | |
| 284 | + } | |
| 285 | + if ($index >= 0) { | |
| 286 | + if (isset($itemsArr[$index])) { | |
| 287 | + return $itemsArr[$index]; | |
| 288 | + } else { | |
| 289 | + return false; | |
| 290 | + } | |
| 291 | + } else { | |
| 292 | + if ($count = count($itemsArr)) { | |
| 293 | + return $itemsArr[$count-1]; | |
| 294 | + } else { | |
| 295 | + return false; | |
| 296 | + } | |
| 297 | + } | |
| 298 | + } // end func &getItem | |
| 299 | + | |
| 300 | + /** | |
| 301 | + * Finds a node using XPATH like format. | |
| 302 | + * | |
| 303 | + * The search format is an array: | |
| 304 | + * array(item1, item2, item3, ...) | |
| 305 | + * | |
| 306 | + * Each item can be defined as the following: | |
| 307 | + * item = 'string' : will match the container named 'string' | |
| 308 | + * item = array('string', array('name' => 'xyz')) | |
| 309 | + * will match the container name 'string' whose attribute name is equal to "xyz" | |
| 310 | + * For example : <string name="xyz"> | |
| 311 | + * | |
| 312 | + * @param mixed Search path and attributes | |
| 313 | + * | |
| 314 | + * @return mixed Config_Container object, array of Config_Container objects or false on failure. | |
| 315 | + * @access public | |
| 316 | + */ | |
| 317 | + function &searchPath($args) | |
| 318 | + { | |
| 319 | + if ($this->type != 'section') { | |
| 320 | + return PEAR::raiseError('Config_Container::searchPath must be called on a section type object.', null, PEAR_ERROR_RETURN); | |
| 321 | + } | |
| 322 | + | |
| 323 | + $arg = array_shift($args); | |
| 324 | + | |
| 325 | + if (is_array($arg)) { | |
| 326 | + $name = $arg[0]; | |
| 327 | + $attributes = $arg[1]; | |
| 328 | + } else { | |
| 329 | + $name = $arg; | |
| 330 | + $attributes = null; | |
| 331 | + } | |
| 332 | + // find all the matches for first.. | |
| 333 | + $match =& $this->getItem(null, $name, null, $attributes); | |
| 334 | + | |
| 335 | + if (!$match) { | |
| 336 | + return false; | |
| 337 | + } | |
| 338 | + if (!empty($args)) { | |
| 339 | + return $match->searchPath($args); | |
| 340 | + } | |
| 341 | + return $match; | |
| 342 | + } // end func &searchPath | |
| 343 | + | |
| 344 | + /** | |
| 345 | + * Return a child directive's content. | |
| 346 | + * | |
| 347 | + * This method can use two different search approach, depending on | |
| 348 | + * the parameter it is given. If the parameter is an array, it will use | |
| 349 | + * the {@link Config_Container::searchPath()} method. If it is a string, | |
| 350 | + * it will use the {@link Config_Container::getItem()} method. | |
| 351 | + * | |
| 352 | + * Example: | |
| 353 | + * <code> | |
| 354 | + * require_once 'Config.php'; | |
| 355 | + * $ini = new Config(); | |
| 356 | + * $conf =& $ini->parseConfig('/path/to/config.ini', 'inicommented'); | |
| 357 | + * | |
| 358 | + * // Will return the value found at : | |
| 359 | + * // [Database] | |
| 360 | + * // host=localhost | |
| 361 | + * echo $conf->directiveContent(array('Database', 'host'))); | |
| 362 | + * | |
| 363 | + * // Will return the value found at : | |
| 364 | + * // date="dec-2004" | |
| 365 | + * echo $conf->directiveContent('date'); | |
| 366 | + * | |
| 367 | + * </code> | |
| 368 | + * | |
| 369 | + * @param mixed Search path and attributes or a directive name | |
| 370 | + * @param int Index of the item in the returned directive list. | |
| 371 | + * Eventually used if args is a string. | |
| 372 | + * | |
| 373 | + * @return mixed Content of directive or false if not found. | |
| 374 | + * @access public | |
| 375 | + */ | |
| 376 | + function directiveContent($args, $index = -1) | |
| 377 | + { | |
| 378 | + if (is_array($args)) { | |
| 379 | + $item =& $this->searchPath($args); | |
| 380 | + } else { | |
| 381 | + $item =& $this->getItem('directive', $args, null, null, $index); | |
| 382 | + } | |
| 383 | + if ($item) { | |
| 384 | + return $item->getContent(); | |
| 385 | + } | |
| 386 | + return false; | |
| 387 | + } // end func getDirectiveContent | |
| 388 | + | |
| 389 | + /** | |
| 390 | + * Returns how many children this container has | |
| 391 | + * | |
| 392 | + * @param string $type type of children counted | |
| 393 | + * @param string $name name of children counted | |
| 394 | + * @return int number of children found | |
| 395 | + */ | |
| 396 | + function countChildren($type = null, $name = null) | |
| 397 | + { | |
| 398 | + if (is_null($type) && is_null($name)) { | |
| 399 | + return count($this->children); | |
| 400 | + } | |
| 401 | + $count = 0; | |
| 402 | + if (isset($name) && isset($type)) { | |
| 403 | + for ($i = 0, $children = count($this->children); $i < $children; $i++) { | |
| 404 | + if ($this->children[$i]->name == $name && | |
| 405 | + $this->children[$i]->type == $type) { | |
| 406 | + $count++; | |
| 407 | + } | |
| 408 | + } | |
| 409 | + return $count; | |
| 410 | + } | |
| 411 | + if (isset($type)) { | |
| 412 | + for ($i = 0, $children = count($this->children); $i < $children; $i++) { | |
| 413 | + if ($this->children[$i]->type == $type) { | |
| 414 | + $count++; | |
| 415 | + } | |
| 416 | + } | |
| 417 | + return $count; | |
| 418 | + } | |
| 419 | + if (isset($name)) { | |
| 420 | + // Some directives can have the same name | |
| 421 | + for ($i = 0, $children = count($this->children); $i < $children; $i++) { | |
| 422 | + if ($this->children[$i]->name == $name) { | |
| 423 | + $count++; | |
| 424 | + } | |
| 425 | + } | |
| 426 | + return $count; | |
| 427 | + } | |
| 428 | + } // end func &countChildren | |
| 429 | + | |
| 430 | + /** | |
| 431 | + * Deletes an item (section, directive, comment...) from the current object | |
| 432 | + * TODO: recursive remove in sub-sections | |
| 433 | + * @return mixed true if object was removed, false if not, or PEAR_Error if root | |
| 434 | + */ | |
| 435 | + function removeItem() | |
| 436 | + { | |
| 437 | + if ($this->isRoot()) { | |
| 438 | + return PEAR::raiseError('Cannot remove root item in Config_Container::removeItem.', null, PEAR_ERROR_RETURN); | |
| 439 | + } | |
| 440 | + $index = $this->getItemIndex(); | |
| 441 | + if (!is_null($index)) { | |
| 442 | + array_splice($this->parent->children, $index, 1); | |
| 443 | + return true; | |
| 444 | + } | |
| 445 | + return false; | |
| 446 | + } // end func removeItem | |
| 447 | + | |
| 448 | + /** | |
| 449 | + * Returns the item index in its parent children array. | |
| 450 | + * @return int returns int or null if root object | |
| 451 | + */ | |
| 452 | + function getItemIndex() | |
| 453 | + { | |
| 454 | + if (is_object($this->parent)) { | |
| 455 | + // This will be optimized with Zend Engine 2 | |
| 456 | + $pchildren =& $this->parent->children; | |
| 457 | + for ($i = 0, $count = count($pchildren); $i < $count; $i++) { | |
| 458 | + if ($pchildren[$i]->_id == $this->_id) { | |
| 459 | + return $i; | |
| 460 | + } | |
| 461 | + } | |
| 462 | + } | |
| 463 | + return; | |
| 464 | + } // end func getItemIndex | |
| 465 | + | |
| 466 | + /** | |
| 467 | + * Returns the item rank in its parent children array | |
| 468 | + * according to other items with same type and name. | |
| 469 | + * @return int returns int or null if root object | |
| 470 | + */ | |
| 471 | + function getItemPosition() | |
| 472 | + { | |
| 473 | + if (is_object($this->parent)) { | |
| 474 | + $pchildren =& $this->parent->children; | |
| 475 | + for ($i = 0, $count = count($pchildren); $i < $count; $i++) { | |
| 476 | + if ($pchildren[$i]->name == $this->name && | |
| 477 | + $pchildren[$i]->type == $this->type) { | |
| 478 | + $obj[] =& $pchildren[$i]; | |
| 479 | + } | |
| 480 | + } | |
| 481 | + for ($i = 0, $count = count($obj); $i < $count; $i++) { | |
| 482 | + if ($obj[$i]->_id == $this->_id) { | |
| 483 | + return $i; | |
| 484 | + } | |
| 485 | + } | |
| 486 | + } | |
| 487 | + return; | |
| 488 | + } // end func getItemPosition | |
| 489 | + | |
| 490 | + /** | |
| 491 | + * Returns the item parent object. | |
| 492 | + * @return object returns reference to parent object or null if root object | |
| 493 | + */ | |
| 494 | + function &getParent() | |
| 495 | + { | |
| 496 | + return $this->parent; | |
| 497 | + } // end func &getParent | |
| 498 | + | |
| 499 | + /** | |
| 500 | + * Returns the item parent object. | |
| 501 | + * @return mixed returns reference to child object or false if child does not exist | |
| 502 | + */ | |
| 503 | + function &getChild($index = 0) | |
| 504 | + { | |
| 505 | + if (!empty($this->children[$index])) { | |
| 506 | + return $this->children[$index]; | |
| 507 | + } else { | |
| 508 | + return false; | |
| 509 | + } | |
| 510 | + } // end func &getChild | |
| 511 | + | |
| 512 | + /** | |
| 513 | + * Set this item's name. | |
| 514 | + * @return void | |
| 515 | + */ | |
| 516 | + function setName($name) | |
| 517 | + { | |
| 518 | + $this->name = $name; | |
| 519 | + } // end func setName | |
| 520 | + | |
| 521 | + /** | |
| 522 | + * Get this item's name. | |
| 523 | + * @return string item's name | |
| 524 | + */ | |
| 525 | + function getName() | |
| 526 | + { | |
| 527 | + return $this->name; | |
| 528 | + } // end func getName | |
| 529 | + | |
| 530 | + /** | |
| 531 | + * Set this item's content. | |
| 532 | + * @return void | |
| 533 | + */ | |
| 534 | + function setContent($content) | |
| 535 | + { | |
| 536 | + $this->content = $content; | |
| 537 | + } // end func setContent | |
| 538 | + | |
| 539 | + /** | |
| 540 | + * Get this item's content. | |
| 541 | + * @return string item's content | |
| 542 | + */ | |
| 543 | + function getContent() | |
| 544 | + { | |
| 545 | + return $this->content; | |
| 546 | + } // end func getContent | |
| 547 | + | |
| 548 | + /** | |
| 549 | + * Set this item's type. | |
| 550 | + * @return void | |
| 551 | + */ | |
| 552 | + function setType($type) | |
| 553 | + { | |
| 554 | + $this->type = $type; | |
| 555 | + } // end func setType | |
| 556 | + | |
| 557 | + /** | |
| 558 | + * Get this item's type. | |
| 559 | + * @return string item's type | |
| 560 | + */ | |
| 561 | + function getType() | |
| 562 | + { | |
| 563 | + return $this->type; | |
| 564 | + } // end func getType | |
| 565 | + | |
| 566 | + /** | |
| 567 | + * Set this item's attributes. | |
| 568 | + * @param array $attributes Array of attributes | |
| 569 | + * @return void | |
| 570 | + */ | |
| 571 | + function setAttributes($attributes) | |
| 572 | + { | |
| 573 | + $this->attributes = $attributes; | |
| 574 | + } // end func setAttributes | |
| 575 | + | |
| 576 | + /** | |
| 577 | + * Set this item's attributes. | |
| 578 | + * @param array $attributes Array of attributes | |
| 579 | + * @return void | |
| 580 | + */ | |
| 581 | + function updateAttributes($attributes) | |
| 582 | + { | |
| 583 | + if (is_array($attributes)) { | |
| 584 | + foreach ($attributes as $key => $value) { | |
| 585 | + $this->attributes[$key] = $value; | |
| 586 | + } | |
| 587 | + } | |
| 588 | + } // end func updateAttributes | |
| 589 | + | |
| 590 | + /** | |
| 591 | + * Get this item's attributes. | |
| 592 | + * @return array item's attributes | |
| 593 | + */ | |
| 594 | + function getAttributes() | |
| 595 | + { | |
| 596 | + return $this->attributes; | |
| 597 | + } // end func getAttributes | |
| 598 | + | |
| 599 | + /** | |
| 600 | + * Get one attribute value of this item | |
| 601 | + * @param string $attribute Attribute key | |
| 602 | + * @return mixed item's attribute value | |
| 603 | + */ | |
| 604 | + function getAttribute($attribute) | |
| 605 | + { | |
| 606 | + if (isset($this->attributes[$attribute])) { | |
| 607 | + return $this->attributes[$attribute]; | |
| 608 | + } | |
| 609 | + return null; | |
| 610 | + } // end func getAttribute | |
| 611 | + | |
| 612 | + /** | |
| 613 | + * Set a children directive content. | |
| 614 | + * This is an helper method calling getItem and addItem or setContent for you. | |
| 615 | + * If the directive does not exist, it will be created at the bottom. | |
| 616 | + * | |
| 617 | + * @param string $name Name of the directive to look for | |
| 618 | + * @param mixed $content New content | |
| 619 | + * @param int $index Index of the directive to set, | |
| 620 | + * in case there are more than one directive | |
| 621 | + * with the same name | |
| 622 | + * @return object newly set directive | |
| 623 | + */ | |
| 624 | + function &setDirective($name, $content, $index = -1) | |
| 625 | + { | |
| 626 | + $item =& $this->getItem('directive', $name, null, null, $index); | |
| 627 | + if ($item === false || PEAR::isError($item)) { | |
| 628 | + // Directive does not exist, will create one | |
| 629 | + unset($item); | |
| 630 | + return $this->createDirective($name, $content, null); | |
| 631 | + } else { | |
| 632 | + // Change existing directive value | |
| 633 | + $item->setContent($content); | |
| 634 | + return $item; | |
| 635 | + } | |
| 636 | + } // end func setDirective | |
| 637 | + | |
| 638 | + /** | |
| 639 | + * Is this item root, in a config container object | |
| 640 | + * @return bool true if item is root | |
| 641 | + */ | |
| 642 | + function isRoot() | |
| 643 | + { | |
| 644 | + if (is_null($this->parent)) { | |
| 645 | + return true; | |
| 646 | + } | |
| 647 | + return false; | |
| 648 | + } // end func isRoot | |
| 649 | + | |
| 650 | + /** | |
| 651 | + * Call the toString methods in the container plugin | |
| 652 | + * @param string $configType Type of configuration used to generate the string | |
| 653 | + * @param array $options Specify special options used by the parser | |
| 654 | + * @return mixed true on success or PEAR_ERROR | |
| 655 | + */ | |
| 656 | + function toString($configType, $options = array()) | |
| 657 | + { | |
| 658 | + $configType = strtolower($configType); | |
| 659 | + if (!isset($GLOBALS['CONFIG_TYPES'][$configType])) { | |
| 660 | + return PEAR::raiseError("Configuration type '$configType' is not registered in Config_Container::toString.", null, PEAR_ERROR_RETURN); | |
| 661 | + } | |
| 662 | + $includeFile = $GLOBALS['CONFIG_TYPES'][$configType][0]; | |
| 663 | + $className = $GLOBALS['CONFIG_TYPES'][$configType][1]; | |
| 664 | + include_once($includeFile); | |
| 665 | + $renderer = new $className($options); | |
| 666 | + return $renderer->toString($this); | |
| 667 | + } // end func toString | |
| 668 | + | |
| 669 | + /** | |
| 670 | + * Returns a key/value pair array of the container and its children. | |
| 671 | + * | |
| 672 | + * Format : section[directive][index] = value | |
| 673 | + * If the container has attributes, it will use '@' and '#' | |
| 674 | + * index is here because multiple directives can have the same name. | |
| 675 | + * | |
| 676 | + * @param bool $useAttr Whether to return the attributes too | |
| 677 | + * @return array | |
| 678 | + */ | |
| 679 | + function toArray($useAttr = true) | |
| 680 | + { | |
| 681 | + $array[$this->name] = array(); | |
| 682 | + switch ($this->type) { | |
| 683 | + case 'directive': | |
| 684 | + if ($useAttr && count($this->attributes) > 0) { | |
| 685 | + $array[$this->name]['#'] = $this->content; | |
| 686 | + $array[$this->name]['@'] = $this->attributes; | |
| 687 | + } else { | |
| 688 | + $array[$this->name] = $this->content; | |
| 689 | + } | |
| 690 | + break; | |
| 691 | + case 'section': | |
| 692 | + if ($useAttr && count($this->attributes) > 0) { | |
| 693 | + $array[$this->name]['@'] = $this->attributes; | |
| 694 | + } | |
| 695 | + if ($count = count($this->children)) { | |
| 696 | + for ($i = 0; $i < $count; $i++) { | |
| 697 | + $newArr = $this->children[$i]->toArray($useAttr); | |
| 698 | + if (!is_null($newArr)) { | |
| 699 | + foreach ($newArr as $key => $value) { | |
| 700 | + if (isset($array[$this->name][$key])) { | |
| 701 | + // duplicate name/type | |
| 702 | + if (!is_array($array[$this->name][$key]) || | |
| 703 | + !isset($array[$this->name][$key][0])) { | |
| 704 | + $old = $array[$this->name][$key]; | |
| 705 | + unset($array[$this->name][$key]); | |
| 706 | + $array[$this->name][$key][0] = $old; | |
| 707 | + } | |
| 708 | + $array[$this->name][$key][] = $value; | |
| 709 | + } else { | |
| 710 | + $array[$this->name][$key] = $value; | |
| 711 | + } | |
| 712 | + } | |
| 713 | + } | |
| 714 | + } | |
| 715 | + } | |
| 716 | + break; | |
| 717 | + default: | |
| 718 | + return null; | |
| 719 | + } | |
| 720 | + return $array; | |
| 721 | + } // end func toArray | |
| 722 | + | |
| 723 | + /** | |
| 724 | + * Writes the configuration to a file | |
| 725 | + * | |
| 726 | + * @param mixed $datasrc Info on datasource such as path to the configuraton file or dsn... | |
| 727 | + * @param string $configType Type of configuration | |
| 728 | + * @param array $options Options for writer | |
| 729 | + * @access public | |
| 730 | + * @return mixed true on success or PEAR_ERROR | |
| 731 | + */ | |
| 732 | + function writeDatasrc($datasrc, $configType, $options = array()) | |
| 733 | + { | |
| 734 | + $configType = strtolower($configType); | |
| 735 | + if (!isset($GLOBALS['CONFIG_TYPES'][$configType])) { | |
| 736 | + return PEAR::raiseError("Configuration type '$configType' is not registered in Config_Container::writeDatasrc.", null, PEAR_ERROR_RETURN); | |
| 737 | + } | |
| 738 | + $includeFile = $GLOBALS['CONFIG_TYPES'][$configType][0]; | |
| 739 | + $className = $GLOBALS['CONFIG_TYPES'][$configType][1]; | |
| 740 | + include_once($includeFile); | |
| 741 | + | |
| 742 | + $writeMethodName = (version_compare(phpversion(), '5', '<')) ? 'writedatasrc' : 'writeDatasrc'; | |
| 743 | + if (in_array($writeMethodName, get_class_methods($className))) { | |
| 744 | + $writer = new $className($options); | |
| 745 | + return $writer->writeDatasrc($datasrc, $this); | |
| 746 | + } | |
| 747 | + | |
| 748 | + // Default behaviour | |
| 749 | + $fp = @fopen($datasrc, 'w'); | |
| 750 | + if ($fp) { | |
| 751 | + $string = $this->toString($configType, $options); | |
| 752 | + $len = strlen($string); | |
| 753 | + @flock($fp, LOCK_EX); | |
| 754 | + @fwrite($fp, $string, $len); | |
| 755 | + @flock($fp, LOCK_UN); | |
| 756 | + @fclose($fp); | |
| 757 | + return true; | |
| 758 | + } else { | |
| 759 | + return PEAR::raiseError('Cannot open datasource for writing.', 1, PEAR_ERROR_RETURN); | |
| 760 | + } | |
| 761 | + } // end func writeDatasrc | |
| 762 | +} // end class Config_Container | |
| 763 | +?> | ... | ... |
thirdparty/pear/Config/Container/Apache.php
0 → 100644
| 1 | +<?php | |
| 2 | +// +----------------------------------------------------------------------+ | |
| 3 | +// | PHP Version 4 | | |
| 4 | +// +----------------------------------------------------------------------+ | |
| 5 | +// | Copyright (c) 1997-2003 The PHP Group | | |
| 6 | +// +----------------------------------------------------------------------+ | |
| 7 | +// | This source file is subject to version 2.0 of the PHP license, | | |
| 8 | +// | that is bundled with this package in the file LICENSE, and is | | |
| 9 | +// | available at through the world-wide-web at | | |
| 10 | +// | http://www.php.net/license/2_02.txt. | | |
| 11 | +// | If you did not receive a copy of the PHP license and are unable to | | |
| 12 | +// | obtain it through the world-wide-web, please send a note to | | |
| 13 | +// | license@php.net so we can mail you a copy immediately. | | |
| 14 | +// +----------------------------------------------------------------------+ | |
| 15 | +// | Author: Bertrand Mansion <bmansion@mamasam.com> | | |
| 16 | +// +----------------------------------------------------------------------+ | |
| 17 | +// | |
| 18 | +// $Id$ | |
| 19 | + | |
| 20 | +/** | |
| 21 | +* Simple config parser for apache httpd.conf files | |
| 22 | +* A more complex version could handle directives as | |
| 23 | +* associative arrays. | |
| 24 | +* | |
| 25 | +* @author Bertrand Mansion <bmansion@mamasam.com> | |
| 26 | +* @package Config | |
| 27 | +*/ | |
| 28 | +class Config_Container_Apache { | |
| 29 | + | |
| 30 | + /** | |
| 31 | + * This class options | |
| 32 | + * Not used at the moment | |
| 33 | + * | |
| 34 | + * @var array | |
| 35 | + */ | |
| 36 | + var $options = array(); | |
| 37 | + | |
| 38 | + /** | |
| 39 | + * Constructor | |
| 40 | + * | |
| 41 | + * @access public | |
| 42 | + * @param string $options (optional)Options to be used by renderer | |
| 43 | + */ | |
| 44 | + function Config_Container_Apache($options = array()) | |
| 45 | + { | |
| 46 | + $this->options = $options; | |
| 47 | + } // end constructor | |
| 48 | + | |
| 49 | + /** | |
| 50 | + * Parses the data of the given configuration file | |
| 51 | + * | |
| 52 | + * @access public | |
| 53 | + * @param string $datasrc path to the configuration file | |
| 54 | + * @param object $obj reference to a config object | |
| 55 | + * @return mixed returns a PEAR_ERROR, if error occurs or true if ok | |
| 56 | + */ | |
| 57 | + function &parseDatasrc($datasrc, &$obj) | |
| 58 | + { | |
| 59 | + if (!is_readable($datasrc)) { | |
| 60 | + return PEAR::raiseError("Datasource file cannot be read.", null, PEAR_ERROR_RETURN); | |
| 61 | + } | |
| 62 | + $lines = file($datasrc); | |
| 63 | + $n = 0; | |
| 64 | + $lastline = ''; | |
| 65 | + $sections[0] =& $obj->container; | |
| 66 | + foreach ($lines as $line) { | |
| 67 | + $n++; | |
| 68 | + if (!preg_match('/^\s*#/', $line) && | |
| 69 | + preg_match('/^\s*(.*)\s+\\\$/', $line, $match)) { | |
| 70 | + // directive on more than one line | |
| 71 | + $lastline .= $match[1].' '; | |
| 72 | + continue; | |
| 73 | + } | |
| 74 | + if ($lastline != '') { | |
| 75 | + $line = $lastline.trim($line); | |
| 76 | + $lastline = ''; | |
| 77 | + } | |
| 78 | + if (preg_match('/^\s*#+\s*(.*?)\s*$/', $line, $match)) { | |
| 79 | + // a comment | |
| 80 | + $currentSection =& $sections[count($sections)-1]; | |
| 81 | + $currentSection->createComment($match[1]); | |
| 82 | + } elseif (trim($line) == '') { | |
| 83 | + // a blank line | |
| 84 | + $currentSection =& $sections[count($sections)-1]; | |
| 85 | + $currentSection->createBlank(); | |
| 86 | + } elseif (preg_match('/^\s*(\w+)(?:\s+(.*?)|)\s*$/', $line, $match)) { | |
| 87 | + // a directive | |
| 88 | + $currentSection =& $sections[count($sections)-1]; | |
| 89 | + $currentSection->createDirective($match[1], $match[2]); | |
| 90 | + } elseif (preg_match('/^\s*<(\w+)(?:\s+([^>]*)|\s*)>\s*$/', $line, $match)) { | |
| 91 | + // a section opening | |
| 92 | + if (!isset($match[2])) | |
| 93 | + $match[2] = ''; | |
| 94 | + $currentSection =& $sections[count($sections)-1]; | |
| 95 | + $attributes = explode(' ', $match[2]); | |
| 96 | + $sections[] =& $currentSection->createSection($match[1], $attributes); | |
| 97 | + } elseif (preg_match('/^\s*<\/(\w+)\s*>\s*$/', $line, $match)) { | |
| 98 | + // a section closing | |
| 99 | + $currentSection =& $sections[count($sections)-1]; | |
| 100 | + if ($currentSection->name != $match[1]) { | |
| 101 | + return PEAR::raiseError("Section not closed in '$datasrc' at line $n.", null, PEAR_ERROR_RETURN); | |
| 102 | + } | |
| 103 | + array_pop($sections); | |
| 104 | + } else { | |
| 105 | + return PEAR::raiseError("Syntax error in '$datasrc' at line $n.", null, PEAR_ERROR_RETURN); | |
| 106 | + } | |
| 107 | + } | |
| 108 | + return true; | |
| 109 | + } // end func parseDatasrc | |
| 110 | + | |
| 111 | + /** | |
| 112 | + * Returns a formatted string of the object | |
| 113 | + * @param object $obj Container object to be output as string | |
| 114 | + * @access public | |
| 115 | + * @return string | |
| 116 | + */ | |
| 117 | + function toString(&$obj) | |
| 118 | + { | |
| 119 | + static $deep = -1; | |
| 120 | + $ident = ''; | |
| 121 | + if (!$obj->isRoot()) { | |
| 122 | + // no indent for root | |
| 123 | + $deep++; | |
| 124 | + $ident = str_repeat(' ', $deep); | |
| 125 | + } | |
| 126 | + if (!isset($string)) { | |
| 127 | + $string = ''; | |
| 128 | + } | |
| 129 | + switch ($obj->type) { | |
| 130 | + case 'blank': | |
| 131 | + $string = "\n"; | |
| 132 | + break; | |
| 133 | + case 'comment': | |
| 134 | + $string = $ident.'# '.$obj->content."\n"; | |
| 135 | + break; | |
| 136 | + case 'directive': | |
| 137 | + $string = $ident.$obj->name.' '.$obj->content."\n"; | |
| 138 | + break; | |
| 139 | + case 'section': | |
| 140 | + if (!$obj->isRoot()) { | |
| 141 | + $string = $ident.'<'.$obj->name; | |
| 142 | + if (is_array($obj->attributes) && count($obj->attributes) > 0) { | |
| 143 | + while (list(,$val) = each($obj->attributes)) { | |
| 144 | + $string .= ' '.$val; | |
| 145 | + } | |
| 146 | + } | |
| 147 | + $string .= ">\n"; | |
| 148 | + } | |
| 149 | + if (count($obj->children) > 0) { | |
| 150 | + for ($i = 0; $i < count($obj->children); $i++) { | |
| 151 | + $string .= $this->toString($obj->getChild($i)); | |
| 152 | + } | |
| 153 | + } | |
| 154 | + if (!$obj->isRoot()) { | |
| 155 | + // object is not root | |
| 156 | + $string .= $ident.'</'.$obj->name.">\n"; | |
| 157 | + } | |
| 158 | + break; | |
| 159 | + default: | |
| 160 | + $string = ''; | |
| 161 | + } | |
| 162 | + if (!$obj->isRoot()) { | |
| 163 | + $deep--; | |
| 164 | + } | |
| 165 | + return $string; | |
| 166 | + } // end func toString | |
| 167 | +} // end class Config_Container_Apache | |
| 168 | +?> | |
| 0 | 169 | \ No newline at end of file | ... | ... |
thirdparty/pear/Config/Container/GenericConf.php
0 → 100644
| 1 | +<?php | |
| 2 | +// +----------------------------------------------------------------------+ | |
| 3 | +// | PHP Version 4 | | |
| 4 | +// +----------------------------------------------------------------------+ | |
| 5 | +// | Copyright (c) 1997-2003 The PHP Group | | |
| 6 | +// +----------------------------------------------------------------------+ | |
| 7 | +// | This source file is subject to version 2.0 of the PHP license, | | |
| 8 | +// | that is bundled with this package in the file LICENSE, and is | | |
| 9 | +// | available at through the world-wide-web at | | |
| 10 | +// | http://www.php.net/license/2_02.txt. | | |
| 11 | +// | If you did not receive a copy of the PHP license and are unable to | | |
| 12 | +// | obtain it through the world-wide-web, please send a note to | | |
| 13 | +// | license@php.net so we can mail you a copy immediately. | | |
| 14 | +// +----------------------------------------------------------------------+ | |
| 15 | +// | Author: Bertrand Mansion <bmansion@mamasam.com> | | |
| 16 | +// +----------------------------------------------------------------------+ | |
| 17 | +// | |
| 18 | +// $Id$ | |
| 19 | + | |
| 20 | +/** | |
| 21 | +* Config parser for generic .conf files like | |
| 22 | +* htdig.conf... | |
| 23 | +* | |
| 24 | +* @author Bertrand Mansion <bmansion@mamasam.com> | |
| 25 | +* @package Config | |
| 26 | +*/ | |
| 27 | +class Config_Container_GenericConf { | |
| 28 | + | |
| 29 | + /** | |
| 30 | + * This class options: | |
| 31 | + * Ex: $options['comment'] = '#'; | |
| 32 | + * Ex: $options['equals'] = ':'; | |
| 33 | + * Ex: $options['newline'] = '\\'; | |
| 34 | + * | |
| 35 | + * @var array | |
| 36 | + */ | |
| 37 | + var $options = array(); | |
| 38 | + | |
| 39 | + /** | |
| 40 | + * Constructor | |
| 41 | + * | |
| 42 | + * @access public | |
| 43 | + * @param string $options (optional)Options to be used by renderer | |
| 44 | + */ | |
| 45 | + function Config_Container_GenericConf($options = array()) | |
| 46 | + { | |
| 47 | + if (empty($options['comment'])) { | |
| 48 | + $options['comment'] = '#'; | |
| 49 | + } | |
| 50 | + if (empty($options['equals'])) { | |
| 51 | + $options['equals'] = ':'; | |
| 52 | + } | |
| 53 | + if (empty($options['newline'])) { | |
| 54 | + $options['newline'] = '\\'; | |
| 55 | + } | |
| 56 | + $this->options = $options; | |
| 57 | + } // end constructor | |
| 58 | + | |
| 59 | + /** | |
| 60 | + * Parses the data of the given configuration file | |
| 61 | + * | |
| 62 | + * @access public | |
| 63 | + * @param string $datasrc path to the configuration file | |
| 64 | + * @param object $obj reference to a config object | |
| 65 | + * @return mixed returns a PEAR_ERROR, if error occurs or true if ok | |
| 66 | + */ | |
| 67 | + function &parseDatasrc($datasrc, &$obj) | |
| 68 | + { | |
| 69 | + if (!is_readable($datasrc)) { | |
| 70 | + return PEAR::raiseError("Datasource file cannot be read.", null, PEAR_ERROR_RETURN); | |
| 71 | + } | |
| 72 | + | |
| 73 | + $lines = file($datasrc); | |
| 74 | + $n = 0; | |
| 75 | + $lastline = ''; | |
| 76 | + $currentSection =& $obj->container; | |
| 77 | + foreach ($lines as $line) { | |
| 78 | + $n++; | |
| 79 | + if (!preg_match('/^\s*'.$this->options['comment'].'/', $line) && | |
| 80 | + preg_match('/^\s*(.*)\s+'.$this->options['newline'].'\s*$/', $line, $match)) { | |
| 81 | + // directive on more than one line | |
| 82 | + $lastline .= $match[1].' '; | |
| 83 | + continue; | |
| 84 | + } | |
| 85 | + if ($lastline != '') { | |
| 86 | + $line = $lastline.trim($line); | |
| 87 | + $lastline = ''; | |
| 88 | + } | |
| 89 | + if (preg_match('/^\s*'.$this->options['comment'].'+\s*(.*?)\s*$/', $line, $match)) { | |
| 90 | + // a comment | |
| 91 | + $currentSection->createComment($match[1]); | |
| 92 | + } elseif (preg_match('/^\s*$/', $line)) { | |
| 93 | + // a blank line | |
| 94 | + $currentSection->createBlank(); | |
| 95 | + } elseif (preg_match('/^\s*(\w+)'.$this->options['equals'].'\s*((.*?)|)\s*$/', $line, $match)) { | |
| 96 | + // a directive | |
| 97 | + $currentSection->createDirective($match[1], $match[2]); | |
| 98 | + } else { | |
| 99 | + return PEAR::raiseError("Syntax error in '$datasrc' at line $n.", null, PEAR_ERROR_RETURN); | |
| 100 | + } | |
| 101 | + } | |
| 102 | + return true; | |
| 103 | + } // end func parseDatasrc | |
| 104 | + | |
| 105 | + /** | |
| 106 | + * Returns a formatted string of the object | |
| 107 | + * @param object $obj Container object to be output as string | |
| 108 | + * @access public | |
| 109 | + * @return string | |
| 110 | + */ | |
| 111 | + function toString(&$obj) | |
| 112 | + { | |
| 113 | + $string = ''; | |
| 114 | + switch ($obj->type) { | |
| 115 | + case 'blank': | |
| 116 | + $string = "\n"; | |
| 117 | + break; | |
| 118 | + case 'comment': | |
| 119 | + $string = $this->options['comment'].$obj->content."\n"; | |
| 120 | + break; | |
| 121 | + case 'directive': | |
| 122 | + $string = $obj->name.$this->options['equals'].$obj->content."\n"; | |
| 123 | + break; | |
| 124 | + case 'section': | |
| 125 | + // How to deal with sections ??? | |
| 126 | + if (count($obj->children) > 0) { | |
| 127 | + for ($i = 0; $i < count($obj->children); $i++) { | |
| 128 | + $string .= $this->toString($obj->getChild($i)); | |
| 129 | + } | |
| 130 | + } | |
| 131 | + break; | |
| 132 | + default: | |
| 133 | + $string = ''; | |
| 134 | + } | |
| 135 | + return $string; | |
| 136 | + } // end func toString | |
| 137 | +} // end class Config_Container_GenericConf | |
| 138 | +?> | |
| 0 | 139 | \ No newline at end of file | ... | ... |
thirdparty/pear/Config/Container/IniCommented.php
0 → 100644
| 1 | +<?php | |
| 2 | +// +----------------------------------------------------------------------+ | |
| 3 | +// | PHP Version 4 | | |
| 4 | +// +----------------------------------------------------------------------+ | |
| 5 | +// | Copyright (c) 1997-2003 The PHP Group | | |
| 6 | +// +----------------------------------------------------------------------+ | |
| 7 | +// | This source file is subject to version 2.0 of the PHP license, | | |
| 8 | +// | that is bundled with this package in the file LICENSE, and is | | |
| 9 | +// | available at through the world-wide-web at | | |
| 10 | +// | http://www.php.net/license/2_02.txt. | | |
| 11 | +// | If you did not receive a copy of the PHP license and are unable to | | |
| 12 | +// | obtain it through the world-wide-web, please send a note to | | |
| 13 | +// | license@php.net so we can mail you a copy immediately. | | |
| 14 | +// +----------------------------------------------------------------------+ | |
| 15 | +// | Author: Bertrand Mansion <bmansion@mamasam.com> | | |
| 16 | +// +----------------------------------------------------------------------+ | |
| 17 | +// | |
| 18 | +// $Id$ | |
| 19 | + | |
| 20 | +/** | |
| 21 | +* Config parser for PHP .ini files with comments | |
| 22 | +* | |
| 23 | +* @author Bertrand Mansion <bmansion@mamasam.com> | |
| 24 | +* @package Config | |
| 25 | +*/ | |
| 26 | +class Config_Container_IniCommented { | |
| 27 | + | |
| 28 | + /** | |
| 29 | + * This class options | |
| 30 | + * Not used at the moment | |
| 31 | + * | |
| 32 | + * @var array | |
| 33 | + */ | |
| 34 | + var $options = array(); | |
| 35 | + | |
| 36 | + /** | |
| 37 | + * Constructor | |
| 38 | + * | |
| 39 | + * @access public | |
| 40 | + * @param string $options (optional)Options to be used by renderer | |
| 41 | + */ | |
| 42 | + function Config_Container_IniCommented($options = array()) | |
| 43 | + { | |
| 44 | + $this->options = $options; | |
| 45 | + } // end constructor | |
| 46 | + | |
| 47 | + /** | |
| 48 | + * Parses the data of the given configuration file | |
| 49 | + * | |
| 50 | + * @access public | |
| 51 | + * @param string $datasrc path to the configuration file | |
| 52 | + * @param object $obj reference to a config object | |
| 53 | + * @return mixed returns a PEAR_ERROR, if error occurs or true if ok | |
| 54 | + */ | |
| 55 | + function &parseDatasrc($datasrc, &$obj) | |
| 56 | + { | |
| 57 | + if (!file_exists($datasrc)) { | |
| 58 | + return PEAR::raiseError("Datasource file does not exist.", null, PEAR_ERROR_RETURN); | |
| 59 | + } | |
| 60 | + $lines = file($datasrc); | |
| 61 | + $n = 0; | |
| 62 | + $lastline = ''; | |
| 63 | + $currentSection =& $obj->container; | |
| 64 | + foreach ($lines as $line) { | |
| 65 | + $n++; | |
| 66 | + if (preg_match('/^\s*;(.*?)\s*$/', $line, $match)) { | |
| 67 | + // a comment | |
| 68 | + $currentSection->createComment($match[1]); | |
| 69 | + } elseif (preg_match('/^\s*$/', $line)) { | |
| 70 | + // a blank line | |
| 71 | + $currentSection->createBlank(); | |
| 72 | + } elseif (preg_match('/^\s*([a-zA-Z0-9_\-\.\s]*)\s*=\s*(.*)\s*$/', $line, $match)) { | |
| 73 | + // a directive | |
| 74 | + | |
| 75 | + $values = $this->_quoteAndCommaParser($match[2]); | |
| 76 | + if (PEAR::isError($values)) { | |
| 77 | + return PEAR::raiseError($values); | |
| 78 | + } | |
| 79 | + | |
| 80 | + if (count($values)) { | |
| 81 | + foreach($values as $value) { | |
| 82 | + if ($value[0] == 'normal') { | |
| 83 | + $currentSection->createDirective(trim($match[1]), $value[1]); | |
| 84 | + } | |
| 85 | + if ($value[0] == 'comment') { | |
| 86 | + $currentSection->createComment(substr($value[1], 1)); | |
| 87 | + } | |
| 88 | + } | |
| 89 | + } | |
| 90 | + } elseif (preg_match('/^\s*\[\s*(.*)\s*\]\s*$/', $line, $match)) { | |
| 91 | + // a section | |
| 92 | + $currentSection =& $obj->container->createSection($match[1]); | |
| 93 | + } else { | |
| 94 | + return PEAR::raiseError("Syntax error in '$datasrc' at line $n.", null, PEAR_ERROR_RETURN); | |
| 95 | + } | |
| 96 | + } | |
| 97 | + return true; | |
| 98 | + } // end func parseDatasrc | |
| 99 | + | |
| 100 | + /** | |
| 101 | + * Quote and Comma Parser for INI files | |
| 102 | + * | |
| 103 | + * This function allows complex values such as: | |
| 104 | + * | |
| 105 | + * <samp> | |
| 106 | + * mydirective = "Item, number \"1\"", Item 2 ; "This" is really, really tricky | |
| 107 | + * </samp> | |
| 108 | + * @param string $text value of a directive to parse for quotes/multiple values | |
| 109 | + * @return array The array returned contains multiple values, if any (unquoted literals | |
| 110 | + * to be used as is), and a comment, if any. The format of the array is: | |
| 111 | + * | |
| 112 | + * <pre> | |
| 113 | + * array(array('normal', 'first value'), | |
| 114 | + * array('normal', 'next value'),... | |
| 115 | + * array('comment', '; comment with leading ;')) | |
| 116 | + * </pre> | |
| 117 | + * @author Greg Beaver <cellog@users.sourceforge.net> | |
| 118 | + * @access private | |
| 119 | + */ | |
| 120 | + function _quoteAndCommaParser($text) | |
| 121 | + { | |
| 122 | + $text = trim($text); | |
| 123 | + if ($text == '') { | |
| 124 | + return array(); | |
| 125 | + } | |
| 126 | + | |
| 127 | + // tokens | |
| 128 | + $tokens['normal'] = array('"', ';', ','); | |
| 129 | + $tokens['quote'] = array('"', '\\'); | |
| 130 | + $tokens['escape'] = false; // cycle | |
| 131 | + $tokens['after_quote'] = array(',', ';'); | |
| 132 | + | |
| 133 | + // events | |
| 134 | + $events['normal'] = array('"' => 'quote', ';' => 'comment', ',' => 'normal'); | |
| 135 | + $events['quote'] = array('"' => 'after_quote', '\\' => 'escape'); | |
| 136 | + $events['after_quote'] = array(',' => 'normal', ';' => 'comment'); | |
| 137 | + | |
| 138 | + // state stack | |
| 139 | + $stack = array(); | |
| 140 | + | |
| 141 | + // return information | |
| 142 | + $return = array(); | |
| 143 | + $returnpos = 0; | |
| 144 | + $returntype = 'normal'; | |
| 145 | + | |
| 146 | + // initialize | |
| 147 | + array_push($stack, 'normal'); | |
| 148 | + $pos = 0; // position in $text | |
| 149 | + | |
| 150 | + do { | |
| 151 | + $char = $text{$pos}; | |
| 152 | + $state = $this->_getQACEvent($stack); | |
| 153 | + | |
| 154 | + if ($tokens[$state]) { | |
| 155 | + if (in_array($char, $tokens[$state])) { | |
| 156 | + switch($events[$state][$char]) { | |
| 157 | + case 'quote' : | |
| 158 | + if ($state == 'normal' && | |
| 159 | + isset($return[$returnpos]) && | |
| 160 | + !empty($return[$returnpos][1])) { | |
| 161 | + return PEAR::raiseError("invalid ini syntax, quotes cannot follow text '$text'", | |
| 162 | + null, PEAR_ERROR_RETURN); | |
| 163 | + } | |
| 164 | + if ($returnpos >= 0 && isset($return[$returnpos])) { | |
| 165 | + // trim any unnecessary whitespace in earlier entries | |
| 166 | + $return[$returnpos][1] = trim($return[$returnpos][1]); | |
| 167 | + } else { | |
| 168 | + $returnpos++; | |
| 169 | + } | |
| 170 | + $return[$returnpos] = array('normal', ''); | |
| 171 | + array_push($stack, 'quote'); | |
| 172 | + continue 2; | |
| 173 | + break; | |
| 174 | + case 'comment' : | |
| 175 | + // comments go to the end of the line, so we are done | |
| 176 | + $return[++$returnpos] = array('comment', substr($text, $pos)); | |
| 177 | + return $return; | |
| 178 | + break; | |
| 179 | + case 'after_quote' : | |
| 180 | + array_push($stack, 'after_quote'); | |
| 181 | + break; | |
| 182 | + case 'escape' : | |
| 183 | + // don't save the first slash | |
| 184 | + array_push($stack, 'escape'); | |
| 185 | + continue 2; | |
| 186 | + break; | |
| 187 | + case 'normal' : | |
| 188 | + // start a new segment | |
| 189 | + if ($state == 'normal') { | |
| 190 | + $returnpos++; | |
| 191 | + continue 2; | |
| 192 | + } else { | |
| 193 | + while ($state != 'normal') { | |
| 194 | + array_pop($stack); | |
| 195 | + $state = $this->_getQACEvent($stack); | |
| 196 | + } | |
| 197 | + } | |
| 198 | + break; | |
| 199 | + default : | |
| 200 | + PEAR::raiseError("::_quoteAndCommaParser oops, state missing", null, PEAR_ERROR_DIE); | |
| 201 | + break; | |
| 202 | + } | |
| 203 | + } else { | |
| 204 | + if ($state != 'after_quote') { | |
| 205 | + if (!isset($return[$returnpos])) { | |
| 206 | + $return[$returnpos] = array('normal', ''); | |
| 207 | + } | |
| 208 | + // add this character to the current ini segment if non-empty, or if in a quote | |
| 209 | + if ($state == 'quote') { | |
| 210 | + $return[$returnpos][1] .= $char; | |
| 211 | + } elseif (!empty($return[$returnpos][1]) || | |
| 212 | + (empty($return[$returnpos][1]) && trim($char) != '')) { | |
| 213 | + if (!isset($return[$returnpos])) { | |
| 214 | + $return[$returnpos] = array('normal', ''); | |
| 215 | + } | |
| 216 | + $return[$returnpos][1] .= $char; | |
| 217 | + } | |
| 218 | + } else { | |
| 219 | + if (trim($char) != '') { | |
| 220 | + return PEAR::raiseError("invalid ini syntax, text after a quote not allowed '$text'", | |
| 221 | + null, PEAR_ERROR_RETURN); | |
| 222 | + } | |
| 223 | + } | |
| 224 | + } | |
| 225 | + } else { | |
| 226 | + // no tokens, so add this one and cycle to previous state | |
| 227 | + $return[$returnpos][1] .= $char; | |
| 228 | + array_pop($stack); | |
| 229 | + } | |
| 230 | + } while (++$pos < strlen($text)); | |
| 231 | + return $return; | |
| 232 | + } // end func _quoteAndCommaParser | |
| 233 | + | |
| 234 | + /** | |
| 235 | + * Retrieve the state off of a state stack for the Quote and Comma Parser | |
| 236 | + * @param array $stack The parser state stack | |
| 237 | + * @author Greg Beaver <cellog@users.sourceforge.net> | |
| 238 | + * @access private | |
| 239 | + */ | |
| 240 | + function _getQACEvent($stack) | |
| 241 | + { | |
| 242 | + return array_pop($stack); | |
| 243 | + } // end func _getQACEvent | |
| 244 | + | |
| 245 | + /** | |
| 246 | + * Returns a formatted string of the object | |
| 247 | + * @param object $obj Container object to be output as string | |
| 248 | + * @access public | |
| 249 | + * @return string | |
| 250 | + */ | |
| 251 | + function toString(&$obj) | |
| 252 | + { | |
| 253 | + static $childrenCount, $commaString; | |
| 254 | + | |
| 255 | + if (!isset($string)) { | |
| 256 | + $string = ''; | |
| 257 | + } | |
| 258 | + switch ($obj->type) { | |
| 259 | + case 'blank': | |
| 260 | + $string = "\n"; | |
| 261 | + break; | |
| 262 | + case 'comment': | |
| 263 | + $string = ';'.$obj->content."\n"; | |
| 264 | + break; | |
| 265 | + case 'directive': | |
| 266 | + $count = $obj->parent->countChildren('directive', $obj->name); | |
| 267 | + $content = $obj->content; | |
| 268 | + if ($content === false) { | |
| 269 | + $content = '0'; | |
| 270 | + } elseif ($content === true) { | |
| 271 | + $content = '1'; | |
| 272 | + } elseif (strlen(trim($content)) < strlen($content) || | |
| 273 | + strpos($content, ',') !== false || | |
| 274 | + strpos($content, ';') !== false || | |
| 275 | + strpos($content, '"') !== false || | |
| 276 | + strpos($content, '%') !== false) { | |
| 277 | + $content = '"'.addslashes($content).'"'; | |
| 278 | + } | |
| 279 | + if ($count > 1) { | |
| 280 | + // multiple values for a directive are separated by a comma | |
| 281 | + if (isset($childrenCount[$obj->name])) { | |
| 282 | + $childrenCount[$obj->name]++; | |
| 283 | + } else { | |
| 284 | + $childrenCount[$obj->name] = 0; | |
| 285 | + $commaString[$obj->name] = $obj->name.' = '; | |
| 286 | + } | |
| 287 | + if ($childrenCount[$obj->name] == $count-1) { | |
| 288 | + // Clean the static for future calls to toString | |
| 289 | + $string .= $commaString[$obj->name].$content."\n"; | |
| 290 | + unset($childrenCount[$obj->name]); | |
| 291 | + unset($commaString[$obj->name]); | |
| 292 | + } else { | |
| 293 | + $commaString[$obj->name] .= $content.', '; | |
| 294 | + } | |
| 295 | + } else { | |
| 296 | + $string = $obj->name.' = '.$content."\n"; | |
| 297 | + } | |
| 298 | + break; | |
| 299 | + case 'section': | |
| 300 | + if (!$obj->isRoot()) { | |
| 301 | + $string = '['.$obj->name."]\n"; | |
| 302 | + } | |
| 303 | + if (count($obj->children) > 0) { | |
| 304 | + for ($i = 0; $i < count($obj->children); $i++) { | |
| 305 | + $string .= $this->toString($obj->getChild($i)); | |
| 306 | + } | |
| 307 | + } | |
| 308 | + break; | |
| 309 | + default: | |
| 310 | + $string = ''; | |
| 311 | + } | |
| 312 | + return $string; | |
| 313 | + } // end func toString | |
| 314 | +} // end class Config_Container_IniCommented | |
| 315 | +?> | ... | ... |
thirdparty/pear/Config/Container/IniFile.php
0 → 100644
| 1 | +<?php | |
| 2 | +// +----------------------------------------------------------------------+ | |
| 3 | +// | PHP Version 4 | | |
| 4 | +// +----------------------------------------------------------------------+ | |
| 5 | +// | Copyright (c) 1997-2003 The PHP Group | | |
| 6 | +// +----------------------------------------------------------------------+ | |
| 7 | +// | This source file is subject to version 2.0 of the PHP license, | | |
| 8 | +// | that is bundled with this package in the file LICENSE, and is | | |
| 9 | +// | available at through the world-wide-web at | | |
| 10 | +// | http://www.php.net/license/2_02.txt. | | |
| 11 | +// | If you did not receive a copy of the PHP license and are unable to | | |
| 12 | +// | obtain it through the world-wide-web, please send a note to | | |
| 13 | +// | license@php.net so we can mail you a copy immediately. | | |
| 14 | +// +----------------------------------------------------------------------+ | |
| 15 | +// | Authors: Bertrand Mansion <bmansion@mamasam.com> | | |
| 16 | +// +----------------------------------------------------------------------+ | |
| 17 | +// | |
| 18 | +// $Id$ | |
| 19 | + | |
| 20 | +/** | |
| 21 | +* Config parser for PHP .ini files | |
| 22 | +* Faster because it uses parse_ini_file() but get rid of comments, | |
| 23 | +* quotes, types and converts On, Off, True, False, Yes, No to 0 and 1. | |
| 24 | +* | |
| 25 | +* @author Bertrand Mansion <bmansion@mamasam.com> | |
| 26 | +* @package Config | |
| 27 | +*/ | |
| 28 | +class Config_Container_IniFile { | |
| 29 | + | |
| 30 | + /** | |
| 31 | + * This class options | |
| 32 | + * Not used at the moment | |
| 33 | + * | |
| 34 | + * @var array | |
| 35 | + */ | |
| 36 | + var $options = array(); | |
| 37 | + | |
| 38 | + /** | |
| 39 | + * Constructor | |
| 40 | + * | |
| 41 | + * @access public | |
| 42 | + * @param string $options (optional)Options to be used by renderer | |
| 43 | + */ | |
| 44 | + function Config_Container_IniFile($options = array()) | |
| 45 | + { | |
| 46 | + $this->options = $options; | |
| 47 | + } // end constructor | |
| 48 | + | |
| 49 | + /** | |
| 50 | + * Parses the data of the given configuration file | |
| 51 | + * | |
| 52 | + * @access public | |
| 53 | + * @param string $datasrc path to the configuration file | |
| 54 | + * @param object $obj reference to a config object | |
| 55 | + * @return mixed returns a PEAR_ERROR, if error occurs or true if ok | |
| 56 | + */ | |
| 57 | + function &parseDatasrc($datasrc, &$obj) | |
| 58 | + { | |
| 59 | + if (!file_exists($datasrc)) { | |
| 60 | + return PEAR::raiseError("Datasource file does not exist.", null, PEAR_ERROR_RETURN); | |
| 61 | + } | |
| 62 | + $currentSection =& $obj->container; | |
| 63 | + $confArray = parse_ini_file($datasrc, true); | |
| 64 | + if (!$confArray) { | |
| 65 | + return PEAR::raiseError("File '$datasrc' does not contain configuration data.", null, PEAR_ERROR_RETURN); | |
| 66 | + } | |
| 67 | + foreach ($confArray as $key => $value) { | |
| 68 | + if (is_array($value)) { | |
| 69 | + $currentSection =& $obj->container->createSection($key); | |
| 70 | + foreach ($value as $directive => $content) { | |
| 71 | + // try to split the value if comma found | |
| 72 | + if (strpos($content, '"') === false) { | |
| 73 | + $values = preg_split('/\s*,\s+/', $content); | |
| 74 | + if (count($values) > 1) { | |
| 75 | + foreach ($values as $k => $v) { | |
| 76 | + $currentSection->createDirective($directive, $v); | |
| 77 | + } | |
| 78 | + } else { | |
| 79 | + $currentSection->createDirective($directive, $content); | |
| 80 | + } | |
| 81 | + } else { | |
| 82 | + $currentSection->createDirective($directive, $content); | |
| 83 | + } | |
| 84 | + } | |
| 85 | + } else { | |
| 86 | + $currentSection->createDirective($key, $value); | |
| 87 | + } | |
| 88 | + } | |
| 89 | + return true; | |
| 90 | + } // end func parseDatasrc | |
| 91 | + | |
| 92 | + /** | |
| 93 | + * Returns a formatted string of the object | |
| 94 | + * @param object $obj Container object to be output as string | |
| 95 | + * @access public | |
| 96 | + * @return string | |
| 97 | + */ | |
| 98 | + function toString(&$obj) | |
| 99 | + { | |
| 100 | + static $childrenCount, $commaString; | |
| 101 | + | |
| 102 | + if (!isset($string)) { | |
| 103 | + $string = ''; | |
| 104 | + } | |
| 105 | + switch ($obj->type) { | |
| 106 | + case 'blank': | |
| 107 | + $string = "\n"; | |
| 108 | + break; | |
| 109 | + case 'comment': | |
| 110 | + $string = ';'.$obj->content."\n"; | |
| 111 | + break; | |
| 112 | + case 'directive': | |
| 113 | + $count = $obj->parent->countChildren('directive', $obj->name); | |
| 114 | + $content = $obj->content; | |
| 115 | + if ($content === false) { | |
| 116 | + $content = '0'; | |
| 117 | + } elseif ($content === true) { | |
| 118 | + $content = '1'; | |
| 119 | + } elseif (strlen(trim($content)) < strlen($content) || | |
| 120 | + strpos($content, ',') !== false || | |
| 121 | + strpos($content, ';') !== false || | |
| 122 | + strpos($content, '"') !== false || | |
| 123 | + strpos($content, '%') !== false || | |
| 124 | + strpos($content, '~') !== false) { | |
| 125 | + $content = '"'.addslashes($content).'"'; | |
| 126 | + } | |
| 127 | + if ($count > 1) { | |
| 128 | + // multiple values for a directive are separated by a comma | |
| 129 | + if (isset($childrenCount[$obj->name])) { | |
| 130 | + $childrenCount[$obj->name]++; | |
| 131 | + } else { | |
| 132 | + $childrenCount[$obj->name] = 0; | |
| 133 | + $commaString[$obj->name] = $obj->name.'='; | |
| 134 | + } | |
| 135 | + if ($childrenCount[$obj->name] == $count-1) { | |
| 136 | + // Clean the static for future calls to toString | |
| 137 | + $string .= $commaString[$obj->name].$content."\n"; | |
| 138 | + unset($childrenCount[$obj->name]); | |
| 139 | + unset($commaString[$obj->name]); | |
| 140 | + } else { | |
| 141 | + $commaString[$obj->name] .= $content.', '; | |
| 142 | + } | |
| 143 | + } else { | |
| 144 | + $string = $obj->name.'='.$content."\n"; | |
| 145 | + } | |
| 146 | + break; | |
| 147 | + case 'section': | |
| 148 | + if (!$obj->isRoot()) { | |
| 149 | + $string = '['.$obj->name."]\n"; | |
| 150 | + } | |
| 151 | + if (count($obj->children) > 0) { | |
| 152 | + for ($i = 0; $i < count($obj->children); $i++) { | |
| 153 | + $string .= $this->toString($obj->getChild($i)); | |
| 154 | + } | |
| 155 | + } | |
| 156 | + break; | |
| 157 | + default: | |
| 158 | + $string = ''; | |
| 159 | + } | |
| 160 | + return $string; | |
| 161 | + } // end func toString | |
| 162 | +} // end class Config_Container_IniFile | |
| 163 | +?> | |
| 0 | 164 | \ No newline at end of file | ... | ... |
thirdparty/pear/Config/Container/PHPArray.php
0 → 100644
| 1 | +<?php | |
| 2 | +// +----------------------------------------------------------------------+ | |
| 3 | +// | PHP Version 4 | | |
| 4 | +// +----------------------------------------------------------------------+ | |
| 5 | +// | Copyright (c) 1997-2003 The PHP Group | | |
| 6 | +// +----------------------------------------------------------------------+ | |
| 7 | +// | This source file is subject to version 2.0 of the PHP license, | | |
| 8 | +// | that is bundled with this package in the file LICENSE, and is | | |
| 9 | +// | available at through the world-wide-web at | | |
| 10 | +// | http://www.php.net/license/2_02.txt. | | |
| 11 | +// | If you did not receive a copy of the PHP license and are unable to | | |
| 12 | +// | obtain it through the world-wide-web, please send a note to | | |
| 13 | +// | license@php.net so we can mail you a copy immediately. | | |
| 14 | +// +----------------------------------------------------------------------+ | |
| 15 | +// | Authors: Bertrand Mansion <bmansion@mamasam.com> | | |
| 16 | +// +----------------------------------------------------------------------+ | |
| 17 | +// | |
| 18 | +// $Id$ | |
| 19 | + | |
| 20 | +/** | |
| 21 | +* Config parser for common PHP configuration array | |
| 22 | +* such as found in the horde project. | |
| 23 | +* | |
| 24 | +* Options expected is: | |
| 25 | +* 'name' => 'conf' | |
| 26 | +* Name of the configuration array. | |
| 27 | +* Default is $conf[]. | |
| 28 | +* 'useAttr' => true | |
| 29 | +* Whether we render attributes | |
| 30 | +* | |
| 31 | +* @author Bertrand Mansion <bmansion@mamasam.com> | |
| 32 | +* @package Config | |
| 33 | +*/ | |
| 34 | +class Config_Container_PHPArray { | |
| 35 | + | |
| 36 | + /** | |
| 37 | + * This class options: | |
| 38 | + * - name of the config array to parse/output | |
| 39 | + * Ex: $options['name'] = 'myconf'; | |
| 40 | + * - Whether to add attributes to the array | |
| 41 | + * Ex: $options['useAttr'] = false; | |
| 42 | + * | |
| 43 | + * @var array | |
| 44 | + */ | |
| 45 | + var $options = array('name' => 'conf', | |
| 46 | + 'useAttr' => true); | |
| 47 | + | |
| 48 | + /** | |
| 49 | + * Constructor | |
| 50 | + * | |
| 51 | + * @access public | |
| 52 | + * @param string $options Options to be used by renderer | |
| 53 | + */ | |
| 54 | + function Config_Container_PHPArray($options = array()) | |
| 55 | + { | |
| 56 | + foreach ($options as $key => $value) { | |
| 57 | + $this->options[$key] = $value; | |
| 58 | + } | |
| 59 | + } // end constructor | |
| 60 | + | |
| 61 | + /** | |
| 62 | + * Parses the data of the given configuration file | |
| 63 | + * | |
| 64 | + * @access public | |
| 65 | + * @param string $datasrc path to the configuration file | |
| 66 | + * @param object $obj reference to a config object | |
| 67 | + * @return mixed returns a PEAR_ERROR, if error occurs or true if ok | |
| 68 | + */ | |
| 69 | + function &parseDatasrc($datasrc, &$obj) | |
| 70 | + { | |
| 71 | + if (empty($datasrc)) { | |
| 72 | + return PEAR::raiseError("Datasource file path is empty.", null, PEAR_ERROR_RETURN); | |
| 73 | + } | |
| 74 | + if (is_array($datasrc)) { | |
| 75 | + $this->_parseArray($datasrc, $obj->container); | |
| 76 | + } else { | |
| 77 | + if (!file_exists($datasrc)) { | |
| 78 | + return PEAR::raiseError("Datasource file does not exist.", null, PEAR_ERROR_RETURN); | |
| 79 | + } else { | |
| 80 | + include($datasrc); | |
| 81 | + if (!isset(${$this->options['name']}) || !is_array(${$this->options['name']})) { | |
| 82 | + return PEAR::raiseError("File '$datasrc' does not contain a required '".$this->options['name']."' array.", null, PEAR_ERROR_RETURN); | |
| 83 | + } | |
| 84 | + } | |
| 85 | + $this->_parseArray(${$this->options['name']}, $obj->container); | |
| 86 | + } | |
| 87 | + return true; | |
| 88 | + } // end func parseDatasrc | |
| 89 | + | |
| 90 | + /** | |
| 91 | + * Parses the PHP array recursively | |
| 92 | + * @param array $array array values from the config file | |
| 93 | + * @param object $container reference to the container object | |
| 94 | + * @access private | |
| 95 | + * @return void | |
| 96 | + */ | |
| 97 | + function _parseArray($array, &$container) | |
| 98 | + { | |
| 99 | + foreach ($array as $key => $value) { | |
| 100 | + switch ((string)$key) { | |
| 101 | + case '@': | |
| 102 | + $container->setAttributes($value); | |
| 103 | + break; | |
| 104 | + case '#': | |
| 105 | + $container->setType('directive'); | |
| 106 | + $container->setContent($value); | |
| 107 | + break; | |
| 108 | + default: | |
| 109 | +/* if (is_array($value)) { | |
| 110 | + $section =& $container->createSection($key); | |
| 111 | + $this->_parseArray($value, $section); | |
| 112 | + } else { | |
| 113 | + $container->createDirective($key, $value); | |
| 114 | + }*/ | |
| 115 | + | |
| 116 | + if (is_array($value)) { | |
| 117 | + if (is_integer(key($value))) { | |
| 118 | + foreach ($value as $nestedValue) { | |
| 119 | + $section =& $container->createSection($key); | |
| 120 | + $this->_parseArray($nestedValue, $section); | |
| 121 | + } | |
| 122 | + } else { | |
| 123 | + | |
| 124 | + $section =& $container->createSection($key); | |
| 125 | + $this->_parseArray($value, $section); | |
| 126 | + } | |
| 127 | + } else { | |
| 128 | + $container->createDirective($key, $value); | |
| 129 | + } | |
| 130 | + | |
| 131 | + } | |
| 132 | + } | |
| 133 | + } // end func _parseArray | |
| 134 | + | |
| 135 | + /** | |
| 136 | + * Returns a formatted string of the object | |
| 137 | + * @param object $obj Container object to be output as string | |
| 138 | + * @access public | |
| 139 | + * @return string | |
| 140 | + */ | |
| 141 | + function toString(&$obj) | |
| 142 | + { | |
| 143 | + if (!isset($string)) { | |
| 144 | + $string = ''; | |
| 145 | + } | |
| 146 | + switch ($obj->type) { | |
| 147 | + case 'blank': | |
| 148 | + $string .= "\n"; | |
| 149 | + break; | |
| 150 | + case 'comment': | |
| 151 | + $string .= '// '.$obj->content."\n"; | |
| 152 | + break; | |
| 153 | + case 'directive': | |
| 154 | + $attrString = ''; | |
| 155 | + $parentString = $this->_getParentString($obj); | |
| 156 | + $attributes = $obj->getAttributes(); | |
| 157 | + if ($this->options['useAttr'] && is_array($attributes) && count($attributes) > 0) { | |
| 158 | + // Directive with attributes '@' and value '#' | |
| 159 | + $string .= $parentString."['#']"; | |
| 160 | + foreach ($attributes as $attr => $val) { | |
| 161 | + $attrString .= $parentString."['@']" | |
| 162 | + ."['".$attr."'] = '".addslashes($val)."';\n"; | |
| 163 | + } | |
| 164 | + } else { | |
| 165 | + $string .= $parentString; | |
| 166 | + } | |
| 167 | + $string .= ' = '; | |
| 168 | + if (is_string($obj->content)) { | |
| 169 | + $string .= "'".addslashes($obj->content)."'"; | |
| 170 | + } elseif (is_int($obj->content) || is_float($obj->content)) { | |
| 171 | + $string .= $obj->content; | |
| 172 | + } elseif (is_bool($obj->content)) { | |
| 173 | + $string .= ($obj->content) ? 'true' : 'false'; | |
| 174 | + } | |
| 175 | + $string .= ";\n"; | |
| 176 | + $string .= $attrString; | |
| 177 | + break; | |
| 178 | + case 'section': | |
| 179 | + $attrString = ''; | |
| 180 | + $attributes = $obj->getAttributes(); | |
| 181 | + if ($this->options['useAttr'] && is_array($attributes) && count($attributes) > 0) { | |
| 182 | + $parentString = $this->_getParentString($obj); | |
| 183 | + foreach ($attributes as $attr => $val) { | |
| 184 | + $attrString .= $parentString."['@']" | |
| 185 | + ."['".$attr."'] = '".addslashes($val)."';\n"; | |
| 186 | + } | |
| 187 | + } | |
| 188 | + $string .= $attrString; | |
| 189 | + if ($count = count($obj->children)) { | |
| 190 | + for ($i = 0; $i < $count; $i++) { | |
| 191 | + $string .= $this->toString($obj->getChild($i)); | |
| 192 | + } | |
| 193 | + } | |
| 194 | + break; | |
| 195 | + default: | |
| 196 | + $string = ''; | |
| 197 | + } | |
| 198 | + return $string; | |
| 199 | + } // end func toString | |
| 200 | + | |
| 201 | + /** | |
| 202 | + * Returns a formatted string of the object parents | |
| 203 | + * @access private | |
| 204 | + * @return string | |
| 205 | + */ | |
| 206 | + function _getParentString(&$obj) | |
| 207 | + { | |
| 208 | + $string = ''; | |
| 209 | + if (!$obj->isRoot()) { | |
| 210 | + if (!$obj->parent->isRoot()) { | |
| 211 | + $string = is_int($obj->name) ? "[".$obj->name."]" : "['".$obj->name."']"; | |
| 212 | + } else { | |
| 213 | + if (empty($this->options['name'])) { | |
| 214 | + $string .= '$'.$obj->name; | |
| 215 | + } else { | |
| 216 | + $string .= '$'.$this->options['name']."['".$obj->name."']"; | |
| 217 | + } | |
| 218 | + } | |
| 219 | + $string = $this->_getParentString($obj->parent).$string; | |
| 220 | + $count = $obj->parent->countChildren(null, $obj->name); | |
| 221 | + if ($count > 1) { | |
| 222 | + $string .= '['.$obj->getItemPosition().']'; | |
| 223 | + } | |
| 224 | + } | |
| 225 | + return $string; | |
| 226 | + } // end func _getParentString | |
| 227 | + | |
| 228 | + /** | |
| 229 | + * Writes the configuration to a file | |
| 230 | + * | |
| 231 | + * @param mixed datasrc info on datasource such as path to the configuraton file | |
| 232 | + * @param string configType (optional)type of configuration | |
| 233 | + * @access public | |
| 234 | + * @return string | |
| 235 | + */ | |
| 236 | + function writeDatasrc($datasrc, &$obj) | |
| 237 | + { | |
| 238 | + $fp = @fopen($datasrc, 'w'); | |
| 239 | + if ($fp) { | |
| 240 | + $string = "<?php\n". $this->toString($obj) ."?>"; // <? : Fix my syntax coloring | |
| 241 | + $len = strlen($string); | |
| 242 | + @flock($fp, LOCK_EX); | |
| 243 | + @fwrite($fp, $string, $len); | |
| 244 | + @flock($fp, LOCK_UN); | |
| 245 | + @fclose($fp); | |
| 246 | + return true; | |
| 247 | + } else { | |
| 248 | + return PEAR::raiseError('Cannot open datasource for writing.', 1, PEAR_ERROR_RETURN); | |
| 249 | + } | |
| 250 | + } // end func writeDatasrc | |
| 251 | +} // end class Config_Container_PHPArray | |
| 252 | +?> | ... | ... |
thirdparty/pear/Config/Container/PHPConstants.php
0 → 100644
| 1 | +<?php | |
| 2 | +// +----------------------------------------------------------------------+ | |
| 3 | +// | PHP Version 4 | | |
| 4 | +// +----------------------------------------------------------------------+ | |
| 5 | +// | Copyright (c) 1997-2003 The PHP Group | | |
| 6 | +// +----------------------------------------------------------------------+ | |
| 7 | +// | This source file is subject to version 2.0 of the PHP license, | | |
| 8 | +// | that is bundled with this package in the file LICENSE, and is | | |
| 9 | +// | available at through the world-wide-web at | | |
| 10 | +// | http://www.php.net/license/2_02.txt. | | |
| 11 | +// | If you did not receive a copy of the PHP license and are unable to | | |
| 12 | +// | obtain it through the world-wide-web, please send a note to | | |
| 13 | +// | license@php.net so we can mail you a copy immediately. | | |
| 14 | +// +----------------------------------------------------------------------+ | |
| 15 | +// | Authors: Phillip Oertel <me@phillipoertel.com> | | |
| 16 | +// +----------------------------------------------------------------------+ | |
| 17 | +// | |
| 18 | +// $Id$ | |
| 19 | + | |
| 20 | +/** | |
| 21 | +* Config parser for PHP constant files | |
| 22 | +* | |
| 23 | +* @author Phillip Oertel <me@phillipoertel.com> | |
| 24 | +* @package Config | |
| 25 | +* @version 0.1 (not submitted) | |
| 26 | +*/ | |
| 27 | + | |
| 28 | +require_once 'Config/Container.php'; | |
| 29 | + | |
| 30 | +class Config_Container_PHPConstants extends Config_Container { | |
| 31 | + | |
| 32 | + /** | |
| 33 | + * This class options | |
| 34 | + * Not used at the moment | |
| 35 | + * | |
| 36 | + * @var array | |
| 37 | + */ | |
| 38 | + var $options = array(); | |
| 39 | + | |
| 40 | + /** | |
| 41 | + * Constructor | |
| 42 | + * | |
| 43 | + * @access public | |
| 44 | + * @param string $options (optional)Options to be used by renderer | |
| 45 | + */ | |
| 46 | + function Config_Container_PHPConstants($options = array()) | |
| 47 | + { | |
| 48 | + $this->options = $options; | |
| 49 | + } // end constructor | |
| 50 | + | |
| 51 | + /** | |
| 52 | + * Parses the data of the given configuration file | |
| 53 | + * | |
| 54 | + * @access public | |
| 55 | + * @param string $datasrc path to the configuration file | |
| 56 | + * @param object $obj reference to a config object | |
| 57 | + * @return mixed returns a PEAR_ERROR, if error occurs or true if ok | |
| 58 | + */ | |
| 59 | + function &parseDatasrc($datasrc, &$obj) | |
| 60 | + { | |
| 61 | + if (!file_exists($datasrc)) { | |
| 62 | + return PEAR::raiseError("Datasource file does not exist.", null, | |
| 63 | + PEAR_ERROR_RETURN); | |
| 64 | + } | |
| 65 | + | |
| 66 | + $fileContent = file_get_contents($datasrc, true); | |
| 67 | + | |
| 68 | + if (!$fileContent) { | |
| 69 | + return PEAR::raiseError("File '$datasrc' could not be read.", null, | |
| 70 | + PEAR_ERROR_RETURN); | |
| 71 | + } | |
| 72 | + | |
| 73 | + $rows = explode("\n", $fileContent); | |
| 74 | + for ($i=0, $max=count($rows); $i<$max; $i++) { | |
| 75 | + $line = $rows[$i]; | |
| 76 | + | |
| 77 | + //blanks? | |
| 78 | + | |
| 79 | + // sections | |
| 80 | + if (preg_match("/^\/\/\s*$/", $line)) { | |
| 81 | + preg_match("/^\/\/\s*(.+)$/", $rows[$i+1], $matches); | |
| 82 | + $obj->container->createSection(trim($matches[1])); | |
| 83 | + $i += 2; | |
| 84 | + continue; | |
| 85 | + } | |
| 86 | + | |
| 87 | + // comments | |
| 88 | + if (preg_match("/^\/\/\s*(.+)$/", $line, $matches) || | |
| 89 | + preg_match("/^#\s*(.+)$/", $line, $matches)) { | |
| 90 | + $obj->container->createComment(trim($matches[1])); | |
| 91 | + continue; | |
| 92 | + } | |
| 93 | + | |
| 94 | + // directives | |
| 95 | + $regex = "/^\s*define\s*\('([A-Z1-9_]+)',\s*'*(.[^\']*)'*\)/"; | |
| 96 | + preg_match($regex, $line, $matches); | |
| 97 | + if (!empty($matches)) { | |
| 98 | + $obj->container->createDirective(trim($matches[1]), | |
| 99 | + trim($matches[2])); | |
| 100 | + } | |
| 101 | + } | |
| 102 | + | |
| 103 | + return true; | |
| 104 | + | |
| 105 | + } // end func parseDatasrc | |
| 106 | + | |
| 107 | + /** | |
| 108 | + * Returns a formatted string of the object | |
| 109 | + * @param object $obj Container object to be output as string | |
| 110 | + * @access public | |
| 111 | + * @return string | |
| 112 | + */ | |
| 113 | + function toString(&$obj) | |
| 114 | + { | |
| 115 | + $string = ''; | |
| 116 | + | |
| 117 | + switch ($obj->type) | |
| 118 | + { | |
| 119 | + case 'blank': | |
| 120 | + $string = "\n"; | |
| 121 | + break; | |
| 122 | + | |
| 123 | + case 'comment': | |
| 124 | + $string = '// '.$obj->content."\n"; | |
| 125 | + break; | |
| 126 | + | |
| 127 | + case 'directive': | |
| 128 | + $content = $obj->content; | |
| 129 | + // don't quote numeric values, true/false and constants | |
| 130 | + if (!is_numeric($content) && !in_array($content, array('false', | |
| 131 | + 'true')) && !preg_match('/^[A-Z_]+$/', $content)) { | |
| 132 | + $content = "'".$content."'"; | |
| 133 | + } | |
| 134 | + $string = 'define(\''.$obj->name.'\', '.$content.');'.chr(10); | |
| 135 | + break; | |
| 136 | + | |
| 137 | + case 'section': | |
| 138 | + if (!$obj->isRoot()) { | |
| 139 | + $string = chr(10); | |
| 140 | + $string .= '//'.chr(10); | |
| 141 | + $string .= '// '.$obj->name.chr(10); | |
| 142 | + $string .= '//'.chr(10); | |
| 143 | + } | |
| 144 | + if (count($obj->children) > 0) { | |
| 145 | + for ($i = 0, $max = count($obj->children); $i < $max; $i++) { | |
| 146 | + $string .= $this->toString($obj->getChild($i)); | |
| 147 | + } | |
| 148 | + } | |
| 149 | + break; | |
| 150 | + default: | |
| 151 | + $string = ''; | |
| 152 | + } | |
| 153 | + return $string; | |
| 154 | + } // end func toString | |
| 155 | + | |
| 156 | + /** | |
| 157 | + * Writes the configuration to a file | |
| 158 | + * | |
| 159 | + * @param mixed datasrc info on datasource such as path to the file | |
| 160 | + * @param string configType (optional)type of configuration | |
| 161 | + * @access public | |
| 162 | + * @return string | |
| 163 | + */ | |
| 164 | + function writeDatasrc($datasrc, &$obj) | |
| 165 | + { | |
| 166 | + $fp = @fopen($datasrc, 'w'); | |
| 167 | + if ($fp) { | |
| 168 | + $string = "<?php"; | |
| 169 | + $string .= "\n\n"; | |
| 170 | + $string .= '/**' . chr(10); | |
| 171 | + $string .= ' *' . chr(10); | |
| 172 | + $string .= ' * AUTOMATICALLY GENERATED CODE - | |
| 173 | + DO NOT EDIT BY HAND' . chr(10); | |
| 174 | + $string .= ' *' . chr(10); | |
| 175 | + $string .= '**/' . chr(10); | |
| 176 | + $string .= $this->toString($obj); | |
| 177 | + $string .= "\n?>"; // <? : Fix my syntax coloring | |
| 178 | + | |
| 179 | + $len = strlen($string); | |
| 180 | + @flock($fp, LOCK_EX); | |
| 181 | + @fwrite($fp, $string, $len); | |
| 182 | + @flock($fp, LOCK_UN); | |
| 183 | + @fclose($fp); | |
| 184 | + | |
| 185 | + // need an error check here | |
| 186 | + | |
| 187 | + return true; | |
| 188 | + } else { | |
| 189 | + return PEAR::raiseError('Cannot open datasource for writing.', 1, | |
| 190 | + PEAR_ERROR_RETURN); | |
| 191 | + } | |
| 192 | + } // end func writeDatasrc | |
| 193 | + | |
| 194 | + | |
| 195 | +} // end class Config_Container_PHPConstants | |
| 196 | + | |
| 197 | +?> | ... | ... |
thirdparty/pear/Config/Container/XML.php
0 → 100644
| 1 | +<?php | |
| 2 | +// +----------------------------------------------------------------------+ | |
| 3 | +// | PHP Version 4 | | |
| 4 | +// +----------------------------------------------------------------------+ | |
| 5 | +// | Copyright (c) 1997-2003 The PHP Group | | |
| 6 | +// +----------------------------------------------------------------------+ | |
| 7 | +// | This source file is subject to version 2.0 of the PHP license, | | |
| 8 | +// | that is bundled with this package in the file LICENSE, and is | | |
| 9 | +// | available at through the world-wide-web at | | |
| 10 | +// | http://www.php.net/license/2_02.txt. | | |
| 11 | +// | If you did not receive a copy of the PHP license and are unable to | | |
| 12 | +// | obtain it through the world-wide-web, please send a note to | | |
| 13 | +// | license@php.net so we can mail you a copy immediately. | | |
| 14 | +// +----------------------------------------------------------------------+ | |
| 15 | +// | Author: Bertrand Mansion <bmansion@mamasam.com> | | |
| 16 | +// +----------------------------------------------------------------------+ | |
| 17 | +// | |
| 18 | +// $Id$ | |
| 19 | + | |
| 20 | +require_once('XML/Parser.php'); | |
| 21 | +require_once('XML/Util.php'); | |
| 22 | + | |
| 23 | +/** | |
| 24 | +* Config parser for XML Files | |
| 25 | +* | |
| 26 | +* @author Bertrand Mansion <bmansion@mamasam.com> | |
| 27 | +* @package Config | |
| 28 | +*/ | |
| 29 | +class Config_Container_XML extends XML_Parser | |
| 30 | +{ | |
| 31 | + /** | |
| 32 | + * Deep level used for indentation | |
| 33 | + * | |
| 34 | + * @var int | |
| 35 | + * @access private | |
| 36 | + */ | |
| 37 | + var $_deep = -1; | |
| 38 | + | |
| 39 | + /** | |
| 40 | + * This class options: | |
| 41 | + * version (1.0) : XML version | |
| 42 | + * encoding (ISO-8859-1) : XML content encoding | |
| 43 | + * name : like in phparray, name of your config global entity | |
| 44 | + * indent : char used for indentation | |
| 45 | + * linebreak : char used for linebreak | |
| 46 | + * addDecl : whether to add the xml declaration at beginning or not | |
| 47 | + * useAttr : whether to use the attributes | |
| 48 | + * isFile : whether the given content is a file or an XML string | |
| 49 | + * useCData : whether to surround data with <![CDATA[...]]> | |
| 50 | + * | |
| 51 | + * @var array | |
| 52 | + */ | |
| 53 | + var $options = array('version' => '1.0', | |
| 54 | + 'encoding' => 'ISO-8859-1', | |
| 55 | + 'name' => '', | |
| 56 | + 'indent' => ' ', | |
| 57 | + 'linebreak' => "\n", | |
| 58 | + 'addDecl' => true, | |
| 59 | + 'useAttr' => true, | |
| 60 | + 'isFile' => true, | |
| 61 | + 'useCData' => false); | |
| 62 | + | |
| 63 | + /** | |
| 64 | + * Container objects | |
| 65 | + * | |
| 66 | + * @var array | |
| 67 | + */ | |
| 68 | + var $containers = array(); | |
| 69 | + | |
| 70 | + /** | |
| 71 | + * Constructor | |
| 72 | + * | |
| 73 | + * @access public | |
| 74 | + * @param string $options Options to be used by renderer | |
| 75 | + * version : (1.0) XML version | |
| 76 | + * encoding : (ISO-8859-1) XML content encoding | |
| 77 | + * name : like in phparray, name of your config global entity | |
| 78 | + * indent : char used for indentation | |
| 79 | + * linebreak : char used for linebreak | |
| 80 | + * addDecl : whether to add the xml declaration at beginning or not | |
| 81 | + * useAttr : whether to use the attributes | |
| 82 | + * isFile : whether the given content is a file or an XML string | |
| 83 | + */ | |
| 84 | + function Config_Container_XML($options = array()) | |
| 85 | + { | |
| 86 | + foreach ($options as $key => $value) { | |
| 87 | + $this->options[$key] = $value; | |
| 88 | + } | |
| 89 | + } // end constructor | |
| 90 | + | |
| 91 | + /** | |
| 92 | + * Parses the data of the given configuration file | |
| 93 | + * | |
| 94 | + * @access public | |
| 95 | + * @param string $datasrc path to the configuration file | |
| 96 | + * @param object $obj reference to a config object | |
| 97 | + * @return mixed returns a PEAR_ERROR, if error occurs or true if ok | |
| 98 | + */ | |
| 99 | + function &parseDatasrc($datasrc, &$obj) | |
| 100 | + { | |
| 101 | + $this->folding = false; | |
| 102 | + $this->cdata = null; | |
| 103 | + $this->XML_Parser($this->options['encoding'], 'event'); | |
| 104 | + $this->containers[0] =& $obj->container; | |
| 105 | + if (is_string($datasrc)) { | |
| 106 | + if ($this->options['isFile']) { | |
| 107 | + $err = $this->setInputFile($datasrc); | |
| 108 | + if (PEAR::isError($err)) { | |
| 109 | + return $err; | |
| 110 | + } | |
| 111 | + $err = $this->parse(); | |
| 112 | + } else { | |
| 113 | + $err = $this->parseString($datasrc, true); | |
| 114 | + } | |
| 115 | + } else { | |
| 116 | + $this->setInput($datasrc); | |
| 117 | + $err = $this->parse(); | |
| 118 | + } | |
| 119 | + if (PEAR::isError($err)) { | |
| 120 | + return $err; | |
| 121 | + } | |
| 122 | + return true; | |
| 123 | + } // end func parseDatasrc | |
| 124 | + | |
| 125 | + /** | |
| 126 | + * Handler for the xml-data | |
| 127 | + * | |
| 128 | + * @param mixed $xp ignored | |
| 129 | + * @param string $elem name of the element | |
| 130 | + * @param array $attribs attributes for the generated node | |
| 131 | + * | |
| 132 | + * @access private | |
| 133 | + */ | |
| 134 | + function startHandler($xp, $elem, &$attribs) | |
| 135 | + { | |
| 136 | + $container =& new Config_Container('section', $elem, null, $attribs); | |
| 137 | + $this->containers[] =& $container; | |
| 138 | + return null; | |
| 139 | + } // end func startHandler | |
| 140 | + | |
| 141 | + /** | |
| 142 | + * Handler for the xml-data | |
| 143 | + * | |
| 144 | + * @param mixed $xp ignored | |
| 145 | + * @param string $elem name of the element | |
| 146 | + * | |
| 147 | + * @access private | |
| 148 | + */ | |
| 149 | + function endHandler($xp, $elem) | |
| 150 | + { | |
| 151 | + $count = count($this->containers); | |
| 152 | + $container =& $this->containers[$count-1]; | |
| 153 | + $currentSection =& $this->containers[$count-2]; | |
| 154 | + if (count($container->children) == 0) { | |
| 155 | + $container->setType('directive'); | |
| 156 | + $container->setContent(trim($this->cdata)); | |
| 157 | + } | |
| 158 | + $currentSection->addItem($container); | |
| 159 | + array_pop($this->containers); | |
| 160 | + $this->cdata = null; | |
| 161 | + return null; | |
| 162 | + } // end func endHandler | |
| 163 | + | |
| 164 | + /* | |
| 165 | + * The xml character data handler | |
| 166 | + * | |
| 167 | + * @param mixed $xp ignored | |
| 168 | + * @param string $data PCDATA between tags | |
| 169 | + * | |
| 170 | + * @access private | |
| 171 | + */ | |
| 172 | + function cdataHandler($xp, $cdata) | |
| 173 | + { | |
| 174 | + $this->cdata .= $cdata; | |
| 175 | + } // end func cdataHandler | |
| 176 | + | |
| 177 | + /** | |
| 178 | + * Returns a formatted string of the object | |
| 179 | + * @param object $obj Container object to be output as string | |
| 180 | + * @access public | |
| 181 | + * @return string | |
| 182 | + */ | |
| 183 | + function toString(&$obj) | |
| 184 | + { | |
| 185 | + $indent = ''; | |
| 186 | + if (!$obj->isRoot()) { | |
| 187 | + // no indent for root | |
| 188 | + $this->_deep++; | |
| 189 | + $indent = str_repeat($this->options['indent'], $this->_deep); | |
| 190 | + } else { | |
| 191 | + // Initialize string with xml declaration | |
| 192 | + $string = ''; | |
| 193 | + if ($this->options['addDecl']) { | |
| 194 | + $string .= XML_Util::getXMLDeclaration($this->options['version'], $this->options['encoding']); | |
| 195 | + $string .= $this->options['linebreak']; | |
| 196 | + } | |
| 197 | + if (!empty($this->options['name'])) { | |
| 198 | + $string .= '<'.$this->options['name'].'>'.$this->options['linebreak']; | |
| 199 | + $this->_deep++; | |
| 200 | + $indent = str_repeat($this->options['indent'], $this->_deep); | |
| 201 | + } | |
| 202 | + } | |
| 203 | + if (!isset($string)) { | |
| 204 | + $string = ''; | |
| 205 | + } | |
| 206 | + switch ($obj->type) { | |
| 207 | + case 'directive': | |
| 208 | + $attributes = ($this->options['useAttr']) ? $obj->attributes : array(); | |
| 209 | + $string .= $indent.XML_Util::createTag($obj->name, $attributes, $obj->content, null, | |
| 210 | + ($this->options['useCData'] ? XML_UTIL_CDATA_SECTION : XML_UTIL_REPLACE_ENTITIES)); | |
| 211 | + $string .= $this->options['linebreak']; | |
| 212 | + break; | |
| 213 | + case 'comment': | |
| 214 | + $string .= $indent.'<!-- '.$obj->content.' -->'; | |
| 215 | + $string .= $this->options['linebreak']; | |
| 216 | + break; | |
| 217 | + case 'section': | |
| 218 | + if (!$obj->isRoot()) { | |
| 219 | + $string = $indent.'<'.$obj->name; | |
| 220 | + $string .= ($this->options['useAttr']) ? XML_Util::attributesToString($obj->attributes) : ''; | |
| 221 | + } | |
| 222 | + if ($children = count($obj->children)) { | |
| 223 | + if (!$obj->isRoot()) { | |
| 224 | + $string .= '>'.$this->options['linebreak']; | |
| 225 | + } | |
| 226 | + for ($i = 0; $i < $children; $i++) { | |
| 227 | + $string .= $this->toString($obj->getChild($i)); | |
| 228 | + } | |
| 229 | + } | |
| 230 | + if (!$obj->isRoot()) { | |
| 231 | + if ($children) { | |
| 232 | + $string .= $indent.'</'.$obj->name.'>'.$this->options['linebreak']; | |
| 233 | + } else { | |
| 234 | + $string .= '/>'.$this->options['linebreak']; | |
| 235 | + } | |
| 236 | + } else { | |
| 237 | + if (!empty($this->options['name'])) { | |
| 238 | + $string .= '</'.$this->options['name'].'>'.$this->options['linebreak']; | |
| 239 | + } | |
| 240 | + } | |
| 241 | + break; | |
| 242 | + default: | |
| 243 | + $string = ''; | |
| 244 | + } | |
| 245 | + if (!$obj->isRoot()) { | |
| 246 | + $this->_deep--; | |
| 247 | + } | |
| 248 | + return $string; | |
| 249 | + } // end func toString | |
| 250 | +} // end class Config_Container_XML | |
| 251 | +?> | |
| 0 | 252 | \ No newline at end of file | ... | ... |