[ Index ]
 

Code source de PHP PEAR 1.4.5

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

title

Body

[fermer]

/PEAR/ -> PackageFile.php (source)

   1  <?php
   2  /**
   3   * PEAR_PackageFile, package.xml parsing utility class
   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: PackageFile.php,v 1.40 2006/09/25 05:12:21 cellog Exp $
  19   * @link       http://pear.php.net/package/PEAR
  20   * @since      File available since Release 1.4.0a1
  21   */
  22  
  23  /**
  24   * needed for PEAR_VALIDATE_* constants
  25   */
  26  require_once  'PEAR/Validate.php';
  27  /**
  28   * Error code if the package.xml <package> tag does not contain a valid version
  29   */
  30  define('PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION', 1);
  31  /**
  32   * Error code if the package.xml <package> tag version is not supported (version 1.0 and 1.1 are the only supported versions,
  33   * currently
  34   */
  35  define('PEAR_PACKAGEFILE_ERROR_INVALID_PACKAGEVERSION', 2);
  36  /**
  37   * Abstraction for the package.xml package description file
  38   *
  39   * @category   pear
  40   * @package    PEAR
  41   * @author     Greg Beaver <cellog@php.net>
  42   * @copyright  1997-2006 The PHP Group
  43   * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  44   * @version    Release: 1.5.0
  45   * @link       http://pear.php.net/package/PEAR
  46   * @since      Class available since Release 1.4.0a1
  47   */
  48  class PEAR_PackageFile
  49  {
  50      /**
  51       * @var PEAR_Config
  52       */
  53      var $_config;
  54      var $_debug;
  55      /**
  56       * Temp directory for uncompressing tgz files.
  57       * @var string|false
  58       */
  59      var $_tmpdir;
  60      var $_logger = false;
  61      /**
  62       * @var boolean
  63       */
  64      var $_rawReturn = false;
  65  
  66      /**
  67       *
  68       * @param   PEAR_Config $config
  69       * @param   ?   $debug
  70       * @param   string @tmpdir Optional temporary directory for uncompressing
  71       *          files
  72       */
  73      function PEAR_PackageFile(&$config, $debug = false, $tmpdir = false)
  74      {
  75          $this->_config = $config;
  76          $this->_debug = $debug;
  77          $this->_tmpdir = $tmpdir;
  78      }
  79  
  80      /**
  81       * Turn off validation - return a parsed package.xml without checking it
  82       *
  83       * This is used by the package-validate command
  84       */
  85      function rawReturn()
  86      {
  87          $this->_rawReturn = true;
  88      }
  89  
  90      function setLogger(&$l)
  91      {
  92          $this->_logger = &$l;
  93      }
  94  
  95      /**
  96       * Create a PEAR_PackageFile_Parser_v* of a given version.
  97       * @param   int $version
  98       * @return  PEAR_PackageFile_Parser_v1|PEAR_PackageFile_Parser_v1
  99       */
 100      function &parserFactory($version)
 101      {
 102          if (!in_array($version{0}, array('1', '2'))) {
 103              $a = false;
 104              return $a;
 105          }
 106          include_once 'PEAR/PackageFile/Parser/v' . $version{0} . '.php';
 107          $version = $version{0};
 108          $class = "PEAR_PackageFile_Parser_v$version";
 109          $a = new $class;
 110          return $a;
 111      }
 112  
 113      /**
 114       * For simpler unit-testing
 115       * @return string
 116       */
 117      function getClassPrefix()
 118      {
 119          return 'PEAR_PackageFile_v';
 120      }
 121  
 122      /**
 123       * Create a PEAR_PackageFile_v* of a given version.
 124       * @param   int $version
 125       * @return  PEAR_PackageFile_v1|PEAR_PackageFile_v1
 126       */
 127      function &factory($version)
 128      {
 129          if (!in_array($version{0}, array('1', '2'))) {
 130              $a = false;
 131              return $a;
 132          }
 133          include_once 'PEAR/PackageFile/v' . $version{0} . '.php';
 134          $version = $version{0};
 135          $class = $this->getClassPrefix() . $version;
 136          $a = new $class;
 137          return $a;
 138      }
 139  
 140      /**
 141       * Create a PEAR_PackageFile_v* from its toArray() method
 142       *
 143       * WARNING: no validation is performed, the array is assumed to be valid,
 144       * always parse from xml if you want validation.
 145       * @param   array $arr
 146       * @return PEAR_PackageFileManager_v1|PEAR_PackageFileManager_v2
 147       * @uses    factory() to construct the returned object.
 148       */
 149      function &fromArray($arr)
 150      {
 151          if (isset($arr['xsdversion'])) {
 152              $obj = &$this->factory($arr['xsdversion']);
 153              if ($this->_logger) {
 154                  $obj->setLogger($this->_logger);
 155              }
 156              $obj->setConfig($this->_config);
 157              $obj->fromArray($arr);
 158              return $obj;
 159          } else {
 160              if (isset($arr['package']['attribs']['version'])) {
 161                  $obj = &$this->factory($arr['package']['attribs']['version']);
 162              } else {
 163                  $obj = &$this->factory('1.0');
 164              }
 165              if ($this->_logger) {
 166                  $obj->setLogger($this->_logger);
 167              }
 168              $obj->setConfig($this->_config);
 169              $obj->fromArray($arr);
 170              return $obj;
 171          }
 172      }
 173  
 174      /**
 175       * Create a PEAR_PackageFile_v* from an XML string.
 176       * @access  public
 177       * @param   string $data contents of package.xml file
 178       * @param   int $state package state (one of PEAR_VALIDATE_* constants)
 179       * @param   string $file full path to the package.xml file (and the files
 180       *          it references)
 181       * @param   string $archive optional name of the archive that the XML was
 182       *          extracted from, if any
 183       * @return  PEAR_PackageFile_v1|PEAR_PackageFile_v2
 184       * @uses    parserFactory() to construct a parser to load the package.
 185       */
 186      function &fromXmlString($data, $state, $file, $archive = false)
 187      {
 188          if (preg_match('/<package[^>]+version="([0-9]+\.[0-9]+)"/', $data, $packageversion)) {
 189              if (!in_array($packageversion[1], array('1.0', '2.0', '2.1'))) {
 190                  return PEAR::raiseError('package.xml version "' . $packageversion[1] .
 191                      '" is not supported, only 1.0, 2.0, and 2.1 are supported.');
 192              }
 193              $object = &$this->parserFactory($packageversion[1]);
 194              if ($this->_logger) {
 195                  $object->setLogger($this->_logger);
 196              }
 197              $object->setConfig($this->_config);
 198              $pf = $object->parse($data, $file, $archive);
 199              if (PEAR::isError($pf)) {
 200                  return $pf;
 201              }
 202              if ($this->_rawReturn) {
 203                  return $pf;
 204              }
 205              if ($pf->validate($state)) {
 206                  if ($this->_logger) {
 207                      if ($pf->getValidationWarnings(false)) {
 208                          foreach ($pf->getValidationWarnings() as $warning) {
 209                              $this->_logger->log(0, 'WARNING: ' . $warning['message']);
 210                          }
 211                      }
 212                  }
 213                  if (method_exists($pf, 'flattenFilelist')) {
 214                      $pf->flattenFilelist(); // for v2
 215                  }
 216                  return $pf;
 217              } else {
 218                  if ($this->_config->get('verbose') > 0) {
 219                      if ($this->_logger) {
 220                          if ($pf->getValidationWarnings(false)) {
 221                              foreach ($pf->getValidationWarnings(false) as $warning) {
 222                                  $this->_logger->log(0, 'ERROR: ' . $warning['message']);
 223                              }
 224                          }
 225                      }
 226                  }
 227                  $a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed',
 228                      2, null, null, $pf->getValidationWarnings());
 229                  return $a;
 230              }
 231          } elseif (preg_match('/<package[^>]+version="([^"]+)"/', $data, $packageversion)) {
 232              $a = PEAR::raiseError('package.xml file "' . $file .
 233                  '" has unsupported package.xml <package> version "' . $packageversion[1] . '"');
 234              return $a;
 235          } else {
 236              if (!class_exists('PEAR_ErrorStack')) {
 237                  require_once  'PEAR/ErrorStack.php';
 238              }
 239              PEAR_ErrorStack::staticPush('PEAR_PackageFile',
 240                  PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION,
 241                  'warning', array('xml' => $data), 'package.xml "' . $file .
 242                      '" has no package.xml <package> version');
 243              $object = &$this->parserFactory('1.0');
 244              $object->setConfig($this->_config);
 245              $pf = $object->parse($data, $file, $archive);
 246              if (PEAR::isError($pf)) {
 247                  return $pf;
 248              }
 249              if ($this->_rawReturn) {
 250                  return $pf;
 251              }
 252              if ($pf->validate($state)) {
 253                  if ($this->_logger) {
 254                      if ($pf->getValidationWarnings(false)) {
 255                          foreach ($pf->getValidationWarnings() as $warning) {
 256                              $this->_logger->log(0, 'WARNING: ' . $warning['message']);
 257                          }
 258                      }
 259                  }
 260                  if (method_exists($pf, 'flattenFilelist')) {
 261                      $pf->flattenFilelist(); // for v2
 262                  }
 263                  return $pf;
 264              } else {
 265                  $a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed',
 266                      2, null, null, $pf->getValidationWarnings());
 267                  return $a;
 268              }
 269          }
 270      }
 271  
 272      /**
 273       * Register a temporary file or directory.  When the destructor is
 274       * executed, all registered temporary files and directories are
 275       * removed.
 276       *
 277       * @param string  $file  name of file or directory
 278       * @return  void
 279       */
 280      function addTempFile($file)
 281      {
 282          $GLOBALS['_PEAR_Common_tempfiles'][] = $file;
 283      }
 284  
 285      /**
 286       * Create a PEAR_PackageFile_v* from a compresed Tar or Tgz file.
 287       * @access  public
 288       * @param string contents of package.xml file
 289       * @param int package state (one of PEAR_VALIDATE_* constants)
 290       * @return  PEAR_PackageFile_v1|PEAR_PackageFile_v2
 291       * @using   Archive_Tar to extract the files
 292       * @using   fromPackageFile() to load the package after the package.xml
 293       *          file is extracted.
 294       */
 295      function &fromTgzFile($file, $state)
 296      {
 297          if (!class_exists('Archive_Tar')) {
 298              require_once  'Archive/Tar.php';
 299          }
 300          $tar = new Archive_Tar($file);
 301          if ($this->_debug <= 1) {
 302              $tar->pushErrorHandling(PEAR_ERROR_RETURN);
 303          }
 304          $content = $tar->listContent();
 305          if ($this->_debug <= 1) {
 306              $tar->popErrorHandling();
 307          }
 308          if (!is_array($content)) {
 309              if (is_string($file) && strlen($file < 255) &&
 310                    (!file_exists($file) || !@is_file($file))) {
 311                  $ret = PEAR::raiseError("could not open file \"$file\"");
 312                  return $ret;
 313              }
 314              $file = realpath($file);
 315              $ret = PEAR::raiseError("Could not get contents of package \"$file\"".
 316                                       '. Invalid tgz file.');
 317              return $ret;
 318          } else {
 319              if (!count($content) && !@is_file($file)) {
 320                  $ret = PEAR::raiseError("could not open file \"$file\"");
 321                  return $ret;
 322              }
 323          }
 324          $xml = null;
 325          $origfile = $file;
 326          foreach ($content as $file) {
 327              $name = $file['filename'];
 328              if ($name == 'package2.xml') { // allow a .tgz to distribute both versions
 329                  $xml = $name;
 330                  break;
 331              }
 332              if ($name == 'package.xml') {
 333                  $xml = $name;
 334                  break;
 335              } elseif (ereg('package.xml$', $name, $match)) {
 336                  $xml = $name;
 337                  break;
 338              }
 339          }
 340          if ($this->_tmpdir) {
 341              $tmpdir = $this->_tmpdir;
 342          } else {
 343              $tmpdir = System::mkTemp(array('-d', 'pear'));
 344              PEAR_PackageFile::addTempFile($tmpdir);
 345          }
 346          $this->_extractErrors();
 347          PEAR::staticPushErrorHandling(PEAR_ERROR_CALLBACK, array($this, '_extractErrors'));
 348          if (!$xml || !$tar->extractList(array($xml), $tmpdir)) {
 349              $extra = implode("\n", $this->_extractErrors());
 350              if ($extra) {
 351                  $extra = ' ' . $extra;
 352              }
 353              PEAR::staticPopErrorHandling();
 354              $ret = PEAR::raiseError('could not extract the package.xml file from "' .
 355                  $origfile . '"' . $extra);
 356              return $ret;
 357          }
 358          PEAR::staticPopErrorHandling();
 359          $ret = &PEAR_PackageFile::fromPackageFile("$tmpdir/$xml", $state, $origfile);
 360          return $ret;
 361      }
 362  
 363      /**
 364       * helper for extracting Archive_Tar errors
 365       * @var array
 366       * @access private
 367       */
 368      var $_extractErrors = array();
 369  
 370      /**
 371       * helper callback for extracting Archive_Tar errors
 372       *
 373       * @param PEAR_Error|null $err
 374       * @return array
 375       * @access private
 376       */
 377      function _extractErrors($err = null)
 378      {
 379          static $errors = array();
 380          if ($err === null) {
 381              $e = $errors;
 382              $errors = array();
 383              return $e;
 384          }
 385          $errors[] = $err->getMessage();
 386      }
 387  
 388      /**
 389       * Create a PEAR_PackageFile_v* from a package.xml file.
 390       *
 391       * @access public
 392       * @param   string  $descfile  name of package xml file
 393       * @param   int     $state package state (one of PEAR_VALIDATE_* constants)
 394       * @param   string|false $archive name of the archive this package.xml came
 395       *          from, if any
 396       * @return  PEAR_PackageFile_v1|PEAR_PackageFile_v2
 397       * @uses    PEAR_PackageFile::fromXmlString to create the oject after the
 398       *          XML is loaded from the package.xml file.
 399       */
 400      function &fromPackageFile($descfile, $state, $archive = false)
 401      {
 402          if (is_string($descfile) && strlen($descfile) < 255 &&
 403               (!file_exists($descfile) || !is_file($descfile) || !is_readable($descfile) ||
 404               (!$fp = @fopen($descfile, 'r')))) {
 405              $a = PEAR::raiseError("Unable to open $descfile");
 406              return $a;
 407          }
 408  
 409          // read the whole thing so we only get one cdata callback
 410          // for each block of cdata
 411          fclose($fp);
 412          $data = file_get_contents($descfile);
 413          $ret = &PEAR_PackageFile::fromXmlString($data, $state, $descfile, $archive);
 414          return $ret;
 415      }
 416  
 417  
 418      /**
 419       * Create a PEAR_PackageFile_v* from a .tgz archive or package.xml file.
 420       *
 421       * This method is able to extract information about a package from a .tgz
 422       * archive or from a XML package definition file.
 423       *
 424       * @access public
 425       * @param   string  $info file name
 426       * @param   int     $state package state (one of PEAR_VALIDATE_* constants)
 427       * @return  PEAR_PackageFile_v1|PEAR_PackageFile_v2
 428       * @uses    fromPackageFile() if the file appears to be XML
 429       * @uses    fromTgzFile() to load all non-XML files
 430       */
 431      function &fromAnyFile($info, $state)
 432      {
 433          if (is_dir($info)) {
 434              $dir_name = realpath($info);
 435              if (file_exists($dir_name . '/package.xml')) {
 436                  $info = PEAR_PackageFile::fromPackageFile($dir_name .  '/package.xml', $state);
 437              } elseif (file_exists($dir_name .  '/package2.xml')) {
 438                  $info = PEAR_PackageFile::fromPackageFile($dir_name .  '/package2.xml', $state);
 439              } else {
 440                  $info = PEAR::raiseError("No package definition found in '$info' directory");
 441              }
 442              return $info;
 443          }
 444  
 445          $fp = false;
 446          if (is_string($info) && strlen($info) < 255 &&
 447               (file_exists($info) || ($fp = @fopen($info, 'r')))) {
 448              if ($fp) {
 449                  fclose($fp);
 450              }
 451              $tmp = substr($info, -4);
 452              if ($tmp == '.xml') {
 453                  $info = &PEAR_PackageFile::fromPackageFile($info, $state);
 454              } elseif ($tmp == '.tar' || $tmp == '.tgz') {
 455                  $info = &PEAR_PackageFile::fromTgzFile($info, $state);
 456              } else {
 457                  $fp = fopen($info, "r");
 458                  $test = fread($fp, 5);
 459                  fclose($fp);
 460                  if ($test == "<?xml") {
 461                      $info = &PEAR_PackageFile::fromPackageFile($info, $state);
 462                  } else {
 463                      $info = &PEAR_PackageFile::fromTgzFile($info, $state);
 464                  }
 465              }
 466          } else {
 467              $info = PEAR::raiseError("Cannot open '$info' for parsing");
 468              return $info;
 469          }
 470          return $info;
 471      }
 472  }
 473  
 474  ?>


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