Aller au contenu principal

Architecture Generale

Vue d'ensemble

CMS-V1 est un CMS automobile (chiptuning/ECU) construit sur le pattern MVC via Zend Framework 1.x avec PHP 7.0.33. L'application dessert deux marques : OLSx et Shiftech.

La couche Web4u (library/Web4u/) constitue une librairie d'abstraction personnalisee au-dessus de Zend Framework. Elle fournit les plugins middleware, l'acces multi-base de donnees, le systeme ACL, la gestion du cache, les vues enrichies et les controleurs de base. Toute l'architecture repose sur cette couche intermediaire entre le code metier (modules CMS/Front) et le framework Zend sous-jacent.

Flux d'une requete HTTP

Le cycle de vie complet d'une requete HTTP dans CMS-V1 suit le parcours suivant :

Detail du plugin Auth

Le plugin Web4u_Plugin_Cms_Auth est le premier middleware execute. Son role est critique :

  1. Il verifie si l'utilisateur possede une identite via Zend_Auth
  2. Il charge l'utilisateur depuis la base via loadMD5() (hash de l'ID)
  3. Il recupere les ressources ACL specifiques a l'utilisateur via Cms_Model_Users_Resources
  4. Si l'utilisateur n'a pas les droits :
    • Non authentifie : redirection vers le controleur login
    • Authentifie sans droits : redirection vers la page d'erreur de droits
    • Requete AJAX : reponse JSON avec message d'erreur
  5. Il gere egalement la fonctionnalite "se souvenir de moi" (session de 30 jours)

Separation des modules

L'application est divisee en trois modules principaux, tous enregistres dans le Bootstrap :

Module CMS (application/modules/cms/)

C'est le module principal - l'interface d'administration. Il contient :

  • controllers/ : Plus de 100 controleurs, convention de nommage Cms_{Domain}Controller
  • models/ : Plus de 200 modeles heritant de Cms_Model_Abstract
  • views/scripts/ : Templates PHTML organises par nom de controleur
  • forms/ : Classes de formulaires Zend heritant de Web4u_Form_Admin
  • services/ : 18 classes de service pour les integrations API et la logique metier

Quand APPLICATION_MODULE == 'cms', le Bootstrap enregistre les plugins specifiques au CMS :

  • Web4u_Plugin_Cms_Auth (avec Web4u_Acl_Cms)
  • Web4u_Plugin_Cms_Routes
  • Web4u_Plugin_Cms_Languages
  • Web4u_Plugin_Front_Routes

Module Front (application/modules/front/)

Le module front-end public, avec ses propres controleurs et modeles. Quand APPLICATION_MODULE == 'front', les plugins enregistres sont differents :

  • Web4u_Plugin_Front_Host : Detection du site/domaine
  • Web4u_Plugin_Languages : Gestion des langues front
  • Web4u_Plugin_Front_Router : Routeur front
  • Web4u_Plugin_Front_Shiftech : Logique specifique Shiftech

Module WWW (application/modules/www/)

Un module additionnel enregistre dans les repertoires de controleurs.

Couche partagee

Les trois modules partagent :

  • Le meme Bootstrap (application/Bootstrap.php)
  • La librairie Web4u (library/Web4u/)
  • La configuration globale (application/configs/application.ini)
  • Les traductions (application/locale/default/)

Role de la librairie Web4u

Le repertoire library/Web4u/ constitue une couche d'abstraction personnalisee au-dessus de Zend Framework. Elle centralise les fonctionnalites transversales utilisees par tous les modules.

Web4u_Plugin_* -- Plugins middleware

Les plugins s'enregistrent dans le Front Controller et s'executent a differentes etapes du dispatch :

PluginRole
Web4u_Plugin_Cms_AuthValidation session, enforcement ACL, redirection login, chargement des ressources utilisateur
Web4u_Plugin_Cms_RoutesEnregistrement des routes specifiques au CMS
Web4u_Plugin_Cms_LanguagesConfiguration de la locale pour le CMS
Web4u_Plugin_Front_RoutesRoutes additionnelles (utilisees par CMS et Front)
Web4u_Plugin_Front_HostDetection du domaine/site en mode front
Web4u_Plugin_Front_RouterRouteur specifique au front-end
Web4u_Plugin_Front_ShiftechLogique specifique a la marque Shiftech
Web4u_Plugin_LanguagesGestion des langues en mode front
Web4u_Plugin_ErrorControllerGestion centralisee des erreurs et exceptions
Web4u_Plugin_PageCacheCache de pages completes

Web4u_Db_Table_Abstract -- Table DB etendue avec support multi-base

Classe de base pour tous les modeles. Etend Zend_Db_Table_Abstract avec :

  • Support multi-base : La propriete $_db_name permet de specifier la base de donnees cible. Le constructeur recupere automatiquement la connexion correspondante via Zend_Registry::get('multidb')
  • Pattern Singleton : Methode statique getInstance() (voir section dediee ci-dessous)
  • Chargement par ID : load($iddb), findOne($iddb), findMultiple($key, $ids)
  • Obfuscation d'ID : loadMD5($iddb), addMD5WhereClause() (voir section dediee)
  • CRUD etendu : save($data) gere automatiquement insert/update, truncate() vide une table
  • Cache automatique : Invalidation du cache sur insert/update/delete via Web4u_Cache::remove()
  • Collections : getCollection(), getCollectionCached(), getCollectionSelect() pour les requetes paginables et filtrables

Web4u_Acl_Cms -- ACL base sur les roles

Systeme de controle d'acces avec deux roles de base :

  • visitor : Utilisateur non authentifie
  • user : Utilisateur authentifie

Les ressources ACL (140+) sont definies dans application/configs/cms/acl.ini. Les permissions specifiques par utilisateur sont chargees dynamiquement depuis la base via Cms_Model_Users_Resources. L'ACL supporte egalement l'autorisation au niveau de la ligne (row-level) grace a l'interface Zend_Acl_Resource_Interface implementee sur les modeles.

Web4u_Cache -- Abstraction cache

Systeme de cache unifie avec fallback automatique selon les extensions disponibles :

  • Duree de vie par defaut : 2 heures (7200 secondes)
  • Serialisation automatique des donnees
  • Tagging par module (APPLICATION_MODULE . '_module')
  • Respect du flag cacheEnable dans la configuration
  • Utilise pour le cache des metadata DB (Zend_Db_Table_Abstract::setDefaultMetadataCache) et les collections de modeles

Web4u_View -- Vue custom avec helpers ACL

Classe de vue personnalisee qui remplace Zend_View. Fournit des helpers de vue integrant la verification ACL, permettant d'afficher ou masquer des elements d'interface en fonction des droits de l'utilisateur connecte.

Web4u_Mail_* -- Providers email

Abstraction pour l'envoi d'emails avec support de plusieurs providers :

  • Web4u_Mail_Mandrill : Envoi via l'API Mandrill (Mailchimp)
  • Web4u_Mail_Shiftech : Provider specifique Shiftech
  • Web4u_Mail_Olsx : Provider specifique OLSx

Web4u_Controller_Admin_Cms -- Controleur de base CMS

Classe de base pour tous les controleurs CMS. Herite de Web4u_Controller_Admin et definit :

  • Le titre du site par defaut ('Admin')
  • Le prefixe de namespace des classes ('Cms_')
  • Les feuilles de style CSS a charger (30+ fichiers CSS)
  • Les scripts JavaScript inline (jQuery 1.9.1, jQuery UI, Bootstrap, etc.)

Tous les controleurs CMS heritent de cette classe, ce qui garantit un layout et un chargement d'assets coherent.

Web4u_Form_Admin -- Formulaire de base admin

Classe de formulaire heritant de Web4u_Form, elle fournit :

  • Les decorateurs par defaut pour le rendu Bootstrap (classes form-horizontal, controls, control-label)
  • Support des galeries media, pieces jointes et liens
  • Decorateurs personnalises pour les champs de saisie avec affichage des erreurs via tooltips

Pattern Singleton des Modeles

Web4u_Db_Table_Abstract implemente un pattern Singleton via la methode statique getInstance(). Ce pattern evite de reinstancier les modeles a chaque utilisation :

class Web4u_Db_Table_Abstract extends Zend_Db_Table_Abstract
{
protected $_db_name;
static protected $instances = array();

static protected function getInstance() {
$className = get_called_class();

if (!isset(self::$instances[$className])) {
self::$instances[$className] = new $className();
}

return self::$instances[$className];
}
}

Fonctionnement :

  • Chaque sous-classe maintient une instance unique dans le tableau statique $instances, indexee par le nom de la classe
  • get_called_class() assure la resolution tardive (late static binding) pour que chaque modele enfant obtienne sa propre instance
  • Les methodes statiques comme findOne() et findMultiple() utilisent getInstance() en interne, ce qui permet des appels concis : Cms_Model_Users::findOne($iddb)

Support multi-base via $_db_name

La propriete $_db_name permet a chaque modele de cibler une base de donnees specifique. Le constructeur recupere automatiquement l'adaptateur correspondant :

public function __construct($config = array())
{
if ($this->_db_name) {
$multidb = Zend_Registry::get('multidb');
$this->_db = $multidb->getDb($this->_db_name);
}
parent::__construct($config);
}

Les trois bases de donnees disponibles sont :

  • shiftech : Donnees produit principales (vehicules, tuning, utilisateurs)
  • shiftech_cms (alias cms) : Donnees specifiques au CMS
  • olsx : Donnees de la plateforme legacy OLSx

La classe intermediaire Cms_Model_Abstract definit $_db_name = 'cms' par defaut, donc tous les modeles CMS pointent vers la base shiftech_cms sauf s'ils redefinissent explicitement cette propriete.

Obfuscation d'ID par hashage MD5

Le systeme utilise un mecanisme d'obfuscation des identifiants primaires dans les URLs et parametres de requete. Au lieu de passer l'ID brut (ex: 42), un hash MD5 est utilise :

MD5(CONCAT(cle_primaire, sel, nom_table))
  • Le sel est stocke dans la configuration du module (Module_Config->salt)
  • Le nom de la table est ajoute pour eviter les collisions entre tables
  • Le hash resultant (32 caracteres hexadecimaux) est utilise dans les URLs comme parametre iddb

La methode loadMD5($iddb) reconstruit la clause WHERE en SQL pour retrouver la ligne correspondante. La methode exists() detecte automatiquement si l'identifiant est un hash MD5 (longueur 32) ou un ID brut pour adapter sa requete.

Ce mecanisme assure que les identifiants internes de la base de donnees ne sont jamais exposes directement dans les URLs du CMS.