Skip to content

Commit a65e4e9

Browse files
committed
Moved Config-Package from Experimental to main-directory, since noone complained about it ;)
1 parent 30ca718 commit a65e4e9

File tree

6 files changed

+1476
-0
lines changed

6 files changed

+1476
-0
lines changed

pear/Config.php

Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,329 @@
1+
<?php
2+
// +----------------------------------------------------------------------+
3+
// | PHP version 4.0 |
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+
// | Authors: Alexander Merz <alexander.merz@t-online.de> |
16+
// | Christian Stocker <chregu@phant.ch> |
17+
// +----------------------------------------------------------------------+
18+
//
19+
// $Id$
20+
21+
require_once( "PEAR.php") ;
22+
23+
/**
24+
* Partly implementation of the Config-Interface-API
25+
*
26+
* This class implements a part of the API for working on configuration data
27+
* ConfigDefault implements getValues(), getBlocks(), getValue(), setValue()
28+
* The data is internally saved in a nested array.
29+
*
30+
* Example:
31+
* include("Config.php");
32+
* $i = new Config("IniFile");
33+
* $i -> parseInput( "yourfile.ini");
34+
* $ret = $i->getValues('/section');
35+
*
36+
*
37+
* @author Alexander Merz <alexander.merz@t-online.de>
38+
* @access public
39+
* @version $Id$
40+
* @package Config
41+
*/
42+
43+
class Config {
44+
45+
/**
46+
* contains the data source given by parseInput
47+
* @var string
48+
*/
49+
var $datasrc ;
50+
51+
/**
52+
* contains the internal data structure
53+
* @var array
54+
*/
55+
var $data = array() ;
56+
57+
/**
58+
* Constructor
59+
*
60+
* requires the type of the data container, if the container needs
61+
* special parameters during creation, set them with $storage_options
62+
*
63+
* @access public
64+
* @param string $storage_driver type of container
65+
* @param string $storage_options parameter for container constructor
66+
*/
67+
function Config($storage_driver,$storage_options = "")
68+
{
69+
70+
$storage_class = 'Config_Container_' . $storage_driver;
71+
$storage_classfile = 'Config/Container/' . $storage_driver . '.php';
72+
73+
include_once $storage_classfile;
74+
$this->container = new $storage_class($storage_options);
75+
} // end func Config()
76+
77+
78+
79+
/**
80+
* returns all key-value-pairs of the given block
81+
*
82+
* If the block not exists, a PEAR_Error will returned, else
83+
* a hash: $array["key"] = value
84+
*
85+
* @access public
86+
* @param string $block block path
87+
* @return array returns a hash containing all values, but a PEAR_Error if fails
88+
*/
89+
90+
function getValues( $block = "/")
91+
{
92+
if( !empty( $this -> data ) )
93+
{
94+
// if leading slash was forgotten...
95+
if( "/" != substr( $block, 0, 1) )
96+
{
97+
$block = "/".$block ;
98+
}
99+
if( isset( $this -> data[ $block ] ) )
100+
{
101+
if( is_array( $this -> data[ $block ] ) )
102+
{
103+
$ret = $this -> data[ $block ] ;
104+
}
105+
else
106+
{
107+
$ret = false ;
108+
}
109+
}
110+
else
111+
{
112+
$ret = new PEAR_Error("Block path '".$block."' doesn't exists! Request couldn't be answered.", 12, PEAR_ERROR_RETURN, null, null );
113+
}
114+
}
115+
else
116+
{
117+
$ret = new PEAR_Error("No internal data! Request couldn't be answered.", 11, PEAR_ERROR_RETURN, null, null );
118+
}
119+
120+
return $ret ;
121+
} // end func getValues
122+
123+
/**
124+
* returns all blocks of the given block
125+
*
126+
* If the block not exists, a PEAR_Error will returned, else
127+
* a array containing all child blocks
128+
*
129+
* @access public
130+
* @param string $block block path
131+
* @return array returns a array containing all values, or a PEAR_Error, if fails
132+
*/
133+
134+
function getBlocks( $block = "/")
135+
{
136+
if( !empty( $this -> data ) )
137+
{
138+
// if leading slash was forgotten...
139+
if( "/" != substr( $block, 0, 1) )
140+
{
141+
$block = "/".$block ;
142+
}
143+
$ret = array() ;
144+
foreach( $this -> data as $key => $value)
145+
{
146+
$key = $key."/" ;
147+
if( $block == substr( $key, 0, strlen( $block ) ) )
148+
{
149+
array_push ( $ret, trim( substr( $key, strlen( $block ), strpos( substr( $key, strlen( $block ) ), "/" ) ) ) ) ;
150+
}
151+
}
152+
}
153+
else
154+
{
155+
$ret = new PEAR_Error("No internal data! Request couldn't be answered.", 21, PEAR_ERROR_RETURN, null, null );
156+
}
157+
158+
return $ret ;
159+
} // end func getBlocks
160+
161+
/**
162+
* sets the value of the key of the given block
163+
*
164+
* If the block or the key not exists, both will be created.
165+
* The value will be returned.
166+
*
167+
* @access public
168+
* @param string $block block path
169+
* @param string $key key to set
170+
* @param string $value value for the key
171+
* @return mixed type depends on $value
172+
* @see getValue()
173+
*/
174+
175+
function setValue( $block = "/", $key, $value = "")
176+
{
177+
// if leading slash was forgotten...
178+
if( "/" != substr( $block, 0, 1) )
179+
{
180+
$block = "/".$block ;
181+
}
182+
// check for existing block and key
183+
if( !isset ( $this -> data[ $block ] ) )
184+
{
185+
$this->data[ $block ] = array() ;
186+
}
187+
$kvp = $this -> data[ $block ] ;
188+
$kvp[ $key ] = $value ;
189+
$this -> data[ $block ] = $kvp ;
190+
$ret = $value ;
191+
192+
return $ret ;
193+
} // end func setValue
194+
195+
/**
196+
* return the value of the key of the given block
197+
*
198+
* If the block or the key not exists, both will be created and
199+
* sets on the default.
200+
* The value or if not exists the default will be returned.
201+
*
202+
* @access public
203+
* @param string $block block path
204+
* @param string $key key to set
205+
* @param string $default default value for the key
206+
* @return mixed type depends of the value
207+
*/
208+
209+
function getValue( $block = "/", $key, $default = "")
210+
{
211+
// if leading slash was forgotten...
212+
if( "/" != substr( $block, 0, 1) )
213+
{
214+
$block = "/".$block ;
215+
}
216+
// check for existing block and key
217+
$values = $this -> getValues( $block ) ;
218+
if( PEAR::isError($values) or !in_array( $key, array_keys( $values) ) )
219+
{
220+
$this -> setValue( $block, $key, $default) ;
221+
$values = $this -> getValues( $block ) ;
222+
}
223+
$ret = $values[ $key ] ;
224+
225+
return $ret ;
226+
} // end func getValue
227+
228+
/**
229+
* parses the input of the given data source
230+
*
231+
* The format and required content of $datasrc depends of the implementation.
232+
* If the implemention requires additional data, for example a comment char, it have to
233+
* deliver in a hash as second argument.
234+
*
235+
* @access public
236+
* @param string $files Name of the datasource to parse
237+
* @param array $feature Contains a hash of features depending on the implentation
238+
* @return mixed returns a PEAR_ERROR, if error occurs
239+
*/
240+
241+
function parseInput ($files ,$feature = array() )
242+
{
243+
if (is_array($files)) {
244+
$totaldata = array();
245+
foreach ($files as $datasrc)
246+
{
247+
$this->container->parseInput($datasrc,$feature);
248+
$totaldata = $this->array_merge_clobber($totaldata,$this->container->data);
249+
unset ($this->data);
250+
$this->datasrc = $datasrc;
251+
}
252+
$this->data = $totaldata;
253+
}
254+
else
255+
{
256+
$this->container->parseInput($files,$feature);
257+
$this->data = $this->container->data;
258+
$this->datasrc = $files;
259+
}
260+
261+
} // end func parseInput()
262+
263+
264+
/**
265+
* writes the data to the given data source or if not given to the datasource of parseInput
266+
* If $datasrc was a array, the last file will used.
267+
*
268+
* See parseInput for $datasrc. If the second argument $preserve is true, the implementation
269+
* should try to preserve the original format and data of the source except changed or added values.
270+
* This mean to preserve for example comments in files or so.
271+
*
272+
* @access public
273+
* @param string $datasrc Name of the datasource to parse
274+
* @param boolean $preserve preserving behavior
275+
* @return mixed returns PEAR_Error, if fails
276+
* @see parseInput()
277+
*/
278+
function writeInput( $datasrc = "", $preserve = True )
279+
{
280+
if( empty( $datasrc ) ) {
281+
$datasrc = $this -> datasrc ;
282+
}
283+
$this->container->writeInput($datasrc,$preserve);
284+
}
285+
286+
287+
288+
//taken from kc@hireability.com at http://www.php.net/manual/en/function.array-merge-recursive.php
289+
/**
290+
* There seemed to be no built in function that would merge two arrays recursively and clobber
291+
* any existing key/value pairs. Array_Merge() is not recursive, and array_merge_recursive
292+
* seemed to give unsatisfactory results... it would append duplicate key/values.
293+
*
294+
* So here's a cross between array_merge and array_merge_recursive
295+
*
296+
* @param array first array to be merged
297+
* @param array second array to be merged
298+
* @return array merged array
299+
* @acces private
300+
*/
301+
function array_merge_clobber($a1,$a2)
302+
{
303+
if(!is_array($a1) || !is_array($a2)) return false;
304+
$newarray = $a1;
305+
while (list($key, $val) = each($a2))
306+
{
307+
if (is_array($val) && is_array($newarray[$key]))
308+
{
309+
$newarray[$key] = $this->array_merge_clobber($newarray[$key], $val);
310+
}
311+
else
312+
{
313+
$newarray[$key] = $val;
314+
}
315+
}
316+
return $newarray;
317+
}
318+
319+
320+
321+
}; // end class Config
322+
323+
324+
325+
326+
327+
328+
329+
?>

0 commit comments

Comments
 (0)