3 * Copyright (c) STMicroelectronics, 2007. All Rights Reserved.
5 * Originally written by Manuel VACELET, 2007.
7 * This file is a part of Codendi.
9 * Codendi is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * Codendi is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with Codendi. If not, see <http://www.gnu.org/licenses/>.
33 * Check if $val is a valid not.
35 * @param String $val Value to check.
38 function isValid($val) {
39 trigger_error(get_class($this).'::isValid() => Not yet implemented', E_USER_ERROR);
43 * Default error message if rule is not apply on value.
45 * @param string $key Value to check.
48 function getErrorMessage($key) {
54 * Validate date provided by Codendi calendar.
56 * Note: this date format is more restrictive than php check date because in
57 * this case, 2007-01-01 format (with zero in month or day) is not allowed.
61 function isValid($val) {
62 if(preg_match('/^(\d{1,4})-(\d{1,2})-(\d{1,2}?)$/', $val, $m)) {
63 return checkdate($m[2], $m[3], $m[1]);
71 * Abstract class that define left-hand operand for a comparison.
79 function Rule_Comparator($ref) {
85 * Check that given value is strictly greater than the one defined in
88 class Rule_GreaterThan
89 extends Rule_Comparator {
90 function isValid($val) {
91 if(is_numeric($val) && $val > $this->ref) {
99 * Check that given value is strictly less than the one defined in constructor.
102 extends Rule_Comparator {
103 function isValid($val) {
104 if(is_numeric($val) && $val < $this->ref) {
112 * Check that given value is greater or equal to the one defined in
115 class Rule_GreaterOrEqual
116 extends Rule_Comparator {
117 function isValid($val) {
118 if(is_numeric($val) && $val >= $this->ref) {
126 * Check that given value is strictly less or equal to the one defined in
129 class Rule_lessOrEqual
130 extends Rule_Comparator {
131 function isValid($val) {
132 if(is_numeric($val) && $val <= $this->ref) {
140 * Check that given value belong to the array defined in constructor.
142 * There is no type check.
145 extends Rule_Comparator {
146 function isValid($val) {
147 if(is_array($this->ref)
148 && count($this->ref) > 0
149 && in_array($val, $this->ref)) {
157 * Check that given value is a valid signed 32 bits decimal integer.
162 * Check the format according to PHP definition of a decimal integer.
163 * @see http://php.net/int
166 function checkFormat($val) {
167 if(preg_match('/^([+-]?[1-9][0-9]*|[+-]?0)$/', $val)) {
174 function isValid($val) {
175 // Need to check with the regexp because of octal form '0123' that is
176 // equal to '123' with string '==' comparison.
177 if($this->checkFormat($val)) {
178 // Check (-2^31;2^31-1) range
179 if(strval(intval($val)) == $val) {
191 * Check that given value is a string.
195 function isValid($val) {
196 return is_string($val);
201 * Check if given string contains neither a carrige return nor a null char.
205 function isValid($val) {
206 if(is_string($val) && strpos($val, 0x0A) === false && strpos($val, 0x0D) === false
207 && strpos($val, 0x00) === false) {
215 * Check if an email address is valid or not in Codendi context.
217 * This rule is influenced by a global variable 'sys_disable_subdomain'. If
218 * this variable is set (no subdomain for codendi) and only in this case, emails
219 * like 'user@codendi' are allowed.
221 * The faulty email address is available with $this->getErrorMessage();
227 function Rule_Email($separator = null) {
228 $this->separator = $separator;
231 function isValid($val) {
232 if($this->separator !== null) {
233 // If separator is defined, split the string and check each email.
234 $emails = split($this->separator, $val);
236 while((list($key,$email) = each($emails)) && $valid) {
237 $valid = $valid & $this->validEmail(trim(rtrim($email)));
240 // $val must contains only one email address
241 $valid = $this->validEmail($val);
247 * Check email validity
249 * Important note: this is very important to keep the 'D' regexp modifier
250 * as this is the only way not to be bothered by injections of \n into the
253 * Spaces are allowed at the beginning and the end of the address.
255 function validEmail($email) {
256 $valid_chars='-!#$%&\'*+0-9=?A-Z^_`a-z{|}~\.';
257 if (array_key_exists('sys_disable_subdomains', $GLOBALS)
258 && $GLOBALS['sys_disable_subdomains']) {
259 $valid_domain='['.$valid_chars.']+';
261 $valid_domain='['.$valid_chars.']+\.['.$valid_chars.']+';
263 $regexp = '/^['.$valid_chars.']+'.'@'.$valid_domain.'$/D';
264 return preg_match($regexp, $email);
269 * Check if value match Codendi user names format.
271 * This rule doesn't check that user actually exists.
273 class Rule_UserNameFormat
276 function containsIllegalChars($val) {
277 return (strspn($val,"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_") != strlen($val));
280 function isNotLegalName($val) {
281 return preg_match('/^((root)|(bin)|(daemon)|(adm)|(lp)|(sync)|(shutdown)|(halt)|(mail)|(news)'
282 .'|(uucp)|(operator)|(games)|(mysql)|(httpd)|(nobody)|(dummy)'
283 .'|(www)|(cvs)|(shell)|(ftp)|(irc)|(debian)|(ns)|(download))$/i', $val);
286 function isCvsAccount($val) {
287 return preg_match('/^anoncvs_/i', $val);
290 function lessThanMin($val) {
291 return (strlen($val) < 3);
294 function greaterThanMax($val) {
295 return (strlen($val) > 30);
298 function isValid($val) {
299 return !$this->isNotLegalName($val)
300 && !$this->isCvsAccount($val)
301 && !$this->lessThanMin($val)
302 && !$this->greaterThanMax($val)
303 && !$this->containsIllegalChars($val);
308 * Check that file was correctly uploaded doesn't by pass Codendi limits.
310 * Tests mainly rely on PHP $_FILES error code but add a double check of file
311 * size because MAX_FILE_SIZE (used by PHP to check allowed size) is submitted
314 * By default the maxSize is defined by 'sys_max_size_upload' Codendi
315 * variable but may be customized with setMaxSize.
317 //require_once("www/file/file_utils.php"); // Needed for 2 GB workaround
323 function Rule_File() {
324 $this->maxSize = $GLOBALS['sys_max_size_upload'];
325 $this->i18nPageName = 'rule_valid';
328 function setMaxSize($max) {
329 $this->maxSize = $max;
332 function geti18nError($key, $params="") {
333 return $GLOBALS['Language']->getText($this->i18nPageName, $key, $params);
337 * Check file upload validity
339 * @param string $file
340 * @return boolean Is file upload valid or not.
342 function isValid($file) {
344 if(is_array($file)) {
345 switch($file['error']) {
350 case UPLOAD_ERR_INI_SIZE:
351 case UPLOAD_ERR_FORM_SIZE:
352 $this->error = $this->geti18nError('error_upload_size', $file['error']);
354 case UPLOAD_ERR_PARTIAL:
355 $this->error = $this->geti18nError('error_upload_partial', $file['error']);
357 case UPLOAD_ERR_NO_FILE:
358 $this->error = $this->geti18nError('error_upload_nofile', $file['error']);
360 //case UPLOAD_ERR_NO_TMP_DIR: PHP 5.0.3
361 //case UPLOAD_ERR_CANT_WRITE: PHP 5.1.0
362 //case UPLOAD_ERR_EXTENSION: PHP 5.2.0
364 $this->error = $this->geti18nError('error_upload_unknown', $file['error']);
366 if($ok && $file['name'] == '') {
368 $this->error = $this->geti18nError('error_upload');
371 // Re-check filesize (do not trust uploaded MAX_FILE_SIZE)
372 if(file_utils_get_size($file['tmp_name']) > $this->maxSize) {
374 $this->error = $this->geti18nError('error_upload_size', 1);