MOTEUR DE RENDU DE GRILLES DE DONNEES V1.2
Table des matières Introduction... 3 Fonctionnalités... 3 Bibliothèques requises... 3 Architecture... 4 La classe abstraite de rendu... 4 Le générateur de grille... 6 Comment est géré l intervalle de temps... 6 Comment créer un module utilisant les grilles de données facilement... 7 Page 2
Introduction Surcouche permettant de créer des grilles de données en utilisant une méthode de rendu donnée (ExtJS, HTML). Fonctionnalités Facile d utilisation : Le moteur nécessite juste la présence d un tableau de données et il va créer la grille associée. Extensible : Vous pouvez ajouter rapidement et facilement différents moteur de rendus. Bibliothèques requises ExtJS : (le navigateur internet doit avoir Javascript activé). Page 3
Architecture Il y a 5 points principaux à savoir afin de comprendre comment le moteur fonctionne et comment créer un module qui génère des grilles : La classe abstraite de rendu : ModuleGridEngine La classe demandant la génération de la grille : ModuleGrid La classe de génération de la grille : ~/admin/grider.php Comment l intervalle de temps est déterminé Comment créer un module simple utilisant les grilles de données La classe abstraite de rendu Une grille de données peut être créée en utilisant différentes technologies de rendu : ExtJS, HTML ou autres. Chaque moteur de rendu est un module ayant sa propre manière de créer une grille. Ce moteur a besoin d une couche abstraite qui permette de créer tous les types de grilles sans se soucier de la façon dont la grille est effectivement rendue. ModuleGridEngine est la classe abstraite nécessaire pour créer tous ces types de grilles. Chaque classe de rendu de grille doit hériter de la classe ModuleGridEngine et implémenter chacune de ses méthodes : hookgridengine($params, $grid): contient le code qui va appeler le moteur de rendu $params est un tableau qui contient la largeur et la hauteur de la grille $grider est la page grider.php setvalues($values): Insère le paramètre $values (tableau contenant les valeurs nécessaires au rendu de la grille) dans la grille setsize($width, $height) : Défini la taille de la grille settitle($title) : Défini le titre de la grille settotalcount($totalcount) : Défini le nombre de lignes que contiendra la grille au total ModuleGridEngine a aussi une méthode publique : getgridengines() qui permet de récupérer la liste des différents moteurs de rendus. L attribut _type de cette classe défini le type de grille à générer. Actuellement cet attribut est inutilisé mais reste présent en prévision de futures fonctionnalités. Il n y a actuellement qu une seule classe qui hérite de ModuleGridEngine : GridExtJS Page 4
La classe demandant la génération de la grille Chaque module utilisant une grille doit hériter de ModuleGrid (qui lui-même hérite de Module). Cette classe est une classe factory qui se charge de créer le bon type de grille en fonction du moteur de rendu sélectionnée dans la période de temps donnée. Cette classe a quelques attributs: $_render: classe de rendu $_title : titre de la grille $_values: tableau d éléments à afficher dans la grille $_totalcount: le nombre total d éléments à afficher $_start: index du premier élément à afficher $_limit: nombre de lignes à afficher $_sort: nom de la colonne sur laquelle effectué le tri $_direction: sens du tri (ASC/DESC) Voici les différentes méthodes de la classe : getdata(): doit être implémentée dans le module, cette méthode devrait appeler gettotalcount() en premier. create($render, $type, $width, $height, $start, $limit, $sort, $dir): créé un objet render (qui hérite de RenderAbstract) et appelle this->getdata(), render->setvalues(), render->setsize() et render->settitles();. La method create nécessite un certain nombre de paramètres : render : extjs... width : largeur de la grille height : hauteur de la grille start : nombre de lignes à afficher limit : nombre de lignes à afficher sort : nom de la colonne sur laquelle effectué le tri dir : sens du tri render() : Génère la grille. engine($params): Méthode pouvant être considérée comme l appelant. $params est un tableau dans lequel se trouvent les informations sur le type de grille que vous voulez et tout les paramètres dont celle-ci à besoin. Cette méthode devrait être appelée par les différents modules qui ont besoin d une grille. Page 5
Le générateur de grille Précédemment nous avons vu que ModuleGrid::engine() appelle le module de grille. Cependant la grille doit être dessinée avant que des données ne la remplissent. Dès lors, ModuleGrid::engine() appellera grider.php qui appellera la factory avec les différents paramètres nécessaires à l affichage de la grille. Voici les différents paramètres : $_GET[ module'] : le nom du module qui doit être dessiné $_GET[ render'] : Extjs $_GET[ type'] : non utilisé pour le moment $_GET[ option'] : quelques paramètres si le module en a l utilité $_GET[ width'] : largeur du graphique $_GET[ height'] : hauteur du graphique $_GET[ start ] : index de la première ligne à afficher $_GET[ limit ] : nombre de ligne à afficher par page $_GET[ sort ] : colonne sur laquelle s effectue le tri $_GET[ dir'] : sens du tri Le générateur de grille va créer un objet $_GET[ module ], définir la variable $_GET[ option ] dans ce module et ensuite rendra la grille grâce à ModuleGrid::create() et ModuleGrid::render(). Comment est géré l intervalle de temps Parfois un utilisateur veut pouvoir afficher des informations pour une journée précise ou bien pour une période de temps donnée. Dans Prestashop Statistics, il y a un calendrier qui aide permet à l utilisateur de choisir sa période de temps facilement et rapidement. Le calendrier remplie un témoin avec les informations de date sélectionnées : $cookie->stats_day; $cookie->stats_month; $cookie->stats_year; Grâce à ce témoin, le moteur peut savoir si l utilisateur veut les données d un jour précis ou d un mois ou même d une année. Page 6
Comment créer un module utilisant les grilles de données facilement Avant de créer un module, nous devons bien comprendre comment les hooks des modules fonctionnent. Il y a trois types d analyses : AdminStatsActivity (Activité), AdminStatsCatalog (Catalogue) and AdminStatsCommercial (Commerciale). Le module devra appartenir (être hooké à) un de ceux-ci. Lorsque l administrateur ira sur l une de ces pages (dans l onglet Stats), le module sera hooké à la frame de navigation. Le module de statistique devrait être dans un dossier dont le nom commence par stats lequel devant se situer dans ~/modules/. Le nom du fichier doit être le même que le nom du dossier le contenant. Prenons pour exemple un module qui dresse la liste des meilleurs clients. Ce module sera placé dans ~/modules/statsbestcustomers/statsbestcustomers.php Vous pouvez aussi ajouter un logo pour le module dans ~/modules/[name of the module]/logo.gif. <?php class StatsBestCustomers extends ModuleGrid private $_html = null; private $_query = null; private $_columns = null; private $_defaultsortcolumn = null; private $_emptymessage = null; private $_pagingmessage = null; function construct() $this->name = 'statsbestcustomers'; $this->tab = 'Stats'; $this->version = 1.0; $this->page = basename( FILE, '.php'); $this->_defaultsortcolumn = 'total'; $this->_emptymessage = $this->l('empty recordset returned'); $this->_pagingmessage = $this->l('displaying').' 0-1 '.$this->l('of').' 2'; $this->_columns = array( array( 'id' => 'lastname', 'header' => $this->l('lastname'), 'dataindex' => 'lastname', 'width' => 100 ), array( 'id' => 'firstname', 'header' => $this->l('firstname'), 'dataindex' => 'firstname', 'width' => 100 ), array( 'id' => 'email', 'header' => $this->l('email'), Page 7
) 'dataindex' => 'email', 'width' => 100, 'align' => "right" ), array( 'id' => 'total', 'header' => $this->l('total'), 'dataindex' => 'total', 'width' => 50, 'align' => 'right') parent:: construct(); $this->displayname = $this->l('best customers'); $this->description = $this->l('a list of the best customers'); public function install() return (parent::install() AND $this->registerhook('adminstatsmodules')); public function hookadminstatsmodules($params) $engineparams = array( 'id' => 'id_customer', 'title' => $this->displayname, 'columns' => $this->_columns, 'defaultsortcolumn' => $this->_defaultsortcolumn, 'emptymessage' => $this->_emptymessage, 'pagingmessage' => $this->_pagingmessage ); $this->_html = ' <fieldset class="width3"><legend><img src="../modules/'.$this->name.'/logo.gif" /> '.$this- >displayname.'</legend> '.ModuleGrid::engine($engineParams).' <h2 class="space">'.$this->l('my title').'</h2> <h3>'.$this->l('my subtitle').'</h3> <p class="space"> '.$this->l('my description').' <br /> </p> </fieldset>'; return $this->_html; public function gettotalcount() $result = Db::getInstance()->GetRow('SELECT COUNT(t.`id_customer`) AS totalcount FROM ( SELECT c.`id_customer` FROM `'._DB_PREFIX_.'customer` c LEFT OUTER JOIN `'._DB_PREFIX_.'orders` o ON c.`id_customer` = o.`id_customer` LEFT OUTER JOIN `'._DB_PREFIX_.'order_history` oh ON oh.`id_order` = o.`id_order` LEFT OUTER JOIN `'._DB_PREFIX_.'order_state` os ON os.`id_order_state` = oh.`id_order_state` WHERE os.`invoice` = 1 GROUP BY c.`id_customer` ) AS t'); return $result['totalcount']; public function setoption($option) Page 8
public function getdata() $this->_totalcount = $this->gettotalcount(); $this->_query = 'SELECT c.`id_customer`, c.`lastname`, c.`firstname`, c.`email`, SUM(o.`total_paid_real`) AS total FROM `'._DB_PREFIX_.'orders` o LEFT JOIN `'._DB_PREFIX_.'customer` c ON c.id_customer = o.id_customer LEFT JOIN `'._DB_PREFIX_.'order_history` oh ON oh.`id_order` = o.`id_order` LEFT JOIN `'._DB_PREFIX_.'order_state` os ON os.`id_order_state` = oh.`id_order_state` WHERE os.`invoice` = 1 GROUP BY c.`id_customer`, c.`lastname`, c.`firstname`, c.`email`'; if (Validate::IsName($this->_sort)) $this->_query.= ' ORDER BY `'.$this->_sort.'`'; if (isset($this->_direction) AND Validate::IsSortDirection($this->_direction)) $this->_query.= ' '.$this->_direction; if (($this->_start === 0 OR Validate::IsUnsignedInt($this->_start)) AND Validate::IsUnsignedInt($this- >_limit)) $this->_query.= ' LIMIT '.$this->_start.', '.($this->_limit); $this->_values = Db::getInstance()->ExecuteS($this->_query);?> Page 9