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.

Créer un premier 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 jelix.php --actu.org 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="iso-8859-1"?>
<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="autoincrement"/>
    <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à.

Lister les news

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');
        $rep->title = 'Dernières actualités';
        $rep->bodyTpl = 'listenews';
 
        $fact = jDao::get('news~news');
        $liste = $fact->findAll();
 
        $rep->body->assign('liste', $liste);
 
        return $rep;
    }

Comme il a été dit précédemment, la propriété body de jResponseHtml est un objet jTpl (moteur de template). On lui donne la liste dans une variable de template “liste”, pour pouvoir l'utiliser dans le template. Celui-ci devient donc :

<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/jelix/actu.org/www/index.php?module=news&action=default:index

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 dbprofils.ini.php.