Seagull PHP Cross Reference Content Management Systems

Source: /lib/pear/PEAR/Dependency.php - 495 lines - 17569 bytes - Summary - Text - Print

   1  <?php
   2  //
   3  // +----------------------------------------------------------------------+
   4  // | PHP Version 5                                                        |
   5  // +----------------------------------------------------------------------+
   6  // | Copyright (c) 1997-2004 The PHP Group                                |
   7  // +----------------------------------------------------------------------+
   8  // | This source file is subject to version 3.0 of the PHP license,       |
   9  // | that is bundled with this package in the file LICENSE, and is        |
  10  // | available through the world-wide-web at the following url:           |
  11  // | http://www.php.net/license/3_0.txt.                                  |
  12  // | If you did not receive a copy of the PHP license and are unable to   |
  13  // | obtain it through the world-wide-web, please send a note to          |
  14  // | license@php.net so we can mail you a copy immediately.               |
  15  // +----------------------------------------------------------------------+
  16  // | Authors: Tomas V.V.Cox <cox@idecnet.com>                             |
  17  // |          Stig Bakken <ssb@php.net>                                   |
  18  // +----------------------------------------------------------------------+
  19  //
  20  // THIS FILE IS DEPRECATED IN FAVOR OF DEPENDENCY2.PHP, AND IS NOT USED IN THE INSTALLER
  21  // $Id: Dependency.php,v 1.42 2006/03/26 23:25:56 cellog Exp $
  22  
  23  require_once "PEAR.php";
  24  require_once "OS/Guess.php";
  25  
  26  define('PEAR_DEPENDENCY_MISSING',        -1);
  27  define('PEAR_DEPENDENCY_CONFLICT',       -2);
  28  define('PEAR_DEPENDENCY_UPGRADE_MINOR',  -3);
  29  define('PEAR_DEPENDENCY_UPGRADE_MAJOR',  -4);
  30  define('PEAR_DEPENDENCY_BAD_DEPENDENCY', -5);
  31  define('PEAR_DEPENDENCY_MISSING_OPTIONAL', -6);
  32  define('PEAR_DEPENDENCY_CONFLICT_OPTIONAL',       -7);
  33  define('PEAR_DEPENDENCY_UPGRADE_MINOR_OPTIONAL',  -8);
  34  define('PEAR_DEPENDENCY_UPGRADE_MAJOR_OPTIONAL',  -9);
  35  
  36  /**
  37   * Dependency check for PEAR packages
  38   *
  39   * The class is based on the dependency RFC that can be found at
  40   * http://cvs.php.net/cvs.php/pearweb/rfc. It requires PHP >= 4.1
  41   *
  42   * @author Tomas V.V.Vox <cox@idecnet.com>
  43   * @author Stig Bakken <ssb@php.net>
  44   */
  45  class PEAR_Dependency
  46  {
  47      // {{{ constructor
  48      /**
  49       * Constructor
  50       *
  51       * @access public
  52       * @param  object Registry object
  53       * @return void
  54       */
  55      function PEAR_Dependency(&$registry)
  56      {
  57          $this->registry = &$registry;
  58      }
  59  
  60      // }}}
  61      // {{{ callCheckMethod()
  62  
  63      /**
  64      * This method maps the XML dependency definition to the
  65      * corresponding one from PEAR_Dependency
  66      *
  67      * <pre>
  68      * $opts => Array
  69      *    (
  70      *        [type] => pkg
  71      *        [rel] => ge
  72      *        [version] => 3.4
  73      *        [name] => HTML_Common
  74      *        [optional] => false
  75      *    )
  76      * </pre>
  77      *
  78      * @param  string Error message
  79      * @param  array  Options
  80      * @return boolean
  81      */
  82      function callCheckMethod(&$errmsg, $opts)
  83      {
  84          $rel = isset($opts['rel']) ? $opts['rel'] : 'has';
  85          $req = isset($opts['version']) ? $opts['version'] : null;
  86          $name = isset($opts['name']) ? $opts['name'] : null;
  87          $channel = isset($opts['channel']) ? $opts['channel'] : 'pear.php.net';
  88          $opt = (isset($opts['optional']) && $opts['optional'] == 'yes') ?
  89              $opts['optional'] : null;
  90          $errmsg = '';
  91          switch ($opts['type']) {
  92              case 'pkg':
  93                  return $this->checkPackage($errmsg, $name, $req, $rel, $opt, $channel);
  94                  break;
  95              case 'ext':
  96                  return $this->checkExtension($errmsg, $name, $req, $rel, $opt);
  97                  break;
  98              case 'php':
  99                  return $this->checkPHP($errmsg, $req, $rel);
 100                  break;
 101              case 'prog':
 102                  return $this->checkProgram($errmsg, $name);
 103                  break;
 104              case 'os':
 105                  return $this->checkOS($errmsg, $name);
 106                  break;
 107              case 'sapi':
 108                  return $this->checkSAPI($errmsg, $name);
 109                  break;
 110              case 'zend':
 111                  return $this->checkZend($errmsg, $name);
 112                  break;
 113              default:
 114                  return "'{$opts['type']}' dependency type not supported";
 115          }
 116      }
 117  
 118      // }}}
 119      // {{{ checkPackage()
 120  
 121      /**
 122       * Package dependencies check method
 123       *
 124       * @param string $errmsg    Empty string, it will be populated with an error message, if any
 125       * @param string $name      Name of the package to test
 126       * @param string $req       The package version required
 127       * @param string $relation  How to compare versions with each other
 128       * @param bool   $opt       Whether the relationship is optional
 129       * @param string $channel   Channel name
 130       *
 131       * @return mixed bool false if no error or the error string
 132       */
 133      function checkPackage(&$errmsg, $name, $req = null, $relation = 'has',
 134                            $opt = false, $channel = 'pear.php.net')
 135      {
 136          if (is_string($req) && substr($req, 0, 2) == 'v.') {
 137              $req = substr($req, 2);
 138          }
 139          switch ($relation) {
 140              case 'has':
 141                  if (!$this->registry->packageExists($name, $channel)) {
 142                      if ($opt) {
 143                          $errmsg = "package `$channel/$name' is recommended to utilize some features.";
 144                          return PEAR_DEPENDENCY_MISSING_OPTIONAL;
 145                      }
 146                      $errmsg = "requires package `$channel/$name'";
 147                      return PEAR_DEPENDENCY_MISSING;
 148                  }
 149                  return false;
 150              case 'not':
 151                  if ($this->registry->packageExists($name, $channel)) {
 152                      $errmsg = "conflicts with package `$channel/$name'";
 153                      return PEAR_DEPENDENCY_CONFLICT;
 154                  }
 155                  return false;
 156              case 'lt':
 157              case 'le':
 158              case 'eq':
 159              case 'ne':
 160              case 'ge':
 161              case 'gt':
 162                  $version = $this->registry->packageInfo($name, 'version', $channel);
 163                  if (!$this->registry->packageExists($name, $channel)
 164                      || !version_compare("$version", "$req", $relation))
 165                  {
 166                      $code = $this->codeFromRelation($relation, $version, $req, $opt);
 167                      if ($opt) {
 168                          $errmsg = "package `$channel/$name' version " . $this->signOperator($relation) .
 169                              " $req is recommended to utilize some features.";
 170                          if ($version) {
 171                              $errmsg .= "  Installed version is $version";
 172                          }
 173                          return $code;
 174                      }
 175                      $errmsg = "requires package `$channel/$name' " .
 176                          $this->signOperator($relation) . " $req";
 177                      return $code;
 178                  }
 179                  return false;
 180          }
 181          $errmsg = "relation '$relation' with requirement '$req' is not supported (name=$channel/$name)";
 182          return PEAR_DEPENDENCY_BAD_DEPENDENCY;
 183      }
 184  
 185      // }}}
 186      // {{{ checkPackageUninstall()
 187  
 188      /**
 189       * Check package dependencies on uninstall
 190       *
 191       * @param string $error     The resultant error string
 192       * @param string $warning   The resultant warning string
 193       * @param string $name      Name of the package to test
 194       * @param string $channel   Channel name of the package
 195       *
 196       * @return bool true if there were errors
 197       */
 198      function checkPackageUninstall(&$error, &$warning, $package, $channel = 'pear.php.net')
 199      {
 200          $channel = strtolower($channel);
 201          $error = null;
 202          $channels = $this->registry->listAllPackages();
 203          foreach ($channels as $channelname => $packages) {
 204              foreach ($packages as $pkg) {
 205                  if ($pkg == $package && $channel == $channelname) {
 206                      continue;
 207                  }
 208                  $deps = $this->registry->packageInfo($pkg, 'release_deps', $channel);
 209                  if (empty($deps)) {
 210                      continue;
 211                  }
 212                  foreach ($deps as $dep) {
 213                      $depchannel = isset($dep['channel']) ? $dep['channel'] : 'pear.php.net';
 214                      if ($dep['type'] == 'pkg' && (strcasecmp($dep['name'], $package) == 0) &&
 215                            ($depchannel == $channel)) {
 216                          if ($dep['rel'] == 'ne') {
 217                              continue;
 218                          }
 219                          if (isset($dep['optional']) && $dep['optional'] == 'yes') {
 220                              $warning .= "\nWarning: Package '$depchannel/$pkg' optionally depends on '$channel:/package'";
 221                          } else {
 222                              $error .= "Package '$depchannel/$pkg' depends on '$channel/$package'\n";
 223                          }
 224                      }
 225                  }
 226              }
 227          }
 228          return ($error) ? true : false;
 229      }
 230  
 231      // }}}
 232      // {{{ checkExtension()
 233  
 234      /**
 235       * Extension dependencies check method
 236       *
 237       * @param string $name        Name of the extension to test
 238       * @param string $req_ext_ver Required extension version to compare with
 239       * @param string $relation    How to compare versions with eachother
 240       * @param bool   $opt         Whether the relationship is optional
 241       *
 242       * @return mixed bool false if no error or the error string
 243       */
 244      function checkExtension(&$errmsg, $name, $req = null, $relation = 'has',
 245          $opt = false)
 246      {
 247          if ($relation == 'not') {
 248              if (extension_loaded($name)) {
 249                  $errmsg = "conflicts with  PHP extension '$name'";
 250                  return PEAR_DEPENDENCY_CONFLICT;
 251              } else {
 252                  return false;
 253              }
 254          }
 255  
 256          if (!extension_loaded($name)) {
 257              if ($relation == 'ne') {
 258                  return false;
 259              }
 260              if ($opt) {
 261                  $errmsg = "'$name' PHP extension is recommended to utilize some features";
 262                  return PEAR_DEPENDENCY_MISSING_OPTIONAL;
 263              }
 264              $errmsg = "'$name' PHP extension is not installed";
 265              return PEAR_DEPENDENCY_MISSING;
 266          }
 267          if ($relation == 'has') {
 268              return false;
 269          }
 270          $code = false;
 271          if (is_string($req) && substr($req, 0, 2) == 'v.') {
 272              $req = substr($req, 2);
 273          }
 274          $ext_ver = phpversion($name);
 275          $operator = $relation;
 276          // Force params to be strings, otherwise the comparation will fail (ex. 0.9==0.90)
 277          if (!version_compare("$ext_ver", "$req", $operator)) {
 278              $errmsg = "'$name' PHP extension version " .
 279                  $this->signOperator($operator) . " $req is required";
 280              $code = $this->codeFromRelation($relation, $ext_ver, $req, $opt);
 281              if ($opt) {
 282                  $errmsg = "'$name' PHP extension version " . $this->signOperator($operator) .
 283                      " $req is recommended to utilize some features";
 284                  return $code;
 285              }
 286          }
 287          return $code;
 288      }
 289  
 290      // }}}
 291      // {{{ checkOS()
 292  
 293      /**
 294       * Operating system  dependencies check method
 295       *
 296       * @param string $os  Name of the operating system
 297       *
 298       * @return mixed bool false if no error or the error string
 299       */
 300      function checkOS(&$errmsg, $os)
 301      {
 302          // XXX Fixme: Implement a more flexible way, like
 303          // comma separated values or something similar to PEAR_OS
 304          static $myos;
 305          if (empty($myos)) {
 306              $myos = new OS_Guess();
 307          }
 308          // only 'has' relation is currently supported
 309          if ($myos->matchSignature($os)) {
 310              return false;
 311          }
 312          $errmsg = "'$os' operating system not supported";
 313          return PEAR_DEPENDENCY_CONFLICT;
 314      }
 315  
 316      // }}}
 317      // {{{ checkPHP()
 318  
 319      /**
 320       * PHP version check method
 321       *
 322       * @param string $req   which version to compare
 323       * @param string $relation  how to compare the version
 324       *
 325       * @return mixed bool false if no error or the error string
 326       */
 327      function checkPHP(&$errmsg, $req, $relation = 'ge')
 328      {
 329          // this would be a bit stupid, but oh well :)
 330          if ($relation == 'has') {
 331              return false;
 332          }
 333          if ($relation == 'not') {
 334              $errmsg = "Invalid dependency - 'not' is allowed when specifying PHP, you must run PHP in PHP";
 335              return PEAR_DEPENDENCY_BAD_DEPENDENCY;
 336          }
 337          if (substr($req, 0, 2) == 'v.') {
 338              $req = substr($req,2, strlen($req) - 2);
 339          }
 340          $php_ver = phpversion();
 341          $operator = $relation;
 342          if (!version_compare("$php_ver", "$req", $operator)) {
 343              $errmsg = "PHP version " . $this->signOperator($operator) .
 344                  " $req is required";
 345              return PEAR_DEPENDENCY_CONFLICT;
 346          }
 347          return false;
 348      }
 349  
 350      // }}}
 351      // {{{ checkProgram()
 352  
 353      /**
 354       * External program check method.  Looks for executable files in
 355       * directories listed in the PATH environment variable.
 356       *
 357       * @param string $program   which program to look for
 358       *
 359       * @return mixed bool false if no error or the error string
 360       */
 361      function checkProgram(&$errmsg, $program)
 362      {
 363          // XXX FIXME honor safe mode
 364          $exe_suffix = OS_WINDOWS ? '.exe' : '';
 365          $path_elements = explode(PATH_SEPARATOR, getenv('PATH'));
 366          foreach ($path_elements as $dir) {
 367              $file = $dir . DIRECTORY_SEPARATOR . $program . $exe_suffix;
 368              if (file_exists($file) && is_executable($file)) {
 369                  return false;
 370              }
 371          }
 372          $errmsg = "'$program' program is not present in the PATH";
 373          return PEAR_DEPENDENCY_MISSING;
 374      }
 375  
 376      // }}}
 377      // {{{ checkSAPI()
 378  
 379      /**
 380       * SAPI backend check method.  Version comparison is not yet
 381       * available here.
 382       *
 383       * @param string $name      name of SAPI backend
 384       * @param string $req   which version to compare
 385       * @param string $relation  how to compare versions (currently
 386       *                          hardcoded to 'has')
 387       * @return mixed bool false if no error or the error string
 388       */
 389      function checkSAPI(&$errmsg, $name, $req = null, $relation = 'has')
 390      {
 391          // XXX Fixme: There is no way to know if the user has or
 392          // not other SAPI backends installed than the installer one
 393  
 394          $sapi_backend = php_sapi_name();
 395          // Version comparisons not supported, sapi backends don't have
 396          // version information yet.
 397          if ($sapi_backend == $name) {
 398              return false;
 399          }
 400          $errmsg = "'$sapi_backend' SAPI backend not supported";
 401          return PEAR_DEPENDENCY_CONFLICT;
 402      }
 403  
 404      // }}}
 405      // {{{ checkZend()
 406  
 407      /**
 408       * Zend version check method
 409       *
 410       * @param string $req   which version to compare
 411       * @param string $relation  how to compare the version
 412       *
 413       * @return mixed bool false if no error or the error string
 414       */
 415      function checkZend(&$errmsg, $req, $relation = 'ge')
 416      {
 417          if (substr($req, 0, 2) == 'v.') {
 418              $req = substr($req,2, strlen($req) - 2);
 419          }
 420          $zend_ver = zend_version();
 421          $operator = substr($relation,0,2);
 422          if (!version_compare("$zend_ver", "$req", $operator)) {
 423              $errmsg = "Zend version " . $this->signOperator($operator) .
 424                  " $req is required";
 425              return PEAR_DEPENDENCY_CONFLICT;
 426          }
 427          return false;
 428      }
 429  
 430      // }}}
 431      // {{{ signOperator()
 432  
 433      /**
 434       * Converts text comparing operators to them sign equivalents
 435       *
 436       * Example: 'ge' to '>='
 437       *
 438       * @access public
 439       * @param  string Operator
 440       * @return string Sign equivalent
 441       */
 442      function signOperator($operator)
 443      {
 444          switch($operator) {
 445              case 'lt': return '<';
 446              case 'le': return '<=';
 447              case 'gt': return '>';
 448              case 'ge': return '>=';
 449              case 'eq': return '==';
 450              case 'ne': return '!=';
 451              default:
 452                  return $operator;
 453          }
 454      }
 455  
 456      // }}}
 457      // {{{ codeFromRelation()
 458  
 459      /**
 460       * Convert relation into corresponding code
 461       *
 462       * @access public
 463       * @param  string Relation
 464       * @param  string Version
 465       * @param  string Requirement
 466       * @param  bool   Optional dependency indicator
 467       * @return integer
 468       */
 469      function codeFromRelation($relation, $version, $req, $opt = false)
 470      {
 471          $code = PEAR_DEPENDENCY_BAD_DEPENDENCY;
 472          switch ($relation) {
 473              case 'gt': case 'ge': case 'eq':
 474                  // upgrade
 475                  $have_major = preg_replace('/\D.*/', '', $version);
 476                  $need_major = preg_replace('/\D.*/', '', $req);
 477                  if ($need_major > $have_major) {
 478                      $code = $opt ? PEAR_DEPENDENCY_UPGRADE_MAJOR_OPTIONAL :
 479                                     PEAR_DEPENDENCY_UPGRADE_MAJOR;
 480                  } else {
 481                      $code = $opt ? PEAR_DEPENDENCY_UPGRADE_MINOR_OPTIONAL :
 482                                     PEAR_DEPENDENCY_UPGRADE_MINOR;
 483                  }
 484                  break;
 485              case 'lt': case 'le': case 'ne':
 486                  $code = $opt ? PEAR_DEPENDENCY_CONFLICT_OPTIONAL :
 487                                 PEAR_DEPENDENCY_CONFLICT;
 488                  break;
 489          }
 490          return $code;
 491      }
 492  
 493      // }}}
 494  }
 495  ?>

title

Description

title

Description

title

Description

title

title

Body