1
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
|
<com:TContent ID="Main">
<h1>Création de la page nouvel utilisateur <tt>NewUser</tt></h1>
<p>
La page <tt>NewUser</tt> est fournie à l'administrateur pour créer des nouveaux comptes utilisateurs. Elle doit afficher un formulaire qui permet la saisie des informations d'un nouveau compte. Tel que défini dans la <a href="?page=Day2.CreateDB">base de données</a>, nous devons prévoir la saisie des informations suivantes :
</p>
<ul>
<li><tt>username</tt> - string, pseudo de l'utilisateur, obligatoire et unique</li>
<li><tt>email</tt> - string, email, obligatoire et unique</li>
<li><tt>password</tt> - string, mot de passe, obligatoire</li>
<li><tt>role</tt> - integer, rôle, obligatoire (0 ou 1)</li>
<li><tt>first_name</tt> - string, prénom, optionnel</li>
<li><tt>last_name</tt> - string, nom, optionnel</li>
</ul>
<p>
Nous créons deux fichiers, <tt>protected/pages/users/NewUser.page</tt> et <tt>protected/pages/users/NewUser.php</tt> qui contiendront respectivement le gabarit et la classe.
</p>
<h2>Création du gabarit</h2>
<p>
En fonction de l'analyse précédente, nous créons le gabarit comme ci-dessous :
</p>
<com:TTextHighlighter CssClass="source" Language="prado">
<%@ Title="Mon Blog - Nouvel utilisateur" %>
<com:TContent ID="Main">
<h1>Création nouvel utilisateur</h1>
<span>Pseudo:</span>
<com:TRequiredFieldValidator
ControlToValidate="Username"
ErrorMessage="Veuillez indiquer un pseudo."
Display="Dynamic" />
<com:TCustomValidator
ControlToValidate="Username"
ErrorMessage="Désolé, le pseudo choisi est déjà utilisé. Veuillez en saisir un autre."
OnServerValidate="checkUsername"
Display="Dynamic" />
<br/>
<com:TTextBox ID="Username" />
<br/>
<span>Mot de passe:</span>
<com:TRequiredFieldValidator
ControlToValidate="Password"
ErrorMessage="Veuillez indiquer un mot de passe."
Display="Dynamic" />
<br/>
<com:TTextBox ID="Password" TextMode="Password" />
<br/>
<span>Confirmation mot de passe:</span>
<com:TCompareValidator
ControlToValidate="Password"
ControlToCompare="Password2"
ErrorMessage="Différence entre le mot de passe et la confirmation."
Display="Dynamic" />
<br/>
<com:TTextBox ID="Password2" TextMode="Password" />
<br/>
<span>Email:</span>
<com:TRequiredFieldValidator
ControlToValidate="Email"
ErrorMessage="Veuillez indiquer votre email."
Display="Dynamic" />
<com:TEmailAddressValidator
ControlToValidate="Email"
ErrorMessage="Vous avez indiqué un mot de passe invalide."
Display="Dynamic" />
<br/>
<com:TTextBox ID="Email" />
<br/>
<span>Rôle:</span>
<br/>
<com:TDropDownList ID="Role">
<com:TListItem Text="Utilisateur standard" Value="0" />
<com:TListItem Text="Administrateur" Value="1" />
</com:TDropDownList>
<br/>
<span>Prénom:</span>
<br/>
<com:TTextBox ID="FirstName" />
<br/>
<span>Nom:</span>
<br/>
<com:TTextBox ID="LastName" />
<br/>
<com:TButton Text="Ajouter" OnClick="createButtonClicked" />
</com:TContent>
</com:TTextHighlighter>
<p>
Le gabarit est très proche du gabarit de la page <tt>Contact</tt> et de la page <tt>LoginUser</tt>. Il consiste principalement en deux champs de saisie et de plusieurs validateurs. Certains champs de saisie sont associés à plusieurs validateurs vu qu'il est nécessaire de vérifier plusieurs règles.
</p>
<h2>Création du fichier de classe</h2>
<p>
En fonction du gabarit précédent, nous constatons que nous avons besoin d'une classe qui implémente deux gestionnaires d'évènements : <tt>checkUsername()</tt> (appellé par le premier validateur dans l'évènement <tt>OnServerValidate</tt>) et <tt>createButtonClicked()</tt> (appellé par l'évènement <tt>OnClick</tt> du bouton "create"). ainsi, nous écrirons la classe comme ci-dessous :
</p>
<com:TTextHighlighter CssClass="source" Language="php">
class NewUser extends TPage
{
/**
* Vérifie si le nom d'utilisateur existe dans la base de données.
* Cette méthode répond à l'évènement OnServerValidate du validateur username.
* @param mixed sender : celui qui a généré l'évènement
* @param mixed param : paramètres de l'évènement
*/
public function checkUsername($sender,$param)
{
// valide si l'utilisateur existe
$param->IsValid=UserRecord::finder()->findByPk($this->Username->Text)===null;
}
/**
* Créer un nouveau compte utilisateur si tous les champs sont valides.
* Cette méthode répond à l'évènement OnClick du bouton "create".
* @param mixed sender : celui qui a généré l'évènement
* @param mixed param : paramètres de l'évènement
*/
public function createButtonClicked($sender,$param)
{
if($this->IsValid) // si toutes les validations sont ok
{
// rempli l'objet UserRecord avec les données saisies
$userRecord=new UserRecord;
$userRecord->username=$this->Username->Text;
$userRecord->password=$this->Password->Text;
$userRecord->email=$this->Email->Text;
$userRecord->role=(int)$this->Role->SelectedValue;
$userRecord->first_name=$this->FirstName->Text;
$userRecord->last_name=$this->LastName->Text;
// l'enregistre dans la base de données par la méthode save de l'Active Record
$userRecord->save();
// redirige l'utilisateur vers la page d'accueil
$this->Response->redirect($this->Service->DefaultPageUrl);
}
}
}
</com:TTextHighlighter>
<p>
Dans le code précédent, l'appel à la méthode <tt>save()</tt> insère un enregistrement dans la table <tt>users</tt>. Cette fonctionnalité est fournie par l'objet <a href="http://www.pradosoft.com/demos/quickstart/?page=Database.ActiveRecord">Active Record</a>.
</p>
<com:NoteBox>
Par simplification, le pseudo dans notre blog est sensible à la casse. Dans beaucoup de systèmes, le pseudo est insensible à la casse. Il faudrait donc prévoir un traitement particulier lors de la création d'un nouvel utilisateur, ainsi que dans la partie <a href="?page=Day3.Auth">authentification</a>. De même, les espaces en début et fin de pseudo devrait être supprimés.
Par simplification, le pseudo dans notre blog est sensible à la casse. Dans beaucoup de systèmes, le pseudo est insensible à la casse. Il faudrait donc prévoir un traitement particulier lors de la création d'un nouvel utilisateur, ainsi que dans la partie <a href="?page=Day3.Auth">authentification</a>. De même les espaces en début et fin de pseudo devrait être supprimés.
Par simplification, le pseudo dans notre blog est sensible à la casse. Dans beaucoup de systèmes, le pseudo est insensible à la casse. Il faudrait donc prévoir un traitement particulier lors de la création d'un nouvel utilisateur, ainsi que dans la partie <a href="?page=Day3.Auth">authentification</a>. De même les espaces en début et fin de pseudo devrait être supprimés.
</com:NoteBox>
<h2>Test</h2>
<p>
Pour tester la page <tt>NewUser</tt>, il suffit de naviguer à l'URL <tt>http://hostname/blog/index.php?page=users.NewUser</tt>. vous devriez voir apparaitre la page suivante. Essayez de saisir différentes informations et remarquez comment les données sont validées. Si toutes les règles sont valides, nous devrions avoir inséré un nouvel utilisateur et être redirigés vers la page d'accueil.
</p>
<img src="<%~ output2.gif %>" class="output"/>
<h2>Ajout de la vérification des droits d'accès</h2>
<p>
Durant le test, vous vous êtes peut-être demandé : Est-ce que la page <tt>NewUser</tt> ne devrait être accessible qu'aux administrateurs ? Oui, ceci est dénommé <a href="http://www.pradosoft.com/demos/quickstart/?page=Advanced.Auth">autorisation</a>. Nous allons maintenant décrire comment ajouter cette vérification d'accès à la page <tt>NewUser</tt>.
</p>
<p>
Une façon simple serait de vérifier dans le code de la classe si <tt>$this->User->IsAdmin</tt> est vrai, dans le cas contraire, une redirection vers la page de connexion <tt>LoginUser</tt> serait faite.
</p>
<p>
PRADO propose une approche complémentaire de vérification des droits. Pour ce faire, nous devons utiliser un fichier de <a href="http://www.pradosoft.com/demos/quickstart/?page=Configurations.PageConfig">configuration de page</a>. Créer un fichier <tt>protected/pages/users/config.xml</tt> avec le contenu suivant :
</p>
<com:TTextHighlighter CssClass="source" Language="xml">
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<authorization>
<allow pages="NewUser" roles="admin" />
<deny users="?" />
</authorization>
</configuration>
</com:TTextHighlighter>
<p>
Le fichier de configuration de page contient les règles d'accès aux pages contenues dans le dossier <tt>protected/pages/users</tt>. Ce fichier indique que la page <tt>NewUser</tt> peut être vue par les utilisateurs dont le rôle est "admin" (concernant le mot "admin" voir <a href="?page=Day3.Auth">BlogUser.createUser()</a>), et toutes les autres pages de ce dossier interdites aux utilisateurs anonymes (<tt>users="?"</tt> signifie utilisateur anonyme).
</p>
<p>
Dorénavant, si nous naviguons à la page <tt>NewUser</tt> en tant qu'anonyme, nous serons redirigés vers la page <tt>LoginUser</tt>. Si notre connexion est acceptée, nous serons redirigés en retour vers la page <tt>NewUser</tt>
</p>
<com:TipBox>
Le fichier de configuration de pages peut contenir d'autres éléments que les règles d'autorisations. Par exemple, il pourrait inclure un <a href="http://www.pradosoft.com/demos/quickstart/?page=Fundamentals.Modules">module</a> tout comme nous l'avons fait pour le fichier de <a href="?page=Day2.ConnectDB">configuration de l'application</a>. Dans une application PRADO, chaque dossier de pages peut contenir un fichier de configuration de pages qui s'applique à tous les fichiers du dossier ainsi qu'aux sous dossiers.
</com:TipBox>
</com:TContent>
|