[ Index ]
 

Code source de GeekLog 1.4.1

Accédez au Source d'autres logiciels libres

title

Body

[fermer]

/system/pear/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.69 2006/03/02 18:14:13 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.4.11
 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          $this->_packageInfo['dirtree'][$path] = true;
 461      }
 462  
 463      function getDirtree()
 464      {
 465          if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) {
 466              return $this->_packageInfo['dirtree'];
 467          }
 468          return false;
 469      }
 470  
 471      function resetDirtree()
 472      {
 473          unset($this->_packageInfo['dirtree']);
 474      }
 475  
 476      function fromArray($pinfo)
 477      {
 478          $this->_incomplete = false;
 479          $this->_packageInfo = $pinfo;
 480      }
 481  
 482      function isIncomplete()
 483      {
 484          return $this->_incomplete;
 485      }
 486  
 487      function getChannel()
 488      {
 489          return 'pear.php.net';
 490      }
 491  
 492      function getUri()
 493      {
 494          return false;
 495      }
 496  
 497      function getTime()
 498      {
 499          return false;
 500      }
 501  
 502      function getExtends()
 503      {
 504          if (isset($this->_packageInfo['extends'])) {
 505              return $this->_packageInfo['extends'];
 506          }
 507          return false;
 508      }
 509  
 510      /**
 511       * @return array
 512       */
 513      function toArray()
 514      {
 515          if (!$this->validate(PEAR_VALIDATE_NORMAL)) {
 516              return false;
 517          }
 518          return $this->getArray();
 519      }
 520  
 521      function getArray()
 522      {
 523          return $this->_packageInfo;
 524      }
 525  
 526      function getName()
 527      {
 528          return $this->getPackage();
 529      }
 530  
 531      function getPackage()
 532      {
 533          if (isset($this->_packageInfo['package'])) {
 534              return $this->_packageInfo['package'];
 535          }
 536          return false;
 537      }
 538  
 539      /**
 540       * WARNING - don't use this unless you know what you are doing
 541       */
 542      function setRawPackage($package)
 543      {
 544          $this->_packageInfo['package'] = $package;
 545      }
 546  
 547      function setPackage($package)
 548      {
 549          $this->_packageInfo['package'] = $package;
 550          $this->_isValid = false;
 551      }
 552  
 553      function getVersion()
 554      {
 555          if (isset($this->_packageInfo['version'])) {
 556              return $this->_packageInfo['version'];
 557          }
 558          return false;
 559      }
 560  
 561      function setVersion($version)
 562      {
 563          $this->_packageInfo['version'] = $version;
 564          $this->_isValid = false;
 565      }
 566  
 567      function clearMaintainers()
 568      {
 569          unset($this->_packageInfo['maintainers']);
 570      }
 571  
 572      function getMaintainers()
 573      {
 574          if (isset($this->_packageInfo['maintainers'])) {
 575              return $this->_packageInfo['maintainers'];
 576          }
 577          return false;
 578      }
 579  
 580      /**
 581       * Adds a new maintainer - no checking of duplicates is performed, use
 582       * updatemaintainer for that purpose.
 583       */
 584      function addMaintainer($role, $handle, $name, $email)
 585      {
 586          $this->_packageInfo['maintainers'][] =
 587              array('handle' => $handle, 'role' => $role, 'email' => $email, 'name' => $name);
 588          $this->_isValid = false;
 589      }
 590  
 591      function updateMaintainer($role, $handle, $name, $email)
 592      {
 593          $found = false;
 594          if (!isset($this->_packageInfo['maintainers']) ||
 595                !is_array($this->_packageInfo['maintainers'])) {
 596              return $this->addMaintainer($role, $handle, $name, $email);
 597          }
 598          foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) {
 599              if ($maintainer['handle'] == $handle) {
 600                  $found = $i;
 601                  break;
 602              }
 603          }
 604          if ($found !== false) {
 605              unset($this->_packageInfo['maintainers'][$found]);
 606              $this->_packageInfo['maintainers'] =
 607                  array_values($this->_packageInfo['maintainers']);
 608          }
 609          $this->addMaintainer($role, $handle, $name, $email);
 610      }
 611  
 612      function deleteMaintainer($handle)
 613      {
 614          $found = false;
 615          foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) {
 616              if ($maintainer['handle'] == $handle) {
 617                  $found = $i;
 618                  break;
 619              }
 620          }
 621          if ($found !== false) {
 622              unset($this->_packageInfo['maintainers'][$found]);
 623              $this->_packageInfo['maintainers'] =
 624                  array_values($this->_packageInfo['maintainers']);
 625              return true;
 626          }
 627          return false;
 628      }
 629  
 630      function getState()
 631      {
 632          if (isset($this->_packageInfo['release_state'])) {
 633              return $this->_packageInfo['release_state'];
 634          }
 635          return false;
 636      }
 637  
 638      function setRawState($state)
 639      {
 640          $this->_packageInfo['release_state'] = $state;
 641      }
 642  
 643      function setState($state)
 644      {
 645          $this->_packageInfo['release_state'] = $state;
 646          $this->_isValid = false;
 647      }
 648  
 649      function getDate()
 650      {
 651          if (isset($this->_packageInfo['release_date'])) {
 652              return $this->_packageInfo['release_date'];
 653          }
 654          return false;
 655      }
 656  
 657      function setDate($date)
 658      {
 659          $this->_packageInfo['release_date'] = $date;
 660          $this->_isValid = false;
 661      }
 662  
 663      function getLicense()
 664      {
 665          if (isset($this->_packageInfo['release_license'])) {
 666              return $this->_packageInfo['release_license'];
 667          }
 668          return false;
 669      }
 670  
 671      function setLicense($date)
 672      {
 673          $this->_packageInfo['release_license'] = $date;
 674          $this->_isValid = false;
 675      }
 676  
 677      function getSummary()
 678      {
 679          if (isset($this->_packageInfo['summary'])) {
 680              return $this->_packageInfo['summary'];
 681          }
 682          return false;
 683      }
 684  
 685      function setSummary($summary)
 686      {
 687          $this->_packageInfo['summary'] = $summary;
 688          $this->_isValid = false;
 689      }
 690  
 691      function getDescription()
 692      {
 693          if (isset($this->_packageInfo['description'])) {
 694              return $this->_packageInfo['description'];
 695          }
 696          return false;
 697      }
 698  
 699      function setDescription($desc)
 700      {
 701          $this->_packageInfo['description'] = $desc;
 702          $this->_isValid = false;
 703      }
 704  
 705      function getNotes()
 706      {
 707          if (isset($this->_packageInfo['release_notes'])) {
 708              return $this->_packageInfo['release_notes'];
 709          }
 710          return false;
 711      }
 712  
 713      function setNotes($notes)
 714      {
 715          $this->_packageInfo['release_notes'] = $notes;
 716          $this->_isValid = false;
 717      }
 718  
 719      function getDeps()
 720      {
 721          if (isset($this->_packageInfo['release_deps'])) {
 722              return $this->_packageInfo['release_deps'];
 723          }
 724          return false;
 725      }
 726  
 727      /**
 728       * Reset dependencies prior to adding new ones
 729       */
 730      function clearDeps()
 731      {
 732          unset($this->_packageInfo['release_deps']);
 733      }
 734  
 735      function addPhpDep($version, $rel)
 736      {
 737          $this->_isValid = false;
 738          $this->_packageInfo['release_deps'][] =
 739              array('type' => 'php',
 740                    'rel' => $rel,
 741                    'version' => $version);
 742      }
 743  
 744      function addPackageDep($name, $version, $rel, $optional = 'no')
 745      {
 746          $this->_isValid = false;
 747          $dep =
 748              array('type' => 'pkg',
 749                    'name' => $name,
 750                    'rel' => $rel,
 751                    'optional' => $optional);
 752          if ($rel != 'has' && $rel != 'not') {
 753              $dep['version'] = $version;
 754          }
 755          $this->_packageInfo['release_deps'][] = $dep;
 756      }
 757  
 758      function addExtensionDep($name, $version, $rel, $optional = 'no')
 759      {
 760          $this->_isValid = false;
 761          $this->_packageInfo['release_deps'][] =
 762              array('type' => 'ext',
 763                    'name' => $name,
 764                    'rel' => $rel,
 765                    'version' => $version,
 766                    'optional' => $optional);
 767      }
 768  
 769      /**
 770       * WARNING - do not use this function directly unless you know what you're doing
 771       */
 772      function setDeps($deps)
 773      {
 774          $this->_packageInfo['release_deps'] = $deps;
 775      }
 776  
 777      function hasDeps()
 778      {
 779          return isset($this->_packageInfo['release_deps']) &&
 780              count($this->_packageInfo['release_deps']);
 781      }
 782  
 783      function getDependencyGroup($group)
 784      {
 785          return false;
 786      }
 787  
 788      function isCompatible($pf)
 789      {
 790          return false;
 791      }
 792  
 793      function isSubpackageOf($p)
 794      {
 795          return $p->isSubpackage($this);
 796      }
 797  
 798      function isSubpackage($p)
 799      {
 800          return false;
 801      }
 802  
 803      function dependsOn($package, $channel)
 804      {
 805          if (strtolower($channel) != 'pear.php.net') {
 806              return false;
 807          }
 808          if (!($deps = $this->getDeps())) {
 809              return false;
 810          }
 811          foreach ($deps as $dep) {
 812              if ($dep['type'] != 'pkg') {
 813                  continue;
 814              }
 815              if (strtolower($dep['name']) == strtolower($package)) {
 816                  return true;
 817              }
 818          }
 819          return false;
 820      }
 821  
 822      function getConfigureOptions()
 823      {
 824          if (isset($this->_packageInfo['configure_options'])) {
 825              return $this->_packageInfo['configure_options'];
 826          }
 827          return false;
 828      }
 829  
 830      function hasConfigureOptions()
 831      {
 832          return isset($this->_packageInfo['configure_options']) &&
 833              count($this->_packageInfo['configure_options']);
 834      }
 835  
 836      function addConfigureOption($name, $prompt, $default = false)
 837      {
 838          $o = array('name' => $name, 'prompt' => $prompt);
 839          if ($default !== false) {
 840              $o['default'] = $default;
 841          }
 842          if (!isset($this->_packageInfo['configure_options'])) {
 843              $this->_packageInfo['configure_options'] = array();
 844          }
 845          $this->_packageInfo['configure_options'][] = $o;
 846      }
 847  
 848      function clearConfigureOptions()
 849      {
 850          unset($this->_packageInfo['configure_options']);
 851      }
 852  
 853      function getProvides()
 854      {
 855          if (isset($this->_packageInfo['provides'])) {
 856              return $this->_packageInfo['provides'];
 857          }
 858          return false;
 859      }
 860  
 861      function addFile($dir, $file, $attrs)
 862      {
 863          $dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir);
 864          if ($dir == '/' || $dir == '') {
 865              $dir = '';
 866          } else {
 867              $dir .= '/';
 868          }
 869          $file = $dir . $file;
 870          $file = preg_replace('![\\/]+!', '/', $file);
 871          $this->_packageInfo['filelist'][$file] = $attrs;
 872      }
 873  
 874      function getInstallationFilelist()
 875      {
 876          return $this->getFilelist();
 877      }
 878  
 879      function getFilelist()
 880      {
 881          if (isset($this->_packageInfo['filelist'])) {
 882              return $this->_packageInfo['filelist'];
 883          }
 884          return false;
 885      }
 886  
 887      function setFileAttribute($file, $attr, $value)
 888      {
 889          $this->_packageInfo['filelist'][$file][$attr] = $value;
 890      }
 891  
 892      function resetFilelist()
 893      {
 894          $this->_packageInfo['filelist'] = array();
 895      }
 896  
 897      function setInstalledAs($file, $path)
 898      {
 899          if ($path) {
 900              return $this->_packageInfo['filelist'][$file]['installed_as'] = $path;
 901          }
 902          unset($this->_packageInfo['filelist'][$file]['installed_as']);
 903      }
 904  
 905      function installedFile($file, $atts)
 906      {
 907          if (isset($this->_packageInfo['filelist'][$file])) {
 908              $this->_packageInfo['filelist'][$file] =
 909                  array_merge($this->_packageInfo['filelist'][$file], $atts);
 910          } else {
 911              $this->_packageInfo['filelist'][$file] = $atts;
 912          }
 913      }
 914  
 915      function getChangelog()
 916      {
 917          if (isset($this->_packageInfo['changelog'])) {
 918              return $this->_packageInfo['changelog'];
 919          }
 920          return false;
 921      }
 922  
 923      function getPackagexmlVersion()
 924      {
 925          return '1.0';
 926      }
 927  
 928      /**
 929       * Wrapper to {@link PEAR_ErrorStack::getErrors()}
 930       * @param boolean determines whether to purge the error stack after retrieving
 931       * @return array
 932       */
 933      function getValidationWarnings($purge = true)
 934      {
 935          return $this->_stack->getErrors($purge);
 936      }
 937  
 938      // }}}
 939      /**
 940       * Validation error.  Also marks the object contents as invalid
 941       * @param error code
 942       * @param array error information
 943       * @access private
 944       */
 945      function _validateError($code, $params = array())
 946      {
 947          $this->_stack->push($code, 'error', $params, false, false, debug_backtrace());
 948          $this->_isValid = false;
 949      }
 950  
 951      /**
 952       * Validation warning.  Does not mark the object contents invalid.
 953       * @param error code
 954       * @param array error information
 955       * @access private
 956       */
 957      function _validateWarning($code, $params = array())
 958      {
 959          $this->_stack->push($code, 'warning', $params, false, false, debug_backtrace());
 960      }
 961  
 962      /**
 963       * @param integer error code
 964       * @access protected
 965       */
 966      function _getErrorMessage()
 967      {
 968          return array(
 969                  PEAR_PACKAGEFILE_ERROR_NO_NAME =>
 970                      'Missing Package Name',
 971                  PEAR_PACKAGEFILE_ERROR_NO_SUMMARY =>
 972                      'No summary found',
 973                  PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY =>
 974                      'Summary should be on one line',
 975                  PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION =>
 976                      'Missing description',
 977                  PEAR_PACKAGEFILE_ERROR_NO_LICENSE =>
 978                      'Missing license',
 979                  PEAR_PACKAGEFILE_ERROR_NO_VERSION =>
 980                      'No release version found',
 981                  PEAR_PACKAGEFILE_ERROR_NO_STATE =>
 982                      'No release state found',
 983                  PEAR_PACKAGEFILE_ERROR_NO_DATE =>
 984                      'No release date found',
 985                  PEAR_PACKAGEFILE_ERROR_NO_NOTES =>
 986                      'No release notes found',
 987                  PEAR_PACKAGEFILE_ERROR_NO_LEAD =>
 988                      'Package must have at least one lead maintainer',
 989                  PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS =>
 990                      'No maintainers found, at least one must be defined',
 991                  PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE =>
 992                      'Maintainer %index% has no handle (user ID at channel server)',
 993                  PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE =>
 994                      'Maintainer %index% has no role',
 995                  PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME =>
 996                      'Maintainer %index% has no name',
 997                  PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL =>
 998                      'Maintainer %index% has no email',
 999                  PEAR_PACKAGEFILE_ERROR_NO_DEPNAME =>
1000                      'Dependency %index% is not a php dependency, and has no name',
1001                  PEAR_PACKAGEFILE_ERROR_NO_DEPREL =>
1002                      'Dependency %index% has no relation (rel)',
1003                  PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE =>
1004                      'Dependency %index% has no type',
1005                  PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED =>
1006                      'PHP Dependency %index% has a name attribute of "%name%" which will be' .
1007                          ' ignored!',
1008                  PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION =>
1009                      'Dependency %index% is not a rel="has" or rel="not" dependency, ' .
1010                          'and has no version',
1011                  PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION =>
1012                      'Dependency %index% is a type="php" dependency, ' .
1013                          'and has no version',
1014                  PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED =>
1015                      'Dependency %index% is a rel="%rel%" dependency, versioning is ignored',
1016                  PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL =>
1017                      'Dependency %index% has invalid optional value "%opt%", should be yes or no',
1018                  PEAR_PACKAGEFILE_PHP_NO_NOT =>
1019                      'Dependency %index%: php dependencies cannot use "not" rel, use "ne"' .
1020                          ' to exclude specific versions',
1021                  PEAR_PACKAGEFILE_ERROR_NO_CONFNAME =>
1022                      'Configure Option %index% has no name',
1023                  PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT =>
1024                      'Configure Option %index% has no prompt',
1025                  PEAR_PACKAGEFILE_ERROR_NO_FILES =>
1026                      'No files in <filelist> section of package.xml',
1027                  PEAR_PACKAGEFILE_ERROR_NO_FILEROLE =>
1028                      'File "%file%" has no role, expecting one of "%roles%"',
1029                  PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE =>
1030                      'File "%file%" has invalid role "%role%", expecting one of "%roles%"',
1031                  PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME =>
1032                      'File "%file%" cannot start with ".", cannot package or install',
1033                  PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE =>
1034                      'Parser error: invalid PHP found in file "%file%"',
1035                  PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX =>
1036                      'in %file%: %type% "%name%" not prefixed with package name "%package%"',
1037                  PEAR_PACKAGEFILE_ERROR_INVALID_FILE =>
1038                      'Parser error: invalid PHP file "%file%"',
1039                  PEAR_PACKAGEFILE_ERROR_CHANNELVAL =>
1040                      'Channel validator error: field "%field%" - %reason%',
1041                  PEAR_PACKAGEFILE_ERROR_PHP5 =>
1042                      'Error, PHP5 token encountered in %file%, analysis should be in PHP5',
1043                  PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND =>
1044                      'File "%file%" in package.xml does not exist',
1045                  PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS =>
1046                      'Package.xml contains non-ISO-8859-1 characters, and may not validate',
1047              );
1048      }
1049  
1050      /**
1051       * Validate XML package definition file.
1052       *
1053       * @access public
1054       * @return boolean
1055       */
1056      function validate($state = PEAR_VALIDATE_NORMAL, $nofilechecking = false)
1057      {
1058          if (($this->_isValid & $state) == $state) {
1059              return true;
1060          }
1061          $this->_isValid = true;
1062          $info = $this->_packageInfo;
1063          if (empty($info['package'])) {
1064              $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NAME);
1065              $this->_packageName = $pn = 'unknown';
1066          } else {
1067              $this->_packageName = $pn = $info['package'];
1068          }
1069  
1070          if (empty($info['summary'])) {
1071              $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_SUMMARY);
1072          } elseif (strpos(trim($info['summary']), "\n") !== false) {
1073              $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY,
1074                  array('summary' => $info['summary']));
1075          }
1076          if (empty($info['description'])) {
1077              $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION);
1078          }
1079          if (empty($info['release_license'])) {
1080              $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LICENSE);
1081          }
1082          if (empty($info['version'])) {
1083              $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_VERSION);
1084          }
1085          if (empty($info['release_state'])) {
1086              $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_STATE);
1087          }
1088          if (empty($info['release_date'])) {
1089              $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DATE);
1090          }
1091          if (empty($info['release_notes'])) {
1092              $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NOTES);
1093          }
1094          if (empty($info['maintainers'])) {
1095              $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS);
1096          } else {
1097              $haslead = false;
1098              $i = 1;
1099              foreach ($info['maintainers'] as $m) {
1100                  if (empty($m['handle'])) {
1101                      $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE,
1102                          array('index' => $i));
1103                  }
1104                  if (empty($m['role'])) {
1105                      $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE,
1106                          array('index' => $i, 'roles' => PEAR_Common::getUserRoles()));
1107                  } elseif ($m['role'] == 'lead') {
1108                      $haslead = true;
1109                  }
1110                  if (empty($m['name'])) {
1111                      $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME,
1112                          array('index' => $i));
1113                  }
1114                  if (empty($m['email'])) {
1115                      $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL,
1116                          array('index' => $i));
1117                  }
1118                  $i++;
1119              }
1120              if (!$haslead) {
1121                  $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LEAD);
1122              }
1123          }
1124          if (!empty($info['release_deps'])) {
1125              $i = 1;
1126              foreach ($info['release_deps'] as $d) {
1127                  if (!isset($d['type']) || empty($d['type'])) {
1128                      $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE,
1129                          array('index' => $i, 'types' => PEAR_Common::getDependencyTypes()));
1130                      continue;
1131                  }
1132                  if (!isset($d['rel']) || empty($d['rel'])) {
1133                      $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPREL,
1134                          array('index' => $i, 'rels' => PEAR_Common::getDependencyRelations()));
1135                      continue;
1136                  }
1137                  if (!empty($d['optional'])) {
1138                      if (!in_array($d['optional'], array('yes', 'no'))) {
1139                          $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL,
1140                              array('index' => $i, 'opt' => $d['optional']));
1141                      }
1142                  }
1143                  if ($d['rel'] != 'has' && $d['rel'] != 'not' && empty($d['version'])) {
1144                      $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION,
1145                          array('index' => $i));
1146                  } elseif (($d['rel'] == 'has' || $d['rel'] == 'not') && !empty($d['version'])) {
1147                      $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED,
1148                          array('index' => $i, 'rel' => $d['rel']));
1149                  }
1150                  if ($d['type'] == 'php' && !empty($d['name'])) {
1151                      $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED,
1152                          array('index' => $i, 'name' => $d['name']));
1153                  } elseif ($d['type'] != 'php' && empty($d['name'])) {
1154                      $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPNAME,
1155                          array('index' => $i));
1156                  }
1157                  if ($d['type'] == 'php' && empty($d['version'])) {
1158                      $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION,
1159                          array('index' => $i));
1160                  }
1161                  if (($d['rel'] == 'not') && ($d['type'] == 'php')) {
1162                      $this->_validateError(PEAR_PACKAGEFILE_PHP_NO_NOT,
1163                          array('index' => $i));
1164                  }
1165                  $i++;
1166              }
1167          }
1168          if (!empty($info['configure_options'])) {
1169              $i = 1;
1170              foreach ($info['configure_options'] as $c) {
1171                  if (empty($c['name'])) {
1172                      $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFNAME,
1173                          array('index' => $i));
1174                  }
1175                  if (empty($c['prompt'])) {
1176                      $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT,
1177                          array('index' => $i));
1178                  }
1179                  $i++;
1180              }
1181          }
1182          if (empty($info['filelist'])) {
1183              $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILES);
1184              $errors[] = 'no files';
1185          } else {
1186              foreach ($info['filelist'] as $file => $fa) {
1187                  if (empty($fa['role'])) {
1188                      $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILEROLE,
1189                          array('file' => $file, 'roles' => PEAR_Common::getFileRoles()));
1190                      continue;
1191                  } elseif (!in_array($fa['role'], PEAR_Common::getFileRoles())) {
1192                      $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE,
1193                          array('file' => $file, 'role' => $fa['role'], 'roles' => PEAR_Common::getFileRoles()));
1194                  }
1195                  if ($file{0} == '.' && $file{1} == '/') {
1196                      $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
1197                          array('file' => $file));
1198                  }
1199              }
1200          }
1201          if (isset($this->_registry) && $this->_isValid) {
1202              $chan = $this->_registry->getChannel('pear.php.net');
1203              if (PEAR::isError($chan)) {
1204                  $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $chan->getMessage());
1205                  return $this->_isValid = 0;
1206              }
1207              $validator = $chan->getValidationObject();
1208              $validator->setPackageFile($this);
1209              $validator->validate($state);
1210              $failures = $validator->getFailures();
1211              foreach ($failures['errors'] as $error) {
1212                  $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $error);
1213              }
1214              foreach ($failures['warnings'] as $warning) {
1215                  $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $warning);
1216              }
1217          }
1218          if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$nofilechecking) {
1219              if ($this->_analyzePhpFiles()) {
1220                  $this->_isValid = true;
1221              }
1222          }
1223          if ($this->_isValid) {
1224              return $this->_isValid = $state;
1225          }
1226          return $this->_isValid = 0;
1227      }
1228  
1229      function _analyzePhpFiles()
1230      {
1231          if (!$this->_isValid) {
1232              return false;
1233          }
1234          if (!isset($this->_packageFile)) {
1235              return false;
1236          }
1237          $dir_prefix = dirname($this->_packageFile);
1238          $common = new PEAR_Common;
1239          $log = isset($this->_logger) ? array(&$this->_logger, 'log') :
1240              array($common, 'log');
1241          $info = $this->getFilelist();
1242          foreach ($info as $file => $fa) {
1243              if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) {
1244                  $this->_validateError(PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND,
1245                      array('file' => realpath($dir_prefix) . DIRECTORY_SEPARATOR . $file));
1246                  continue;
1247              }
1248              if ($fa['role'] == 'php' && $dir_prefix) {
1249                  call_user_func_array($log, array(1, "Analyzing $file"));
1250                  $srcinfo = $this->_analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file);
1251                  if ($srcinfo) {
1252                      $this->_buildProvidesArray($srcinfo);
1253                  }
1254              }
1255          }
1256          $this->_packageName = $pn = $this->getPackage();
1257          $pnl = strlen($pn);
1258          if (isset($this->_packageInfo['provides'])) {
1259              foreach ((array) $this->_packageInfo['provides'] as $key => $what) {
1260                  if (isset($what['explicit'])) {
1261                      // skip conformance checks if the provides entry is
1262                      // specified in the package.xml file
1263                      continue;
1264                  }
1265                  extract($what);
1266                  if ($type == 'class') {
1267                      if (!strncasecmp($name, $pn, $pnl)) {
1268                          continue;
1269                      }
1270                      $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX,
1271                          array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn));
1272                  } elseif ($type == 'function') {
1273                      if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) {
1274                          continue;
1275                      }
1276                      $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX,
1277                          array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn));
1278                  }
1279              }
1280          }
1281          return $this->_isValid;
1282      }
1283  
1284      /**
1285       * Get the default xml generator object
1286       *
1287       * @return PEAR_PackageFile_Generator_v1
1288       */
1289      function &getDefaultGenerator()
1290      {
1291          if (!class_exists('PEAR_PackageFile_Generator_v1')) {
1292              require_once 'PEAR/PackageFile/Generator/v1.php';
1293          }
1294          $a = &new PEAR_PackageFile_Generator_v1($this);
1295          return $a;
1296      }
1297  
1298      /**
1299       * Get the contents of a file listed within the package.xml
1300       * @param string
1301       * @return string
1302       */
1303      function getFileContents($file)
1304      {
1305          if ($this->_archiveFile == $this->_packageFile) { // unpacked
1306              $dir = dirname($this->_packageFile);
1307              $file = $dir . DIRECTORY_SEPARATOR . $file;
1308              $file = str_replace(array('/', '\\'),
1309                  array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file);
1310              if (file_exists($file) && is_readable($file)) {
1311                  return implode('', file($file));
1312              }
1313          } else { // tgz
1314              if (!class_exists('Archive_Tar')) {
1315                  require_once 'Archive/Tar.php';
1316              }
1317              $tar = &new Archive_Tar($this->_archiveFile);
1318              $tar->pushErrorHandling(PEAR_ERROR_RETURN);
1319              if ($file != 'package.xml' && $file != 'package2.xml') {
1320                  $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file;
1321              }
1322              $file = $tar->extractInString($file);
1323              $tar->popErrorHandling();
1324              if (PEAR::isError($file)) {
1325                  return PEAR::raiseError("Cannot locate file '$file' in archive");
1326              }
1327              return $file;
1328          }
1329      }
1330  
1331      // {{{ analyzeSourceCode()
1332      /**
1333       * Analyze the source code of the given PHP file
1334       *
1335       * @param  string Filename of the PHP file
1336       * @return mixed
1337       * @access private
1338       */
1339      function _analyzeSourceCode($file)
1340      {
1341          if (!function_exists("token_get_all")) {
1342              return false;
1343          }
1344          if (!defined('T_DOC_COMMENT')) {
1345              define('T_DOC_COMMENT', T_COMMENT);
1346          }
1347          if (!defined('T_INTERFACE')) {
1348              define('T_INTERFACE', -1);
1349          }
1350          if (!defined('T_IMPLEMENTS')) {
1351              define('T_IMPLEMENTS', -1);
1352          }
1353          if (!$fp = @fopen($file, "r")) {
1354              return false;
1355          }
1356          if (function_exists('file_get_contents')) {
1357              fclose($fp);
1358              $contents = file_get_contents($file);
1359          } else {
1360              $contents = @fread($fp, filesize($file));
1361              fclose($fp);
1362          }
1363          $tokens = token_get_all($contents);
1364  /*
1365          for ($i = 0; $i < sizeof($tokens); $i++) {
1366              @list($token, $data) = $tokens[$i];
1367              if (is_string($token)) {
1368                  var_dump($token);
1369              } else {
1370                  print token_name($token) . ' ';
1371                  var_dump(rtrim($data));
1372              }
1373          }
1374  */
1375          $look_for = 0;
1376          $paren_level = 0;
1377          $bracket_level = 0;
1378          $brace_level = 0;
1379          $lastphpdoc = '';
1380          $current_class = '';
1381          $current_interface = '';
1382          $current_class_level = -1;
1383          $current_function = '';
1384          $current_function_level = -1;
1385          $declared_classes = array();
1386          $declared_interfaces = array();
1387          $declared_functions = array();
1388          $declared_methods = array();
1389          $used_classes = array();
1390          $used_functions = array();
1391          $extends = array();
1392          $implements = array();
1393          $nodeps = array();
1394          $inquote = false;
1395          $interface = false;
1396          for ($i = 0; $i < sizeof($tokens); $i++) {
1397              if (is_array($tokens[$i])) {
1398                  list($token, $data) = $tokens[$i];
1399              } else {
1400                  $token = $tokens[$i];
1401                  $data = '';
1402              }
1403              if ($inquote) {
1404                  if ($token != '"' && $token != T_END_HEREDOC) {
1405                      continue;
1406                  } else {
1407                      $inquote = false;
1408                      continue;
1409                  }
1410              }
1411              switch ($token) {
1412                  case T_WHITESPACE :
1413                      continue;
1414                  case ';':
1415                      if ($interface) {
1416                          $current_function = '';
1417                          $current_function_level = -1;
1418                      }
1419                      break;
1420                  case '"':
1421                  case T_START_HEREDOC:
1422                      $inquote = true;
1423                      break;
1424                  case T_CURLY_OPEN:
1425                  case T_DOLLAR_OPEN_CURLY_BRACES:
1426                  case '{': $brace_level++; continue 2;
1427                  case '}':
1428                      $brace_level--;
1429                      if ($current_class_level == $brace_level) {
1430                          $current_class = '';
1431                          $current_class_level = -1;
1432                      }
1433                      if ($current_function_level == $brace_level) {
1434                          $current_function = '';
1435                          $current_function_level = -1;
1436                      }
1437                      continue 2;
1438                  case '[': $bracket_level++; continue 2;
1439                  case ']': $bracket_level--; continue 2;
1440                  case '(': $paren_level++;   continue 2;
1441                  case ')': $paren_level--;   continue 2;
1442                  case T_INTERFACE:
1443                      $interface = true;
1444                  case T_CLASS:
1445                      if (($current_class_level != -1) || ($current_function_level != -1)) {
1446                          $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE,
1447                              array('file' => $file));
1448                          return false;
1449                      }
1450                  case T_FUNCTION:
1451                  case T_NEW:
1452                  case T_EXTENDS:
1453                  case T_IMPLEMENTS:
1454                      $look_for = $token;
1455                      continue 2;
1456                  case T_STRING:
1457                      if (version_compare(zend_version(), '2.0', '<')) {
1458                          if (in_array(strtolower($data),
1459                              array('public', 'private', 'protected', 'abstract',
1460                                    'interface', 'implements', 'throw') 
1461                                   )) {
1462                              $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_PHP5,
1463                                  array($file));
1464                          }
1465                      }
1466                      if ($look_for == T_CLASS) {
1467                          $current_class = $data;
1468                          $current_class_level = $brace_level;
1469                          $declared_classes[] = $current_class;
1470                      } elseif ($look_for == T_INTERFACE) {
1471                          $current_interface = $data;
1472                          $current_class_level = $brace_level;
1473                          $declared_interfaces[] = $current_interface;
1474                      } elseif ($look_for == T_IMPLEMENTS) {
1475                          $implements[$current_class] = $data;
1476                      } elseif ($look_for == T_EXTENDS) {
1477                          $extends[$current_class] = $data;
1478                      } elseif ($look_for == T_FUNCTION) {
1479                          if ($current_class) {
1480                              $current_function = "$current_class::$data";
1481                              $declared_methods[$current_class][] = $data;
1482                          } elseif ($current_interface) {
1483                              $current_function = "$current_interface::$data";
1484                              $declared_methods[$current_interface][] = $data;
1485                          } else {
1486                              $current_function = $data;
1487                              $declared_functions[] = $current_function;
1488                          }
1489                          $current_function_level = $brace_level;
1490                          $m = array();
1491                      } elseif ($look_for == T_NEW) {
1492                          $used_classes[$data] = true;
1493                      }
1494                      $look_for = 0;
1495                      continue 2;
1496                  case T_VARIABLE:
1497                      $look_for = 0;
1498                      continue 2;
1499                  case T_DOC_COMMENT:
1500                  case T_COMMENT:
1501                      if (preg_match('!^/\*\*\s!', $data)) {
1502                          $lastphpdoc = $data;
1503                          if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) {
1504                              $nodeps = array_merge($nodeps, $m[1]);
1505                          }
1506                      }
1507                      continue 2;
1508                  case T_DOUBLE_COLON:
1509                      if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) {
1510                          $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE,
1511                              array('file' => $file));
1512                          return false;
1513                      }
1514                      $class = $tokens[$i - 1][1];
1515                      if (strtolower($class) != 'parent') {
1516                          $used_classes[$class] = true;
1517                      }
1518                      continue 2;
1519              }
1520          }
1521          return array(
1522              "source_file" => $file,
1523              "declared_classes" => $declared_classes,
1524              "declared_interfaces" => $declared_interfaces,
1525              "declared_methods" => $declared_methods,
1526              "declared_functions" => $declared_functions,
1527              "used_classes" => array_diff(array_keys($used_classes), $nodeps),
1528              "inheritance" => $extends,
1529              "implements" => $implements,
1530              );
1531      }
1532  
1533      /**
1534       * Build a "provides" array from data returned by
1535       * analyzeSourceCode().  The format of the built array is like
1536       * this:
1537       *
1538       *  array(
1539       *    'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'),
1540       *    ...
1541       *  )
1542       *
1543       *
1544       * @param array $srcinfo array with information about a source file
1545       * as returned by the analyzeSourceCode() method.
1546       *
1547       * @return void
1548       *
1549       * @access private
1550       *
1551       */
1552      function _buildProvidesArray($srcinfo)
1553      {
1554          if (!$this->_isValid) {
1555              return false;
1556          }
1557          $file = basename($srcinfo['source_file']);
1558          $pn = $this->getPackage();
1559          $pnl = strlen($pn);
1560          foreach ($srcinfo['declared_classes'] as $class) {
1561              $key = "class;$class";
1562              if (isset($this->_packageInfo['provides'][$key])) {
1563                  continue;
1564              }
1565              $this->_packageInfo['provides'][$key] =
1566                  array('file'=> $file, 'type' => 'class', 'name' => $class);
1567              if (isset($srcinfo['inheritance'][$class])) {
1568                  $this->_packageInfo['provides'][$key]['extends'] =
1569                      $srcinfo['inheritance'][$class];
1570              }
1571          }
1572          foreach ($srcinfo['declared_methods'] as $class => $methods) {
1573              foreach ($methods as $method) {
1574                  $function = "$class::$method";
1575                  $key = "function;$function";
1576                  if ($method{0} == '_' || !strcasecmp($method, $class) ||
1577                      isset($this->_packageInfo['provides'][$key])) {
1578                      continue;
1579                  }
1580                  $this->_packageInfo['provides'][$key] =
1581                      array('file'=> $file, 'type' => 'function', 'name' => $function);
1582              }
1583          }
1584  
1585          foreach ($srcinfo['declared_functions'] as $function) {
1586              $key = "function;$function";
1587              if ($function{0} == '_' || isset($this->_packageInfo['provides'][$key])) {
1588                  continue;
1589              }
1590              if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) {
1591                  $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\"";
1592              }
1593              $this->_packageInfo['provides'][$key] =
1594                  array('file'=> $file, 'type' => 'function', 'name' => $function);
1595          }
1596      }
1597  
1598      // }}}
1599  }
1600  ?>


Généré le : Wed Nov 21 12:27:40 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics