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 :
- Il verifie si l'utilisateur possede une identite via
Zend_Auth - Il charge l'utilisateur depuis la base via
loadMD5()(hash de l'ID) - Il recupere les ressources ACL specifiques a l'utilisateur via
Cms_Model_Users_Resources - 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
- Non authentifie : redirection vers le controleur
- 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(avecWeb4u_Acl_Cms)Web4u_Plugin_Cms_RoutesWeb4u_Plugin_Cms_LanguagesWeb4u_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/domaineWeb4u_Plugin_Languages: Gestion des langues frontWeb4u_Plugin_Front_Router: Routeur frontWeb4u_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 :
| Plugin | Role |
|---|---|
Web4u_Plugin_Cms_Auth | Validation session, enforcement ACL, redirection login, chargement des ressources utilisateur |
Web4u_Plugin_Cms_Routes | Enregistrement des routes specifiques au CMS |
Web4u_Plugin_Cms_Languages | Configuration de la locale pour le CMS |
Web4u_Plugin_Front_Routes | Routes additionnelles (utilisees par CMS et Front) |
Web4u_Plugin_Front_Host | Detection du domaine/site en mode front |
Web4u_Plugin_Front_Router | Routeur specifique au front-end |
Web4u_Plugin_Front_Shiftech | Logique specifique a la marque Shiftech |
Web4u_Plugin_Languages | Gestion des langues en mode front |
Web4u_Plugin_ErrorController | Gestion centralisee des erreurs et exceptions |
Web4u_Plugin_PageCache | Cache 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_namepermet de specifier la base de donnees cible. Le constructeur recupere automatiquement la connexion correspondante viaZend_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
cacheEnabledans 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 ShiftechWeb4u_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()etfindMultiple()utilisentgetInstance()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.