[ Index ]
 

Code source de GeekLog 1.4.1

Accédez au Source d'autres logiciels libres

title

Body

[fermer]

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


Généré le : Wed Nov 21 12:27:40 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics