[ Index ] |
|
Code source de PHP PEAR 1.4.5 |
1 <?php 2 /** 3 * PEAR_Validate 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: Validate.php,v 1.50 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 * Constants for install stage 24 */ 25 define('PEAR_VALIDATE_INSTALLING', 1); 26 define('PEAR_VALIDATE_UNINSTALLING', 2); // this is not bit-mapped like the others 27 define('PEAR_VALIDATE_NORMAL', 3); 28 define('PEAR_VALIDATE_DOWNLOADING', 4); // this is not bit-mapped like the others 29 define('PEAR_VALIDATE_PACKAGING', 7); 30 /**#@-*/ 31 require_once 'PEAR/Common.php'; 32 require_once 'PEAR/Validator/PECL.php'; 33 34 /** 35 * Validation class for package.xml - channel-level advanced validation 36 * @category pear 37 * @package PEAR 38 * @author Greg Beaver <cellog@php.net> 39 * @copyright 1997-2006 The PHP Group 40 * @license http://www.php.net/license/3_0.txt PHP License 3.0 41 * @version Release: 1.5.0 42 * @link http://pear.php.net/package/PEAR 43 * @since Class available since Release 1.4.0a1 44 */ 45 class PEAR_Validate 46 { 47 var $packageregex = _PEAR_COMMON_PACKAGE_NAME_PREG; 48 /** 49 * @var PEAR_PackageFile_v1|PEAR_PackageFile_v2 50 */ 51 var $_packagexml; 52 /** 53 * @var int one of the PEAR_VALIDATE_* constants 54 */ 55 var $_state = PEAR_VALIDATE_NORMAL; 56 /** 57 * Format: ('error' => array('field' => name, 'reason' => reason), 'warning' => same) 58 * @var array 59 * @access private 60 */ 61 var $_failures = array('error' => array(), 'warning' => array()); 62 63 /** 64 * Override this method to handle validation of normal package names 65 * @param string 66 * @return bool 67 * @access protected 68 */ 69 function _validPackageName($name) 70 { 71 return (bool) preg_match('/^' . $this->packageregex . '$/', $name); 72 } 73 74 /** 75 * @param string package name to validate 76 * @param string name of channel-specific validation package 77 * @final 78 */ 79 function validPackageName($name, $validatepackagename = false) 80 { 81 if ($validatepackagename) { 82 if (strtolower($name) == strtolower($validatepackagename)) { 83 return (bool) preg_match('/^[a-zA-Z0-9_]+(?:\.[a-zA-Z0-9_]+)*$/', $name); 84 } 85 } 86 return $this->_validPackageName($name); 87 } 88 89 /** 90 * This validates a bundle name, and bundle names must conform 91 * to the PEAR naming convention, so the method is final and static. 92 * @param string 93 * @final 94 * @static 95 */ 96 function validGroupName($name) 97 { 98 return (bool) preg_match('/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '$/', $name); 99 } 100 101 /** 102 * Determine whether $state represents a valid stability level 103 * @param string 104 * @return bool 105 * @static 106 * @final 107 */ 108 function validState($state) 109 { 110 return in_array($state, array('snapshot', 'devel', 'alpha', 'beta', 'stable')); 111 } 112 113 /** 114 * Get a list of valid stability levels 115 * @return array 116 * @static 117 * @final 118 */ 119 function getValidStates() 120 { 121 return array('snapshot', 'devel', 'alpha', 'beta', 'stable'); 122 } 123 124 /** 125 * Determine whether a version is a properly formatted version number that can be used 126 * by version_compare 127 * @param string 128 * @return bool 129 * @static 130 * @final 131 */ 132 function validVersion($ver) 133 { 134 return (bool) preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver); 135 } 136 137 /** 138 * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 139 */ 140 function setPackageFile(&$pf) 141 { 142 $this->_packagexml = &$pf; 143 } 144 145 /** 146 * @access private 147 */ 148 function _addFailure($field, $reason) 149 { 150 $this->_failures['errors'][] = array('field' => $field, 'reason' => $reason); 151 } 152 153 /** 154 * @access private 155 */ 156 function _addWarning($field, $reason) 157 { 158 $this->_failures['warnings'][] = array('field' => $field, 'reason' => $reason); 159 } 160 161 function getFailures() 162 { 163 $failures = $this->_failures; 164 $this->_failures = array('warnings' => array(), 'errors' => array()); 165 return $failures; 166 } 167 168 /** 169 * @param int one of the PEAR_VALIDATE_* constants 170 */ 171 function validate($state = null) 172 { 173 if (!isset($this->_packagexml)) { 174 return false; 175 } 176 if ($state !== null) { 177 $this->_state = $state; 178 } 179 $this->_failures = array('warnings' => array(), 'errors' => array()); 180 $this->validatePackageName(); 181 $this->validateVersion(); 182 $this->validateMaintainers(); 183 $this->validateDate(); 184 $this->validateSummary(); 185 $this->validateDescription(); 186 $this->validateLicense(); 187 $this->validateNotes(); 188 if ($this->_packagexml->getPackagexmlVersion() == '1.0') { 189 $this->validateState(); 190 $this->validateFilelist(); 191 } elseif ($this->_packagexml->getPackagexmlVersion() == '2.0' || 192 $this->_packagexml->getPackagexmlVersion() == '2.1') { 193 $this->validateTime(); 194 $this->validateStability(); 195 $this->validateDeps(); 196 $this->validateMainFilelist(); 197 $this->validateReleaseFilelist(); 198 //$this->validateGlobalTasks(); 199 $this->validateChangelog(); 200 } 201 return !((bool) count($this->_failures['errors'])); 202 } 203 204 /** 205 * @access protected 206 */ 207 function validatePackageName() 208 { 209 if ($this->_state == PEAR_VALIDATE_PACKAGING || 210 $this->_state == PEAR_VALIDATE_NORMAL) { 211 if (($this->_packagexml->getPackagexmlVersion() == '2.0' || 212 $this->_packagexml->getPackagexmlVersion() == '2.1') && 213 $this->_packagexml->getExtends()) { 214 $version = $this->_packagexml->getVersion() . ''; 215 $name = $this->_packagexml->getPackage(); 216 $test = array_shift($a = explode('.', $version)); 217 if ($test == '0') { 218 return true; 219 } 220 $vlen = strlen($test); 221 $majver = substr($name, strlen($name) - $vlen); 222 while ($majver && !is_numeric($majver{0})) { 223 $majver = substr($majver, 1); 224 } 225 if ($majver != $test) { 226 $this->_addWarning('package', "package $name extends package " . 227 $this->_packagexml->getExtends() . ' and so the name should ' . 228 'have a postfix equal to the major version like "' . 229 $this->_packagexml->getExtends() . $test . '"'); 230 return true; 231 } elseif (substr($name, 0, strlen($name) - $vlen) != 232 $this->_packagexml->getExtends()) { 233 $this->_addWarning('package', "package $name extends package " . 234 $this->_packagexml->getExtends() . ' and so the name must ' . 235 'be an extension like "' . $this->_packagexml->getExtends() . 236 $test . '"'); 237 return true; 238 } 239 } 240 } 241 if (!$this->validPackageName($this->_packagexml->getPackage())) { 242 $this->_addFailure('name', 'package name "' . 243 $this->_packagexml->getPackage() . '" is invalid'); 244 return false; 245 } 246 } 247 248 /** 249 * @access protected 250 */ 251 function validateVersion() 252 { 253 if ($this->_state != PEAR_VALIDATE_PACKAGING) { 254 if (!$this->validVersion($this->_packagexml->getVersion())) { 255 $this->_addFailure('version', 256 'Invalid version number "' . $this->_packagexml->getVersion() . '"'); 257 } 258 return false; 259 } 260 $version = $this->_packagexml->getVersion(); 261 $versioncomponents = explode('.', $version); 262 if (count($versioncomponents) != 3) { 263 $this->_addWarning('version', 264 'A version number should have 3 decimals (x.y.z)'); 265 return true; 266 } 267 $name = $this->_packagexml->getPackage(); 268 // version must be based upon state 269 switch ($this->_packagexml->getState()) { 270 case 'snapshot' : 271 return true; 272 case 'devel' : 273 if ($versioncomponents[0] . 'a' == '0a') { 274 return true; 275 } 276 if ($versioncomponents[0] == 0) { 277 $versioncomponents[0] = '0'; 278 $this->_addWarning('version', 279 'version "' . $version . '" should be "' . 280 implode('.' ,$versioncomponents) . '"'); 281 } else { 282 $this->_addWarning('version', 283 'packages with devel stability must be < version 1.0.0'); 284 } 285 return true; 286 break; 287 case 'alpha' : 288 case 'beta' : 289 // check for a package that extends a package, 290 // like Foo and Foo2 291 if ($this->_state == PEAR_VALIDATE_PACKAGING) { 292 if (substr($versioncomponents[2], 1, 2) == 'rc') { 293 $this->_addFailure('version', 'Release Candidate versions ' . 294 'must have capital RC, not lower-case rc'); 295 return false; 296 } 297 } 298 if (!$this->_packagexml->getExtends()) { 299 if ($versioncomponents[0] == '1') { 300 if ($versioncomponents[2]{0} == '0') { 301 if ($versioncomponents[2] == '0') { 302 // version 1.*.0000 303 $this->_addWarning('version', 304 'version 1.' . $versioncomponents[1] . 305 '.0 probably should not be alpha or beta'); 306 return true; 307 } elseif (strlen($versioncomponents[2]) > 1) { 308 // version 1.*.0RC1 or 1.*.0beta24 etc. 309 return true; 310 } else { 311 // version 1.*.0 312 $this->_addWarning('version', 313 'version 1.' . $versioncomponents[1] . 314 '.0 probably should not be alpha or beta'); 315 return true; 316 } 317 } else { 318 $this->_addWarning('version', 319 'bugfix versions (1.3.x where x > 0) probably should ' . 320 'not be alpha or beta'); 321 return true; 322 } 323 } elseif ($versioncomponents[0] != '0') { 324 $this->_addWarning('version', 325 'major versions greater than 1 are not allowed for packages ' . 326 'without an <extends> tag or an identical postfix (foo2 v2.0.0)'); 327 return true; 328 } 329 if ($versioncomponents[0] . 'a' == '0a') { 330 return true; 331 } 332 if ($versioncomponents[0] == 0) { 333 $versioncomponents[0] = '0'; 334 $this->_addWarning('version', 335 'version "' . $version . '" should be "' . 336 implode('.' ,$versioncomponents) . '"'); 337 } 338 } else { 339 $vlen = strlen($versioncomponents[0] . ''); 340 $majver = substr($name, strlen($name) - $vlen); 341 while ($majver && !is_numeric($majver{0})) { 342 $majver = substr($majver, 1); 343 } 344 if (($versioncomponents[0] != 0) && $majver != $versioncomponents[0]) { 345 $this->_addWarning('version', 'first version number "' . 346 $versioncomponents[0] . '" must match the postfix of ' . 347 'package name "' . $name . '" (' . 348 $majver . ')'); 349 return true; 350 } 351 if ($versioncomponents[0] == $majver) { 352 if ($versioncomponents[2]{0} == '0') { 353 if ($versioncomponents[2] == '0') { 354 // version 2.*.0000 355 $this->_addWarning('version', 356 "version $majver." . $versioncomponents[1] . 357 '.0 probably should not be alpha or beta'); 358 return false; 359 } elseif (strlen($versioncomponents[2]) > 1) { 360 // version 2.*.0RC1 or 2.*.0beta24 etc. 361 return true; 362 } else { 363 // version 2.*.0 364 $this->_addWarning('version', 365 "version $majver." . $versioncomponents[1] . 366 '.0 cannot be alpha or beta'); 367 return true; 368 } 369 } else { 370 $this->_addWarning('version', 371 "bugfix versions ($majver.x.y where y > 0) should " . 372 'not be alpha or beta'); 373 return true; 374 } 375 } elseif ($versioncomponents[0] != '0') { 376 $this->_addWarning('version', 377 "only versions 0.x.y and $majver.x.y are allowed for alpha/beta releases"); 378 return true; 379 } 380 if ($versioncomponents[0] . 'a' == '0a') { 381 return true; 382 } 383 if ($versioncomponents[0] == 0) { 384 $versioncomponents[0] = '0'; 385 $this->_addWarning('version', 386 'version "' . $version . '" should be "' . 387 implode('.' ,$versioncomponents) . '"'); 388 } 389 } 390 return true; 391 break; 392 case 'stable' : 393 if ($versioncomponents[0] == '0') { 394 $this->_addWarning('version', 'versions less than 1.0.0 cannot ' . 395 'be stable'); 396 return true; 397 } 398 if (!is_numeric($versioncomponents[2])) { 399 if (preg_match('/\d+(rc|a|alpha|b|beta)\d*/i', 400 $versioncomponents[2])) { 401 $this->_addWarning('version', 'version "' . $version . '" or any ' . 402 'RC/beta/alpha version cannot be stable'); 403 return true; 404 } 405 } 406 // check for a package that extends a package, 407 // like Foo and Foo2 408 if ($this->_packagexml->getExtends()) { 409 $vlen = strlen($versioncomponents[0] . ''); 410 $majver = substr($name, strlen($name) - $vlen); 411 while ($majver && !is_numeric($majver{0})) { 412 $majver = substr($majver, 1); 413 } 414 if (($versioncomponents[0] != 0) && $majver != $versioncomponents[0]) { 415 $this->_addWarning('version', 'first version number "' . 416 $versioncomponents[0] . '" must match the postfix of ' . 417 'package name "' . $name . '" (' . 418 $majver . ')'); 419 return true; 420 } 421 } elseif ($versioncomponents[0] > 1) { 422 $this->_addWarning('version', 'major version x in x.y.z may not be greater than ' . 423 '1 for any package that does not have an <extends> tag'); 424 } 425 return true; 426 break; 427 default : 428 return false; 429 break; 430 } 431 } 432 433 /** 434 * @access protected 435 */ 436 function validateMaintainers() 437 { 438 // maintainers can only be truly validated server-side for most channels 439 // but allow this customization for those who wish it 440 return true; 441 } 442 443 /** 444 * @access protected 445 */ 446 function validateDate() 447 { 448 if ($this->_state == PEAR_VALIDATE_NORMAL || 449 $this->_state == PEAR_VALIDATE_PACKAGING) { 450 451 if (!preg_match('/(\d\d\d\d)\-(\d\d)\-(\d\d)/', 452 $this->_packagexml->getDate(), $res) || 453 count($res) < 4 454 || !checkdate($res[2], $res[3], $res[1]) 455 ) { 456 $this->_addFailure('date', 'invalid release date "' . 457 $this->_packagexml->getDate() . '"'); 458 return false; 459 } 460 461 462 if ($this->_state == PEAR_VALIDATE_PACKAGING && 463 $this->_packagexml->getDate() != date('Y-m-d')) { 464 $this->_addWarning('date', 'Release Date "' . 465 $this->_packagexml->getDate() . '" is not today'); 466 } 467 } 468 return true; 469 } 470 471 /** 472 * @access protected 473 */ 474 function validateTime() 475 { 476 if (!$this->_packagexml->getTime()) { 477 // default of no time value set 478 return true; 479 } 480 // packager automatically sets time, so only validate if 481 // pear validate is called 482 if ($this->_state = PEAR_VALIDATE_NORMAL) { 483 if (!preg_match('/\d\d:\d\d:\d\d/', 484 $this->_packagexml->getTime())) { 485 $this->_addFailure('time', 'invalid release time "' . 486 $this->_packagexml->getTime() . '"'); 487 return false; 488 } 489 if (strtotime($this->_packagexml->getTime()) == -1) { 490 $this->_addFailure('time', 'invalid release time "' . 491 $this->_packagexml->getTime() . '"'); 492 return false; 493 } 494 } 495 return true; 496 } 497 498 /** 499 * @access protected 500 */ 501 function validateState() 502 { 503 // this is the closest to "final" php4 can get 504 if (!PEAR_Validate::validState($this->_packagexml->getState())) { 505 if (strtolower($this->_packagexml->getState() == 'rc')) { 506 $this->_addFailure('state', 'RC is not a state, it is a version ' . 507 'postfix, use ' . $this->_packagexml->getVersion() . 'RC1, state beta'); 508 } 509 $this->_addFailure('state', 'invalid release state "' . 510 $this->_packagexml->getState() . '", must be one of: ' . 511 implode(', ', PEAR_Validate::getValidStates())); 512 return false; 513 } 514 return true; 515 } 516 517 /** 518 * @access protected 519 */ 520 function validateStability() 521 { 522 $ret = true; 523 $packagestability = $this->_packagexml->getState(); 524 $apistability = $this->_packagexml->getState('api'); 525 if (!PEAR_Validate::validState($packagestability)) { 526 $this->_addFailure('state', 'invalid release stability "' . 527 $this->_packagexml->getState() . '", must be one of: ' . 528 implode(', ', PEAR_Validate::getValidStates())); 529 $ret = false; 530 } 531 $apistates = PEAR_Validate::getValidStates(); 532 array_shift($apistates); // snapshot is not allowed 533 if (!in_array($apistability, $apistates)) { 534 $this->_addFailure('state', 'invalid API stability "' . 535 $this->_packagexml->getState('api') . '", must be one of: ' . 536 implode(', ', $apistates)); 537 $ret = false; 538 } 539 return $ret; 540 } 541 542 /** 543 * @access protected 544 */ 545 function validateSummary() 546 { 547 return true; 548 } 549 550 /** 551 * @access protected 552 */ 553 function validateDescription() 554 { 555 return true; 556 } 557 558 /** 559 * @access protected 560 */ 561 function validateLicense() 562 { 563 return true; 564 } 565 566 /** 567 * @access protected 568 */ 569 function validateNotes() 570 { 571 return true; 572 } 573 574 /** 575 * for package.xml 2.0 only - channels can't use package.xml 1.0 576 * @access protected 577 */ 578 function validateDependencies() 579 { 580 return true; 581 } 582 583 /** 584 * for package.xml 1.0 only 585 * @access private 586 */ 587 function _validateFilelist() 588 { 589 return true; // placeholder for now 590 } 591 592 /** 593 * for package.xml 2.0 only 594 * @access protected 595 */ 596 function validateMainFilelist() 597 { 598 return true; // placeholder for now 599 } 600 601 /** 602 * for package.xml 2.0 only 603 * @access protected 604 */ 605 function validateReleaseFilelist() 606 { 607 return true; // placeholder for now 608 } 609 610 /** 611 * @access protected 612 */ 613 function validateChangelog() 614 { 615 return true; 616 } 617 618 /** 619 * @access protected 620 */ 621 function validateFilelist() 622 { 623 return true; 624 } 625 626 /** 627 * @access protected 628 */ 629 function validateDeps() 630 { 631 return true; 632 } 633 } 634 ?>
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 |