[ Index ]
 

Code source de PHP PEAR 1.4.5

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/PEAR/PackageFile/ -> v1.php (source)

   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  ?>


Généré le : Sun Feb 25 14:08:00 2007 par Balluche grâce à PHPXref 0.7