| [ Index ] |
|
Code source de PHP PEAR 1.4.5 |
1 <?php 2 /** 3 * PEAR_PackageFile_v2, package.xml version 2.0 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: v2.php,v 1.135 2006/10/31 02:54:41 cellog Exp $ 19 * @link http://pear.php.net/package/PEAR 20 * @since File available since Release 1.4.0a1 21 */ 22 /** 23 * For error handling 24 */ 25 require_once 'PEAR/ErrorStack.php'; 26 /** 27 * @category pear 28 * @package PEAR 29 * @author Greg Beaver <cellog@php.net> 30 * @copyright 1997-2006 The PHP Group 31 * @license http://www.php.net/license/3_0.txt PHP License 3.0 32 * @version Release: 1.5.0 33 * @link http://pear.php.net/package/PEAR 34 * @since Class available since Release 1.4.0a1 35 */ 36 class PEAR_PackageFile_v2 37 { 38 39 /** 40 * Parsed package information 41 * @var array 42 * @access private 43 */ 44 var $_packageInfo = array(); 45 46 /** 47 * path to package .tgz or false if this is a local/extracted package.xml 48 * @var string|false 49 * @access private 50 */ 51 var $_archiveFile; 52 53 /** 54 * path to package .xml or false if this is an abstract parsed-from-string xml 55 * @var string|false 56 * @access private 57 */ 58 var $_packageFile; 59 60 /** 61 * This is used by file analysis routines to log progress information 62 * @var PEAR_Common 63 * @access protected 64 */ 65 var $_logger; 66 67 /** 68 * This is set to the highest validation level that has been validated 69 * 70 * If the package.xml is invalid or unknown, this is set to 0. If 71 * normal validation has occurred, this is set to PEAR_VALIDATE_NORMAL. If 72 * downloading/installation validation has occurred it is set to PEAR_VALIDATE_DOWNLOADING 73 * or INSTALLING, and so on up to PEAR_VALIDATE_PACKAGING. This allows validation 74 * "caching" to occur, which is particularly important for package validation, so 75 * that PHP files are not validated twice 76 * @var int 77 * @access private 78 */ 79 var $_isValid = 0; 80 81 /** 82 * True if the filelist has been validated 83 * @param bool 84 */ 85 var $_filesValid = false; 86 87 /** 88 * @var PEAR_Registry 89 * @access protected 90 */ 91 var $_registry; 92 93 /** 94 * @var PEAR_Config 95 * @access protected 96 */ 97 var $_config; 98 99 /** 100 * Optional Dependency group requested for installation 101 * @var string 102 * @access private 103 */ 104 var $_requestedGroup = false; 105 106 /** 107 * @var PEAR_ErrorStack 108 * @access protected 109 */ 110 var $_stack; 111 112 /** 113 * Namespace prefix used for tasks in this package.xml - use tasks: whenever possible 114 */ 115 var $_tasksNs; 116 117 /** 118 * Determines whether this packagefile was initialized only with partial package info 119 * 120 * If this package file was constructed via parsing REST, it will only contain 121 * 122 * - package name 123 * - channel name 124 * - dependencies 125 * @var boolean 126 * @access private 127 */ 128 var $_incomplete = true; 129 130 /** 131 * @var PEAR_PackageFile_v2_Validator 132 */ 133 var $_v2Validator; 134 135 /** 136 * The constructor merely sets up the private error stack 137 */ 138 function PEAR_PackageFile_v2() 139 { 140 $this->_stack = new PEAR_ErrorStack('PEAR_PackageFile_v2', false, null); 141 $this->_isValid = false; 142 } 143 144 /** 145 * To make unit-testing easier 146 * @param PEAR_Frontend_* 147 * @param array options 148 * @param PEAR_Config 149 * @return PEAR_Downloader 150 * @access protected 151 */ 152 function &getPEARDownloader(&$i, $o, &$c) 153 { 154 $z = &new PEAR_Downloader($i, $o, $c); 155 return $z; 156 } 157 158 /** 159 * To make unit-testing easier 160 * @param PEAR_Config 161 * @param array options 162 * @param array package name as returned from {@link PEAR_Registry::parsePackageName()} 163 * @param int PEAR_VALIDATE_* constant 164 * @return PEAR_Dependency2 165 * @access protected 166 */ 167 function &getPEARDependency2(&$c, $o, $p, $s = PEAR_VALIDATE_INSTALLING) 168 { 169 if (!class_exists('PEAR_Dependency2')) { 170 require_once 'PEAR/Dependency2.php'; 171 } 172 $z = &new PEAR_Dependency2($c, $o, $p, $s); 173 return $z; 174 } 175 176 function getInstalledBinary() 177 { 178 return isset($this->_packageInfo['#binarypackage']) ? $this->_packageInfo['#binarypackage'] : 179 false; 180 } 181 182 /** 183 * Installation of source package has failed, attempt to download and install the 184 * binary version of this package. 185 * @param PEAR_Installer 186 * @return array|false 187 */ 188 function installBinary(&$installer) 189 { 190 if (!OS_WINDOWS) { 191 $a = false; 192 return $a; 193 } 194 if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') { 195 $releasetype = $this->getPackageType() . 'release'; 196 if (!is_array($installer->getInstallPackages())) { 197 $a = false; 198 return $a; 199 } 200 foreach ($installer->getInstallPackages() as $p) { 201 if ($p->isExtension($this->_packageInfo['providesextension'])) { 202 if ($p->getPackageType() != 'extsrc' && $p->getPackageType() != 'zendextsrc') { 203 $a = false; 204 return $a; // the user probably downloaded it separately 205 } 206 } 207 } 208 if (isset($this->_packageInfo[$releasetype]['binarypackage'])) { 209 $installer->log(0, 'Attempting to download binary version of extension "' . 210 $this->_packageInfo['providesextension'] . '"'); 211 $params = $this->_packageInfo[$releasetype]['binarypackage']; 212 if (!is_array($params) || !isset($params[0])) { 213 $params = array($params); 214 } 215 if (isset($this->_packageInfo['channel'])) { 216 foreach ($params as $i => $param) { 217 $params[$i] = array('channel' => $this->_packageInfo['channel'], 218 'package' => $param, 'version' => $this->getVersion()); 219 } 220 } 221 $dl = &$this->getPEARDownloader($installer->ui, $installer->getOptions(), 222 $installer->config); 223 $verbose = $dl->config->get('verbose'); 224 $dl->config->set('verbose', -1); 225 foreach ($params as $param) { 226 PEAR::pushErrorHandling(PEAR_ERROR_RETURN); 227 $ret = $dl->download(array($param)); 228 PEAR::popErrorHandling(); 229 if (is_array($ret) && count($ret)) { 230 break; 231 } 232 } 233 $dl->config->set('verbose', $verbose); 234 if (is_array($ret)) { 235 if (count($ret) == 1) { 236 $pf = $ret[0]->getPackageFile(); 237 PEAR::pushErrorHandling(PEAR_ERROR_RETURN); 238 $err = $installer->install($ret[0]); 239 PEAR::popErrorHandling(); 240 if (is_array($err)) { 241 $this->_packageInfo['#binarypackage'] = $ret[0]->getPackage(); 242 // "install" self, so all dependencies will work transparently 243 $this->_registry->addPackage2($this); 244 $installer->log(0, 'Download and install of binary extension "' . 245 $this->_registry->parsedPackageNameToString( 246 array('channel' => $pf->getChannel(), 247 'package' => $pf->getPackage()), true) . '" successful'); 248 $a = array($ret[0], $err); 249 return $a; 250 } 251 $installer->log(0, 'Download and install of binary extension "' . 252 $this->_registry->parsedPackageNameToString( 253 array('channel' => $pf->getChannel(), 254 'package' => $pf->getPackage()), true) . '" failed'); 255 } 256 } 257 } 258 } 259 $a = false; 260 return $a; 261 } 262 263 /** 264 * @return string|false Extension name 265 */ 266 function getProvidesExtension() 267 { 268 if (in_array($this->getPackageType(), 269 array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) { 270 if (isset($this->_packageInfo['providesextension'])) { 271 return $this->_packageInfo['providesextension']; 272 } 273 } 274 return false; 275 } 276 277 /** 278 * @param string Extension name 279 * @return bool 280 */ 281 function isExtension($extension) 282 { 283 if (in_array($this->getPackageType(), 284 array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) { 285 return $this->_packageInfo['providesextension'] == $extension; 286 } 287 return false; 288 } 289 290 /** 291 * Tests whether every part of the package.xml 1.0 is represented in 292 * this package.xml 2.0 293 * @param PEAR_PackageFile_v1 294 * @return bool 295 */ 296 function isEquivalent($pf1) 297 { 298 if (!$pf1) { 299 return true; 300 } 301 if ($this->getPackageType() == 'bundle') { 302 return false; 303 } 304 $this->_stack->getErrors(true); 305 if (!$pf1->validate(PEAR_VALIDATE_NORMAL)) { 306 return false; 307 } 308 $pass = true; 309 if ($pf1->getPackage() != $this->getPackage()) { 310 $this->_differentPackage($pf1->getPackage()); 311 $pass = false; 312 } 313 if ($pf1->getVersion() != $this->getVersion()) { 314 $this->_differentVersion($pf1->getVersion()); 315 $pass = false; 316 } 317 if (trim($pf1->getSummary()) != $this->getSummary()) { 318 $this->_differentSummary($pf1->getSummary()); 319 $pass = false; 320 } 321 if (preg_replace('/\s+/', '', $pf1->getDescription()) != 322 preg_replace('/\s+/', '', $this->getDescription())) { 323 $this->_differentDescription($pf1->getDescription()); 324 $pass = false; 325 } 326 if ($pf1->getState() != $this->getState()) { 327 $this->_differentState($pf1->getState()); 328 $pass = false; 329 } 330 if (!strstr(preg_replace('/\s+/', '', $this->getNotes()), 331 preg_replace('/\s+/', '', $pf1->getNotes()))) { 332 $this->_differentNotes($pf1->getNotes()); 333 $pass = false; 334 } 335 $mymaintainers = $this->getMaintainers(); 336 $yourmaintainers = $pf1->getMaintainers(); 337 for ($i1 = 0; $i1 < count($yourmaintainers); $i1++) { 338 $reset = false; 339 for ($i2 = 0; $i2 < count($mymaintainers); $i2++) { 340 if ($mymaintainers[$i2]['handle'] == $yourmaintainers[$i1]['handle']) { 341 if ($mymaintainers[$i2]['role'] != $yourmaintainers[$i1]['role']) { 342 $this->_differentRole($mymaintainers[$i2]['handle'], 343 $yourmaintainers[$i1]['role'], $mymaintainers[$i2]['role']); 344 $pass = false; 345 } 346 if ($mymaintainers[$i2]['email'] != $yourmaintainers[$i1]['email']) { 347 $this->_differentEmail($mymaintainers[$i2]['handle'], 348 $yourmaintainers[$i1]['email'], $mymaintainers[$i2]['email']); 349 $pass = false; 350 } 351 if ($mymaintainers[$i2]['name'] != $yourmaintainers[$i1]['name']) { 352 $this->_differentName($mymaintainers[$i2]['handle'], 353 $yourmaintainers[$i1]['name'], $mymaintainers[$i2]['name']); 354 $pass = false; 355 } 356 unset($mymaintainers[$i2]); 357 $mymaintainers = array_values($mymaintainers); 358 unset($yourmaintainers[$i1]); 359 $yourmaintainers = array_values($yourmaintainers); 360 $reset = true; 361 break; 362 } 363 } 364 if ($reset) { 365 $i1 = -1; 366 } 367 } 368 $this->_unmatchedMaintainers($mymaintainers, $yourmaintainers); 369 $filelist = $this->getFilelist(); 370 foreach ($pf1->getFilelist() as $file => $atts) { 371 if (!isset($filelist[$file])) { 372 $this->_missingFile($file); 373 $pass = false; 374 } 375 } 376 return $pass; 377 } 378 379 function _differentPackage($package) 380 { 381 $this->_stack->push(__FUNCTION__, 'error', array('package' => $package, 382 'self' => $this->getPackage()), 383 'package.xml 1.0 package "%package%" does not match "%self%"'); 384 } 385 386 function _differentVersion($version) 387 { 388 $this->_stack->push(__FUNCTION__, 'error', array('version' => $version, 389 'self' => $this->getVersion()), 390 'package.xml 1.0 version "%version%" does not match "%self%"'); 391 } 392 393 function _differentState($state) 394 { 395 $this->_stack->push(__FUNCTION__, 'error', array('state' => $state, 396 'self' => $this->getState()), 397 'package.xml 1.0 state "%state%" does not match "%self%"'); 398 } 399 400 function _differentRole($handle, $role, $selfrole) 401 { 402 $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle, 403 'role' => $role, 'self' => $selfrole), 404 'package.xml 1.0 maintainer "%handle%" role "%role%" does not match "%self%"'); 405 } 406 407 function _differentEmail($handle, $email, $selfemail) 408 { 409 $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle, 410 'email' => $email, 'self' => $selfemail), 411 'package.xml 1.0 maintainer "%handle%" email "%email%" does not match "%self%"'); 412 } 413 414 function _differentName($handle, $name, $selfname) 415 { 416 $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle, 417 'name' => $name, 'self' => $selfname), 418 'package.xml 1.0 maintainer "%handle%" name "%name%" does not match "%self%"'); 419 } 420 421 function _unmatchedMaintainers($my, $yours) 422 { 423 if ($my) { 424 array_walk($my, create_function('&$i, $k', '$i = $i["handle"];')); 425 $this->_stack->push(__FUNCTION__, 'error', array('handles' => $my), 426 'package.xml 2.0 has unmatched extra maintainers "%handles%"'); 427 } 428 if ($yours) { 429 array_walk($yours, create_function('&$i, $k', '$i = $i["handle"];')); 430 $this->_stack->push(__FUNCTION__, 'error', array('handles' => $yours), 431 'package.xml 1.0 has unmatched extra maintainers "%handles%"'); 432 } 433 } 434 435 function _differentNotes($notes) 436 { 437 $truncnotes = strlen($notes) < 25 ? $notes : substr($notes, 0, 24) . '...'; 438 $truncmynotes = strlen($this->getNotes()) < 25 ? $this->getNotes() : 439 substr($this->getNotes(), 0, 24) . '...'; 440 $this->_stack->push(__FUNCTION__, 'error', array('notes' => $truncnotes, 441 'self' => $truncmynotes), 442 'package.xml 1.0 release notes "%notes%" do not match "%self%"'); 443 } 444 445 function _differentSummary($summary) 446 { 447 $truncsummary = strlen($summary) < 25 ? $summary : substr($summary, 0, 24) . '...'; 448 $truncmysummary = strlen($this->getsummary()) < 25 ? $this->getSummary() : 449 substr($this->getsummary(), 0, 24) . '...'; 450 $this->_stack->push(__FUNCTION__, 'error', array('summary' => $truncsummary, 451 'self' => $truncmysummary), 452 'package.xml 1.0 summary "%summary%" does not match "%self%"'); 453 } 454 455 function _differentDescription($description) 456 { 457 $truncdescription = trim(strlen($description) < 25 ? $description : substr($description, 0, 24) . '...'); 458 $truncmydescription = trim(strlen($this->getDescription()) < 25 ? $this->getDescription() : 459 substr($this->getdescription(), 0, 24) . '...'); 460 $this->_stack->push(__FUNCTION__, 'error', array('description' => $truncdescription, 461 'self' => $truncmydescription), 462 'package.xml 1.0 description "%description%" does not match "%self%"'); 463 } 464 465 function _missingFile($file) 466 { 467 $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), 468 'package.xml 1.0 file "%file%" is not present in <contents>'); 469 } 470 471 /** 472 * WARNING - do not use this function unless you know what you're doing 473 */ 474 function setRawState($state) 475 { 476 $this->_packageInfo['stability']['release'] = $state; 477 } 478 479 /** 480 * WARNING - do not use this function unless you know what you're doing 481 */ 482 function setRawCompatible($compatible) 483 { 484 $this->_packageInfo['compatible'] = $compatible; 485 } 486 487 /** 488 * WARNING - do not use this function unless you know what you're doing 489 */ 490 function setRawPackage($package) 491 { 492 $this->_packageInfo['name'] = $package; 493 } 494 495 /** 496 * WARNING - do not use this function unless you know what you're doing 497 */ 498 function setRawChannel($channel) 499 { 500 $this->_packageInfo['channel'] = $channel; 501 } 502 503 function setRequestedGroup($group) 504 { 505 $this->_requestedGroup = $group; 506 } 507 508 function getRequestedGroup() 509 { 510 if (isset($this->_requestedGroup)) { 511 return $this->_requestedGroup; 512 } 513 return false; 514 } 515 516 /** 517 * For saving in the registry. 518 * 519 * Set the last version that was installed 520 * @param string 521 */ 522 function setLastInstalledVersion($version) 523 { 524 $this->_packageInfo['_lastversion'] = $version; 525 } 526 527 /** 528 * @return string|false 529 */ 530 function getLastInstalledVersion() 531 { 532 if (isset($this->_packageInfo['_lastversion'])) { 533 return $this->_packageInfo['_lastversion']; 534 } 535 return false; 536 } 537 538 /** 539 * Determines whether this package.xml has post-install scripts or not 540 * @return array|false 541 */ 542 function listPostinstallScripts() 543 { 544 $filelist = $this->getFilelist(); 545 $contents = $this->getContents(); 546 $contents = $contents['dir']['file']; 547 if (!is_array($contents) || !isset($contents[0])) { 548 $contents = array($contents); 549 } 550 $taskfiles = array(); 551 foreach ($contents as $file) { 552 $atts = $file['attribs']; 553 unset($file['attribs']); 554 if (count($file)) { 555 $taskfiles[$atts['name']] = $file; 556 } 557 } 558 $common = new PEAR_Common; 559 $common->debug = $this->_config->get('verbose'); 560 $this->_scripts = array(); 561 $ret = array(); 562 foreach ($taskfiles as $name => $tasks) { 563 if (!isset($filelist[$name])) { 564 // ignored files will not be in the filelist 565 continue; 566 } 567 $atts = $filelist[$name]; 568 foreach ($tasks as $tag => $raw) { 569 $task = $this->getTask($tag); 570 $task = &new $task($this->_config, $common, PEAR_TASK_INSTALL); 571 if ($task->isScript()) { 572 $ret[] = $filelist[$name]['installed_as']; 573 } 574 } 575 } 576 if (count($ret)) { 577 return $ret; 578 } 579 return false; 580 } 581 582 /** 583 * Initialize post-install scripts for running 584 * 585 * This method can be used to detect post-install scripts, as the return value 586 * indicates whether any exist 587 * @return bool 588 */ 589 function initPostinstallScripts() 590 { 591 $filelist = $this->getFilelist(); 592 $contents = $this->getContents(); 593 $contents = $contents['dir']['file']; 594 if (!is_array($contents) || !isset($contents[0])) { 595 $contents = array($contents); 596 } 597 $taskfiles = array(); 598 foreach ($contents as $file) { 599 $atts = $file['attribs']; 600 unset($file['attribs']); 601 if (count($file)) { 602 $taskfiles[$atts['name']] = $file; 603 } 604 } 605 $common = new PEAR_Common; 606 $common->debug = $this->_config->get('verbose'); 607 $this->_scripts = array(); 608 foreach ($taskfiles as $name => $tasks) { 609 if (!isset($filelist[$name])) { 610 // file was not installed due to installconditions 611 continue; 612 } 613 $atts = $filelist[$name]; 614 foreach ($tasks as $tag => $raw) { 615 $taskname = $this->getTask($tag); 616 $task = &new $taskname($this->_config, $common, PEAR_TASK_INSTALL); 617 if (!$task->isScript()) { 618 continue; // scripts are only handled after installation 619 } 620 $lastversion = isset($this->_packageInfo['_lastversion']) ? 621 $this->_packageInfo['_lastversion'] : null; 622 $task->init($raw, $atts, $lastversion); 623 $res = $task->startSession($this, $atts['installed_as']); 624 if (!$res) { 625 continue; // skip this file 626 } 627 if (PEAR::isError($res)) { 628 return $res; 629 } 630 $assign = &$task; 631 $this->_scripts[] = &$assign; 632 } 633 } 634 if (count($this->_scripts)) { 635 return true; 636 } 637 return false; 638 } 639 640 function runPostinstallScripts() 641 { 642 if ($this->initPostinstallScripts()) { 643 $ui = &PEAR_Frontend::singleton(); 644 if ($ui) { 645 $ui->runPostinstallScripts($this->_scripts, $this); 646 } 647 } 648 } 649 650 651 /** 652 * Convert a recursive set of <dir> and <file> tags into a single <dir> tag with 653 * <file> tags. 654 */ 655 function flattenFilelist() 656 { 657 if (isset($this->_packageInfo['bundle'])) { 658 return; 659 } 660 $filelist = array(); 661 if (isset($this->_packageInfo['contents']['dir']['dir'])) { 662 $this->_getFlattenedFilelist($filelist, $this->_packageInfo['contents']['dir']); 663 if (!isset($filelist[1])) { 664 $filelist = $filelist[0]; 665 } 666 $this->_packageInfo['contents']['dir']['file'] = $filelist; 667 unset($this->_packageInfo['contents']['dir']['dir']); 668 } else { 669 // else already flattened but check for baseinstalldir propagation 670 if (isset($this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'])) { 671 if (isset($this->_packageInfo['contents']['dir']['file'][0])) { 672 foreach ($this->_packageInfo['contents']['dir']['file'] as $i => $file) { 673 if (isset($file['attribs']['baseinstalldir'])) { 674 continue; 675 } 676 $this->_packageInfo['contents']['dir']['file'][$i]['attribs']['baseinstalldir'] 677 = $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir']; 678 } 679 } else { 680 if (!isset($this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir'])) { 681 $this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir'] 682 = $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir']; 683 } 684 } 685 } 686 } 687 } 688 689 /** 690 * @param array the final flattened file list 691 * @param array the current directory being processed 692 * @param string|false any recursively inherited baeinstalldir attribute 693 * @param string private recursion variable 694 * @return array 695 * @access protected 696 */ 697 function _getFlattenedFilelist(&$files, $dir, $baseinstall = false, $path = '') 698 { 699 if (isset($dir['attribs']) && isset($dir['attribs']['baseinstalldir'])) { 700 $baseinstall = $dir['attribs']['baseinstalldir']; 701 } 702 if (isset($dir['dir'])) { 703 if (!isset($dir['dir'][0])) { 704 $dir['dir'] = array($dir['dir']); 705 } 706 foreach ($dir['dir'] as $subdir) { 707 if (!isset($subdir['attribs']) || !isset($subdir['attribs']['name'])) { 708 $name = '*unknown*'; 709 } else { 710 $name = $subdir['attribs']['name']; 711 } 712 $newpath = empty($path) ? $name : 713 $path . '/' . $name; 714 $this->_getFlattenedFilelist($files, $subdir, 715 $baseinstall, $newpath); 716 } 717 } 718 if (isset($dir['file'])) { 719 if (!isset($dir['file'][0])) { 720 $dir['file'] = array($dir['file']); 721 } 722 foreach ($dir['file'] as $file) { 723 $attrs = $file['attribs']; 724 $name = $attrs['name']; 725 if ($baseinstall && !isset($attrs['baseinstalldir'])) { 726 $attrs['baseinstalldir'] = $baseinstall; 727 } 728 $attrs['name'] = empty($path) ? $name : $path . '/' . $name; 729 $attrs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), 730 $attrs['name']); 731 $file['attribs'] = $attrs; 732 $files[] = $file; 733 } 734 } 735 } 736 737 function setConfig(&$config) 738 { 739 $this->_config = &$config; 740 $this->_registry = &$config->getRegistry(); 741 } 742 743 function setLogger(&$logger) 744 { 745 if (!is_object($logger) || !method_exists($logger, 'log')) { 746 return PEAR::raiseError('Logger must be compatible with PEAR_Common::log'); 747 } 748 $this->_logger = &$logger; 749 } 750 751 /** 752 * WARNING - do not use this function directly unless you know what you're doing 753 */ 754 function setDeps($deps) 755 { 756 $this->_packageInfo['dependencies'] = $deps; 757 } 758 759 function setPackagefile($file, $archive = false) 760 { 761 $this->_packageFile = $file; 762 $this->_archiveFile = $archive ? $archive : $file; 763 } 764 765 /** 766 * Wrapper to {@link PEAR_ErrorStack::getErrors()} 767 * @param boolean determines whether to purge the error stack after retrieving 768 * @return array 769 */ 770 function getValidationWarnings($purge = true) 771 { 772 return $this->_stack->getErrors($purge); 773 } 774 775 function getPackageFile() 776 { 777 return $this->_packageFile; 778 } 779 780 function getArchiveFile() 781 { 782 return $this->_archiveFile; 783 } 784 785 786 /** 787 * Directly set the array that defines this packagefile 788 * 789 * WARNING: no validation. This should only be performed by internal methods 790 * inside PEAR or by inputting an array saved from an existing PEAR_PackageFile_v2 791 * @param array 792 */ 793 function fromArray($pinfo) 794 { 795 unset($pinfo['old']); 796 unset($pinfo['xsdversion']); 797 $this->_incomplete = false; 798 $this->_packageInfo = $pinfo; 799 } 800 801 function isIncomplete() 802 { 803 return $this->_incomplete; 804 } 805 806 /** 807 * @return array 808 */ 809 function toArray($forreg = false) 810 { 811 if (!$this->validate(PEAR_VALIDATE_NORMAL)) { 812 return false; 813 } 814 return $this->getArray($forreg); 815 } 816 817 function getArray($forReg = false) 818 { 819 if ($forReg) { 820 $arr = $this->_packageInfo; 821 $arr['old'] = array(); 822 $arr['old']['version'] = $this->getVersion(); 823 $arr['old']['release_date'] = $this->getDate(); 824 $arr['old']['release_state'] = $this->getState(); 825 $arr['old']['release_license'] = $this->getLicense(); 826 $arr['old']['release_notes'] = $this->getNotes(); 827 $arr['old']['release_deps'] = $this->getDeps(); 828 $arr['old']['maintainers'] = $this->getMaintainers(); 829 $arr['xsdversion'] = '2.0'; 830 return $arr; 831 } else { 832 $info = $this->_packageInfo; 833 unset($info['dirtree']); 834 if (isset($info['_lastversion'])) { 835 unset($info['_lastversion']); 836 } 837 if (isset($info['#binarypackage'])) { 838 unset($info['#binarypackage']); 839 } 840 return $info; 841 } 842 } 843 844 function packageInfo($field) 845 { 846 $arr = $this->getArray(true); 847 if ($field == 'state') { 848 return $arr['stability']['release']; 849 } 850 if ($field == 'api-version') { 851 return $arr['version']['api']; 852 } 853 if ($field == 'api-state') { 854 return $arr['stability']['api']; 855 } 856 if (isset($arr['old'][$field])) { 857 if (!is_string($arr['old'][$field])) { 858 return null; 859 } 860 return $arr['old'][$field]; 861 } 862 if (isset($arr[$field])) { 863 if (!is_string($arr[$field])) { 864 return null; 865 } 866 return $arr[$field]; 867 } 868 return null; 869 } 870 871 function getName() 872 { 873 return $this->getPackage(); 874 } 875 876 function getPackage() 877 { 878 if (isset($this->_packageInfo['name'])) { 879 return $this->_packageInfo['name']; 880 } 881 return false; 882 } 883 884 function getChannel() 885 { 886 if (isset($this->_packageInfo['uri'])) { 887 return '__uri'; 888 } 889 if (isset($this->_packageInfo['channel'])) { 890 return strtolower($this->_packageInfo['channel']); 891 } 892 return false; 893 } 894 895 function getUri() 896 { 897 if (isset($this->_packageInfo['uri'])) { 898 return $this->_packageInfo['uri']; 899 } 900 return false; 901 } 902 903 function getExtends() 904 { 905 if (isset($this->_packageInfo['extends'])) { 906 return $this->_packageInfo['extends']; 907 } 908 return false; 909 } 910 911 function getSummary() 912 { 913 if (isset($this->_packageInfo['summary'])) { 914 return $this->_packageInfo['summary']; 915 } 916 return false; 917 } 918 919 function getDescription() 920 { 921 if (isset($this->_packageInfo['description'])) { 922 return $this->_packageInfo['description']; 923 } 924 return false; 925 } 926 927 function getMaintainers($raw = false) 928 { 929 if (!isset($this->_packageInfo['lead'])) { 930 return false; 931 } 932 if ($raw) { 933 $ret = array('lead' => $this->_packageInfo['lead']); 934 (isset($this->_packageInfo['developer'])) ? 935 $ret['developer'] = $this->_packageInfo['developer'] :null; 936 (isset($this->_packageInfo['contributor'])) ? 937 $ret['contributor'] = $this->_packageInfo['contributor'] :null; 938 (isset($this->_packageInfo['helper'])) ? 939 $ret['helper'] = $this->_packageInfo['helper'] :null; 940 return $ret; 941 } else { 942 $ret = array(); 943 $leads = isset($this->_packageInfo['lead'][0]) ? $this->_packageInfo['lead'] : 944 array($this->_packageInfo['lead']); 945 foreach ($leads as $lead) { 946 $s = $lead; 947 $s['handle'] = $s['user']; 948 unset($s['user']); 949 $s['role'] = 'lead'; 950 $ret[] = $s; 951 } 952 if (isset($this->_packageInfo['developer'])) { 953 $leads = isset($this->_packageInfo['developer'][0]) ? 954 $this->_packageInfo['developer'] : 955 array($this->_packageInfo['developer']); 956 foreach ($leads as $maintainer) { 957 $s = $maintainer; 958 $s['handle'] = $s['user']; 959 unset($s['user']); 960 $s['role'] = 'developer'; 961 $ret[] = $s; 962 } 963 } 964 if (isset($this->_packageInfo['contributor'])) { 965 $leads = isset($this->_packageInfo['contributor'][0]) ? 966 $this->_packageInfo['contributor'] : 967 array($this->_packageInfo['contributor']); 968 foreach ($leads as $maintainer) { 969 $s = $maintainer; 970 $s['handle'] = $s['user']; 971 unset($s['user']); 972 $s['role'] = 'contributor'; 973 $ret[] = $s; 974 } 975 } 976 if (isset($this->_packageInfo['helper'])) { 977 $leads = isset($this->_packageInfo['helper'][0]) ? 978 $this->_packageInfo['helper'] : 979 array($this->_packageInfo['helper']); 980 foreach ($leads as $maintainer) { 981 $s = $maintainer; 982 $s['handle'] = $s['user']; 983 unset($s['user']); 984 $s['role'] = 'helper'; 985 $ret[] = $s; 986 } 987 } 988 return $ret; 989 } 990 return false; 991 } 992 993 function getLeads() 994 { 995 if (isset($this->_packageInfo['lead'])) { 996 return $this->_packageInfo['lead']; 997 } 998 return false; 999 } 1000 1001 function getDevelopers() 1002 { 1003 if (isset($this->_packageInfo['developer'])) { 1004 return $this->_packageInfo['developer']; 1005 } 1006 return false; 1007 } 1008 1009 function getContributors() 1010 { 1011 if (isset($this->_packageInfo['contributor'])) { 1012 return $this->_packageInfo['contributor']; 1013 } 1014 return false; 1015 } 1016 1017 function getHelpers() 1018 { 1019 if (isset($this->_packageInfo['helper'])) { 1020 return $this->_packageInfo['helper']; 1021 } 1022 return false; 1023 } 1024 1025 function setDate($date) 1026 { 1027 if (!isset($this->_packageInfo['date'])) { 1028 // ensure that the extends tag is set up in the right location 1029 $this->_packageInfo = $this->_insertBefore($this->_packageInfo, 1030 array('time', 'version', 1031 'stability', 'license', 'notes', 'contents', 'compatible', 1032 'dependencies', 'providesextension', 'srcpackage', 'srcuri', 1033 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 1034 'zendextbinrelease', 'bundle', 'changelog'), array(), 'date'); 1035 } 1036 $this->_packageInfo['date'] = $date; 1037 $this->_isValid = 0; 1038 } 1039 1040 function setTime($time) 1041 { 1042 $this->_isValid = 0; 1043 if (!isset($this->_packageInfo['time'])) { 1044 // ensure that the time tag is set up in the right location 1045 $this->_packageInfo = $this->_insertBefore($this->_packageInfo, 1046 array('version', 1047 'stability', 'license', 'notes', 'contents', 'compatible', 1048 'dependencies', 'providesextension', 'srcpackage', 'srcuri', 1049 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 1050 'zendextbinrelease', 'bundle', 'changelog'), $time, 'time'); 1051 } 1052 $this->_packageInfo['time'] = $time; 1053 } 1054 1055 function getDate() 1056 { 1057 if (isset($this->_packageInfo['date'])) { 1058 return $this->_packageInfo['date']; 1059 } 1060 return false; 1061 } 1062 1063 function getTime() 1064 { 1065 if (isset($this->_packageInfo['time'])) { 1066 return $this->_packageInfo['time']; 1067 } 1068 return false; 1069 } 1070 1071 /** 1072 * @param package|api version category to return 1073 */ 1074 function getVersion($key = 'release') 1075 { 1076 if (isset($this->_packageInfo['version'][$key])) { 1077 return $this->_packageInfo['version'][$key]; 1078 } 1079 return false; 1080 } 1081 1082 function getStability() 1083 { 1084 if (isset($this->_packageInfo['stability'])) { 1085 return $this->_packageInfo['stability']; 1086 } 1087 return false; 1088 } 1089 1090 function getState($key = 'release') 1091 { 1092 if (isset($this->_packageInfo['stability'][$key])) { 1093 return $this->_packageInfo['stability'][$key]; 1094 } 1095 return false; 1096 } 1097 1098 function getLicense($raw = false) 1099 { 1100 if (isset($this->_packageInfo['license'])) { 1101 if ($raw) { 1102 return $this->_packageInfo['license']; 1103 } 1104 if (is_array($this->_packageInfo['license'])) { 1105 return $this->_packageInfo['license']['_content']; 1106 } else { 1107 return $this->_packageInfo['license']; 1108 } 1109 } 1110 return false; 1111 } 1112 1113 function getLicenseLocation() 1114 { 1115 if (!isset($this->_packageInfo['license']) || !is_array($this->_packageInfo['license'])) { 1116 return false; 1117 } 1118 return $this->_packageInfo['license']['attribs']; 1119 } 1120 1121 function getNotes() 1122 { 1123 if (isset($this->_packageInfo['notes'])) { 1124 return $this->_packageInfo['notes']; 1125 } 1126 return false; 1127 } 1128 1129 /** 1130 * Return the <usesrole> tag contents, if any 1131 * @return array|false 1132 */ 1133 function getUsesrole() 1134 { 1135 if (isset($this->_packageInfo['usesrole'])) { 1136 return $this->_packageInfo['usesrole']; 1137 } 1138 return false; 1139 } 1140 1141 /** 1142 * Return the <usestask> tag contents, if any 1143 * @return array|false 1144 */ 1145 function getUsestask() 1146 { 1147 if (isset($this->_packageInfo['usestask'])) { 1148 return $this->_packageInfo['usestask']; 1149 } 1150 return false; 1151 } 1152 1153 /** 1154 * This should only be used to retrieve filenames and install attributes 1155 */ 1156 function getFilelist($preserve = false) 1157 { 1158 if (isset($this->_packageInfo['filelist']) && !$preserve) { 1159 return $this->_packageInfo['filelist']; 1160 } 1161 $this->flattenFilelist(); 1162 if ($contents = $this->getContents()) { 1163 $ret = array(); 1164 if (!isset($contents['dir']['file'][0])) { 1165 $contents['dir']['file'] = array($contents['dir']['file']); 1166 } 1167 foreach ($contents['dir']['file'] as $file) { 1168 $name = $file['attribs']['name']; 1169 if (!$preserve) { 1170 $file = $file['attribs']; 1171 } 1172 $ret[$name] = $file; 1173 } 1174 if (!$preserve) { 1175 $this->_packageInfo['filelist'] = $ret; 1176 } 1177 return $ret; 1178 } 1179 return false; 1180 } 1181 1182 /** 1183 * Return configure options array, if any 1184 * 1185 * @return array|false 1186 */ 1187 function getConfigureOptions() 1188 { 1189 if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') { 1190 return false; 1191 } 1192 $releases = $this->getReleases(); 1193 if (isset($releases[0])) { 1194 $releases = $releases[0]; 1195 } 1196 if (isset($releases['configureoption'])) { 1197 if (!isset($releases['configureoption'][0])) { 1198 $releases['configureoption'] = array($releases['configureoption']); 1199 } 1200 for ($i = 0; $i < count($releases['configureoption']); $i++) { 1201 $releases['configureoption'][$i] = $releases['configureoption'][$i]['attribs']; 1202 } 1203 return $releases['configureoption']; 1204 } 1205 return false; 1206 } 1207 1208 /** 1209 * This is only used at install-time, after all serialization 1210 * is over. 1211 */ 1212 function resetFilelist() 1213 { 1214 $this->_packageInfo['filelist'] = array(); 1215 } 1216 1217 /** 1218 * Retrieve a list of files that should be installed on this computer 1219 * @return array 1220 */ 1221 function getInstallationFilelist($forfilecheck = false) 1222 { 1223 $contents = $this->getFilelist(true); 1224 if (isset($contents['dir']['attribs']['baseinstalldir'])) { 1225 $base = $contents['dir']['attribs']['baseinstalldir']; 1226 } 1227 if (isset($this->_packageInfo['bundle'])) { 1228 return PEAR::raiseError( 1229 'Exception: bundles should be handled in download code only'); 1230 } 1231 $release = $this->getReleases(); 1232 if ($release) { 1233 if (!isset($release[0])) { 1234 if (!isset($release['installconditions']) && !isset($release['filelist'])) { 1235 if ($forfilecheck) { 1236 return $this->getFilelist(); 1237 } 1238 return $contents; 1239 } 1240 $release = array($release); 1241 } 1242 $depchecker = &$this->getPEARDependency2($this->_config, array(), 1243 array('channel' => $this->getChannel(), 'package' => $this->getPackage()), 1244 PEAR_VALIDATE_INSTALLING); 1245 foreach ($release as $instance) { 1246 if (isset($instance['installconditions'])) { 1247 $installconditions = $instance['installconditions']; 1248 if (is_array($installconditions)) { 1249 PEAR::pushErrorHandling(PEAR_ERROR_RETURN); 1250 foreach ($installconditions as $type => $conditions) { 1251 if (!isset($conditions[0])) { 1252 $conditions = array($conditions); 1253 } 1254 foreach ($conditions as $condition) { 1255 $ret = $depchecker->{"validate{$type}Dependency"}($condition); 1256 if (PEAR::isError($ret)) { 1257 PEAR::popErrorHandling(); 1258 continue 3; // skip this release 1259 } 1260 } 1261 } 1262 PEAR::popErrorHandling(); 1263 } 1264 } 1265 // this is the release to use 1266 if (isset($instance['filelist'])) { 1267 // ignore files 1268 if (isset($instance['filelist']['ignore'])) { 1269 $ignore = isset($instance['filelist']['ignore'][0]) ? 1270 $instance['filelist']['ignore'] : 1271 array($instance['filelist']['ignore']); 1272 foreach ($ignore as $ig) { 1273 unset ($contents[$ig['attribs']['name']]); 1274 } 1275 } 1276 // install files as this name 1277 if (isset($instance['filelist']['install'])) { 1278 $installas = isset($instance['filelist']['install'][0]) ? 1279 $instance['filelist']['install'] : 1280 array($instance['filelist']['install']); 1281 foreach ($installas as $as) { 1282 $contents[$as['attribs']['name']]['attribs']['install-as'] = 1283 $as['attribs']['as']; 1284 } 1285 } 1286 } 1287 if ($forfilecheck) { 1288 foreach ($contents as $file => $attrs) { 1289 $contents[$file] = $attrs['attribs']; 1290 } 1291 } 1292 return $contents; 1293 } 1294 } else { // simple release - no installconditions or install-as 1295 if ($forfilecheck) { 1296 return $this->getFilelist(); 1297 } 1298 return $contents; 1299 } 1300 // no releases matched 1301 return PEAR::raiseError('No releases in package.xml matched the existing operating ' . 1302 'system, extensions installed, or architecture, cannot install'); 1303 } 1304 1305 /** 1306 * This is only used at install-time, after all serialization 1307 * is over. 1308 * @param string file name 1309 * @param string installed path 1310 */ 1311 function setInstalledAs($file, $path) 1312 { 1313 if ($path) { 1314 return $this->_packageInfo['filelist'][$file]['installed_as'] = $path; 1315 } 1316 unset($this->_packageInfo['filelist'][$file]['installed_as']); 1317 } 1318 1319 function getInstalledLocation($file) 1320 { 1321 if (isset($this->_packageInfo['filelist'][$file]['installed_as'])) { 1322 return $this->_packageInfo['filelist'][$file]['installed_as']; 1323 } 1324 return false; 1325 } 1326 1327 /** 1328 * This is only used at install-time, after all serialization 1329 * is over. 1330 */ 1331 function installedFile($file, $atts) 1332 { 1333 if (isset($this->_packageInfo['filelist'][$file])) { 1334 $this->_packageInfo['filelist'][$file] = 1335 array_merge($this->_packageInfo['filelist'][$file], $atts['attribs']); 1336 } else { 1337 $this->_packageInfo['filelist'][$file] = $atts['attribs']; 1338 } 1339 } 1340 1341 /** 1342 * Retrieve the contents tag 1343 */ 1344 function getContents() 1345 { 1346 if (isset($this->_packageInfo['contents'])) { 1347 return $this->_packageInfo['contents']; 1348 } 1349 return false; 1350 } 1351 1352 /** 1353 * @param string full path to file 1354 * @param string attribute name 1355 * @param string attribute value 1356 * @param int risky but fast - use this to choose a file based on its position in the list 1357 * of files. Index is zero-based like PHP arrays. 1358 * @return bool success of operation 1359 */ 1360 function setFileAttribute($filename, $attr, $value, $index = false) 1361 { 1362 $this->_isValid = 0; 1363 if (in_array($attr, array('role', 'name', 'baseinstalldir'))) { 1364 $this->_filesValid = false; 1365 } 1366 if ($index !== false && 1367 isset($this->_packageInfo['contents']['dir']['file'][$index]['attribs'])) { 1368 $this->_packageInfo['contents']['dir']['file'][$index]['attribs'][$attr] = $value; 1369 return true; 1370 } 1371 if (!isset($this->_packageInfo['contents']['dir']['file'])) { 1372 return false; 1373 } 1374 $files = $this->_packageInfo['contents']['dir']['file']; 1375 if (!isset($files[0])) { 1376 $files = array($files); 1377 $ind = false; 1378 } else { 1379 $ind = true; 1380 } 1381 foreach ($files as $i => $file) { 1382 if (isset($file['attribs'])) { 1383 if ($file['attribs']['name'] == $filename) { 1384 if ($ind) { 1385 $this->_packageInfo['contents']['dir']['file'][$i]['attribs'][$attr] = $value; 1386 } else { 1387 $this->_packageInfo['contents']['dir']['file']['attribs'][$attr] = $value; 1388 } 1389 return true; 1390 } 1391 } 1392 } 1393 return false; 1394 } 1395 1396 function setDirtree($path) 1397 { 1398 if (!isset($this->_packageInfo['dirtree'])) { 1399 $this->_packageInfo['dirtree'] = array(); 1400 } 1401 $this->_packageInfo['dirtree'][$path] = true; 1402 } 1403 1404 function getDirtree() 1405 { 1406 if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) { 1407 return $this->_packageInfo['dirtree']; 1408 } 1409 return false; 1410 } 1411 1412 function resetDirtree() 1413 { 1414 unset($this->_packageInfo['dirtree']); 1415 } 1416 1417 /** 1418 * Determines whether this package claims it is compatible with the version of 1419 * the package that has a recommended version dependency 1420 * @param PEAR_PackageFile_v2|PEAR_PackageFile_v1|PEAR_Downloader_Package 1421 * @return boolean 1422 */ 1423 function isCompatible($pf) 1424 { 1425 if (!isset($this->_packageInfo['compatible'])) { 1426 return false; 1427 } 1428 if (!isset($this->_packageInfo['channel'])) { 1429 return false; 1430 } 1431 $me = $pf->getVersion(); 1432 $compatible = $this->_packageInfo['compatible']; 1433 if (!isset($compatible[0])) { 1434 $compatible = array($compatible); 1435 } 1436 $found = false; 1437 foreach ($compatible as $info) { 1438 if (strtolower($info['name']) == strtolower($pf->getPackage())) { 1439 if (strtolower($info['channel']) == strtolower($pf->getChannel())) { 1440 $found = true; 1441 break; 1442 } 1443 } 1444 } 1445 if (!$found) { 1446 return false; 1447 } 1448 if (isset($info['exclude'])) { 1449 if (!isset($info['exclude'][0])) { 1450 $info['exclude'] = array($info['exclude']); 1451 } 1452 foreach ($info['exclude'] as $exclude) { 1453 if (version_compare($me, $exclude, '==')) { 1454 return false; 1455 } 1456 } 1457 } 1458 if (version_compare($me, $info['min'], '>=') && version_compare($me, $info['max'], '<=')) { 1459 return true; 1460 } 1461 return false; 1462 } 1463 1464 /** 1465 * @return array|false 1466 */ 1467 function getCompatible() 1468 { 1469 if (isset($this->_packageInfo['compatible'])) { 1470 return $this->_packageInfo['compatible']; 1471 } 1472 return false; 1473 } 1474 1475 function getDependencies() 1476 { 1477 if (isset($this->_packageInfo['dependencies'])) { 1478 return $this->_packageInfo['dependencies']; 1479 } 1480 return false; 1481 } 1482 1483 function isSubpackageOf($p) 1484 { 1485 return $p->isSubpackage($this); 1486 } 1487 1488 /** 1489 * Determines whether the passed in package is a subpackage of this package. 1490 * 1491 * No version checking is done, only name verification. 1492 * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 1493 * @return bool 1494 */ 1495 function isSubpackage($p) 1496 { 1497 $sub = array(); 1498 if (isset($this->_packageInfo['dependencies']['required']['subpackage'])) { 1499 $sub = $this->_packageInfo['dependencies']['required']['subpackage']; 1500 if (!isset($sub[0])) { 1501 $sub = array($sub); 1502 } 1503 } 1504 if (isset($this->_packageInfo['dependencies']['optional']['subpackage'])) { 1505 $sub1 = $this->_packageInfo['dependencies']['optional']['subpackage']; 1506 if (!isset($sub1[0])) { 1507 $sub1 = array($sub1); 1508 } 1509 $sub = array_merge($sub, $sub1); 1510 } 1511 if (isset($this->_packageInfo['dependencies']['group'])) { 1512 $group = $this->_packageInfo['dependencies']['group']; 1513 if (!isset($group[0])) { 1514 $group = array($group); 1515 } 1516 foreach ($group as $deps) { 1517 if (isset($deps['subpackage'])) { 1518 $sub2 = $deps['subpackage']; 1519 if (!isset($sub2[0])) { 1520 $sub2 = array($sub2); 1521 } 1522 $sub = array_merge($sub, $sub2); 1523 } 1524 } 1525 } 1526 foreach ($sub as $dep) { 1527 if (strtolower($dep['name']) == strtolower($p->getPackage())) { 1528 if (isset($dep['channel'])) { 1529 if (strtolower($dep['channel']) == strtolower($p->getChannel())) { 1530 return true; 1531 } 1532 } else { 1533 if ($dep['uri'] == $p->getURI()) { 1534 return true; 1535 } 1536 } 1537 } 1538 } 1539 return false; 1540 } 1541 1542 function dependsOn($package, $channel) 1543 { 1544 if (!($deps = $this->getDependencies())) { 1545 return false; 1546 } 1547 foreach (array('package', 'subpackage') as $type) { 1548 foreach (array('required', 'optional') as $needed) { 1549 if (isset($deps[$needed][$type])) { 1550 if (!isset($deps[$needed][$type][0])) { 1551 $deps[$needed][$type] = array($deps[$needed][$type]); 1552 } 1553 foreach ($deps[$needed][$type] as $dep) { 1554 $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; 1555 if (strtolower($dep['name']) == strtolower($package) && 1556 $depchannel == $channel) { 1557 return true; 1558 } 1559 } 1560 } 1561 } 1562 if (isset($deps['group'])) { 1563 if (!isset($deps['group'][0])) { 1564 $dep['group'] = array($deps['group']); 1565 } 1566 foreach ($deps['group'] as $group) { 1567 if (isset($group[$type])) { 1568 if (!is_array($group[$type])) { 1569 $group[$type] = array($group[$type]); 1570 } 1571 foreach ($group[$type] as $dep) { 1572 $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; 1573 if (strtolower($dep['name']) == strtolower($package) && 1574 $depchannel == $channel) { 1575 return true; 1576 } 1577 } 1578 } 1579 } 1580 } 1581 } 1582 return false; 1583 } 1584 1585 /** 1586 * Get the contents of a dependency group 1587 * @param string 1588 * @return array|false 1589 */ 1590 function getDependencyGroup($name) 1591 { 1592 $name = strtolower($name); 1593 if (!isset($this->_packageInfo['dependencies']['group'])) { 1594 return false; 1595 } 1596 $groups = $this->_packageInfo['dependencies']['group']; 1597 if (!isset($groups[0])) { 1598 $groups = array($groups); 1599 } 1600 foreach ($groups as $group) { 1601 if (strtolower($group['attribs']['name']) == $name) { 1602 return $group; 1603 } 1604 } 1605 return false; 1606 } 1607 1608 /** 1609 * Retrieve a partial package.xml 1.0 representation of dependencies 1610 * 1611 * a very limited representation of dependencies is returned by this method. 1612 * The <exclude> tag for excluding certain versions of a dependency is 1613 * completely ignored. In addition, dependency groups are ignored, with the 1614 * assumption that all dependencies in dependency groups are also listed in 1615 * the optional group that work with all dependency groups 1616 * @param boolean return package.xml 2.0 <dependencies> tag 1617 * @return array|false 1618 */ 1619 function getDeps($raw = false, $nopearinstaller = false) 1620 { 1621 if (isset($this->_packageInfo['dependencies'])) { 1622 if ($raw) { 1623 return $this->_packageInfo['dependencies']; 1624 } 1625 $ret = array(); 1626 $map = array( 1627 'php' => 'php', 1628 'package' => 'pkg', 1629 'subpackage' => 'pkg', 1630 'extension' => 'ext', 1631 'os' => 'os', 1632 'pearinstaller' => 'pkg', 1633 ); 1634 foreach (array('required', 'optional') as $type) { 1635 $optional = ($type == 'optional') ? 'yes' : 'no'; 1636 if (!isset($this->_packageInfo['dependencies'][$type])) { 1637 continue; 1638 } 1639 foreach ($this->_packageInfo['dependencies'][$type] as $dtype => $deps) { 1640 if ($dtype == 'pearinstaller' && $nopearinstaller) { 1641 continue; 1642 } 1643 if (!isset($deps[0])) { 1644 $deps = array($deps); 1645 } 1646 foreach ($deps as $dep) { 1647 if (!isset($map[$dtype])) { 1648 // no support for arch type 1649 continue; 1650 } 1651 if ($dtype == 'pearinstaller') { 1652 $dep['name'] = 'PEAR'; 1653 $dep['channel'] = 'pear.php.net'; 1654 } 1655 $s = array('type' => $map[$dtype]); 1656 if (isset($dep['channel'])) { 1657 $s['channel'] = $dep['channel']; 1658 } 1659 if (isset($dep['uri'])) { 1660 $s['uri'] = $dep['uri']; 1661 } 1662 if (isset($dep['name'])) { 1663 $s['name'] = $dep['name']; 1664 } 1665 if (isset($dep['conflicts'])) { 1666 $s['rel'] = 'not'; 1667 } else { 1668 if (!isset($dep['min']) && 1669 !isset($dep['max'])) { 1670 $s['rel'] = 'has'; 1671 $s['optional'] = $optional; 1672 } elseif (isset($dep['min']) && 1673 isset($dep['max'])) { 1674 $s['rel'] = 'ge'; 1675 $s1 = $s; 1676 $s1['rel'] = 'le'; 1677 $s['version'] = $dep['min']; 1678 $s1['version'] = $dep['max']; 1679 if (isset($dep['channel'])) { 1680 $s1['channel'] = $dep['channel']; 1681 } 1682 if ($dtype != 'php') { 1683 $s['name'] = $dep['name']; 1684 $s1['name'] = $dep['name']; 1685 } 1686 $s['optional'] = $optional; 1687 $s1['optional'] = $optional; 1688 $ret[] = $s1; 1689 } elseif (isset($dep['min'])) { 1690 if (isset($dep['exclude']) && 1691 $dep['exclude'] == $dep['min']) { 1692 $s['rel'] = 'gt'; 1693 } else { 1694 $s['rel'] = 'ge'; 1695 } 1696 $s['version'] = $dep['min']; 1697 $s['optional'] = $optional; 1698 if ($dtype != 'php') { 1699 $s['name'] = $dep['name']; 1700 } 1701 } elseif (isset($dep['max'])) { 1702 if (isset($dep['exclude']) && 1703 $dep['exclude'] == $dep['max']) { 1704 $s['rel'] = 'lt'; 1705 } else { 1706 $s['rel'] = 'le'; 1707 } 1708 $s['version'] = $dep['max']; 1709 $s['optional'] = $optional; 1710 if ($dtype != 'php') { 1711 $s['name'] = $dep['name']; 1712 } 1713 } 1714 } 1715 $ret[] = $s; 1716 } 1717 } 1718 } 1719 if (count($ret)) { 1720 return $ret; 1721 } 1722 } 1723 return false; 1724 } 1725 1726 /** 1727 * @return php|extsrc|extbin|zendextsrc|zendextbin|bundle|false 1728 */ 1729 function getPackageType() 1730 { 1731 if (isset($this->_packageInfo['phprelease'])) { 1732 return 'php'; 1733 } 1734 if (isset($this->_packageInfo['extsrcrelease'])) { 1735 return 'extsrc'; 1736 } 1737 if (isset($this->_packageInfo['extbinrelease'])) { 1738 return 'extbin'; 1739 } 1740 if (isset($this->_packageInfo['zendextsrcrelease'])) { 1741 return 'zendextsrc'; 1742 } 1743 if (isset($this->_packageInfo['zendextbinrelease'])) { 1744 return 'zendextbin'; 1745 } 1746 if (isset($this->_packageInfo['bundle'])) { 1747 return 'bundle'; 1748 } 1749 return false; 1750 } 1751 1752 /** 1753 * @return array|false 1754 */ 1755 function getReleases() 1756 { 1757 $type = $this->getPackageType(); 1758 if ($type != 'bundle') { 1759 $type .= 'release'; 1760 } 1761 if ($this->getPackageType() && isset($this->_packageInfo[$type])) { 1762 return $this->_packageInfo[$type]; 1763 } 1764 return false; 1765 } 1766 1767 /** 1768 * @return array 1769 */ 1770 function getChangelog() 1771 { 1772 if (isset($this->_packageInfo['changelog'])) { 1773 return $this->_packageInfo['changelog']; 1774 } 1775 return false; 1776 } 1777 1778 function hasDeps() 1779 { 1780 return isset($this->_packageInfo['dependencies']); 1781 } 1782 1783 function getPackagexmlVersion() 1784 { 1785 if (isset($this->_packageInfo['zendextsrcrelease'])) { 1786 return '2.1'; 1787 } 1788 if (isset($this->_packageInfo['zendextbinrelease'])) { 1789 return '2.1'; 1790 } 1791 return '2.0'; 1792 } 1793 1794 /** 1795 * @return array|false 1796 */ 1797 function getSourcePackage() 1798 { 1799 if (isset($this->_packageInfo['extbinrelease']) || 1800 isset($this->_packageInfo['zendextbinrelease'])) { 1801 return array('channel' => $this->_packageInfo['srcchannel'], 1802 'package' => $this->_packageInfo['srcpackage']); 1803 } 1804 return false; 1805 } 1806 1807 function getBundledPackages() 1808 { 1809 if (isset($this->_packageInfo['bundle'])) { 1810 return $this->_packageInfo['contents']['bundledpackage']; 1811 } 1812 return false; 1813 } 1814 1815 function getLastModified() 1816 { 1817 if (isset($this->_packageInfo['_lastmodified'])) { 1818 return $this->_packageInfo['_lastmodified']; 1819 } 1820 return false; 1821 } 1822 1823 /** 1824 * Get the contents of a file listed within the package.xml 1825 * @param string 1826 * @return string 1827 */ 1828 function getFileContents($file) 1829 { 1830 if ($this->_archiveFile == $this->_packageFile) { // unpacked 1831 $dir = dirname($this->_packageFile); 1832 $file = $dir . DIRECTORY_SEPARATOR . $file; 1833 $file = str_replace(array('/', '\\'), 1834 array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file); 1835 if (file_exists($file) && is_readable($file)) { 1836 return implode('', file($file)); 1837 } 1838 } else { // tgz 1839 $tar = &new Archive_Tar($this->_archiveFile); 1840 $tar->pushErrorHandling(PEAR_ERROR_RETURN); 1841 if ($file != 'package.xml' && $file != 'package2.xml') { 1842 $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file; 1843 } 1844 $file = $tar->extractInString($file); 1845 $tar->popErrorHandling(); 1846 if (PEAR::isError($file)) { 1847 return PEAR::raiseError("Cannot locate file '$file' in archive"); 1848 } 1849 return $file; 1850 } 1851 } 1852 1853 function &getRW() 1854 { 1855 if (!class_exists('PEAR_PackageFile_v2_rw')) { 1856 require_once 'PEAR/PackageFile/v2/rw.php'; 1857 } 1858 $a = new PEAR_PackageFile_v2_rw; 1859 foreach (get_object_vars($this) as $name => $unused) { 1860 if (!isset($this->$name)) { 1861 continue; 1862 } 1863 if ($name == '_config' || $name == '_logger'|| $name == '_registry' || 1864 $name == '_stack') { 1865 $a->$name = &$this->$name; 1866 } else { 1867 $a->$name = $this->$name; 1868 } 1869 } 1870 return $a; 1871 } 1872 1873 function &getDefaultGenerator() 1874 { 1875 if (!class_exists('PEAR_PackageFile_Generator_v2')) { 1876 require_once 'PEAR/PackageFile/Generator/v2.php'; 1877 } 1878 $a = &new PEAR_PackageFile_Generator_v2($this); 1879 return $a; 1880 } 1881 1882 function analyzeSourceCode($file, $string = false) 1883 { 1884 if (!isset($this->_v2Validator) || 1885 !is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) { 1886 if (!class_exists('PEAR_PackageFile_v2_Validator')) { 1887 require_once 'PEAR/PackageFile/v2/Validator.php'; 1888 } 1889 $this->_v2Validator = new PEAR_PackageFile_v2_Validator; 1890 } 1891 return $this->_v2Validator->analyzeSourceCode($file, $string); 1892 } 1893 1894 function validate($state = PEAR_VALIDATE_NORMAL) 1895 { 1896 if (!isset($this->_packageInfo) || !is_array($this->_packageInfo)) { 1897 return false; 1898 } 1899 if (!isset($this->_v2Validator) || 1900 !is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) { 1901 if (!class_exists('PEAR_PackageFile_v2_Validator')) { 1902 require_once 'PEAR/PackageFile/v2/Validator.php'; 1903 } 1904 $this->_v2Validator = new PEAR_PackageFile_v2_Validator; 1905 } 1906 if (isset($this->_packageInfo['xsdversion'])) { 1907 unset($this->_packageInfo['xsdversion']); 1908 } 1909 return $this->_v2Validator->validate($this, $state); 1910 } 1911 1912 function getTasksNs() 1913 { 1914 if (!isset($this->_tasksNs)) { 1915 if (isset($this->_packageInfo['attribs'])) { 1916 foreach ($this->_packageInfo['attribs'] as $name => $value) { 1917 if ($value == 'http://pear.php.net/dtd/tasks-1.0') { 1918 $this->_tasksNs = str_replace('xmlns:', '', $name); 1919 break; 1920 } 1921 } 1922 } 1923 } 1924 return $this->_tasksNs; 1925 } 1926 1927 /** 1928 * Determine whether a task name is a valid task. Custom tasks may be defined 1929 * using subdirectories by putting a "-" in the name, as in <tasks:mycustom-task> 1930 * 1931 * Note that this method will auto-load the task class file and test for the existence 1932 * of the name with "-" replaced by "_" as in PEAR/Task/mycustom/task.php makes class 1933 * PEAR_Task_mycustom_task 1934 * @param string 1935 * @return boolean 1936 */ 1937 function getTask($task) 1938 { 1939 $this->getTasksNs(); 1940 // transform all '-' to '/' and 'tasks:' to '' so tasks:replace becomes replace 1941 $task = str_replace(array($this->_tasksNs . ':', '-'), array('', ' '), $task); 1942 $task = str_replace(' ', '/', ucwords($task)); 1943 $ps = (strtolower(substr(PHP_OS, 0, 3)) == 'win') ? ';' : ':'; 1944 foreach (explode($ps, ini_get('include_path')) as $path) { 1945 if (file_exists($path . "/PEAR/Task/$task.php")) { 1946 include_once "PEAR/Task/$task.php"; 1947 $task = str_replace('/', '_', $task); 1948 if (class_exists("PEAR_Task_$task")) { 1949 return "PEAR_Task_$task"; 1950 } 1951 } 1952 } 1953 return false; 1954 } 1955 1956 /** 1957 * Key-friendly array_splice 1958 * @param tagname to splice a value in before 1959 * @param mixed the value to splice in 1960 * @param string the new tag name 1961 */ 1962 function _ksplice($array, $key, $value, $newkey) 1963 { 1964 $offset = array_search($key, array_keys($array)); 1965 $after = array_slice($array, $offset); 1966 $before = array_slice($array, 0, $offset); 1967 $before[$newkey] = $value; 1968 return array_merge($before, $after); 1969 } 1970 1971 /** 1972 * @param array a list of possible keys, in the order they may occur 1973 * @param mixed contents of the new package.xml tag 1974 * @param string tag name 1975 * @access private 1976 */ 1977 function _insertBefore($array, $keys, $contents, $newkey) 1978 { 1979 foreach ($keys as $key) { 1980 if (isset($array[$key])) { 1981 return $array = $this->_ksplice($array, $key, $contents, $newkey); 1982 } 1983 } 1984 $array[$newkey] = $contents; 1985 return $array; 1986 } 1987 1988 /** 1989 * @param subsection of {@link $_packageInfo} 1990 * @param array|string tag contents 1991 * @param array format: 1992 * <pre> 1993 * array( 1994 * tagname => array(list of tag names that follow this one), 1995 * childtagname => array(list of child tag names that follow this one), 1996 * ) 1997 * </pre> 1998 * 1999 * This allows construction of nested tags 2000 * @access private 2001 */ 2002 function _mergeTag($manip, $contents, $order) 2003 { 2004 if (count($order)) { 2005 foreach ($order as $tag => $curorder) { 2006 if (!isset($manip[$tag])) { 2007 // ensure that the tag is set up 2008 $manip = $this->_insertBefore($manip, $curorder, array(), $tag); 2009 } 2010 if (count($order) > 1) { 2011 $manip[$tag] = $this->_mergeTag($manip[$tag], $contents, array_slice($order, 1)); 2012 return $manip; 2013 } 2014 } 2015 } else { 2016 return $manip; 2017 } 2018 if (is_array($manip[$tag]) && !empty($manip[$tag]) && isset($manip[$tag][0])) { 2019 $manip[$tag][] = $contents; 2020 } else { 2021 if (!count($manip[$tag])) { 2022 $manip[$tag] = $contents; 2023 } else { 2024 $manip[$tag] = array($manip[$tag]); 2025 $manip[$tag][] = $contents; 2026 } 2027 } 2028 return $manip; 2029 } 2030 } 2031 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sun Feb 25 14:08:00 2007 | par Balluche grâce à PHPXref 0.7 |