1 | <?php |
---|
2 | /** |
---|
3 | * PEAR_Config, customized configuration handling for the PEAR Installer |
---|
4 | * |
---|
5 | * PHP versions 4 and 5 |
---|
6 | * |
---|
7 | * @category pear |
---|
8 | * @package PEAR |
---|
9 | * @author Stig Bakken <ssb@php.net> |
---|
10 | * @author Greg Beaver <cellog@php.net> |
---|
11 | * @copyright 1997-2009 The Authors |
---|
12 | * @license http://opensource.org/licenses/bsd-license.php New BSD License |
---|
13 | * @version CVS: $Id: Config.php 313023 2011-07-06 19:17:11Z dufuz $ |
---|
14 | * @link http://pear.php.net/package/PEAR |
---|
15 | * @since File available since Release 0.1 |
---|
16 | */ |
---|
17 | |
---|
18 | /** |
---|
19 | * Required for error handling |
---|
20 | */ |
---|
21 | require_once 'PEAR.php'; |
---|
22 | require_once 'PEAR/Registry.php'; |
---|
23 | require_once 'PEAR/Installer/Role.php'; |
---|
24 | require_once 'System.php'; |
---|
25 | |
---|
26 | /** |
---|
27 | * Last created PEAR_Config instance. |
---|
28 | * @var object |
---|
29 | */ |
---|
30 | $GLOBALS['_PEAR_Config_instance'] = null; |
---|
31 | if (!defined('PEAR_INSTALL_DIR') || !PEAR_INSTALL_DIR) { |
---|
32 | $PEAR_INSTALL_DIR = PHP_LIBDIR . DIRECTORY_SEPARATOR . 'pear'; |
---|
33 | } else { |
---|
34 | $PEAR_INSTALL_DIR = PEAR_INSTALL_DIR; |
---|
35 | } |
---|
36 | |
---|
37 | // Below we define constants with default values for all configuration |
---|
38 | // parameters except username/password. All of them can have their |
---|
39 | // defaults set through environment variables. The reason we use the |
---|
40 | // PHP_ prefix is for some security, PHP protects environment |
---|
41 | // variables starting with PHP_*. |
---|
42 | |
---|
43 | // default channel and preferred mirror is based on whether we are invoked through |
---|
44 | // the "pear" or the "pecl" command |
---|
45 | if (!defined('PEAR_RUNTYPE')) { |
---|
46 | define('PEAR_RUNTYPE', 'pear'); |
---|
47 | } |
---|
48 | |
---|
49 | if (PEAR_RUNTYPE == 'pear') { |
---|
50 | define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pear.php.net'); |
---|
51 | } else { |
---|
52 | define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pecl.php.net'); |
---|
53 | } |
---|
54 | |
---|
55 | if (getenv('PHP_PEAR_SYSCONF_DIR')) { |
---|
56 | define('PEAR_CONFIG_SYSCONFDIR', getenv('PHP_PEAR_SYSCONF_DIR')); |
---|
57 | } elseif (getenv('SystemRoot')) { |
---|
58 | define('PEAR_CONFIG_SYSCONFDIR', getenv('SystemRoot')); |
---|
59 | } else { |
---|
60 | define('PEAR_CONFIG_SYSCONFDIR', PHP_SYSCONFDIR); |
---|
61 | } |
---|
62 | |
---|
63 | // Default for master_server |
---|
64 | if (getenv('PHP_PEAR_MASTER_SERVER')) { |
---|
65 | define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', getenv('PHP_PEAR_MASTER_SERVER')); |
---|
66 | } else { |
---|
67 | define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', 'pear.php.net'); |
---|
68 | } |
---|
69 | |
---|
70 | // Default for http_proxy |
---|
71 | if (getenv('PHP_PEAR_HTTP_PROXY')) { |
---|
72 | define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('PHP_PEAR_HTTP_PROXY')); |
---|
73 | } elseif (getenv('http_proxy')) { |
---|
74 | define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('http_proxy')); |
---|
75 | } else { |
---|
76 | define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', ''); |
---|
77 | } |
---|
78 | |
---|
79 | // Default for php_dir |
---|
80 | if (getenv('PHP_PEAR_INSTALL_DIR')) { |
---|
81 | define('PEAR_CONFIG_DEFAULT_PHP_DIR', getenv('PHP_PEAR_INSTALL_DIR')); |
---|
82 | } else { |
---|
83 | if (@file_exists($PEAR_INSTALL_DIR) && is_dir($PEAR_INSTALL_DIR)) { |
---|
84 | define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR); |
---|
85 | } else { |
---|
86 | define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR); |
---|
87 | } |
---|
88 | } |
---|
89 | |
---|
90 | // Default for ext_dir |
---|
91 | if (getenv('PHP_PEAR_EXTENSION_DIR')) { |
---|
92 | define('PEAR_CONFIG_DEFAULT_EXT_DIR', getenv('PHP_PEAR_EXTENSION_DIR')); |
---|
93 | } else { |
---|
94 | if (ini_get('extension_dir')) { |
---|
95 | define('PEAR_CONFIG_DEFAULT_EXT_DIR', ini_get('extension_dir')); |
---|
96 | } elseif (defined('PEAR_EXTENSION_DIR') && |
---|
97 | file_exists(PEAR_EXTENSION_DIR) && is_dir(PEAR_EXTENSION_DIR)) { |
---|
98 | define('PEAR_CONFIG_DEFAULT_EXT_DIR', PEAR_EXTENSION_DIR); |
---|
99 | } elseif (defined('PHP_EXTENSION_DIR')) { |
---|
100 | define('PEAR_CONFIG_DEFAULT_EXT_DIR', PHP_EXTENSION_DIR); |
---|
101 | } else { |
---|
102 | define('PEAR_CONFIG_DEFAULT_EXT_DIR', '.'); |
---|
103 | } |
---|
104 | } |
---|
105 | |
---|
106 | // Default for doc_dir |
---|
107 | if (getenv('PHP_PEAR_DOC_DIR')) { |
---|
108 | define('PEAR_CONFIG_DEFAULT_DOC_DIR', getenv('PHP_PEAR_DOC_DIR')); |
---|
109 | } else { |
---|
110 | define('PEAR_CONFIG_DEFAULT_DOC_DIR', |
---|
111 | $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'docs'); |
---|
112 | } |
---|
113 | |
---|
114 | // Default for bin_dir |
---|
115 | if (getenv('PHP_PEAR_BIN_DIR')) { |
---|
116 | define('PEAR_CONFIG_DEFAULT_BIN_DIR', getenv('PHP_PEAR_BIN_DIR')); |
---|
117 | } else { |
---|
118 | define('PEAR_CONFIG_DEFAULT_BIN_DIR', PHP_BINDIR); |
---|
119 | } |
---|
120 | |
---|
121 | // Default for data_dir |
---|
122 | if (getenv('PHP_PEAR_DATA_DIR')) { |
---|
123 | define('PEAR_CONFIG_DEFAULT_DATA_DIR', getenv('PHP_PEAR_DATA_DIR')); |
---|
124 | } else { |
---|
125 | define('PEAR_CONFIG_DEFAULT_DATA_DIR', |
---|
126 | $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'data'); |
---|
127 | } |
---|
128 | |
---|
129 | // Default for cfg_dir |
---|
130 | if (getenv('PHP_PEAR_CFG_DIR')) { |
---|
131 | define('PEAR_CONFIG_DEFAULT_CFG_DIR', getenv('PHP_PEAR_CFG_DIR')); |
---|
132 | } else { |
---|
133 | define('PEAR_CONFIG_DEFAULT_CFG_DIR', |
---|
134 | $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'cfg'); |
---|
135 | } |
---|
136 | |
---|
137 | // Default for www_dir |
---|
138 | if (getenv('PHP_PEAR_WWW_DIR')) { |
---|
139 | define('PEAR_CONFIG_DEFAULT_WWW_DIR', getenv('PHP_PEAR_WWW_DIR')); |
---|
140 | } else { |
---|
141 | define('PEAR_CONFIG_DEFAULT_WWW_DIR', |
---|
142 | $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'www'); |
---|
143 | } |
---|
144 | |
---|
145 | // Default for test_dir |
---|
146 | if (getenv('PHP_PEAR_TEST_DIR')) { |
---|
147 | define('PEAR_CONFIG_DEFAULT_TEST_DIR', getenv('PHP_PEAR_TEST_DIR')); |
---|
148 | } else { |
---|
149 | define('PEAR_CONFIG_DEFAULT_TEST_DIR', |
---|
150 | $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'tests'); |
---|
151 | } |
---|
152 | |
---|
153 | // Default for temp_dir |
---|
154 | if (getenv('PHP_PEAR_TEMP_DIR')) { |
---|
155 | define('PEAR_CONFIG_DEFAULT_TEMP_DIR', getenv('PHP_PEAR_TEMP_DIR')); |
---|
156 | } else { |
---|
157 | define('PEAR_CONFIG_DEFAULT_TEMP_DIR', |
---|
158 | System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . |
---|
159 | DIRECTORY_SEPARATOR . 'temp'); |
---|
160 | } |
---|
161 | |
---|
162 | // Default for cache_dir |
---|
163 | if (getenv('PHP_PEAR_CACHE_DIR')) { |
---|
164 | define('PEAR_CONFIG_DEFAULT_CACHE_DIR', getenv('PHP_PEAR_CACHE_DIR')); |
---|
165 | } else { |
---|
166 | define('PEAR_CONFIG_DEFAULT_CACHE_DIR', |
---|
167 | System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . |
---|
168 | DIRECTORY_SEPARATOR . 'cache'); |
---|
169 | } |
---|
170 | |
---|
171 | // Default for download_dir |
---|
172 | if (getenv('PHP_PEAR_DOWNLOAD_DIR')) { |
---|
173 | define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR', getenv('PHP_PEAR_DOWNLOAD_DIR')); |
---|
174 | } else { |
---|
175 | define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR', |
---|
176 | System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . |
---|
177 | DIRECTORY_SEPARATOR . 'download'); |
---|
178 | } |
---|
179 | |
---|
180 | // Default for php_bin |
---|
181 | if (getenv('PHP_PEAR_PHP_BIN')) { |
---|
182 | define('PEAR_CONFIG_DEFAULT_PHP_BIN', getenv('PHP_PEAR_PHP_BIN')); |
---|
183 | } else { |
---|
184 | define('PEAR_CONFIG_DEFAULT_PHP_BIN', PEAR_CONFIG_DEFAULT_BIN_DIR. |
---|
185 | DIRECTORY_SEPARATOR.'php'.(OS_WINDOWS ? '.exe' : '')); |
---|
186 | } |
---|
187 | |
---|
188 | // Default for verbose |
---|
189 | if (getenv('PHP_PEAR_VERBOSE')) { |
---|
190 | define('PEAR_CONFIG_DEFAULT_VERBOSE', getenv('PHP_PEAR_VERBOSE')); |
---|
191 | } else { |
---|
192 | define('PEAR_CONFIG_DEFAULT_VERBOSE', 1); |
---|
193 | } |
---|
194 | |
---|
195 | // Default for preferred_state |
---|
196 | if (getenv('PHP_PEAR_PREFERRED_STATE')) { |
---|
197 | define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', getenv('PHP_PEAR_PREFERRED_STATE')); |
---|
198 | } else { |
---|
199 | define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', 'stable'); |
---|
200 | } |
---|
201 | |
---|
202 | // Default for umask |
---|
203 | if (getenv('PHP_PEAR_UMASK')) { |
---|
204 | define('PEAR_CONFIG_DEFAULT_UMASK', getenv('PHP_PEAR_UMASK')); |
---|
205 | } else { |
---|
206 | define('PEAR_CONFIG_DEFAULT_UMASK', decoct(umask())); |
---|
207 | } |
---|
208 | |
---|
209 | // Default for cache_ttl |
---|
210 | if (getenv('PHP_PEAR_CACHE_TTL')) { |
---|
211 | define('PEAR_CONFIG_DEFAULT_CACHE_TTL', getenv('PHP_PEAR_CACHE_TTL')); |
---|
212 | } else { |
---|
213 | define('PEAR_CONFIG_DEFAULT_CACHE_TTL', 3600); |
---|
214 | } |
---|
215 | |
---|
216 | // Default for sig_type |
---|
217 | if (getenv('PHP_PEAR_SIG_TYPE')) { |
---|
218 | define('PEAR_CONFIG_DEFAULT_SIG_TYPE', getenv('PHP_PEAR_SIG_TYPE')); |
---|
219 | } else { |
---|
220 | define('PEAR_CONFIG_DEFAULT_SIG_TYPE', 'gpg'); |
---|
221 | } |
---|
222 | |
---|
223 | // Default for sig_bin |
---|
224 | if (getenv('PHP_PEAR_SIG_BIN')) { |
---|
225 | define('PEAR_CONFIG_DEFAULT_SIG_BIN', getenv('PHP_PEAR_SIG_BIN')); |
---|
226 | } else { |
---|
227 | define('PEAR_CONFIG_DEFAULT_SIG_BIN', |
---|
228 | System::which( |
---|
229 | 'gpg', OS_WINDOWS ? 'c:\gnupg\gpg.exe' : '/usr/local/bin/gpg')); |
---|
230 | } |
---|
231 | |
---|
232 | // Default for sig_keydir |
---|
233 | if (getenv('PHP_PEAR_SIG_KEYDIR')) { |
---|
234 | define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR', getenv('PHP_PEAR_SIG_KEYDIR')); |
---|
235 | } else { |
---|
236 | define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR', |
---|
237 | PEAR_CONFIG_SYSCONFDIR . DIRECTORY_SEPARATOR . 'pearkeys'); |
---|
238 | } |
---|
239 | |
---|
240 | /** |
---|
241 | * This is a class for storing configuration data, keeping track of |
---|
242 | * which are system-defined, user-defined or defaulted. |
---|
243 | * @category pear |
---|
244 | * @package PEAR |
---|
245 | * @author Stig Bakken <ssb@php.net> |
---|
246 | * @author Greg Beaver <cellog@php.net> |
---|
247 | * @copyright 1997-2009 The Authors |
---|
248 | * @license http://opensource.org/licenses/bsd-license.php New BSD License |
---|
249 | * @version Release: 1.9.4 |
---|
250 | * @link http://pear.php.net/package/PEAR |
---|
251 | * @since Class available since Release 0.1 |
---|
252 | */ |
---|
253 | class PEAR_Config extends PEAR |
---|
254 | { |
---|
255 | /** |
---|
256 | * Array of config files used. |
---|
257 | * |
---|
258 | * @var array layer => config file |
---|
259 | */ |
---|
260 | var $files = array( |
---|
261 | 'system' => '', |
---|
262 | 'user' => '', |
---|
263 | ); |
---|
264 | |
---|
265 | var $layers = array(); |
---|
266 | |
---|
267 | /** |
---|
268 | * Configuration data, two-dimensional array where the first |
---|
269 | * dimension is the config layer ('user', 'system' and 'default'), |
---|
270 | * and the second dimension is keyname => value. |
---|
271 | * |
---|
272 | * The order in the first dimension is important! Earlier |
---|
273 | * layers will shadow later ones when a config value is |
---|
274 | * requested (if a 'user' value exists, it will be returned first, |
---|
275 | * then 'system' and finally 'default'). |
---|
276 | * |
---|
277 | * @var array layer => array(keyname => value, ...) |
---|
278 | */ |
---|
279 | var $configuration = array( |
---|
280 | 'user' => array(), |
---|
281 | 'system' => array(), |
---|
282 | 'default' => array(), |
---|
283 | ); |
---|
284 | |
---|
285 | /** |
---|
286 | * Configuration values that can be set for a channel |
---|
287 | * |
---|
288 | * All other configuration values can only have a global value |
---|
289 | * @var array |
---|
290 | * @access private |
---|
291 | */ |
---|
292 | var $_channelConfigInfo = array( |
---|
293 | 'php_dir', 'ext_dir', 'doc_dir', 'bin_dir', 'data_dir', 'cfg_dir', |
---|
294 | 'test_dir', 'www_dir', 'php_bin', 'php_prefix', 'php_suffix', 'username', |
---|
295 | 'password', 'verbose', 'preferred_state', 'umask', 'preferred_mirror', 'php_ini' |
---|
296 | ); |
---|
297 | |
---|
298 | /** |
---|
299 | * Channels that can be accessed |
---|
300 | * @see setChannels() |
---|
301 | * @var array |
---|
302 | * @access private |
---|
303 | */ |
---|
304 | var $_channels = array('pear.php.net', 'pecl.php.net', '__uri'); |
---|
305 | |
---|
306 | /** |
---|
307 | * This variable is used to control the directory values returned |
---|
308 | * @see setInstallRoot(); |
---|
309 | * @var string|false |
---|
310 | * @access private |
---|
311 | */ |
---|
312 | var $_installRoot = false; |
---|
313 | |
---|
314 | /** |
---|
315 | * If requested, this will always refer to the registry |
---|
316 | * contained in php_dir |
---|
317 | * @var PEAR_Registry |
---|
318 | */ |
---|
319 | var $_registry = array(); |
---|
320 | |
---|
321 | /** |
---|
322 | * @var array |
---|
323 | * @access private |
---|
324 | */ |
---|
325 | var $_regInitialized = array(); |
---|
326 | |
---|
327 | /** |
---|
328 | * @var bool |
---|
329 | * @access private |
---|
330 | */ |
---|
331 | var $_noRegistry = false; |
---|
332 | |
---|
333 | /** |
---|
334 | * amount of errors found while parsing config |
---|
335 | * @var integer |
---|
336 | * @access private |
---|
337 | */ |
---|
338 | var $_errorsFound = 0; |
---|
339 | var $_lastError = null; |
---|
340 | |
---|
341 | /** |
---|
342 | * Information about the configuration data. Stores the type, |
---|
343 | * default value and a documentation string for each configuration |
---|
344 | * value. |
---|
345 | * |
---|
346 | * @var array layer => array(infotype => value, ...) |
---|
347 | */ |
---|
348 | var $configuration_info = array( |
---|
349 | // Channels/Internet Access |
---|
350 | 'default_channel' => array( |
---|
351 | 'type' => 'string', |
---|
352 | 'default' => PEAR_CONFIG_DEFAULT_CHANNEL, |
---|
353 | 'doc' => 'the default channel to use for all non explicit commands', |
---|
354 | 'prompt' => 'Default Channel', |
---|
355 | 'group' => 'Internet Access', |
---|
356 | ), |
---|
357 | 'preferred_mirror' => array( |
---|
358 | 'type' => 'string', |
---|
359 | 'default' => PEAR_CONFIG_DEFAULT_CHANNEL, |
---|
360 | 'doc' => 'the default server or mirror to use for channel actions', |
---|
361 | 'prompt' => 'Default Channel Mirror', |
---|
362 | 'group' => 'Internet Access', |
---|
363 | ), |
---|
364 | 'remote_config' => array( |
---|
365 | 'type' => 'password', |
---|
366 | 'default' => '', |
---|
367 | 'doc' => 'ftp url of remote configuration file to use for synchronized install', |
---|
368 | 'prompt' => 'Remote Configuration File', |
---|
369 | 'group' => 'Internet Access', |
---|
370 | ), |
---|
371 | 'auto_discover' => array( |
---|
372 | 'type' => 'integer', |
---|
373 | 'default' => 0, |
---|
374 | 'doc' => 'whether to automatically discover new channels', |
---|
375 | 'prompt' => 'Auto-discover new Channels', |
---|
376 | 'group' => 'Internet Access', |
---|
377 | ), |
---|
378 | // Internet Access |
---|
379 | 'master_server' => array( |
---|
380 | 'type' => 'string', |
---|
381 | 'default' => 'pear.php.net', |
---|
382 | 'doc' => 'name of the main PEAR server [NOT USED IN THIS VERSION]', |
---|
383 | 'prompt' => 'PEAR server [DEPRECATED]', |
---|
384 | 'group' => 'Internet Access', |
---|
385 | ), |
---|
386 | 'http_proxy' => array( |
---|
387 | 'type' => 'string', |
---|
388 | 'default' => PEAR_CONFIG_DEFAULT_HTTP_PROXY, |
---|
389 | 'doc' => 'HTTP proxy (host:port) to use when downloading packages', |
---|
390 | 'prompt' => 'HTTP Proxy Server Address', |
---|
391 | 'group' => 'Internet Access', |
---|
392 | ), |
---|
393 | // File Locations |
---|
394 | 'php_dir' => array( |
---|
395 | 'type' => 'directory', |
---|
396 | 'default' => PEAR_CONFIG_DEFAULT_PHP_DIR, |
---|
397 | 'doc' => 'directory where .php files are installed', |
---|
398 | 'prompt' => 'PEAR directory', |
---|
399 | 'group' => 'File Locations', |
---|
400 | ), |
---|
401 | 'ext_dir' => array( |
---|
402 | 'type' => 'directory', |
---|
403 | 'default' => PEAR_CONFIG_DEFAULT_EXT_DIR, |
---|
404 | 'doc' => 'directory where loadable extensions are installed', |
---|
405 | 'prompt' => 'PHP extension directory', |
---|
406 | 'group' => 'File Locations', |
---|
407 | ), |
---|
408 | 'doc_dir' => array( |
---|
409 | 'type' => 'directory', |
---|
410 | 'default' => PEAR_CONFIG_DEFAULT_DOC_DIR, |
---|
411 | 'doc' => 'directory where documentation is installed', |
---|
412 | 'prompt' => 'PEAR documentation directory', |
---|
413 | 'group' => 'File Locations', |
---|
414 | ), |
---|
415 | 'bin_dir' => array( |
---|
416 | 'type' => 'directory', |
---|
417 | 'default' => PEAR_CONFIG_DEFAULT_BIN_DIR, |
---|
418 | 'doc' => 'directory where executables are installed', |
---|
419 | 'prompt' => 'PEAR executables directory', |
---|
420 | 'group' => 'File Locations', |
---|
421 | ), |
---|
422 | 'data_dir' => array( |
---|
423 | 'type' => 'directory', |
---|
424 | 'default' => PEAR_CONFIG_DEFAULT_DATA_DIR, |
---|
425 | 'doc' => 'directory where data files are installed', |
---|
426 | 'prompt' => 'PEAR data directory', |
---|
427 | 'group' => 'File Locations (Advanced)', |
---|
428 | ), |
---|
429 | 'cfg_dir' => array( |
---|
430 | 'type' => 'directory', |
---|
431 | 'default' => PEAR_CONFIG_DEFAULT_CFG_DIR, |
---|
432 | 'doc' => 'directory where modifiable configuration files are installed', |
---|
433 | 'prompt' => 'PEAR configuration file directory', |
---|
434 | 'group' => 'File Locations (Advanced)', |
---|
435 | ), |
---|
436 | 'www_dir' => array( |
---|
437 | 'type' => 'directory', |
---|
438 | 'default' => PEAR_CONFIG_DEFAULT_WWW_DIR, |
---|
439 | 'doc' => 'directory where www frontend files (html/js) are installed', |
---|
440 | 'prompt' => 'PEAR www files directory', |
---|
441 | 'group' => 'File Locations (Advanced)', |
---|
442 | ), |
---|
443 | 'test_dir' => array( |
---|
444 | 'type' => 'directory', |
---|
445 | 'default' => PEAR_CONFIG_DEFAULT_TEST_DIR, |
---|
446 | 'doc' => 'directory where regression tests are installed', |
---|
447 | 'prompt' => 'PEAR test directory', |
---|
448 | 'group' => 'File Locations (Advanced)', |
---|
449 | ), |
---|
450 | 'cache_dir' => array( |
---|
451 | 'type' => 'directory', |
---|
452 | 'default' => PEAR_CONFIG_DEFAULT_CACHE_DIR, |
---|
453 | 'doc' => 'directory which is used for web service cache', |
---|
454 | 'prompt' => 'PEAR Installer cache directory', |
---|
455 | 'group' => 'File Locations (Advanced)', |
---|
456 | ), |
---|
457 | 'temp_dir' => array( |
---|
458 | 'type' => 'directory', |
---|
459 | 'default' => PEAR_CONFIG_DEFAULT_TEMP_DIR, |
---|
460 | 'doc' => 'directory which is used for all temp files', |
---|
461 | 'prompt' => 'PEAR Installer temp directory', |
---|
462 | 'group' => 'File Locations (Advanced)', |
---|
463 | ), |
---|
464 | 'download_dir' => array( |
---|
465 | 'type' => 'directory', |
---|
466 | 'default' => PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR, |
---|
467 | 'doc' => 'directory which is used for all downloaded files', |
---|
468 | 'prompt' => 'PEAR Installer download directory', |
---|
469 | 'group' => 'File Locations (Advanced)', |
---|
470 | ), |
---|
471 | 'php_bin' => array( |
---|
472 | 'type' => 'file', |
---|
473 | 'default' => PEAR_CONFIG_DEFAULT_PHP_BIN, |
---|
474 | 'doc' => 'PHP CLI/CGI binary for executing scripts', |
---|
475 | 'prompt' => 'PHP CLI/CGI binary', |
---|
476 | 'group' => 'File Locations (Advanced)', |
---|
477 | ), |
---|
478 | 'php_prefix' => array( |
---|
479 | 'type' => 'string', |
---|
480 | 'default' => '', |
---|
481 | 'doc' => '--program-prefix for php_bin\'s ./configure, used for pecl installs', |
---|
482 | 'prompt' => '--program-prefix passed to PHP\'s ./configure', |
---|
483 | 'group' => 'File Locations (Advanced)', |
---|
484 | ), |
---|
485 | 'php_suffix' => array( |
---|
486 | 'type' => 'string', |
---|
487 | 'default' => '', |
---|
488 | 'doc' => '--program-suffix for php_bin\'s ./configure, used for pecl installs', |
---|
489 | 'prompt' => '--program-suffix passed to PHP\'s ./configure', |
---|
490 | 'group' => 'File Locations (Advanced)', |
---|
491 | ), |
---|
492 | 'php_ini' => array( |
---|
493 | 'type' => 'file', |
---|
494 | 'default' => '', |
---|
495 | 'doc' => 'location of php.ini in which to enable PECL extensions on install', |
---|
496 | 'prompt' => 'php.ini location', |
---|
497 | 'group' => 'File Locations (Advanced)', |
---|
498 | ), |
---|
499 | // Maintainers |
---|
500 | 'username' => array( |
---|
501 | 'type' => 'string', |
---|
502 | 'default' => '', |
---|
503 | 'doc' => '(maintainers) your PEAR account name', |
---|
504 | 'prompt' => 'PEAR username (for maintainers)', |
---|
505 | 'group' => 'Maintainers', |
---|
506 | ), |
---|
507 | 'password' => array( |
---|
508 | 'type' => 'password', |
---|
509 | 'default' => '', |
---|
510 | 'doc' => '(maintainers) your PEAR account password', |
---|
511 | 'prompt' => 'PEAR password (for maintainers)', |
---|
512 | 'group' => 'Maintainers', |
---|
513 | ), |
---|
514 | // Advanced |
---|
515 | 'verbose' => array( |
---|
516 | 'type' => 'integer', |
---|
517 | 'default' => PEAR_CONFIG_DEFAULT_VERBOSE, |
---|
518 | 'doc' => 'verbosity level |
---|
519 | 0: really quiet |
---|
520 | 1: somewhat quiet |
---|
521 | 2: verbose |
---|
522 | 3: debug', |
---|
523 | 'prompt' => 'Debug Log Level', |
---|
524 | 'group' => 'Advanced', |
---|
525 | ), |
---|
526 | 'preferred_state' => array( |
---|
527 | 'type' => 'set', |
---|
528 | 'default' => PEAR_CONFIG_DEFAULT_PREFERRED_STATE, |
---|
529 | 'doc' => 'the installer will prefer releases with this state when installing packages without a version or state specified', |
---|
530 | 'valid_set' => array( |
---|
531 | 'stable', 'beta', 'alpha', 'devel', 'snapshot'), |
---|
532 | 'prompt' => 'Preferred Package State', |
---|
533 | 'group' => 'Advanced', |
---|
534 | ), |
---|
535 | 'umask' => array( |
---|
536 | 'type' => 'mask', |
---|
537 | 'default' => PEAR_CONFIG_DEFAULT_UMASK, |
---|
538 | 'doc' => 'umask used when creating files (Unix-like systems only)', |
---|
539 | 'prompt' => 'Unix file mask', |
---|
540 | 'group' => 'Advanced', |
---|
541 | ), |
---|
542 | 'cache_ttl' => array( |
---|
543 | 'type' => 'integer', |
---|
544 | 'default' => PEAR_CONFIG_DEFAULT_CACHE_TTL, |
---|
545 | 'doc' => 'amount of secs where the local cache is used and not updated', |
---|
546 | 'prompt' => 'Cache TimeToLive', |
---|
547 | 'group' => 'Advanced', |
---|
548 | ), |
---|
549 | 'sig_type' => array( |
---|
550 | 'type' => 'set', |
---|
551 | 'default' => PEAR_CONFIG_DEFAULT_SIG_TYPE, |
---|
552 | 'doc' => 'which package signature mechanism to use', |
---|
553 | 'valid_set' => array('gpg'), |
---|
554 | 'prompt' => 'Package Signature Type', |
---|
555 | 'group' => 'Maintainers', |
---|
556 | ), |
---|
557 | 'sig_bin' => array( |
---|
558 | 'type' => 'string', |
---|
559 | 'default' => PEAR_CONFIG_DEFAULT_SIG_BIN, |
---|
560 | 'doc' => 'which package signature mechanism to use', |
---|
561 | 'prompt' => 'Signature Handling Program', |
---|
562 | 'group' => 'Maintainers', |
---|
563 | ), |
---|
564 | 'sig_keyid' => array( |
---|
565 | 'type' => 'string', |
---|
566 | 'default' => '', |
---|
567 | 'doc' => 'which key to use for signing with', |
---|
568 | 'prompt' => 'Signature Key Id', |
---|
569 | 'group' => 'Maintainers', |
---|
570 | ), |
---|
571 | 'sig_keydir' => array( |
---|
572 | 'type' => 'directory', |
---|
573 | 'default' => PEAR_CONFIG_DEFAULT_SIG_KEYDIR, |
---|
574 | 'doc' => 'directory where signature keys are located', |
---|
575 | 'prompt' => 'Signature Key Directory', |
---|
576 | 'group' => 'Maintainers', |
---|
577 | ), |
---|
578 | // __channels is reserved - used for channel-specific configuration |
---|
579 | ); |
---|
580 | |
---|
581 | /** |
---|
582 | * Constructor. |
---|
583 | * |
---|
584 | * @param string file to read user-defined options from |
---|
585 | * @param string file to read system-wide defaults from |
---|
586 | * @param bool determines whether a registry object "follows" |
---|
587 | * the value of php_dir (is automatically created |
---|
588 | * and moved when php_dir is changed) |
---|
589 | * @param bool if true, fails if configuration files cannot be loaded |
---|
590 | * |
---|
591 | * @access public |
---|
592 | * |
---|
593 | * @see PEAR_Config::singleton |
---|
594 | */ |
---|
595 | function PEAR_Config($user_file = '', $system_file = '', $ftp_file = false, |
---|
596 | $strict = true) |
---|
597 | { |
---|
598 | $this->PEAR(); |
---|
599 | PEAR_Installer_Role::initializeConfig($this); |
---|
600 | $sl = DIRECTORY_SEPARATOR; |
---|
601 | if (empty($user_file)) { |
---|
602 | if (OS_WINDOWS) { |
---|
603 | $user_file = PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini'; |
---|
604 | } else { |
---|
605 | $user_file = getenv('HOME') . $sl . '.pearrc'; |
---|
606 | } |
---|
607 | } |
---|
608 | |
---|
609 | if (empty($system_file)) { |
---|
610 | $system_file = PEAR_CONFIG_SYSCONFDIR . $sl; |
---|
611 | if (OS_WINDOWS) { |
---|
612 | $system_file .= 'pearsys.ini'; |
---|
613 | } else { |
---|
614 | $system_file .= 'pear.conf'; |
---|
615 | } |
---|
616 | } |
---|
617 | |
---|
618 | $this->layers = array_keys($this->configuration); |
---|
619 | $this->files['user'] = $user_file; |
---|
620 | $this->files['system'] = $system_file; |
---|
621 | if ($user_file && file_exists($user_file)) { |
---|
622 | $this->pushErrorHandling(PEAR_ERROR_RETURN); |
---|
623 | $this->readConfigFile($user_file, 'user', $strict); |
---|
624 | $this->popErrorHandling(); |
---|
625 | if ($this->_errorsFound > 0) { |
---|
626 | return; |
---|
627 | } |
---|
628 | } |
---|
629 | |
---|
630 | if ($system_file && @file_exists($system_file)) { |
---|
631 | $this->mergeConfigFile($system_file, false, 'system', $strict); |
---|
632 | if ($this->_errorsFound > 0) { |
---|
633 | return; |
---|
634 | } |
---|
635 | |
---|
636 | } |
---|
637 | |
---|
638 | if (!$ftp_file) { |
---|
639 | $ftp_file = $this->get('remote_config'); |
---|
640 | } |
---|
641 | |
---|
642 | if ($ftp_file && defined('PEAR_REMOTEINSTALL_OK')) { |
---|
643 | $this->readFTPConfigFile($ftp_file); |
---|
644 | } |
---|
645 | |
---|
646 | foreach ($this->configuration_info as $key => $info) { |
---|
647 | $this->configuration['default'][$key] = $info['default']; |
---|
648 | } |
---|
649 | |
---|
650 | $this->_registry['default'] = &new PEAR_Registry($this->configuration['default']['php_dir']); |
---|
651 | $this->_registry['default']->setConfig($this, false); |
---|
652 | $this->_regInitialized['default'] = false; |
---|
653 | //$GLOBALS['_PEAR_Config_instance'] = &$this; |
---|
654 | } |
---|
655 | |
---|
656 | /** |
---|
657 | * Return the default locations of user and system configuration files |
---|
658 | * @static |
---|
659 | */ |
---|
660 | function getDefaultConfigFiles() |
---|
661 | { |
---|
662 | $sl = DIRECTORY_SEPARATOR; |
---|
663 | if (OS_WINDOWS) { |
---|
664 | return array( |
---|
665 | 'user' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini', |
---|
666 | 'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pearsys.ini' |
---|
667 | ); |
---|
668 | } |
---|
669 | |
---|
670 | return array( |
---|
671 | 'user' => getenv('HOME') . $sl . '.pearrc', |
---|
672 | 'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.conf' |
---|
673 | ); |
---|
674 | } |
---|
675 | |
---|
676 | /** |
---|
677 | * Static singleton method. If you want to keep only one instance |
---|
678 | * of this class in use, this method will give you a reference to |
---|
679 | * the last created PEAR_Config object if one exists, or create a |
---|
680 | * new object. |
---|
681 | * |
---|
682 | * @param string (optional) file to read user-defined options from |
---|
683 | * @param string (optional) file to read system-wide defaults from |
---|
684 | * |
---|
685 | * @return object an existing or new PEAR_Config instance |
---|
686 | * |
---|
687 | * @access public |
---|
688 | * |
---|
689 | * @see PEAR_Config::PEAR_Config |
---|
690 | */ |
---|
691 | function &singleton($user_file = '', $system_file = '', $strict = true) |
---|
692 | { |
---|
693 | if (is_object($GLOBALS['_PEAR_Config_instance'])) { |
---|
694 | return $GLOBALS['_PEAR_Config_instance']; |
---|
695 | } |
---|
696 | |
---|
697 | $t_conf = &new PEAR_Config($user_file, $system_file, false, $strict); |
---|
698 | if ($t_conf->_errorsFound > 0) { |
---|
699 | return $t_conf->lastError; |
---|
700 | } |
---|
701 | |
---|
702 | $GLOBALS['_PEAR_Config_instance'] = &$t_conf; |
---|
703 | return $GLOBALS['_PEAR_Config_instance']; |
---|
704 | } |
---|
705 | |
---|
706 | /** |
---|
707 | * Determine whether any configuration files have been detected, and whether a |
---|
708 | * registry object can be retrieved from this configuration. |
---|
709 | * @return bool |
---|
710 | * @since PEAR 1.4.0a1 |
---|
711 | */ |
---|
712 | function validConfiguration() |
---|
713 | { |
---|
714 | if ($this->isDefinedLayer('user') || $this->isDefinedLayer('system')) { |
---|
715 | return true; |
---|
716 | } |
---|
717 | |
---|
718 | return false; |
---|
719 | } |
---|
720 | |
---|
721 | /** |
---|
722 | * Reads configuration data from a file. All existing values in |
---|
723 | * the config layer are discarded and replaced with data from the |
---|
724 | * file. |
---|
725 | * @param string file to read from, if NULL or not specified, the |
---|
726 | * last-used file for the same layer (second param) is used |
---|
727 | * @param string config layer to insert data into ('user' or 'system') |
---|
728 | * @return bool TRUE on success or a PEAR error on failure |
---|
729 | */ |
---|
730 | function readConfigFile($file = null, $layer = 'user', $strict = true) |
---|
731 | { |
---|
732 | if (empty($this->files[$layer])) { |
---|
733 | return $this->raiseError("unknown config layer `$layer'"); |
---|
734 | } |
---|
735 | |
---|
736 | if ($file === null) { |
---|
737 | $file = $this->files[$layer]; |
---|
738 | } |
---|
739 | |
---|
740 | $data = $this->_readConfigDataFrom($file); |
---|
741 | if (PEAR::isError($data)) { |
---|
742 | if (!$strict) { |
---|
743 | return true; |
---|
744 | } |
---|
745 | |
---|
746 | $this->_errorsFound++; |
---|
747 | $this->lastError = $data; |
---|
748 | |
---|
749 | return $data; |
---|
750 | } |
---|
751 | |
---|
752 | $this->files[$layer] = $file; |
---|
753 | $this->_decodeInput($data); |
---|
754 | $this->configuration[$layer] = $data; |
---|
755 | $this->_setupChannels(); |
---|
756 | if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) { |
---|
757 | $this->_registry[$layer] = &new PEAR_Registry($phpdir); |
---|
758 | $this->_registry[$layer]->setConfig($this, false); |
---|
759 | $this->_regInitialized[$layer] = false; |
---|
760 | } else { |
---|
761 | unset($this->_registry[$layer]); |
---|
762 | } |
---|
763 | return true; |
---|
764 | } |
---|
765 | |
---|
766 | /** |
---|
767 | * @param string url to the remote config file, like ftp://www.example.com/pear/config.ini |
---|
768 | * @return true|PEAR_Error |
---|
769 | */ |
---|
770 | function readFTPConfigFile($path) |
---|
771 | { |
---|
772 | do { // poor man's try |
---|
773 | if (!class_exists('PEAR_FTP')) { |
---|
774 | if (!class_exists('PEAR_Common')) { |
---|
775 | require_once 'PEAR/Common.php'; |
---|
776 | } |
---|
777 | if (PEAR_Common::isIncludeable('PEAR/FTP.php')) { |
---|
778 | require_once 'PEAR/FTP.php'; |
---|
779 | } |
---|
780 | } |
---|
781 | |
---|
782 | if (!class_exists('PEAR_FTP')) { |
---|
783 | return PEAR::raiseError('PEAR_RemoteInstaller must be installed to use remote config'); |
---|
784 | } |
---|
785 | |
---|
786 | $this->_ftp = &new PEAR_FTP; |
---|
787 | $this->_ftp->pushErrorHandling(PEAR_ERROR_RETURN); |
---|
788 | $e = $this->_ftp->init($path); |
---|
789 | if (PEAR::isError($e)) { |
---|
790 | $this->_ftp->popErrorHandling(); |
---|
791 | return $e; |
---|
792 | } |
---|
793 | |
---|
794 | $tmp = System::mktemp('-d'); |
---|
795 | PEAR_Common::addTempFile($tmp); |
---|
796 | $e = $this->_ftp->get(basename($path), $tmp . DIRECTORY_SEPARATOR . |
---|
797 | 'pear.ini', false, FTP_BINARY); |
---|
798 | if (PEAR::isError($e)) { |
---|
799 | $this->_ftp->popErrorHandling(); |
---|
800 | return $e; |
---|
801 | } |
---|
802 | |
---|
803 | PEAR_Common::addTempFile($tmp . DIRECTORY_SEPARATOR . 'pear.ini'); |
---|
804 | $this->_ftp->disconnect(); |
---|
805 | $this->_ftp->popErrorHandling(); |
---|
806 | $this->files['ftp'] = $tmp . DIRECTORY_SEPARATOR . 'pear.ini'; |
---|
807 | $e = $this->readConfigFile(null, 'ftp'); |
---|
808 | if (PEAR::isError($e)) { |
---|
809 | return $e; |
---|
810 | } |
---|
811 | |
---|
812 | $fail = array(); |
---|
813 | foreach ($this->configuration_info as $key => $val) { |
---|
814 | if (in_array($this->getGroup($key), |
---|
815 | array('File Locations', 'File Locations (Advanced)')) && |
---|
816 | $this->getType($key) == 'directory') { |
---|
817 | // any directory configs must be set for this to work |
---|
818 | if (!isset($this->configuration['ftp'][$key])) { |
---|
819 | $fail[] = $key; |
---|
820 | } |
---|
821 | } |
---|
822 | } |
---|
823 | |
---|
824 | if (!count($fail)) { |
---|
825 | return true; |
---|
826 | } |
---|
827 | |
---|
828 | $fail = '"' . implode('", "', $fail) . '"'; |
---|
829 | unset($this->files['ftp']); |
---|
830 | unset($this->configuration['ftp']); |
---|
831 | return PEAR::raiseError('ERROR: Ftp configuration file must set all ' . |
---|
832 | 'directory configuration variables. These variables were not set: ' . |
---|
833 | $fail); |
---|
834 | } while (false); // poor man's catch |
---|
835 | unset($this->files['ftp']); |
---|
836 | return PEAR::raiseError('no remote host specified'); |
---|
837 | } |
---|
838 | |
---|
839 | /** |
---|
840 | * Reads the existing configurations and creates the _channels array from it |
---|
841 | */ |
---|
842 | function _setupChannels() |
---|
843 | { |
---|
844 | $set = array_flip(array_values($this->_channels)); |
---|
845 | foreach ($this->configuration as $layer => $data) { |
---|
846 | $i = 1000; |
---|
847 | if (isset($data['__channels']) && is_array($data['__channels'])) { |
---|
848 | foreach ($data['__channels'] as $channel => $info) { |
---|
849 | $set[$channel] = $i++; |
---|
850 | } |
---|
851 | } |
---|
852 | } |
---|
853 | $this->_channels = array_values(array_flip($set)); |
---|
854 | $this->setChannels($this->_channels); |
---|
855 | } |
---|
856 | |
---|
857 | function deleteChannel($channel) |
---|
858 | { |
---|
859 | $ch = strtolower($channel); |
---|
860 | foreach ($this->configuration as $layer => $data) { |
---|
861 | if (isset($data['__channels']) && isset($data['__channels'][$ch])) { |
---|
862 | unset($this->configuration[$layer]['__channels'][$ch]); |
---|
863 | } |
---|
864 | } |
---|
865 | |
---|
866 | $this->_channels = array_flip($this->_channels); |
---|
867 | unset($this->_channels[$ch]); |
---|
868 | $this->_channels = array_flip($this->_channels); |
---|
869 | } |
---|
870 | |
---|
871 | /** |
---|
872 | * Merges data into a config layer from a file. Does the same |
---|
873 | * thing as readConfigFile, except it does not replace all |
---|
874 | * existing values in the config layer. |
---|
875 | * @param string file to read from |
---|
876 | * @param bool whether to overwrite existing data (default TRUE) |
---|
877 | * @param string config layer to insert data into ('user' or 'system') |
---|
878 | * @param string if true, errors are returned if file opening fails |
---|
879 | * @return bool TRUE on success or a PEAR error on failure |
---|
880 | */ |
---|
881 | function mergeConfigFile($file, $override = true, $layer = 'user', $strict = true) |
---|
882 | { |
---|
883 | if (empty($this->files[$layer])) { |
---|
884 | return $this->raiseError("unknown config layer `$layer'"); |
---|
885 | } |
---|
886 | |
---|
887 | if ($file === null) { |
---|
888 | $file = $this->files[$layer]; |
---|
889 | } |
---|
890 | |
---|
891 | $data = $this->_readConfigDataFrom($file); |
---|
892 | if (PEAR::isError($data)) { |
---|
893 | if (!$strict) { |
---|
894 | return true; |
---|
895 | } |
---|
896 | |
---|
897 | $this->_errorsFound++; |
---|
898 | $this->lastError = $data; |
---|
899 | |
---|
900 | return $data; |
---|
901 | } |
---|
902 | |
---|
903 | $this->_decodeInput($data); |
---|
904 | if ($override) { |
---|
905 | $this->configuration[$layer] = |
---|
906 | PEAR_Config::arrayMergeRecursive($this->configuration[$layer], $data); |
---|
907 | } else { |
---|
908 | $this->configuration[$layer] = |
---|
909 | PEAR_Config::arrayMergeRecursive($data, $this->configuration[$layer]); |
---|
910 | } |
---|
911 | |
---|
912 | $this->_setupChannels(); |
---|
913 | if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) { |
---|
914 | $this->_registry[$layer] = &new PEAR_Registry($phpdir); |
---|
915 | $this->_registry[$layer]->setConfig($this, false); |
---|
916 | $this->_regInitialized[$layer] = false; |
---|
917 | } else { |
---|
918 | unset($this->_registry[$layer]); |
---|
919 | } |
---|
920 | return true; |
---|
921 | } |
---|
922 | |
---|
923 | /** |
---|
924 | * @param array |
---|
925 | * @param array |
---|
926 | * @return array |
---|
927 | * @static |
---|
928 | */ |
---|
929 | function arrayMergeRecursive($arr2, $arr1) |
---|
930 | { |
---|
931 | $ret = array(); |
---|
932 | foreach ($arr2 as $key => $data) { |
---|
933 | if (!isset($arr1[$key])) { |
---|
934 | $ret[$key] = $data; |
---|
935 | unset($arr1[$key]); |
---|
936 | continue; |
---|
937 | } |
---|
938 | if (is_array($data)) { |
---|
939 | if (!is_array($arr1[$key])) { |
---|
940 | $ret[$key] = $arr1[$key]; |
---|
941 | unset($arr1[$key]); |
---|
942 | continue; |
---|
943 | } |
---|
944 | $ret[$key] = PEAR_Config::arrayMergeRecursive($arr1[$key], $arr2[$key]); |
---|
945 | unset($arr1[$key]); |
---|
946 | } |
---|
947 | } |
---|
948 | |
---|
949 | return array_merge($ret, $arr1); |
---|
950 | } |
---|
951 | |
---|
952 | /** |
---|
953 | * Writes data into a config layer from a file. |
---|
954 | * |
---|
955 | * @param string|null file to read from, or null for default |
---|
956 | * @param string config layer to insert data into ('user' or |
---|
957 | * 'system') |
---|
958 | * @param string|null data to write to config file or null for internal data [DEPRECATED] |
---|
959 | * @return bool TRUE on success or a PEAR error on failure |
---|
960 | */ |
---|
961 | function writeConfigFile($file = null, $layer = 'user', $data = null) |
---|
962 | { |
---|
963 | $this->_lazyChannelSetup($layer); |
---|
964 | if ($layer == 'both' || $layer == 'all') { |
---|
965 | foreach ($this->files as $type => $file) { |
---|
966 | $err = $this->writeConfigFile($file, $type, $data); |
---|
967 | if (PEAR::isError($err)) { |
---|
968 | return $err; |
---|
969 | } |
---|
970 | } |
---|
971 | return true; |
---|
972 | } |
---|
973 | |
---|
974 | if (empty($this->files[$layer])) { |
---|
975 | return $this->raiseError("unknown config file type `$layer'"); |
---|
976 | } |
---|
977 | |
---|
978 | if ($file === null) { |
---|
979 | $file = $this->files[$layer]; |
---|
980 | } |
---|
981 | |
---|
982 | $data = ($data === null) ? $this->configuration[$layer] : $data; |
---|
983 | $this->_encodeOutput($data); |
---|
984 | $opt = array('-p', dirname($file)); |
---|
985 | if (!@System::mkDir($opt)) { |
---|
986 | return $this->raiseError("could not create directory: " . dirname($file)); |
---|
987 | } |
---|
988 | |
---|
989 | if (file_exists($file) && is_file($file) && !is_writeable($file)) { |
---|
990 | return $this->raiseError("no write access to $file!"); |
---|
991 | } |
---|
992 | |
---|
993 | $fp = @fopen($file, "w"); |
---|
994 | if (!$fp) { |
---|
995 | return $this->raiseError("PEAR_Config::writeConfigFile fopen('$file','w') failed ($php_errormsg)"); |
---|
996 | } |
---|
997 | |
---|
998 | $contents = "#PEAR_Config 0.9\n" . serialize($data); |
---|
999 | if (!@fwrite($fp, $contents)) { |
---|
1000 | return $this->raiseError("PEAR_Config::writeConfigFile: fwrite failed ($php_errormsg)"); |
---|
1001 | } |
---|
1002 | return true; |
---|
1003 | } |
---|
1004 | |
---|
1005 | /** |
---|
1006 | * Reads configuration data from a file and returns the parsed data |
---|
1007 | * in an array. |
---|
1008 | * |
---|
1009 | * @param string file to read from |
---|
1010 | * @return array configuration data or a PEAR error on failure |
---|
1011 | * @access private |
---|
1012 | */ |
---|
1013 | function _readConfigDataFrom($file) |
---|
1014 | { |
---|
1015 | $fp = false; |
---|
1016 | if (file_exists($file)) { |
---|
1017 | $fp = @fopen($file, "r"); |
---|
1018 | } |
---|
1019 | |
---|
1020 | if (!$fp) { |
---|
1021 | return $this->raiseError("PEAR_Config::readConfigFile fopen('$file','r') failed"); |
---|
1022 | } |
---|
1023 | |
---|
1024 | $size = filesize($file); |
---|
1025 | $rt = get_magic_quotes_runtime(); |
---|
1026 | set_magic_quotes_runtime(0); |
---|
1027 | fclose($fp); |
---|
1028 | $contents = file_get_contents($file); |
---|
1029 | if (empty($contents)) { |
---|
1030 | return $this->raiseError('Configuration file "' . $file . '" is empty'); |
---|
1031 | } |
---|
1032 | |
---|
1033 | set_magic_quotes_runtime($rt); |
---|
1034 | |
---|
1035 | $version = false; |
---|
1036 | if (preg_match('/^#PEAR_Config\s+(\S+)\s+/si', $contents, $matches)) { |
---|
1037 | $version = $matches[1]; |
---|
1038 | $contents = substr($contents, strlen($matches[0])); |
---|
1039 | } else { |
---|
1040 | // Museum config file |
---|
1041 | if (substr($contents,0,2) == 'a:') { |
---|
1042 | $version = '0.1'; |
---|
1043 | } |
---|
1044 | } |
---|
1045 | |
---|
1046 | if ($version && version_compare("$version", '1', '<')) { |
---|
1047 | // no '@', it is possible that unserialize |
---|
1048 | // raises a notice but it seems to block IO to |
---|
1049 | // STDOUT if a '@' is used and a notice is raise |
---|
1050 | $data = unserialize($contents); |
---|
1051 | |
---|
1052 | if (!is_array($data) && !$data) { |
---|
1053 | if ($contents == serialize(false)) { |
---|
1054 | $data = array(); |
---|
1055 | } else { |
---|
1056 | $err = $this->raiseError("PEAR_Config: bad data in $file"); |
---|
1057 | return $err; |
---|
1058 | } |
---|
1059 | } |
---|
1060 | if (!is_array($data)) { |
---|
1061 | if (strlen(trim($contents)) > 0) { |
---|
1062 | $error = "PEAR_Config: bad data in $file"; |
---|
1063 | $err = $this->raiseError($error); |
---|
1064 | return $err; |
---|
1065 | } |
---|
1066 | |
---|
1067 | $data = array(); |
---|
1068 | } |
---|
1069 | // add parsing of newer formats here... |
---|
1070 | } else { |
---|
1071 | $err = $this->raiseError("$file: unknown version `$version'"); |
---|
1072 | return $err; |
---|
1073 | } |
---|
1074 | |
---|
1075 | return $data; |
---|
1076 | } |
---|
1077 | |
---|
1078 | /** |
---|
1079 | * Gets the file used for storing the config for a layer |
---|
1080 | * |
---|
1081 | * @param string $layer 'user' or 'system' |
---|
1082 | */ |
---|
1083 | function getConfFile($layer) |
---|
1084 | { |
---|
1085 | return $this->files[$layer]; |
---|
1086 | } |
---|
1087 | |
---|
1088 | /** |
---|
1089 | * @param string Configuration class name, used for detecting duplicate calls |
---|
1090 | * @param array information on a role as parsed from its xml file |
---|
1091 | * @return true|PEAR_Error |
---|
1092 | * @access private |
---|
1093 | */ |
---|
1094 | function _addConfigVars($class, $vars) |
---|
1095 | { |
---|
1096 | static $called = array(); |
---|
1097 | if (isset($called[$class])) { |
---|
1098 | return; |
---|
1099 | } |
---|
1100 | |
---|
1101 | $called[$class] = 1; |
---|
1102 | if (count($vars) > 3) { |
---|
1103 | return $this->raiseError('Roles can only define 3 new config variables or less'); |
---|
1104 | } |
---|
1105 | |
---|
1106 | foreach ($vars as $name => $var) { |
---|
1107 | if (!is_array($var)) { |
---|
1108 | return $this->raiseError('Configuration information must be an array'); |
---|
1109 | } |
---|
1110 | |
---|
1111 | if (!isset($var['type'])) { |
---|
1112 | return $this->raiseError('Configuration information must contain a type'); |
---|
1113 | } elseif (!in_array($var['type'], |
---|
1114 | array('string', 'mask', 'password', 'directory', 'file', 'set'))) { |
---|
1115 | return $this->raiseError( |
---|
1116 | 'Configuration type must be one of directory, file, string, ' . |
---|
1117 | 'mask, set, or password'); |
---|
1118 | } |
---|
1119 | if (!isset($var['default'])) { |
---|
1120 | return $this->raiseError( |
---|
1121 | 'Configuration information must contain a default value ("default" index)'); |
---|
1122 | } |
---|
1123 | |
---|
1124 | if (is_array($var['default'])) { |
---|
1125 | $real_default = ''; |
---|
1126 | foreach ($var['default'] as $config_var => $val) { |
---|
1127 | if (strpos($config_var, 'text') === 0) { |
---|
1128 | $real_default .= $val; |
---|
1129 | } elseif (strpos($config_var, 'constant') === 0) { |
---|
1130 | if (!defined($val)) { |
---|
1131 | return $this->raiseError( |
---|
1132 | 'Unknown constant "' . $val . '" requested in ' . |
---|
1133 | 'default value for configuration variable "' . |
---|
1134 | $name . '"'); |
---|
1135 | } |
---|
1136 | |
---|
1137 | $real_default .= constant($val); |
---|
1138 | } elseif (isset($this->configuration_info[$config_var])) { |
---|
1139 | $real_default .= |
---|
1140 | $this->configuration_info[$config_var]['default']; |
---|
1141 | } else { |
---|
1142 | return $this->raiseError( |
---|
1143 | 'Unknown request for "' . $config_var . '" value in ' . |
---|
1144 | 'default value for configuration variable "' . |
---|
1145 | $name . '"'); |
---|
1146 | } |
---|
1147 | } |
---|
1148 | $var['default'] = $real_default; |
---|
1149 | } |
---|
1150 | |
---|
1151 | if ($var['type'] == 'integer') { |
---|
1152 | $var['default'] = (integer) $var['default']; |
---|
1153 | } |
---|
1154 | |
---|
1155 | if (!isset($var['doc'])) { |
---|
1156 | return $this->raiseError( |
---|
1157 | 'Configuration information must contain a summary ("doc" index)'); |
---|
1158 | } |
---|
1159 | |
---|
1160 | if (!isset($var['prompt'])) { |
---|
1161 | return $this->raiseError( |
---|
1162 | 'Configuration information must contain a simple prompt ("prompt" index)'); |
---|
1163 | } |
---|
1164 | |
---|
1165 | if (!isset($var['group'])) { |
---|
1166 | return $this->raiseError( |
---|
1167 | 'Configuration information must contain a simple group ("group" index)'); |
---|
1168 | } |
---|
1169 | |
---|
1170 | if (isset($this->configuration_info[$name])) { |
---|
1171 | return $this->raiseError('Configuration variable "' . $name . |
---|
1172 | '" already exists'); |
---|
1173 | } |
---|
1174 | |
---|
1175 | $this->configuration_info[$name] = $var; |
---|
1176 | // fix bug #7351: setting custom config variable in a channel fails |
---|
1177 | $this->_channelConfigInfo[] = $name; |
---|
1178 | } |
---|
1179 | |
---|
1180 | return true; |
---|
1181 | } |
---|
1182 | |
---|
1183 | /** |
---|
1184 | * Encodes/scrambles configuration data before writing to files. |
---|
1185 | * Currently, 'password' values will be base64-encoded as to avoid |
---|
1186 | * that people spot cleartext passwords by accident. |
---|
1187 | * |
---|
1188 | * @param array (reference) array to encode values in |
---|
1189 | * @return bool TRUE on success |
---|
1190 | * @access private |
---|
1191 | */ |
---|
1192 | function _encodeOutput(&$data) |
---|
1193 | { |
---|
1194 | foreach ($data as $key => $value) { |
---|
1195 | if ($key == '__channels') { |
---|
1196 | foreach ($data['__channels'] as $channel => $blah) { |
---|
1197 | $this->_encodeOutput($data['__channels'][$channel]); |
---|
1198 | } |
---|
1199 | } |
---|
1200 | |
---|
1201 | if (!isset($this->configuration_info[$key])) { |
---|
1202 | continue; |
---|
1203 | } |
---|
1204 | |
---|
1205 | $type = $this->configuration_info[$key]['type']; |
---|
1206 | switch ($type) { |
---|
1207 | // we base64-encode passwords so they are at least |
---|
1208 | // not shown in plain by accident |
---|
1209 | case 'password': { |
---|
1210 | $data[$key] = base64_encode($data[$key]); |
---|
1211 | break; |
---|
1212 | } |
---|
1213 | case 'mask': { |
---|
1214 | $data[$key] = octdec($data[$key]); |
---|
1215 | break; |
---|
1216 | } |
---|
1217 | } |
---|
1218 | } |
---|
1219 | |
---|
1220 | return true; |
---|
1221 | } |
---|
1222 | |
---|
1223 | /** |
---|
1224 | * Decodes/unscrambles configuration data after reading from files. |
---|
1225 | * |
---|
1226 | * @param array (reference) array to encode values in |
---|
1227 | * @return bool TRUE on success |
---|
1228 | * @access private |
---|
1229 | * |
---|
1230 | * @see PEAR_Config::_encodeOutput |
---|
1231 | */ |
---|
1232 | function _decodeInput(&$data) |
---|
1233 | { |
---|
1234 | if (!is_array($data)) { |
---|
1235 | return true; |
---|
1236 | } |
---|
1237 | |
---|
1238 | foreach ($data as $key => $value) { |
---|
1239 | if ($key == '__channels') { |
---|
1240 | foreach ($data['__channels'] as $channel => $blah) { |
---|
1241 | $this->_decodeInput($data['__channels'][$channel]); |
---|
1242 | } |
---|
1243 | } |
---|
1244 | |
---|
1245 | if (!isset($this->configuration_info[$key])) { |
---|
1246 | continue; |
---|
1247 | } |
---|
1248 | |
---|
1249 | $type = $this->configuration_info[$key]['type']; |
---|
1250 | switch ($type) { |
---|
1251 | case 'password': { |
---|
1252 | $data[$key] = base64_decode($data[$key]); |
---|
1253 | break; |
---|
1254 | } |
---|
1255 | case 'mask': { |
---|
1256 | $data[$key] = decoct($data[$key]); |
---|
1257 | break; |
---|
1258 | } |
---|
1259 | } |
---|
1260 | } |
---|
1261 | |
---|
1262 | return true; |
---|
1263 | } |
---|
1264 | |
---|
1265 | /** |
---|
1266 | * Retrieve the default channel. |
---|
1267 | * |
---|
1268 | * On startup, channels are not initialized, so if the default channel is not |
---|
1269 | * pear.php.net, then initialize the config. |
---|
1270 | * @param string registry layer |
---|
1271 | * @return string|false |
---|
1272 | */ |
---|
1273 | function getDefaultChannel($layer = null) |
---|
1274 | { |
---|
1275 | $ret = false; |
---|
1276 | if ($layer === null) { |
---|
1277 | foreach ($this->layers as $layer) { |
---|
1278 | if (isset($this->configuration[$layer]['default_channel'])) { |
---|
1279 | $ret = $this->configuration[$layer]['default_channel']; |
---|
1280 | break; |
---|
1281 | } |
---|
1282 | } |
---|
1283 | } elseif (isset($this->configuration[$layer]['default_channel'])) { |
---|
1284 | $ret = $this->configuration[$layer]['default_channel']; |
---|
1285 | } |
---|
1286 | |
---|
1287 | if ($ret == 'pear.php.net' && defined('PEAR_RUNTYPE') && PEAR_RUNTYPE == 'pecl') { |
---|
1288 | $ret = 'pecl.php.net'; |
---|
1289 | } |
---|
1290 | |
---|
1291 | if ($ret) { |
---|
1292 | if ($ret != 'pear.php.net') { |
---|
1293 | $this->_lazyChannelSetup(); |
---|
1294 | } |
---|
1295 | |
---|
1296 | return $ret; |
---|
1297 | } |
---|
1298 | |
---|
1299 | return PEAR_CONFIG_DEFAULT_CHANNEL; |
---|
1300 | } |
---|
1301 | |
---|
1302 | /** |
---|
1303 | * Returns a configuration value, prioritizing layers as per the |
---|
1304 | * layers property. |
---|
1305 | * |
---|
1306 | * @param string config key |
---|
1307 | * @return mixed the config value, or NULL if not found |
---|
1308 | * @access public |
---|
1309 | */ |
---|
1310 | function get($key, $layer = null, $channel = false) |
---|
1311 | { |
---|
1312 | if (!isset($this->configuration_info[$key])) { |
---|
1313 | return null; |
---|
1314 | } |
---|
1315 | |
---|
1316 | if ($key == '__channels') { |
---|
1317 | return null; |
---|
1318 | } |
---|
1319 | |
---|
1320 | if ($key == 'default_channel') { |
---|
1321 | return $this->getDefaultChannel($layer); |
---|
1322 | } |
---|
1323 | |
---|
1324 | if (!$channel) { |
---|
1325 | $channel = $this->getDefaultChannel(); |
---|
1326 | } elseif ($channel != 'pear.php.net') { |
---|
1327 | $this->_lazyChannelSetup(); |
---|
1328 | } |
---|
1329 | $channel = strtolower($channel); |
---|
1330 | |
---|
1331 | $test = (in_array($key, $this->_channelConfigInfo)) ? |
---|
1332 | $this->_getChannelValue($key, $layer, $channel) : |
---|
1333 | null; |
---|
1334 | if ($test !== null) { |
---|
1335 | if ($this->_installRoot) { |
---|
1336 | if (in_array($this->getGroup($key), |
---|
1337 | array('File Locations', 'File Locations (Advanced)')) && |
---|
1338 | $this->getType($key) == 'directory') { |
---|
1339 | return $this->_prependPath($test, $this->_installRoot); |
---|
1340 | } |
---|
1341 | } |
---|
1342 | return $test; |
---|
1343 | } |
---|
1344 | |
---|
1345 | if ($layer === null) { |
---|
1346 | foreach ($this->layers as $layer) { |
---|
1347 | if (isset($this->configuration[$layer][$key])) { |
---|
1348 | $test = $this->configuration[$layer][$key]; |
---|
1349 | if ($this->_installRoot) { |
---|
1350 | if (in_array($this->getGroup($key), |
---|
1351 | array('File Locations', 'File Locations (Advanced)')) && |
---|
1352 | $this->getType($key) == 'directory') { |
---|
1353 | return $this->_prependPath($test, $this->_installRoot); |
---|
1354 | } |
---|
1355 | } |
---|
1356 | |
---|
1357 | if ($key == 'preferred_mirror') { |
---|
1358 | $reg = &$this->getRegistry(); |
---|
1359 | if (is_object($reg)) { |
---|
1360 | $chan = &$reg->getChannel($channel); |
---|
1361 | if (PEAR::isError($chan)) { |
---|
1362 | return $channel; |
---|
1363 | } |
---|
1364 | |
---|
1365 | if (!$chan->getMirror($test) && $chan->getName() != $test) { |
---|
1366 | return $channel; // mirror does not exist |
---|
1367 | } |
---|
1368 | } |
---|
1369 | } |
---|
1370 | return $test; |
---|
1371 | } |
---|
1372 | } |
---|
1373 | } elseif (isset($this->configuration[$layer][$key])) { |
---|
1374 | $test = $this->configuration[$layer][$key]; |
---|
1375 | if ($this->_installRoot) { |
---|
1376 | if (in_array($this->getGroup($key), |
---|
1377 | array('File Locations', 'File Locations (Advanced)')) && |
---|
1378 | $this->getType($key) == 'directory') { |
---|
1379 | return $this->_prependPath($test, $this->_installRoot); |
---|
1380 | } |
---|
1381 | } |
---|
1382 | |
---|
1383 | if ($key == 'preferred_mirror') { |
---|
1384 | $reg = &$this->getRegistry(); |
---|
1385 | if (is_object($reg)) { |
---|
1386 | $chan = &$reg->getChannel($channel); |
---|
1387 | if (PEAR::isError($chan)) { |
---|
1388 | return $channel; |
---|
1389 | } |
---|
1390 | |
---|
1391 | if (!$chan->getMirror($test) && $chan->getName() != $test) { |
---|
1392 | return $channel; // mirror does not exist |
---|
1393 | } |
---|
1394 | } |
---|
1395 | } |
---|
1396 | |
---|
1397 | return $test; |
---|
1398 | } |
---|
1399 | |
---|
1400 | return null; |
---|
1401 | } |
---|
1402 | |
---|
1403 | /** |
---|
1404 | * Returns a channel-specific configuration value, prioritizing layers as per the |
---|
1405 | * layers property. |
---|
1406 | * |
---|
1407 | * @param string config key |
---|
1408 | * @return mixed the config value, or NULL if not found |
---|
1409 | * @access private |
---|
1410 | */ |
---|
1411 | function _getChannelValue($key, $layer, $channel) |
---|
1412 | { |
---|
1413 | if ($key == '__channels' || $channel == 'pear.php.net') { |
---|
1414 | return null; |
---|
1415 | } |
---|
1416 | |
---|
1417 | $ret = null; |
---|
1418 | if ($layer === null) { |
---|
1419 | foreach ($this->layers as $ilayer) { |
---|
1420 | if (isset($this->configuration[$ilayer]['__channels'][$channel][$key])) { |
---|
1421 | $ret = $this->configuration[$ilayer]['__channels'][$channel][$key]; |
---|
1422 | break; |
---|
1423 | } |
---|
1424 | } |
---|
1425 | } elseif (isset($this->configuration[$layer]['__channels'][$channel][$key])) { |
---|
1426 | $ret = $this->configuration[$layer]['__channels'][$channel][$key]; |
---|
1427 | } |
---|
1428 | |
---|
1429 | if ($key != 'preferred_mirror') { |
---|
1430 | return $ret; |
---|
1431 | } |
---|
1432 | |
---|
1433 | |
---|
1434 | if ($ret !== null) { |
---|
1435 | $reg = &$this->getRegistry($layer); |
---|
1436 | if (is_object($reg)) { |
---|
1437 | $chan = &$reg->getChannel($channel); |
---|
1438 | if (PEAR::isError($chan)) { |
---|
1439 | return $channel; |
---|
1440 | } |
---|
1441 | |
---|
1442 | if (!$chan->getMirror($ret) && $chan->getName() != $ret) { |
---|
1443 | return $channel; // mirror does not exist |
---|
1444 | } |
---|
1445 | } |
---|
1446 | |
---|
1447 | return $ret; |
---|
1448 | } |
---|
1449 | |
---|
1450 | if ($channel != $this->getDefaultChannel($layer)) { |
---|
1451 | return $channel; // we must use the channel name as the preferred mirror |
---|
1452 | // if the user has not chosen an alternate |
---|
1453 | } |
---|
1454 | |
---|
1455 | return $this->getDefaultChannel($layer); |
---|
1456 | } |
---|
1457 | |
---|
1458 | /** |
---|
1459 | * Set a config value in a specific layer (defaults to 'user'). |
---|
1460 | * Enforces the types defined in the configuration_info array. An |
---|
1461 | * integer config variable will be cast to int, and a set config |
---|
1462 | * variable will be validated against its legal values. |
---|
1463 | * |
---|
1464 | * @param string config key |
---|
1465 | * @param string config value |
---|
1466 | * @param string (optional) config layer |
---|
1467 | * @param string channel to set this value for, or null for global value |
---|
1468 | * @return bool TRUE on success, FALSE on failure |
---|
1469 | */ |
---|
1470 | function set($key, $value, $layer = 'user', $channel = false) |
---|
1471 | { |
---|
1472 | if ($key == '__channels') { |
---|
1473 | return false; |
---|
1474 | } |
---|
1475 | |
---|
1476 | if (!isset($this->configuration[$layer])) { |
---|
1477 | return false; |
---|
1478 | } |
---|
1479 | |
---|
1480 | if ($key == 'default_channel') { |
---|
1481 | // can only set this value globally |
---|
1482 | $channel = 'pear.php.net'; |
---|
1483 | if ($value != 'pear.php.net') { |
---|
1484 | $this->_lazyChannelSetup($layer); |
---|
1485 | } |
---|
1486 | } |
---|
1487 | |
---|
1488 | if ($key == 'preferred_mirror') { |
---|
1489 | if ($channel == '__uri') { |
---|
1490 | return false; // can't set the __uri pseudo-channel's mirror |
---|
1491 | } |
---|
1492 | |
---|
1493 | $reg = &$this->getRegistry($layer); |
---|
1494 | if (is_object($reg)) { |
---|
1495 | $chan = &$reg->getChannel($channel ? $channel : 'pear.php.net'); |
---|
1496 | if (PEAR::isError($chan)) { |
---|
1497 | return false; |
---|
1498 | } |
---|
1499 | |
---|
1500 | if (!$chan->getMirror($value) && $chan->getName() != $value) { |
---|
1501 | return false; // mirror does not exist |
---|
1502 | } |
---|
1503 | } |
---|
1504 | } |
---|
1505 | |
---|
1506 | if (!isset($this->configuration_info[$key])) { |
---|
1507 | return false; |
---|
1508 | } |
---|
1509 | |
---|
1510 | extract($this->configuration_info[$key]); |
---|
1511 | switch ($type) { |
---|
1512 | case 'integer': |
---|
1513 | $value = (int)$value; |
---|
1514 | break; |
---|
1515 | case 'set': { |
---|
1516 | // If a valid_set is specified, require the value to |
---|
1517 | // be in the set. If there is no valid_set, accept |
---|
1518 | // any value. |
---|
1519 | if ($valid_set) { |
---|
1520 | reset($valid_set); |
---|
1521 | if ((key($valid_set) === 0 && !in_array($value, $valid_set)) || |
---|
1522 | (key($valid_set) !== 0 && empty($valid_set[$value]))) |
---|
1523 | { |
---|
1524 | return false; |
---|
1525 | } |
---|
1526 | } |
---|
1527 | break; |
---|
1528 | } |
---|
1529 | } |
---|
1530 | |
---|
1531 | if (!$channel) { |
---|
1532 | $channel = $this->get('default_channel', null, 'pear.php.net'); |
---|
1533 | } |
---|
1534 | |
---|
1535 | if (!in_array($channel, $this->_channels)) { |
---|
1536 | $this->_lazyChannelSetup($layer); |
---|
1537 | $reg = &$this->getRegistry($layer); |
---|
1538 | if ($reg) { |
---|
1539 | $channel = $reg->channelName($channel); |
---|
1540 | } |
---|
1541 | |
---|
1542 | if (!in_array($channel, $this->_channels)) { |
---|
1543 | return false; |
---|
1544 | } |
---|
1545 | } |
---|
1546 | |
---|
1547 | if ($channel != 'pear.php.net') { |
---|
1548 | if (in_array($key, $this->_channelConfigInfo)) { |
---|
1549 | $this->configuration[$layer]['__channels'][$channel][$key] = $value; |
---|
1550 | return true; |
---|
1551 | } |
---|
1552 | |
---|
1553 | return false; |
---|
1554 | } |
---|
1555 | |
---|
1556 | if ($key == 'default_channel') { |
---|
1557 | if (!isset($reg)) { |
---|
1558 | $reg = &$this->getRegistry($layer); |
---|
1559 | if (!$reg) { |
---|
1560 | $reg = &$this->getRegistry(); |
---|
1561 | } |
---|
1562 | } |
---|
1563 | |
---|
1564 | if ($reg) { |
---|
1565 | $value = $reg->channelName($value); |
---|
1566 | } |
---|
1567 | |
---|
1568 | if (!$value) { |
---|
1569 | return false; |
---|
1570 | } |
---|
1571 | } |
---|
1572 | |
---|
1573 | $this->configuration[$layer][$key] = $value; |
---|
1574 | if ($key == 'php_dir' && !$this->_noRegistry) { |
---|
1575 | if (!isset($this->_registry[$layer]) || |
---|
1576 | $value != $this->_registry[$layer]->install_dir) { |
---|
1577 | $this->_registry[$layer] = &new PEAR_Registry($value); |
---|
1578 | $this->_regInitialized[$layer] = false; |
---|
1579 | $this->_registry[$layer]->setConfig($this, false); |
---|
1580 | } |
---|
1581 | } |
---|
1582 | |
---|
1583 | return true; |
---|
1584 | } |
---|
1585 | |
---|
1586 | function _lazyChannelSetup($uselayer = false) |
---|
1587 | { |
---|
1588 | if ($this->_noRegistry) { |
---|
1589 | return; |
---|
1590 | } |
---|
1591 | |
---|
1592 | $merge = false; |
---|
1593 | foreach ($this->_registry as $layer => $p) { |
---|
1594 | if ($uselayer && $uselayer != $layer) { |
---|
1595 | continue; |
---|
1596 | } |
---|
1597 | |
---|
1598 | if (!$this->_regInitialized[$layer]) { |
---|
1599 | if ($layer == 'default' && isset($this->_registry['user']) || |
---|
1600 | isset($this->_registry['system'])) { |
---|
1601 | // only use the default registry if there are no alternatives |
---|
1602 | continue; |
---|
1603 | } |
---|
1604 | |
---|
1605 | if (!is_object($this->_registry[$layer])) { |
---|
1606 | if ($phpdir = $this->get('php_dir', $layer, 'pear.php.net')) { |
---|
1607 | $this->_registry[$layer] = &new PEAR_Registry($phpdir); |
---|
1608 | $this->_registry[$layer]->setConfig($this, false); |
---|
1609 | $this->_regInitialized[$layer] = false; |
---|
1610 | } else { |
---|
1611 | unset($this->_registry[$layer]); |
---|
1612 | return; |
---|
1613 | } |
---|
1614 | } |
---|
1615 | |
---|
1616 | $this->setChannels($this->_registry[$layer]->listChannels(), $merge); |
---|
1617 | $this->_regInitialized[$layer] = true; |
---|
1618 | $merge = true; |
---|
1619 | } |
---|
1620 | } |
---|
1621 | } |
---|
1622 | |
---|
1623 | /** |
---|
1624 | * Set the list of channels. |
---|
1625 | * |
---|
1626 | * This should be set via a call to {@link PEAR_Registry::listChannels()} |
---|
1627 | * @param array |
---|
1628 | * @param bool |
---|
1629 | * @return bool success of operation |
---|
1630 | */ |
---|
1631 | function setChannels($channels, $merge = false) |
---|
1632 | { |
---|
1633 | if (!is_array($channels)) { |
---|
1634 | return false; |
---|
1635 | } |
---|
1636 | |
---|
1637 | if ($merge) { |
---|
1638 | $this->_channels = array_merge($this->_channels, $channels); |
---|
1639 | } else { |
---|
1640 | $this->_channels = $channels; |
---|
1641 | } |
---|
1642 | |
---|
1643 | foreach ($channels as $channel) { |
---|
1644 | $channel = strtolower($channel); |
---|
1645 | if ($channel == 'pear.php.net') { |
---|
1646 | continue; |
---|
1647 | } |
---|
1648 | |
---|
1649 | foreach ($this->layers as $layer) { |
---|
1650 | if (!isset($this->configuration[$layer]['__channels'])) { |
---|
1651 | $this->configuration[$layer]['__channels'] = array(); |
---|
1652 | } |
---|
1653 | if (!isset($this->configuration[$layer]['__channels'][$channel]) |
---|
1654 | || !is_array($this->configuration[$layer]['__channels'][$channel])) { |
---|
1655 | $this->configuration[$layer]['__channels'][$channel] = array(); |
---|
1656 | } |
---|
1657 | } |
---|
1658 | } |
---|
1659 | |
---|
1660 | return true; |
---|
1661 | } |
---|
1662 | |
---|
1663 | /** |
---|
1664 | * Get the type of a config value. |
---|
1665 | * |
---|
1666 | * @param string config key |
---|
1667 | * |
---|
1668 | * @return string type, one of "string", "integer", "file", |
---|
1669 | * "directory", "set" or "password". |
---|
1670 | * |
---|
1671 | * @access public |
---|
1672 | * |
---|
1673 | */ |
---|
1674 | function getType($key) |
---|
1675 | { |
---|
1676 | if (isset($this->configuration_info[$key])) { |
---|
1677 | return $this->configuration_info[$key]['type']; |
---|
1678 | } |
---|
1679 | return false; |
---|
1680 | } |
---|
1681 | |
---|
1682 | /** |
---|
1683 | * Get the documentation for a config value. |
---|
1684 | * |
---|
1685 | * @param string config key |
---|
1686 | * @return string documentation string |
---|
1687 | * |
---|
1688 | * @access public |
---|
1689 | * |
---|
1690 | */ |
---|
1691 | function getDocs($key) |
---|
1692 | { |
---|
1693 | if (isset($this->configuration_info[$key])) { |
---|
1694 | return $this->configuration_info[$key]['doc']; |
---|
1695 | } |
---|
1696 | |
---|
1697 | return false; |
---|
1698 | } |
---|
1699 | |
---|
1700 | /** |
---|
1701 | * Get the short documentation for a config value. |
---|
1702 | * |
---|
1703 | * @param string config key |
---|
1704 | * @return string short documentation string |
---|
1705 | * |
---|
1706 | * @access public |
---|
1707 | * |
---|
1708 | */ |
---|
1709 | function getPrompt($key) |
---|
1710 | { |
---|
1711 | if (isset($this->configuration_info[$key])) { |
---|
1712 | return $this->configuration_info[$key]['prompt']; |
---|
1713 | } |
---|
1714 | |
---|
1715 | return false; |
---|
1716 | } |
---|
1717 | |
---|
1718 | /** |
---|
1719 | * Get the parameter group for a config key. |
---|
1720 | * |
---|
1721 | * @param string config key |
---|
1722 | * @return string parameter group |
---|
1723 | * |
---|
1724 | * @access public |
---|
1725 | * |
---|
1726 | */ |
---|
1727 | function getGroup($key) |
---|
1728 | { |
---|
1729 | if (isset($this->configuration_info[$key])) { |
---|
1730 | return $this->configuration_info[$key]['group']; |
---|
1731 | } |
---|
1732 | |
---|
1733 | return false; |
---|
1734 | } |
---|
1735 | |
---|
1736 | /** |
---|
1737 | * Get the list of parameter groups. |
---|
1738 | * |
---|
1739 | * @return array list of parameter groups |
---|
1740 | * |
---|
1741 | * @access public |
---|
1742 | * |
---|
1743 | */ |
---|
1744 | function getGroups() |
---|
1745 | { |
---|
1746 | $tmp = array(); |
---|
1747 | foreach ($this->configuration_info as $key => $info) { |
---|
1748 | $tmp[$info['group']] = 1; |
---|
1749 | } |
---|
1750 | |
---|
1751 | return array_keys($tmp); |
---|
1752 | } |
---|
1753 | |
---|
1754 | /** |
---|
1755 | * Get the list of the parameters in a group. |
---|
1756 | * |
---|
1757 | * @param string $group parameter group |
---|
1758 | * @return array list of parameters in $group |
---|
1759 | * |
---|
1760 | * @access public |
---|
1761 | * |
---|
1762 | */ |
---|
1763 | function getGroupKeys($group) |
---|
1764 | { |
---|
1765 | $keys = array(); |
---|
1766 | foreach ($this->configuration_info as $key => $info) { |
---|
1767 | if ($info['group'] == $group) { |
---|
1768 | $keys[] = $key; |
---|
1769 | } |
---|
1770 | } |
---|
1771 | |
---|
1772 | return $keys; |
---|
1773 | } |
---|
1774 | |
---|
1775 | /** |
---|
1776 | * Get the list of allowed set values for a config value. Returns |
---|
1777 | * NULL for config values that are not sets. |
---|
1778 | * |
---|
1779 | * @param string config key |
---|
1780 | * @return array enumerated array of set values, or NULL if the |
---|
1781 | * config key is unknown or not a set |
---|
1782 | * |
---|
1783 | * @access public |
---|
1784 | * |
---|
1785 | */ |
---|
1786 | function getSetValues($key) |
---|
1787 | { |
---|
1788 | if (isset($this->configuration_info[$key]) && |
---|
1789 | isset($this->configuration_info[$key]['type']) && |
---|
1790 | $this->configuration_info[$key]['type'] == 'set') |
---|
1791 | { |
---|
1792 | $valid_set = $this->configuration_info[$key]['valid_set']; |
---|
1793 | reset($valid_set); |
---|
1794 | if (key($valid_set) === 0) { |
---|
1795 | return $valid_set; |
---|
1796 | } |
---|
1797 | |
---|
1798 | return array_keys($valid_set); |
---|
1799 | } |
---|
1800 | |
---|
1801 | return null; |
---|
1802 | } |
---|
1803 | |
---|
1804 | /** |
---|
1805 | * Get all the current config keys. |
---|
1806 | * |
---|
1807 | * @return array simple array of config keys |
---|
1808 | * |
---|
1809 | * @access public |
---|
1810 | */ |
---|
1811 | function getKeys() |
---|
1812 | { |
---|
1813 | $keys = array(); |
---|
1814 | foreach ($this->layers as $layer) { |
---|
1815 | $test = $this->configuration[$layer]; |
---|
1816 | if (isset($test['__channels'])) { |
---|
1817 | foreach ($test['__channels'] as $channel => $configs) { |
---|
1818 | $keys = array_merge($keys, $configs); |
---|
1819 | } |
---|
1820 | } |
---|
1821 | |
---|
1822 | unset($test['__channels']); |
---|
1823 | $keys = array_merge($keys, $test); |
---|
1824 | |
---|
1825 | } |
---|
1826 | return array_keys($keys); |
---|
1827 | } |
---|
1828 | |
---|
1829 | /** |
---|
1830 | * Remove the a config key from a specific config layer. |
---|
1831 | * |
---|
1832 | * @param string config key |
---|
1833 | * @param string (optional) config layer |
---|
1834 | * @param string (optional) channel (defaults to default channel) |
---|
1835 | * @return bool TRUE on success, FALSE on failure |
---|
1836 | * |
---|
1837 | * @access public |
---|
1838 | */ |
---|
1839 | function remove($key, $layer = 'user', $channel = null) |
---|
1840 | { |
---|
1841 | if ($channel === null) { |
---|
1842 | $channel = $this->getDefaultChannel(); |
---|
1843 | } |
---|
1844 | |
---|
1845 | if ($channel !== 'pear.php.net') { |
---|
1846 | if (isset($this->configuration[$layer]['__channels'][$channel][$key])) { |
---|
1847 | unset($this->configuration[$layer]['__channels'][$channel][$key]); |
---|
1848 | return true; |
---|
1849 | } |
---|
1850 | } |
---|
1851 | |
---|
1852 | if (isset($this->configuration[$layer][$key])) { |
---|
1853 | unset($this->configuration[$layer][$key]); |
---|
1854 | return true; |
---|
1855 | } |
---|
1856 | |
---|
1857 | return false; |
---|
1858 | } |
---|
1859 | |
---|
1860 | /** |
---|
1861 | * Temporarily remove an entire config layer. USE WITH CARE! |
---|
1862 | * |
---|
1863 | * @param string config key |
---|
1864 | * @param string (optional) config layer |
---|
1865 | * @return bool TRUE on success, FALSE on failure |
---|
1866 | * |
---|
1867 | * @access public |
---|
1868 | */ |
---|
1869 | function removeLayer($layer) |
---|
1870 | { |
---|
1871 | if (isset($this->configuration[$layer])) { |
---|
1872 | $this->configuration[$layer] = array(); |
---|
1873 | return true; |
---|
1874 | } |
---|
1875 | |
---|
1876 | return false; |
---|
1877 | } |
---|
1878 | |
---|
1879 | /** |
---|
1880 | * Stores configuration data in a layer. |
---|
1881 | * |
---|
1882 | * @param string config layer to store |
---|
1883 | * @return bool TRUE on success, or PEAR error on failure |
---|
1884 | * |
---|
1885 | * @access public |
---|
1886 | */ |
---|
1887 | function store($layer = 'user', $data = null) |
---|
1888 | { |
---|
1889 | return $this->writeConfigFile(null, $layer, $data); |
---|
1890 | } |
---|
1891 | |
---|
1892 | /** |
---|
1893 | * Tells what config layer that gets to define a key. |
---|
1894 | * |
---|
1895 | * @param string config key |
---|
1896 | * @param boolean return the defining channel |
---|
1897 | * |
---|
1898 | * @return string|array the config layer, or an empty string if not found. |
---|
1899 | * |
---|
1900 | * if $returnchannel, the return is an array array('layer' => layername, |
---|
1901 | * 'channel' => channelname), or an empty string if not found |
---|
1902 | * |
---|
1903 | * @access public |
---|
1904 | */ |
---|
1905 | function definedBy($key, $returnchannel = false) |
---|
1906 | { |
---|
1907 | foreach ($this->layers as $layer) { |
---|
1908 | $channel = $this->getDefaultChannel(); |
---|
1909 | if ($channel !== 'pear.php.net') { |
---|
1910 | if (isset($this->configuration[$layer]['__channels'][$channel][$key])) { |
---|
1911 | if ($returnchannel) { |
---|
1912 | return array('layer' => $layer, 'channel' => $channel); |
---|
1913 | } |
---|
1914 | return $layer; |
---|
1915 | } |
---|
1916 | } |
---|
1917 | |
---|
1918 | if (isset($this->configuration[$layer][$key])) { |
---|
1919 | if ($returnchannel) { |
---|
1920 | return array('layer' => $layer, 'channel' => 'pear.php.net'); |
---|
1921 | } |
---|
1922 | return $layer; |
---|
1923 | } |
---|
1924 | } |
---|
1925 | |
---|
1926 | return ''; |
---|
1927 | } |
---|
1928 | |
---|
1929 | /** |
---|
1930 | * Tells whether a given key exists as a config value. |
---|
1931 | * |
---|
1932 | * @param string config key |
---|
1933 | * @return bool whether <config key> exists in this object |
---|
1934 | * |
---|
1935 | * @access public |
---|
1936 | */ |
---|
1937 | function isDefined($key) |
---|
1938 | { |
---|
1939 | foreach ($this->layers as $layer) { |
---|
1940 | if (isset($this->configuration[$layer][$key])) { |
---|
1941 | return true; |
---|
1942 | } |
---|
1943 | } |
---|
1944 | |
---|
1945 | return false; |
---|
1946 | } |
---|
1947 | |
---|
1948 | /** |
---|
1949 | * Tells whether a given config layer exists. |
---|
1950 | * |
---|
1951 | * @param string config layer |
---|
1952 | * @return bool whether <config layer> exists in this object |
---|
1953 | * |
---|
1954 | * @access public |
---|
1955 | */ |
---|
1956 | function isDefinedLayer($layer) |
---|
1957 | { |
---|
1958 | return isset($this->configuration[$layer]); |
---|
1959 | } |
---|
1960 | |
---|
1961 | /** |
---|
1962 | * Returns the layers defined (except the 'default' one) |
---|
1963 | * |
---|
1964 | * @return array of the defined layers |
---|
1965 | */ |
---|
1966 | function getLayers() |
---|
1967 | { |
---|
1968 | $cf = $this->configuration; |
---|
1969 | unset($cf['default']); |
---|
1970 | return array_keys($cf); |
---|
1971 | } |
---|
1972 | |
---|
1973 | function apiVersion() |
---|
1974 | { |
---|
1975 | return '1.1'; |
---|
1976 | } |
---|
1977 | |
---|
1978 | /** |
---|
1979 | * @return PEAR_Registry |
---|
1980 | */ |
---|
1981 | function &getRegistry($use = null) |
---|
1982 | { |
---|
1983 | $layer = $use === null ? 'user' : $use; |
---|
1984 | if (isset($this->_registry[$layer])) { |
---|
1985 | return $this->_registry[$layer]; |
---|
1986 | } elseif ($use === null && isset($this->_registry['system'])) { |
---|
1987 | return $this->_registry['system']; |
---|
1988 | } elseif ($use === null && isset($this->_registry['default'])) { |
---|
1989 | return $this->_registry['default']; |
---|
1990 | } elseif ($use) { |
---|
1991 | $a = false; |
---|
1992 | return $a; |
---|
1993 | } |
---|
1994 | |
---|
1995 | // only go here if null was passed in |
---|
1996 | echo "CRITICAL ERROR: Registry could not be initialized from any value"; |
---|
1997 | exit(1); |
---|
1998 | } |
---|
1999 | |
---|
2000 | /** |
---|
2001 | * This is to allow customization like the use of installroot |
---|
2002 | * @param PEAR_Registry |
---|
2003 | * @return bool |
---|
2004 | */ |
---|
2005 | function setRegistry(&$reg, $layer = 'user') |
---|
2006 | { |
---|
2007 | if ($this->_noRegistry) { |
---|
2008 | return false; |
---|
2009 | } |
---|
2010 | |
---|
2011 | if (!in_array($layer, array('user', 'system'))) { |
---|
2012 | return false; |
---|
2013 | } |
---|
2014 | |
---|
2015 | $this->_registry[$layer] = &$reg; |
---|
2016 | if (is_object($reg)) { |
---|
2017 | $this->_registry[$layer]->setConfig($this, false); |
---|
2018 | } |
---|
2019 | |
---|
2020 | return true; |
---|
2021 | } |
---|
2022 | |
---|
2023 | function noRegistry() |
---|
2024 | { |
---|
2025 | $this->_noRegistry = true; |
---|
2026 | } |
---|
2027 | |
---|
2028 | /** |
---|
2029 | * @return PEAR_REST |
---|
2030 | */ |
---|
2031 | function &getREST($version, $options = array()) |
---|
2032 | { |
---|
2033 | $version = str_replace('.', '', $version); |
---|
2034 | if (!class_exists($class = 'PEAR_REST_' . $version)) { |
---|
2035 | require_once 'PEAR/REST/' . $version . '.php'; |
---|
2036 | } |
---|
2037 | |
---|
2038 | $remote = &new $class($this, $options); |
---|
2039 | return $remote; |
---|
2040 | } |
---|
2041 | |
---|
2042 | /** |
---|
2043 | * The ftp server is set in {@link readFTPConfigFile()}. It exists only if a |
---|
2044 | * remote configuration file has been specified |
---|
2045 | * @return PEAR_FTP|false |
---|
2046 | */ |
---|
2047 | function &getFTP() |
---|
2048 | { |
---|
2049 | if (isset($this->_ftp)) { |
---|
2050 | return $this->_ftp; |
---|
2051 | } |
---|
2052 | |
---|
2053 | $a = false; |
---|
2054 | return $a; |
---|
2055 | } |
---|
2056 | |
---|
2057 | function _prependPath($path, $prepend) |
---|
2058 | { |
---|
2059 | if (strlen($prepend) > 0) { |
---|
2060 | if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) { |
---|
2061 | if (preg_match('/^[a-z]:/i', $prepend)) { |
---|
2062 | $prepend = substr($prepend, 2); |
---|
2063 | } elseif ($prepend{0} != '\\') { |
---|
2064 | $prepend = "\\$prepend"; |
---|
2065 | } |
---|
2066 | $path = substr($path, 0, 2) . $prepend . substr($path, 2); |
---|
2067 | } else { |
---|
2068 | $path = $prepend . $path; |
---|
2069 | } |
---|
2070 | } |
---|
2071 | return $path; |
---|
2072 | } |
---|
2073 | |
---|
2074 | /** |
---|
2075 | * @param string|false installation directory to prepend to all _dir variables, or false to |
---|
2076 | * disable |
---|
2077 | */ |
---|
2078 | function setInstallRoot($root) |
---|
2079 | { |
---|
2080 | if (substr($root, -1) == DIRECTORY_SEPARATOR) { |
---|
2081 | $root = substr($root, 0, -1); |
---|
2082 | } |
---|
2083 | $old = $this->_installRoot; |
---|
2084 | $this->_installRoot = $root; |
---|
2085 | if (($old != $root) && !$this->_noRegistry) { |
---|
2086 | foreach (array_keys($this->_registry) as $layer) { |
---|
2087 | if ($layer == 'ftp' || !isset($this->_registry[$layer])) { |
---|
2088 | continue; |
---|
2089 | } |
---|
2090 | $this->_registry[$layer] = |
---|
2091 | &new PEAR_Registry($this->get('php_dir', $layer, 'pear.php.net')); |
---|
2092 | $this->_registry[$layer]->setConfig($this, false); |
---|
2093 | $this->_regInitialized[$layer] = false; |
---|
2094 | } |
---|
2095 | } |
---|
2096 | } |
---|
2097 | } |
---|