Aller au contenu

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 :

email

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é.