[ Index ] |
|
Code source de PHP PEAR 1.4.5 |
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 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 14:08:00 2007 | par Balluche grâce à PHPXref 0.7 |