|
|
|
|
|
|
| |
See documentation and code for more information.
| <?php
/**
* FormChecker package
* @author Johan Barbier <johan.barbier@gmail.com>
* @version 20070104
*
*/
/**
* Messages classes
* must be named this way : formCheckerMessagesXXX
* where XXX is the alpha 3 country code
*/
/**
* class formCheckerMessagesENG
* English localization of the messages
*
*/
class formCheckerMessagesENG {
const EMAIL_INVALID = 'The email address is invalid';
const URL_INVALID = 'The URL is invalid';
const REGEXP_FOUND_NOT_MATCH = 'Input {__INPUT__} does not match given regexp pattern';
const USER_FUNC_RETURNED_FALSE = 'User function {__FUNC__} returned false for {__INPUT__}';
const INPUT_EMPTY = 'You must fill in your {__INPUT__}';
const INPUT_NOT_IN_MIN_LENGTH = 'Your {__INPUT__} must et least have {__MIN_LENGTH__} characters';
const INPUT_NOT_IN_MAX_LENGTH = 'Your {__INPUT__} must at most have {__MAX_LENGTH__} characters';
const INPUT_NOT_IN_STRICT_LENGTH = 'Your {__INPUT__} must have {__STRICT_LENGTH__} characters';
const INPUT_STARTS_WITH = 'Your {__INPUT__} must start with {__START__}';
const INPUT_DONOT_START_WITH = 'Your {__INPUT__} must not start with {__START__}';
const INPUT_FORBIDDEN = 'these input are forbidden : {__FORBIDDEN__}';
const NUMERIC_NOT_NUMERIC = 'Your {__NUMERIC__} must be numeric';
const NUMERIC_NOT_IN_MIN_RANGE = 'Your {__NUMERIC__} must be greater than {__MIN_RANGE__}';
const NUMERIC_NOT_IN_MAX_RANGE = 'Your {__NUMERIC__} must be lesser than {__MAX_RANGE__}'; }
/**
* class formCheckerMessagesFRA
* French localization of the messages
*
*/
class formCheckerMessagesFRA {
const EMAIL_INVALID = 'L\'adresse email saisie est invalide';
const URL_INVALID = 'L\'URL est invalide';
const REGEXP_FOUND_NOT_MATCH = 'Le motif d\'expression régulière n\'a pas été trouvé dans {__INPUT__}';
const USER_FUNC_RETURNED_FALSE = 'La fonction utilisateur {__FUNC__} a retourné false pour {__INPUT__}';
const INPUT_EMPTY = 'Vous devez saisir votre {__INPUT__}';
const INPUT_NOT_IN_MIN_LENGTH = 'Votre {__INPUT__} doit contenir au moins {__MIN_LENGTH__} caractères';
const INPUT_NOT_IN_MAX_LENGTH = 'Votre {__INPUT__} doit contenir au plus {__MAX_LENGTH__} caractères';
const INPUT_NOT_IN_STRICT_LENGTH = 'Votre {__INPUT__} doit être composé de {__STRICT_LENGTH__} caractères';
const INPUT_STARTS_WITH = 'Votre {__INPUT__} doit commencer par {__START__}';
const INPUT_DONOT_START_WITH = 'Votre {__INPUT__} ne doit pas commencer par {__START__}';
const INPUT_FORBIDDEN = 'Ces entrées sont interdites : {__FORBIDDEN__}';
const NUMERIC_NOT_NUMERIC = 'Votre {__NUMERIC__} doit être composé de chiffres';
const NUMERIC_NOT_IN_MIN_RANGE = 'Votre {__NUMERIC__} doit être supérieur à {__MIN_RANGE__}';
const NUMERIC_NOT_IN_MAX_RANGE = 'Votre {__NUMERIC__} doit être inférieur à {__MAX_RANGE__}'; }
/**
* class formCheckerException extends Exception
* Specialized exceptions class
*
*/
class formCheckerException extends Exception {
const CLASS_NOT_EXISTS = 'Invalid pattern';
const CLASS_LOC_NOT_EXISTS = 'Invalid localization class';
const FILTER_MUST_BE_INT = 'Filter must be an integer';
const FILTER_NOT_ARRAY = 'Filter must be an array';
const NO_REGEXP = 'Regexp filter needs a regexp option';
const BAD_REGEXP = 'Bad regexp pattern';
const NO_USER_FUNC = 'No user function filter given';
const USER_FUNC_PARAMS_NO_ARRAY = 'User function parameters filter must be an array';
const SANITIZE_NO_USER_FUNC = 'No user function given to the sanitizer';
const SANITIZE_USER_FUNC_NOT_EXISTS = 'User function given to the sanitizer has not been found';
const SANITIZE_USER_FUNC_PARAMS_NOT_ARRAY = 'User function parameters given to the sanitizer must be an array'; }
/**
* class formCheckerMessages
* The factory chosing correct messages localization class
*
*/
class formCheckerMessages {
/**
* public static function factory
* factory building the correct localized formCheckerMessages class through a ReflectionClass object
*
* @param string $loc : country alpha 3 code
* @return ReflectionClass object
*/
public static function factory ($loc) {
if (false === class_exists ('formCheckerMessages'.$loc)) {
throw new formCheckerException
(formCheckerException::CLASS_LOC_NOT_EXISTS);
}
$sClass = 'formCheckerMessages'.$loc;
return new ReflectionClass ($sClass);
}
}
/**
* abstract class validateGen
* the parent of all validateZZZ classes
* defines common methods and properties
*
*/
abstract class validateGen {
/**
* protected sName
* user defined name given to the input (used for the messages)
*
* @var string
*/
protected $sName = null;
/**
* protected sLocClass
* used to store a ReflectionClass object pointing on the messages localization class
*
* @var ReflectionClass
*/
protected $sLocClass = null;
/**
* protected function isEmpty
* test if a given input is empty or not
*
* @param string $mString : the input
* @param boolean $bMandatory : is the input mandatory or not (if not, it can be empty)
* @return boolean true if not empty, false if empty AND mandatory, -1 if empty AND NOT mandatory
*/
protected function isEmpty ($mString, $bMandatory) {
if (empty ($mString)) {
if (true === $bMandatory) {
formChecker::$aMsg[$this -> sName] = str_replace ('{__INPUT__}', $this
-> sName, $this -> sLocClass -> getConstant ('INPUT_EMPTY'));
return false;
}
return -1;
}
return true;
}
/**
* protected function assign
* just assigns properties and instanciate the ReflectionClass via the formCheckerMessages::factory () method
*
* @param string $sName : name given to the input
* @param string $loc : country alpha 3 code
*/
protected function assign ($sName, $loc) {
$this -> sName = $sName;
$this -> sLocClass = formCheckerMessages::factory ($loc);
}
/**
* protected function validateMinLength
* checks if the input length matches the minimum required length
*
* @param string $mString : the input
* @param int $iMinLength : minimum length
* @return boolean true if the input length is greater or equal to the minimum length, false if not
*/
protected function validateMinLength($mString, $iMinLength) {
if (true === $this -> isInt ($iMinLength)) {
if (strlen ($mString) < $iMinLength) {
formChecker::$aMsg[$this -> sName] = str_replace (array ('{__INPUT__}', '{__MIN_LENGTH__}'), array ($this -> sName, $iMinLength), $this -> sLocClass
-> getConstant ('INPUT_NOT_IN_MIN_LENGTH'));
return false;
}
return true;
}
return false;
}
/**
* protected function validateMaxLength
* checks if the input length matches the maximum required length
*
* @param string $mString : the input
* @param int $iMaxLength : maximum length
* @return boolean true if the input length is lesser or equal to the maximum length, false if not
*/
protected function validateMaxLength($mString, $iMaxLength) {
if (true === $this -> isInt ($iMaxLength)) {
if (strlen ($mString) > $iMaxLength) {
formChecker::$aMsg[$this -> sName] = str_replace (array ('{__INPUT__}', '{__MAX_LENGTH__}'), array ($this -> sName, $iMaxLength), $this -> sLocClass
-> getConstant ('INPUT_NOT_IN_MAX_LENGTH'));
return false;
}
return true;
}
return false;
}
/**
* protected function validateStrictLength
* checks if the input has the mandatory strict length
*
* @param string $mString : the input
* @param int $iStrictLength : strict length
* @return boolean true if the input length is equal to the mandaotry strict length, false if not
*/
protected function validateStrictLength($mString, $iStrictLength) {
if (true === $this -> isInt ($iStrictLength)) {
if (strlen ($mString) !== $iStrictLength) {
formChecker::$aMsg[$this -> sName] = str_replace (array ('{__INPUT__}', '{__STRICT_LENGTH__}'), array ($this -> sName, $iStrictLength), $this -> sLocClass -> getConstant ('INPUT_NOT_IN_STRICT_LENGTH'));
return false;
}
return true;
}
return false;
}
/**
* protected function validateStartsWith
* checks if the input starts with each values in a given array
*
* @param string $mString : the input
* @param array $aStarts : array of values
* @return boolean true if the input starts with at least one of the values, false if not.
*/
protected function validateStartsWith ($mString, $aStarts) {
$bRes = false;
if (!is_array ($aStarts)) {
throw new formCheckerException (formCheckerException::FILTER_NOT_ARRAY);
}
foreach ($aStarts as $mVal) {
if (substr ($mString, 0, strlen ($mVal)) === $mVal) {
$bRes = true;
}
}
if (false === $bRes) {
formChecker::$aMsg[$this -> sName] = str_replace (array ('{__INPUT__}', '{__START__}'), array ($this -> sName, implode (',', $aStarts)), $this -> sLocClass -> getConstant ('INPUT_STARTS_WITH'));
}
return $bRes;
}
/**
* protected function validateStartsWith
* checks if the input does not start with each values in a given array
*
* @param string $mString : the input
* @param array $aStarts : array of values
* @return boolean false if the input starts with at least one of the values, true if not.
*/
protected function validateStartsWithout ($mString, $aStarts) {
$bRes = true;
if (!is_array ($aStarts)) {
throw new formCheckerException (formCheckerException::FILTER_NOT_ARRAY);
}
foreach ($aStarts as $mVal) {
if (substr ($mString, 0, strlen ($mVal)) === $mVal) {
$bRes = false;
break;
}
}
if (false === $bRes) {
formChecker::$aMsg[$this -> sName] = str_replace (array ('{__INPUT__}', '{__START__}'), array ($this -> sName, implode (',', $aStarts)), $this -> sLocClass -> getConstant ('INPUT_DONOT_START_WITH'));
}
return $bRes;
}
/**
* protected function hasForbidden
* checks if the input is equal to one of the forbidden values
*
* @param string $mString : the input
* @param string or array $mForbidden : string or array of forbidden values
* @return boolean false if the input is equal to one of the forbidden values, true if not
*/
protected function hasForbidden ($mString, $mForbidden) {
if (is_array ($mForbidden)) {
if (in_array ($mString, $mForbidden)) {
formChecker::$aMsg[$this -> sName] = str_replace ('{__FORBIDDEN__}', $mForbidden[array_search($mString, $mForbidden)], $this -> sLocClass -> getConstant ('INPUT_FORBIDDEN'));
return false;
}
} else {
if ($mForbidden === $mString) {
formChecker::$aMsg[$this -> sName] = str_replace ('{__FORBIDDEN__}',$mForbidden, $this -> sLocClass -> getConstant ('INPUT_FORBIDDEN'));
return false;
}
}
return true;
}
/**
* protected function isInt
* checks if the given parameter is an integer
*
* @param int $iNum
* @return boolean tue if $iNum is an integer (throw an exception if not)
*/
protected function isInt ($iNum) {
if (!is_int ($iNum)) {
throw new formCheckerException
(formCheckerException::FILTER_MUST_BE_INT);
}
return true;
}
/**
* protected function validate
* validation method, calls the required check methods
*
* @param string $mString : the input
* @param string $sName : user defined name given to the input
* @param string $loc : country alpha 3 code
* @param array $aOptions : null if no option, array of options
* @param boolean $bMandatory : true if the input is mandaotry, false if
not
* @return boolean true if the input successfully meets all the
requirements, false if not, -1 if input is empty
*/
protected function validate ($mString, $sName, $loc, $aOptions,
$bMandatory) {
$this -> assign ($sName, $loc);
if (false === ($bRes = $this -> isEmpty ($mString, $bMandatory))) {
return false;
} elseif (true === $bRes) {
if (isset ($aOptions['forbidden'])) {
if (false === $this -> hasForbidden ($mString, $aOptions['forbidden']))
{
return false;
}
}
if (isset ($aOptions['min_length']) && is_int ($aOptions['min_length']))
{
if (false === $this -> validateMinLength ($mString,
$aOptions['min_length'])) {
return false;
}
}
if (isset ($aOptions['max_length']) && is_int ($aOptions['max_length']))
{
if (false === $this -> validateMaxLength ($mString,
$aOptions['max_length'])) {
return false;
}
}
if (isset ($aOptions['strict_length']) && is_int
($aOptions['strict_length'])) {
if (false === $this -> validateStrictLength ($mString,
$aOptions['strict_length'])) {
return false;
}
}
if (isset ($aOptions['starting_with'])) {
if (false === $this -> validateStartsWith ($mString,
$aOptions['starting_with'])) {
return false;
}
}
if (isset ($aOptions['not_starting_with'])) {
if (false === $this -> validateStartsWithout ($mString,
$aOptions['not_starting_with'])) {
return false;
}
}
} else {
return -1;
}
return true;
}
}
/**
* class validateText extends validateGen
* basic text checker class
*
*/
class validateText extends validateGen {
/**
* protected function validate
* validation method, calls the required check methods and prior to them,
calls parent validate method
*
* @param string $mString : the input
* @param string $sName : user defined name given to the input
* @param string $loc : country alpha 3 code
* @param array $aOptions : null if no option, array of options
* @param boolean $bMandatory : true if the input is mandaotry, false if
not
* @return boolean true if the input successfully meets all the
requirements, false if not
*/
public function validate ($mString, $sName, $loc, $aOptions, $bMandatory) {
if (false === parent::validate ($mString, $sName, $loc, $aOptions,
$bMandatory)) {
return false;
}
return true;
}
}
/**
* class validateEmail extends validateGen
* emails checker class
*
*/
class validateEmail extends validateGen {
/**
* protected function validate
* validation method, checks if the input is an email and prior to it,
calls parent validate method
*
* @param string $mString : the input
* @param string $sName : user defined name given to the input
* @param string $loc : country alpha 3 code
* @param array $aOptions : null if no option, array of options
* @param boolean $bMandatory : true if the input is mandaotry, false if
not
* @return boolean true if the input successfully meets all the
requirements, false if not
*/
public function validate ($mString, $sName, $loc, $aOptions, $bMandatory) {
if (false === ($bRes = parent::validate ($mString, $sName, $loc,
$aOptions, $bMandatory))) {
return false;
} elseif (true === $bRes){
if (!preg_match
('`^[[:alnum:]]([-_.]?[[:alnum:]])*@[[:alnum:]]([-.]?[[:alnum:]])*\.([a-z]{2,4})$`',
$mString)) {
formChecker::$aMsg[$this -> sName] = $this -> sLocClass -> getConstant
('EMAIL_INVALID');
return false;
}
}
return true;
}
}
/**
* class validateUrl extends validateGen
* url checker class
*
*/
class validateUrl extends validateGen {
/**
* protected function validate
* validation method, checks if the input is an url and prior to it, calls
parent validate method
*
* @param string $mString : the input
* @param string $sName : user defined name given to the input
* @param string $loc : country alpha 3 code
* @param array $aOptions : null if no option, array of options
* @param boolean $bMandatory : true if the input is mandaotry, false if
not
* @return boolean true if the input successfully meets all the
requirements, false if not
*/
public function validate ($mString, $sName, $loc, $aOptions, $bMandatory) {
if (false === ($bRes = parent::validate ($mString, $sName, $loc,
$aOptions, $bMandatory))) {
return false;
} elseif (true === $bRes){
if (!preg_match ('`((?:https?|ftp)://\S+[[:alnum:]]/?)`si', $mString) &&
!preg_match ('`((?<!//)(www\.\S+[[:alnum:]]/?))`si', $mString)) {
formChecker::$aMsg[$this -> sName] = $this -> sLocClass -> getConstant
('URL_INVALID');
return false;
}
}
return true;
}
}
/**
* class validateRegExp extends validateGen
* user defined regexp checker class
*
*/
class validateRegExp extends validateGen {
/**
* protected function validate
* validation method, checks if the input matches the user defined regexp
and prior to it, calls parent validate method
* needs a mandaotory option at least : $aOptions['regexp'] = user defined
regexp pattern
*
* @param string $mString : the input
* @param string $sName : user defined name given to the input
* @param string $loc : country alpha 3 code
* @param array $aOptions : null if no option, array of options
* @param boolean $bMandatory : true if the input is mandaotry, false if
not
* @return boolean true if the input successfully meets all the
requirements, false if not
*/
public function validate ($mString, $sName, $loc, $aOptions, $bMandatory) {
if (false === ($bRes = parent::validate ($mString, $sName, $loc,
$aOptions, $bMandatory))) {
return false;
} elseif (true === $bRes){
if (!isset ($aOptions['regexp'])) {
throw new formCheckerException (formCheckerException::NO_REGEXP);
}
$bReg = @preg_match ($aOptions['regexp'], $mString);
if ((function_exists ('preg_last_error') && @preg_last_error() !==
PREG_NO_ERROR) || false === $bReg) {
throw new formCheckerException (formCheckerException::BAD_REGEXP);
} elseif (0 === $bReg) {
formChecker::$aMsg[$this -> sName] = str_replace ('{__INPUT__}', $this
-> sName, $this -> sLocClass -> getConstant ('REGEXP_FOUND_NOT_MATCH'));
return false;
}
}
return true;
}
}
/**
* class validateUserFunc extends validateGen
* user defined function checker class
*
*/
class validateUserFunc extends validateGen {
/**
* protected function validate
* validation method, checks if the input matches the user defined function
and prior to it, calls parent validate method
* needs a mandatory option at least : $aOptions['user_func'] = name of the
user function
* you can add parameters via the optional option
$aOptions['user_func_params']. This must be an array with all the
parameters.
* Please note the method will add at the end of the array of options the
input $mString.
* So, your user function MUST implements at least 1 parameter (the input),
and if there are others, the input parameter MUST be the last parameter
*
* @param string $mString : the input
* @param string $sName : user defined name given to the input
* @param string $loc : country alpha 3 code
* @param array $aOptions : null if no option, array of options
* @param boolean $bMandatory : true if the input is mandaotry, false if
not
* @return boolean true if the input successfully meets all the
requirements, false if not
*/
public function validate ($mString, $sName, $loc, $aOptions, $bMandatory) {
if (false === ($bRes = parent::validate ($mString, $sName, $loc,
$aOptions, $bMandatory))) {
return false;
} elseif (true === $bRes){
if (!isset ($aOptions['user_func'])) {
throw new formCheckerException (formCheckerException::NO_USER_FUNC);
}
if (isset ($aOptions['user_func_params']) && !is_array
($aOptions['user_func_params'])) {
throw new formCheckerException
(formCheckerException::USER_FUNC_PARAMS_NO_ARRAY);
}
$aOptions['user_func_params'][] = $mString;
$bFunc = call_user_func_array ($aOptions['user_func'],
$aOptions['user_func_params']);
if (false === $bFunc) {
formChecker::$aMsg[$this -> sName] = str_replace (array ('{__INPUT__}',
'{__FUNC__}'), array ($this -> sName, $aOptions['user_func']), $this ->
sLocClass -> getConstant ('USER_FUNC_RETURNED_FALSE'));
}
}
return true;
}
}
/**
* class validateInt extends validateGen
* integer checker class
*
*/
class validateInt extends validateGen {
/**
* protected function validate
* validation method, checks some specific numeric requirements and prior
to them, calls parent validate method
*
* @param string $mString : the input
* @param string $sName : user defined name given to the input
* @param string $loc : country alpha 3 code
* @param array $aOptions : null if no option, array of options
* @param boolean $bMandatory : true if the input is mandaotry, false if
not
* @return boolean true if the input successfully meets all the
requirements, false if not
*/
public function validate ($mString, $sName, $loc, $aOptions, $bMandatory) {
if (false === ($bRes = parent::validate ($mString, $sName, $loc,
$aOptions, $bMandatory))) {
return false;
} elseif (true === $bRes) {
if (false === ctype_digit ($mString)) {
formChecker::$aMsg[$this -> sName] = str_replace ('{__NUMERIC__}', $this
-> sName, $this -> sLocClass -> getConstant ('NUMERIC_NOT_NUMERIC'));
return false;
}
if (isset ($aOptions['min_range'])) {
if (false === $this -> validateMinRange ($mString,
$aOptions['min_range'])) {
return false;
}
}
if (isset ($aOptions['max_range'])) {
if (false === $this -> validateMaxRange ($mString,
$aOptions['max_range'])) {
return false;
}
}
}
return true;
}
/**
* private function validateMinRange
* checks if the numeric input is greater or equal than the minimum range
*
* @param string $mString : the input
* @param int $iMinRange : minimum range
* @return boolean if the input is greater or equal than the minimum range,
false if not
*/
private function validateMinRange ($mString, $iMinRange) {
if (true === $this -> isInt ($iMinRange)) {
if ($mString < $iMinRange) {
formChecker::$aMsg[$this -> sName] = str_replace (array
('{__NUMERIC__}', '{__MIN_RANGE__}'), array ($this -> sName, $iMinRange),
$this -> sLocClass -> getConstant ('NUMERIC_NOT_IN_MIN_RANGE'));
return false;
}
return true;
}
return false;
}
/**
* private function validateMaxRange
* checks if the numeric input is lesser or equal than the maximum range
*
* @param string $mString : the input
* @param int $iMaxRange : maximum range
* @return boolean if the input is lesser or equal than the maximum range,
false if not
*/
private function validateMaxRange ($mString, $iMaxRange) {
if (true === $this -> isInt ($iMaxRange)) {
if ($mString > $iMaxRange) {
formChecker::$aMsg[$this -> sName] = str_replace (array
('{__NUMERIC__}', '{__MAX_RANGE__}'), array ($this -> sName, $iMaxRange),
$this -> sLocClass -> getConstant ('NUMERIC_NOT_IN_MAX_RANGE'));
return false;
}
return true;
}
return false;
}
}
/**
* class formChecker
* only class to be called
* uses ReflectionClass to call the correct validateZZZ class
*
*/
class formChecker {
/**
* constants defining the allowed validation classes
*
*/
const VALIDATE_EMAIL = 'validateEmail';
const VALIDATE_INT = 'validateInt';
const VALIDATE_TEXT = 'validateText';
const VALIDATE_URL = 'validateUrl';
const VALIDATE_REGEXP = 'validateRegExp';
const VALIDATE_USER_FUNC = 'validateUserFunc';
/**
* public static aMsg
* static property storing the messages returned by the validateZZZ classes
(error messages)
* key is the user defined name for the input, value being the error
message
*
* @var array
*/
public static $aMsg = null;
/**
* private bValid
* true if the form (all the input validated) is ok, false if there is at
least one error among all the validation
*
* @var boolean
*/
private $bValid = true;
/**
* private loc
* localization property, country alpha 3 code
*
* @var string
*/
private $loc = null;
/**
* public function __construct
* constructor, sets some properties : localization, and reset aMsg array
of error messages
*
* @param string $loc
*/
public function __construct |
| |