| [ Index ] |
|
Code source de PHP PEAR 1.4.5 |
1 <?php 2 /** 3 * PEAR_PackageFile_v1, package.xml version 1.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: v1.php,v 1.72 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 /** 28 * Error code if parsing is attempted with no xml extension 29 */ 30 define('PEAR_PACKAGEFILE_ERROR_NO_XML_EXT', 3); 31 32 /** 33 * Error code if creating the xml parser resource fails 34 */ 35 define('PEAR_PACKAGEFILE_ERROR_CANT_MAKE_PARSER', 4); 36 37 /** 38 * Error code used for all sax xml parsing errors 39 */ 40 define('PEAR_PACKAGEFILE_ERROR_PARSER_ERROR', 5); 41 42 /** 43 * Error code used when there is no name 44 */ 45 define('PEAR_PACKAGEFILE_ERROR_NO_NAME', 6); 46 47 /** 48 * Error code when a package name is not valid 49 */ 50 define('PEAR_PACKAGEFILE_ERROR_INVALID_NAME', 7); 51 52 /** 53 * Error code used when no summary is parsed 54 */ 55 define('PEAR_PACKAGEFILE_ERROR_NO_SUMMARY', 8); 56 57 /** 58 * Error code for summaries that are more than 1 line 59 */ 60 define('PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY', 9); 61 62 /** 63 * Error code used when no description is present 64 */ 65 define('PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION', 10); 66 67 /** 68 * Error code used when no license is present 69 */ 70 define('PEAR_PACKAGEFILE_ERROR_NO_LICENSE', 11); 71 72 /** 73 * Error code used when a <version> version number is not present 74 */ 75 define('PEAR_PACKAGEFILE_ERROR_NO_VERSION', 12); 76 77 /** 78 * Error code used when a <version> version number is invalid 79 */ 80 define('PEAR_PACKAGEFILE_ERROR_INVALID_VERSION', 13); 81 82 /** 83 * Error code when release state is missing 84 */ 85 define('PEAR_PACKAGEFILE_ERROR_NO_STATE', 14); 86 87 /** 88 * Error code when release state is invalid 89 */ 90 define('PEAR_PACKAGEFILE_ERROR_INVALID_STATE', 15); 91 92 /** 93 * Error code when release state is missing 94 */ 95 define('PEAR_PACKAGEFILE_ERROR_NO_DATE', 16); 96 97 /** 98 * Error code when release state is invalid 99 */ 100 define('PEAR_PACKAGEFILE_ERROR_INVALID_DATE', 17); 101 102 /** 103 * Error code when no release notes are found 104 */ 105 define('PEAR_PACKAGEFILE_ERROR_NO_NOTES', 18); 106 107 /** 108 * Error code when no maintainers are found 109 */ 110 define('PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS', 19); 111 112 /** 113 * Error code when a maintainer has no handle 114 */ 115 define('PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE', 20); 116 117 /** 118 * Error code when a maintainer has no handle 119 */ 120 define('PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE', 21); 121 122 /** 123 * Error code when a maintainer has no name 124 */ 125 define('PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME', 22); 126 127 /** 128 * Error code when a maintainer has no email 129 */ 130 define('PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL', 23); 131 132 /** 133 * Error code when a maintainer has no handle 134 */ 135 define('PEAR_PACKAGEFILE_ERROR_INVALID_MAINTROLE', 24); 136 137 /** 138 * Error code when a dependency is not a PHP dependency, but has no name 139 */ 140 define('PEAR_PACKAGEFILE_ERROR_NO_DEPNAME', 25); 141 142 /** 143 * Error code when a dependency has no type (pkg, php, etc.) 144 */ 145 define('PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE', 26); 146 147 /** 148 * Error code when a dependency has no relation (lt, ge, has, etc.) 149 */ 150 define('PEAR_PACKAGEFILE_ERROR_NO_DEPREL', 27); 151 152 /** 153 * Error code when a dependency is not a 'has' relation, but has no version 154 */ 155 define('PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION', 28); 156 157 /** 158 * Error code when a dependency has an invalid relation 159 */ 160 define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPREL', 29); 161 162 /** 163 * Error code when a dependency has an invalid type 164 */ 165 define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPTYPE', 30); 166 167 /** 168 * Error code when a dependency has an invalid optional option 169 */ 170 define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL', 31); 171 172 /** 173 * Error code when a dependency is a pkg dependency, and has an invalid package name 174 */ 175 define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPNAME', 32); 176 177 /** 178 * Error code when a dependency has a channel="foo" attribute, and foo is not a registered channel 179 */ 180 define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_DEPCHANNEL', 33); 181 182 /** 183 * Error code when rel="has" and version attribute is present. 184 */ 185 define('PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED', 34); 186 187 /** 188 * Error code when type="php" and dependency name is present 189 */ 190 define('PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED', 35); 191 192 /** 193 * Error code when a configure option has no name 194 */ 195 define('PEAR_PACKAGEFILE_ERROR_NO_CONFNAME', 36); 196 197 /** 198 * Error code when a configure option has no name 199 */ 200 define('PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT', 37); 201 202 /** 203 * Error code when a file in the filelist has an invalid role 204 */ 205 define('PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE', 38); 206 207 /** 208 * Error code when a file in the filelist has no role 209 */ 210 define('PEAR_PACKAGEFILE_ERROR_NO_FILEROLE', 39); 211 212 /** 213 * Error code when analyzing a php source file that has parse errors 214 */ 215 define('PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE', 40); 216 217 /** 218 * Error code when analyzing a php source file reveals a source element 219 * without a package name prefix 220 */ 221 define('PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX', 41); 222 223 /** 224 * Error code when an unknown channel is specified 225 */ 226 define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_CHANNEL', 42); 227 228 /** 229 * Error code when no files are found in the filelist 230 */ 231 define('PEAR_PACKAGEFILE_ERROR_NO_FILES', 43); 232 233 /** 234 * Error code when a file is not valid php according to _analyzeSourceCode() 235 */ 236 define('PEAR_PACKAGEFILE_ERROR_INVALID_FILE', 44); 237 238 /** 239 * Error code when the channel validator returns an error or warning 240 */ 241 define('PEAR_PACKAGEFILE_ERROR_CHANNELVAL', 45); 242 243 /** 244 * Error code when a php5 package is packaged in php4 (analysis doesn't work) 245 */ 246 define('PEAR_PACKAGEFILE_ERROR_PHP5', 46); 247 248 /** 249 * Error code when a file is listed in package.xml but does not exist 250 */ 251 define('PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND', 47); 252 253 /** 254 * Error code when a <dep type="php" rel="not"... is encountered (use rel="ne") 255 */ 256 define('PEAR_PACKAGEFILE_PHP_NO_NOT', 48); 257 258 /** 259 * Error code when a package.xml contains non-ISO-8859-1 characters 260 */ 261 define('PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS', 49); 262 263 /** 264 * Error code when a dependency is not a 'has' relation, but has no version 265 */ 266 define('PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION', 50); 267 268 /** 269 * Error code when a package has no lead developer 270 */ 271 define('PEAR_PACKAGEFILE_ERROR_NO_LEAD', 51); 272 273 /** 274 * Error code when a filename begins with "." 275 */ 276 define('PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME', 52); 277 /** 278 * package.xml encapsulator 279 * @category pear 280 * @package PEAR 281 * @author Greg Beaver <cellog@php.net> 282 * @copyright 1997-2006 The PHP Group 283 * @license http://www.php.net/license/3_0.txt PHP License 3.0 284 * @version Release: 1.5.0 285 * @link http://pear.php.net/package/PEAR 286 * @since Class available since Release 1.4.0a1 287 */ 288 class PEAR_PackageFile_v1 289 { 290 /** 291 * @access private 292 * @var PEAR_ErrorStack 293 * @access private 294 */ 295 var $_stack; 296 297 /** 298 * A registry object, used to access the package name validation regex for non-standard channels 299 * @var PEAR_Registry 300 * @access private 301 */ 302 var $_registry; 303 304 /** 305 * An object that contains a log method that matches PEAR_Common::log's signature 306 * @var object 307 * @access private 308 */ 309 var $_logger; 310 311 /** 312 * Parsed package information 313 * @var array 314 * @access private 315 */ 316 var $_packageInfo; 317 318 /** 319 * path to package.xml 320 * @var string 321 * @access private 322 */ 323 var $_packageFile; 324 325 /** 326 * path to package .tgz or false if this is a local/extracted package.xml 327 * @var string 328 * @access private 329 */ 330 var $_archiveFile; 331 332 /** 333 * @var int 334 * @access private 335 */ 336 var $_isValid = 0; 337 338 /** 339 * Determines whether this packagefile was initialized only with partial package info 340 * 341 * If this package file was constructed via parsing REST, it will only contain 342 * 343 * - package name 344 * - channel name 345 * - dependencies 346 * @var boolean 347 * @access private 348 */ 349 var $_incomplete = true; 350 351 /** 352 * @param bool determines whether to return a PEAR_Error object, or use the PEAR_ErrorStack 353 * @param string Name of Error Stack class to use. 354 */ 355 function PEAR_PackageFile_v1() 356 { 357 $this->_stack = &new PEAR_ErrorStack('PEAR_PackageFile_v1'); 358 $this->_stack->setErrorMessageTemplate($this->_getErrorMessage()); 359 $this->_isValid = 0; 360 } 361 362 function installBinary($installer) 363 { 364 return false; 365 } 366 367 function isExtension($name) 368 { 369 return false; 370 } 371 372 function setConfig(&$config) 373 { 374 $this->_config = &$config; 375 $this->_registry = &$config->getRegistry(); 376 } 377 378 function setRequestedGroup() 379 { 380 // placeholder 381 } 382 383 /** 384 * For saving in the registry. 385 * 386 * Set the last version that was installed 387 * @param string 388 */ 389 function setLastInstalledVersion($version) 390 { 391 $this->_packageInfo['_lastversion'] = $version; 392 } 393 394 /** 395 * @return string|false 396 */ 397 function getLastInstalledVersion() 398 { 399 if (isset($this->_packageInfo['_lastversion'])) { 400 return $this->_packageInfo['_lastversion']; 401 } 402 return false; 403 } 404 405 function getInstalledBinary() 406 { 407 return false; 408 } 409 410 function listPostinstallScripts() 411 { 412 return false; 413 } 414 415 function initPostinstallScripts() 416 { 417 return false; 418 } 419 420 function setLogger(&$logger) 421 { 422 if ($logger && (!is_object($logger) || !method_exists($logger, 'log'))) { 423 return PEAR::raiseError('Logger must be compatible with PEAR_Common::log'); 424 } 425 $this->_logger = &$logger; 426 } 427 428 function setPackagefile($file, $archive = false) 429 { 430 $this->_packageFile = $file; 431 $this->_archiveFile = $archive ? $archive : $file; 432 } 433 434 function getPackageFile() 435 { 436 return isset($this->_packageFile) ? $this->_packageFile : false; 437 } 438 439 function getPackageType() 440 { 441 return 'php'; 442 } 443 444 function getArchiveFile() 445 { 446 return $this->_archiveFile; 447 } 448 449 function packageInfo($field) 450 { 451 if (!is_string($field) || empty($field) || 452 !isset($this->_packageInfo[$field])) { 453 return false; 454 } 455 return $this->_packageInfo[$field]; 456 } 457 458 function setDirtree($path) 459 { 460 if (!isset($this->_packageInfo['dirtree'])) { 461 $this->_packageInfo['dirtree'] = array(); 462 } 463 $this->_packageInfo['dirtree'][$path] = true; 464 } 465 466 function getDirtree() 467 { 468 if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) { 469 return $this->_packageInfo['dirtree']; 470 } 471 return false; 472 } 473 474 function resetDirtree() 475 { 476 unset($this->_packageInfo['dirtree']); 477 } 478 479 function fromArray($pinfo) 480 { 481 $this->_incomplete = false; 482 $this->_packageInfo = $pinfo; 483 } 484 485 function isIncomplete() 486 { 487 return $this->_incomplete; 488 } 489 490 function getChannel() 491 { 492 return 'pear.php.net'; 493 } 494 495 function getUri() 496 { 497 return false; 498 } 499 500 function getTime() 501 { 502 return false; 503 } 504 505 function getExtends() 506 { 507 if (isset($this->_packageInfo['extends'])) { 508 return $this->_packageInfo['extends']; 509 } 510 return false; 511 } 512 513 /** 514 * @return array 515 */ 516 function toArray() 517 { 518 if (!$this->validate(PEAR_VALIDATE_NORMAL)) { 519 return false; 520 } 521 return $this->getArray(); 522 } 523 524 function getArray() 525 { 526 return $this->_packageInfo; 527 } 528 529 function getName() 530 { 531 return $this->getPackage(); 532 } 533 534 function getPackage() 535 { 536 if (isset($this->_packageInfo['package'])) { 537 return $this->_packageInfo['package']; 538 } 539 return false; 540 } 541 542 /** 543 * WARNING - don't use this unless you know what you are doing 544 */ 545 function setRawPackage($package) 546 { 547 $this->_packageInfo['package'] = $package; 548 } 549 550 function setPackage($package) 551 { 552 $this->_packageInfo['package'] = $package; 553 $this->_isValid = false; 554 } 555 556 function getVersion() 557 { 558 if (isset($this->_packageInfo['version'])) { 559 return $this->_packageInfo['version']; 560 } 561 return false; 562 } 563 564 function setVersion($version) 565 { 566 $this->_packageInfo['version'] = $version; 567 $this->_isValid = false; 568 } 569 570 function clearMaintainers() 571 { 572 unset($this->_packageInfo['maintainers']); 573 } 574 575 function getMaintainers() 576 { 577 if (isset($this->_packageInfo['maintainers'])) { 578 return $this->_packageInfo['maintainers']; 579 } 580 return false; 581 } 582 583 /** 584 * Adds a new maintainer - no checking of duplicates is performed, use 585 * updatemaintainer for that purpose. 586 */ 587 function addMaintainer($role, $handle, $name, $email) 588 { 589 $this->_packageInfo['maintainers'][] = 590 array('handle' => $handle, 'role' => $role, 'email' => $email, 'name' => $name); 591 $this->_isValid = false; 592 } 593 594 function updateMaintainer($role, $handle, $name, $email) 595 { 596 $found = false; 597 if (!isset($this->_packageInfo['maintainers']) || 598 !is_array($this->_packageInfo['maintainers'])) { 599 return $this->addMaintainer($role, $handle, $name, $email); 600 } 601 foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) { 602 if ($maintainer['handle'] == $handle) { 603 $found = $i; 604 break; 605 } 606 } 607 if ($found !== false) { 608 unset($this->_packageInfo['maintainers'][$found]); 609 $this->_packageInfo['maintainers'] = 610 array_values($this->_packageInfo['maintainers']); 611 } 612 $this->addMaintainer($role, $handle, $name, $email); 613 } 614 615 function deleteMaintainer($handle) 616 { 617 $found = false; 618 foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) { 619 if ($maintainer['handle'] == $handle) { 620 $found = $i; 621 break; 622 } 623 } 624 if ($found !== false) { 625 unset($this->_packageInfo['maintainers'][$found]); 626 $this->_packageInfo['maintainers'] = 627 array_values($this->_packageInfo['maintainers']); 628 return true; 629 } 630 return false; 631 } 632 633 function getState() 634 { 635 if (isset($this->_packageInfo['release_state'])) { 636 return $this->_packageInfo['release_state']; 637 } 638 return false; 639 } 640 641 function setRawState($state) 642 { 643 $this->_packageInfo['release_state'] = $state; 644 } 645 646 function setState($state) 647 { 648 $this->_packageInfo['release_state'] = $state; 649 $this->_isValid = false; 650 } 651 652 function getDate() 653 { 654 if (isset($this->_packageInfo['release_date'])) { 655 return $this->_packageInfo['release_date']; 656 } 657 return false; 658 } 659 660 function setDate($date) 661 { 662 $this->_packageInfo['release_date'] = $date; 663 $this->_isValid = false; 664 } 665 666 function getLicense() 667 { 668 if (isset($this->_packageInfo['release_license'])) { 669 return $this->_packageInfo['release_license']; 670 } 671 return false; 672 } 673 674 function setLicense($date) 675 { 676 $this->_packageInfo['release_license'] = $date; 677 $this->_isValid = false; 678 } 679 680 function getSummary() 681 { 682 if (isset($this->_packageInfo['summary'])) { 683 return $this->_packageInfo['summary']; 684 } 685 return false; 686 } 687 688 function setSummary($summary) 689 { 690 $this->_packageInfo['summary'] = $summary; 691 $this->_isValid = false; 692 } 693 694 function getDescription() 695 { 696 if (isset($this->_packageInfo['description'])) { 697 return $this->_packageInfo['description']; 698 } 699 return false; 700 } 701 702 function setDescription($desc) 703 { 704 $this->_packageInfo['description'] = $desc; 705 $this->_isValid = false; 706 } 707 708 function getNotes() 709 { 710 if (isset($this->_packageInfo['release_notes'])) { 711 return $this->_packageInfo['release_notes']; 712 } 713 return false; 714 } 715 716 function setNotes($notes) 717 { 718 $this->_packageInfo['release_notes'] = $notes; 719 $this->_isValid = false; 720 } 721 722 function getDeps() 723 { 724 if (isset($this->_packageInfo['release_deps'])) { 725 return $this->_packageInfo['release_deps']; 726 } 727 return false; 728 } 729 730 /** 731 * Reset dependencies prior to adding new ones 732 */ 733 function clearDeps() 734 { 735 unset($this->_packageInfo['release_deps']); 736 } 737 738 function addPhpDep($version, $rel) 739 { 740 $this->_isValid = false; 741 $this->_packageInfo['release_deps'][] = 742 array('type' => 'php', 743 'rel' => $rel, 744 'version' => $version); 745 } 746 747 function addPackageDep($name, $version, $rel, $optional = 'no') 748 { 749 $this->_isValid = false; 750 $dep = 751 array('type' => 'pkg', 752 'name' => $name, 753 'rel' => $rel, 754 'optional' => $optional); 755 if ($rel != 'has' && $rel != 'not') { 756 $dep['version'] = $version; 757 } 758 $this->_packageInfo['release_deps'][] = $dep; 759 } 760 761 function addExtensionDep($name, $version, $rel, $optional = 'no') 762 { 763 $this->_isValid = false; 764 $this->_packageInfo['release_deps'][] = 765 array('type' => 'ext', 766 'name' => $name, 767 'rel' => $rel, 768 'version' => $version, 769 'optional' => $optional); 770 } 771 772 /** 773 * WARNING - do not use this function directly unless you know what you're doing 774 */ 775 function setDeps($deps) 776 { 777 $this->_packageInfo['release_deps'] = $deps; 778 } 779 780 function hasDeps() 781 { 782 return isset($this->_packageInfo['release_deps']) && 783 count($this->_packageInfo['release_deps']); 784 } 785 786 function getDependencyGroup($group) 787 { 788 return false; 789 } 790 791 function isCompatible($pf) 792 { 793 return false; 794 } 795 796 function isSubpackageOf($p) 797 { 798 return $p->isSubpackage($this); 799 } 800 801 function isSubpackage($p) 802 { 803 return false; 804 } 805 806 function dependsOn($package, $channel) 807 { 808 if (strtolower($channel) != 'pear.php.net') { 809 return false; 810 } 811 if (!($deps = $this->getDeps())) { 812 return false; 813 } 814 foreach ($deps as $dep) { 815 if ($dep['type'] != 'pkg') { 816 continue; 817 } 818 if (strtolower($dep['name']) == strtolower($package)) { 819 return true; 820 } 821 } 822 return false; 823 } 824 825 function getConfigureOptions() 826 { 827 if (isset($this->_packageInfo['configure_options'])) { 828 return $this->_packageInfo['configure_options']; 829 } 830 return false; 831 } 832 833 function hasConfigureOptions() 834 { 835 return isset($this->_packageInfo['configure_options']) && 836 count($this->_packageInfo['configure_options']); 837 } 838 839 function addConfigureOption($name, $prompt, $default = false) 840 { 841 $o = array('name' => $name, 'prompt' => $prompt); 842 if ($default !== false) { 843 $o['default'] = $default; 844 } 845 if (!isset($this->_packageInfo['configure_options'])) { 846 $this->_packageInfo['configure_options'] = array(); 847 } 848 $this->_packageInfo['configure_options'][] = $o; 849 } 850 851 function clearConfigureOptions() 852 { 853 unset($this->_packageInfo['configure_options']); 854 } 855 856 function getProvides() 857 { 858 if (isset($this->_packageInfo['provides'])) { 859 return $this->_packageInfo['provides']; 860 } 861 return false; 862 } 863 864 function getProvidesExtension() 865 { 866 return false; 867 } 868 869 function addFile($dir, $file, $attrs) 870 { 871 $dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir); 872 if ($dir == '/' || $dir == '') { 873 $dir = ''; 874 } else { 875 $dir .= '/'; 876 } 877 $file = $dir . $file; 878 $file = preg_replace('![\\/]+!', '/', $file); 879 $this->_packageInfo['filelist'][$file] = $attrs; 880 } 881 882 function getInstallationFilelist() 883 { 884 return $this->getFilelist(); 885 } 886 887 function getFilelist() 888 { 889 if (isset($this->_packageInfo['filelist'])) { 890 return $this->_packageInfo['filelist']; 891 } 892 return false; 893 } 894 895 function setFileAttribute($file, $attr, $value) 896 { 897 $this->_packageInfo['filelist'][$file][$attr] = $value; 898 } 899 900 function resetFilelist() 901 { 902 $this->_packageInfo['filelist'] = array(); 903 } 904 905 function setInstalledAs($file, $path) 906 { 907 if ($path) { 908 return $this->_packageInfo['filelist'][$file]['installed_as'] = $path; 909 } 910 unset($this->_packageInfo['filelist'][$file]['installed_as']); 911 } 912 913 function installedFile($file, $atts) 914 { 915 if (isset($this->_packageInfo['filelist'][$file])) { 916 $this->_packageInfo['filelist'][$file] = 917 array_merge($this->_packageInfo['filelist'][$file], $atts); 918 } else { 919 $this->_packageInfo['filelist'][$file] = $atts; 920 } 921 } 922 923 function getChangelog() 924 { 925 if (isset($this->_packageInfo['changelog'])) { 926 return $this->_packageInfo['changelog']; 927 } 928 return false; 929 } 930 931 function getPackagexmlVersion() 932 { 933 return '1.0'; 934 } 935 936 /** 937 * Wrapper to {@link PEAR_ErrorStack::getErrors()} 938 * @param boolean determines whether to purge the error stack after retrieving 939 * @return array 940 */ 941 function getValidationWarnings($purge = true) 942 { 943 return $this->_stack->getErrors($purge); 944 } 945 946 // }}} 947 /** 948 * Validation error. Also marks the object contents as invalid 949 * @param error code 950 * @param array error information 951 * @access private 952 */ 953 function _validateError($code, $params = array()) 954 { 955 $this->_stack->push($code, 'error', $params, false, false, debug_backtrace()); 956 $this->_isValid = false; 957 } 958 959 /** 960 * Validation warning. Does not mark the object contents invalid. 961 * @param error code 962 * @param array error information 963 * @access private 964 */ 965 function _validateWarning($code, $params = array()) 966 { 967 $this->_stack->push($code, 'warning', $params, false, false, debug_backtrace()); 968 } 969 970 /** 971 * @param integer error code 972 * @access protected 973 */ 974 function _getErrorMessage() 975 { 976 return array( 977 PEAR_PACKAGEFILE_ERROR_NO_NAME => 978 'Missing Package Name', 979 PEAR_PACKAGEFILE_ERROR_NO_SUMMARY => 980 'No summary found', 981 PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY => 982 'Summary should be on one line', 983 PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION => 984 'Missing description', 985 PEAR_PACKAGEFILE_ERROR_NO_LICENSE => 986 'Missing license', 987 PEAR_PACKAGEFILE_ERROR_NO_VERSION => 988 'No release version found', 989 PEAR_PACKAGEFILE_ERROR_NO_STATE => 990 'No release state found', 991 PEAR_PACKAGEFILE_ERROR_NO_DATE => 992 'No release date found', 993 PEAR_PACKAGEFILE_ERROR_NO_NOTES => 994 'No release notes found', 995 PEAR_PACKAGEFILE_ERROR_NO_LEAD => 996 'Package must have at least one lead maintainer', 997 PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS => 998 'No maintainers found, at least one must be defined', 999 PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE => 1000 'Maintainer %index% has no handle (user ID at channel server)', 1001 PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE => 1002 'Maintainer %index% has no role', 1003 PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME => 1004 'Maintainer %index% has no name', 1005 PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL => 1006 'Maintainer %index% has no email', 1007 PEAR_PACKAGEFILE_ERROR_NO_DEPNAME => 1008 'Dependency %index% is not a php dependency, and has no name', 1009 PEAR_PACKAGEFILE_ERROR_NO_DEPREL => 1010 'Dependency %index% has no relation (rel)', 1011 PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE => 1012 'Dependency %index% has no type', 1013 PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED => 1014 'PHP Dependency %index% has a name attribute of "%name%" which will be' . 1015 ' ignored!', 1016 PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION => 1017 'Dependency %index% is not a rel="has" or rel="not" dependency, ' . 1018 'and has no version', 1019 PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION => 1020 'Dependency %index% is a type="php" dependency, ' . 1021 'and has no version', 1022 PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED => 1023 'Dependency %index% is a rel="%rel%" dependency, versioning is ignored', 1024 PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL => 1025 'Dependency %index% has invalid optional value "%opt%", should be yes or no', 1026 PEAR_PACKAGEFILE_PHP_NO_NOT => 1027 'Dependency %index%: php dependencies cannot use "not" rel, use "ne"' . 1028 ' to exclude specific versions', 1029 PEAR_PACKAGEFILE_ERROR_NO_CONFNAME => 1030 'Configure Option %index% has no name', 1031 PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT => 1032 'Configure Option %index% has no prompt', 1033 PEAR_PACKAGEFILE_ERROR_NO_FILES => 1034 'No files in <filelist> section of package.xml', 1035 PEAR_PACKAGEFILE_ERROR_NO_FILEROLE => 1036 'File "%file%" has no role, expecting one of "%roles%"', 1037 PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE => 1038 'File "%file%" has invalid role "%role%", expecting one of "%roles%"', 1039 PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME => 1040 'File "%file%" cannot start with ".", cannot package or install', 1041 PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE => 1042 'Parser error: invalid PHP found in file "%file%"', 1043 PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX => 1044 'in %file%: %type% "%name%" not prefixed with package name "%package%"', 1045 PEAR_PACKAGEFILE_ERROR_INVALID_FILE => 1046 'Parser error: invalid PHP file "%file%"', 1047 PEAR_PACKAGEFILE_ERROR_CHANNELVAL => 1048 'Channel validator error: field "%field%" - %reason%', 1049 PEAR_PACKAGEFILE_ERROR_PHP5 => 1050 'Error, PHP5 token encountered in %file%, analysis should be in PHP5', 1051 PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND => 1052 'File "%file%" in package.xml does not exist', 1053 PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS => 1054 'Package.xml contains non-ISO-8859-1 characters, and may not validate', 1055 ); 1056 } 1057 1058 /** 1059 * Validate XML package definition file. 1060 * 1061 * @access public 1062 * @return boolean 1063 */ 1064 function validate($state = PEAR_VALIDATE_NORMAL, $nofilechecking = false) 1065 { 1066 if (($this->_isValid & $state) == $state) { 1067 return true; 1068 } 1069 $this->_isValid = true; 1070 $info = $this->_packageInfo; 1071 if (empty($info['package'])) { 1072 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NAME); 1073 $this->_packageName = $pn = 'unknown'; 1074 } else { 1075 $this->_packageName = $pn = $info['package']; 1076 } 1077 1078 if (empty($info['summary'])) { 1079 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_SUMMARY); 1080 } elseif (strpos(trim($info['summary']), "\n") !== false) { 1081 $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY, 1082 array('summary' => $info['summary'])); 1083 } 1084 if (empty($info['description'])) { 1085 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION); 1086 } 1087 if (empty($info['release_license'])) { 1088 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LICENSE); 1089 } 1090 if (empty($info['version'])) { 1091 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_VERSION); 1092 } 1093 if (empty($info['release_state'])) { 1094 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_STATE); 1095 } 1096 if (empty($info['release_date'])) { 1097 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DATE); 1098 } 1099 if (empty($info['release_notes'])) { 1100 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NOTES); 1101 } 1102 if (empty($info['maintainers'])) { 1103 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS); 1104 } else { 1105 $haslead = false; 1106 $i = 1; 1107 foreach ($info['maintainers'] as $m) { 1108 if (empty($m['handle'])) { 1109 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE, 1110 array('index' => $i)); 1111 } 1112 if (empty($m['role'])) { 1113 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE, 1114 array('index' => $i, 'roles' => PEAR_Common::getUserRoles())); 1115 } elseif ($m['role'] == 'lead') { 1116 $haslead = true; 1117 } 1118 if (empty($m['name'])) { 1119 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME, 1120 array('index' => $i)); 1121 } 1122 if (empty($m['email'])) { 1123 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL, 1124 array('index' => $i)); 1125 } 1126 $i++; 1127 } 1128 if (!$haslead) { 1129 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LEAD); 1130 } 1131 } 1132 if (!empty($info['release_deps'])) { 1133 $i = 1; 1134 foreach ($info['release_deps'] as $d) { 1135 if (!isset($d['type']) || empty($d['type'])) { 1136 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE, 1137 array('index' => $i, 'types' => PEAR_Common::getDependencyTypes())); 1138 continue; 1139 } 1140 if (!isset($d['rel']) || empty($d['rel'])) { 1141 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPREL, 1142 array('index' => $i, 'rels' => PEAR_Common::getDependencyRelations())); 1143 continue; 1144 } 1145 if (!empty($d['optional'])) { 1146 if (!in_array($d['optional'], array('yes', 'no'))) { 1147 $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL, 1148 array('index' => $i, 'opt' => $d['optional'])); 1149 } 1150 } 1151 if ($d['rel'] != 'has' && $d['rel'] != 'not' && empty($d['version'])) { 1152 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION, 1153 array('index' => $i)); 1154 } elseif (($d['rel'] == 'has' || $d['rel'] == 'not') && !empty($d['version'])) { 1155 $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED, 1156 array('index' => $i, 'rel' => $d['rel'])); 1157 } 1158 if ($d['type'] == 'php' && !empty($d['name'])) { 1159 $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED, 1160 array('index' => $i, 'name' => $d['name'])); 1161 } elseif ($d['type'] != 'php' && empty($d['name'])) { 1162 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPNAME, 1163 array('index' => $i)); 1164 } 1165 if ($d['type'] == 'php' && empty($d['version'])) { 1166 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION, 1167 array('index' => $i)); 1168 } 1169 if (($d['rel'] == 'not') && ($d['type'] == 'php')) { 1170 $this->_validateError(PEAR_PACKAGEFILE_PHP_NO_NOT, 1171 array('index' => $i)); 1172 } 1173 $i++; 1174 } 1175 } 1176 if (!empty($info['configure_options'])) { 1177 $i = 1; 1178 foreach ($info['configure_options'] as $c) { 1179 if (empty($c['name'])) { 1180 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFNAME, 1181 array('index' => $i)); 1182 } 1183 if (empty($c['prompt'])) { 1184 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT, 1185 array('index' => $i)); 1186 } 1187 $i++; 1188 } 1189 } 1190 if (empty($info['filelist'])) { 1191 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILES); 1192 $errors[] = 'no files'; 1193 } else { 1194 foreach ($info['filelist'] as $file => $fa) { 1195 if (empty($fa['role'])) { 1196 $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILEROLE, 1197 array('file' => $file, 'roles' => PEAR_Common::getFileRoles())); 1198 continue; 1199 } elseif (!in_array($fa['role'], PEAR_Common::getFileRoles())) { 1200 $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE, 1201 array('file' => $file, 'role' => $fa['role'], 'roles' => PEAR_Common::getFileRoles())); 1202 } 1203 if ($file{0} == '.' && $file{1} == '/') { 1204 $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, 1205 array('file' => $file)); 1206 } 1207 } 1208 } 1209 if (isset($this->_registry) && $this->_isValid) { 1210 $chan = $this->_registry->getChannel('pear.php.net'); 1211 if (PEAR::isError($chan)) { 1212 $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $chan->getMessage()); 1213 return $this->_isValid = 0; 1214 } 1215 $validator = $chan->getValidationObject(); 1216 $validator->setPackageFile($this); 1217 $validator->validate($state); 1218 $failures = $validator->getFailures(); 1219 foreach ($failures['errors'] as $error) { 1220 $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $error); 1221 } 1222 foreach ($failures['warnings'] as $warning) { 1223 $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $warning); 1224 } 1225 } 1226 if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$nofilechecking) { 1227 if ($this->_analyzePhpFiles()) { 1228 $this->_isValid = true; 1229 } 1230 } 1231 if ($this->_isValid) { 1232 return $this->_isValid = $state; 1233 } 1234 return $this->_isValid = 0; 1235 } 1236 1237 function _analyzePhpFiles() 1238 { 1239 if (!$this->_isValid) { 1240 return false; 1241 } 1242 if (!isset($this->_packageFile)) { 1243 return false; 1244 } 1245 $dir_prefix = dirname($this->_packageFile); 1246 $common = new PEAR_Common; 1247 $log = isset($this->_logger) ? array(&$this->_logger, 'log') : 1248 array($common, 'log'); 1249 $info = $this->getFilelist(); 1250 foreach ($info as $file => $fa) { 1251 if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) { 1252 $this->_validateError(PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND, 1253 array('file' => realpath($dir_prefix) . DIRECTORY_SEPARATOR . $file)); 1254 continue; 1255 } 1256 if ($fa['role'] == 'php' && $dir_prefix) { 1257 call_user_func_array($log, array(1, "Analyzing $file")); 1258 $srcinfo = $this->_analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file); 1259 if ($srcinfo) { 1260 $this->_buildProvidesArray($srcinfo); 1261 } 1262 } 1263 } 1264 $this->_packageName = $pn = $this->getPackage(); 1265 $pnl = strlen($pn); 1266 if (isset($this->_packageInfo['provides'])) { 1267 foreach ((array) $this->_packageInfo['provides'] as $key => $what) { 1268 if (isset($what['explicit'])) { 1269 // skip conformance checks if the provides entry is 1270 // specified in the package.xml file 1271 continue; 1272 } 1273 extract($what); 1274 if ($type == 'class') { 1275 if (!strncasecmp($name, $pn, $pnl)) { 1276 continue; 1277 } 1278 $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX, 1279 array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn)); 1280 } elseif ($type == 'function') { 1281 if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) { 1282 continue; 1283 } 1284 $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX, 1285 array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn)); 1286 } 1287 } 1288 } 1289 return $this->_isValid; 1290 } 1291 1292 /** 1293 * Get the default xml generator object 1294 * 1295 * @return PEAR_PackageFile_Generator_v1 1296 */ 1297 function &getDefaultGenerator() 1298 { 1299 if (!class_exists('PEAR_PackageFile_Generator_v1')) { 1300 require_once 'PEAR/PackageFile/Generator/v1.php'; 1301 } 1302 $a = &new PEAR_PackageFile_Generator_v1($this); 1303 return $a; 1304 } 1305 1306 /** 1307 * Get the contents of a file listed within the package.xml 1308 * @param string 1309 * @return string 1310 */ 1311 function getFileContents($file) 1312 { 1313 if ($this->_archiveFile == $this->_packageFile) { // unpacked 1314 $dir = dirname($this->_packageFile); 1315 $file = $dir . DIRECTORY_SEPARATOR . $file; 1316 $file = str_replace(array('/', '\\'), 1317 array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file); 1318 if (file_exists($file) && is_readable($file)) { 1319 return implode('', file($file)); 1320 } 1321 } else { // tgz 1322 if (!class_exists('Archive_Tar')) { 1323 require_once 'Archive/Tar.php'; 1324 } 1325 $tar = &new Archive_Tar($this->_archiveFile); 1326 $tar->pushErrorHandling(PEAR_ERROR_RETURN); 1327 if ($file != 'package.xml' && $file != 'package2.xml') { 1328 $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file; 1329 } 1330 $file = $tar->extractInString($file); 1331 $tar->popErrorHandling(); 1332 if (PEAR::isError($file)) { 1333 return PEAR::raiseError("Cannot locate file '$file' in archive"); 1334 } 1335 return $file; 1336 } 1337 } 1338 1339 // {{{ analyzeSourceCode() 1340 /** 1341 * Analyze the source code of the given PHP file 1342 * 1343 * @param string Filename of the PHP file 1344 * @return mixed 1345 * @access private 1346 */ 1347 function _analyzeSourceCode($file) 1348 { 1349 if (!function_exists("token_get_all")) { 1350 return false; 1351 } 1352 if (!defined('T_DOC_COMMENT')) { 1353 define('T_DOC_COMMENT', T_COMMENT); 1354 } 1355 if (!defined('T_INTERFACE')) { 1356 define('T_INTERFACE', -1); 1357 } 1358 if (!defined('T_IMPLEMENTS')) { 1359 define('T_IMPLEMENTS', -1); 1360 } 1361 if (!$fp = @fopen($file, "r")) { 1362 return false; 1363 } 1364 fclose($fp); 1365 $contents = file_get_contents($file); 1366 $tokens = token_get_all($contents); 1367 /* 1368 for ($i = 0; $i < sizeof($tokens); $i++) { 1369 @list($token, $data) = $tokens[$i]; 1370 if (is_string($token)) { 1371 var_dump($token); 1372 } else { 1373 print token_name($token) . ' '; 1374 var_dump(rtrim($data)); 1375 } 1376 } 1377 */ 1378 $look_for = 0; 1379 $paren_level = 0; 1380 $bracket_level = 0; 1381 $brace_level = 0; 1382 $lastphpdoc = ''; 1383 $current_class = ''; 1384 $current_interface = ''; 1385 $current_class_level = -1; 1386 $current_function = ''; 1387 $current_function_level = -1; 1388 $declared_classes = array(); 1389 $declared_interfaces = array(); 1390 $declared_functions = array(); 1391 $declared_methods = array(); 1392 $used_classes = array(); 1393 $used_functions = array(); 1394 $extends = array(); 1395 $implements = array(); 1396 $nodeps = array(); 1397 $inquote = false; 1398 $interface = false; 1399 for ($i = 0; $i < sizeof($tokens); $i++) { 1400 if (is_array($tokens[$i])) { 1401 list($token, $data) = $tokens[$i]; 1402 } else { 1403 $token = $tokens[$i]; 1404 $data = ''; 1405 } 1406 if ($inquote) { 1407 if ($token != '"' && $token != T_END_HEREDOC) { 1408 continue; 1409 } else { 1410 $inquote = false; 1411 continue; 1412 } 1413 } 1414 switch ($token) { 1415 case T_WHITESPACE : 1416 continue; 1417 case ';': 1418 if ($interface) { 1419 $current_function = ''; 1420 $current_function_level = -1; 1421 } 1422 break; 1423 case '"': 1424 case T_START_HEREDOC: 1425 $inquote = true; 1426 break; 1427 case T_CURLY_OPEN: 1428 case T_DOLLAR_OPEN_CURLY_BRACES: 1429 case '{': $brace_level++; continue 2; 1430 case '}': 1431 $brace_level--; 1432 if ($current_class_level == $brace_level) { 1433 $current_class = ''; 1434 $current_class_level = -1; 1435 } 1436 if ($current_function_level == $brace_level) { 1437 $current_function = ''; 1438 $current_function_level = -1; 1439 } 1440 continue 2; 1441 case '[': $bracket_level++; continue 2; 1442 case ']': $bracket_level--; continue 2; 1443 case '(': $paren_level++; continue 2; 1444 case ')': $paren_level--; continue 2; 1445 case T_INTERFACE: 1446 $interface = true; 1447 case T_CLASS: 1448 if (($current_class_level != -1) || ($current_function_level != -1)) { 1449 $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE, 1450 array('file' => $file)); 1451 return false; 1452 } 1453 case T_FUNCTION: 1454 case T_NEW: 1455 case T_EXTENDS: 1456 case T_IMPLEMENTS: 1457 $look_for = $token; 1458 continue 2; 1459 case T_STRING: 1460 if (version_compare(zend_version(), '2.0', '<')) { 1461 if (in_array(strtolower($data), 1462 array('public', 'private', 'protected', 'abstract', 1463 'interface', 'implements', 'throw') 1464 )) { 1465 $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_PHP5, 1466 array($file)); 1467 } 1468 } 1469 if ($look_for == T_CLASS) { 1470 $current_class = $data; 1471 $current_class_level = $brace_level; 1472 $declared_classes[] = $current_class; 1473 } elseif ($look_for == T_INTERFACE) { 1474 $current_interface = $data; 1475 $current_class_level = $brace_level; 1476 $declared_interfaces[] = $current_interface; 1477 } elseif ($look_for == T_IMPLEMENTS) { 1478 $implements[$current_class] = $data; 1479 } elseif ($look_for == T_EXTENDS) { 1480 $extends[$current_class] = $data; 1481 } elseif ($look_for == T_FUNCTION) { 1482 if ($current_class) { 1483 $current_function = "$current_class::$data"; 1484 $declared_methods[$current_class][] = $data; 1485 } elseif ($current_interface) { 1486 $current_function = "$current_interface::$data"; 1487 $declared_methods[$current_interface][] = $data; 1488 } else { 1489 $current_function = $data; 1490 $declared_functions[] = $current_function; 1491 } 1492 $current_function_level = $brace_level; 1493 $m = array(); 1494 } elseif ($look_for == T_NEW) { 1495 $used_classes[$data] = true; 1496 } 1497 $look_for = 0; 1498 continue 2; 1499 case T_VARIABLE: 1500 $look_for = 0; 1501 continue 2; 1502 case T_DOC_COMMENT: 1503 case T_COMMENT: 1504 if (preg_match('!^/\*\*\s!', $data)) { 1505 $lastphpdoc = $data; 1506 if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) { 1507 $nodeps = array_merge($nodeps, $m[1]); 1508 } 1509 } 1510 continue 2; 1511 case T_DOUBLE_COLON: 1512 if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) { 1513 $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE, 1514 array('file' => $file)); 1515 return false; 1516 } 1517 $class = $tokens[$i - 1][1]; 1518 if (strtolower($class) != 'parent') { 1519 $used_classes[$class] = true; 1520 } 1521 continue 2; 1522 } 1523 } 1524 return array( 1525 "source_file" => $file, 1526 "declared_classes" => $declared_classes, 1527 "declared_interfaces" => $declared_interfaces, 1528 "declared_methods" => $declared_methods, 1529 "declared_functions" => $declared_functions, 1530 "used_classes" => array_diff(array_keys($used_classes), $nodeps), 1531 "inheritance" => $extends, 1532 "implements" => $implements, 1533 ); 1534 } 1535 1536 /** 1537 * Build a "provides" array from data returned by 1538 * analyzeSourceCode(). The format of the built array is like 1539 * this: 1540 * 1541 * array( 1542 * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), 1543 * ... 1544 * ) 1545 * 1546 * 1547 * @param array $srcinfo array with information about a source file 1548 * as returned by the analyzeSourceCode() method. 1549 * 1550 * @return void 1551 * 1552 * @access private 1553 * 1554 */ 1555 function _buildProvidesArray($srcinfo) 1556 { 1557 if (!$this->_isValid) { 1558 return false; 1559 } 1560 $file = basename($srcinfo['source_file']); 1561 $pn = $this->getPackage(); 1562 $pnl = strlen($pn); 1563 foreach ($srcinfo['declared_classes'] as $class) { 1564 $key = "class;$class"; 1565 if (isset($this->_packageInfo['provides'][$key])) { 1566 continue; 1567 } 1568 $this->_packageInfo['provides'][$key] = 1569 array('file'=> $file, 'type' => 'class', 'name' => $class); 1570 if (isset($srcinfo['inheritance'][$class])) { 1571 $this->_packageInfo['provides'][$key]['extends'] = 1572 $srcinfo['inheritance'][$class]; 1573 } 1574 } 1575 foreach ($srcinfo['declared_methods'] as $class => $methods) { 1576 foreach ($methods as $method) { 1577 $function = "$class::$method"; 1578 $key = "function;$function"; 1579 if ($method{0} == '_' || !strcasecmp($method, $class) || 1580 isset($this->_packageInfo['provides'][$key])) { 1581 continue; 1582 } 1583 $this->_packageInfo['provides'][$key] = 1584 array('file'=> $file, 'type' => 'function', 'name' => $function); 1585 } 1586 } 1587 1588 foreach ($srcinfo['declared_functions'] as $function) { 1589 $key = "function;$function"; 1590 if ($function{0} == '_' || isset($this->_packageInfo['provides'][$key])) { 1591 continue; 1592 } 1593 if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { 1594 $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; 1595 } 1596 $this->_packageInfo['provides'][$key] = 1597 array('file'=> $file, 'type' => 'function', 'name' => $function); 1598 } 1599 } 1600 1601 // }}} 1602 } 1603 ?>
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 |