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