From 2fd00de2170fcb16b5214c7839c18f0dacab8cdb Mon Sep 17 00:00:00 2001 From: tof <> Date: Fri, 31 Aug 2007 09:58:35 +0000 Subject: Full translation of Blog Tutorial in French. Thanks to Eric.M ! --- .../protected/pages/Day3/fr/Auth.page | 106 +++++++++++ .../protected/pages/Day3/fr/CreateAdminUser.page | 159 ++++++++++++++++ .../protected/pages/Day3/fr/CreateEditUser.page | 199 +++++++++++++++++++ .../protected/pages/Day3/fr/CreateLoginUser.page | 161 ++++++++++++++++ .../protected/pages/Day3/fr/CreateNewUser.page | 212 +++++++++++++++++++++ .../protected/pages/Day3/fr/Overview.page | 42 ++++ .../protected/pages/Day3/fr/directories.gif | Bin 0 -> 10329 bytes .../protected/pages/Day3/fr/output.gif | Bin 0 -> 10006 bytes .../protected/pages/Day3/fr/output2.gif | Bin 0 -> 9222 bytes .../protected/pages/Day3/fr/output3.gif | Bin 0 -> 9464 bytes 10 files changed, 879 insertions(+) create mode 100755 demos/blog-tutorial/protected/pages/Day3/fr/Auth.page create mode 100755 demos/blog-tutorial/protected/pages/Day3/fr/CreateAdminUser.page create mode 100755 demos/blog-tutorial/protected/pages/Day3/fr/CreateEditUser.page create mode 100755 demos/blog-tutorial/protected/pages/Day3/fr/CreateLoginUser.page create mode 100755 demos/blog-tutorial/protected/pages/Day3/fr/CreateNewUser.page create mode 100755 demos/blog-tutorial/protected/pages/Day3/fr/Overview.page create mode 100755 demos/blog-tutorial/protected/pages/Day3/fr/directories.gif create mode 100755 demos/blog-tutorial/protected/pages/Day3/fr/output.gif create mode 100755 demos/blog-tutorial/protected/pages/Day3/fr/output2.gif create mode 100755 demos/blog-tutorial/protected/pages/Day3/fr/output3.gif (limited to 'demos/blog-tutorial/protected/pages/Day3/fr') diff --git a/demos/blog-tutorial/protected/pages/Day3/fr/Auth.page b/demos/blog-tutorial/protected/pages/Day3/fr/Auth.page new file mode 100755 index 00000000..0cced90b --- /dev/null +++ b/demos/blog-tutorial/protected/pages/Day3/fr/Auth.page @@ -0,0 +1,106 @@ + + +

Authentification et Autorisation

+ + +

+Avant que nous n'implémentions la gestion des utilisateurs, nous devons activer les modules authentification et autorisation. +

+ + +

+Nous ajoutons deux nouveaux modules à notre fichier de configuration de l'application. +

+ + + + ...modules TDataSourceConfig et TActiveRecordConfig ... + + + + + + + +

+Le module TAuthManager gère le processus d'authentification et d'autorisation. Il utilise le module users comme gestionnaire d'utilisateur (voir ci-après). En spécifiant la propriété LoginPage, nous indiquons au module d'authentification de rediriger vers la page LoginUser quand il est nécessaire de s'authentifier. Nous décrirons comment créer la page LoginUser ci-après. +

+ +

+Le module user est une classe de type TDbUserManager qui est responsable de la vérification et de la validation des utilisateurs et qui enregistre dans une session PHP les données utilisateurs. La propriété UserClass est initialisée comme étant de type Application.BlogUser, ceci indique au module user de chercher une classe BlogUser dans le dossier protected (rappellez-vous que l'alias Application fait référence au dossier protected) et d'utiliser cette classe pour conserver les données utilisateurs dans une session. +Le module user est une classe de type TDbUserManager qui est responsable de la vérification et de la validation des utilisateurs et qui enregistre dans une session PHP les données utilisateurs. La propriété UserClass est initialisée comme étant de type Application.BlogUser, ceci indique au module user de chercher une classe BlogUser dans le dossier protected (rappellez-vous que l'alias Application fait référence au dossier protected) et d'utilisez cette classe pour conserver les données utilisateurs dans une session. +

+ +

+Comme vous pourrez le constater dans les sections suivantes, dans les différents contrôles et pages, nous pourrons utiliser $this->User pour accéder à l'objet qui contient les informations de l'utilisateur actuellement connecté. +

+ + +

+Ci-dessous les détails de l'implémentation de la classe BlogUser. Remarquez que les Active Record sont utilisés pour exécuter une requête. Par exemple, nous utilisons UserRecord::finder()->findByPk($username) pour chercher la valeur de $username dans la table users et ceci par la clé primaire. +

+ + +// Include TDbUserManager.php file which defines TDbUser +Prado::using('System.Security.TDbUserManager'); + +/** + * La classe BlogUser. + * BlogUser représente les données utilisateurs à conserver en session. + * L'implémentation par défaut conserve le nom et le rôle de l'utilisateur. + */ +class BlogUser extends TDbUser +{ + /** + * Créer un objet de type BlogUser basé sur le nom de l'utilisateur. + * Cette méthode est requise par TDbUser. Cet objet vérifie si l'utilisateur + * est bien présent en base de données. Si oui, un objet BlogUser + * est créé et initialisé. + * @param string le nom de l'utilisateur + * @return l'objet BlogUser, null si le nom de l'utilisateur est invalide. + */ + public function createUser($username) + { + // utilise l'Active Record UserRecord pour chercher l'utilisateur username + $userRecord=UserRecord::finder()->findByPk($username); + if($userRecord instanceof UserRecord) // si trouvé + { + $user=new BlogUser($this->Manager); + $user->Name=$username; // enregistre le nom de l'utilisateur + $user->Roles=($userRecord->role==1?'admin':'user'); // et son rôle + $user->IsGuest=false; // l'utilisateur n'est pas un invité + return $user; + } + else + return null; + } + + /** + * Vérifie que le nom d'utilisateur et son mot de passe sont correct. + * Cette méthode est requise par TDbUser. + * @param string le nom de l'utilisateur + * @param string le mot de passe + * @return boolean en fonction de la validité de la vérification. + */ + public function validateUser($username,$password) + { + // utilise l'Active Record UserRecord pour vérifier le nom d'utilisateur couplé au mot de passe. + return UserRecord::finder()->findBy_username_AND_password($username,$password)!==null; + } + + /** + * @return boolean indiquant si l'utilisateur est un administrateur. + */ + public function getIsAdmin() + { + return $this->isInRole('admin'); + } +} + + +
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day3/fr/CreateAdminUser.page b/demos/blog-tutorial/protected/pages/Day3/fr/CreateAdminUser.page new file mode 100755 index 00000000..04571c43 --- /dev/null +++ b/demos/blog-tutorial/protected/pages/Day3/fr/CreateAdminUser.page @@ -0,0 +1,159 @@ + + +

Création de la page d'administration des utilisateurs AdminUser

+ +

+La page AdminUser affiche la liste de tous les comptes utilisateurs, ainsi l'administrateur peut effectuer les tâches de maintenance. Par simplification, les tâches administratives pour notre blog seront la mise à jour des utilisateurs et la suppression. +

+ + +

+Nous allons lister les utilisateurs dans une table HTML. Chaque ligne correspondra à un compte utilisateur, les colonnes suivantes seront affichées: +

+ + + +

+Nous créons deux fichiers protected/pages/users/AdminUser.page et protected/pages/users/AdminUser.php qui contiendront respectivement le gabarit et la classe. +

+ +

Création du gabarit

+

+Nous allons utiliser un contrôle TDataGrid pour afficher les données. Suivant l'analyse précédente, nous allons configurer quatre colonnes: +

+ + + + +

Le gabarit complet est affiché ci-après:

+ + + +<%@ Title="Mon Blog - Administration des comptes utilisateurs" %> + +<com:TContent ID="Main"> + +

Administration des comptes utilisateurs

+ +Créer un nouvel utilisateur +
+ +<com:TDataGrid ID="UserGrid" + DataKeyField="username" + AutoGenerateColumns="false" + OnDeleteCommand="deleteButtonClicked"> + + <com:THyperLinkColumn + HeaderText="Pseudo" + DataTextField="username" + DataNavigateUrlField="username"> + <prop:DataNavigateUrlFormatString># + $this->Service->constructUrl('users.EditUser',array('username'=>{0})) + </prop:DataNavigateUrlFormatString> + </com:THyperLinkColumn> + + <com:TBoundColumn + HeaderText="Email" + DataField="email" /> + + <com:TCheckBoxColumn + HeaderText="Administrateur" + DataField="role" /> + + <com:TButtonColumn + HeaderText="Commande" + Text="Supprimer" + ButtonType="PushButton" + CommandName="delete" /> + +</com:TDataGrid> + +</com:TContent> +
+ + +

Création du fichier de classe

+ + +

+Dans le gabarit précédent, le bouton OnDeleteCommand déclenche l'évènement deleteButtonClicked() que nous devons implémenter dans le fichier de classe. De plus, la grille de données doit être renseignée avec les informations utilisateurs lorsque la page est initialisée. Nous écrivons donc notre fichier de classe comme ci-dessous : +

+ + +class AdminUser extends TPage +{ + /** + * Remplis la grille avec la liste des utilisateurs. + * Cette méthode est appelée lors de l'initialisation de la page. + * @param mixed param : paramètres de l'évènement + */ + public function onInit($param) + { + parent::onInit($param); + // lit tout les comptes utilisateurs + $this->UserGrid->DataSource=UserRecord::finder()->findAll(); + // et les associes à la grille + $this->UserGrid->dataBind(); + } + + /** + * Supprime un compte utilisateur. + * Cette méthode répond à l'évènement OnDeleteCommand. + * @param mixed sender : celui qui a généré l'évènement + * @param mixed param : paramètres de l'évènement + */ + public function deleteButtonClicked($sender,$param) + { + // récupère l'identifiant du bouton sur lequel on a cliqué + $item=$param->Item; + // récupère auprès de la grille la clé primaire correspondante à l'identifiant + $username=$this->UserGrid->DataKeys[$item->ItemIndex]; + // supprime le compte utilisateur en utilisant la clé primaire + UserRecord::finder()->deleteByPk($username); + } +} + + +

+Dans le code précédent, la méthode deleteButtonClicked() est appelée quand on clique sur le bouton "Supprimer". Pour savoir à quelle ligne appartenait le bouton, nous utilisons la propriété Item.ItemIndex du paramètre de l'évènement. Avec cet index, nous recherchons quelle est la clé primaire de la ligne grâce à la propriété DataKeys. +Dans le code précédent, la méthode deleteButtonClicked() est appelée quand on clique sur le bouton "Supprimer". Pour savoir à quelle ligne appartenait le bouton, nous utilisons la propriété Item.ItemIndex du paramètre de l'évènement. Avec cet index, nous recherchons quelle est la clé primaire de la ligne grâce à la propriété DataKeys. +

+ + +Tous les contrôles liés sont basé sur le même modèle. C'est à dire, définition de la propriété DataSource pour savoir d'où proviennent les données et appel à la méthode dataBind() pour effectivement lier les données au contrôle. + + +

Ajout de la vérification des droits d'accès

+

+Vu que seuls les administrateurs doivent pouvoir accéder à la page AdminUser, nous devons modifier notre fichier de configuration de page protected/pages/users/config.xml. +

+ + + + + + + + + + + +

Test

+ +

+Pour tester notre page AdminUser, nous naviguons à l'adresse http://hostname/blog/index.php?page=users.AdminUser. Il peut vous être demandé de vous connecter en tant qu'administrateur auparavant si ce n'est déjà fait. Le résultat suivant apparaitra. +

+ + + +
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day3/fr/CreateEditUser.page b/demos/blog-tutorial/protected/pages/Day3/fr/CreateEditUser.page new file mode 100755 index 00000000..f83a30f5 --- /dev/null +++ b/demos/blog-tutorial/protected/pages/Day3/fr/CreateEditUser.page @@ -0,0 +1,199 @@ + + +

Création de la page de mise à jour des utilisateurs EditUser

+ +

+La page EditUser ressemble beaucoup à la page NewUser. La différence principale est le fait que lorsque la page EditUser est requise, les champs sont renseignés avec les données de l'utilisateur en cours. Une autre différence est que la page EditUser est accessible à un utilisateur standard. +

+ +

+Pour définir quels sont les comptes qui peuvent être modifiés, nous allons utiliser les règles suivantes : +

+ + +

+Nous créons deux fichiers protected/pages/users/EditUser.page et protected/pages/users/EditUser.php qui contiendront respectivement le gabarit et la classe. +

+ +

Création du gabarit

+p> +Comme vous avez pu le deviner, la page EditUser est fortement ressemblante à la page NewUser. En dehors du titre de la page et du bouton "envoyer", il y a trois différences principales. +

+ + + + + +<%@ Title="Mon blog - Mise à jour utilisateur" %> + +<com:TContent ID="Main"> + +

Mise à jour utilisateur

+ +Pseudo: +<com:TLabel ID="Username" /> + +
+Mot de passe: +
+<com:TTextBox ID="Password" TextMode="Password" /> + +
+Confirmation mot de passe: +<com:TCompareValidator + ControlToValidate="Password" + ControlToCompare="Password2" + ErrorMessage="Différence entre le mot de passe et la confirmation." + Display="Dynamic" /> +
+<com:TTextBox ID="Password2" TextMode="Password" /> + +
+Email: +<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" /> +
+<com:TTextBox ID="Email" /> + +<com:TControl Visible="<%= $this->User->IsAdmin %>"> +
+Role: +
+<com:TDropDownList ID="Role"> + <com:TListItem Text="Utilisateur standard" Value="0" /> + <com:TListItem Text="Administrateur" Value="1" /> +</com:TDropDownList> +</com:TControl> + +
+Prénom: +
+<com:TTextBox ID="FirstName" /> + +
+Nom: +
+<com:TTextBox ID="LastName" /> + +
+<com:TButton Text="Enregistrer" OnClick="saveButtonClicked" /> + +</com:TContent> +
+ + +

Création du fichier de classe

+ + +

+En suivant les indications du gabarit, nous devons écrire une page de classe qui initialise les champs avec les données de l'utilisateur. De plus, la classe doit implémenter la méthode saveButtonClicked() appelée par l'évènement OnClick du bouton "Enregistrer". +

+ + +class EditUser extends TPage +{ + /** + * Initialise les champs avec les données de l'utilisateur. + * Cette méthode est appelée par le framework lorsque la page est initialisée. + * @param mixed param : paramètres de l'évènement + */ + public function onInit($param) + { + parent::onInit($param); + if(!$this->IsPostBack) // est-ce que c'est le premier appel à la page + { + // Lit les informations de l'utilisateur. C'est équivalent à : + // $userRecord=$this->getUserRecord(); + $userRecord=$this->UserRecord; + + // Rempli les contrôles avec les données de l'utilisateur + $this->Username->Text=$userRecord->username; + $this->Email->Text=$userRecord->email; + $this->Role->SelectedValue=$userRecord->role; + $this->FirstName->Text=$userRecord->first_name; + $this->LastName->Text=$userRecord->last_name; + } + } + + /** + * Enregistre les modifications si tous les validateurs sont Ok. + * Cette méthode répond à l'évènement OnClick du bouton "Enregistrer". + * @param mixed sender : celui qui a généré l'évènement + * @param mixed param : paramètres de l'évènement + */ + public function saveButtonClicked($sender,$param) + { + if($this->IsValid) // toutes les validations Ok ? + { + // Lit les informations de l'utilisateur. + $userRecord=$this->UserRecord; + + // Enresgistre les valeurs dans les champs de la BDD + $userRecord->username=$this->Username->Text; + // mets à jour le mot de passe s'il n'est pas vide + if(!empty($this->Password->Text)) + $userRecord->password=$this->Password->Text; + $userRecord->email=$this->Email->Text; + // mets à jour le rôle si l'utilisateur actuel est un administrateur + if($this->User->IsAdmin) + $userRecord->role=(int)$this->Role->SelectedValue; + $userRecord->first_name=$this->FirstName->Text; + $userRecord->last_name=$this->LastName->Text; + + // enregistre les modifications dans la BDD + $userRecord->save(); + + // redirige vers la page d'accueil + $this->Response->redirect($this->Service->DefaultPageUrl); + } + } + + /** + * Retourne l'utilisateur qui doit être mis à jour. + * @return UserRecord l'utilisateur qui doit être modifié. + * @throws THttpException si l'utilisateur n'existe pas. + */ + protected function getUserRecord() + { + // l'utilisateur à modifié est l'utilisateur actuellement connecté + $username=$this->User->Name; + // si la variable GET 'username' n'est pas vide et que l'utilisateur actuel + // est un administrateur, nous utilisons la variable GET à la place + if($this->User->IsAdmin && $this->Request['username']!==null) + $username=$this->Request['username']; + + // lit les données de l'utilisateur par Active Record + $userRecord=UserRecord::finder()->findByPk($username); + if(!($userRecord instanceof UserRecord)) + throw new THttpException(500,'Username is invalid.'); + return $userRecord; + } +} + + + +La méthode onInit() est appelée par PRADO lors du cycle de vie de la page. Les autres méthodes couramment surchargées sont onPreInit(), onLoad() et onPreRender(). + + +

Test

+ +

+Pour tester la page EditUser, rendons-nous à l'URL http://hostname/blog/index.php?page=users.EditUser&username=demo. Il vous sera peut-être demandé de vous authentifier auparavant si vous n'êtes pas déjà connecté. Essayez de vous connecter avec différents comptes (ie: admin/demo, demo/demo) et remarquez comment la page évolue différemment. +

+ + +
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day3/fr/CreateLoginUser.page b/demos/blog-tutorial/protected/pages/Day3/fr/CreateLoginUser.page new file mode 100755 index 00000000..07e97b87 --- /dev/null +++ b/demos/blog-tutorial/protected/pages/Day3/fr/CreateLoginUser.page @@ -0,0 +1,161 @@ + + +

Création de la page LoginUser

+ +

+La page LoginUser affiche un formulaire et gère l'authentification de l'utilisateur. Comme décrit dans authentification et autorisation, le navigateur est automatiquement redirigé vers la page LoginUser quand un utilisateur essaye d'accéder à une page protégée, telle que la page d'administration des utilisateurs. +

+ +

+Le processus de la page LoginUser est similaire à celui de la page Contact: +

+
    +
  1. Quand un utilisateur accède à la page LoginUser, un formulaire est affiché;
  2. +
  3. L'utilisateur remplit les champs, nom de l'utilisateur et mot de passe et clique sur le bouton "envoyer";
  4. +
  5. La classe LoginUser reçoit l'évènement "login" et lance la séquence d'authentification;
  6. +
  7. Si le nom d'utilisateur et le mot de passe sont corrects, le système l'enregistre en session et le redirige vers la page protégée demandée. Dans le cas contraire, un message "mot de passe invalide" est affiché. +
+ +

+Nous créons les deux fichiers protected/pages/users/LoginUser.page et protected/pages/users/LoginUser.php qui enregistre le gabarit et la classe respectivement. +

+ +

Création du gabarit

+ +

+Ci-après est affiché le gabarit pour LoginUser. Comme vous pouvez le constater, la page contient un champ de saisie pour le nom de l'utilisateur et un autre pour le mot de passe. Le nom de l'utilisateur est requis, ce que le validateur TRequiredFieldValidator contrôle. La validité du mot de passe est assurée par le validateur TCustomValidator qui fait un appel à la méthode validateUser() de la classe. La page contient aussi un bouton "envoyer" qui fait un appel à loginButtonClicked() quand il est activé. +

+ + +<%@ Title="My Blog - Login" %> + +<com:TContent ID="Main"> + +

Connexion

+ +Votre nom: +<com:TRequiredFieldValidator + ControlToValidate="Username" + ErrorMessage="Veuillez indiquer votre nom." + Display="Dynamic" /> +
+<com:TTextBox ID="Username" /> + +
+Mot de passe: +<com:TCustomValidator + ControlToValidate="Password" + ErrorMessage="vous avez saisi un mot de passe invalide." + Display="Dynamic" + OnServerValidate="validateUser" /> +
+<com:TTextBox ID="Password" TextMode="Password" /> + +
+<com:TButton Text="Envoyer" OnClick="loginButtonClicked" /> + +</com:TContent> +
+ +

Création de la classe

+ +

+Tout comme la page Contact, la page LoginUser a aussi besoin d'un fichier de classe qui implémente les évènements générés dans le fichier gabarit. Ici, nous avons besoin de deux méthodes : validateUser() et loginButtonClicked(). Dans validateUser(), nous utilisons le gestionnaire d'authentification pour vérifier si le nom d'utilisateur et le mot de passe sont valides. Si c'est le cas, le gestionnaire d'authentification créé automatiquement une session utilisateur avec les données correspondantes. +

+ + +class LoginUser extends TPage +{ + /** + * Vérifie la validité du nom d'utilisateur et du mot de passe. + * Cette méthode implémente l'évènement OnServerValidate du validateur TCustomValidator. + * @param mixed sender : celui qui a généré l'évènement + * @param mixed param : paramètres de l'évènement + */ + public function validateUser($sender,$param) + { + $authManager=$this->Application->getModule('auth'); + if(!$authManager->login($this->Username->Text,$this->Password->Text)) + $param->IsValid=false; // indique au validateur que la validation à échoué + } + + /** + * Rédirige le navigateur vers l'URL originellement demandée si la validation est Ok. + * Cette méthode implémente l'évènement OnClick du bouton "envoyer". + * @param mixed sender : celui qui a généré l'évènement + * @param mixed param : paramètres de l'évènement + */ + public function loginButtonClicked($sender,$param) + { + if($this->Page->IsValid) // toutes les validations sont ok ? + { + // récupère l'URL de la page protégée qui avait été demandée par l'utilisateur + $url=$this->Application->getModule('auth')->ReturnUrl; + if(empty($url)) // l'utilisateur à accéder à la page de connexion directement + $url=$this->Service->DefaultPageUrl; + $this->Response->redirect($url); + } + } +} + + + +

Test

+ +

+Nous avons donc créé la page LoginUser. Nous pouvons la tester en naviguant à l'URL http://hostname/blog/index.php?page=users.LoginUser. Rappellez-vous que la dans la section Création de la base, nous avons déjà créé deux comptes utilisateurs (nom d'utilisateur/mot de passe) admin/demo et demo/demo. Nous pouvons donc les utiliser pour tester notre page de connexion. +

+ + + +

Ajout des liens de connexion/déconnexion à notre gabarit principal

+

+Pour permettre à l'utilisateur d'accéder directement aux pages de connexion/déconnexion, nous modifions le gabarit principal MainLayout. En particulier, nous ajoutons un lien vers la page LoginUser. Nous ajoutons aussi un lien "se déconnecter" qui permet à l'utilisateur de se déconnecter. +

+ +

+Nous modifions le pied de page de notre gabarit principal MainLayout. La visibilité des liens vers "se connecter" et "se déconnecter" dépend du statut de l'utilisateur. Si l'utilisateur n'est pas encore connecté, ie: $this->User->IsGuest est vrai, alors le lien "se connecter" est visible tandis que le lien "se déconnecter" ne l'est pas et inversement s'il est connecté. +

+ + + + + +

+Vu que le lien "se déconnecter" génère l'évènement OnClick avec comme nom d'évènement logoutButtonClicked(), nous devons modifier le fichier de classe de MainLayout comme ci-dessous : +

+ + +class MainLayout extends TTemplateControl +{ + /** + * Déconnecte un utilisateur. + * Cette méthode répond à l'évènement OnClick du lien "se déconnecter". + * @param mixed sender : celui qui a généré l'évènement + * @param mixed param : paramètres de l'évènement + */ + public function logoutButtonClicked($sender,$param) + { + $this->Application->getModule('auth')->logout(); + $url=$this->Service->constructUrl($this->Service->DefaultPage); + $this->Response->redirect($url); + } +} + + +

+Maintenant si nous visitons n'importe quelle page de notre blog, nous verrons apparaitre un lien en pied de page. Le lien affiche "se connecter" si nous ne sommes pas connectés et "se déconnecter" dans le cas contraire. Si nous cliquons sur le lien "se déconnecter", nous sommes redirigés vers la page d'accueil et le lien "se connecter" apparait indiquant que nous ne sommes plus connectés. +

+ +
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day3/fr/CreateNewUser.page b/demos/blog-tutorial/protected/pages/Day3/fr/CreateNewUser.page new file mode 100755 index 00000000..144a686a --- /dev/null +++ b/demos/blog-tutorial/protected/pages/Day3/fr/CreateNewUser.page @@ -0,0 +1,212 @@ + + +

Création de la page nouvel utilisateur NewUser

+ +

+La page NewUser 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 base de données, nous devons prévoir la saisie des informations suivantes : +

+ + + +

+Nous créons deux fichiers, protected/pages/users/NewUser.page et protected/pages/users/NewUser.php qui contiendront respectivement le gabarit et la classe. +

+ +

Création du gabarit

+

+En fonction de l'analyse précédente, nous créons le gabarit comme ci-dessous : +

+ + +<%@ Title="Mon Blog - Nouvel utilisateur" %> + +<com:TContent ID="Main"> + +

Création nouvel utilisateur

+ +Pseudo: +<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" /> +
+<com:TTextBox ID="Username" /> + +
+Mot de passe: +<com:TRequiredFieldValidator + ControlToValidate="Password" + ErrorMessage="Veuillez indiquer un mot de passe." + Display="Dynamic" /> +
+<com:TTextBox ID="Password" TextMode="Password" /> + +
+Confirmation mot de passe: +<com:TCompareValidator + ControlToValidate="Password" + ControlToCompare="Password2" + ErrorMessage="Différence entre le mot de passe et la confirmation." + Display="Dynamic" /> +
+<com:TTextBox ID="Password2" TextMode="Password" /> + +
+Email: +<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" /> +
+<com:TTextBox ID="Email" /> + +
+Rôle: +
+<com:TDropDownList ID="Role"> + <com:TListItem Text="Utilisateur standard" Value="0" /> + <com:TListItem Text="Administrateur" Value="1" /> +</com:TDropDownList> + +
+Prénom: +
+<com:TTextBox ID="FirstName" /> + +
+Nom: +
+<com:TTextBox ID="LastName" /> + +
+<com:TButton Text="Ajouter" OnClick="createButtonClicked" /> + +</com:TContent> +
+ +

+Le gabarit est très proche du gabarit de la page Contact et de la page LoginUser. 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. +

+ + +

Création du fichier de classe

+ +

+En fonction du gabarit précédent, nous constatons que nous avons besoin d'une classe qui implémente deux gestionnaires d'évènements : checkUsername() (appellé par le premier validateur dans l'évènement OnServerValidate) et createButtonClicked() (appellé par l'évènement OnClick du bouton "create"). ainsi, nous écrirons la classe comme ci-dessous : +

+ + +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); + } + } +} + + +

+Dans le code précédent, l'appel à la méthode save() insère un enregistrement dans la table users. Cette fonctionnalité est fournie par l'objet Active Record. +

+ + +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 authentification. 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 authentification. 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 authentification. De même les espaces en début et fin de pseudo devrait être supprimés. + + + +

Test

+

+Pour tester la page NewUser, il suffit de naviguer à l'URL http://hostname/blog/index.php?page=users.NewUser. 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. +

+ + + + +

Ajout de la vérification des droits d'accès

+

+Durant le test, vous vous êtes peut-être demandé : Est-ce que la page NewUser ne devrait être accessible qu'aux administrateurs ? Oui, ceci est dénommé autorisation. Nous allons maintenant décrire comment ajouter cette vérification d'accès à la page NewUser. +

+ +

+Une façon simple serait de vérifier dans le code de la classe si $this->User->IsAdmin est vrai, dans le cas contraire, une redirection vers la page de connexion LoginUser serait faite. +

+ +

+PRADO propose une approche complémentaire de vérification des droits. Pour ce faire, nous devons utiliser un fichier de configuration de page. Créer un fichier protected/pages/users/config.xml avec le contenu suivant : +

+ + + + + + + + + + + +

+Le fichier de configuration de page contient les règles d'accès aux pages contenues dans le dossier protected/pages/users. Ce fichier indique que la page NewUser peut être vue par les utilisateurs dont le rôle est "admin" (concernant le mot "admin" voir BlogUser.createUser()), et toutes les autres pages de ce dossier interdites aux utilisateurs anonymes (users="?" signifie utilisateur anonyme). +

+ +

+Dorénavant, si nous naviguons à la page NewUser en tant qu'anonyme, nous serons redirigés vers la page LoginUser. Si notre connexion est acceptée, nous serons redirigés en retour vers la page NewUser +

+ + +Le fichier de configuration de pages peut contenir d'autres éléments que les règles d'autorisations. Par exemple, il pourrait inclure un module tout comme nous l'avons fait pour le fichier de configuration de l'application. 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. + + +
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day3/fr/Overview.page b/demos/blog-tutorial/protected/pages/Day3/fr/Overview.page new file mode 100755 index 00000000..306434e1 --- /dev/null +++ b/demos/blog-tutorial/protected/pages/Day3/fr/Overview.page @@ -0,0 +1,42 @@ + + +

Vue d'ensemble de la gestion des utilisateurs

+ + +

+Dans cette section, nous allons créer les pages concernant la gestion des utilisateurs. En particulier, nous allons implémenter les fonctionnalités suivantes: connexion/déconnexion des utilisateurs, création d'un utilisateur, mise à jour/suppression des utilisateurs. +

+ + +

+En accord avec les buts à atteindre, nous devons créer les pages suivantes. Pour une meilleure organisation de notre code, ces pages seront créées dans le dossier protected/pages/users. +

+ + + + + +

+Après avoir fini cette section, nous devrions obtenir l'arborescence suivante : +

+ + + + +
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day3/fr/directories.gif b/demos/blog-tutorial/protected/pages/Day3/fr/directories.gif new file mode 100755 index 00000000..f59fda58 Binary files /dev/null and b/demos/blog-tutorial/protected/pages/Day3/fr/directories.gif differ diff --git a/demos/blog-tutorial/protected/pages/Day3/fr/output.gif b/demos/blog-tutorial/protected/pages/Day3/fr/output.gif new file mode 100755 index 00000000..0d812dd0 Binary files /dev/null and b/demos/blog-tutorial/protected/pages/Day3/fr/output.gif differ diff --git a/demos/blog-tutorial/protected/pages/Day3/fr/output2.gif b/demos/blog-tutorial/protected/pages/Day3/fr/output2.gif new file mode 100755 index 00000000..749255d6 Binary files /dev/null and b/demos/blog-tutorial/protected/pages/Day3/fr/output2.gif differ diff --git a/demos/blog-tutorial/protected/pages/Day3/fr/output3.gif b/demos/blog-tutorial/protected/pages/Day3/fr/output3.gif new file mode 100755 index 00000000..a11ee653 Binary files /dev/null and b/demos/blog-tutorial/protected/pages/Day3/fr/output3.gif differ -- cgit v1.2.3