3 * PEAR_Config, customized configuration handling for the PEAR Installer
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 * @link http://pear.php.net/package/PEAR
14 * @since File available since Release 0.1
18 * Required for error handling
20 require_once 'PEAR.php';
21 require_once 'PEAR/Registry.php';
22 require_once 'PEAR/Installer/Role.php';
23 require_once 'System.php';
26 * Last created PEAR_Config instance.
29 $GLOBALS['_PEAR_Config_instance'] = null;
30 if (!defined('PEAR_INSTALL_DIR') || !PEAR_INSTALL_DIR) {
31 $PEAR_INSTALL_DIR = PHP_LIBDIR . DIRECTORY_SEPARATOR . 'pear';
33 $PEAR_INSTALL_DIR = PEAR_INSTALL_DIR;
36 // Below we define constants with default values for all configuration
37 // parameters except username/password. All of them can have their
38 // defaults set through environment variables. The reason we use the
39 // PHP_ prefix is for some security, PHP protects environment
40 // variables starting with PHP_*.
42 // default channel and preferred mirror is based on whether we are invoked through
43 // the "pear" or the "pecl" command
44 if (!defined('PEAR_RUNTYPE')) {
45 define('PEAR_RUNTYPE', 'pear');
48 if (PEAR_RUNTYPE == 'pear') {
49 define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pear.php.net');
51 define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pecl.php.net');
54 if (getenv('PHP_PEAR_SYSCONF_DIR')) {
55 define('PEAR_CONFIG_SYSCONFDIR', getenv('PHP_PEAR_SYSCONF_DIR'));
56 } elseif (getenv('SystemRoot')) {
57 define('PEAR_CONFIG_SYSCONFDIR', getenv('SystemRoot'));
59 define('PEAR_CONFIG_SYSCONFDIR', PHP_SYSCONFDIR);
62 // Default for master_server
63 if (getenv('PHP_PEAR_MASTER_SERVER')) {
64 define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', getenv('PHP_PEAR_MASTER_SERVER'));
66 define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', 'pear.php.net');
69 // Default for http_proxy
70 if (getenv('PHP_PEAR_HTTP_PROXY')) {
71 define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('PHP_PEAR_HTTP_PROXY'));
72 } elseif (getenv('http_proxy')) {
73 define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('http_proxy'));
75 define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', '');
78 // Default for php_dir
79 if (getenv('PHP_PEAR_INSTALL_DIR')) {
80 define('PEAR_CONFIG_DEFAULT_PHP_DIR', getenv('PHP_PEAR_INSTALL_DIR'));
82 if (@file_exists($PEAR_INSTALL_DIR) && is_dir($PEAR_INSTALL_DIR)) {
83 define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR);
85 define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR);
89 // Default for metadata_dir
90 if (getenv('PHP_PEAR_METADATA_DIR')) {
91 define('PEAR_CONFIG_DEFAULT_METADATA_DIR', getenv('PHP_PEAR_METADATA_DIR'));
93 define('PEAR_CONFIG_DEFAULT_METADATA_DIR', '');
96 // Default for ext_dir
97 if (getenv('PHP_PEAR_EXTENSION_DIR')) {
98 define('PEAR_CONFIG_DEFAULT_EXT_DIR', getenv('PHP_PEAR_EXTENSION_DIR'));
100 if (ini_get('extension_dir')) {
101 define('PEAR_CONFIG_DEFAULT_EXT_DIR', ini_get('extension_dir'));
102 } elseif (defined('PEAR_EXTENSION_DIR') &&
103 file_exists(PEAR_EXTENSION_DIR) && is_dir(PEAR_EXTENSION_DIR)) {
104 define('PEAR_CONFIG_DEFAULT_EXT_DIR', PEAR_EXTENSION_DIR);
105 } elseif (defined('PHP_EXTENSION_DIR')) {
106 define('PEAR_CONFIG_DEFAULT_EXT_DIR', PHP_EXTENSION_DIR);
108 define('PEAR_CONFIG_DEFAULT_EXT_DIR', '.');
112 // Default for doc_dir
113 if (getenv('PHP_PEAR_DOC_DIR')) {
114 define('PEAR_CONFIG_DEFAULT_DOC_DIR', getenv('PHP_PEAR_DOC_DIR'));
116 define('PEAR_CONFIG_DEFAULT_DOC_DIR',
117 $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'docs');
120 // Default for bin_dir
121 if (getenv('PHP_PEAR_BIN_DIR')) {
122 define('PEAR_CONFIG_DEFAULT_BIN_DIR', getenv('PHP_PEAR_BIN_DIR'));
124 define('PEAR_CONFIG_DEFAULT_BIN_DIR', PHP_BINDIR);
127 // Default for data_dir
128 if (getenv('PHP_PEAR_DATA_DIR')) {
129 define('PEAR_CONFIG_DEFAULT_DATA_DIR', getenv('PHP_PEAR_DATA_DIR'));
131 define('PEAR_CONFIG_DEFAULT_DATA_DIR',
132 $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'data');
135 // Default for cfg_dir
136 if (getenv('PHP_PEAR_CFG_DIR')) {
137 define('PEAR_CONFIG_DEFAULT_CFG_DIR', getenv('PHP_PEAR_CFG_DIR'));
139 define('PEAR_CONFIG_DEFAULT_CFG_DIR',
140 $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'cfg');
143 // Default for www_dir
144 if (getenv('PHP_PEAR_WWW_DIR')) {
145 define('PEAR_CONFIG_DEFAULT_WWW_DIR', getenv('PHP_PEAR_WWW_DIR'));
147 define('PEAR_CONFIG_DEFAULT_WWW_DIR',
148 $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'www');
151 // Default for man_dir
152 if (getenv('PHP_PEAR_MAN_DIR')) {
153 define('PEAR_CONFIG_DEFAULT_MAN_DIR', getenv('PHP_PEAR_MAN_DIR'));
155 if (defined('PHP_MANDIR')) { // Added in PHP5.3.7
156 define('PEAR_CONFIG_DEFAULT_MAN_DIR', PHP_MANDIR);
158 define('PEAR_CONFIG_DEFAULT_MAN_DIR', PHP_PREFIX . DIRECTORY_SEPARATOR .
159 'local' . DIRECTORY_SEPARATOR .'man');
163 // Default for test_dir
164 if (getenv('PHP_PEAR_TEST_DIR')) {
165 define('PEAR_CONFIG_DEFAULT_TEST_DIR', getenv('PHP_PEAR_TEST_DIR'));
167 define('PEAR_CONFIG_DEFAULT_TEST_DIR',
168 $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'tests');
171 // Default for temp_dir
172 if (getenv('PHP_PEAR_TEMP_DIR')) {
173 define('PEAR_CONFIG_DEFAULT_TEMP_DIR', getenv('PHP_PEAR_TEMP_DIR'));
175 define('PEAR_CONFIG_DEFAULT_TEMP_DIR',
176 System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' .
177 DIRECTORY_SEPARATOR . 'temp');
180 // Default for cache_dir
181 if (getenv('PHP_PEAR_CACHE_DIR')) {
182 define('PEAR_CONFIG_DEFAULT_CACHE_DIR', getenv('PHP_PEAR_CACHE_DIR'));
184 define('PEAR_CONFIG_DEFAULT_CACHE_DIR',
185 System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' .
186 DIRECTORY_SEPARATOR . 'cache');
189 // Default for download_dir
190 if (getenv('PHP_PEAR_DOWNLOAD_DIR')) {
191 define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR', getenv('PHP_PEAR_DOWNLOAD_DIR'));
193 define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR',
194 System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' .
195 DIRECTORY_SEPARATOR . 'download');
198 // Default for php_bin
199 if (getenv('PHP_PEAR_PHP_BIN')) {
200 define('PEAR_CONFIG_DEFAULT_PHP_BIN', getenv('PHP_PEAR_PHP_BIN'));
202 define('PEAR_CONFIG_DEFAULT_PHP_BIN', PEAR_CONFIG_DEFAULT_BIN_DIR.
203 DIRECTORY_SEPARATOR.'php'.(OS_WINDOWS ? '.exe' : ''));
206 // Default for verbose
207 if (getenv('PHP_PEAR_VERBOSE')) {
208 define('PEAR_CONFIG_DEFAULT_VERBOSE', getenv('PHP_PEAR_VERBOSE'));
210 define('PEAR_CONFIG_DEFAULT_VERBOSE', 1);
213 // Default for preferred_state
214 if (getenv('PHP_PEAR_PREFERRED_STATE')) {
215 define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', getenv('PHP_PEAR_PREFERRED_STATE'));
217 define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', 'stable');
221 if (getenv('PHP_PEAR_UMASK')) {
222 define('PEAR_CONFIG_DEFAULT_UMASK', getenv('PHP_PEAR_UMASK'));
224 define('PEAR_CONFIG_DEFAULT_UMASK', decoct(umask()));
227 // Default for cache_ttl
228 if (getenv('PHP_PEAR_CACHE_TTL')) {
229 define('PEAR_CONFIG_DEFAULT_CACHE_TTL', getenv('PHP_PEAR_CACHE_TTL'));
231 define('PEAR_CONFIG_DEFAULT_CACHE_TTL', 3600);
234 // Default for sig_type
235 if (getenv('PHP_PEAR_SIG_TYPE')) {
236 define('PEAR_CONFIG_DEFAULT_SIG_TYPE', getenv('PHP_PEAR_SIG_TYPE'));
238 define('PEAR_CONFIG_DEFAULT_SIG_TYPE', 'gpg');
241 // Default for sig_bin
242 if (getenv('PHP_PEAR_SIG_BIN')) {
243 define('PEAR_CONFIG_DEFAULT_SIG_BIN', getenv('PHP_PEAR_SIG_BIN'));
245 define('PEAR_CONFIG_DEFAULT_SIG_BIN',
247 'gpg', OS_WINDOWS ? 'c:\gnupg\gpg.exe' : '/usr/local/bin/gpg'));
250 // Default for sig_keydir
251 if (getenv('PHP_PEAR_SIG_KEYDIR')) {
252 define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR', getenv('PHP_PEAR_SIG_KEYDIR'));
254 define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR',
255 PEAR_CONFIG_SYSCONFDIR . DIRECTORY_SEPARATOR . 'pearkeys');
259 * This is a class for storing configuration data, keeping track of
260 * which are system-defined, user-defined or defaulted.
263 * @author Stig Bakken <ssb@php.net>
264 * @author Greg Beaver <cellog@php.net>
265 * @copyright 1997-2009 The Authors
266 * @license http://opensource.org/licenses/bsd-license.php New BSD License
267 * @version Release: 1.10.1
268 * @link http://pear.php.net/package/PEAR
269 * @since Class available since Release 0.1
271 class PEAR_Config extends PEAR
274 * Array of config files used.
276 * @var array layer => config file
283 var $layers = array();
286 * Configuration data, two-dimensional array where the first
287 * dimension is the config layer ('user', 'system' and 'default'),
288 * and the second dimension is keyname => value.
290 * The order in the first dimension is important! Earlier
291 * layers will shadow later ones when a config value is
292 * requested (if a 'user' value exists, it will be returned first,
293 * then 'system' and finally 'default').
295 * @var array layer => array(keyname => value, ...)
297 var $configuration = array(
300 'default' => array(),
304 * Configuration values that can be set for a channel
306 * All other configuration values can only have a global value
310 var $_channelConfigInfo = array(
311 'php_dir', 'ext_dir', 'doc_dir', 'bin_dir', 'data_dir', 'cfg_dir',
312 'test_dir', 'www_dir', 'php_bin', 'php_prefix', 'php_suffix', 'username',
313 'password', 'verbose', 'preferred_state', 'umask', 'preferred_mirror', 'php_ini'
317 * Channels that can be accessed
322 var $_channels = array('pear.php.net', 'pecl.php.net', '__uri');
325 * This variable is used to control the directory values returned
326 * @see setInstallRoot();
330 var $_installRoot = false;
333 * If requested, this will always refer to the registry
334 * contained in php_dir
337 var $_registry = array();
343 var $_regInitialized = array();
349 var $_noRegistry = false;
352 * amount of errors found while parsing config
356 var $_errorsFound = 0;
357 var $_lastError = null;
360 * Information about the configuration data. Stores the type,
361 * default value and a documentation string for each configuration
364 * @var array layer => array(infotype => value, ...)
366 var $configuration_info = array(
367 // Channels/Internet Access
368 'default_channel' => array(
370 'default' => PEAR_CONFIG_DEFAULT_CHANNEL,
371 'doc' => 'the default channel to use for all non explicit commands',
372 'prompt' => 'Default Channel',
373 'group' => 'Internet Access',
375 'preferred_mirror' => array(
377 'default' => PEAR_CONFIG_DEFAULT_CHANNEL,
378 'doc' => 'the default server or mirror to use for channel actions',
379 'prompt' => 'Default Channel Mirror',
380 'group' => 'Internet Access',
382 'remote_config' => array(
383 'type' => 'password',
385 'doc' => 'ftp url of remote configuration file to use for synchronized install',
386 'prompt' => 'Remote Configuration File',
387 'group' => 'Internet Access',
389 'auto_discover' => array(
392 'doc' => 'whether to automatically discover new channels',
393 'prompt' => 'Auto-discover new Channels',
394 'group' => 'Internet Access',
397 'master_server' => array(
399 'default' => 'pear.php.net',
400 'doc' => 'name of the main PEAR server [NOT USED IN THIS VERSION]',
401 'prompt' => 'PEAR server [DEPRECATED]',
402 'group' => 'Internet Access',
404 'http_proxy' => array(
406 'default' => PEAR_CONFIG_DEFAULT_HTTP_PROXY,
407 'doc' => 'HTTP proxy (host:port) to use when downloading packages',
408 'prompt' => 'HTTP Proxy Server Address',
409 'group' => 'Internet Access',
413 'type' => 'directory',
414 'default' => PEAR_CONFIG_DEFAULT_PHP_DIR,
415 'doc' => 'directory where .php files are installed',
416 'prompt' => 'PEAR directory',
417 'group' => 'File Locations',
420 'type' => 'directory',
421 'default' => PEAR_CONFIG_DEFAULT_EXT_DIR,
422 'doc' => 'directory where loadable extensions are installed',
423 'prompt' => 'PHP extension directory',
424 'group' => 'File Locations',
427 'type' => 'directory',
428 'default' => PEAR_CONFIG_DEFAULT_DOC_DIR,
429 'doc' => 'directory where documentation is installed',
430 'prompt' => 'PEAR documentation directory',
431 'group' => 'File Locations',
434 'type' => 'directory',
435 'default' => PEAR_CONFIG_DEFAULT_BIN_DIR,
436 'doc' => 'directory where executables are installed',
437 'prompt' => 'PEAR executables directory',
438 'group' => 'File Locations',
441 'type' => 'directory',
442 'default' => PEAR_CONFIG_DEFAULT_DATA_DIR,
443 'doc' => 'directory where data files are installed',
444 'prompt' => 'PEAR data directory',
445 'group' => 'File Locations (Advanced)',
448 'type' => 'directory',
449 'default' => PEAR_CONFIG_DEFAULT_CFG_DIR,
450 'doc' => 'directory where modifiable configuration files are installed',
451 'prompt' => 'PEAR configuration file directory',
452 'group' => 'File Locations (Advanced)',
455 'type' => 'directory',
456 'default' => PEAR_CONFIG_DEFAULT_WWW_DIR,
457 'doc' => 'directory where www frontend files (html/js) are installed',
458 'prompt' => 'PEAR www files directory',
459 'group' => 'File Locations (Advanced)',
462 'type' => 'directory',
463 'default' => PEAR_CONFIG_DEFAULT_MAN_DIR,
464 'doc' => 'directory where unix manual pages are installed',
465 'prompt' => 'Systems manpage files directory',
466 'group' => 'File Locations (Advanced)',
469 'type' => 'directory',
470 'default' => PEAR_CONFIG_DEFAULT_TEST_DIR,
471 'doc' => 'directory where regression tests are installed',
472 'prompt' => 'PEAR test directory',
473 'group' => 'File Locations (Advanced)',
475 'cache_dir' => array(
476 'type' => 'directory',
477 'default' => PEAR_CONFIG_DEFAULT_CACHE_DIR,
478 'doc' => 'directory which is used for web service cache',
479 'prompt' => 'PEAR Installer cache directory',
480 'group' => 'File Locations (Advanced)',
483 'type' => 'directory',
484 'default' => PEAR_CONFIG_DEFAULT_TEMP_DIR,
485 'doc' => 'directory which is used for all temp files',
486 'prompt' => 'PEAR Installer temp directory',
487 'group' => 'File Locations (Advanced)',
489 'download_dir' => array(
490 'type' => 'directory',
491 'default' => PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR,
492 'doc' => 'directory which is used for all downloaded files',
493 'prompt' => 'PEAR Installer download directory',
494 'group' => 'File Locations (Advanced)',
498 'default' => PEAR_CONFIG_DEFAULT_PHP_BIN,
499 'doc' => 'PHP CLI/CGI binary for executing scripts',
500 'prompt' => 'PHP CLI/CGI binary',
501 'group' => 'File Locations (Advanced)',
503 'php_prefix' => array(
506 'doc' => '--program-prefix for php_bin\'s ./configure, used for pecl installs',
507 'prompt' => '--program-prefix passed to PHP\'s ./configure',
508 'group' => 'File Locations (Advanced)',
510 'php_suffix' => array(
513 'doc' => '--program-suffix for php_bin\'s ./configure, used for pecl installs',
514 'prompt' => '--program-suffix passed to PHP\'s ./configure',
515 'group' => 'File Locations (Advanced)',
520 'doc' => 'location of php.ini in which to enable PECL extensions on install',
521 'prompt' => 'php.ini location',
522 'group' => 'File Locations (Advanced)',
524 'metadata_dir' => array(
525 'type' => 'directory',
526 'default' => PEAR_CONFIG_DEFAULT_METADATA_DIR,
527 'doc' => 'directory where metadata files are installed (registry, filemap, channels, ...)',
528 'prompt' => 'PEAR metadata directory',
529 'group' => 'File Locations (Advanced)',
535 'doc' => '(maintainers) your PEAR account name',
536 'prompt' => 'PEAR username (for maintainers)',
537 'group' => 'Maintainers',
540 'type' => 'password',
542 'doc' => '(maintainers) your PEAR account password',
543 'prompt' => 'PEAR password (for maintainers)',
544 'group' => 'Maintainers',
549 'default' => PEAR_CONFIG_DEFAULT_VERBOSE,
550 'doc' => 'verbosity level
555 'prompt' => 'Debug Log Level',
556 'group' => 'Advanced',
558 'preferred_state' => array(
560 'default' => PEAR_CONFIG_DEFAULT_PREFERRED_STATE,
561 'doc' => 'the installer will prefer releases with this state when installing packages without a version or state specified',
562 'valid_set' => array(
563 'stable', 'beta', 'alpha', 'devel', 'snapshot'),
564 'prompt' => 'Preferred Package State',
565 'group' => 'Advanced',
569 'default' => PEAR_CONFIG_DEFAULT_UMASK,
570 'doc' => 'umask used when creating files (Unix-like systems only)',
571 'prompt' => 'Unix file mask',
572 'group' => 'Advanced',
574 'cache_ttl' => array(
576 'default' => PEAR_CONFIG_DEFAULT_CACHE_TTL,
577 'doc' => 'amount of secs where the local cache is used and not updated',
578 'prompt' => 'Cache TimeToLive',
579 'group' => 'Advanced',
583 'default' => PEAR_CONFIG_DEFAULT_SIG_TYPE,
584 'doc' => 'which package signature mechanism to use',
585 'valid_set' => array('gpg'),
586 'prompt' => 'Package Signature Type',
587 'group' => 'Maintainers',
591 'default' => PEAR_CONFIG_DEFAULT_SIG_BIN,
592 'doc' => 'which package signature mechanism to use',
593 'prompt' => 'Signature Handling Program',
594 'group' => 'Maintainers',
596 'sig_keyid' => array(
599 'doc' => 'which key to use for signing with',
600 'prompt' => 'Signature Key Id',
601 'group' => 'Maintainers',
603 'sig_keydir' => array(
604 'type' => 'directory',
605 'default' => PEAR_CONFIG_DEFAULT_SIG_KEYDIR,
606 'doc' => 'directory where signature keys are located',
607 'prompt' => 'Signature Key Directory',
608 'group' => 'Maintainers',
610 // __channels is reserved - used for channel-specific configuration
616 * @param string file to read user-defined options from
617 * @param string file to read system-wide defaults from
618 * @param bool determines whether a registry object "follows"
619 * the value of php_dir (is automatically created
620 * and moved when php_dir is changed)
621 * @param bool if true, fails if configuration files cannot be loaded
625 * @see PEAR_Config::singleton
627 function __construct($user_file = '', $system_file = '', $ftp_file = false,
630 parent::__construct();
631 PEAR_Installer_Role::initializeConfig($this);
632 $sl = DIRECTORY_SEPARATOR;
633 if (empty($user_file)) {
635 $user_file = PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini';
637 $user_file = getenv('HOME') . $sl . '.pearrc';
641 if (empty($system_file)) {
642 $system_file = PEAR_CONFIG_SYSCONFDIR . $sl;
644 $system_file .= 'pearsys.ini';
646 $system_file .= 'pear.conf';
650 $this->layers = array_keys($this->configuration);
651 $this->files['user'] = $user_file;
652 $this->files['system'] = $system_file;
653 if ($user_file && file_exists($user_file)) {
654 $this->pushErrorHandling(PEAR_ERROR_RETURN);
655 $this->readConfigFile($user_file, 'user', $strict);
656 $this->popErrorHandling();
657 if ($this->_errorsFound > 0) {
662 if ($system_file && @file_exists($system_file)) {
663 $this->mergeConfigFile($system_file, false, 'system', $strict);
664 if ($this->_errorsFound > 0) {
671 $ftp_file = $this->get('remote_config');
674 if ($ftp_file && defined('PEAR_REMOTEINSTALL_OK')) {
675 $this->readFTPConfigFile($ftp_file);
678 foreach ($this->configuration_info as $key => $info) {
679 $this->configuration['default'][$key] = $info['default'];
682 $this->_registry['default'] = new PEAR_Registry(
683 $this->configuration['default']['php_dir'], false, false,
684 $this->configuration['default']['metadata_dir']);
685 $this->_registry['default']->setConfig($this, false);
686 $this->_regInitialized['default'] = false;
687 //$GLOBALS['_PEAR_Config_instance'] = &$this;
691 * Return the default locations of user and system configuration files
693 public static function getDefaultConfigFiles()
695 $sl = DIRECTORY_SEPARATOR;
698 'user' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini',
699 'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pearsys.ini'
704 'user' => getenv('HOME') . $sl . '.pearrc',
705 'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.conf'
710 * Static singleton method. If you want to keep only one instance
711 * of this class in use, this method will give you a reference to
712 * the last created PEAR_Config object if one exists, or create a
715 * @param string (optional) file to read user-defined options from
716 * @param string (optional) file to read system-wide defaults from
718 * @return object an existing or new PEAR_Config instance
720 * @see PEAR_Config::PEAR_Config
722 public static function &singleton($user_file = '', $system_file = '', $strict = true)
724 if (is_object($GLOBALS['_PEAR_Config_instance'])) {
725 return $GLOBALS['_PEAR_Config_instance'];
728 $t_conf = new PEAR_Config($user_file, $system_file, false, $strict);
729 if ($t_conf->_errorsFound > 0) {
730 return $t_conf->lastError;
733 $GLOBALS['_PEAR_Config_instance'] = &$t_conf;
734 return $GLOBALS['_PEAR_Config_instance'];
738 * Determine whether any configuration files have been detected, and whether a
739 * registry object can be retrieved from this configuration.
741 * @since PEAR 1.4.0a1
743 function validConfiguration()
745 if ($this->isDefinedLayer('user') || $this->isDefinedLayer('system')) {
753 * Reads configuration data from a file. All existing values in
754 * the config layer are discarded and replaced with data from the
756 * @param string file to read from, if NULL or not specified, the
757 * last-used file for the same layer (second param) is used
758 * @param string config layer to insert data into ('user' or 'system')
759 * @return bool TRUE on success or a PEAR error on failure
761 function readConfigFile($file = null, $layer = 'user', $strict = true)
763 if (empty($this->files[$layer])) {
764 return $this->raiseError("unknown config layer `$layer'");
767 if ($file === null) {
768 $file = $this->files[$layer];
771 $data = $this->_readConfigDataFrom($file);
772 if (PEAR::isError($data)) {
777 $this->_errorsFound++;
778 $this->lastError = $data;
783 $this->files[$layer] = $file;
784 $this->_decodeInput($data);
785 $this->configuration[$layer] = $data;
786 $this->_setupChannels();
787 if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) {
788 $this->_registry[$layer] = new PEAR_Registry(
789 $phpdir, false, false,
790 $this->get('metadata_dir', $layer, 'pear.php.net'));
791 $this->_registry[$layer]->setConfig($this, false);
792 $this->_regInitialized[$layer] = false;
794 unset($this->_registry[$layer]);
800 * @param string url to the remote config file, like ftp://www.example.com/pear/config.ini
801 * @return true|PEAR_Error
803 function readFTPConfigFile($path)
805 do { // poor man's try
806 if (!class_exists('PEAR_FTP')) {
807 if (!class_exists('PEAR_Common')) {
808 require_once 'PEAR/Common.php';
810 if (PEAR_Common::isIncludeable('PEAR/FTP.php')) {
811 require_once 'PEAR/FTP.php';
815 if (!class_exists('PEAR_FTP')) {
816 return PEAR::raiseError('PEAR_RemoteInstaller must be installed to use remote config');
819 $this->_ftp = new PEAR_FTP;
820 $this->_ftp->pushErrorHandling(PEAR_ERROR_RETURN);
821 $e = $this->_ftp->init($path);
822 if (PEAR::isError($e)) {
823 $this->_ftp->popErrorHandling();
827 $tmp = System::mktemp('-d');
828 PEAR_Common::addTempFile($tmp);
829 $e = $this->_ftp->get(basename($path), $tmp . DIRECTORY_SEPARATOR .
830 'pear.ini', false, FTP_BINARY);
831 if (PEAR::isError($e)) {
832 $this->_ftp->popErrorHandling();
836 PEAR_Common::addTempFile($tmp . DIRECTORY_SEPARATOR . 'pear.ini');
837 $this->_ftp->disconnect();
838 $this->_ftp->popErrorHandling();
839 $this->files['ftp'] = $tmp . DIRECTORY_SEPARATOR . 'pear.ini';
840 $e = $this->readConfigFile(null, 'ftp');
841 if (PEAR::isError($e)) {
846 foreach ($this->configuration_info as $key => $val) {
847 if (in_array($this->getGroup($key),
848 array('File Locations', 'File Locations (Advanced)')) &&
849 $this->getType($key) == 'directory') {
850 // any directory configs must be set for this to work
851 if (!isset($this->configuration['ftp'][$key])) {
861 $fail = '"' . implode('", "', $fail) . '"';
862 unset($this->files['ftp']);
863 unset($this->configuration['ftp']);
864 return PEAR::raiseError('ERROR: Ftp configuration file must set all ' .
865 'directory configuration variables. These variables were not set: ' .
867 } while (false); // poor man's catch
868 unset($this->files['ftp']);
869 return PEAR::raiseError('no remote host specified');
873 * Reads the existing configurations and creates the _channels array from it
875 function _setupChannels()
877 $set = array_flip(array_values($this->_channels));
878 foreach ($this->configuration as $layer => $data) {
880 if (isset($data['__channels']) && is_array($data['__channels'])) {
881 foreach ($data['__channels'] as $channel => $info) {
882 $set[$channel] = $i++;
886 $this->_channels = array_values(array_flip($set));
887 $this->setChannels($this->_channels);
890 function deleteChannel($channel)
892 $ch = strtolower($channel);
893 foreach ($this->configuration as $layer => $data) {
894 if (isset($data['__channels']) && isset($data['__channels'][$ch])) {
895 unset($this->configuration[$layer]['__channels'][$ch]);
899 $this->_channels = array_flip($this->_channels);
900 unset($this->_channels[$ch]);
901 $this->_channels = array_flip($this->_channels);
905 * Merges data into a config layer from a file. Does the same
906 * thing as readConfigFile, except it does not replace all
907 * existing values in the config layer.
908 * @param string file to read from
909 * @param bool whether to overwrite existing data (default TRUE)
910 * @param string config layer to insert data into ('user' or 'system')
911 * @param string if true, errors are returned if file opening fails
912 * @return bool TRUE on success or a PEAR error on failure
914 function mergeConfigFile($file, $override = true, $layer = 'user', $strict = true)
916 if (empty($this->files[$layer])) {
917 return $this->raiseError("unknown config layer `$layer'");
920 if ($file === null) {
921 $file = $this->files[$layer];
924 $data = $this->_readConfigDataFrom($file);
925 if (PEAR::isError($data)) {
930 $this->_errorsFound++;
931 $this->lastError = $data;
936 $this->_decodeInput($data);
938 $this->configuration[$layer] =
939 PEAR_Config::arrayMergeRecursive($this->configuration[$layer], $data);
941 $this->configuration[$layer] =
942 PEAR_Config::arrayMergeRecursive($data, $this->configuration[$layer]);
945 $this->_setupChannels();
946 if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) {
947 $this->_registry[$layer] = new PEAR_Registry(
948 $phpdir, false, false,
949 $this->get('metadata_dir', $layer, 'pear.php.net'));
950 $this->_registry[$layer]->setConfig($this, false);
951 $this->_regInitialized[$layer] = false;
953 unset($this->_registry[$layer]);
963 public static function arrayMergeRecursive($arr2, $arr1)
966 foreach ($arr2 as $key => $data) {
967 if (!isset($arr1[$key])) {
972 if (is_array($data)) {
973 if (!is_array($arr1[$key])) {
974 $ret[$key] = $arr1[$key];
978 $ret[$key] = PEAR_Config::arrayMergeRecursive($arr1[$key], $arr2[$key]);
983 return array_merge($ret, $arr1);
987 * Writes data into a config layer from a file.
989 * @param string|null file to read from, or null for default
990 * @param string config layer to insert data into ('user' or
992 * @param string|null data to write to config file or null for internal data [DEPRECATED]
993 * @return bool TRUE on success or a PEAR error on failure
995 function writeConfigFile($file = null, $layer = 'user', $data = null)
997 $this->_lazyChannelSetup($layer);
998 if ($layer == 'both' || $layer == 'all') {
999 foreach ($this->files as $type => $file) {
1000 $err = $this->writeConfigFile($file, $type, $data);
1001 if (PEAR::isError($err)) {
1008 if (empty($this->files[$layer])) {
1009 return $this->raiseError("unknown config file type `$layer'");
1012 if ($file === null) {
1013 $file = $this->files[$layer];
1016 $data = ($data === null) ? $this->configuration[$layer] : $data;
1017 $this->_encodeOutput($data);
1018 $opt = array('-p', dirname($file));
1019 if (!@System::mkDir($opt)) {
1020 return $this->raiseError("could not create directory: " . dirname($file));
1023 if (file_exists($file) && is_file($file) && !is_writeable($file)) {
1024 return $this->raiseError("no write access to $file!");
1027 $fp = @fopen($file, "w");
1029 return $this->raiseError("PEAR_Config::writeConfigFile fopen('$file','w') failed ($php_errormsg)");
1032 $contents = "#PEAR_Config 0.9\n" . serialize($data);
1033 if (!@fwrite($fp, $contents)) {
1034 return $this->raiseError("PEAR_Config::writeConfigFile: fwrite failed ($php_errormsg)");
1040 * Reads configuration data from a file and returns the parsed data
1043 * @param string file to read from
1044 * @return array configuration data or a PEAR error on failure
1047 function _readConfigDataFrom($file)
1050 if (file_exists($file)) {
1051 $fp = @fopen($file, "r");
1055 return $this->raiseError("PEAR_Config::readConfigFile fopen('$file','r') failed");
1058 $size = filesize($file);
1060 $contents = file_get_contents($file);
1061 if (empty($contents)) {
1062 return $this->raiseError('Configuration file "' . $file . '" is empty');
1066 if (preg_match('/^#PEAR_Config\s+(\S+)\s+/si', $contents, $matches)) {
1067 $version = $matches[1];
1068 $contents = substr($contents, strlen($matches[0]));
1070 // Museum config file
1071 if (substr($contents,0,2) == 'a:') {
1076 if ($version && version_compare("$version", '1', '<')) {
1077 // no '@', it is possible that unserialize
1078 // raises a notice but it seems to block IO to
1079 // STDOUT if a '@' is used and a notice is raise
1080 $data = unserialize($contents);
1082 if (!is_array($data) && !$data) {
1083 if ($contents == serialize(false)) {
1086 $err = $this->raiseError("PEAR_Config: bad data in $file");
1090 if (!is_array($data)) {
1091 if (strlen(trim($contents)) > 0) {
1092 $error = "PEAR_Config: bad data in $file";
1093 $err = $this->raiseError($error);
1099 // add parsing of newer formats here...
1101 $err = $this->raiseError("$file: unknown version `$version'");
1109 * Gets the file used for storing the config for a layer
1111 * @param string $layer 'user' or 'system'
1113 function getConfFile($layer)
1115 return $this->files[$layer];
1119 * @param string Configuration class name, used for detecting duplicate calls
1120 * @param array information on a role as parsed from its xml file
1121 * @return true|PEAR_Error
1124 function _addConfigVars($class, $vars)
1126 static $called = array();
1127 if (isset($called[$class])) {
1131 $called[$class] = 1;
1132 if (count($vars) > 3) {
1133 return $this->raiseError('Roles can only define 3 new config variables or less');
1136 foreach ($vars as $name => $var) {
1137 if (!is_array($var)) {
1138 return $this->raiseError('Configuration information must be an array');
1141 if (!isset($var['type'])) {
1142 return $this->raiseError('Configuration information must contain a type');
1143 } elseif (!in_array($var['type'],
1144 array('string', 'mask', 'password', 'directory', 'file', 'set'))) {
1145 return $this->raiseError(
1146 'Configuration type must be one of directory, file, string, ' .
1147 'mask, set, or password');
1149 if (!isset($var['default'])) {
1150 return $this->raiseError(
1151 'Configuration information must contain a default value ("default" index)');
1154 if (is_array($var['default'])) {
1156 foreach ($var['default'] as $config_var => $val) {
1157 if (strpos($config_var, 'text') === 0) {
1158 $real_default .= $val;
1159 } elseif (strpos($config_var, 'constant') === 0) {
1160 if (!defined($val)) {
1161 return $this->raiseError(
1162 'Unknown constant "' . $val . '" requested in ' .
1163 'default value for configuration variable "' .
1167 $real_default .= constant($val);
1168 } elseif (isset($this->configuration_info[$config_var])) {
1170 $this->configuration_info[$config_var]['default'];
1172 return $this->raiseError(
1173 'Unknown request for "' . $config_var . '" value in ' .
1174 'default value for configuration variable "' .
1178 $var['default'] = $real_default;
1181 if ($var['type'] == 'integer') {
1182 $var['default'] = (integer) $var['default'];
1185 if (!isset($var['doc'])) {
1186 return $this->raiseError(
1187 'Configuration information must contain a summary ("doc" index)');
1190 if (!isset($var['prompt'])) {
1191 return $this->raiseError(
1192 'Configuration information must contain a simple prompt ("prompt" index)');
1195 if (!isset($var['group'])) {
1196 return $this->raiseError(
1197 'Configuration information must contain a simple group ("group" index)');
1200 if (isset($this->configuration_info[$name])) {
1201 return $this->raiseError('Configuration variable "' . $name .
1202 '" already exists');
1205 $this->configuration_info[$name] = $var;
1206 // fix bug #7351: setting custom config variable in a channel fails
1207 $this->_channelConfigInfo[] = $name;
1214 * Encodes/scrambles configuration data before writing to files.
1215 * Currently, 'password' values will be base64-encoded as to avoid
1216 * that people spot cleartext passwords by accident.
1218 * @param array (reference) array to encode values in
1219 * @return bool TRUE on success
1222 function _encodeOutput(&$data)
1224 foreach ($data as $key => $value) {
1225 if ($key == '__channels') {
1226 foreach ($data['__channels'] as $channel => $blah) {
1227 $this->_encodeOutput($data['__channels'][$channel]);
1231 if (!isset($this->configuration_info[$key])) {
1235 $type = $this->configuration_info[$key]['type'];
1237 // we base64-encode passwords so they are at least
1238 // not shown in plain by accident
1240 $data[$key] = base64_encode($data[$key]);
1244 $data[$key] = octdec($data[$key]);
1254 * Decodes/unscrambles configuration data after reading from files.
1256 * @param array (reference) array to encode values in
1257 * @return bool TRUE on success
1260 * @see PEAR_Config::_encodeOutput
1262 function _decodeInput(&$data)
1264 if (!is_array($data)) {
1268 foreach ($data as $key => $value) {
1269 if ($key == '__channels') {
1270 foreach ($data['__channels'] as $channel => $blah) {
1271 $this->_decodeInput($data['__channels'][$channel]);
1275 if (!isset($this->configuration_info[$key])) {
1279 $type = $this->configuration_info[$key]['type'];
1282 $data[$key] = base64_decode($data[$key]);
1286 $data[$key] = decoct($data[$key]);
1296 * Retrieve the default channel.
1298 * On startup, channels are not initialized, so if the default channel is not
1299 * pear.php.net, then initialize the config.
1300 * @param string registry layer
1301 * @return string|false
1303 function getDefaultChannel($layer = null)
1306 if ($layer === null) {
1307 foreach ($this->layers as $layer) {
1308 if (isset($this->configuration[$layer]['default_channel'])) {
1309 $ret = $this->configuration[$layer]['default_channel'];
1313 } elseif (isset($this->configuration[$layer]['default_channel'])) {
1314 $ret = $this->configuration[$layer]['default_channel'];
1317 if ($ret == 'pear.php.net' && defined('PEAR_RUNTYPE') && PEAR_RUNTYPE == 'pecl') {
1318 $ret = 'pecl.php.net';
1322 if ($ret != 'pear.php.net') {
1323 $this->_lazyChannelSetup();
1329 return PEAR_CONFIG_DEFAULT_CHANNEL;
1333 * Returns a configuration value, prioritizing layers as per the
1336 * @param string config key
1337 * @return mixed the config value, or NULL if not found
1340 function get($key, $layer = null, $channel = false)
1342 if (!isset($this->configuration_info[$key])) {
1346 if ($key == '__channels') {
1350 if ($key == 'default_channel') {
1351 return $this->getDefaultChannel($layer);
1355 $channel = $this->getDefaultChannel();
1356 } elseif ($channel != 'pear.php.net') {
1357 $this->_lazyChannelSetup();
1359 $channel = strtolower($channel);
1361 $test = (in_array($key, $this->_channelConfigInfo)) ?
1362 $this->_getChannelValue($key, $layer, $channel) :
1364 if ($test !== null) {
1365 if ($this->_installRoot) {
1366 if (in_array($this->getGroup($key),
1367 array('File Locations', 'File Locations (Advanced)')) &&
1368 $this->getType($key) == 'directory') {
1369 return $this->_prependPath($test, $this->_installRoot);
1375 if ($layer === null) {
1376 foreach ($this->layers as $layer) {
1377 if (isset($this->configuration[$layer][$key])) {
1378 $test = $this->configuration[$layer][$key];
1379 if ($this->_installRoot) {
1380 if (in_array($this->getGroup($key),
1381 array('File Locations', 'File Locations (Advanced)')) &&
1382 $this->getType($key) == 'directory') {
1383 return $this->_prependPath($test, $this->_installRoot);
1387 if ($key == 'preferred_mirror') {
1388 $reg = &$this->getRegistry();
1389 if (is_object($reg)) {
1390 $chan = $reg->getChannel($channel);
1391 if (PEAR::isError($chan)) {
1395 if (!$chan->getMirror($test) && $chan->getName() != $test) {
1396 return $channel; // mirror does not exist
1403 } elseif (isset($this->configuration[$layer][$key])) {
1404 $test = $this->configuration[$layer][$key];
1405 if ($this->_installRoot) {
1406 if (in_array($this->getGroup($key),
1407 array('File Locations', 'File Locations (Advanced)')) &&
1408 $this->getType($key) == 'directory') {
1409 return $this->_prependPath($test, $this->_installRoot);
1413 if ($key == 'preferred_mirror') {
1414 $reg = &$this->getRegistry();
1415 if (is_object($reg)) {
1416 $chan = $reg->getChannel($channel);
1417 if (PEAR::isError($chan)) {
1421 if (!$chan->getMirror($test) && $chan->getName() != $test) {
1422 return $channel; // mirror does not exist
1434 * Returns a channel-specific configuration value, prioritizing layers as per the
1437 * @param string config key
1438 * @return mixed the config value, or NULL if not found
1441 function _getChannelValue($key, $layer, $channel)
1443 if ($key == '__channels' || $channel == 'pear.php.net') {
1448 if ($layer === null) {
1449 foreach ($this->layers as $ilayer) {
1450 if (isset($this->configuration[$ilayer]['__channels'][$channel][$key])) {
1451 $ret = $this->configuration[$ilayer]['__channels'][$channel][$key];
1455 } elseif (isset($this->configuration[$layer]['__channels'][$channel][$key])) {
1456 $ret = $this->configuration[$layer]['__channels'][$channel][$key];
1459 if ($key != 'preferred_mirror') {
1464 if ($ret !== null) {
1465 $reg = &$this->getRegistry($layer);
1466 if (is_object($reg)) {
1467 $chan = $reg->getChannel($channel);
1468 if (PEAR::isError($chan)) {
1472 if (!$chan->getMirror($ret) && $chan->getName() != $ret) {
1473 return $channel; // mirror does not exist
1480 if ($channel != $this->getDefaultChannel($layer)) {
1481 return $channel; // we must use the channel name as the preferred mirror
1482 // if the user has not chosen an alternate
1485 return $this->getDefaultChannel($layer);
1489 * Set a config value in a specific layer (defaults to 'user').
1490 * Enforces the types defined in the configuration_info array. An
1491 * integer config variable will be cast to int, and a set config
1492 * variable will be validated against its legal values.
1494 * @param string config key
1495 * @param string config value
1496 * @param string (optional) config layer
1497 * @param string channel to set this value for, or null for global value
1498 * @return bool TRUE on success, FALSE on failure
1500 function set($key, $value, $layer = 'user', $channel = false)
1502 if ($key == '__channels') {
1506 if (!isset($this->configuration[$layer])) {
1510 if ($key == 'default_channel') {
1511 // can only set this value globally
1512 $channel = 'pear.php.net';
1513 if ($value != 'pear.php.net') {
1514 $this->_lazyChannelSetup($layer);
1518 if ($key == 'preferred_mirror') {
1519 if ($channel == '__uri') {
1520 return false; // can't set the __uri pseudo-channel's mirror
1523 $reg = &$this->getRegistry($layer);
1524 if (is_object($reg)) {
1525 $chan = $reg->getChannel($channel ? $channel : 'pear.php.net');
1526 if (PEAR::isError($chan)) {
1530 if (!$chan->getMirror($value) && $chan->getName() != $value) {
1531 return false; // mirror does not exist
1536 if (!isset($this->configuration_info[$key])) {
1540 extract($this->configuration_info[$key]);
1543 $value = (int)$value;
1546 // If a valid_set is specified, require the value to
1547 // be in the set. If there is no valid_set, accept
1551 if ((key($valid_set) === 0 && !in_array($value, $valid_set)) ||
1552 (key($valid_set) !== 0 && empty($valid_set[$value])))
1562 $channel = $this->get('default_channel', null, 'pear.php.net');
1565 if (!in_array($channel, $this->_channels)) {
1566 $this->_lazyChannelSetup($layer);
1567 $reg = &$this->getRegistry($layer);
1569 $channel = $reg->channelName($channel);
1572 if (!in_array($channel, $this->_channels)) {
1577 if ($channel != 'pear.php.net') {
1578 if (in_array($key, $this->_channelConfigInfo)) {
1579 $this->configuration[$layer]['__channels'][$channel][$key] = $value;
1586 if ($key == 'default_channel') {
1588 $reg = &$this->getRegistry($layer);
1590 $reg = &$this->getRegistry();
1595 $value = $reg->channelName($value);
1603 $this->configuration[$layer][$key] = $value;
1604 if ($key == 'php_dir' && !$this->_noRegistry) {
1605 if (!isset($this->_registry[$layer]) ||
1606 $value != $this->_registry[$layer]->install_dir) {
1607 $this->_registry[$layer] = new PEAR_Registry($value);
1608 $this->_regInitialized[$layer] = false;
1609 $this->_registry[$layer]->setConfig($this, false);
1616 function _lazyChannelSetup($uselayer = false)
1618 if ($this->_noRegistry) {
1623 foreach ($this->_registry as $layer => $p) {
1624 if ($uselayer && $uselayer != $layer) {
1628 if (!$this->_regInitialized[$layer]) {
1629 if ($layer == 'default' && isset($this->_registry['user']) ||
1630 isset($this->_registry['system'])) {
1631 // only use the default registry if there are no alternatives
1635 if (!is_object($this->_registry[$layer])) {
1636 if ($phpdir = $this->get('php_dir', $layer, 'pear.php.net')) {
1637 $this->_registry[$layer] = new PEAR_Registry(
1638 $phpdir, false, false,
1639 $this->get('metadata_dir', $layer, 'pear.php.net'));
1640 $this->_registry[$layer]->setConfig($this, false);
1641 $this->_regInitialized[$layer] = false;
1643 unset($this->_registry[$layer]);
1648 $this->setChannels($this->_registry[$layer]->listChannels(), $merge);
1649 $this->_regInitialized[$layer] = true;
1656 * Set the list of channels.
1658 * This should be set via a call to {@link PEAR_Registry::listChannels()}
1661 * @return bool success of operation
1663 function setChannels($channels, $merge = false)
1665 if (!is_array($channels)) {
1670 $this->_channels = array_merge($this->_channels, $channels);
1672 $this->_channels = $channels;
1675 foreach ($channels as $channel) {
1676 $channel = strtolower($channel);
1677 if ($channel == 'pear.php.net') {
1681 foreach ($this->layers as $layer) {
1682 if (!isset($this->configuration[$layer]['__channels'])) {
1683 $this->configuration[$layer]['__channels'] = array();
1685 if (!isset($this->configuration[$layer]['__channels'][$channel])
1686 || !is_array($this->configuration[$layer]['__channels'][$channel])) {
1687 $this->configuration[$layer]['__channels'][$channel] = array();
1696 * Get the type of a config value.
1698 * @param string config key
1700 * @return string type, one of "string", "integer", "file",
1701 * "directory", "set" or "password".
1706 function getType($key)
1708 if (isset($this->configuration_info[$key])) {
1709 return $this->configuration_info[$key]['type'];
1715 * Get the documentation for a config value.
1717 * @param string config key
1718 * @return string documentation string
1723 function getDocs($key)
1725 if (isset($this->configuration_info[$key])) {
1726 return $this->configuration_info[$key]['doc'];
1733 * Get the short documentation for a config value.
1735 * @param string config key
1736 * @return string short documentation string
1741 function getPrompt($key)
1743 if (isset($this->configuration_info[$key])) {
1744 return $this->configuration_info[$key]['prompt'];
1751 * Get the parameter group for a config key.
1753 * @param string config key
1754 * @return string parameter group
1759 function getGroup($key)
1761 if (isset($this->configuration_info[$key])) {
1762 return $this->configuration_info[$key]['group'];
1769 * Get the list of parameter groups.
1771 * @return array list of parameter groups
1776 function getGroups()
1779 foreach ($this->configuration_info as $key => $info) {
1780 $tmp[$info['group']] = 1;
1783 return array_keys($tmp);
1787 * Get the list of the parameters in a group.
1789 * @param string $group parameter group
1790 * @return array list of parameters in $group
1795 function getGroupKeys($group)
1798 foreach ($this->configuration_info as $key => $info) {
1799 if ($info['group'] == $group) {
1808 * Get the list of allowed set values for a config value. Returns
1809 * NULL for config values that are not sets.
1811 * @param string config key
1812 * @return array enumerated array of set values, or NULL if the
1813 * config key is unknown or not a set
1818 function getSetValues($key)
1820 if (isset($this->configuration_info[$key]) &&
1821 isset($this->configuration_info[$key]['type']) &&
1822 $this->configuration_info[$key]['type'] == 'set')
1824 $valid_set = $this->configuration_info[$key]['valid_set'];
1826 if (key($valid_set) === 0) {
1830 return array_keys($valid_set);
1837 * Get all the current config keys.
1839 * @return array simple array of config keys
1846 foreach ($this->layers as $layer) {
1847 $test = $this->configuration[$layer];
1848 if (isset($test['__channels'])) {
1849 foreach ($test['__channels'] as $channel => $configs) {
1850 $keys = array_merge($keys, $configs);
1854 unset($test['__channels']);
1855 $keys = array_merge($keys, $test);
1858 return array_keys($keys);
1862 * Remove the a config key from a specific config layer.
1864 * @param string config key
1865 * @param string (optional) config layer
1866 * @param string (optional) channel (defaults to default channel)
1867 * @return bool TRUE on success, FALSE on failure
1871 function remove($key, $layer = 'user', $channel = null)
1873 if ($channel === null) {
1874 $channel = $this->getDefaultChannel();
1877 if ($channel !== 'pear.php.net') {
1878 if (isset($this->configuration[$layer]['__channels'][$channel][$key])) {
1879 unset($this->configuration[$layer]['__channels'][$channel][$key]);
1884 if (isset($this->configuration[$layer][$key])) {
1885 unset($this->configuration[$layer][$key]);
1893 * Temporarily remove an entire config layer. USE WITH CARE!
1895 * @param string config key
1896 * @param string (optional) config layer
1897 * @return bool TRUE on success, FALSE on failure
1901 function removeLayer($layer)
1903 if (isset($this->configuration[$layer])) {
1904 $this->configuration[$layer] = array();
1912 * Stores configuration data in a layer.
1914 * @param string config layer to store
1915 * @return bool TRUE on success, or PEAR error on failure
1919 function store($layer = 'user', $data = null)
1921 return $this->writeConfigFile(null, $layer, $data);
1925 * Tells what config layer that gets to define a key.
1927 * @param string config key
1928 * @param boolean return the defining channel
1930 * @return string|array the config layer, or an empty string if not found.
1932 * if $returnchannel, the return is an array array('layer' => layername,
1933 * 'channel' => channelname), or an empty string if not found
1937 function definedBy($key, $returnchannel = false)
1939 foreach ($this->layers as $layer) {
1940 $channel = $this->getDefaultChannel();
1941 if ($channel !== 'pear.php.net') {
1942 if (isset($this->configuration[$layer]['__channels'][$channel][$key])) {
1943 if ($returnchannel) {
1944 return array('layer' => $layer, 'channel' => $channel);
1950 if (isset($this->configuration[$layer][$key])) {
1951 if ($returnchannel) {
1952 return array('layer' => $layer, 'channel' => 'pear.php.net');
1962 * Tells whether a given key exists as a config value.
1964 * @param string config key
1965 * @return bool whether <config key> exists in this object
1969 function isDefined($key)
1971 foreach ($this->layers as $layer) {
1972 if (isset($this->configuration[$layer][$key])) {
1981 * Tells whether a given config layer exists.
1983 * @param string config layer
1984 * @return bool whether <config layer> exists in this object
1988 function isDefinedLayer($layer)
1990 return isset($this->configuration[$layer]);
1994 * Returns the layers defined (except the 'default' one)
1996 * @return array of the defined layers
1998 function getLayers()
2000 $cf = $this->configuration;
2001 unset($cf['default']);
2002 return array_keys($cf);
2005 function apiVersion()
2011 * @return PEAR_Registry
2013 function &getRegistry($use = null)
2015 $layer = $use === null ? 'user' : $use;
2016 if (isset($this->_registry[$layer])) {
2017 return $this->_registry[$layer];
2018 } elseif ($use === null && isset($this->_registry['system'])) {
2019 return $this->_registry['system'];
2020 } elseif ($use === null && isset($this->_registry['default'])) {
2021 return $this->_registry['default'];
2027 // only go here if null was passed in
2028 echo "CRITICAL ERROR: Registry could not be initialized from any value";
2033 * This is to allow customization like the use of installroot
2034 * @param PEAR_Registry
2037 function setRegistry(&$reg, $layer = 'user')
2039 if ($this->_noRegistry) {
2043 if (!in_array($layer, array('user', 'system'))) {
2047 $this->_registry[$layer] = &$reg;
2048 if (is_object($reg)) {
2049 $this->_registry[$layer]->setConfig($this, false);
2055 function noRegistry()
2057 $this->_noRegistry = true;
2063 function &getREST($version, $options = array())
2065 $version = str_replace('.', '', $version);
2066 if (!class_exists($class = 'PEAR_REST_' . $version)) {
2067 require_once 'PEAR/REST/' . $version . '.php';
2070 $remote = new $class($this, $options);
2075 * The ftp server is set in {@link readFTPConfigFile()}. It exists only if a
2076 * remote configuration file has been specified
2077 * @return PEAR_FTP|false
2081 if (isset($this->_ftp)) {
2089 function _prependPath($path, $prepend)
2091 if (strlen($prepend) > 0) {
2092 if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) {
2093 if (preg_match('/^[a-z]:/i', $prepend)) {
2094 $prepend = substr($prepend, 2);
2095 } elseif ($prepend{0} != '\\') {
2096 $prepend = "\\$prepend";
2098 $path = substr($path, 0, 2) . $prepend . substr($path, 2);
2100 $path = $prepend . $path;
2107 * @param string|false installation directory to prepend to all _dir variables, or false to
2110 function setInstallRoot($root)
2112 if (substr($root, -1) == DIRECTORY_SEPARATOR) {
2113 $root = substr($root, 0, -1);
2115 $old = $this->_installRoot;
2116 $this->_installRoot = $root;
2117 if (($old != $root) && !$this->_noRegistry) {
2118 foreach (array_keys($this->_registry) as $layer) {
2119 if ($layer == 'ftp' || !isset($this->_registry[$layer])) {
2122 $this->_registry[$layer] =
2124 $this->get('php_dir', $layer, 'pear.php.net'), false, false,
2125 $this->get('metadata_dir', $layer, 'pear.php.net'));
2126 $this->_registry[$layer]->setConfig($this, false);
2127 $this->_regInitialized[$layer] = false;