====== Créer un service Ajax ====== ===== Qu'est ce qu'un service Ajax? ===== Un service Ajax permet de collecter et retourner des données sous forme d'un fichier XML. Ce service sera appelé via une requête Ajax de façon dynamique et sera ensuite traité par du Javascript pour mettre à jour une partie d'une page de l'administration de Dotclear. C'est par exemple ce qui est utilisé pour afficher la liste des tags lors de la rédaction d'un billet. Lors du clic sur le lien __//Voir les tags//__, le service Ajax associé est appelé, retourne la liste des tags qui est ensuite affichée à l'utilisateur. ===== Pré-requis ===== Pour créer un service Ajax, il faut : * Avoir créer une fonction PHP publique et statique. C'est cette fonction qui va faire en sorte de retourner les résultats attendus * Déclarer le nouveau service auprès de Dotclear * Appeler le service et traiter les données par du javascript Pour la suite, nous supposerons que nous voulons créer un service pour afficher dynamiquement, sur la page de rédaction de billet, le temps qu'il reste avant qu'un billet programmé ne soit en ligne. ===== Création du service ===== Le nom de la fonction sera l'identifiant du service. Il faut donc le choisir de manière à ne pas le confondre avec un autre. Dans notre cas, nous l'appellerons //getPostRemainingTime// Par soucis de convention, nous allons écrire le code de nos services dans le fichier [[files#structure-generale-d-un-plugin|_services.php]] à la racine du plugin. Si vous souhaitez proposer plusieurs services, ils peuvent tous être écris ici. Pour obtenir l'information voulue, il nous faut l'id du billet en cours. Nous allons le récupérer grâce au paramètre **id** qui sera passé dans l'url. Il nous faut également l'objet $core pour récupérer le billet associé à cet id. Pour cela nous allons utiliser les paramètres de la méthode définie plus tôt : $id = isset($get['id']) ? $get['id'] : null; $rs = $core->blog->getPost(array('post_id' => $id)); $date = strtotime($rs->post_dt); # Différence en secondes entre maintenant et la date de publication $delta = $date - time(); Maintenant que nous avons l'information voulue, il est possible de la transformer pour qu'elle adopte le format de votre choix. On peut par exemple imaginer passer en paramètre dans l'url le format souhaité et convertir le $delta en fonction. Il faut ensuite retourner cette valeur sous forme XML. Pour cela Dotclear possède une classe spéciale //xmlTags// permettant de créer très simplement ce type de structure. Par convention, nos réponses seront encapsulées dans un noeud //rsp// : # Création de l'enveloppe $rsp = new xmlTag(); # Ajout du noeud "value" dans le noeud "rsp" contenant la variable $delta $rsp->value($delta); # On retourne le tout return $rsp; Le fichier XML généré sera donc de cette forme : 65765432456 Il est bien sur possible d'ajouter des attribut aux noeuds, faire des combinaisons. Pour plus de détails, vous pouvez regardez les différents plugins utilisants ce système ou Dotclear lui même ===== Déclaration du service ===== Dotclear possède son propre //dispacher// générique de service au travers du fichier //services.php//. Pour l'utiliser, il faut déclarer le service auprès de Dotclear par la méthode suivante : $core->rest->addFunction('getPostRemainingTime',array('myPluginRestMethods','getPostRemainingTime')); Ce code est a placer dans le fichier [[files#structure-generale-d-un-plugin|_prepend.php]] du plugin. Maintenant que notre service est déclaré, il est accessible via l'URL **//ADMIN_URL/services.php?f=getPostRemainingTime&id=1//**. Testez par vous-même si il fonctionne correctement, si il retourne les bonnes valeurs avant de passer à la suite. Il ne faut pas oublier de charger le fichier _service.php **avant** la déclaration du service. ===== Traitement des données ===== C'est maintenant que nous allons aborder la partie //Ajax// du service. Le code javascript décrit ici va permettre d'aller interroger le service et d'afficher la réponse sur la page sans rechargement de celle-ci. Nous allons utiliser //jQuery// fourni par défaut avec Dotclear $(function(){ $('#remaining-time').click(function(){ $.get('services.php', {f: 'getPostRemainingTime',id: $('#id').val()}, function(rsp){ $('#remaining-time-display').html('

Temps restant avant la publication :'+$(rsp).find('value').text()+'

'); }); }); });
Lors du clic sur l'élément ayant pour id **remaining-time**, une requête est faite auprès du service **getPostRemainingTime** en passant en paramètre le service que l'on veut utiliser + l'id du billet en cours récupéré via le champ caché du formulaire ayant pour id **id**. La réponse est alors affiché dans le conteneur ayant pour id **remaining-time-display**. ===== Gestion des erreurs ===== Le code ci-dessus ne prend pas en compte les erreurs qui peuvent survenir lors de l'interrogation du service. L'avantage d'être passé par la classe //xmlTags// pour générer le fichier XML est que si une exception est levée, l'XML résultant sera de la forme : Message d'exception Par exemple pour notre service, si aucun id n'est passé en paramètre, on va lever une exception afin d'en informer l'utilisateur $id = isset($_GET['id']) ? $_GET['id'] : null; if ($id === null) { throw new Exception(__('No ID given')); } Il est donc très facile d'intercepter ce type d'XML pour le traiter différemment. Par exemple : $(function(){ $('#remaining-time').click(function(){ $.get('services.php', {f: 'getPostRemainingTime',id: $('#id').val()}, function(data){ var rsp = $(data).children('rsp')[0]; if (rsp.attributes[0].value == 'ok') { $('#remaining-time-display').html('

Temps restant avant la publication :'+$(rsp).find('value').text()+'

'); } else { alert($(rsp).find('message').text()); } }); }); });
Ce code informera l'utilisateur via un //alert()// qu'une erreur est survenue lors de la requête ou du traitement par le service.