Table des matières

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 :

Note :

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

<?php
 
class myPluginRestMethods
{
	public static function getPostRemainingTime($core,$get)
	{
 
	}
}
 
?>

Note :

Par soucis de convention, nous allons écrire le code de nos services dans le fichier _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 :

<rsp status="ok">
	<value>65765432456</value>
</rsp>

Note :

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 _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.

Note :

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('<p>Temps restant avant la publication :'+$(rsp).find('value').text()+'</p>');
		});
	});
});

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 :

<rsp status="err">
	<message>Message d'exception</message>
</rsp>

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('<p>Temps restant avant la publication :'+$(rsp).find('value').text()+'</p>');
			} 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.