Gérer une communauté d'utilisateurs
Créez site15 en copiant site14.
- /cms
- ...
- site14
- site15
Dans ce chapitre, nous allons gérer une communauté d'utilisateurs dans une BD et leur attribuer des rôles.
Pour tester le résultat en ligne, entrez http://www.frasq.org/cms/site15 dans la barre d'adresse de votre navigateur.
Identifiez-vous en tant que foobar
avec le mot de passe f00bar
.
Un bouton vert avec une coche apparaît dans le bandeau de la page d'accueil.
Si vous cliquez dessus, le contenu de la page est transmis au validateur du W3C.
Déconnectez-vous et identifiez-vous de nouveau mais en tant que barfoo
avec le mot de passe barf00
.
Le lien sur le W3C n'est pas affiché.
Démarrez le processeur de commandes de MySQL et entrez dans la BD du site :
$ mysql -u root -p
mysql> use frasqdb2;
NOTE : Utilisez phpMyAdmin pour plus de confort.
Ajoutez la table user
à la BD du site :
user_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(40) NOT NULL,
`password` VARCHAR(32) NOT NULL,
mail VARCHAR(100) DEFAULT NULL,
created datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`access` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
locale enum('fr','en') NOT NULL DEFAULT 'fr',
active tinyint(1) NOT NULL DEFAULT '1',
banned tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (user_id),
UNIQUE KEY name (name),
UNIQUE KEY mail (mail)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Le numéro de l'utilisateur user_id
est aussi la clé primaire .
name
et mail
sont des clés uniques qui permettent d'identifier un utilisateur.
password
garde le mot de passe de l'utilisateur chiffré en MD5.
created
contient la date et l'heure de création du compte.
access
note la date et l'heure de la dernière connexion au compte.
locale
donne la langue préférée de l'utilisateur parmi celles gérées par le site.
active
indique si le compte est accessible.
banned
signale un utilisateur indésirable.
Créez un utilisateur foobar
avec le mot de passe f00bar
et un utilisateur barfoo
avec le mot de passe barf00
:
VALUES ('foobar', MD5('f00bar'), 'foobar@localhost', NOW());
INSERT INTO USER (name, password, mail, created)
VALUES ('barfoo', MD5('barf00'), 'barfoo@localhost', NOW());
Remarquez que les mots de passe sont encodés en MD5. IMPORTANT : Ne conservez jamais les mots de passe en clair.
Ajoutez les tables role
et user_role
à la BD du site :
role_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(40) NOT NULL,
PRIMARY KEY (role_id),
UNIQUE KEY name (name)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
role
n'est rien de plus qu'une liste de noms.
user_id INT(10) UNSIGNED NOT NULL DEFAULT '0',
role_id INT(10) UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (user_id,role_id),
KEY `role` (role_id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
user_role
associe un numéro d'utilisateur avec un rôle. Un utilisateur peut avoir plusieurs rôles.
Définissez les rôles administrator
, writer
, reader
et moderator
:
INSERT INTO `role` (name) VALUES ('writer');
INSERT INTO `role` (name) VALUES ('reader');
INSERT INTO `role` (name) VALUES ('moderator');
Associez l'utilisateur foobar
aux rôles administrator
et writer
:
INSERT INTO user_role (user_id, role_id) VALUES (1, 2);
Vérifiez que vous pouvez lister les noms des rôles d'un utilisateur :
mysql> SELECT u.name AS user_name, r.name AS role_name FROM user u
JOIN user_role ur ON ur.user_id=u.user_id
JOIN role r ON r.role_id=ur.role_id
WHERE ur.user_id=1;
+-----------+---------------+
| user_name | role_name |
+-----------+---------------+
| foobar | administrator |
| foobar | writer |
+-----------+---------------+
2 rows in set (0.00 sec)
mysql> quit
Éditez le fichier user.inc
dans le dossier models
et ajoutez les fonctions suivantes :
- function user_get($user_id) {
- if (!is_numeric($user_id)) {
- return false;
- }
- $tabuser=db_prefix_table('user');
- $sql="SELECT name AS user_name, password AS user_password, mail AS user_mail, UNIX_TIMESTAMP(created) AS user_created, UNIX_TIMESTAMP(access) AS user_access, locale AS user_locale, active AS user_active, banned AS user_banned FROM $tabuser WHERE user_id=$user_id LIMIT 1";
- $r = db_query($sql);
- return $r ? $r[0] : false;
- }
user_get
retourne un tableau avec les champs user_name
, user_password
, user_mail
, user_created
, user_access
, user_locale
, user_active
et user_banned
de l'utilisateur dont le numéro est $user_id
ou false
si $user_id
n'est pas un numéro d'utilisateur valide.
- function user_get_role($user_id) {
- if (!is_numeric($user_id)) {
- return false;
- }
- $tabrole=db_prefix_table('role');
- $tabuserrole=db_prefix_table('user_role');
- $sql="SELECT r.name AS role_name FROM $tabuserrole ur JOIN $tabrole r ON r.role_id=ur.role_id WHERE ur.user_id=$user_id";
- $r = db_query($sql);
- if (!$r) {
- return false;
- }
- $role=array();
- foreach ($r as $v) {
- $role[] = $v['role_name'];
- }
- return $role;
- }
user_get_role
retourne la liste des rôles de l'utilisateur $user_id
ou false
si $user_id
n'est pas un numéro d'utilisateur valide.
- function user_find($login) {
- $sqllogin=db_sql_arg($login, true);
- $tabuser=db_prefix_table('user');
- $sql="SELECT user_id FROM $tabuser WHERE name=$sqllogin OR mail=$sqllogin LIMIT 1";
- $r = db_query($sql);
- return $r ? $r[0]['user_id'] : false;
- }
user_find
vérifie si un utilisateur dont le nom ou l'adresse d'email est $login
est défini dans la BD.
user_find
retourne le numéro unique de l'utilisateur ou false
en cas d'échec.
- function user_login($login, $password) {
- $user_id = user_find($login);
- if (!$user_id) {
- return false;
- }
- $r = user_get($user_id);
- if (!$r) {
- return false;
- }
- extract($r); /* user_name user_password user_mail user_created user_access user_locale user_active user_banned */
- if (!$user_active or $user_banned) {
- return false;
- }
- $password=md5($password);
- if ($password != $user_password) {
- return false;
- }
- $now=time();
- $user = array();
- $user['id'] = $user_id;
- $user['name'] = $user_name;
- $user['mail'] = $user_mail;
- $user['locale'] = $user_locale;
- $user['created'] = (int)$user_created;
- $user['access'] = $now;
- $r = user_get_role($user_id);
- $user['role'] = $r;
- $tabuser=db_prefix_table('user');
- $sql="UPDATE $tabuser SET access=FROM_UNIXTIME($now) WHERE user_id=$user_id LIMIT 1";
- db_update($sql);
- return $user;
- }
user_login
obtient avec user_find
le numéro de l'utilisateur dont le nom ou l'adresse d'email est $login
puis les propriétés du compte avec user_get
.
Si $login
n'est pas le nom ou l'adresse d'email d'un utilisateur ou si $password
ne correspond pas au mot de passe ou si le compte est inactif ou bloqué, user_login
retourne false
.
Si la connexion est acceptée, $login
note la date et l'heure dans la BD avant de retourner un tableau avec les champs id
, name
, mail
, locale
, created
et access
extraits du tableau des propriétés renvoyé par user_get
et le champ role
contenant la liste des rôles renvoyée par user_get_role
.
Remarquez que l'interface de la fonction user_login
n'a pas changé. Vous n'avez donc pas besoin de modifier le formulaire de la page d'identification.
Entrez http://localhost/cms/site15/fr/utilisateur dans la barre d'adresse de votre navigateur et vérifiez que tout fonctionne comme auparavant.
Ajoutez le fichier userhasrole.php
dans le dossier library
avec le contenu suivant :
- /cms/site15
- library
- userhasrole.php
- library
- function user_has_role($role) {
- return isset($_SESSION['user']) and $_SESSION['user']['role'] and in_array($role, $_SESSION['user']['role']);
- }
user_has_role
retourne true
si l'utilisateur est connecté et si $role
est un de ses rôles, ou false
dans le cas contraire.
Modifiez la fonction banner
qui fabrique le bloc du bandeau du site dans le fichier banner.php
dans le dossier blocks
:
- require_once 'userhasrole.php';
Charge la fonction user_has_role
.
- $menu=$contact=$login=$logout=$validate=false;
- $languages=false;
- $user_page=$contact_page=$nobody_page=$validate_page=false;
- $is_identified = user_is_identified();
- $is_writer = user_has_role('writer');
Initialise les variables $validate
et $validate_page
.
Met $is_writer
à true
si l'utilisateur a le rôle writer
, a false
dans le cas contraire.
- case 'validate':
- if ($param) {
- if ($is_writer) {
- $validate_page=$param;
- $validate=true;
- }
- }
- break;
Si 'validate'
est dans $components
, si $param
n'est pas false
et si $is_writer
est true
, assigne la valeur associée au composant à $validate_page
et met $validate
à true
.
- if ($logout or $contact) {
- $menu = view('bannermenu', $lang, compact('contact', 'contact_page', 'validate', 'validate_page', 'logout', 'nobody_page', 'login', 'user_page'));
- }
Passe les paramètres $validate
et $validate_page
à la vue.
Modifiez l'action home
dans le fichier home.php dans le dossier actions pour passer le lien sur la page d'accueil au bloc du bandeau :
- $validate=url('home', $lang);
- $banner = build('banner', $lang, compact('languages', 'contact', 'account', 'validate'));
Assigne l'URL de la page d'accueil à $validate
et passe le paramètre à banner
.
Ajoutez le lien sur le validateur à la vue du menu du bandeau dans les fichiers views/fr/bannermenu.phtml pour la version française et views/en/bannermenu.phtml pour la version en anglais :
- <?php if (isset($validate) and $validate): ?>
- <li><a id="validate" href="http://validator.w3.org/check?uri=<?php echo $base_root . $validate_page; ?>" target="validator.w3.org" title="Valider"><span>Valider</span></a></li>
- <?php endif; ?>
- <?php if (isset($validate) and $validate): ?>
- <li><a id="validate" href="http://validator.w3.org/check?uri=<?php echo $base_root . $validate_page; ?>" target="validator.w3.org" title="Validate"><span>Valider</span></a></li>
- <?php endif; ?>
Modifiez la feuille de style pour afficher un bouton à la place du lien sur le W3C :
- #bannermenu #validate {width:24px;height:24px;float:left;margin-right:6px;background:transparent url(../buttons/check.png) no-repeat center center;}
Copiez l'icône dans le dossier buttons :
- /cms/site15
- buttons
- check.png
- buttons
Entrez http://localhost/cms/site15 dans la barre d'adresse de votre navigateur.
Identifiez-vous en tant que foobar
avec le mot de passe f00bar
.
Vérifiez que le bouton de validation est bien affiché sur la page d'accueil.
Désactivez le CSS pour juger de la qualité du document généré.
Passez la souris sur le bouton pour contrôler l'URL.
Si votre site est accessible sur le web, cliquez sur le bouton pour valider le contenu de la page.
Identifiez-vous en tant que barfoo
avec le mot de passe barf00
.
Vérifiez que le bouton de validation n'est pas affiché sur la page d'accueil.
Commentaires