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