MFormValidator
Présentation
MFormValidator est une classe php qui permet de valider les donner envoyées via un formulaire.
La validation se fait sur la base d'un fichier de configuration simple à écrire et qui offre de nombreuses possibilités.
On pourra valider toutes les données d'un formulaire avec un code php aussi simple que :
$validator = mlib\utils\validator\MFormValidatorFactory::createFromFile(__DIR__."/path/to/validator.conf");
if(! $validator->run()){
echo $validator->getErrorMessage().'<br>';
echo 'Error on : '.$validator->getErrorField().'<br>';
}
et un fichier "validator.conf" très simple à écrire également (voir plus bas)
Le fichier de configuration
Les fichiers de configuration pour MFormValidator sont des fichiers de type MConfig (voir ici).
Ils consistent en une succession de blocs comme ceci :
<nom_du_champ_de_formulaire>
type = le_type
...
...
</nom_du_champ_de_formulaire>
Paramètres communs, quelque soit le type :
Requis :
- type : une des valeurs parmis : string, enum, email, phone, integer, float, date, datetime, time, file, complex, custom
Optionnels :
* multi (booléen) : si le champ est multivalué
* required (booléen) : si le champ est requis ou non
* error : un message d'erreur si aucun autre message plus précis n'est retourné
* check_method : le nom d'une méthode de la classe qui implémente la validation, si on veut faire une validation additionnelle personnalisée (voir plus bas)
En fonction du type renseigné, un certain nombre d'autre directives seront à fournir de manière obligatoire ou optionnelle.
string
On peut utiliser le type string pour vérifier un champ un "input type=text" ou une "textarea"
Paramètres optionnels :
* minlength :
* maxlength :
* regex :
On peut utiliser le type email pour vérifier un champ un "input type=text" ou une "input type=email"
Paramètres optionnels :
* regex :
integer
Paramètres optionnels :
* min :
* max :
float
Paramètres optionnels :
* min :
* max :
enum
Le type enum sert à vérifier la(les) valeur(s) d'un select, de checkboxes ou de boutons radio html.
Paramètres requis :
* options (config) : un bloc de configuration pour les valeurs (voir ici)
date
Paramètres (tous optionnels):
* format : un format de date conforme pour une DateTimeInterface (voir ici)
- 'Y-m-d' (default)
* min : la date minimale acceptée (la date du jour si non renseigné)
* max : la date maximale acceptée (la date du jour + 1 an si non renseigné)
min et max peuvent être des dates au format spécifié (Y-m-d par défaut) ou bien
- Y ou Y ± N (avec N un nombre entier) : le 1er janvier (min) ou le 31 décembre (max) de l'année ± N années
- M ou M ± N (avec N un nombre entier) : le 1er (min) ou dernier (max) jour du mois ± N mois
- D ou D ± N (avec N un nombre entier) : aujourd'hui ± N jours
Exemples :
min = D # à partir d'aujourd'hui
max = D+365 # à l'horizon d'un an
min = Y-1 # du premier janvier de l'année précédente
max = Y+1 # au 31 décembre de l'anée suivante
datetime
idem date
* format : 'Y-m-d H:i' (default)
time
idem date
* format :'H:i' (default)
file
Permet de vérifier un fichier téléversé.
Paramètres optionnels :
* file_types : les extensions de fichiers acceptés.
- une ou plusieurs extensions de fichiers séparées par des "/"
Une certain nombre de vérifications ystème sont faites également qui permettent de connaitre la cause en cas d'échec.
complex
Le type complex permet de vérifier plusieurs champs liés entre eux.
Un type complex peut être multivalué (voir type complex de MForm)
Paramètres requis :
* une ou plusieurs configs des champs qui composent le champ combiné
custom
Le type custom permet de faire une vérification personnalisée d'un champ de formulaire (si aucun autre type ne convient à ce que l'on veut faire).
Pour cela on devra écrire une classe php qui hérite de MFormValidator, dans laquelle on écrira une méthode chargée de vérifier le champ de formulaire. On indiquera le nom de cette méthode dans un paramètre de la configuration du champ.
Paramètres requis :
* check_method : le nom de la méthode à appeler pour vérifier le champ
Le bloc "options" pour le type enum
Le bloc "options doit contenir le paramètre "type" qui peut prendre une des deux valeurs suivantes :
* constant : la liste des options est toujours la même. Elle doit être indiquée dans le bloc (voir ci-dessous)
* custom : la liste des options est dynamique. Elle sera précisée à l'exécution grâce à la méthode setCustomOptions (voir plus bas). On utilisera cette méthode si les éléments d'une enumération (type enum) sont stockés en base de données par exemple.
Si le type est "contant", il faut alors préciser le paramètre suivant :
* values : les valeurs des options séparées par des "/" (Ex : 1/2/3)
Exemple d'un select avec des options constantes :
<le_nom_du_champ>
type = enum
<options>
type = constant
values = 1/2/3
</options>
error = la valeur transmise ne fait pas partie des valeurs autorisées
</le_nom_du_champ>
Exemple d'un enum avec des options dynamiques à l’exécution :
<le_nom_du_champ>
type = enum
<options>
type = custom
</options>
error = la valeur transmise ne fait pas partie des valeurs autorisées
</le_nom_du_champ>
Exemple d'utilisation de setCustomOptions :
$validator = mlib\utils\validator\MFormValidatorFactory::createFromFile(__DIR__."/path/to/validator.conf");
$values = $database->getValuesOrderByValues(); // pour l'exemple
$validator_options = array(
'my_enum_with_dynamic_options' => $values
// other options for other fields could be set here
);
$validator->setCustomOptions($validator_options);
$result = $validator->run();
La méthode globalCheck()
Dans un formulaire on peut avoir besoin de faire des vérifications croisées entre les champs du formulaire. C'est à dire qu'en fonction de la valeur d'un champ, la valeur d'un autre doit respecter certains critères (deux mots de passes identiques par exemple).
Il existe pour cela une methode spéciale : globalCheck($vars)
Pour mettre en place cette vérification globale, il faut créer une classe validateur qui hérite de MFormValidator et redéfinir la méthode.
Exemple :
class PasswordFormValidator extends mlib\utils\validator\MFormValidator{
public function globalCheck($vars){
if($vars['password1'] != $vars['password2']){
$this->setErrorMessage("Vous n'avez pas saisi 2 fois le même mot de passe");
return false;
}
return true;
}
}
mlib\utils\validator\MFormValidatorFactory::setImplementation(PasswordFormValidator::class);
$validator = mlib\utils\validator\MFormValidatorFactory::createFromFile(__DIR__."/path/to/validator.conf");
$result = $validator->run();
$vars contient tout ce qui a été envoyé (copie de $_POST)
La méthode doit retourner true ou false.
Le paramètre "check_method"
Nous l'avons vu pour les champs de type "custom", le paramètre "check_method" permet de spécifier le nom d'une méthode de la classe qui implémente la validation.
Si pour un champ de type "custom le paramètre est obligatoire, pour les autres types, il est optionnel, mais sera utile si on veut faire des vérifications personnalisées, en plus des vérifications fournies par MFormValidator grace aux paramètre fournis.
Exemple :
<my_field>
type = password
regex = ^[a-zA-Z0-9_]{10,}$
error_regex = "Le mot de passe doit contenir au moins 10 caractères"
check_method = myCheckMethod # Si on veut faire d'autre vérifications sur le mot de passe (historique du mot de passe, absence d'une base de données par exemple)
</my_field>
La méthode myCheckMethod devra être redéfinie dans la classe qui implémente la validation.
Exemple :
class PasswordFormValidator extends mlib\utils\validator\MFormValidator{
...
...
public function myCheckMethod($value){
// on vérifie que le mot de passe n'est pas dans la base de données
$passwords = $this->getDatabase()->getPasswords();
if(in_array($value, $passwords)){
$this->setErrorMessage("Le mot de passe fait partie d'une base de données de mots de passe connus");
return false;
}
return true;
}
}
Les messages d'erreur
Pour chaque champ de formulaire à vérifier, il est recommandé, d'ajouter un ou plusieurs messages d'erreur dans le fichier de configuration.
Sans cela, si le validateur retourne false, on ne sera pas capable de dire pourquoi à l'utilisateur.
ainsi on peut ajouter l'option error qui seara un message générique pas très précis :
<my_field>
type = xxxx
....
error = "Une erreur a été détectée sur le champ my_field"
</my_field>
mais pour chaque option (selon le type), on peut ajouter des messages adaptés à l'erreur en préfixant le critère par error_.
Exemple :
<my_field>
type = integer
min = 10
max = 100
required
error = "Une erreur a été détectée sur le champ my_field"
error_type = "my_field doit être un nombre entier"
error_min = "my_field doit être supérieur ou égal à 10"
error_max = "my_field doit être inférieur ou égal à 100"
error_required = "Veuillez saisir une valeur pour my_field"
</my_field>
Ces options ne sont pas obligatoires, mais si rien n'est défini, la méthode getErrorMessage() ne renverra rien. On aura juste l'indication du champ en erreur grace à la méthode getErrorField().
C'est pourquoi il est conseillé de définir a minima le paramètre error, qui sera retourné si le message correspondant au critère qui provoque l'erreur n'est pas précisé.