(version de Jelix supportée 1.1.x)
Voici la seconde partie, de l'article Création de module génériques (1/2).
Le premier article détaillait le moyen d'ajouter facilement des Tags à ses discussions, lors de la création/modification d'une discussion.
Ici, je dispose d'une page listant des discussions et j'ai envi que les visiteurs/membres du site puissent donner une appréciation (via une note) sur le contenu de ce qu'ils lisent.
Ce article repose sur le code du module HfnuRates de l'application HaveFnuBB
Rappel
Aparté
Une fois un formulaire enregistré, l'utilisateur est redirigé sur la page présentant la discussion ajoutée.
C'est classique !
Classique oui, mais cela est possible car tout est traité par le même module qui “sait” d'où vient l'utilisateur et où l'envoyer.
La difficulté qui se pose ici est :
je suis sur une page présentant la liste des discussions (d'un module forum), et à l'intérieure de celle-ci
j'utilise un autre module
(HfnuRates) qui ne sait pas où renvoyer l'utilisateur
une fois les données soumises.
On utilisera donc une astuce pour y remédier.
Fin Aparté
J'ouvre donc le template de ma page discussions et ajoute ce qui suit où bon me semble :
{zone 'hfnurates~rates', array('id_source'=>$id_posts' 'source'=>'posts', 'return_url'=>'havefnubb~posts:list', 'return_url_param'=>array('id_posts'=>$id_posts)) }
'id_source'
= l'id de la table du module “utilisateur”'source'
= une chaine permettant d'identifier la provenance des donnéesreturn_url
qui contient le chemin “jelix” du module “utilisateur”return_url_param
contient des params nécessaires pour retourner au module “utilisateur”Donc, dans le template du module “forum”, on ajoutera les paramètres de “provenance” pour qu'ensuite le module HfnuRates puisse renvoyer l'utilisateur sur la page d'où il venait !
Dans la zone je récupère donc les paramètres passés, pour les assigner dans le template de la zone 'zone.rates'.
Toujours dans la zone, j'en profite pour récupérer les “notes” pour cette discussion et calculer la moyenne et l'afficher dans la zone 'zone.rates'
zone ratesZone
class ratesZone extends jZone { protected $_tplname='zone.rates'; protected function _prepareTpl(){ //get the params $id_source = $this->intParam('id_source'); $source = $this->param('source'); $return_url = $this->param('return_url'); $return_url_params = $this->param('return_url_params'); // get the rates from the class $rates = jClasses::getService('hfnurates~rates'); $result = $rates->getTotalRatesBySource($id_source,$source); $resultText = jLocale::get('hfnurates~main.total.of.rates') . ':'.$result->total_rates . ' ' . jLocale::get('hfnurates~main.rate') .':'. $result->avg_level; //let's assign the var to the template $this->_tpl->assign('id_source',$id_source); $this->_tpl->assign('source',$source); $this->_tpl->assign('result',$resultText); $this->_tpl->assign('return_url',$return_url); $this->_tpl->assign('return_url_params',$return_url_params); } }
le template de la zone ressemble à ceci :
<div class="rates-result">{$result}</div> <form id="form{$id_source}" action="{formurl 'hfnurates~default:rate_it'}" method="post"> <div class="post-rates"> <input type="hidden" value="{$id_source}" id="id_source" name="id_source"/> <input type="hidden" value="{$source}" id="source" name="source"/> <input type="hidden" value="{$return_url}" name="return_url" /> {foreach $return_url_params as $key => $value} <input type="hidden" value="{$value}" name="return_url_params[{$key}]" /> {/foreach} [...ici le code HTML affichant le radiobutton "star1"... ] </div> </form> <div id="post-rates-msg"></div>
on verra plus bas que la méthode rate_it du controleur default du module hfnurates exploitera les parms return_url* pour renvoyer l'utilisateur sur la bonne page.
La table du module “générique”, ici HfnuRates doit stocker les données le reliant au module “utilisateur”, ici “forum” :
CREATE TABLE `hf_rates` ( `id_user` INT NOT NULL , `id_source` INT NOT NULL , `source` VARCHAR(40) NOT NULL, `ip` VARCHAR(80) NOT NULL, level FLOAT NOT NULL , INDEX ( `id_user` ), INDEX ( `id_source` ), INDEX ( `source` ), PRIMARY KEY rates_id (id_user,id_source,SOURCE) );
la colonne “id_source” contiendra l'id de la discussion, et “source”, la chaine “posts”. Le reste de la table est spécifique au module HfnuRates et la clé primaire permet à un même utilisateur de mettre à jour sa note si bon lui semble.
class rates { // get the Rate of a given source and ID function getTotalRatesBySource($id_source, $source) { $cnx = jDb::getConnection(); $strQuery = 'SELECT COUNT(*) as total_rates, SUM(level) as total_level, AVG(level) as avg_level ' . ' FROM '.$cnx->prefixTable('rates'). " WHERE id_source = '".$id_source."' AND source='".addslashes($source). "' GROUP BY id_source"; $rs = $cnx->query($strQuery); $total = $rs->fetch(); return $total; } // save the Rate to a given source and ID function saveRatesBySource($id_source, $source, $rate) { [...] } }
class defaultCtrl extends jController { function rate_it() { //info about the "source" from where the datas come from $id_source = $this->Intaram('id_source'); $source = (string) $this->param('source'); // the star $rate = $this->floatParam('star1'); $rates = jClasses::getService('hfnurates~rates'); $result = $rates->saveRatesBySource($id_source,$source,$rate); $rep = $this->getResponse('redirect'); $rep->action= (string) $this->param('return_url'); $rep->params= (array) $this->param('return_url_params'); return $rep; } function rate_ajax_it() { //info about the "source" from where the datas come from $id_source = $this->intParam('id_source'); $source = (string) $this->param('source'); //check if the cancel button was selected if ($id_source == 0 or $source == '') return; $rate = $this->floatParam('star1'); $rates = jClasses::getService('hfnurates~rates'); $rates->saveRatesBySource($id_source,$source,$rate); $result = $rates->getTotalRatesBySource($id_source,$source); // used for Ajax response $rep = $this->getResponse('htmlfragment'); $rep->addContent( jLocale::get('hfnurates~main.total.of.rates').':'.$result->total_rates . ' ' . jLocale::get('hfnurates~main.rate') .':'. $result->avg_level ); return $rep; } }
Pour obtenir un module, on ne peut plus générique, la zone est l'arme absolue puisqu'elle embarque toute la mécanique nécessaire aux échanges entre les modules concernés.
Pour résumer ce qu'il faut pour qu'un module qui soit ré-exploitable à souhait :
Revenir sur Création de module génériques (1/2)