3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2014
36 require_once 'HTML/QuickForm/Rule/Email.php';
39 * Class CRM_Utils_Rule
41 class CRM_Utils_Rule
{
45 * @param int $maxLength
49 static function title($str, $maxLength = 127) {
52 if (empty($str) ||
strlen($str) > $maxLength) {
56 // Make sure it include valid characters, alpha numeric and underscores
57 if (!preg_match('/^\w[\w\s\'\&\,\$\#\-\.\"\?\!]+$/i', $str)) {
69 static function longTitle($str) {
70 return self
::title($str, 255);
78 static function variable($str) {
80 if (empty($str) ||
strlen($str) > 31) {
84 // make sure it include valid characters, alpha numeric and underscores
85 if (!preg_match('/^[\w]+$/i', $str)) {
97 static function qfVariable($str) {
99 //if ( empty( $str ) || strlen( $str ) > 31 ) {
100 if (strlen(trim($str)) == 0 ||
strlen($str) > 31) {
104 // make sure it include valid characters, alpha numeric and underscores
105 // added (. and ,) option (CRM-1336)
106 if (!preg_match('/^[\w\s\.\,]+$/i', $str)) {
118 static function phone($phone) {
120 if (empty($phone) ||
strlen($phone) > 16) {
124 // make sure it include valid characters, (, \s and numeric
125 if (preg_match('/^[\d\(\)\-\.\s]+$/', $phone)) {
136 static function query($query) {
138 if (empty($query) ||
strlen($query) < 3 ||
strlen($query) > 127) {
142 // make sure it include valid characters, alpha numeric and underscores
143 if (!preg_match('/^[\w\s\%\'\&\,\$\#]+$/i', $query)) {
155 static function url($url) {
156 return (bool) filter_var($url, FILTER_VALIDATE_URL
);
164 static function wikiURL($string) {
165 $items = explode(' ', trim($string), 2);
166 return self
::url($items[0]);
174 static function domain($domain) {
175 // not perfect, but better than the previous one; see CRM-1502
176 if (!preg_match('/^[A-Za-z0-9]([A-Za-z0-9\.\-]*[A-Za-z0-9])?$/', $domain)) {
184 * @param null $default
188 static function date($value, $default = NULL) {
189 if (is_string($value) &&
190 preg_match('/^\d\d\d\d-?\d\d-?\d\d$/', $value)
199 * @param null $default
201 * @return null|string
203 static function dateTime($value, $default = NULL) {
205 if (is_string($value) &&
206 preg_match('/^\d\d\d\d-?\d\d-?\d\d(\s\d\d:\d\d(:\d\d)?|\d\d\d\d(\d\d)?)?$/', $value)
215 * check the validity of the date (in qf format)
216 * note that only a year is valid, or a mon-year is
217 * also valid in addition to day-mon-year. The date
218 * specified has to be beyond today. (i.e today or later)
221 * @param bool $monthRequired check whether month is mandatory
223 * @return bool true if valid date
227 static function currentDate($date, $monthRequired = TRUE) {
228 $config = CRM_Core_Config
::singleton();
230 $d = CRM_Utils_Array
::value('d', $date);
231 $m = CRM_Utils_Array
::value('M', $date);
232 $y = CRM_Utils_Array
::value('Y', $date);
234 if (!$d && !$m && !$y) {
238 // CRM-9017 CiviContribute/CiviMember form with expiration date format 'm Y'
239 if (!$m && !empty($date['m'])) {
240 $m = CRM_Utils_Array
::value('m', $date);
255 // if we have day we need mon, and if we have mon we need year
264 if (!empty($day) ||
!empty($mon) ||
!empty($year)) {
265 $result = checkdate($mon, $day, $year);
272 // ensure we have month if required
273 if ($monthRequired && !$m) {
277 // now make sure this date is greater that today
278 $currentDate = getdate();
279 if ($year > $currentDate['year']) {
282 elseif ($year < $currentDate['year']) {
287 if ($mon > $currentDate['mon']) {
290 elseif ($mon < $currentDate['mon']) {
296 if ($day > $currentDate['mday']) {
299 elseif ($day < $currentDate['mday']) {
308 * check the validity of a date or datetime (timestamp)
309 * value which is in YYYYMMDD or YYYYMMDDHHMMSS format
311 * Uses PHP checkdate() - params are ( int $month, int $day, int $year )
313 * @param string $date
315 * @return bool true if valid date
319 static function mysqlDate($date) {
320 // allow date to be null
325 if (checkdate(substr($date, 4, 2), substr($date, 6, 2), substr($date, 0, 4))) {
337 static function integer($value) {
338 if (is_int($value)) {
343 // ensure number passed is always a string numeral
344 if (!is_numeric($value)) {
348 // note that is_int matches only integer type
349 // and not strings which are only integers
350 // hence we do this here
351 if (preg_match('/^\d+$/', $value)) {
356 $negValue = -1 * $value;
357 if (is_int($negValue)) {
370 static function positiveInteger($value) {
371 if (is_int($value)) {
372 return ($value < 0) ?
FALSE : TRUE;
376 // ensure number passed is always a string numeral
377 if (!is_numeric($value)) {
381 if (preg_match('/^\d+$/', $value)) {
393 static function numeric($value) {
394 // lets use a php gatekeeper to ensure this is numeric
395 if (!is_numeric($value)) {
399 return preg_match('/(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/', $value) ?
TRUE : FALSE;
408 static function numberOfDigit($value, $noOfDigit) {
409 return preg_match('/^\d{' . $noOfDigit . '}$/', $value) ?
TRUE : FALSE;
417 static function cleanMoney($value) {
418 // first remove all white space
419 $value = str_replace(array(' ', "\t", "\n"), '', $value);
421 $config = CRM_Core_Config
::singleton();
423 if ($config->monetaryThousandSeparator
) {
424 $mon_thousands_sep = $config->monetaryThousandSeparator
;
427 $mon_thousands_sep = ',';
430 // ugly fix for CRM-6391: do not drop the thousand separator if
431 // it looks like it’s separating decimal part (because a given
432 // value undergoes a second cleanMoney() call, for example)
433 if ($mon_thousands_sep != '.' or substr($value, -3, 1) != '.') {
434 $value = str_replace($mon_thousands_sep, '', $value);
437 if ($config->monetaryDecimalPoint
) {
438 $mon_decimal_point = $config->monetaryDecimalPoint
;
441 $mon_decimal_point = '.';
443 $value = str_replace($mon_decimal_point, '.', $value);
453 static function money($value) {
454 $config = CRM_Core_Config
::singleton();
456 //only edge case when we have a decimal point in the input money
457 //field and not defined in the decimal Point in config settings
458 if ($config->monetaryDecimalPoint
&&
459 $config->monetaryDecimalPoint
!= '.' &&
460 /* CRM-7122 also check for Thousands Separator in config settings */
461 $config->monetaryThousandSeparator
!= '.' &&
462 substr_count($value, '.')
467 $value = self
::cleanMoney($value);
469 if (self
::integer($value)) {
473 return preg_match('/(^-?\d+\.\d?\d?$)|(^-?\.\d\d?$)/', $value) ?
TRUE : FALSE;
478 * @param int $maxLength
482 static function string($value, $maxLength = 0) {
483 if (is_string($value) &&
484 ($maxLength === 0 ||
strlen($value) <= $maxLength)
496 static function boolean($value) {
498 '/(^(1|0)$)|(^(Y(es)?|N(o)?)$)|(^(T(rue)?|F(alse)?)$)/i', $value
507 static function email($value) {
508 return (bool) filter_var($value, FILTER_VALIDATE_EMAIL
);
516 static function emailList($list) {
517 $emails = explode(',', $list);
518 foreach ($emails as $email) {
519 $email = trim($email);
520 if (!self
::email($email)) {
527 // allow between 4-6 digits as postal code since india needs 6 and US needs 5 (or
528 // if u disregard the first 0, 4 (thanx excel!)
529 // FIXME: we need to figure out how to localize such rules
535 static function postalCode($value) {
536 if (preg_match('/^\d{4,6}(-\d{4})?$/', $value)) {
543 * see how file rules are written in HTML/QuickForm/file.php
544 * Checks to make sure the uploaded file is ascii
546 * @param array Uploaded file info (from $_FILES)
549 * @return bool true if file has been uploaded, false otherwise
551 static function asciiFile($elementValue) {
552 if ((isset($elementValue['error']) && $elementValue['error'] == 0) ||
553 (!empty($elementValue['tmp_name']) && $elementValue['tmp_name'] != 'none')
555 return CRM_Utils_File
::isAscii($elementValue['tmp_name']);
561 * Checks to make sure the uploaded file is in UTF-8, recodes if it's not
563 * @param array Uploaded file info (from $_FILES)
566 * @return bool whether file has been uploaded properly and is now in UTF-8
568 static function utf8File($elementValue) {
571 if ((isset($elementValue['error']) && $elementValue['error'] == 0) ||
572 (!empty($elementValue['tmp_name']) && $elementValue['tmp_name'] != 'none')
575 $success = CRM_Utils_File
::isAscii($elementValue['tmp_name']);
577 // if it's a file, but not UTF-8, let's try and recode it
578 // and then make sure it's an UTF-8 file in the end
580 $success = CRM_Utils_File
::toUtf8($elementValue['tmp_name']);
582 $success = CRM_Utils_File
::isAscii($elementValue['tmp_name']);
590 * see how file rules are written in HTML/QuickForm/file.php
591 * Checks to make sure the uploaded file is html
593 * @param array Uploaded file info (from $_FILES)
596 * @return bool true if file has been uploaded, false otherwise
598 static function htmlFile($elementValue) {
599 if ((isset($elementValue['error']) && $elementValue['error'] == 0) ||
600 (!empty($elementValue['tmp_name']) && $elementValue['tmp_name'] != 'none')
602 return CRM_Utils_File
::isHtmlFile($elementValue['tmp_name']);
608 * Check if there is a record with the same name in the db
610 * @param string $value the value of the field we are checking
611 * @param array $options the daoName and fieldName (optional )
613 * @return boolean true if object exists
617 static function objectExists($value, $options) {
619 if (isset($options[2])) {
623 return CRM_Core_DAO
::objectExists($value, CRM_Utils_Array
::value(0, $options), CRM_Utils_Array
::value(1, $options), CRM_Utils_Array
::value(2, $options, $name));
632 static function optionExists($value, $options) {
633 return CRM_Core_OptionValue
::optionExists($value, $options[0], $options[1], $options[2], CRM_Utils_Array
::value(3, $options, 'name'));
642 static function creditCardNumber($value, $type) {
643 require_once 'Validate/Finance/CreditCard.php';
644 return Validate_Finance_CreditCard
::number($value, $type);
653 static function cvv($value, $type) {
654 require_once 'Validate/Finance/CreditCard.php';
656 return Validate_Finance_CreditCard
::cvv($value, $type);
664 static function currencyCode($value) {
665 static $currencyCodes = NULL;
666 if (!$currencyCodes) {
667 $currencyCodes = CRM_Core_PseudoConstant
::currencyCode();
669 if (in_array($value, $currencyCodes)) {
680 static function xssString($value) {
681 if (is_string($value)) {
682 return preg_match('!<(vb)?script[^>]*>.*</(vb)?script.*>!ims',
696 static function fileExists($path) {
697 return file_exists($path);
706 static function autocomplete($value, $options) {
708 $selectOption = CRM_Core_BAO_CustomOption
::valuesByID($options['fieldID'], $options['optionGroupID']);
710 if (!in_array($value, $selectOption)) {
719 * @param null $actualElementValue
723 static function validContact($value, $actualElementValue = NULL) {
724 if ($actualElementValue) {
725 $value = $actualElementValue;
728 if ($value && !is_numeric($value)) {
735 * check the validity of the date (in qf format)
736 * note that only a year is valid, or a mon-year is
737 * also valid in addition to day-mon-year
741 * @return bool true if valid date
745 static function qfDate($date) {
746 $config = CRM_Core_Config
::singleton();
748 $d = CRM_Utils_Array
::value('d', $date);
749 $m = CRM_Utils_Array
::value('M', $date);
750 $y = CRM_Utils_Array
::value('Y', $date);
751 if (isset($date['h']) ||
754 $m = CRM_Utils_Array
::value('M', $date);
757 if (!$d && !$m && !$y) {
773 // if we have day we need mon, and if we have mon we need year
781 if (!empty($day) ||
!empty($mon) ||
!empty($year)) {
782 return checkdate($mon, $day, $year);
792 static function qfKey($key) {
793 return ($key) ? CRM_Core_Key
::valid($key) : FALSE;