Gestion utilisateur/membre en version objet !

Gestion utilisateur/membre en version objet !

Description

Bon, tout le monde sait faire de la gestion de membres via des fonctions style ( if is_membre() ) qui testent si le niveau du membre est bien celui qu'on attend.
Eh bin, je vais faire la même chose, mais à ceci près que je vais le faire en orienté objet.
Je ne marque aucun code à l'intérieur, seulement les grandes lignes !

Comment faire ça en objet ?

Voici le découpage qu'on peut établir entre un visiteur quelconque, un membre et un admin par exemple :

Si on analyse le schéma (vite fait) du haut, on s'aperçoit qu'être Membre ou Admin, on a quand même quelque chose en commun avec le fait d'être Visiteur. J'aurais pu pousser la chose plus loin comme ça :
Visiteur --> Membre --> Admin.

Qu'est ce que cela donne en objet alors...

Une classe abstraite User qui va contenir les infos d'un Visiteur standard.
Une classe héritière de User que je vais appeler Visiteur qui va ajouter des composantes de base d'un Visiteur standard (car on peut avoir plusieurs types de Visiteurs si on veut).

Une autre classe abstraite qui hérite de User, que je vais appeler MemberUser qui va prendre les infos initiales d'un Visiteur standard en lui rajoutant le fait que ce soit un membre qui est maintenant logué.
Une classe héritière de MemberUser que je vais appeler Membre qui va ajouter des composantes d'un membre (car on peut aussi avoir plusieurs types de membres (genre Membre standard, Membre Club, Membre VIP etc...)

Une autre classe abstraite qui hérite de MemberUser (ou de User), que je vais appeler AdminUser qui va prendre les infos initiales d'un Visiteur standard en lui rajoutant le fait que c'est un membre de type Admin qui vient de se loguer.
Une classe héritière de AdminUser qui va ajouter des composantes que seul un Admin peut avoir accès (mais on peut aussi avoir plusieurs types d'admins spécifiques (admin niveau DIEU, admin bas niveau etc...)

Donc en relation objet, ça donne ça :

Voila la hiérarchie des classes.
Maintenant rentrons plus dans le détail.
Nous allons donner un niveau de priorité pour chacun des personnes venant sur notre site.
0 correspondra à un Visiteur, 1 à un membre, 4 à un admin.

Donc, dans la classe abstraite User, je vais définir le niveau de mon visiteur à 0.

abstract class User {
  protected $level;
   public function __construct() {
     $this->level = 0;
   }
}

Pareil pour les autres :

abstract class MemberUser extends User {
  public function __construct() { // Surcharge du constructeur
    $this->level = 1;
}
abstract class AdminUser extends MemberUser {
  public function __construct() {
   $this->level = 4;
 }
}

Voila, on a défini nos bases de départ. Que reste t'il ensuite à faire ? Réussir à identifier notre visiteur pour savoir si il est membre ou admin ou simplement un visiteur. Il suffit pour cela d'utiliser les sessions. Lorsque votre visiteur se logue, il suffira de remplir la superglobal $_SESSION[] et lui dire qu'il est logué. De plus, il faudra s'assurer de garder les logins/levels de votre membre lors de l'identification pour pouvoir charger la bonne classe.

Et comment je peux utiliser ça ensuite ? Il faut encore rajouter quelque chose... Et oui, c'est pas tout de faire 40 classes si on peut pas les différencier lors de l'utilisation. Car :
$User = new Member;
ou
$User = new Visiteur;

Bah le script il sait pas trop faire la différence :p Donc il va falloir charger 3 méthodes en plus. Pour faire cela, je vais utiliser les interfaces qui sont arrivées grâce à PHP5.
Voici donc l'interface (très basique) que j'ai repris d'un membre de PHPCS d'une source il y a fort longtemps.

interface user_level {
  public function IsMember();
  public function IsAdmin();
}

Et voila c'est tout ! Il suffit juste de mettre l'interface dans les classes abstraites, ce qui évitera de recopier le code dans les classes héritières !
Et donc le modèle final sera de ce style : ( j'ai ajouté des méthodes histoire de bien démarquer les classes)

abstract class User implements user_level {
  protected $level;
   public function __construct() {
     $this->level = 0;
   }
   public function IsMember() {
    return FALSE;
   }
   public function IsAdmin() {
    return FALSE;
   }
  
}
class Visiteur extends User {

   public function __construct() {
    parent::__construct();
   }

   public function login($login, $password); // Tente un login.

   public function checklogin($login); // Pour vérifier si personne n'utilise ce login

}

abstract class MemberUser extends User implements user_level {
 
 protected $login;
 protected $email;

  public function __construct() { // Surcharge du constructeur
    $this->level = 1;
  }
   public function IsMember() {
    return TRUE;
   }
   public function IsAdmin() {
    return FALSE;
   }
}

class Member extends MemberUser {

  public function __construct() {
    parent::__construct();
  }

 public function modifieInfos(); // Permet de modifier ces infos dans la BDD
 public function recupererInfos(); // Permet de récupérer des infos

}

abstract class AdminUser extends MemberUser implements user_level {
  public function __construct() {
   $this->level = 4;
 }
   public function IsMember() {
    return TRUE;
   }
   public function IsAdmin() {
    return TRUE;
   }
}

class Admin extends AdminUser {

 public function __construct() {
  parent::__construct();
 }

 public function ChangeSiteInfo(); // permet de changer les infos du site

}
?>

Bref, les possibilités sont immenses après.
Il suffit après d'avoir instancier la bonne classe de faire un

if($User->IsMember()) 

et hop, c'est automatique ! Plus besoin de charger à la main des fonctions spécifiques car tout est dans les classes !

Et si un jour je veux créer un type de membre spécifique ? Bah rien de plus facile, je ré-utilise ce que j'ai déja fait :

class MembreSpecifique extends MembreUser {

  public function __construct() {
    $this->level = 2; // Au lieu de 1;
  }

}

Et voila, vous avez votre nouveau type de membre avec des accès totalement nouveau. Si vous souhaitez simplement utiliser les mêmes accès qu'un membre standart mais en lui rajoutant des choses, il suffit d'hériter la classe de membre standard Member comme ca :

class MembreSpecifique extends Member {

 public function __construct() {
   $this->level = 2; // Je surcharge la méthode pour éviter de le mettre à 1
 }

}

Comme quoi, c'est tout simple. Après niveau vitesse, c'est sur que c'est un peu plus lent. Mais imaginez le fait que vous développiez votre propre site d'un client, et qu'un jour ce même client vous demande de rajouter 2 accès membres avec fonctions totalement différentes et 3 accès admins avec certains pouvoir que n'ont pas les autres... je vous laisse le soin de tout coder de A à Z ! Je gagne presque 50% de mon temps avec la POO.

Voila les grandes lignes de la POO du coté de la gestion de membre... Si vous n'avez pas tout compris, posez des questions je suis la pour ça.

Ce document intitulé « Gestion utilisateur/membre en version objet ! » issu de CodeS SourceS (codes-sources.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.
Rejoignez-nous