123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629 |
- <?php
- /**
- * PEAR_Validate
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Validate.php 313023 2011-07-06 19:17:11Z dufuz $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a1
- */
- /**#@+
- * Constants for install stage
- */
- define('PEAR_VALIDATE_INSTALLING', 1);
- define('PEAR_VALIDATE_UNINSTALLING', 2); // this is not bit-mapped like the others
- define('PEAR_VALIDATE_NORMAL', 3);
- define('PEAR_VALIDATE_DOWNLOADING', 4); // this is not bit-mapped like the others
- define('PEAR_VALIDATE_PACKAGING', 7);
- /**#@-*/
- require_once 'PEAR/Common.php';
- require_once 'PEAR/Validator/PECL.php';
- /**
- * Validation class for package.xml - channel-level advanced validation
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.9.4
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a1
- */
- class PEAR_Validate
- {
- var $packageregex = _PEAR_COMMON_PACKAGE_NAME_PREG;
- /**
- * @var PEAR_PackageFile_v1|PEAR_PackageFile_v2
- */
- var $_packagexml;
- /**
- * @var int one of the PEAR_VALIDATE_* constants
- */
- var $_state = PEAR_VALIDATE_NORMAL;
- /**
- * Format: ('error' => array('field' => name, 'reason' => reason), 'warning' => same)
- * @var array
- * @access private
- */
- var $_failures = array('error' => array(), 'warning' => array());
- /**
- * Override this method to handle validation of normal package names
- * @param string
- * @return bool
- * @access protected
- */
- function _validPackageName($name)
- {
- return (bool) preg_match('/^' . $this->packageregex . '\\z/', $name);
- }
- /**
- * @param string package name to validate
- * @param string name of channel-specific validation package
- * @final
- */
- function validPackageName($name, $validatepackagename = false)
- {
- if ($validatepackagename) {
- if (strtolower($name) == strtolower($validatepackagename)) {
- return (bool) preg_match('/^[a-zA-Z0-9_]+(?:\.[a-zA-Z0-9_]+)*\\z/', $name);
- }
- }
- return $this->_validPackageName($name);
- }
- /**
- * This validates a bundle name, and bundle names must conform
- * to the PEAR naming convention, so the method is final and static.
- * @param string
- * @final
- * @static
- */
- function validGroupName($name)
- {
- return (bool) preg_match('/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '\\z/', $name);
- }
- /**
- * Determine whether $state represents a valid stability level
- * @param string
- * @return bool
- * @static
- * @final
- */
- function validState($state)
- {
- return in_array($state, array('snapshot', 'devel', 'alpha', 'beta', 'stable'));
- }
- /**
- * Get a list of valid stability levels
- * @return array
- * @static
- * @final
- */
- function getValidStates()
- {
- return array('snapshot', 'devel', 'alpha', 'beta', 'stable');
- }
- /**
- * Determine whether a version is a properly formatted version number that can be used
- * by version_compare
- * @param string
- * @return bool
- * @static
- * @final
- */
- function validVersion($ver)
- {
- return (bool) preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver);
- }
- /**
- * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
- */
- function setPackageFile(&$pf)
- {
- $this->_packagexml = &$pf;
- }
- /**
- * @access private
- */
- function _addFailure($field, $reason)
- {
- $this->_failures['errors'][] = array('field' => $field, 'reason' => $reason);
- }
- /**
- * @access private
- */
- function _addWarning($field, $reason)
- {
- $this->_failures['warnings'][] = array('field' => $field, 'reason' => $reason);
- }
- function getFailures()
- {
- $failures = $this->_failures;
- $this->_failures = array('warnings' => array(), 'errors' => array());
- return $failures;
- }
- /**
- * @param int one of the PEAR_VALIDATE_* constants
- */
- function validate($state = null)
- {
- if (!isset($this->_packagexml)) {
- return false;
- }
- if ($state !== null) {
- $this->_state = $state;
- }
- $this->_failures = array('warnings' => array(), 'errors' => array());
- $this->validatePackageName();
- $this->validateVersion();
- $this->validateMaintainers();
- $this->validateDate();
- $this->validateSummary();
- $this->validateDescription();
- $this->validateLicense();
- $this->validateNotes();
- if ($this->_packagexml->getPackagexmlVersion() == '1.0') {
- $this->validateState();
- $this->validateFilelist();
- } elseif ($this->_packagexml->getPackagexmlVersion() == '2.0' ||
- $this->_packagexml->getPackagexmlVersion() == '2.1') {
- $this->validateTime();
- $this->validateStability();
- $this->validateDeps();
- $this->validateMainFilelist();
- $this->validateReleaseFilelist();
- //$this->validateGlobalTasks();
- $this->validateChangelog();
- }
- return !((bool) count($this->_failures['errors']));
- }
- /**
- * @access protected
- */
- function validatePackageName()
- {
- if ($this->_state == PEAR_VALIDATE_PACKAGING ||
- $this->_state == PEAR_VALIDATE_NORMAL) {
- if (($this->_packagexml->getPackagexmlVersion() == '2.0' ||
- $this->_packagexml->getPackagexmlVersion() == '2.1') &&
- $this->_packagexml->getExtends()) {
- $version = $this->_packagexml->getVersion() . '';
- $name = $this->_packagexml->getPackage();
- $test = array_shift($a = explode('.', $version));
- if ($test == '0') {
- return true;
- }
- $vlen = strlen($test);
- $majver = substr($name, strlen($name) - $vlen);
- while ($majver && !is_numeric($majver{0})) {
- $majver = substr($majver, 1);
- }
- if ($majver != $test) {
- $this->_addWarning('package', "package $name extends package " .
- $this->_packagexml->getExtends() . ' and so the name should ' .
- 'have a postfix equal to the major version like "' .
- $this->_packagexml->getExtends() . $test . '"');
- return true;
- } elseif (substr($name, 0, strlen($name) - $vlen) !=
- $this->_packagexml->getExtends()) {
- $this->_addWarning('package', "package $name extends package " .
- $this->_packagexml->getExtends() . ' and so the name must ' .
- 'be an extension like "' . $this->_packagexml->getExtends() .
- $test . '"');
- return true;
- }
- }
- }
- if (!$this->validPackageName($this->_packagexml->getPackage())) {
- $this->_addFailure('name', 'package name "' .
- $this->_packagexml->getPackage() . '" is invalid');
- return false;
- }
- }
- /**
- * @access protected
- */
- function validateVersion()
- {
- if ($this->_state != PEAR_VALIDATE_PACKAGING) {
- if (!$this->validVersion($this->_packagexml->getVersion())) {
- $this->_addFailure('version',
- 'Invalid version number "' . $this->_packagexml->getVersion() . '"');
- }
- return false;
- }
- $version = $this->_packagexml->getVersion();
- $versioncomponents = explode('.', $version);
- if (count($versioncomponents) != 3) {
- $this->_addWarning('version',
- 'A version number should have 3 decimals (x.y.z)');
- return true;
- }
- $name = $this->_packagexml->getPackage();
- // version must be based upon state
- switch ($this->_packagexml->getState()) {
- case 'snapshot' :
- return true;
- case 'devel' :
- if ($versioncomponents[0] . 'a' == '0a') {
- return true;
- }
- if ($versioncomponents[0] == 0) {
- $versioncomponents[0] = '0';
- $this->_addWarning('version',
- 'version "' . $version . '" should be "' .
- implode('.' ,$versioncomponents) . '"');
- } else {
- $this->_addWarning('version',
- 'packages with devel stability must be < version 1.0.0');
- }
- return true;
- break;
- case 'alpha' :
- case 'beta' :
- // check for a package that extends a package,
- // like Foo and Foo2
- if ($this->_state == PEAR_VALIDATE_PACKAGING) {
- if (substr($versioncomponents[2], 1, 2) == 'rc') {
- $this->_addFailure('version', 'Release Candidate versions ' .
- 'must have capital RC, not lower-case rc');
- return false;
- }
- }
- if (!$this->_packagexml->getExtends()) {
- if ($versioncomponents[0] == '1') {
- if ($versioncomponents[2]{0} == '0') {
- if ($versioncomponents[2] == '0') {
- // version 1.*.0000
- $this->_addWarning('version',
- 'version 1.' . $versioncomponents[1] .
- '.0 probably should not be alpha or beta');
- return true;
- } elseif (strlen($versioncomponents[2]) > 1) {
- // version 1.*.0RC1 or 1.*.0beta24 etc.
- return true;
- } else {
- // version 1.*.0
- $this->_addWarning('version',
- 'version 1.' . $versioncomponents[1] .
- '.0 probably should not be alpha or beta');
- return true;
- }
- } else {
- $this->_addWarning('version',
- 'bugfix versions (1.3.x where x > 0) probably should ' .
- 'not be alpha or beta');
- return true;
- }
- } elseif ($versioncomponents[0] != '0') {
- $this->_addWarning('version',
- 'major versions greater than 1 are not allowed for packages ' .
- 'without an <extends> tag or an identical postfix (foo2 v2.0.0)');
- return true;
- }
- if ($versioncomponents[0] . 'a' == '0a') {
- return true;
- }
- if ($versioncomponents[0] == 0) {
- $versioncomponents[0] = '0';
- $this->_addWarning('version',
- 'version "' . $version . '" should be "' .
- implode('.' ,$versioncomponents) . '"');
- }
- } else {
- $vlen = strlen($versioncomponents[0] . '');
- $majver = substr($name, strlen($name) - $vlen);
- while ($majver && !is_numeric($majver{0})) {
- $majver = substr($majver, 1);
- }
- if (($versioncomponents[0] != 0) && $majver != $versioncomponents[0]) {
- $this->_addWarning('version', 'first version number "' .
- $versioncomponents[0] . '" must match the postfix of ' .
- 'package name "' . $name . '" (' .
- $majver . ')');
- return true;
- }
- if ($versioncomponents[0] == $majver) {
- if ($versioncomponents[2]{0} == '0') {
- if ($versioncomponents[2] == '0') {
- // version 2.*.0000
- $this->_addWarning('version',
- "version $majver." . $versioncomponents[1] .
- '.0 probably should not be alpha or beta');
- return false;
- } elseif (strlen($versioncomponents[2]) > 1) {
- // version 2.*.0RC1 or 2.*.0beta24 etc.
- return true;
- } else {
- // version 2.*.0
- $this->_addWarning('version',
- "version $majver." . $versioncomponents[1] .
- '.0 cannot be alpha or beta');
- return true;
- }
- } else {
- $this->_addWarning('version',
- "bugfix versions ($majver.x.y where y > 0) should " .
- 'not be alpha or beta');
- return true;
- }
- } elseif ($versioncomponents[0] != '0') {
- $this->_addWarning('version',
- "only versions 0.x.y and $majver.x.y are allowed for alpha/beta releases");
- return true;
- }
- if ($versioncomponents[0] . 'a' == '0a') {
- return true;
- }
- if ($versioncomponents[0] == 0) {
- $versioncomponents[0] = '0';
- $this->_addWarning('version',
- 'version "' . $version . '" should be "' .
- implode('.' ,$versioncomponents) . '"');
- }
- }
- return true;
- break;
- case 'stable' :
- if ($versioncomponents[0] == '0') {
- $this->_addWarning('version', 'versions less than 1.0.0 cannot ' .
- 'be stable');
- return true;
- }
- if (!is_numeric($versioncomponents[2])) {
- if (preg_match('/\d+(rc|a|alpha|b|beta)\d*/i',
- $versioncomponents[2])) {
- $this->_addWarning('version', 'version "' . $version . '" or any ' .
- 'RC/beta/alpha version cannot be stable');
- return true;
- }
- }
- // check for a package that extends a package,
- // like Foo and Foo2
- if ($this->_packagexml->getExtends()) {
- $vlen = strlen($versioncomponents[0] . '');
- $majver = substr($name, strlen($name) - $vlen);
- while ($majver && !is_numeric($majver{0})) {
- $majver = substr($majver, 1);
- }
- if (($versioncomponents[0] != 0) && $majver != $versioncomponents[0]) {
- $this->_addWarning('version', 'first version number "' .
- $versioncomponents[0] . '" must match the postfix of ' .
- 'package name "' . $name . '" (' .
- $majver . ')');
- return true;
- }
- } elseif ($versioncomponents[0] > 1) {
- $this->_addWarning('version', 'major version x in x.y.z may not be greater than ' .
- '1 for any package that does not have an <extends> tag');
- }
- return true;
- break;
- default :
- return false;
- break;
- }
- }
- /**
- * @access protected
- */
- function validateMaintainers()
- {
- // maintainers can only be truly validated server-side for most channels
- // but allow this customization for those who wish it
- return true;
- }
- /**
- * @access protected
- */
- function validateDate()
- {
- if ($this->_state == PEAR_VALIDATE_NORMAL ||
- $this->_state == PEAR_VALIDATE_PACKAGING) {
- if (!preg_match('/(\d\d\d\d)\-(\d\d)\-(\d\d)/',
- $this->_packagexml->getDate(), $res) ||
- count($res) < 4
- || !checkdate($res[2], $res[3], $res[1])
- ) {
- $this->_addFailure('date', 'invalid release date "' .
- $this->_packagexml->getDate() . '"');
- return false;
- }
- if ($this->_state == PEAR_VALIDATE_PACKAGING &&
- $this->_packagexml->getDate() != date('Y-m-d')) {
- $this->_addWarning('date', 'Release Date "' .
- $this->_packagexml->getDate() . '" is not today');
- }
- }
- return true;
- }
- /**
- * @access protected
- */
- function validateTime()
- {
- if (!$this->_packagexml->getTime()) {
- // default of no time value set
- return true;
- }
- // packager automatically sets time, so only validate if pear validate is called
- if ($this->_state = PEAR_VALIDATE_NORMAL) {
- if (!preg_match('/\d\d:\d\d:\d\d/',
- $this->_packagexml->getTime())) {
- $this->_addFailure('time', 'invalid release time "' .
- $this->_packagexml->getTime() . '"');
- return false;
- }
- $result = preg_match('|\d{2}\:\d{2}\:\d{2}|', $this->_packagexml->getTime(), $matches);
- if ($result === false || empty($matches)) {
- $this->_addFailure('time', 'invalid release time "' .
- $this->_packagexml->getTime() . '"');
- return false;
- }
- }
- return true;
- }
- /**
- * @access protected
- */
- function validateState()
- {
- // this is the closest to "final" php4 can get
- if (!PEAR_Validate::validState($this->_packagexml->getState())) {
- if (strtolower($this->_packagexml->getState() == 'rc')) {
- $this->_addFailure('state', 'RC is not a state, it is a version ' .
- 'postfix, use ' . $this->_packagexml->getVersion() . 'RC1, state beta');
- }
- $this->_addFailure('state', 'invalid release state "' .
- $this->_packagexml->getState() . '", must be one of: ' .
- implode(', ', PEAR_Validate::getValidStates()));
- return false;
- }
- return true;
- }
- /**
- * @access protected
- */
- function validateStability()
- {
- $ret = true;
- $packagestability = $this->_packagexml->getState();
- $apistability = $this->_packagexml->getState('api');
- if (!PEAR_Validate::validState($packagestability)) {
- $this->_addFailure('state', 'invalid release stability "' .
- $this->_packagexml->getState() . '", must be one of: ' .
- implode(', ', PEAR_Validate::getValidStates()));
- $ret = false;
- }
- $apistates = PEAR_Validate::getValidStates();
- array_shift($apistates); // snapshot is not allowed
- if (!in_array($apistability, $apistates)) {
- $this->_addFailure('state', 'invalid API stability "' .
- $this->_packagexml->getState('api') . '", must be one of: ' .
- implode(', ', $apistates));
- $ret = false;
- }
- return $ret;
- }
- /**
- * @access protected
- */
- function validateSummary()
- {
- return true;
- }
- /**
- * @access protected
- */
- function validateDescription()
- {
- return true;
- }
- /**
- * @access protected
- */
- function validateLicense()
- {
- return true;
- }
- /**
- * @access protected
- */
- function validateNotes()
- {
- return true;
- }
- /**
- * for package.xml 2.0 only - channels can't use package.xml 1.0
- * @access protected
- */
- function validateDependencies()
- {
- return true;
- }
- /**
- * for package.xml 1.0 only
- * @access private
- */
- function _validateFilelist()
- {
- return true; // placeholder for now
- }
- /**
- * for package.xml 2.0 only
- * @access protected
- */
- function validateMainFilelist()
- {
- return true; // placeholder for now
- }
- /**
- * for package.xml 2.0 only
- * @access protected
- */
- function validateReleaseFilelist()
- {
- return true; // placeholder for now
- }
- /**
- * @access protected
- */
- function validateChangelog()
- {
- return true;
- }
- /**
- * @access protected
- */
- function validateFilelist()
- {
- return true;
- }
- /**
- * @access protected
- */
- function validateDeps()
- {
- return true;
- }
- }
|