Commit c24f6d21efedb18796c8cfdc294752afcab61058

Authored by Neil Blakey-Milner
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
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
... ...