XVII. Chapitre 17 : Validation▲
Laravel peut nous simplifier aussi la vie dans le domaine de la validation des entrées et la génération des messages d'erreur afférents.
XVII-A. Le formulaire d'inscription▲
Nous allons considérer un formulaire d'inscription app/views/inscription.php :
2.
3.
4.
5.
6.
7.
8.
9.
10.
<h2>Inscription au site : </h2>
<form action
=
"http://localhost/laravel/public/inscription"
method
=
"post"
>
<label for
=
"nom"
><strong>Nom :</strong></label>
<input type
=
"text"
name
=
"nom"
id
=
"nom"
/>
<label for
=
"pass"
><strong>Mot de passe :</strong></label>
<input type
=
"text"
name
=
"passe"
id
=
"pass"
/>
<label for
=
"confirmepasse"
><strong>Confirmation du mot de passe :</strong></label>
<input type
=
"text"
name
=
"confirmepasse"
id
=
"confirmepasse"
/>
<input type
=
"submit"
value
=
"S'inscrire"
/>
</form>
XVII-A-1. Les routes▲
Il nous faut déjà une route pour afficher le formulaire avec l'URL http://localhost/laravel/public/login :
Il nous faut ensuite une route pour le traitement de retour du formulaire avec l'URL localhost/laravel/public/inscription, qui aura cette structure :
2.
3.
4.
Route::
post('
inscription
'
,
function()
{
}
);
XVII-A-2. La validation▲
La validation avec Laravel se fait en définissant des règles :
2.
3.
4.
5.
$rules
=
array(
'
nom
'
=>
'
required|min:5|max:20|alpha
'
,
'
passe
'
=>
'
required|min:6|max:10|alpha
'
,
'
confirmepasse
'
=>
'
required|same:passe
'
);
On définit dans un tableau pour chaque champ les règles correspondantes. Vous pouvez trouver toutes les règles disponibles dans la documentation. Ici par exemple on veut que le nom soit saisi avec un minimum de cinq et un maximum de 20 caractères alphanumériques. Pour le champ confirmepasse on veut qu'il soit identique à passe. Ensuite on crée une instance de la classe Validation en spécifiant les valeurs des champs et les règles :
$validator
=
Validator::
make(Input::
all(),
$rules
);
Il ne reste plus qu'à tester que les règles ont été respectées avec la méthode fails :
if ($validator
->
fails()) {
// Traitement en cas d'échec dans au moins une des règles
}
On peut utiliser la méthode inverse passes :
if ($validator
->
passes()) {
// Traitement en cas de réussite
}
XVII-A-3. Les messages▲
C'est bien de déterminer qu'une règle n'a pas été respectée, encore faut-il savoir laquelle. La classe Validation possède des méthodes pour nous donner des messages relatifs à ces non-respects. Voici notre route maintenant :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Route::
post('
inscription
'
,
function()
{
$rules
=
array(
'
nom
'
=>
'
required|min:5|max:20|alpha
'
,
'
passe
'
=>
'
required|min:6|max:10|alpha
'
,
'
confirmepasse
'
=>
'
required|same:passe
'
);
$validator
=
Validator::
make(Input::
all(),
$rules
);
if ($validator
->
fails()) {
echo $validator
->
messages();
}
else echo '
Vous êtes incrit
'
.
Input::
get('
nom
'
);
}
);
Et quelques messages en cas de non-respect. Par exemple si on ne saisit rien du tout :
{
"nom"
:[
"The nom field is required."
],
"passe"
:[
"The passe field is required."
],
"confirmepasse"
:[
"The confirmepasse field is required."
]}
Avec un nom et un mot de passe trop courts et pas de confirmation du mot de passe :
{
"nom"
:[
"The nom must be at least 5 characters."
],
"passe"
:[
"The passe must be at least 6 characters."
],
"confirmepasse"
:[
"The confirmepasse field is required."
]}
Si la confirmation du mot de passe n'est pas correcte :
{
"confirmepasse"
:[
"The confirmepasse and passe must match."
]}
Bon tout ça semble bien fonctionner, mais c'est en anglais ! Regardez le fichier app/lang/en/validation.php :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
<?php
return
array
(
/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| such as the size rules. Feel free to tweak each of these messages.
|
*/
"accepted"
=>
"The :attribute must be accepted."
,
"active_url"
=>
"The :attribute is not a valid URL."
,
"after"
=>
"The :attribute must be a date after :date."
,
"alpha"
=>
"The :attribute may only contain letters."
,
"alpha_dash"
=>
"The :attribute may only contain letters, numbers, and dashes."
,
"alpha_num"
=>
"The :attribute may only contain letters and numbers."
,
"before"
=>
"The :attribute must be a date before :date."
,
"between"
=>
array
(
"numeric"
=>
"The :attribute must be between :min - :max."
,
"file"
=>
"The :attribute must be between :min - :max kilobytes."
,
"string"
=>
"The :attribute must be between :min - :max characters."
,
),
"confirmed"
=>
"The :attribute confirmation does not match."
,
"different"
=>
"The :attribute and :other must be different."
,
"digits"
=>
"The :attribute must be :digits digits."
,
"digits_between"
=>
"The :attribute must be between :min and :max digits."
,
"email"
=>
"The :attribute format is invalid."
,
"exists"
=>
"The selected :attribute is invalid."
,
"image"
=>
"The :attribute must be an image."
,
"in"
=>
"The selected :attribute is invalid."
,
"integer"
=>
"The :attribute must be an integer."
,
"ip"
=>
"The :attribute must be a valid IP address."
,
"match"
=>
"The :attribute format is invalid."
,
"max"
=>
array
(
"numeric"
=>
"The :attribute must be less than :max."
,
"file"
=>
"The :attribute must be less than :max kilobytes."
,
"string"
=>
"The :attribute must be less than :max characters."
,
),
"mimes"
=>
"The :attribute must be a file of type: :values."
,
"min"
=>
array
(
"numeric"
=>
"The :attribute must be at least :min."
,
"file"
=>
"The :attribute must be at least :min kilobytes."
,
"string"
=>
"The :attribute must be at least :min characters."
,
),
"notin"
=>
"The selected :attribute is invalid."
,
"numeric"
=>
"The :attribute must be a number."
,
"required"
=>
"The :attribute field is required."
,
"required_with"
=>
"The :attribute field is required when :values is present."
,
"same"
=>
"The :attribute and :other must match."
,
"size"
=>
array
(
"numeric"
=>
"The :attribute must be :size."
,
"file"
=>
"The :attribute must be :size kilobytes."
,
"string"
=>
"The :attribute must be :size characters."
,
),
"unique"
=>
"The :attribute has already been taken."
,
"url"
=>
"The :attribute format is invalid."
,
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'custom'
=>
array
(),
/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap attribute place-holders
| with something more reader friendly such as E-Mail Address instead
| of "email". This simply helps us make messages a little cleaner.
|
*/
'attributes'
=>
array
(),
);
Tous les messages sont ici et rien ne vous empêche de les traduire . Vous pouvez aussi récupérer le message créé par Caouecs ici. Mais si vous le faites, adoptez une méthode « propre » et créez un dossier fr pour localiser les fichiers de langues et renseignez la ligne correspondante dans le fichier app/config/app.php.
Il est aussi possible de passer le texte des messages comme troisième paramètre de cette façon :
2.
3.
4.
5.
$validator
=
Validator::
make(
Input::
all(),
$rules
,
array('
required
'
=>
'
Le champ :attribute est requis.
'
,
));
XVII-A-4. Utilisation des messages▲
Maintenant que nous avons des messages, nous devons les afficher pour que l'utilisateur corrige sa saisie. Il faut donc transmettre au formulaire d'inscription ces erreurs et prévoir leur affichage. Pour la transmission c'est simple :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Route::
post('
inscription
'
,
function()
{
$rules
=
array(
'
nom
'
=>
'
required|min:5|max:20|alpha
'
,
'
passe
'
=>
'
required|min:6|max:10|alpha
'
,
'
confirmepasse
'
=>
'
required|same:passe
'
);
$validator
=
Validator::
make(Input::
all(),
$rules
);
if ($validator
->
fails()) {
return Redirect::
to('
login
'
)->
withErrors($validator
);
}
else echo '
Vous êtes incrit
'
.
Input::
get('
nom
'
);
}
);
Et pour le formulaire c'est tout aussi simple :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
<
form action
=
"
http://localhost/laravel/public/inscription
"
method
=
"
post
"
>
<?php
echo $errors
->
first('nom'
,
'<p>:message</p>'
);
?>
<
label for
=
"
nom
"
><strong>
Nom :<
/strong
></label
>
<
input type
=
"
text
"
name
=
"
nom
"
id
=
"
nom
"
/
>
<?php
echo $errors
->
first('passe'
,
'<p>:message</p>'
);
?>
<
label for
=
"
pass
"
><strong>
Mot de passe :<
/strong
></label
>
<
input type
=
"
text
"
name
=
"
passe
"
id
=
"
pass
"
/
>
<?php
echo $errors
->
first('confirmepasse'
,
'<p>:message</p>'
);
?>
<
label for
=
"
confirmepasse
"
><strong>
Confirmation du mot de passe :<
/strong
></label
>
<
input type
=
"
text
"
name
=
"
confirmepasse
"
id
=
"
confirmepasse
"
/
>
<
input type
=
"
submit
"
value
=
"
S'inscrire
"
/
>
<
/form
>
Ce qui donne par exemple :
La méthode first récupère la première erreur rencontrée pour un champ donné. On peut aussi obtenir tous les messages pour un champ avec la méthode get :
$messages
->
get('
nom
'
)
Ou alors tester s'il y a des messages pour un champ :
$messages
->
has('
nom
'
)
XVII-A-5. Renseigner les champs au retour d'erreurs de saisie▲
Bon il nous reste quand même un petit souci. Il serait bien de renseigner certains champs quand on réaffiche le formulaire suite à un non-respect des règles de saisie. La transmission des valeurs des champs se fait facilement :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Route::
post('
inscription
'
,
function()
{
$rules
=
array(
'
nom
'
=>
'
required|min:5|max:20|alpha
'
,
'
passe
'
=>
'
required|min:6|max:10|alpha
'
,
'
confirmepasse
'
=>
'
required|same:passe
'
);
$validator
=
Validator::
make(Input::
all(),
$rules
);
if ($validator
->
fails()) {
return Redirect::
to('
login
'
)->
withErrors($validator
)->
withInput();
}
else echo '
Vous êtes incrit
'
.
Input::
get('
nom
'
);
}
);
Et voici comment les récupérer dans le formulaire avec la méthode old :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
<
form action
=
"
http://localhost/laravel/public/inscription
"
method
=
"
post
"
>
<?php
echo $errors
->
first('nom'
,
'<p>:message</p>'
);
?>
<
label for
=
"
nom
"
><strong>
Nom :<
/strong
></label
>
<
input type
=
"
text
"
name
=
"
nom
"
id
=
"
nom
"
value
=
"
<?php
echo Input::
old('nom'
);
?>
"
/
>
<?php
echo $errors
->
first('passe'
,
'<p>:message</p>'
);
?>
<
label for
=
"
pass
"
><strong>
Mot de passe :<
/strong
></label
>
<
input type
=
"
password
"
name
=
"
passe
"
id
=
"
pass
"
value
=
"
<?php
echo Input::
old('passe'
);
?>
"
/
>
<?php
echo $errors
->
first('confirmepasse'
,
'<p>:message</p>'
);
?>
<
label for
=
"
confirmepasse
"
><strong>
Confirmation du mot de passe :<
/strong
></label
>
<
input type
=
"
password
"
name
=
"
confirmepasse
"
id
=
"
confirmepasse
"
/
>
<
input type
=
"
submit
"
value
=
"
S'inscrire
"
/
>
<
/form
>
Si vous utilisez la classe Form, le remplissage des champs avec les anciennes valeurs est automatique. Voici l'équivalent du formulaire ci-dessus, mais cette fois en utilisant les classes Form et Blade :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
{{
$errors
->
first('nom'
,
'<p>:message</p>'
) }}
{{
Form::
open(array
('url'
=>
'inscription'
)) }}
<
strong>
{{
Form::
label('nom'
,
'Nom : '
) }}
<
/strong
>
{{
Form::
text('nom'
);
}}
<
br>
{{
$errors
->
first('passe'
,
'<p>:message</p>'
) }}
<
strong>
{{
Form::
label('pass'
,
'Mot de passe : '
) }}
<
/strong
>
{{
Form::
password('pass'
);
}}
<
br>
{{
$errors
->
first('confirmepasse'
,
'<p>:message</p>'
) }}
<
strong>
{{
Form::
label('confirmepasse'
,
'Confirmation du mot de passe :'
) }}
<
/strong
>
{{
Form::
password('confirmepasse'
) }}
<
br>
{{
Form::
submit('S
\'
inscrire'
) }}
{{
Form::
close() }}
Vous n'êtes bien sûr pas obligés d'utiliser ces possibilités mais ce serait dommage .