Aggregate Code Coverage for all tests
1 : <?php 2 : /** 3 : * PEAR_PackageFile_v2, package.xml version 2.1 4 : * 5 : * PHP version 5 6 : * 7 : * @category PEAR2 8 : * @package PEAR2_Pyrus 9 : * @author Greg Beaver <cellog@php.net> 10 : * @copyright 2008 The PEAR Group 11 : * @license http://www.opensource.org/licenses/bsd-license.php New BSD License 12 : * @version SVN: $Id$ 13 : * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ 14 : */ 15 : 16 : /** 17 : * File representing a package.xml file version 2.1 18 : * 19 : * @category PEAR2 20 : * @package PEAR2_Pyrus 21 : * @author Greg Beaver <cellog@php.net> 22 : * @copyright 2008 The PEAR Group 23 : * @license http://www.opensource.org/licenses/bsd-license.php New BSD License 24 : * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ 25 : */ 26 : class PEAR2_Pyrus_PackageFile_v2 27 1 : { 28 : public $rootAttributes = array( 29 : 'version' => '2.1', 30 : 'xmlns' => 'http://pear.php.net/dtd/package-2.1', 31 : 'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0', 32 : 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 33 : 'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0 34 : http://pear.php.net/dtd/tasks-1.0.xsd 35 : http://pear.php.net/dtd/package-2.1 36 : http://pear.php.net/dtd/package-2.1.xsd', 37 : ); 38 : /** 39 : * Parsed package information 40 : * 41 : * For created-from-scratch packagefiles, set some basic information needed. 42 : * @var array 43 : * @access private 44 : */ 45 : protected $packageInfo = array('attribs' => array( 46 : 'version' => '2.1', 47 : 'xmlns' => 'http://pear.php.net/dtd/package-2.1', 48 : 'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0', 49 : 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 50 : 'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0 51 : http://pear.php.net/dtd/tasks-1.0.xsd 52 : http://pear.php.net/dtd/package-2.1 53 : http://pear.php.net/dtd/package-2.1.xsd', 54 : ), 55 : 'version' => array( 56 : 'release' => '0.1.0', 57 : 'api' => '0.1.0', 58 : ), 59 : 'stability' => array( 60 : 'release' => 'devel', 61 : 'api' => 'alpha', 62 : ), 63 : 'license' => array('attribs' => array('uri' => 'http://www.opensource.org/licenses/bsd-license.php'), 64 : '_content' => 'New BSD License', 65 : ), 66 : 'dependencies' => array( 67 : 'required' => array( 68 : 'php' => array('min' => '5.2.0'), 69 : 'pearinstaller' => array('min' => '2.0.0a1'), 70 : ), 71 : ), 72 : 'phprelease' => array(), 73 : ); 74 : 75 : /** 76 : * Set if the XML has been validated against schema 77 : * 78 : * @var unknown_type 79 : */ 80 : private $_schemaValidated = false; 81 : 82 : protected $filelist = array(); 83 : protected $baseinstalldirs = array(); 84 : private $_dirtree = array(); 85 : 86 : /** 87 : * path to package.xml or false if this is an abstract parsed-from-string xml 88 : * @var string|false 89 : * @access private 90 : */ 91 : protected $_packageFile = false; 92 : 93 : /** 94 : * path to archive containing this package file, or false if this is a package.xml 95 : * or abstract parsed-from-string xml 96 : * @var string|false 97 : * @access private 98 : */ 99 : protected $_archiveFile = false; 100 : 101 : /** 102 : * Optional Dependency group requested for installation 103 : * @var string 104 : * @access private 105 : */ 106 : var $_requestedGroup = false; 107 : 108 : /** 109 : * Namespace prefix used for tasks in this package.xml - use tasks: whenever possible 110 : */ 111 : var $_tasksNs; 112 : 113 : function setPackagefile($file, $archive = false) 114 : { 115 1 : $this->_packageFile = $file; 116 1 : $this->_archiveFile = $archive ? $archive : $file; 117 1 : } 118 : 119 : function getPackageFile() 120 : { 121 : return $this->_packageFile; 122 : } 123 : 124 : function getArchiveFile() 125 : { 126 : return $this->_archiveFile; 127 : } 128 : 129 : /** 130 : * Directly set the array that defines this packagefile 131 : * 132 : * WARNING: no validation. This should only be performed by internal methods 133 : * inside Pyrus or by inputting an array saved from an existing PEAR_PackageFile_v2 134 : * @param array 135 : */ 136 : function fromArray($pinfo) 137 : { 138 1 : $this->_schemaValidated = true; 139 1 : $this->packageInfo = $pinfo['package']; 140 1 : } 141 : 142 : function hasFile($file) 143 : { 144 : return isset($this->filelist[$file]); 145 : } 146 : 147 : function getFile($file) 148 : { 149 : return $this->filelist[$file]; 150 : } 151 : 152 : function setFilelist(array $list) 153 : { 154 1 : $this->filelist = $list; 155 1 : } 156 : 157 : function setBaseInstallDirs(array $list) 158 : { 159 1 : $this->baseinstalldirs = $list; 160 1 : } 161 : 162 : /** 163 : * @param string full path to file 164 : * @param string attribute name 165 : * @param string attribute value 166 : * @return bool success of operation 167 : */ 168 : function setFileAttribute($filename, $attr, $value) 169 : { 170 : if (!in_array($attr, array('role', 'name', 'baseinstalldir', 'install-as'), true)) { 171 : // check to see if this is a task 172 : if ($this->isValidTask($attr)) { 173 : if (!isset($this->filelist[$filename][$attr])) { 174 : $this->filelist[$filename][$attr] = $value; 175 : } else { 176 : if (!isset($this->filelist[$filename][$attr][0])) { 177 : $this->filelist[$filename][$attr] = array($this->filelist[$filename][$attr]); 178 : } 179 : $this->filelist[$filename][$attr][] = $value; 180 : } 181 : return; 182 : } 183 : throw new PEAR2_Pyrus_PackageFile_Exception( 184 : 'Cannot set invalid attribute ' . $attr . ' for file ' . $filename); 185 : } 186 : if (!isset($this->filelist[$filename])) { 187 : throw new PEAR2_Pyrus_PackageFile_Exception( 188 : 'Cannot set attribute ' . $attr . ' for non-existent file ' . $filename); 189 : } 190 : if ($attr == 'name') { 191 : throw new PEAR2_Pyrus_PackageFile_Exception('Cannot change name of file ' . 192 : $filename); 193 : } 194 : $this->filelist[$filename]['attribs'][$attr] = $value; 195 : } 196 : 197 : function isValidTask($name) 198 : { 199 : $tasksns = $this->getTasksNs(); 200 : if (strlen($name) <= strlen($tasksns) + 1) { 201 : return false; 202 : } 203 : if (substr($name, 0, strlen($tasksns)) === $tasksns) { 204 : if ($name[strlen($tasksns)] == ':') { 205 : return true; 206 : } 207 : } 208 : return false; 209 : } 210 : 211 : /** 212 : * Used by uninstallation to set directory locations to erase 213 : * @param string $path 214 : */ 215 : function setDirtree($path) 216 : { 217 : $this->_dirtree[$path] = true; 218 : } 219 : 220 : function getDirtree() 221 : { 222 : return $this->_dirtree; 223 : } 224 : 225 : /** 226 : * Determines whether this package claims it is compatible with the version of 227 : * the package that has a recommended version dependency 228 : * @param PEAR_PackageFile_v2|PEAR_PackageFile_v1|PEAR_Downloader_Package 229 : * @return boolean 230 : */ 231 : function isCompatible($pf) 232 : { 233 : if (!isset($this->packageInfo['compatible'])) { 234 : return false; 235 : } 236 : if (!isset($this->packageInfo['channel'])) { 237 : return false; 238 : } 239 : $me = $pf->version['release']; 240 : $compatible = $this->packageInfo['compatible']; 241 : if (!isset($compatible[0])) { 242 : $compatible = array($compatible); 243 : } 244 : $found = false; 245 : foreach ($compatible as $info) { 246 : if (strtolower($info['name']) == strtolower($pf->package)) { 247 : if (strtolower($info['channel']) == strtolower($pf->channel)) { 248 : $found = true; 249 : break; 250 : } 251 : } 252 : } 253 : if (!$found) { 254 : return false; 255 : } 256 : if (isset($info['exclude'])) { 257 : if (!isset($info['exclude'][0])) { 258 : $info['exclude'] = array($info['exclude']); 259 : } 260 : foreach ($info['exclude'] as $exclude) { 261 : if (version_compare($me, $exclude, '==')) { 262 : return false; 263 : } 264 : } 265 : } 266 : if (version_compare($me, $info['min'], '>=') && version_compare($me, $info['max'], '<=')) { 267 : return true; 268 : } 269 : return false; 270 : } 271 : 272 : function isSubpackageOf(PEAR2_Pyrus_PackageFile_v2 $p) 273 : { 274 : return $p->isSubpackage($this); 275 : } 276 : 277 : /** 278 : * Determines whether the passed in package is a subpackage of this package. 279 : * 280 : * No version checking is done, only name verification. 281 : * @return bool 282 : */ 283 : function isSubpackage(PEAR2_Pyrus_PackageFile_v2 $p) 284 : { 285 : $sub = array(); 286 : if (isset($this->packageInfo['dependencies']['required']['subpackage'])) { 287 : $sub = $this->packageInfo['dependencies']['required']['subpackage']; 288 : if (!isset($sub[0])) { 289 : $sub = array($sub); 290 : } 291 : } 292 : if (isset($this->packageInfo['dependencies']['optional']['subpackage'])) { 293 : $sub1 = $this->packageInfo['dependencies']['optional']['subpackage']; 294 : if (!isset($sub1[0])) { 295 : $sub1 = array($sub1); 296 : } 297 : $sub = array_merge($sub, $sub1); 298 : } 299 : if (isset($this->packageInfo['dependencies']['group'])) { 300 : $group = $this->packageInfo['dependencies']['group']; 301 : if (!isset($group[0])) { 302 : $group = array($group); 303 : } 304 : foreach ($group as $deps) { 305 : if (isset($deps['subpackage'])) { 306 : $sub2 = $deps['subpackage']; 307 : if (!isset($sub2[0])) { 308 : $sub2 = array($sub2); 309 : } 310 : $sub = array_merge($sub, $sub2); 311 : } 312 : } 313 : } 314 : foreach ($sub as $dep) { 315 : if (strtolower($dep['name']) == strtolower($p->package)) { 316 : if (isset($dep['channel'])) { 317 : if (strtolower($dep['channel']) == strtolower($p->channel)) { 318 : return true; 319 : } 320 : } else { 321 : if ($dep['uri'] == $p->uri) { 322 : return true; 323 : } 324 : } 325 : } 326 : } 327 : return false; 328 : } 329 : 330 : function dependsOn($package, $channel) 331 : { 332 : if (!($deps = $this->dependencies)) { 333 : return false; 334 : } 335 : foreach (array('package', 'subpackage') as $type) { 336 : foreach (array('required', 'optional') as $needed) { 337 : if (isset($deps[$needed][$type])) { 338 : if (!isset($deps[$needed][$type][0])) { 339 : $deps[$needed][$type] = array($deps[$needed][$type]); 340 : } 341 : foreach ($deps[$needed][$type] as $dep) { 342 : $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; 343 : if (strtolower($dep['name']) == strtolower($package) && 344 : $depchannel == $channel) { 345 : return true; 346 : } 347 : } 348 : } 349 : } 350 : if (isset($deps['group'])) { 351 : if (!isset($deps['group'][0])) { 352 : $dep['group'] = array($deps['group']); 353 : } 354 : foreach ($deps['group'] as $group) { 355 : if (isset($group[$type])) { 356 : if (!is_array($group[$type])) { 357 : $group[$type] = array($group[$type]); 358 : } 359 : foreach ($group[$type] as $dep) { 360 : $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; 361 : if (strtolower($dep['name']) == strtolower($package) && 362 : $depchannel == $channel) { 363 : return true; 364 : } 365 : } 366 : } 367 : } 368 : } 369 : } 370 : return false; 371 : } 372 : 373 : /** 374 : * Get the contents of a dependency group 375 : * @param string 376 : * @return array|false 377 : */ 378 : function getDependencyGroup($name) 379 : { 380 : $name = strtolower($name); 381 : if (!isset($this->packageInfo['dependencies']['group'])) { 382 : return false; 383 : } 384 : $groups = $this->packageInfo['dependencies']['group']; 385 : if (!isset($groups[0])) { 386 : $groups = array($groups); 387 : } 388 : foreach ($groups as $group) { 389 : if (strtolower($group['attribs']['name']) == $name) { 390 : return $group; 391 : } 392 : } 393 : return false; 394 : } 395 : 396 : /** 397 : * @return php|extsrc|extbin|zendextsrc|zendextbin|bundle|false 398 : */ 399 : function getPackageType() 400 : { 401 1 : if (isset($this->packageInfo['phprelease'])) { 402 1 : return 'php'; 403 : } 404 : if (isset($this->packageInfo['extsrcrelease'])) { 405 : return 'extsrc'; 406 : } 407 : if (isset($this->packageInfo['extbinrelease'])) { 408 : return 'extbin'; 409 : } 410 : if (isset($this->packageInfo['zendextsrcrelease'])) { 411 : return 'zendextsrc'; 412 : } 413 : if (isset($this->packageInfo['zendextbinrelease'])) { 414 : return 'zendextbin'; 415 : } 416 : if (isset($this->packageInfo['bundle'])) { 417 : return 'bundle'; 418 : } 419 : return false; 420 : } 421 : 422 : function hasDeps() 423 : { 424 : return isset($this->packageInfo['dependencies']); 425 : } 426 : 427 : function getPackagexmlVersion() 428 : { 429 : if (isset($this->packageInfo['zendextsrcrelease'])) { 430 : return '2.1'; 431 : } 432 : if (isset($this->packageInfo['zendextbinrelease'])) { 433 : return '2.1'; 434 : } 435 : return '2.0'; 436 : } 437 : 438 : /** 439 : * validate dependencies against the local registry, packages to be installed, 440 : * and environment (php version, OS, architecture, enabled extensions) 441 : * 442 : * @param array $toInstall an array of PEAR2_Pyrus_Package objects 443 : * @param PEAR2_MultiErrors $errs 444 : */ 445 : function validateDependencies(array $toInstall, PEAR2_MultiErrors $errs) 446 : { 447 : $dep = new PEAR2_Pyrus_Dependency_Validator($this->packageInfo['name'], 448 : PEAR2_Pyrus_Validate::DOWNLOADING, $errs); 449 : $dep->validatePhpDependency($this->dependencies->required->php); 450 : $dep->validatePearinstallerDependency($this->dependencies->required->pearinstaller); 451 : foreach (array('required', 'optional') as $required) { 452 : foreach ($this->dependencies->$required->package as $d) { 453 : $dep->validatePackageDependency($d, $required == 'required', $toInstall); 454 : } 455 : foreach ($this->dependencies->$required->subpackage as $d) { 456 : $dep->validateSubpackageDependency($d, $required == 'required', $toInstall); 457 : } 458 : foreach ($this->dependencies->$required->extension as $d) { 459 : $dep->validateExtensionDependency($d, $required == 'required'); 460 : } 461 : } 462 : foreach ($this->dependencies->required->arch as $d) { 463 : $dep->validateArchDependency($d); 464 : } 465 : foreach ($this->dependencies->required->os as $d) { 466 : $dep->validateOsDependency($d); 467 : } 468 : } 469 : 470 : function validate($state = PEAR2_Pyrus_Validate::NORMAL) 471 : { 472 : if (!isset($this->packageInfo) || !is_array($this->packageInfo)) { 473 : return false; 474 : } 475 : $validator = new PEAR2_Pyrus_PackageFile_v2_Validator; 476 : return $validator->validate($this, $state); 477 : } 478 : 479 : function getTasksNs() 480 : { 481 : if (!isset($this->_tasksNs)) { 482 : if (isset($this->packageInfo['attribs'])) { 483 : foreach ($this->packageInfo['attribs'] as $name => $value) { 484 : if ($value == 'http://pear.php.net/dtd/tasks-1.0') { 485 : $this->_tasksNs = str_replace('xmlns:', '', $name); 486 : break; 487 : } 488 : } 489 : } 490 : } 491 : return $this->_tasksNs; 492 : } 493 : 494 : /** 495 : * Determine whether a task name is a valid task. Custom tasks may be defined 496 : * using subdirectories by putting a "-" in the name, as in <tasks:mycustom-task> 497 : * 498 : * Note that this method will auto-load the task class file and test for the existence 499 : * of the name with "-" replaced by "_" as in PEAR/Task/mycustom/task.php makes class 500 : * PEAR_Task_mycustom_task 501 : * @param string 502 : * @return boolean 503 : */ 504 : function getTask($task) 505 : { 506 : $this->getTasksNs(); 507 : // transform all '-' to '/' and 'tasks:' to '' so tasks:replace becomes replace 508 : $task = str_replace(array($this->_tasksNs . ':', '-'), array('', ' '), $task); 509 : $task = str_replace(' ', '/', ucwords($task)); 510 : $test = str_replace('/', '_', $task); 511 : if (class_exists("PEAR2_Pyrus_Task_$test", true)) { 512 : return "PEAR2_Pyrus_Task_$test"; 513 : } 514 : return false; 515 : } 516 : 517 : function getBaseInstallDir($file) 518 : { 519 1 : $file = dirname($file); 520 1 : while ($file !== '.' && $file != '/') { 521 1 : if (isset($this->baseinstalldirs[$file])) { 522 1 : return $this->baseinstalldirs[$file]; 523 : } 524 1 : $file = dirname($file); 525 1 : } 526 1 : if (isset($this->baseinstalldirs[''])) { 527 : return $this->baseinstalldirs['']; 528 : } 529 1 : return false; 530 : } 531 : 532 : function __get($var) 533 : { 534 : switch ($var) { 535 1 : case 'bundledpackage' : 536 : if ($this->getPackageType() !== 'bundle') { 537 : return false; 538 : } 539 : if (!isset($this->packageInfo['contents'])) { 540 : $this->packageInfo['contents'] = array(); 541 : } 542 : if (!isset($this->packageInfo['contents']['bundledpackage'])) { 543 : $this->packageInfo['contents']['bundledpackage'] = array(); 544 : } 545 : return new ArrayObject($this->packageInfo['contents']['bundledpackage'], 546 : ArrayObject::ARRAY_AS_PROPS); 547 1 : case 'packagefile' : 548 : return $this->_packageFile; 549 1 : case 'filepath' : 550 : return dirname($this->_packageFile); 551 1 : case 'contents' : 552 : // allows stuff like: 553 : // foreach ($pf->contents as $file) { 554 : // echo $file->name; 555 : // $file->installed_as = 'hi'; 556 : // } 557 : return new PEAR2_Pyrus_PackageFile_v2Iterator_File( 558 : new PEAR2_Pyrus_PackageFile_v2Iterator_FileAttribsFilter( 559 : new PEAR2_Pyrus_PackageFile_v2Iterator_FileContents( 560 : $this->packageInfo['contents'], 'contents', $this)), 561 : RecursiveIteratorIterator::LEAVES_ONLY); 562 1 : case 'installcontents' : 563 1 : PEAR2_Pyrus_PackageFile_v2Iterator_FileInstallationFilter::setParent($this); 564 1 : return new PEAR2_Pyrus_PackageFile_v2Iterator_FileInstallationFilter( 565 1 : new ArrayIterator( 566 1 : $this->filelist)); 567 1 : case 'packagingcontents' : 568 : PEAR2_Pyrus_PackageFile_v2Iterator_PackagingIterator::setParent($this); 569 : return new PEAR2_Pyrus_PackageFile_v2Iterator_PackagingIterator( 570 : $this->filelist); 571 1 : case 'installGroup' : 572 1 : $rel = $this->getPackageType(); 573 1 : if ($rel != 'bundle') $rel .= 'release'; 574 1 : $ret = $this->packageInfo[$rel]; 575 1 : if (!isset($ret[0])) { 576 1 : return array($ret); 577 : } 578 : return $ret; 579 1 : case 'channel' : 580 1 : if (isset($this->packageInfo['uri'])) { 581 : return '__uri'; 582 : } 583 1 : break; 584 1 : case 'state' : 585 : if (!isset($this->packageInfo['stability']) || 586 : !isset($this->packageInfo['stability']['release'])) { 587 : return false; 588 : } 589 : return $this->packageInfo['stability']['release']; 590 1 : case 'api-version' : 591 : if (!isset($this->packageInfo['version']) || 592 : !isset($this->packageInfo['version']['api'])) { 593 : return false; 594 : } 595 : return $this->packageInfo['version']['api']; 596 1 : case 'release-version' : 597 : if (!isset($this->packageInfo['version']) || 598 : !isset($this->packageInfo['version']['release'])) { 599 : return false; 600 : } 601 : return $this->packageInfo['version']['release']; 602 1 : case 'api-state' : 603 : if (!isset($this->packageInfo['stability']) || 604 : !isset($this->packageInfo['stability']['api'])) { 605 : return false; 606 : } 607 : return $this->packageInfo['stability']['api']; 608 1 : case 'allmaintainers' : 609 1 : $leads = (array) $this->tag('lead'); 610 1 : if ($leads && !isset($leads[0])) { 611 : $leads = array($leads); 612 : } 613 1 : $developers = (array) $this->tag('developer'); 614 1 : if ($developers && !isset($developers[0])) { 615 : $developers = array($developers); 616 : } 617 1 : $helpers = (array) $this->tag('helper'); 618 1 : if ($helpers && !isset($helpers[0])) { 619 : $helpers = array($helpers); 620 : } 621 1 : $contributors = (array) $this->tag('contributor'); 622 1 : if ($contributors && !isset($contributors[0])) { 623 : $contributors = array($contributors); 624 : } 625 : return array( 626 1 : 'lead' => $leads, 627 1 : 'developer' => $developers, 628 1 : 'helper' => $helpers, 629 : 'contributor' => $contributors 630 1 : ); 631 1 : case 'releases' : 632 : $type = $this->getPackageType(); 633 : if ($type != 'bundle') { 634 : $type .= 'release'; 635 : } 636 : if ($type && isset($this->packageInfo[$type])) { 637 : return $this->packageInfo[$type]; 638 : } 639 : return false; 640 1 : case 'sourcepackage' : 641 : if (isset($this->packageInfo['extbinrelease']) || 642 : isset($this->packageInfo['zendextbinrelease'])) { 643 : return array('channel' => $this->packageInfo['srcchannel'], 644 : 'package' => $this->packageInfo['srcpackage']); 645 : } 646 : return false; 647 1 : case 'license' : 648 1 : if (!isset($this->packageInfo['license'])) { 649 : $this->packageInfo['license'] = array(); 650 : } 651 1 : return new PEAR2_Pyrus_PackageFile_v2_License($this->packageInfo['license']); 652 1 : case 'files' : 653 : return new PEAR2_Pyrus_PackageFile_v2_Files($this->filelist); 654 1 : case 'maintainer' : 655 : return new PEAR2_Pyrus_PackageFile_v2_Developer($this->packageInfo); 656 1 : case 'rawdeps' : 657 : return isset($this->packageInfo['dependencies']) ? 658 : $this->packageInfo['dependencies'] : false; 659 1 : case 'dependencies' : 660 1 : if (!isset($this->packageInfo['dependencies'])) { 661 : $this->packageInfo['dependencies'] = array(); 662 : } 663 1 : return new PEAR2_Pyrus_PackageFile_v2_Dependencies( 664 1 : $this->packageInfo['dependencies'], 665 1 : $this->packageInfo['dependencies']); 666 1 : case 'release' : 667 : $t = $this->getPackageType(); 668 : if (!$t) { 669 : $this->type = 'php'; 670 : $t = 'phprelease'; 671 : } else { 672 : if ($t != 'bundle') { 673 : $t .= 'release'; 674 : } 675 : } 676 : if (!isset($this->packageInfo[$t]) || !is_array($this->packageInfo[$t])) { 677 : $this->packageInfo[$t] = array(); 678 : } 679 : return new PEAR2_Pyrus_PackageFile_v2_Release( 680 : $this, $this->packageInfo[$t], $this->filelist); 681 1 : case 'compatible' : 682 : return new PEAR2_Pyrus_PackageFile_v2_Compatible($this->packageInfo); 683 1 : case 'schemaOK' : 684 : return $this->_schemaValidated; 685 : } 686 1 : return $this->tag($var); 687 : } 688 : 689 : function __set($var, $value) 690 : { 691 : if ($var === 'license') { 692 : if ($value instanceof PEAR2_Pyrus_PackageFile_v2_License) { 693 : $this->packageInfo['license'] = $value->getArray(); 694 : $value->link($this->packageInfo['license']); 695 : } elseif (!is_array($value)) { 696 : $licensemap = 697 : array( 698 : 'php' => 'http://www.php.net/license', 699 : 'php license' => 'http://www.php.net/license', 700 : 'lgpl' => 'http://www.gnu.org/copyleft/lesser.html', 701 : 'bsd' => 'http://www.opensource.org/licenses/bsd-license.php', 702 : 'bsd style' => 'http://www.opensource.org/licenses/bsd-license.php', 703 : 'bsd-style' => 'http://www.opensource.org/licenses/bsd-license.php', 704 : 'mit' => 'http://www.opensource.org/licenses/mit-license.php', 705 : 'gpl' => 'http://www.gnu.org/copyleft/gpl.html', 706 : 'apache' => 'http://www.opensource.org/licenses/apache2.0.php' 707 : ); 708 : if (isset($licensemap[strtolower($value)])) { 709 : $this->packageInfo['license'] = array( 710 : 'attribs' => array('uri' => 711 : $licensemap[strtolower($value)]), 712 : '_content' => $value 713 : ); 714 : } else { 715 : // don't use bogus uri 716 : $arr['license'] = $value; 717 : } 718 : } else { 719 : $this->packageInfo['license'] = $value; 720 : } 721 : return; 722 : } 723 : if ($var === 'type') { 724 : if (!is_string($value)) { 725 : throw new PEAR2_Pyrus_PackageFile_Exception('package.xml type must be a ' . 726 : 'string, was a ' . gettype($value)); 727 : } 728 : if ($value != 'bundle') { 729 : $value .= 'release'; 730 : } 731 : if (in_array($value, $a = array('phprelease', 'extsrcrelease', 'extbinrelease', 732 : 'zendextsrcrelease', 'zendextbinrelease', 'bundle'))) { 733 : foreach ($a as $type) { 734 : if ($value == $type) { 735 : if (!isset($this->packageInfo[$type])) { 736 : $this->packageInfo[$type] = array(); 737 : } 738 : continue; 739 : } 740 : if (isset($this->packageInfo[$type])) { 741 : unset($this->packageInfo[$type]); 742 : } 743 : } 744 : } 745 : return; 746 : } 747 : if ($var === 'dependencies' && $value === null) { 748 : $this->packageInfo['dependencies'] = array(); 749 : return; 750 : } 751 : if ($var === 'rawdependencies' && is_array($value)) { 752 : $this->packageInfo['dependencies'] = $value; 753 : return; 754 : } 755 : if ($var === 'rawrelease' && is_array($value)) { 756 : $t = $this->getPackageType(); 757 : if ($t != 'bundle') { 758 : $t .= 'release'; 759 : } 760 : $this->packageInfo[$t] = $value; 761 : return; 762 : } 763 : if ($var === 'rawcompatible' && is_array($value)) { 764 : $this->packageInfo['compatible'] = $value; 765 : return; 766 : } 767 : if ($var === 'rawstability' && is_string($value)) { 768 : $this->packageInfo['stability'] = array('release' => $value, 'api' => $value); 769 : return; 770 : } 771 : if ($var === 'packagerversion' && is_string($value)) { 772 : $this->packageInfo['attribs']['packagerversion'] = $value; 773 : return; 774 : } 775 : if ($var === 'release' && $value === null) { 776 : $type = $this->getPackageType(); 777 : if ($type != 'bundle') { 778 : $type .= 'release'; 779 : } 780 : $this->packageInfo[$type] = array(); 781 : return; 782 : } 783 : if ($value instanceof ArrayObject) { 784 : $value = $value->getArrayCopy(); 785 : } 786 : if ($var === 'release' && $value === null) { 787 : $rel = $this->getPackageType(); 788 : if ($rel) { 789 : if (isset($this->packageInfo[$rel . 'release'])) { 790 : $rel .= 'release'; 791 : } 792 : $this->packageInfo[$rel] = array(); 793 : } 794 : } 795 : if (in_array($var, array('attribs', 'lead', 796 : 'developer', 'contributor', 'helper', 'version', 797 : 'stability', 'license', 'contents', 'compatible', 798 : 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 799 : 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', 800 : 'extbinrelease', 'bundle', 'changelog'), true)) { 801 : throw new PEAR2_Pyrus_PackageFile_Exception('Cannot set ' . $var . ' directly'); 802 : } 803 : if (!in_array($var, array('name', 'channel', 'uri', 'extends', 'summary', 804 : 'description', 'date', 'time','notes'), true)) { 805 : return; 806 : } 807 : if ($var === 'uri') { 808 : if (isset($this->packageInfo['channel'])) { 809 : unset($this->packageInfo['channel']); 810 : } 811 : } 812 : if ($var == 'api-version') { 813 : $this->packageInfo['version']['api'] = $value; 814 : return; 815 : } 816 : if ($var == 'release-version') { 817 : $this->packageInfo['version']['release'] = $value; 818 : } 819 : $this->packageInfo[$var] = $value; 820 1 : } 821 1 : 822 1 : /** 823 1 : * Return the contents of a tag 824 : * @param string $name 825 : */ 826 1 : protected function tag($name) 827 1 : { 828 : if (!isset($this->packageInfo[$name]) && in_array($name, array('version', 829 1 : 'stability', 'license', 'compatible', 830 1 : 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 831 : ), true)) { 832 1 : $this->packageInfo[$name] = array(); 833 : } 834 : if (!isset($this->packageInfo[$name])) { 835 : return false; 836 : } 837 : if (is_array($this->packageInfo[$name])) { 838 : return new ArrayObject($this->packageInfo[$name], ArrayObject::ARRAY_AS_PROPS); 839 : } 840 : return $this->packageInfo[$name]; 841 : } 842 : 843 : /** 844 : * Update the changelog based on the current information 845 : */ 846 : function updateChangelog() 847 : { 848 : $license = $this->license; 849 : if ($license instanceof ArrayObject) { 850 : $license = $license->getArrayCopy(); 851 : } 852 : $info = array( 853 : 'version' => array( 854 : 'release' => $this->version['release'], 855 : 'api' => $this->version['api'] 856 : ), 857 : 'stability' => array( 858 : 'release' => $this->stability['release'], 859 : 'api' => $this->stability['api'] 860 : ), 861 : 'date' => $this->date, 862 : 'license' => $license, 863 : 'notes' => $this->notes, 864 : ); 865 : 866 : if (!is_array($this->packageInfo['changelog'])) { 867 : $this->packageInfo['changelog'] = $info; 868 : } elseif (!isset($this->packageInfo['changelog'][0])) { 869 : $this->packageInfo['changelog'] = array($info, $this->packageInfo['changelog']); 870 : } else { 871 : array_unshift($this->packageInfo['changelog'], $info); 872 : } 873 : } 874 : 875 : function __toString() 876 : { 877 : $this->packageInfo['attribs'] = $this->rootAttributes; 878 : $this->packageInfo['date'] = date('Y-m-d'); 879 : $this->packageInfo['time'] = date('H:i:s'); 880 : $arr = $this->toArray(); 881 : return (string) new PEAR2_Pyrus_XMLWriter($arr); 882 : } 883 : 884 : public static function sortInstallAs($a, $b) 885 : { 886 : return strnatcasecmp($a['attribs']['name'], $b['attribs']['name']); 887 : } 888 : 889 : function toArray($forpackaging = false) 890 : { 891 : $this->packageInfo['contents'] = array( 892 : 'dir' => array( 893 : 'attribs' => array('name' => '/'), 894 : 'file' => array() 895 : )); 896 : uksort($this->filelist, 'strnatcasecmp'); 897 : $a = array_reverse($this->filelist, 1); 898 : if ($forpackaging) { 899 : PEAR2_Pyrus_PackageFile_v2Iterator_PackagingIterator::setParent($this); 900 : $a = new PEAR2_Pyrus_PackageFile_v2Iterator_PackagingIterator($a); 901 : } 902 : $temp = array(); 903 : foreach ($a as $name => $stuff) { 904 : if ($forpackaging) { 905 : // map old to new name 906 : $temp[$stuff['attribs']['name']] = $name; 907 : } 908 : // if we are packaging, $name is the new name 909 : $stuff['attribs']['name'] = $name; 910 : $this->packageInfo['contents']['dir']['file'][] = $stuff; 911 : } 912 : if (count($this->packageInfo['contents']['dir']['file']) == 1) { 913 : $this->packageInfo['contents']['dir']['file'] = 914 : $this->packageInfo['contents']['dir']['file'][0]; 915 : } 916 : $arr = array(); 917 : foreach (array('attribs', 'name', 'channel', 'uri', 'extends', 'summary', 918 : 'description', 'lead', 919 : 'developer', 'contributor', 'helper', 'date', 'time', 'version', 920 : 'stability', 'license', 'notes', 'contents', 'compatible', 921 : 'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri', 922 : 'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease', 923 : 'extbinrelease', 'bundle', 'changelog') as $index) 924 : { 925 : if (!isset($this->packageInfo[$index])) { 926 : continue; 927 : } 928 : $arr[$index] = $this->packageInfo[$index]; 929 : } 930 : if ($forpackaging) { 931 : // process releases 932 : $reltag = $this->getPackageType(); 933 : if ($reltag != 'bundle') { 934 : $reltag .= 'release'; 935 : if (is_array($arr[$reltag])) { 936 : if (!isset($arr[$reltag][0])) { 937 : $arr[$reltag] = array($arr[$reltag]); 938 : } 939 : foreach ($arr[$reltag] as $i => $inf) { 940 : if (!isset($inf['filelist'])) { 941 : continue; 942 : } 943 : $inf = $inf['filelist']; 944 : if (isset($inf['install'])) { 945 : if (!isset($inf['install'][0])) { 946 : if (isset($temp[$inf['install']['attribs']['name']])) { 947 : $arr[$reltag][$i]['filelist']['install']['attribs'] 948 : ['name'] = 949 : $temp[$inf['install']['attribs']['name']]; 950 : } 951 : } else { 952 : foreach ($inf['install'] as $j => $morinf) { 953 : if (isset($temp[$morinf['attribs']['name']])) { 954 : $arr[$reltag][$i]['filelist']['install'][$j] 955 : ['attribs']['name'] = 956 : $temp[$morinf['attribs']['name']]; 957 : } 958 : } 959 : } 960 : } 961 : if (isset($inf['ignore'])) { 962 : if (!isset($inf['ignore'][0])) { 963 : if (isset($temp[$inf['ignore']['attribs']['name']])) { 964 : $arr[$reltag][$i]['filelist']['ignore'] 965 : ['attribs']['name'] = 966 : $temp[$inf['ignore']['attribs']['name']]; 967 : } 968 : } else { 969 : foreach ($inf['ignore'] as $j => $morinf) { 970 : if (isset($temp[$morinf['attribs']['name']])) { 971 : $arr[$reltag][$i]['filelist']['ignore'][$j] 972 : ['attribs']['name'] = 973 : $temp[$morinf['attribs']['name']]; 974 : } 975 : } 976 : } 977 : } 978 : } 979 : if (count($arr[$reltag]) == 1) { 980 : $arr[$reltag] = $arr[$reltag][0]; 981 : } 982 : } 983 : } 984 : } 985 : $reltag = $this->getPackageType(); 986 : if ($reltag != 'bundle') { 987 : $reltag .= 'release'; 988 : if (!is_array($arr[$reltag])) { 989 : // do nothing 990 : } elseif (!isset($arr[$reltag][0])) { 991 : if (isset($arr[$reltag]['install']) && isset($arr[$reltag]['install'][0])) { 992 : usort($arr[$reltag]['install'], array('PEAR2_Pyrus_PackageFile_v2', 993 : 'sortInstallAs')); 994 : } 995 : if (isset($arr[$reltag]['ignore']) && isset($arr[$reltag]['ignore'][0])) { 996 : usort($arr[$reltag]['ignore'], array('PEAR2_Pyrus_PackageFile_v2', 997 : 'sortInstallAs')); 998 : } 999 : } else { 1000 : foreach ($arr[$reltag] as $i => &$contents) { 1001 : if (isset($contents['install']) && isset($contents['install'][0])) { 1002 : usort($contents['install'], array('PEAR2_Pyrus_PackageFile_v2', 1003 : 'sortInstallAs')); 1004 : } 1005 : if (isset($contents['ignore']) && isset($contents['ignore'][0])) { 1006 : usort($contents['ignore'], array('PEAR2_Pyrus_PackageFile_v2', 1007 : 'sortInstallAs')); 1008 : } 1009 : } 1010 : } 1011 : } 1012 : if (isset($this->packageInfo['dependencies'])) { 1013 : if (isset($this->packageInfo['dependencies']['required'])) { 1014 : $arr['dependencies']['required'] = array(); 1015 : foreach (array('php', 'pearinstaller', 'package', 'subpackage', 1016 : 'extension', 'os', 'arch') as $index) { 1017 : if (!isset($this->packageInfo['dependencies']['required'][$index])) { 1018 : continue; 1019 : } 1020 : $arr['dependencies']['required'][$index] = 1021 : $this->packageInfo['dependencies']['required'][$index]; 1022 : } 1023 : } 1024 : if (isset($this->packageInfo['dependencies']['optional'])) { 1025 : $arr['dependencies']['optional'] = array(); 1026 : foreach (array('package', 'subpackage', 'extension') as $index) { 1027 : if (!isset($this->packageInfo['dependencies']['optional'][$index])) { 1028 : continue; 1029 : } 1030 : $arr['dependencies']['optional'][$index] = 1031 : $this->packageInfo['dependencies']['optional'][$index]; 1032 : } 1033 : } 1034 : if (isset($this->packageInfo['dependencies']['group'])) { 1035 : if (isset($this->packageInfo['dependencies']['group'][0])) { 1036 : foreach ($this->packageInfo['dependencies']['group'] as $i => $g) { 1037 : $arr['dependencies']['group'][$i] = array(); 1038 : foreach (array('attribs', 'package', 'subpackage', 'extension') as $index) { 1039 : if (!isset($g[$index])) { 1040 : continue; 1041 : } 1042 : $arr['dependencies']['group'][$i][$index] = $g[$index]; 1043 : } 1044 : } 1045 : } else { 1046 : $a = $this->packageInfo['dependencies']['group']; 1047 : $arr['dependencies']['group'] = array(); 1048 : foreach (array('attribs', 'package', 'subpackage', 'extension') as $index) { 1049 : if (!isset($a[$index])) { 1050 : continue; 1051 : } 1052 1 : $arr['dependencies']['group'][$index] = $a[$index]; 1053 : } 1054 : } 1055 : } 1056 : } 1057 : return array('package' => $arr); 1058 : } 1059 : }