[ Index ] |
|
Code source de PHP PEAR 1.4.5 |
1 <?php 2 /** 3 * PEAR_Common, the base class for the PEAR Installer 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 Stig Bakken <ssb@php.net> 16 * @author Tomas V. V. Cox <cox@idecnet.com> 17 * @author Greg Beaver <cellog@php.net> 18 * @copyright 1997-2006 The PHP Group 19 * @license http://www.php.net/license/3_0.txt PHP License 3.0 20 * @version CVS: $Id: Common.php,v 1.157 2006/05/12 02:38:58 cellog Exp $ 21 * @link http://pear.php.net/package/PEAR 22 * @since File available since Release 0.1.0 23 * @deprecated File deprecated since Release 1.4.0a1 24 */ 25 26 /** 27 * Include error handling 28 */ 29 require_once 'PEAR.php'; 30 31 // {{{ constants and globals 32 33 /** 34 * PEAR_Common error when an invalid PHP file is passed to PEAR_Common::analyzeSourceCode() 35 */ 36 define('PEAR_COMMON_ERROR_INVALIDPHP', 1); 37 define('_PEAR_COMMON_PACKAGE_NAME_PREG', '[A-Za-z][a-zA-Z0-9_]+'); 38 define('PEAR_COMMON_PACKAGE_NAME_PREG', '/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '$/'); 39 40 // this should allow: 1, 1.0, 1.0RC1, 1.0dev, 1.0dev123234234234, 1.0a1, 1.0b1, 1.0pl1 41 define('_PEAR_COMMON_PACKAGE_VERSION_PREG', '\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?'); 42 define('PEAR_COMMON_PACKAGE_VERSION_PREG', '/^' . _PEAR_COMMON_PACKAGE_VERSION_PREG . '$/i'); 43 44 // XXX far from perfect :-) 45 define('_PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '(' . _PEAR_COMMON_PACKAGE_NAME_PREG . 46 ')(-([.0-9a-zA-Z]+))?'); 47 define('PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_PACKAGE_DOWNLOAD_PREG . 48 '$/'); 49 50 define('_PEAR_CHANNELS_NAME_PREG', '[A-Za-z][a-zA-Z0-9\.]+'); 51 define('PEAR_CHANNELS_NAME_PREG', '/^' . _PEAR_CHANNELS_NAME_PREG . '$/'); 52 53 // this should allow any dns or IP address, plus a path - NO UNDERSCORES ALLOWED 54 define('_PEAR_CHANNELS_SERVER_PREG', '[a-zA-Z0-9\-]+(?:\.[a-zA-Z0-9\-]+)*(\/[a-zA-Z0-9\-]+)*'); 55 define('PEAR_CHANNELS_SERVER_PREG', '/^' . _PEAR_CHANNELS_SERVER_PREG . '$/i'); 56 57 define('_PEAR_CHANNELS_PACKAGE_PREG', '(' ._PEAR_CHANNELS_SERVER_PREG . ')\/(' 58 . _PEAR_COMMON_PACKAGE_NAME_PREG . ')'); 59 define('PEAR_CHANNELS_PACKAGE_PREG', '/^' . _PEAR_CHANNELS_PACKAGE_PREG . '$/i'); 60 61 define('_PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '(' . _PEAR_CHANNELS_NAME_PREG . ')::(' 62 . _PEAR_COMMON_PACKAGE_NAME_PREG . ')(-([.0-9a-zA-Z]+))?'); 63 define('PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_CHANNEL_DOWNLOAD_PREG . '$/'); 64 65 /** 66 * List of temporary files and directories registered by 67 * PEAR_Common::addTempFile(). 68 * @var array 69 */ 70 $GLOBALS['_PEAR_Common_tempfiles'] = array(); 71 72 /** 73 * Valid maintainer roles 74 * @var array 75 */ 76 $GLOBALS['_PEAR_Common_maintainer_roles'] = array('lead','developer','contributor','helper'); 77 78 /** 79 * Valid release states 80 * @var array 81 */ 82 $GLOBALS['_PEAR_Common_release_states'] = array('alpha','beta','stable','snapshot','devel'); 83 84 /** 85 * Valid dependency types 86 * @var array 87 */ 88 $GLOBALS['_PEAR_Common_dependency_types'] = array('pkg','ext','php','prog','ldlib','rtlib','os','websrv','sapi'); 89 90 /** 91 * Valid dependency relations 92 * @var array 93 */ 94 $GLOBALS['_PEAR_Common_dependency_relations'] = array('has','eq','lt','le','gt','ge','not', 'ne'); 95 96 /** 97 * Valid file roles 98 * @var array 99 */ 100 $GLOBALS['_PEAR_Common_file_roles'] = array('php','ext','test','doc','data','src','script'); 101 102 /** 103 * Valid replacement types 104 * @var array 105 */ 106 $GLOBALS['_PEAR_Common_replacement_types'] = array('php-const', 'pear-config', 'package-info'); 107 108 /** 109 * Valid "provide" types 110 * @var array 111 */ 112 $GLOBALS['_PEAR_Common_provide_types'] = array('ext', 'prog', 'class', 'function', 'feature', 'api'); 113 114 /** 115 * Valid "provide" types 116 * @var array 117 */ 118 $GLOBALS['_PEAR_Common_script_phases'] = array('pre-install', 'post-install', 'pre-uninstall', 'post-uninstall', 'pre-build', 'post-build', 'pre-configure', 'post-configure', 'pre-setup', 'post-setup'); 119 120 // }}} 121 122 /** 123 * Class providing common functionality for PEAR administration classes. 124 * @category pear 125 * @package PEAR 126 * @author Stig Bakken <ssb@php.net> 127 * @author Tomas V. V. Cox <cox@idecnet.com> 128 * @author Greg Beaver <cellog@php.net> 129 * @copyright 1997-2006 The PHP Group 130 * @license http://www.php.net/license/3_0.txt PHP License 3.0 131 * @version Release: 1.5.0 132 * @link http://pear.php.net/package/PEAR 133 * @since Class available since Release 1.4.0a1 134 * @deprecated This class will disappear, and its components will be spread 135 * into smaller classes, like the AT&T breakup, as of Release 1.4.0a1 136 */ 137 class PEAR_Common extends PEAR 138 { 139 // {{{ properties 140 141 /** stack of elements, gives some sort of XML context */ 142 var $element_stack = array(); 143 144 /** name of currently parsed XML element */ 145 var $current_element; 146 147 /** array of attributes of the currently parsed XML element */ 148 var $current_attributes = array(); 149 150 /** assoc with information about a package */ 151 var $pkginfo = array(); 152 153 /** 154 * User Interface object (PEAR_Frontend_* class). If null, 155 * the log() method uses print. 156 * @var object 157 */ 158 var $ui = null; 159 160 /** 161 * Configuration object (PEAR_Config). 162 * @var object 163 */ 164 var $config = null; 165 166 var $current_path = null; 167 168 /** 169 * PEAR_SourceAnalyzer instance 170 * @var object 171 */ 172 var $source_analyzer = null; 173 /** 174 * Flag variable used to mark a valid package file 175 * @var boolean 176 * @access private 177 */ 178 var $_validPackageFile; 179 180 // }}} 181 182 // {{{ constructor 183 184 /** 185 * PEAR_Common constructor 186 * 187 * @access public 188 */ 189 function PEAR_Common() 190 { 191 parent::PEAR(); 192 $this->config = &PEAR_Config::singleton(); 193 $this->debug = $this->config->get('verbose'); 194 } 195 196 // }}} 197 // {{{ destructor 198 199 /** 200 * PEAR_Common destructor 201 * 202 * @access private 203 */ 204 function _PEAR_Common() 205 { 206 // doesn't work due to bug #14744 207 //$tempfiles = $this->_tempfiles; 208 $tempfiles =& $GLOBALS['_PEAR_Common_tempfiles']; 209 while ($file = array_shift($tempfiles)) { 210 if (@is_dir($file)) { 211 if (!class_exists('System')) { 212 require_once 'System.php'; 213 } 214 System::rm(array('-rf', $file)); 215 } elseif (file_exists($file)) { 216 unlink($file); 217 } 218 } 219 } 220 221 // }}} 222 // {{{ addTempFile() 223 224 /** 225 * Register a temporary file or directory. When the destructor is 226 * executed, all registered temporary files and directories are 227 * removed. 228 * 229 * @param string $file name of file or directory 230 * 231 * @return void 232 * 233 * @access public 234 */ 235 function addTempFile($file) 236 { 237 if (!class_exists('PEAR_Frontend')) { 238 require_once 'PEAR/Frontend.php'; 239 } 240 PEAR_Frontend::addTempFile($file); 241 } 242 243 // }}} 244 // {{{ mkDirHier() 245 246 /** 247 * Wrapper to System::mkDir(), creates a directory as well as 248 * any necessary parent directories. 249 * 250 * @param string $dir directory name 251 * 252 * @return bool TRUE on success, or a PEAR error 253 * 254 * @access public 255 */ 256 function mkDirHier($dir) 257 { 258 $this->log(2, "+ create dir $dir"); 259 if (!class_exists('System')) { 260 require_once 'System.php'; 261 } 262 return System::mkDir(array('-p', $dir)); 263 } 264 265 // }}} 266 // {{{ log() 267 268 /** 269 * Logging method. 270 * 271 * @param int $level log level (0 is quiet, higher is noisier) 272 * @param string $msg message to write to the log 273 * 274 * @return void 275 * 276 * @access public 277 * @static 278 */ 279 function log($level, $msg, $append_crlf = true) 280 { 281 if ($this->debug >= $level) { 282 if (!class_exists('PEAR_Frontend')) { 283 require_once 'PEAR/Frontend.php'; 284 } 285 $ui = &PEAR_Frontend::singleton(); 286 if (is_a($ui, 'PEAR_Frontend')) { 287 $ui->log($msg, $append_crlf); 288 } else { 289 print "$msg\n"; 290 } 291 } 292 } 293 294 // }}} 295 // {{{ mkTempDir() 296 297 /** 298 * Create and register a temporary directory. 299 * 300 * @param string $tmpdir (optional) Directory to use as tmpdir. 301 * Will use system defaults (for example 302 * /tmp or c:\windows\temp) if not specified 303 * 304 * @return string name of created directory 305 * 306 * @access public 307 */ 308 function mkTempDir($tmpdir = '') 309 { 310 if ($tmpdir) { 311 $topt = array('-t', $tmpdir); 312 } else { 313 $topt = array(); 314 } 315 $topt = array_merge($topt, array('-d', 'pear')); 316 if (!class_exists('System')) { 317 require_once 'System.php'; 318 } 319 if (!$tmpdir = System::mktemp($topt)) { 320 return false; 321 } 322 $this->addTempFile($tmpdir); 323 return $tmpdir; 324 } 325 326 // }}} 327 // {{{ setFrontendObject() 328 329 /** 330 * Set object that represents the frontend to be used. 331 * 332 * @param object Reference of the frontend object 333 * @return void 334 * @access public 335 */ 336 function setFrontendObject(&$ui) 337 { 338 $this->ui = &$ui; 339 } 340 341 // }}} 342 343 // {{{ infoFromTgzFile() 344 345 /** 346 * Returns information about a package file. Expects the name of 347 * a gzipped tar file as input. 348 * 349 * @param string $file name of .tgz file 350 * 351 * @return array array with package information 352 * 353 * @access public 354 * @deprecated use PEAR_PackageFile->fromTgzFile() instead 355 * 356 */ 357 function infoFromTgzFile($file) 358 { 359 $packagefile = &new PEAR_PackageFile($this->config); 360 $pf = &$packagefile->fromTgzFile($file, PEAR_VALIDATE_NORMAL); 361 if (PEAR::isError($pf)) { 362 $errs = $pf->getUserinfo(); 363 if (is_array($errs)) { 364 foreach ($errs as $error) { 365 $e = $this->raiseError($error['message'], $error['code'], null, null, $error); 366 } 367 } 368 return $pf; 369 } 370 return $this->_postProcessValidPackagexml($pf); 371 } 372 373 // }}} 374 // {{{ infoFromDescriptionFile() 375 376 /** 377 * Returns information about a package file. Expects the name of 378 * a package xml file as input. 379 * 380 * @param string $descfile name of package xml file 381 * 382 * @return array array with package information 383 * 384 * @access public 385 * @deprecated use PEAR_PackageFile->fromPackageFile() instead 386 * 387 */ 388 function infoFromDescriptionFile($descfile) 389 { 390 $packagefile = &new PEAR_PackageFile($this->config); 391 $pf = &$packagefile->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL); 392 if (PEAR::isError($pf)) { 393 $errs = $pf->getUserinfo(); 394 if (is_array($errs)) { 395 foreach ($errs as $error) { 396 $e = $this->raiseError($error['message'], $error['code'], null, null, $error); 397 } 398 } 399 return $pf; 400 } 401 return $this->_postProcessValidPackagexml($pf); 402 } 403 404 // }}} 405 // {{{ infoFromString() 406 407 /** 408 * Returns information about a package file. Expects the contents 409 * of a package xml file as input. 410 * 411 * @param string $data contents of package.xml file 412 * 413 * @return array array with package information 414 * 415 * @access public 416 * @deprecated use PEAR_PackageFile->fromXmlstring() instead 417 * 418 */ 419 function infoFromString($data) 420 { 421 $packagefile = &new PEAR_PackageFile($this->config); 422 $pf = &$packagefile->fromXmlString($data, PEAR_VALIDATE_NORMAL, false); 423 if (PEAR::isError($pf)) { 424 $errs = $pf->getUserinfo(); 425 if (is_array($errs)) { 426 foreach ($errs as $error) { 427 $e = $this->raiseError($error['message'], $error['code'], null, null, $error); 428 } 429 } 430 return $pf; 431 } 432 return $this->_postProcessValidPackagexml($pf); 433 } 434 // }}} 435 436 /** 437 * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 438 * @return array 439 */ 440 function _postProcessValidPackagexml(&$pf) 441 { 442 if (is_a($pf, 'PEAR_PackageFile_v2')) { 443 // sort of make this into a package.xml 1.0-style array 444 // changelog is not converted to old format. 445 $arr = $pf->toArray(true); 446 $arr = array_merge($arr, $arr['old']); 447 unset($arr['old']); 448 unset($arr['xsdversion']); 449 unset($arr['contents']); 450 unset($arr['compatible']); 451 unset($arr['channel']); 452 unset($arr['uri']); 453 unset($arr['dependencies']); 454 unset($arr['phprelease']); 455 unset($arr['extsrcrelease']); 456 unset($arr['zendextsrcrelease']); 457 unset($arr['extbinrelease']); 458 unset($arr['zendextbinrelease']); 459 unset($arr['bundle']); 460 unset($arr['lead']); 461 unset($arr['developer']); 462 unset($arr['helper']); 463 unset($arr['contributor']); 464 $arr['filelist'] = $pf->getFilelist(); 465 $this->pkginfo = $arr; 466 return $arr; 467 } else { 468 $this->pkginfo = $pf->toArray(); 469 return $this->pkginfo; 470 } 471 } 472 // {{{ infoFromAny() 473 474 /** 475 * Returns package information from different sources 476 * 477 * This method is able to extract information about a package 478 * from a .tgz archive or from a XML package definition file. 479 * 480 * @access public 481 * @param string Filename of the source ('package.xml', '<package>.tgz') 482 * @return string 483 * @deprecated use PEAR_PackageFile->fromAnyFile() instead 484 */ 485 function infoFromAny($info) 486 { 487 if (is_string($info) && file_exists($info)) { 488 $packagefile = &new PEAR_PackageFile($this->config); 489 $pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL); 490 if (PEAR::isError($pf)) { 491 $errs = $pf->getUserinfo(); 492 if (is_array($errs)) { 493 foreach ($errs as $error) { 494 $e = $this->raiseError($error['message'], $error['code'], null, null, $error); 495 } 496 } 497 return $pf; 498 } 499 return $this->_postProcessValidPackagexml($pf); 500 } 501 return $info; 502 } 503 504 // }}} 505 // {{{ xmlFromInfo() 506 507 /** 508 * Return an XML document based on the package info (as returned 509 * by the PEAR_Common::infoFrom* methods). 510 * 511 * @param array $pkginfo package info 512 * 513 * @return string XML data 514 * 515 * @access public 516 * @deprecated use a PEAR_PackageFile_v* object's generator instead 517 */ 518 function xmlFromInfo($pkginfo) 519 { 520 $config = &PEAR_Config::singleton(); 521 $packagefile = &new PEAR_PackageFile($config); 522 $pf = &$packagefile->fromArray($pkginfo); 523 $gen = &$pf->getDefaultGenerator(); 524 return $gen->toXml(PEAR_VALIDATE_PACKAGING); 525 } 526 527 // }}} 528 // {{{ validatePackageInfo() 529 530 /** 531 * Validate XML package definition file. 532 * 533 * @param string $info Filename of the package archive or of the 534 * package definition file 535 * @param array $errors Array that will contain the errors 536 * @param array $warnings Array that will contain the warnings 537 * @param string $dir_prefix (optional) directory where source files 538 * may be found, or empty if they are not available 539 * @access public 540 * @return boolean 541 * @deprecated use the validation of PEAR_PackageFile objects 542 */ 543 function validatePackageInfo($info, &$errors, &$warnings, $dir_prefix = '') 544 { 545 $config = &PEAR_Config::singleton(); 546 $packagefile = &new PEAR_PackageFile($config); 547 PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); 548 if (strpos($info, '<?xml') !== false) { 549 $pf = &$packagefile->fromXmlString($info, PEAR_VALIDATE_NORMAL, ''); 550 } else { 551 $pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL); 552 } 553 PEAR::staticPopErrorHandling(); 554 if (PEAR::isError($pf)) { 555 $errs = $pf->getUserinfo(); 556 if (is_array($errs)) { 557 foreach ($errs as $error) { 558 if ($error['level'] == 'error') { 559 $errors[] = $error['message']; 560 } else { 561 $warnings[] = $error['message']; 562 } 563 } 564 } 565 return false; 566 } 567 return true; 568 } 569 570 // }}} 571 // {{{ buildProvidesArray() 572 573 /** 574 * Build a "provides" array from data returned by 575 * analyzeSourceCode(). The format of the built array is like 576 * this: 577 * 578 * array( 579 * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), 580 * ... 581 * ) 582 * 583 * 584 * @param array $srcinfo array with information about a source file 585 * as returned by the analyzeSourceCode() method. 586 * 587 * @return void 588 * 589 * @access public 590 * 591 */ 592 function buildProvidesArray($srcinfo) 593 { 594 $file = basename($srcinfo['source_file']); 595 $pn = ''; 596 if (isset($this->_packageName)) { 597 $pn = $this->_packageName; 598 } 599 $pnl = strlen($pn); 600 foreach ($srcinfo['declared_classes'] as $class) { 601 $key = "class;$class"; 602 if (isset($this->pkginfo['provides'][$key])) { 603 continue; 604 } 605 $this->pkginfo['provides'][$key] = 606 array('file'=> $file, 'type' => 'class', 'name' => $class); 607 if (isset($srcinfo['inheritance'][$class])) { 608 $this->pkginfo['provides'][$key]['extends'] = 609 $srcinfo['inheritance'][$class]; 610 } 611 } 612 foreach ($srcinfo['declared_methods'] as $class => $methods) { 613 foreach ($methods as $method) { 614 $function = "$class::$method"; 615 $key = "function;$function"; 616 if ($method{0} == '_' || !strcasecmp($method, $class) || 617 isset($this->pkginfo['provides'][$key])) { 618 continue; 619 } 620 $this->pkginfo['provides'][$key] = 621 array('file'=> $file, 'type' => 'function', 'name' => $function); 622 } 623 } 624 625 foreach ($srcinfo['declared_functions'] as $function) { 626 $key = "function;$function"; 627 if ($function{0} == '_' || isset($this->pkginfo['provides'][$key])) { 628 continue; 629 } 630 if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { 631 $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; 632 } 633 $this->pkginfo['provides'][$key] = 634 array('file'=> $file, 'type' => 'function', 'name' => $function); 635 } 636 } 637 638 // }}} 639 // {{{ analyzeSourceCode() 640 641 /** 642 * Analyze the source code of the given PHP file 643 * 644 * @param string Filename of the PHP file 645 * @return mixed 646 * @access public 647 */ 648 function analyzeSourceCode($file) 649 { 650 if (!function_exists("token_get_all")) { 651 return false; 652 } 653 if (!defined('T_DOC_COMMENT')) { 654 define('T_DOC_COMMENT', T_COMMENT); 655 } 656 if (!defined('T_INTERFACE')) { 657 define('T_INTERFACE', -1); 658 } 659 if (!defined('T_IMPLEMENTS')) { 660 define('T_IMPLEMENTS', -1); 661 } 662 if (!$fp = @fopen($file, "r")) { 663 return false; 664 } 665 fclose($fp); 666 $contents = file_get_contents($file); 667 $tokens = token_get_all($contents); 668 /* 669 for ($i = 0; $i < sizeof($tokens); $i++) { 670 @list($token, $data) = $tokens[$i]; 671 if (is_string($token)) { 672 var_dump($token); 673 } else { 674 print token_name($token) . ' '; 675 var_dump(rtrim($data)); 676 } 677 } 678 */ 679 $look_for = 0; 680 $paren_level = 0; 681 $bracket_level = 0; 682 $brace_level = 0; 683 $lastphpdoc = ''; 684 $current_class = ''; 685 $current_interface = ''; 686 $current_class_level = -1; 687 $current_function = ''; 688 $current_function_level = -1; 689 $declared_classes = array(); 690 $declared_interfaces = array(); 691 $declared_functions = array(); 692 $declared_methods = array(); 693 $used_classes = array(); 694 $used_functions = array(); 695 $extends = array(); 696 $implements = array(); 697 $nodeps = array(); 698 $inquote = false; 699 $interface = false; 700 for ($i = 0; $i < sizeof($tokens); $i++) { 701 if (is_array($tokens[$i])) { 702 list($token, $data) = $tokens[$i]; 703 } else { 704 $token = $tokens[$i]; 705 $data = ''; 706 } 707 if ($inquote) { 708 if ($token != '"') { 709 continue; 710 } else { 711 $inquote = false; 712 continue; 713 } 714 } 715 switch ($token) { 716 case T_WHITESPACE: 717 continue; 718 case ';': 719 if ($interface) { 720 $current_function = ''; 721 $current_function_level = -1; 722 } 723 break; 724 case '"': 725 $inquote = true; 726 break; 727 case T_CURLY_OPEN: 728 case T_DOLLAR_OPEN_CURLY_BRACES: 729 case '{': $brace_level++; continue 2; 730 case '}': 731 $brace_level--; 732 if ($current_class_level == $brace_level) { 733 $current_class = ''; 734 $current_class_level = -1; 735 } 736 if ($current_function_level == $brace_level) { 737 $current_function = ''; 738 $current_function_level = -1; 739 } 740 continue 2; 741 case '[': $bracket_level++; continue 2; 742 case ']': $bracket_level--; continue 2; 743 case '(': $paren_level++; continue 2; 744 case ')': $paren_level--; continue 2; 745 case T_INTERFACE: 746 $interface = true; 747 case T_CLASS: 748 if (($current_class_level != -1) || ($current_function_level != -1)) { 749 PEAR::raiseError("Parser error: invalid PHP found in file \"$file\"", 750 PEAR_COMMON_ERROR_INVALIDPHP); 751 return false; 752 } 753 case T_FUNCTION: 754 case T_NEW: 755 case T_EXTENDS: 756 case T_IMPLEMENTS: 757 $look_for = $token; 758 continue 2; 759 case T_STRING: 760 if (version_compare(zend_version(), '2.0', '<')) { 761 if (in_array(strtolower($data), 762 array('public', 'private', 'protected', 'abstract', 763 'interface', 'implements', 'throw') 764 )) { 765 PEAR::raiseError('Error: PHP5 token encountered in ' . $file . 766 'packaging should be done in PHP 5'); 767 return false; 768 } 769 } 770 if ($look_for == T_CLASS) { 771 $current_class = $data; 772 $current_class_level = $brace_level; 773 $declared_classes[] = $current_class; 774 } elseif ($look_for == T_INTERFACE) { 775 $current_interface = $data; 776 $current_class_level = $brace_level; 777 $declared_interfaces[] = $current_interface; 778 } elseif ($look_for == T_IMPLEMENTS) { 779 $implements[$current_class] = $data; 780 } elseif ($look_for == T_EXTENDS) { 781 $extends[$current_class] = $data; 782 } elseif ($look_for == T_FUNCTION) { 783 if ($current_class) { 784 $current_function = "$current_class::$data"; 785 $declared_methods[$current_class][] = $data; 786 } elseif ($current_interface) { 787 $current_function = "$current_interface::$data"; 788 $declared_methods[$current_interface][] = $data; 789 } else { 790 $current_function = $data; 791 $declared_functions[] = $current_function; 792 } 793 $current_function_level = $brace_level; 794 $m = array(); 795 } elseif ($look_for == T_NEW) { 796 $used_classes[$data] = true; 797 } 798 $look_for = 0; 799 continue 2; 800 case T_VARIABLE: 801 $look_for = 0; 802 continue 2; 803 case T_DOC_COMMENT: 804 case T_COMMENT: 805 if (preg_match('!^/\*\*\s!', $data)) { 806 $lastphpdoc = $data; 807 if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) { 808 $nodeps = array_merge($nodeps, $m[1]); 809 } 810 } 811 continue 2; 812 case T_DOUBLE_COLON: 813 if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) { 814 PEAR::raiseError("Parser error: invalid PHP found in file \"$file\"", 815 PEAR_COMMON_ERROR_INVALIDPHP); 816 return false; 817 } 818 $class = $tokens[$i - 1][1]; 819 if (strtolower($class) != 'parent') { 820 $used_classes[$class] = true; 821 } 822 continue 2; 823 } 824 } 825 return array( 826 "source_file" => $file, 827 "declared_classes" => $declared_classes, 828 "declared_interfaces" => $declared_interfaces, 829 "declared_methods" => $declared_methods, 830 "declared_functions" => $declared_functions, 831 "used_classes" => array_diff(array_keys($used_classes), $nodeps), 832 "inheritance" => $extends, 833 "implements" => $implements, 834 ); 835 } 836 837 // }}} 838 // {{{ betterStates() 839 840 /** 841 * Return an array containing all of the states that are more stable than 842 * or equal to the passed in state 843 * 844 * @param string Release state 845 * @param boolean Determines whether to include $state in the list 846 * @return false|array False if $state is not a valid release state 847 */ 848 function betterStates($state, $include = false) 849 { 850 static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable'); 851 $i = array_search($state, $states); 852 if ($i === false) { 853 return false; 854 } 855 if ($include) { 856 $i--; 857 } 858 return array_slice($states, $i + 1); 859 } 860 861 // }}} 862 // {{{ detectDependencies() 863 864 function detectDependencies($any, $status_callback = null) 865 { 866 if (!function_exists("token_get_all")) { 867 return false; 868 } 869 if (PEAR::isError($info = $this->infoFromAny($any))) { 870 return $this->raiseError($info); 871 } 872 if (!is_array($info)) { 873 return false; 874 } 875 $deps = array(); 876 $used_c = $decl_c = $decl_f = $decl_m = array(); 877 foreach ($info['filelist'] as $file => $fa) { 878 $tmp = $this->analyzeSourceCode($file); 879 $used_c = @array_merge($used_c, $tmp['used_classes']); 880 $decl_c = @array_merge($decl_c, $tmp['declared_classes']); 881 $decl_f = @array_merge($decl_f, $tmp['declared_functions']); 882 $decl_m = @array_merge($decl_m, $tmp['declared_methods']); 883 $inheri = @array_merge($inheri, $tmp['inheritance']); 884 } 885 $used_c = array_unique($used_c); 886 $decl_c = array_unique($decl_c); 887 $undecl_c = array_diff($used_c, $decl_c); 888 return array('used_classes' => $used_c, 889 'declared_classes' => $decl_c, 890 'declared_methods' => $decl_m, 891 'declared_functions' => $decl_f, 892 'undeclared_classes' => $undecl_c, 893 'inheritance' => $inheri, 894 ); 895 } 896 897 // }}} 898 // {{{ getUserRoles() 899 900 /** 901 * Get the valid roles for a PEAR package maintainer 902 * 903 * @return array 904 * @static 905 */ 906 function getUserRoles() 907 { 908 return $GLOBALS['_PEAR_Common_maintainer_roles']; 909 } 910 911 // }}} 912 // {{{ getReleaseStates() 913 914 /** 915 * Get the valid package release states of packages 916 * 917 * @return array 918 * @static 919 */ 920 function getReleaseStates() 921 { 922 return $GLOBALS['_PEAR_Common_release_states']; 923 } 924 925 // }}} 926 // {{{ getDependencyTypes() 927 928 /** 929 * Get the implemented dependency types (php, ext, pkg etc.) 930 * 931 * @return array 932 * @static 933 */ 934 function getDependencyTypes() 935 { 936 return $GLOBALS['_PEAR_Common_dependency_types']; 937 } 938 939 // }}} 940 // {{{ getDependencyRelations() 941 942 /** 943 * Get the implemented dependency relations (has, lt, ge etc.) 944 * 945 * @return array 946 * @static 947 */ 948 function getDependencyRelations() 949 { 950 return $GLOBALS['_PEAR_Common_dependency_relations']; 951 } 952 953 // }}} 954 // {{{ getFileRoles() 955 956 /** 957 * Get the implemented file roles 958 * 959 * @return array 960 * @static 961 */ 962 function getFileRoles() 963 { 964 return $GLOBALS['_PEAR_Common_file_roles']; 965 } 966 967 // }}} 968 // {{{ getReplacementTypes() 969 970 /** 971 * Get the implemented file replacement types in 972 * 973 * @return array 974 * @static 975 */ 976 function getReplacementTypes() 977 { 978 return $GLOBALS['_PEAR_Common_replacement_types']; 979 } 980 981 // }}} 982 // {{{ getProvideTypes() 983 984 /** 985 * Get the implemented file replacement types in 986 * 987 * @return array 988 * @static 989 */ 990 function getProvideTypes() 991 { 992 return $GLOBALS['_PEAR_Common_provide_types']; 993 } 994 995 // }}} 996 // {{{ getScriptPhases() 997 998 /** 999 * Get the implemented file replacement types in 1000 * 1001 * @return array 1002 * @static 1003 */ 1004 function getScriptPhases() 1005 { 1006 return $GLOBALS['_PEAR_Common_script_phases']; 1007 } 1008 1009 // }}} 1010 // {{{ validPackageName() 1011 1012 /** 1013 * Test whether a string contains a valid package name. 1014 * 1015 * @param string $name the package name to test 1016 * 1017 * @return bool 1018 * 1019 * @access public 1020 */ 1021 function validPackageName($name) 1022 { 1023 return (bool)preg_match(PEAR_COMMON_PACKAGE_NAME_PREG, $name); 1024 } 1025 1026 1027 // }}} 1028 // {{{ validPackageVersion() 1029 1030 /** 1031 * Test whether a string contains a valid package version. 1032 * 1033 * @param string $ver the package version to test 1034 * 1035 * @return bool 1036 * 1037 * @access public 1038 */ 1039 function validPackageVersion($ver) 1040 { 1041 return (bool)preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver); 1042 } 1043 1044 1045 // }}} 1046 1047 // {{{ downloadHttp() 1048 1049 /** 1050 * Download a file through HTTP. Considers suggested file name in 1051 * Content-disposition: header and can run a callback function for 1052 * different events. The callback will be called with two 1053 * parameters: the callback type, and parameters. The implemented 1054 * callback types are: 1055 * 1056 * 'setup' called at the very beginning, parameter is a UI object 1057 * that should be used for all output 1058 * 'message' the parameter is a string with an informational message 1059 * 'saveas' may be used to save with a different file name, the 1060 * parameter is the filename that is about to be used. 1061 * If a 'saveas' callback returns a non-empty string, 1062 * that file name will be used as the filename instead. 1063 * Note that $save_dir will not be affected by this, only 1064 * the basename of the file. 1065 * 'start' download is starting, parameter is number of bytes 1066 * that are expected, or -1 if unknown 1067 * 'bytesread' parameter is the number of bytes read so far 1068 * 'done' download is complete, parameter is the total number 1069 * of bytes read 1070 * 'connfailed' if the TCP connection fails, this callback is called 1071 * with array(host,port,errno,errmsg) 1072 * 'writefailed' if writing to disk fails, this callback is called 1073 * with array(destfile,errmsg) 1074 * 1075 * If an HTTP proxy has been configured (http_proxy PEAR_Config 1076 * setting), the proxy will be used. 1077 * 1078 * @param string $url the URL to download 1079 * @param object $ui PEAR_Frontend_* instance 1080 * @param object $config PEAR_Config instance 1081 * @param string $save_dir (optional) directory to save file in 1082 * @param mixed $callback (optional) function/method to call for status 1083 * updates 1084 * 1085 * @return string Returns the full path of the downloaded file or a PEAR 1086 * error on failure. If the error is caused by 1087 * socket-related errors, the error object will 1088 * have the fsockopen error code available through 1089 * getCode(). 1090 * 1091 * @access public 1092 * @deprecated in favor of PEAR_Downloader::downloadHttp() 1093 */ 1094 function downloadHttp($url, &$ui, $save_dir = '.', $callback = null) 1095 { 1096 if (!class_exists('PEAR_Downloader')) { 1097 require_once 'PEAR/Downloader.php'; 1098 } 1099 return PEAR_Downloader::downloadHttp($url, $ui, $save_dir, $callback); 1100 } 1101 1102 // }}} 1103 1104 /** 1105 * @param string $path relative or absolute include path 1106 * @return boolean 1107 * @static 1108 */ 1109 function isIncludeable($path) 1110 { 1111 if (file_exists($path) && is_readable($path)) { 1112 return true; 1113 } 1114 $ipath = explode(PATH_SEPARATOR, ini_get('include_path')); 1115 foreach ($ipath as $include) { 1116 $test = realpath($include . DIRECTORY_SEPARATOR . $path); 1117 if (file_exists($test) && is_readable($test)) { 1118 return true; 1119 } 1120 } 1121 return false; 1122 } 1123 } 1124 require_once 'PEAR/Config.php'; 1125 require_once 'PEAR/PackageFile.php'; 1126 ?>
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 |