[ Index ] |
|
Code source de GeekLog 1.4.1 |
1 <?php 2 /** 3 * PEAR_Dependency2, advanced dependency validation 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 Greg Beaver <cellog@php.net> 16 * @copyright 1997-2006 The PHP Group 17 * @license http://www.php.net/license/3_0.txt PHP License 3.0 18 * @version CVS: $Id: Dependency2.php,v 1.50 2006/01/06 04:47:36 cellog Exp $ 19 * @link http://pear.php.net/package/PEAR 20 * @since File available since Release 1.4.0a1 21 */ 22 23 /** 24 * Required for the PEAR_VALIDATE_* constants 25 */ 26 require_once 'PEAR/Validate.php'; 27 28 /** 29 * Dependency check for PEAR packages 30 * 31 * This class handles both version 1.0 and 2.0 dependencies 32 * WARNING: *any* changes to this class must be duplicated in the 33 * test_PEAR_Dependency2 class found in tests/PEAR_Dependency2/setup.php.inc, 34 * or unit tests will not actually validate the changes 35 * @category pear 36 * @package PEAR 37 * @author Greg Beaver <cellog@php.net> 38 * @copyright 1997-2006 The PHP Group 39 * @license http://www.php.net/license/3_0.txt PHP License 3.0 40 * @version Release: 1.4.11 41 * @link http://pear.php.net/package/PEAR 42 * @since Class available since Release 1.4.0a1 43 */ 44 class PEAR_Dependency2 45 { 46 /** 47 * One of the PEAR_VALIDATE_* states 48 * @see PEAR_VALIDATE_NORMAL 49 * @var integer 50 */ 51 var $_state; 52 /** 53 * Command-line options to install/upgrade/uninstall commands 54 * @param array 55 */ 56 var $_options; 57 /** 58 * @var OS_Guess 59 */ 60 var $_os; 61 /** 62 * @var PEAR_Registry 63 */ 64 var $_registry; 65 /** 66 * @var PEAR_Config 67 */ 68 var $_config; 69 /** 70 * @var PEAR_DependencyDB 71 */ 72 var $_dependencydb; 73 /** 74 * Output of PEAR_Registry::parsedPackageName() 75 * @var array 76 */ 77 var $_currentPackage; 78 /** 79 * @param PEAR_Config 80 * @param array installation options 81 * @param array format of PEAR_Registry::parsedPackageName() 82 * @param int installation state (one of PEAR_VALIDATE_*) 83 */ 84 function PEAR_Dependency2(&$config, $installoptions, $package, 85 $state = PEAR_VALIDATE_INSTALLING) 86 { 87 $this->_config = &$config; 88 if (!class_exists('PEAR_DependencyDB')) { 89 require_once 'PEAR/DependencyDB.php'; 90 } 91 if (isset($installoptions['packagingroot'])) { 92 // make sure depdb is in the right location 93 $config->setInstallRoot($installoptions['packagingroot']); 94 } 95 $this->_registry = &$config->getRegistry(); 96 $this->_dependencydb = &PEAR_DependencyDB::singleton($config); 97 if (isset($installoptions['packagingroot'])) { 98 $config->setInstallRoot(false); 99 } 100 $this->_options = $installoptions; 101 $this->_state = $state; 102 if (!class_exists('OS_Guess')) { 103 require_once 'OS/Guess.php'; 104 } 105 $this->_os = new OS_Guess; 106 $this->_currentPackage = $package; 107 } 108 109 function _getExtraString($dep) 110 { 111 $extra = ' ('; 112 if (isset($dep['uri'])) { 113 return ''; 114 } 115 if (isset($dep['recommended'])) { 116 $extra .= 'recommended version ' . $dep['recommended']; 117 } else { 118 if (isset($dep['min'])) { 119 $extra .= 'version >= ' . $dep['min']; 120 } 121 if (isset($dep['max'])) { 122 if ($extra != ' (') { 123 $extra .= ', '; 124 } 125 $extra .= 'version <= ' . $dep['max']; 126 } 127 if (isset($dep['exclude'])) { 128 if (!is_array($dep['exclude'])) { 129 $dep['exclude'] = array($dep['exclude']); 130 } 131 if ($extra != ' (') { 132 $extra .= ', '; 133 } 134 $extra .= 'excluded versions: '; 135 foreach ($dep['exclude'] as $i => $exclude) { 136 if ($i) { 137 $extra .= ', '; 138 } 139 $extra .= $exclude; 140 } 141 } 142 } 143 $extra .= ')'; 144 if ($extra == ' ()') { 145 $extra = ''; 146 } 147 return $extra; 148 } 149 150 /** 151 * This makes unit-testing a heck of a lot easier 152 */ 153 function getPHP_OS() 154 { 155 return PHP_OS; 156 } 157 158 /** 159 * This makes unit-testing a heck of a lot easier 160 */ 161 function getsysname() 162 { 163 return $this->_os->getSysname(); 164 } 165 166 /** 167 * Specify a dependency on an OS. Use arch for detailed os/processor information 168 * 169 * There are two generic OS dependencies that will be the most common, unix and windows. 170 * Other options are linux, freebsd, darwin (OS X), sunos, irix, hpux, aix 171 */ 172 function validateOsDependency($dep) 173 { 174 if ($this->_state != PEAR_VALIDATE_INSTALLING && 175 $this->_state != PEAR_VALIDATE_DOWNLOADING) { 176 return true; 177 } 178 if (isset($dep['conflicts'])) { 179 $not = true; 180 } else { 181 $not = false; 182 } 183 if ($dep['name'] == '*') { 184 return true; 185 } 186 switch (strtolower($dep['name'])) { 187 case 'windows' : 188 if ($not) { 189 if (strtolower(substr($this->getPHP_OS(), 0, 3)) == 'win') { 190 if (!isset($this->_options['nodeps']) && 191 !isset($this->_options['force'])) { 192 return $this->raiseError("Cannot install %s on Windows"); 193 } else { 194 return $this->warning("warning: Cannot install %s on Windows"); 195 } 196 } 197 } else { 198 if (strtolower(substr($this->getPHP_OS(), 0, 3)) != 'win') { 199 if (!isset($this->_options['nodeps']) && 200 !isset($this->_options['force'])) { 201 return $this->raiseError("Can only install %s on Windows"); 202 } else { 203 return $this->warning("warning: Can only install %s on Windows"); 204 } 205 } 206 } 207 break; 208 case 'unix' : 209 $unices = array('linux', 'freebsd', 'darwin', 'sunos', 'irix', 'hpux', 'aix'); 210 if ($not) { 211 if (in_array($this->getSysname(), $unices)) { 212 if (!isset($this->_options['nodeps']) && 213 !isset($this->_options['force'])) { 214 return $this->raiseError("Cannot install %s on any Unix system"); 215 } else { 216 return $this->warning( 217 "warning: Cannot install %s on any Unix system"); 218 } 219 } 220 } else { 221 if (!in_array($this->getSysname(), $unices)) { 222 if (!isset($this->_options['nodeps']) && 223 !isset($this->_options['force'])) { 224 return $this->raiseError("Can only install %s on a Unix system"); 225 } else { 226 return $this->warning( 227 "warning: Can only install %s on a Unix system"); 228 } 229 } 230 } 231 break; 232 default : 233 if ($not) { 234 if (strtolower($dep['name']) == strtolower($this->getSysname())) { 235 if (!isset($this->_options['nodeps']) && 236 !isset($this->_options['force'])) { 237 return $this->raiseError('Cannot install %s on ' . $dep['name'] . 238 ' operating system'); 239 } else { 240 return $this->warning('warning: Cannot install %s on ' . 241 $dep['name'] . ' operating system'); 242 } 243 } 244 } else { 245 if (strtolower($dep['name']) != strtolower($this->getSysname())) { 246 if (!isset($this->_options['nodeps']) && 247 !isset($this->_options['force'])) { 248 return $this->raiseError('Cannot install %s on ' . 249 $this->getSysname() . 250 ' operating system, can only install on ' . $dep['name']); 251 } else { 252 return $this->warning('warning: Cannot install %s on ' . 253 $this->getSysname() . 254 ' operating system, can only install on ' . $dep['name']); 255 } 256 } 257 } 258 } 259 return true; 260 } 261 262 /** 263 * This makes unit-testing a heck of a lot easier 264 */ 265 function matchSignature($pattern) 266 { 267 return $this->_os->matchSignature($pattern); 268 } 269 270 /** 271 * Specify a complex dependency on an OS/processor/kernel version, 272 * Use OS for simple operating system dependency. 273 * 274 * This is the only dependency that accepts an eregable pattern. The pattern 275 * will be matched against the php_uname() output parsed by OS_Guess 276 */ 277 function validateArchDependency($dep) 278 { 279 if ($this->_state != PEAR_VALIDATE_INSTALLING) { 280 return true; 281 } 282 if (isset($dep['conflicts'])) { 283 $not = true; 284 } else { 285 $not = false; 286 } 287 if (!$this->matchSignature($dep['pattern'])) { 288 if (!$not) { 289 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 290 return $this->raiseError('%s Architecture dependency failed, does not ' . 291 'match "' . $dep['pattern'] . '"'); 292 } else { 293 return $this->warning('warning: %s Architecture dependency failed, does ' . 294 'not match "' . $dep['pattern'] . '"'); 295 } 296 } 297 return true; 298 } else { 299 if ($not) { 300 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 301 return $this->raiseError('%s Architecture dependency failed, required "' . 302 $dep['pattern'] . '"'); 303 } else { 304 return $this->warning('warning: %s Architecture dependency failed, ' . 305 'required "' . $dep['pattern'] . '"'); 306 } 307 } 308 return true; 309 } 310 } 311 312 /** 313 * This makes unit-testing a heck of a lot easier 314 */ 315 function extension_loaded($name) 316 { 317 return extension_loaded($name); 318 } 319 320 /** 321 * This makes unit-testing a heck of a lot easier 322 */ 323 function phpversion($name = null) 324 { 325 if ($name !== null) { 326 return phpversion($name); 327 } else { 328 return phpversion(); 329 } 330 } 331 332 function validateExtensionDependency($dep, $required = true) 333 { 334 if ($this->_state != PEAR_VALIDATE_INSTALLING && 335 $this->_state != PEAR_VALIDATE_DOWNLOADING) { 336 return true; 337 } 338 $loaded = $this->extension_loaded($dep['name']); 339 $extra = $this->_getExtraString($dep); 340 if (isset($dep['exclude'])) { 341 if (!is_array($dep['exclude'])) { 342 $dep['exclude'] = array($dep['exclude']); 343 } 344 } 345 if (!isset($dep['min']) && !isset($dep['max']) && 346 !isset($dep['recommended']) && !isset($dep['exclude'])) { 347 if ($loaded) { 348 if (isset($dep['conflicts'])) { 349 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 350 return $this->raiseError('%s conflicts with PHP extension "' . 351 $dep['name'] . '"' . $extra); 352 } else { 353 return $this->warning('warning: %s conflicts with PHP extension "' . 354 $dep['name'] . '"' . $extra); 355 } 356 } 357 return true; 358 } else { 359 if (isset($dep['conflicts'])) { 360 return true; 361 } 362 if ($required) { 363 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 364 return $this->raiseError('%s requires PHP extension "' . 365 $dep['name'] . '"' . $extra); 366 } else { 367 return $this->warning('warning: %s requires PHP extension "' . 368 $dep['name'] . '"' . $extra); 369 } 370 } else { 371 return $this->warning('%s can optionally use PHP extension "' . 372 $dep['name'] . '"' . $extra); 373 } 374 } 375 } 376 if (!$loaded) { 377 if (isset($dep['conflicts'])) { 378 return true; 379 } 380 if (!$required) { 381 return $this->warning('%s can optionally use PHP extension "' . 382 $dep['name'] . '"' . $extra); 383 } else { 384 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 385 return $this->raiseError('%s requires PHP extension "' . $dep['name'] . 386 '"' . $extra); 387 } 388 return $this->warning('warning: %s requires PHP extension "' . $dep['name'] . 389 '"' . $extra); 390 } 391 } 392 $version = (string) $this->phpversion($dep['name']); 393 if (empty($version)) { 394 $version = '0'; 395 } 396 $fail = false; 397 if (isset($dep['min'])) { 398 if (!version_compare($version, $dep['min'], '>=')) { 399 $fail = true; 400 } 401 } 402 if (isset($dep['max'])) { 403 if (!version_compare($version, $dep['max'], '<=')) { 404 $fail = true; 405 } 406 } 407 if ($fail && !isset($dep['conflicts'])) { 408 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 409 return $this->raiseError('%s requires PHP extension "' . $dep['name'] . 410 '"' . $extra . ', installed version is ' . $version); 411 } else { 412 return $this->warning('warning: %s requires PHP extension "' . $dep['name'] . 413 '"' . $extra . ', installed version is ' . $version); 414 } 415 } elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail && isset($dep['conflicts'])) { 416 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 417 return $this->raiseError('%s conflicts with PHP extension "' . 418 $dep['name'] . '"' . $extra . ', installed version is ' . $version); 419 } else { 420 return $this->warning('warning: %s conflicts with PHP extension "' . 421 $dep['name'] . '"' . $extra . ', installed version is ' . $version); 422 } 423 } 424 if (isset($dep['exclude'])) { 425 foreach ($dep['exclude'] as $exclude) { 426 if (version_compare($version, $exclude, '==')) { 427 if (isset($dep['conflicts'])) { 428 continue; 429 } 430 if (!isset($this->_options['nodeps']) && 431 !isset($this->_options['force'])) { 432 return $this->raiseError('%s is not compatible with PHP extension "' . 433 $dep['name'] . '" version ' . 434 $exclude); 435 } else { 436 return $this->warning('warning: %s is not compatible with PHP extension "' . 437 $dep['name'] . '" version ' . 438 $exclude); 439 } 440 } elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) { 441 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 442 return $this->raiseError('%s conflicts with PHP extension "' . 443 $dep['name'] . '"' . $extra . ', installed version is ' . $version); 444 } else { 445 return $this->warning('warning: %s conflicts with PHP extension "' . 446 $dep['name'] . '"' . $extra . ', installed version is ' . $version); 447 } 448 } 449 } 450 } 451 if (isset($dep['recommended'])) { 452 if (version_compare($version, $dep['recommended'], '==')) { 453 return true; 454 } else { 455 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 456 return $this->raiseError('%s dependency: PHP extension ' . $dep['name'] . 457 ' version "' . $version . '"' . 458 ' is not the recommended version "' . $dep['recommended'] . 459 '", but may be compatible, use --force to install'); 460 } else { 461 return $this->warning('warning: %s dependency: PHP extension ' . 462 $dep['name'] . ' version "' . $version . '"' . 463 ' is not the recommended version "' . $dep['recommended'].'"'); 464 } 465 } 466 } 467 return true; 468 } 469 470 function validatePhpDependency($dep) 471 { 472 if ($this->_state != PEAR_VALIDATE_INSTALLING && 473 $this->_state != PEAR_VALIDATE_DOWNLOADING) { 474 return true; 475 } 476 $version = $this->phpversion(); 477 $extra = $this->_getExtraString($dep); 478 if (isset($dep['exclude'])) { 479 if (!is_array($dep['exclude'])) { 480 $dep['exclude'] = array($dep['exclude']); 481 } 482 } 483 if (isset($dep['min'])) { 484 if (!version_compare($version, $dep['min'], '>=')) { 485 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 486 return $this->raiseError('%s requires PHP' . 487 $extra . ', installed version is ' . $version); 488 } else { 489 return $this->warning('warning: %s requires PHP' . 490 $extra . ', installed version is ' . $version); 491 } 492 } 493 } 494 if (isset($dep['max'])) { 495 if (!version_compare($version, $dep['max'], '<=')) { 496 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 497 return $this->raiseError('%s requires PHP' . 498 $extra . ', installed version is ' . $version); 499 } else { 500 return $this->warning('warning: %s requires PHP' . 501 $extra . ', installed version is ' . $version); 502 } 503 } 504 } 505 if (isset($dep['exclude'])) { 506 foreach ($dep['exclude'] as $exclude) { 507 if (version_compare($version, $exclude, '==')) { 508 if (!isset($this->_options['nodeps']) && 509 !isset($this->_options['force'])) { 510 return $this->raiseError('%s is not compatible with PHP version ' . 511 $exclude); 512 } else { 513 return $this->warning( 514 'warning: %s is not compatible with PHP version ' . 515 $exclude); 516 } 517 } 518 } 519 } 520 return true; 521 } 522 523 /** 524 * This makes unit-testing a heck of a lot easier 525 */ 526 function getPEARVersion() 527 { 528 return '1.4.11'; 529 } 530 531 function validatePearinstallerDependency($dep) 532 { 533 $pearversion = $this->getPEARVersion(); 534 $extra = $this->_getExtraString($dep); 535 if (isset($dep['exclude'])) { 536 if (!is_array($dep['exclude'])) { 537 $dep['exclude'] = array($dep['exclude']); 538 } 539 } 540 if (version_compare($pearversion, $dep['min'], '<')) { 541 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 542 return $this->raiseError('%s requires PEAR Installer' . $extra . 543 ', installed version is ' . $pearversion); 544 } else { 545 return $this->warning('warning: %s requires PEAR Installer' . $extra . 546 ', installed version is ' . $pearversion); 547 } 548 } 549 if (isset($dep['max'])) { 550 if (version_compare($pearversion, $dep['max'], '>')) { 551 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 552 return $this->raiseError('%s requires PEAR Installer' . $extra . 553 ', installed version is ' . $pearversion); 554 } else { 555 return $this->warning('warning: %s requires PEAR Installer' . $extra . 556 ', installed version is ' . $pearversion); 557 } 558 } 559 } 560 if (isset($dep['exclude'])) { 561 if (!isset($dep['exclude'][0])) { 562 $dep['exclude'] = array($dep['exclude']); 563 } 564 foreach ($dep['exclude'] as $exclude) { 565 if (version_compare($exclude, $pearversion, '==')) { 566 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 567 return $this->raiseError('%s is not compatible with PEAR Installer ' . 568 'version ' . $exclude); 569 } else { 570 return $this->warning('warning: %s is not compatible with PEAR ' . 571 'Installer version ' . $exclude); 572 } 573 } 574 } 575 } 576 return true; 577 } 578 579 function validateSubpackageDependency($dep, $required, $params) 580 { 581 return $this->validatePackageDependency($dep, $required, $params); 582 } 583 584 /** 585 * @param array dependency information (2.0 format) 586 * @param boolean whether this is a required dependency 587 * @param array a list of downloaded packages to be installed, if any 588 * @param boolean if true, then deps on pear.php.net that fail will also check 589 * against pecl.php.net packages to accomodate extensions that have 590 * moved to pecl.php.net from pear.php.net 591 */ 592 function validatePackageDependency($dep, $required, $params, $depv1 = false) 593 { 594 if ($this->_state != PEAR_VALIDATE_INSTALLING && 595 $this->_state != PEAR_VALIDATE_DOWNLOADING) { 596 return true; 597 } 598 if (isset($dep['providesextension'])) { 599 if ($this->extension_loaded($dep['providesextension'])) { 600 $save = $dep; 601 $subdep = $dep; 602 $subdep['name'] = $subdep['providesextension']; 603 PEAR::pushErrorHandling(PEAR_ERROR_RETURN); 604 $ret = $this->validateExtensionDependency($subdep, $required); 605 PEAR::popErrorHandling(); 606 if (!PEAR::isError($ret)) { 607 return true; 608 } 609 } 610 } 611 if ($this->_state == PEAR_VALIDATE_INSTALLING) { 612 return $this->_validatePackageInstall($dep, $required, $depv1); 613 } 614 if ($this->_state == PEAR_VALIDATE_DOWNLOADING) { 615 return $this->_validatePackageDownload($dep, $required, $params, $depv1); 616 } 617 } 618 619 function _validatePackageDownload($dep, $required, $params, $depv1 = false) 620 { 621 $dep['package'] = $dep['name']; 622 if (isset($dep['uri'])) { 623 $dep['channel'] = '__uri'; 624 } 625 $depname = $this->_registry->parsedPackageNameToString($dep, true); 626 $found = false; 627 foreach ($params as $param) { 628 if ($param->isEqual( 629 array('package' => $dep['name'], 630 'channel' => $dep['channel']))) { 631 $found = true; 632 break; 633 } 634 if ($depv1 && $dep['channel'] == 'pear.php.net') { 635 if ($param->isEqual( 636 array('package' => $dep['name'], 637 'channel' => 'pecl.php.net'))) { 638 $found = true; 639 break; 640 } 641 } 642 } 643 if (!$found && isset($dep['providesextension'])) { 644 foreach ($params as $param) { 645 if ($param->isExtension($dep['providesextension'])) { 646 $found = true; 647 break; 648 } 649 } 650 } 651 if ($found) { 652 $version = $param->getVersion(); 653 $installed = false; 654 $downloaded = true; 655 } else { 656 if ($this->_registry->packageExists($dep['name'], $dep['channel'])) { 657 $installed = true; 658 $downloaded = false; 659 $version = $this->_registry->packageinfo($dep['name'], 'version', 660 $dep['channel']); 661 } else { 662 if ($dep['channel'] == 'pecl.php.net' && $this->_registry->packageExists($dep['name'], 663 'pear.php.net')) { 664 $installed = true; 665 $downloaded = false; 666 $version = $this->_registry->packageinfo($dep['name'], 'version', 667 'pear.php.net'); 668 } else { 669 $version = 'not installed or downloaded'; 670 $installed = false; 671 $downloaded = false; 672 } 673 } 674 } 675 $extra = $this->_getExtraString($dep); 676 if (isset($dep['exclude'])) { 677 if (!is_array($dep['exclude'])) { 678 $dep['exclude'] = array($dep['exclude']); 679 } 680 } 681 if (!isset($dep['min']) && !isset($dep['max']) && 682 !isset($dep['recommended']) && !isset($dep['exclude'])) { 683 if ($installed || $downloaded) { 684 $installed = $installed ? 'installed' : 'downloaded'; 685 if (isset($dep['conflicts'])) { 686 if ($version) { 687 $rest = ", $installed version is " . $version; 688 } else { 689 $rest = ''; 690 } 691 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 692 return $this->raiseError('%s conflicts with package "' . $depname . '"' . 693 $extra . $rest); 694 } else { 695 return $this->warning('warning: %s conflicts with package "' . $depname . '"' . 696 $extra . $rest); 697 } 698 } 699 return true; 700 } else { 701 if (isset($dep['conflicts'])) { 702 return true; 703 } 704 if ($required) { 705 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 706 return $this->raiseError('%s requires package "' . $depname . '"' . 707 $extra); 708 } else { 709 return $this->warning('warning: %s requires package "' . $depname . '"' . 710 $extra); 711 } 712 } else { 713 return $this->warning('%s can optionally use package "' . $depname . '"' . 714 $extra); 715 } 716 } 717 } 718 if (!$installed && !$downloaded) { 719 if (isset($dep['conflicts'])) { 720 return true; 721 } 722 if ($required) { 723 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 724 return $this->raiseError('%s requires package "' . $depname . '"' . 725 $extra); 726 } else { 727 return $this->warning('warning: %s requires package "' . $depname . '"' . 728 $extra); 729 } 730 } else { 731 return $this->warning('%s can optionally use package "' . $depname . '"' . 732 $extra); 733 } 734 } 735 $fail = false; 736 if (isset($dep['min'])) { 737 if (version_compare($version, $dep['min'], '<')) { 738 $fail = true; 739 } 740 } 741 if (isset($dep['max'])) { 742 if (version_compare($version, $dep['max'], '>')) { 743 $fail = true; 744 } 745 } 746 if ($fail && !isset($dep['conflicts'])) { 747 $installed = $installed ? 'installed' : 'downloaded'; 748 $dep['package'] = $dep['name']; 749 $dep = $this->_registry->parsedPackageNameToString($dep, true); 750 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 751 return $this->raiseError('%s requires package "' . $depname . '"' . 752 $extra . ", $installed version is " . $version); 753 } else { 754 return $this->warning('warning: %s requires package "' . $depname . '"' . 755 $extra . ", $installed version is " . $version); 756 } 757 } elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail && 758 isset($dep['conflicts']) && !isset($dep['exclude'])) { 759 $installed = $installed ? 'installed' : 'downloaded'; 760 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 761 return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra . 762 ", $installed version is " . $version); 763 } else { 764 return $this->warning('warning: %s conflicts with package "' . $depname . '"' . 765 $extra . ", $installed version is " . $version); 766 } 767 } 768 if (isset($dep['exclude'])) { 769 $installed = $installed ? 'installed' : 'downloaded'; 770 foreach ($dep['exclude'] as $exclude) { 771 if (version_compare($version, $exclude, '==') && !isset($dep['conflicts'])) { 772 if (!isset($this->_options['nodeps']) && 773 !isset($this->_options['force'])) { 774 return $this->raiseError('%s is not compatible with ' . 775 $installed . ' package "' . 776 $depname . '" version ' . 777 $exclude); 778 } else { 779 return $this->warning('warning: %s is not compatible with ' . 780 $installed . ' package "' . 781 $depname . '" version ' . 782 $exclude); 783 } 784 } elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) { 785 $installed = $installed ? 'installed' : 'downloaded'; 786 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 787 return $this->raiseError('%s conflicts with package "' . $depname . '"' . 788 $extra . ", $installed version is " . $version); 789 } else { 790 return $this->warning('warning: %s conflicts with package "' . $depname . '"' . 791 $extra . ", $installed version is " . $version); 792 } 793 } 794 } 795 } 796 if (isset($dep['recommended'])) { 797 $installed = $installed ? 'installed' : 'downloaded'; 798 if (version_compare($version, $dep['recommended'], '==')) { 799 return true; 800 } else { 801 if (!$found && $installed) { 802 $param = $this->_registry->getPackage($dep['name'], $dep['channel']); 803 } 804 if ($param) { 805 $found = false; 806 foreach ($params as $parent) { 807 if ($parent->isEqual($this->_currentPackage)) { 808 $found = true; 809 break; 810 } 811 } 812 if ($found) { 813 if ($param->isCompatible($parent)) { 814 return true; 815 } 816 } else { // this is for validPackage() calls 817 $parent = $this->_registry->getPackage($this->_currentPackage['package'], 818 $this->_currentPackage['channel']); 819 if ($parent !== null) { 820 if ($param->isCompatible($parent)) { 821 return true; 822 } 823 } 824 } 825 } 826 if (!isset($this->_options['nodeps']) && !isset($this->_options['force']) && 827 !isset($this->_options['loose'])) { 828 return $this->raiseError('%s dependency package "' . $depname . 829 '" ' . $installed . ' version ' . $version . 830 ' is not the recommended version ' . $dep['recommended'] . 831 ', but may be compatible, use --force to install'); 832 } else { 833 return $this->warning('warning: %s dependency package "' . $depname . 834 '" ' . $installed . ' version ' . $version . 835 ' is not the recommended version ' . $dep['recommended']); 836 } 837 } 838 } 839 return true; 840 } 841 842 function _validatePackageInstall($dep, $required, $depv1 = false) 843 { 844 return $this->_validatePackageDownload($dep, $required, array(), $depv1); 845 } 846 847 /** 848 * Verify that uninstalling packages passed in to command line is OK. 849 * 850 * @param PEAR_Installer $dl 851 * @return PEAR_Error|true 852 */ 853 function validatePackageUninstall(&$dl) 854 { 855 if (PEAR::isError($this->_dependencydb)) { 856 return $this->_dependencydb; 857 } 858 $params = array(); 859 // construct an array of "downloaded" packages to fool the package dependency checker 860 // into using these to validate uninstalls of circular dependencies 861 $downloaded = &$dl->getUninstallPackages(); 862 foreach ($downloaded as $i => $pf) { 863 if (!class_exists('PEAR_Downloader_Package')) { 864 require_once 'PEAR/Downloader/Package.php'; 865 } 866 $dp = &new PEAR_Downloader_Package($dl); 867 $dp->setPackageFile($downloaded[$i]); 868 $params[$i] = &$dp; 869 } 870 $deps = $this->_dependencydb->getDependentPackageDependencies($this->_currentPackage); 871 $fail = false; 872 if ($deps) { 873 foreach ($deps as $channel => $info) { 874 foreach ($info as $package => $ds) { 875 foreach ($ds as $d) { 876 $d['dep']['package'] = $d['dep']['name']; 877 $checker = &new PEAR_Dependency2($this->_config, $this->_options, 878 array('channel' => $channel, 'package' => $package), $this->_state); 879 $dep = $d['dep']; 880 $required = $d['type'] == 'required'; 881 $ret = $checker->_validatePackageUninstall($dep, $required, $params, $dl); 882 if (is_array($ret)) { 883 $dl->log(0, $ret[0]); 884 } elseif (PEAR::isError($ret)) { 885 $dl->log(0, $ret->getMessage()); 886 $fail = true; 887 } 888 } 889 } 890 } 891 } 892 if ($fail) { 893 if (isset($this->_options['nodeps']) || isset($this->_options['force'])) { 894 return $this->warning( 895 'warning: %s should not be uninstalled, other installed packages depend ' . 896 'on this package'); 897 } else { 898 return $this->raiseError( 899 '%s cannot be uninstalled, other installed packages depend on this package'); 900 } 901 } 902 return true; 903 } 904 905 function _validatePackageUninstall($dep, $required, $params, &$dl) 906 { 907 $dep['package'] = $dep['name']; 908 $depname = $this->_registry->parsedPackageNameToString($dep, true); 909 $found = false; 910 foreach ($params as $param) { 911 if ($param->isEqual($this->_currentPackage)) { 912 $found = true; 913 break; 914 } 915 } 916 $version = $this->_registry->packageinfo($dep['name'], 'version', 917 $dep['channel']); 918 if (!$version) { 919 return true; 920 } 921 $extra = $this->_getExtraString($dep); 922 if (isset($dep['exclude'])) { 923 if (!is_array($dep['exclude'])) { 924 $dep['exclude'] = array($dep['exclude']); 925 } 926 } 927 if (isset($dep['conflicts'])) { 928 return true; // uninstall OK - these packages conflict (probably installed with --force) 929 } 930 if (!isset($dep['min']) && !isset($dep['max'])) { 931 if ($required) { 932 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 933 return $this->raiseError('%s' . $extra . ' is required by installed package "' . 934 $depname . '"'); 935 } else { 936 return $this->warning('warning: %s' . $extra . 937 ' is required by installed package "' . $depname . '"'); 938 } 939 } else { 940 return $this->warning('%s' . $extra . 941 ' can be optionally used by installed package "' . $depname . '"'); 942 } 943 } 944 $fail = false; 945 if (isset($dep['min'])) { 946 if (version_compare($version, $dep['min'], '>=')) { 947 $fail = true; 948 } 949 } 950 if (isset($dep['max'])) { 951 if (version_compare($version, $dep['max'], '<=')) { 952 $fail = true; 953 } 954 } 955 if ($fail) { 956 if ($found) { 957 if (!isset($dl->___checked[$this->_currentPackage['channel']] 958 [$this->_currentPackage['package']])) { 959 $dl->___checked[$this->_currentPackage['channel']] 960 [$this->_currentPackage['package']] = true; 961 $deps = $this->_dependencydb->getDependentPackageDependencies( 962 $this->_currentPackage); 963 if ($deps) { 964 foreach ($deps as $channel => $info) { 965 foreach ($info as $package => $ds) { 966 foreach ($ds as $d) { 967 $d['dep']['package'] = $d['dep']['name']; 968 $checker = &new PEAR_Dependency2($this->_config, $this->_options, 969 array('channel' => $channel, 'package' => $package), 970 $this->_state); 971 $dep = $d['dep']; 972 $required = $d['type'] == 'required'; 973 $ret = $checker->_validatePackageUninstall($dep, $required, $params, 974 $dl); 975 if (PEAR::isError($ret)) { 976 $fail = true; 977 break 3; 978 } 979 } 980 } 981 $fail = false; 982 } 983 } 984 } else { 985 return true; 986 } 987 } 988 if (!$fail) { 989 return true; 990 } 991 if ($required) { 992 if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { 993 return $this->raiseError($depname . $extra . ' is required by installed package' . 994 ' "%s"'); 995 } else { 996 return $this->warning('warning: ' . $depname . $extra . 997 ' is required by installed package "%s"'); 998 } 999 } else { 1000 return $this->warning($depname . $extra . ' can be optionally used by installed package' . 1001 ' "%s"'); 1002 } 1003 } 1004 return true; 1005 } 1006 1007 /** 1008 * validate a downloaded package against installed packages 1009 * 1010 * As of PEAR 1.4.3, this will only validate 1011 * 1012 * @param array|PEAR_Downloader_Package|PEAR_PackageFile_v1|PEAR_PackageFile_v2 1013 * $pkg package identifier (either 1014 * array('package' => blah, 'channel' => blah) or an array with 1015 * index 'info' referencing an object) 1016 * @param PEAR_Downloader $dl 1017 * @param array $params full list of packages to install 1018 * @return true|PEAR_Error 1019 */ 1020 function validatePackage($pkg, &$dl, $params = array()) 1021 { 1022 if (is_array($pkg) && isset($pkg['info'])) { 1023 $deps = $this->_dependencydb->getDependentPackageDependencies($pkg['info']); 1024 } else { 1025 $deps = $this->_dependencydb->getDependentPackageDependencies($pkg); 1026 } 1027 $fail = false; 1028 if ($deps) { 1029 if (!class_exists('PEAR_Downloader_Package')) { 1030 require_once 'PEAR/Downloader/Package.php'; 1031 } 1032 $dp = &new PEAR_Downloader_Package($dl); 1033 if (is_object($pkg)) { 1034 $dp->setPackageFile($pkg); 1035 } else { 1036 $dp->setDownloadURL($pkg); 1037 } 1038 PEAR::pushErrorHandling(PEAR_ERROR_RETURN); 1039 foreach ($deps as $channel => $info) { 1040 foreach ($info as $package => $ds) { 1041 foreach ($params as $packd) { 1042 if (strtolower($packd->getPackage()) == strtolower($package) && 1043 $packd->getChannel() == $channel) { 1044 $dl->log(3, 'skipping installed package check of "' . 1045 $this->_registry->parsedPackageNameToString( 1046 array('channel' => $channel, 'package' => $package), 1047 true) . 1048 '", version "' . $packd->getVersion() . '" will be ' . 1049 'downloaded and installed'); 1050 continue 2; // jump to next package 1051 } 1052 } 1053 foreach ($ds as $d) { 1054 $checker = &new PEAR_Dependency2($this->_config, $this->_options, 1055 array('channel' => $channel, 'package' => $package), $this->_state); 1056 $dep = $d['dep']; 1057 $required = $d['type'] == 'required'; 1058 $ret = $checker->_validatePackageDownload($dep, $required, array(&$dp)); 1059 if (is_array($ret)) { 1060 $dl->log(0, $ret[0]); 1061 } elseif (PEAR::isError($ret)) { 1062 $dl->log(0, $ret->getMessage()); 1063 $fail = true; 1064 } 1065 } 1066 } 1067 } 1068 PEAR::popErrorHandling(); 1069 } 1070 if ($fail) { 1071 return $this->raiseError( 1072 '%s cannot be installed, conflicts with installed packages'); 1073 } 1074 return true; 1075 } 1076 1077 /** 1078 * validate a package.xml 1.0 dependency 1079 */ 1080 function validateDependency1($dep, $params = array()) 1081 { 1082 if (!isset($dep['optional'])) { 1083 $dep['optional'] = 'no'; 1084 } 1085 list($newdep, $type) = $this->normalizeDep($dep); 1086 if (!$newdep) { 1087 return $this->raiseError("Invalid Dependency"); 1088 } 1089 if (method_exists($this, "validate{$type}Dependency")) { 1090 return $this->{"validate{$type}Dependency"}($newdep, $dep['optional'] == 'no', 1091 $params, true); 1092 } 1093 } 1094 1095 /** 1096 * Convert a 1.0 dep into a 2.0 dep 1097 */ 1098 function normalizeDep($dep) 1099 { 1100 $types = array( 1101 'pkg' => 'Package', 1102 'ext' => 'Extension', 1103 'os' => 'Os', 1104 'php' => 'Php' 1105 ); 1106 if (isset($types[$dep['type']])) { 1107 $type = $types[$dep['type']]; 1108 } else { 1109 return array(false, false); 1110 } 1111 $newdep = array(); 1112 switch ($type) { 1113 case 'Package' : 1114 $newdep['channel'] = 'pear.php.net'; 1115 case 'Extension' : 1116 case 'Os' : 1117 $newdep['name'] = $dep['name']; 1118 break; 1119 } 1120 $dep['rel'] = PEAR_Dependency2::signOperator($dep['rel']); 1121 switch ($dep['rel']) { 1122 case 'has' : 1123 return array($newdep, $type); 1124 break; 1125 case 'not' : 1126 $newdep['conflicts'] = true; 1127 break; 1128 case '>=' : 1129 case '>' : 1130 $newdep['min'] = $dep['version']; 1131 if ($dep['rel'] == '>') { 1132 $newdep['exclude'] = $dep['version']; 1133 } 1134 break; 1135 case '<=' : 1136 case '<' : 1137 $newdep['max'] = $dep['version']; 1138 if ($dep['rel'] == '<') { 1139 $newdep['exclude'] = $dep['version']; 1140 } 1141 break; 1142 case 'ne' : 1143 case '!=' : 1144 $newdep['min'] = '0'; 1145 $newdep['max'] = '100000'; 1146 $newdep['exclude'] = $dep['version']; 1147 break; 1148 case '==' : 1149 $newdep['min'] = $dep['version']; 1150 $newdep['max'] = $dep['version']; 1151 break; 1152 } 1153 if ($type == 'Php') { 1154 if (!isset($newdep['min'])) { 1155 $newdep['min'] = '4.2.0'; 1156 } 1157 if (!isset($newdep['max'])) { 1158 $newdep['max'] = '6.0.0'; 1159 } 1160 } 1161 return array($newdep, $type); 1162 } 1163 1164 /** 1165 * Converts text comparing operators to them sign equivalents 1166 * 1167 * Example: 'ge' to '>=' 1168 * 1169 * @access public 1170 * @param string Operator 1171 * @return string Sign equivalent 1172 */ 1173 function signOperator($operator) 1174 { 1175 switch($operator) { 1176 case 'lt': return '<'; 1177 case 'le': return '<='; 1178 case 'gt': return '>'; 1179 case 'ge': return '>='; 1180 case 'eq': return '=='; 1181 case 'ne': return '!='; 1182 default: 1183 return $operator; 1184 } 1185 } 1186 1187 function raiseError($msg) 1188 { 1189 if (isset($this->_options['ignore-errors'])) { 1190 return $this->warning($msg); 1191 } 1192 return PEAR::raiseError(sprintf($msg, $this->_registry->parsedPackageNameToString( 1193 $this->_currentPackage, true))); 1194 } 1195 1196 function warning($msg) 1197 { 1198 return array(sprintf($msg, $this->_registry->parsedPackageNameToString( 1199 $this->_currentPackage, true))); 1200 } 1201 } 1202 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Wed Nov 21 12:27:40 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |