[ Index ]
 

Code source de PHP PEAR 1.4.5

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/PEAR/ -> Config.php (source)

   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  ?>


Généré le : Sun Feb 25 14:08:00 2007 par Balluche grâce à PHPXref 0.7