Jelix propose un système de mapping relationnel objet, jDao, basé sur le pattern DAO.
Le pattern DAO se base sur deux types d'objets : un objet “record”, contenant des données (représentant un enregistrement), et un objet “factory”, qui permet de récupérer des listes de records, ou de créer, sauver, effacer des records.
Concrètement avec jDao, un fichier XML DAO vous permet de définir un record et une factory, qui agiront sur une ou plusieurs tables en même temps. Vous y définissez donc le mapping : quel champs de la table ira dans quelle propriété du record, ainsi que le type de donnée, les clés, sur quelles tables s'effectue le mapping, selon quelles jointures, etc…
À partir de ce fichier, jDao génère à la volée deux classes basées respectivement sur jDaoRecordBase et jDaoFactoryBase (qui sont stockées dans un fichier PHP dans le cache de Jelix), dans lesquelles sont fournies toutes les méthodes et requêtes SQL principales en dur. En effet, contrairement à d'autres systèmes de mapping, les requêtes SQL sont donc générées une seule fois, et non pas dynamiquement à chaque appel de pages. Cela permet de meilleures performances.
Dans le fichier XML de DAO, vous pouvez aussi définir vos propres méthodes d'accès aux données, et jDao générera les méthodes et requêtes correspondantes dans la factory du DAO.
Vous disposez d'une commande pour créer un fichier DAO, basé sur une table existante. Elle a la syntaxe suivante :
createdao //nom_module// //nom_dao// //nom_table//
Nous avons précédemment créé une table news, et nous allons créer un DAO appelé “news”, dans le module “news”. Tapez donc :
php cmd.php createdao news news news
Vous obtenez alors un fichier actu.org/modules/news/daos/news.dao.xml
. (vous pouvez bien sûr aussi le créer à la main).
Son contenu est le suivant :
<?xml version="1.0" encoding="utf-8"?> <dao xmlns="http://jelix.org/ns/dao/1.0"> <datasources> <primarytable name="news" realname="news" primarykey="id_news" /> </datasources> <record> <property name="id_news" fieldname="id_news" datatype="int" autoincrement="true"/> <property name="sujet" fieldname="sujet" datatype="string"/> <property name="texte" fieldname="texte" datatype="string"/> <property name="news_date" fieldname="news_date" datatype="date"/> </record> </dao>
C'est un contenu très simple, et bien sûr il existe d'autres attributs et balises pour l'enrichir et le personnaliser. Pour l'instant, nous allons nous en tenir là.
Nous allons maintenant utiliser ce DAO pour récupérer la liste des news. Nous allons donc demander à jDao la factory de ce DAO, et appeler sa méthode findAll()
prédéfinie. Pour ce faire, on fait appel à jDao::get()
:
$fact = jDao::get('news~news'); $liste = $fact->findAll();
En paramètre de jDao::get()
, on donne le sélecteur du DAO (qui a pour nom “news”, et dans le module news) : “news~news”. Elle nous renvoie la factory de ce DAO. et en appelant la méthode findAll()
, on récupère toute la liste des records.
En fait, il ne s'agit pas vraiment d'une liste, mais d'un objet jDbResultSet
, qui est un itérateur sur les résultats de la requête correspondante.
Intégrons ça dans notre contrôleur :
function index() { $rep = $this->getResponse('html'); // on définit un titre de page $rep->title = 'Dernières actualités'; // creation d'un objet template pour le contenu spécifique $tpl = new jTpl(); $fact = jDao::get('news~news'); $liste = $fact->findAll(); // on assigne la liste des news dans notre template spécifique $tpl->assign('liste', $liste); // assignation du resultat du template listenews à la variable $MAIN $rep->body->assign('MAIN', $tpl->fetch('listenews')); return $rep; }
On donne la liste des enregistrement à notre template spécifique à l'action, via une variable de template grâce à la méthode assign
. Modifions notre template spécifique listenews.tpl
:
<h2>Dernières actualités</h2> <table> {foreach $liste as $news} <tr> <td>{$news->sujet}</td><td>{$news->news_date}</td> </tr> {/foreach} </table>
Vous découvrez ici le tag de template {foreach}, qui fonctionne exactement comme le foreach php. Pour afficher des valeurs, il suffit de mettre le nom de la variable de template précédé par un $, et encadré par des accolades.
La liste renvoyée par findAll
est une liste d'objets record, tels qu'ils sont définis dans le fichier XML. Ils ont donc les propriétés id_news
, sujet
, texte
et news_date
.
Affichez à nouveau la page avec :
http://localhost/actu.org/www/index.php/news/
Vous devriez voir la liste des news.
Remarque : si vous avez des problèmes d'affichage des accents, essayez de mettre force_encoding=on
dans le fichier profiles.ini.php
.