41 require_once realpath(dirname(__FILE__)).
"/data_item.inc";
89 if ($this->readOnly)
return "";
91 if($this->checkDisplayNone)
92 $condition =
"form[\"{$this->field}\"] != null && form[\"{$this->field}\"].style.display != \"none\" && ";
94 $script = <<<ENDSCRIPT
96 if ({$condition}form[
"{$this->field}"].value ==
"{$this->empty}")
98 alert(
"{$this->title} is a required field. Please supply a value.");
110 if ($this->readOnly)
return "";
112 if (!isset($_POST[$this->field]) || $_POST[$this->field] === $this->empty)
114 return "{$this->title} is a required field.";
143 if ($this->readOnly)
return "";
145 $script = <<<ENDSCRIPT
147 var div = document.id(
"{$this->field}_table");
150 div.getElements(
"input").each(
function(box)
152 if (box.checked ==
true)
158 alert(
"{$this->title} is a required field. Please supply a value.");
170 if ($this->readOnly)
return "";
172 if (!isset($_POST[$this->field]))
174 return "{$this->title} is a required field.";
203 if ($this->readOnly)
return "";
205 $script = <<<ENDSCRIPT
209 var radios = form[
"{$this->field}"];
211 for(i=0; i < radios.length; i++)
213 if (radios[i].checked ==
true)
221 alert(
"{$this->title} is a required field. Please supply a value.");
240 $this->message =
$message ?
$message :
"{$title} is a required field. Please browse for a file using the 'Browse' button";
242 trace(
"RequiredValidator($field,$title,$message)", 3);
247 if ($this->readOnly)
return "";
249 $msg =
jsSafe($this->message,
true);
250 $script = <<<ENDSCRIPT
252 if (form[
"{$this->field}"].style.display !=
"none" && form[
"{$this->field}"].value ==
"{$this->empty}")
265 if ($this->readOnly)
return "";
267 if (!isset($_FILES[$this->field]))
288 $this->message =
$message ?
$message :
"{$title} is a required field. Please supply a value or uncheck {$checkboxTitle}.";
290 trace(
"RequiredIfCheckedValidator($field,$title,$checkboxTitle, $message)", 4);
295 if ($this->readOnly)
return "";
297 $msg =
jsSafe($this->message,
true);
298 $script = <<<ENDSCRIPT
300 if (form[
"{$this->field}"].style.display !=
"none" && form[
"{$this->checkbox}"].checked && form[
"{$this->field}"].value ==
"{$this->empty}")
313 if ($this->readOnly)
return "";
315 if (!isset($_POST[$this->field]) && isset($_POST[$this->checkbox]))
346 if ($this->readOnly)
return "";
348 $script .= <<<ENDSCRIPT
349 var d = form[
"{$this->field}"].value.split(/\D+/);
351 if (form[
"{$this->field}"].value !=
"" &&
352 (!form[
"{$this->field}"].value.match(/^\d{1,2}\/\d{1,2}\/\d{4}$/) ||
353 (form[
"{$this->field}"].value.match(/^\d{1,2}\/\d{1,2}\/\d{4}$/) &&
354 (parseInt(d[0], 10) == 0 || parseInt(d[1], 10) == 0 || parseInt(d[2], 10) == 0))))
356 alert(
"{$this->title} must be in the format MM/DD/YYYY");
369 if ($this->readOnly)
return "";
371 list($dd,$mm,$yyyy) = explode(
'/', $_POST[$this->field]);
373 if ($_POST[$this->field] !=
"" AND !preg_match(
"|^\\d{1,2}\/\\d{1,2}\/\\d{4}$|", $_POST[$this->field]) ||
374 (preg_match(
"|^\\d{1,2}\/\\d{1,2}\/\\d{4}$|", $_POST[$this->field]) &&
375 (intval($dd) == 0 || intval($mm) == 0 || intval($yyyy) == 0)))
377 $result =
"{$this->title} must be in the format MM/DD/YYYY";
408 if (!$mm && !$dd && !$yy)
413 if (!$mm || !$dd || !$yy)
415 return "Incomplete date of birth - $mm/$dd/$yy";
418 $dob =
new DateTime(
"$mm/$dd/$yy");
419 $today =
new DateTime();
421 $age = $dob->diff($today);
422 if ($age->y < $this->min)
455 if (!$mm && !$dd && !$yy)
460 if (!$mm || !$dd || !$yy)
462 return "Incomplete date of birth - $mm/$dd/$yy";
465 $dob =
new DateTime(
"$mm/$dd/$yy");
466 $today =
new DateTime();
468 $age = $dob->diff($today);
469 if ($age->y > $this->max)
503 if($this->min && preg_match(
"|^(\\d{4})-(\\d\\d)-(\\d\\d)$|", $this->min, $fields))
505 $this->min = $fields[2].
"/".$fields[3].
"/".$fields[1];
508 if($this->max && preg_match(
"|^(\\d{4})-(\\d\\d)-(\\d\\d)$|", $this->max, $fields))
510 $this->max = $fields[2].
"/".$fields[3].
"/".$fields[1];
513 $this->message = $message;
515 trace(
"DateRangeValidator field $field min {$this->min} max {$this->max}", 3);
518 $labelMin = ($this->min && preg_match(
"|^\\d{1,2}\/\\d{1,2}\/\\d{4}$|", $this->min)) ?
521 $labelMax = ($this->max && preg_match(
"|^\\d{1,2}\/\\d{1,2}\/\\d{4}$|", $this->max)) ?
524 if($this->min && $this->max)
526 $this->message =
"$title must be in the range {$labelMin} to {$labelMax}.";
530 $this->message =
"$title must be greater than or equal to the {$labelMin}.";
534 $this->message =
"$title must be less than or equal to the {$labelMax}.";
548 if ($this->readOnly)
return "";
550 $min =
"'{$this->min}'";
551 $max =
"'{$this->max}'";
553 $script .= <<<ENDSCRIPT
562 if(form[
"{$this->field}"].value !=
"" && form[
"{$this->field}"].value.match(/^\d{1,2}\/\d{1,2}\/\d{4}$/))
564 form[
"{$this->field}"].value = Date.parse(form[
"{$this->field}"].value).format(
'%x');
565 fieldDate =
new Date(form[
"{$this->field}"].value);
568 if(max && max.match(/^\d{1,2}\/\d{1,2}\/\d{4}$/))
570 maxDate =
new Date(max);
572 else if(max && form[
"{$this->max}"].value.match(/^\d{1,2}\/\d{1,2}\/\d{4}$/))
574 form[
"{$this->max}"].value = Date.parse(form[
"{$this->max}"].value).format(
'%x');
575 maxDate =
new Date(form[
"{$this->max}"].value);
578 if(min && min.match(/^\d{1,2}\/\d{1,2}\/\d{4}$/))
580 minDate =
new Date(min);
582 else if(min && form[
"{$this->min}"].value.match(/^\d{1,2}\/\d{1,2}\/\d{4}$/))
584 form[
"{$this->min}"].value = Date.parse(form[
"{$this->min}"].value).format(
'%x');
585 minDate =
new Date(form[
"{$this->min}"].value);
589 (minDate && fieldDate.valueOf() < minDate.valueOf()) ||
590 (maxDate && fieldDate.valueOf() > maxDate.valueOf()) )
592 alert(
"{$this->message}");
605 if ($this->readOnly)
return "";
612 if($min && !preg_match(
"|^\\d{1,2}\/\\d{1,2}\/\\d{4}$|", $min))
614 $min = $_POST[$this->min];
617 if(!preg_match(
"|^\\d{1,2}\/\\d{1,2}\/\\d{4}$|", $max))
619 $max = $_POST[$this->max];
622 if($min && preg_match(
"|^\\d{1,2}\/\\d{1,2}\/\\d{4}$|", $min))
624 $minDate =
new DateTime($min.
"00:00:00");
627 if($max && preg_match(
"|^\\d{1,2}\/\\d{1,2}\/\\d{4}$|", $max))
629 $maxDate =
new DateTime($max.
"00:00:00");
632 if($_POST[$this->field] !=
"" AND preg_match(
"|^\\d{1,2}\/\\d{1,2}\/\\d{4}$|", $_POST[$this->field]))
634 $fieldDate =
new DateTime($_POST[$this->field]);
637 if ($_POST[$this->field] !=
"" AND (!preg_match(
"|^\\d{1,2}\/\\d{1,2}\/\\d{4}$|", $_POST[$this->field]) ||
638 (($minDate && $fieldDate && $fieldDate < $minDate) || ($maxDate && $fieldDate && $fieldDate > $maxDate))))
640 $result = $this->message;
668 if ($this->readOnly)
return "";
670 $script = <<<ENDSCRIPT
671 var hourObj = form[
"{$this->field}_hh"];
672 var minObj = form[
"{$this->field}_mm"];
674 if (hourObj.value !=
"" && (hourObj.value < 1 || hourObj.value > 12))
676 alert(
"{$this->title} Hours must be in the range 1 to 12");
680 if (minObj.value !=
"" && (minObj.value < 0 || minObj.value > 59))
682 alert(
"{$this->title} Minutes must be in the range 0 to 59");
713 if ($this->readOnly)
return "";
715 $script = <<<ENDSCRIPT
717 form[
"{$this->field}_hh"] !=
"" && form[
"{$this->field}_hh"].style.display !=
"none" &&
718 form[
"{$this->field}_hh"].value ==
"{$this->empty}") ||
719 (form[
"{$this->field}_mm"] !=
"" && form[
"{$this->field}_mm"].style.display !=
"none" &&
720 form[
"{$this->field}_mm"].value ==
"{$this->empty}")
723 alert(
"{$this->title} is a required field. Please supply a value.");
748 $this->
class = $item->table;
752 $className =
$item->prettifyClassName();
753 $message = (preg_match(
"/^[aeiou]/i", $className)) ?
"An " :
"A ";
754 $fieldName = strtolower(
$title);
755 $message .=
"{$className} already exists with that {$fieldName}. Please choose a different {$fieldName}.";
758 $this->item =&
$item;
759 $this->extraConstraint = $extraConstraint;
781 trace(
"UniqueValidator::validate: ".get_class($this->item), 3);
785 $pk = $this->item->primary_key;
787 $constraint =
"WHERE {$this->field}=$value";
789 if ($this->extraConstraint) $constraint .=
" AND {$this->extraConstraint}";
791 if ($this->item->$pk)
793 $constraint .=
" AND {$pk}!='{$this->item->$pk}'";
796 $matches = $this->item->queryValue(
"COUNT(1)", $constraint);
797 trace(
"***************count matches ". count($matches), 3);
800 trace(
"UniqueValidator::validate - found $matches match(es), raising error", 3);
830 trace(
"MatchValidator::writeClient", 3);
831 if ($this->readOnly)
return "";
833 if ($this->caseSensitive)
836 $script = <<<ENDSCRIPT
838 if (form[
"{$this->field}"].value != form[
"{$this->confirm}"].value)
840 alert(
"{$this->title} and {$this->confirmTitle} do not match.");
847 $script = <<<ENDSCRIPT
849 if (form[
"{$this->field}"].value.toLowerCase() != form[
"{$this->confirm}"].value.toLowerCase())
851 alert(
"{$this->title} and {$this->confirmTitle} do not match.");
867 if ($this->caseSensitive)
869 if ($value1 != $value2)
871 $result =
"{$this->title} and {$this->confirmTitle} do not match";
874 else if (strtolower($value1) != strtolower($value2))
876 $result =
"{$this->title} and {$this->confirmTitle} do not match";
906 if ($this->readOnly)
return "";
908 $pswField =
"{$this->form_id}_{$this->field}_block";
909 $script = <<<ENDSCRIPT
911 var block = document.getElementById(
"$pswField");
913 if (block.style.display !=
"none" && form[
"{$this->field}"].value ==
"{$this->empty}")
915 alert(
"{$this->title} is a required field. Please supply a value.");
928 if ($this->readOnly)
return "";
930 $reset = $_POST[
"{$this->form_id}_reset_password"];
932 if ($reset == 1 AND (!isset($_POST[$this->field]) || $_POST[$this->field] === $this->empty))
934 return "{$this->title} is a required field.";
958 $this->item =& $item;
965 trace(
"RegularExpressionValidator::writeClient", 3);
967 if ($this->readOnly)
return "";
969 $script = <<<ENDSCRIPT
971 if(form[
"{$this->field}"].value !=
"" &&
972 !form[
"{$this->field}"].value.match(/{$this->regexp}/i))
974 alert(
"{$this->message}");
984 if ($this->readOnly)
return "";
988 if ($_POST[$this->field] !=
"" && !preg_match(
"/{$exp}/i", $_POST[$this->field]))
1017 $this->message =
"$title must be in the range $min to $max";
1025 trace(
"RangeValidator::writeClient", 3);
1026 if ($this->readOnly)
return "";
1028 $min = is_numeric($this->min) ? $this->min :
"'{$this->min}'";
1029 $max = is_numeric($this->max) ? $this->max :
"'{$this->max}'";
1031 $script .= <<<ENDSCRIPT
1033 if (form[
"{$this->field}"].value ==
"" || form[
"{$this->field}"].value <
$min || form[
"{$this->field}"].value >
$max)
1035 alert(
"{$this->message}");
1045 if ($this->readOnly)
return "";
1048 if ($val ===
"" || $val < $this->min || $val > $this->max)
1088 if ($this->readOnly)
return "";
1090 $script = <<<ENDSCRIPT
1092 if (form[
"{$this->field}"].style.display !=
"none" && form[
"{$this->field}"].value ==
"{$this->empty}"
1093 && form[
"{$this->field}_addEntry"].value ==
"{$this->empty}")
1095 alert(
"{$this->title} is a required field. Please supply a value.");
1109 if ($this->readOnly)
return "";
1111 if (!isset($_POST[$this->field]) && !isset($_POST[
"{$this->field}_addEntry"]))
1113 return "{$this->title} is a required field.";
1136 if ($this->readOnly)
return "";
1138 $script = <<<ENDSCRIPT
1140 if (form[
"{$this->field}"].style.display !=
"none")
1142 if (form[
"{$this->field}"].value ==
"")
1144 alert(
"{$this->title} is a required field. Please supply a value.");
1147 else if (!form[
"{$this->field}"].manager.validateRequired())
1149 alert(
"{$this->subtitle} is a required field. Please supply a value.");
1164 if ($this->readOnly)
return "";
1166 if (!isset($_POST[$this->field]))
1168 return "{$this->title} is a required field.";
1199 $script = <<<ENDSCRIPT
1201 var ctrl = form[
'{$this->field}'];
1203 if (ctrl.value.length < {$this->min})
1205 alert(
"Please enter at least $this->min characters for {$this->title}.");
1217 if ($this->readOnly)
return "";
1219 if (!isset($_POST[$this->field]))
1221 return "Please enter at least {$this->min} for {$this->title}.";
1256 $script = <<<ENDSCRIPT
1258 var boolObj = form[
"{$this->field}"];
1260 if (boolObj.checked ==
false)
1262 alert(
"{$this->msg}");
1298 $this->msgText =
pluralize($this->msgText);
1303 $script = <<<ENDSCRIPT
1306 var countChecked = 0;
1307 var max = form[
"count_{$this->field}"].value;
1310 var pattern =
new RegExp(
"^{$this->field}\\\\[.*?\\\\]$");
1312 for(i=0; i < form.elements.length; i++)
1314 ctrl = form.elements[i];
1315 if (pattern.test(ctrl.name))
1317 if (ctrl.checked ==
true)
1324 var addEntry = form[
"{$this->field}_addEntry"];
1326 if(addEntry && addEntry.value !=
"")
1331 if ({$this->min} > 0 && countChecked < {$this->min})
1333 alert(
"You must check at least {$this->min} {$this->msgText} for {$this->title}.");
1347 if ($this->readOnly)
return "";
1353 if (is_array($values))
1355 $valueAnswer = implode(
",", array_values($values));
1356 $count = count(explode(
",", $valueAnswer));
1363 if ($this->addEntry AND isset($_POST[
"{$this->field}_addEntry"]))
1366 if ($count < $this->min)
1368 return "You must check at least {$this->min} {$this->msgText} for {$this->title}.";
1404 if($this->min == 0)
return;
1406 $script = <<<ENDSCRIPT
1409 var countChecked = 0;
1410 var max = form[
"count_{$this->field}"].value;
1412 var pattern =
new RegExp(
"^{$this->field}\\\\[.*?\\\\]$");
1414 for(i=0; i < form.elements.length; i++)
1416 ctrl = form.elements[i];
1417 if (pattern.test(ctrl.name))
1419 if (ctrl.checked ==
true)
1426 if (countChecked < {$this->min})
1428 alert(
"You must check at least {$this->min} {$this->msgText} for {$this->title}.");
1441 if ($this->readOnly)
return "";
1443 if (isset($_POST[$this->field]))
1445 $count = count($_POST[$this->field]);
1448 if ($count < $this->min)
1450 return "You must check at least {$this->min} {$this->msgText} for {$this->title}.";
1475 if ($this->readOnly)
return "";
1477 $script = <<<ENDSCRIPT
1479 var num = parseFloat(form[
"{$this->field}"].value);
1483 alert(
"{$this->title} is a required field. Please supply a value.");
1496 if ($this->readOnly)
return "";
1498 if (!isset($_POST[$this->field]) || trim($_POST[$this->field]) ===
"")
1500 return "{$this->title} is a required field.";
1519 $script = <<<ENDSCRIPT
1521 if (form[
"{$this->field}"].value &&
1522 (!luhnCheck(form[
"{$this->field}"].value) ||
1523 form[
"{$this->field}"].value.length < 13 ||
1524 form[
"{$this->field}"].value.length > 19))
1526 alert(
"{$this->title} is not valid.");
1539 if ($this->readOnly)
return "";
1542 $len = strlen($val);
1544 if (!
luhnTest($len) || $len < 13 || $len > 19)
1546 return "{$this->title} is not valid.";
1569 $this->validators = func_get_args();
1577 $suffix = (
$this->id) ?
"_{$this->id}" :
"";
1579 $script = <<<ENDSCRIPT
1585 if ($this->generateScript)
1587 foreach($this->validators as $v)
1589 $script .= $v->writeClient();
1593 $script .= <<<ENDSCRIPT
1608 foreach(func_get_args() as $v)
1610 $this->validators[] = $v;
1621 foreach($this->validators as $v)
1623 if ($v->field == $field && get_class($v) == $class)
1639 foreach($this->validators as $v)
1641 if ($v->field == $field)
1659 foreach($this->validators as $v)
1661 $msg = $v->validate();
1664 $result .=
$msg.
"<br>";
1680 foreach($this->validators as $v)
1694 foreach($this->validators as $v)
1768 echo
"<div id='warning'>{$this->msg}</div>\n";
1780 echo
"<p>{$this->msg}</p>\n";
1795 $script .= <<<ENDSCRIPT
1796 <script type=
"text/javascript">
1797 window.addEvent(
'domready',
function()
1831 $this->test =
$test;
1846 if (isset($value) && $value !== $this->empty)
1848 if ($this->test ==
"password")
1850 $hash = $user->hashPassword($value, $user->password);
1852 if($user->password == $hash)
1856 trace(
"Signature Validator::invalid signature", 3);
1862 if ($user->get($this->test) == $value)
return "";
Base class for Validators.
AbstractValidator($field, $title)
static quote($str)
Quote a string value based on the character set of the global connection.
CreditCardNumberValidator($field, $title)
DateRangeValidator($field, $title, $min, $max, $message=null)
writeClient()
If min or max set and it is a date string then validate as a date, if set and it is not a date string...
DateValidator($field, $title)
Tests whether two fields contain the same value.
MatchValidator($field, $title, $confirm, $confirmTitle, $caseSensitive=true)
MaximumAgeValidator can be used with DateOfBirth fields.
MaximumAgeValidator($field, $title, $max, $message=null)
AgeRangeValidator can be used with DateOfBirth fields.
MinimumAgeValidator($field, $title, $min, $message=null)
PasswordValidator($field, $title, $form_id="", $empty="")
RangeValidator($field, $title, $min, $max, $message=null)
Tests wheteher a field's value matches the supplied regular expression.
RegularExpressionValidator($field, $title, $regexp, $message)
RequiredBoolean Validator.
RequiredBooleanValidator($field, $title, $msg="")
RequiredCheckList Validator.
RequiredCheckListValidator($field, $title, $min=1, $addEntry=true)
RequiredCrossReferenceSelectValidator.
RequiredCrossReferenceSelectValidator($field, $title, $min=1)
RequiredCurrencyField Validator.
RequiredCurrencyValidator($field, $title)
RequiredFileValidator($field, $title, $message="")
RequiredIfCheckedValidator($field, $checkbox, $title, $checkboxTitle, $message="")
RequiredStringValidator($field, $title, $min=0)
RequiredTimeValidator($field, $title, $empty="")
Validates a field rendered with TreeSelectFieldRenderer.
RequiredTreeValidator($field, $title, $empty="")
RequiredValidator($field, $title, $empty="", $checkDisplayNone=true)
SelectFieldRequiredValidator($field, $title, $empty="")
Validates that the user's supplied password is correct.
SignatureValidator($field, $title, $msg, $test="password")
Create a new SignatureValidator.
$empty
Empty value for the control.
$msg
The error message to report if there is a mismatch.
__construct($field, $title, $subtitle)
TimeValidator($field, $title)
UniqueValidator($field, $title, $item, $message, $extraConstraint="")
When the data entry interface contains multiple tabs (pages) that the user can move around freely (e....
message()
Show the validation issue/error as an informative message instead of a warning.
warning()
Called from summary view class for each section if the section is invalid.
writeScript()
When system returns user to a tab b/c not valid or completed, show a popup message for the error.
Validate()
Called when user clicks submit: validate each tab page and redirect to first page that is invalid or ...
The ValidationEngine takes an array of validator objects in its constructor, and is then able to gene...
getValidators($field)
Get the validators attached to a specific field.
validate()
Perform server-side validation of the posted form values.
$generateScript
Specifies whether to generate client-side validation script.
$id
The ID of this validator.
writeScript()
Output the client-side form validation function, based on all the validators that have been added.
isRequired($field)
Checks to see whether the specified field has a RequiredValidator attached to it.
$msg
Validation error messages accumulator;.
$validators
The array of validators making up this validation engine.
hasRequiredFields()
Checks to see whether any fields have been marked as required.
getValidator($field, $class)
Get the specified validator by field and class.
ValidationEngine()
Create a new ValidationEngine.
checkNumeric($p)
Security helper function.
trace($msg, $lvl=3, $callStack=null)
Send output to the trace log.
pluralize($text, $count=0)
Takes a singular string and makes it plural.
jsSafe($str, $escapeEntities=false)
Utility function to escape a string correctly for use in a Javascript client-side call.
luhnTest($num)
Performs a Luhn validity test for credit card or IMEI numbers.
prettify($name)
Takes a variable or field name and converts it into a human-readable version (assuming that the origi...