Finalement le javascript c'est sympa
Qui eut-cru que je dirais ça un jour ? Pas moi en tout cas. Dans le cadre du développement de l'application que je suis en train de développer (habile tournure de phrase pour ne pas en dévoiler la nature), j'ai trouvé deux applications concrètement utiles au javascript. Toutes deux gravitant autour de XML-RPC (d'ailleurs à la demande générale de xethorn je posterai surement bientôt un article sur XML-RPC).
Vérification de formulaire
Ouais bon ok, voilà une problèmatique vieille comme les CGI. La vérification de base a déjà été largement traitée sur openweb, donc je n'en parlerais pas. Je vais à la place me consacrer à un détail qui a son importance, la vérification des champs UNIQUE. L'exemple qui vient tout de suite à l'esprit est bien sur celui de la gestion d'utilisateurs, dans laquelle les champs login et mail (par exemple) doivent être uniques. La solution qui vient elle aussi la première à l'esprit, c'est de faire la vérification après la soumission du formulaire, et de, au choix, faire un history.back(); en javascript (solution que j'ai adopté dans un premier temps, permettant de garder le formulaire rempli), regénérer le formulaire prérempli en entier (lourd pour le développeur) ou rediriger vers le formulaire vide (chiant pour l'utilisateur).
La solution que j'utilise finalement est basée sur XML-RPC et fonctionne comme un charme. C'est simple, à la soumission du formulaire, un appel XML-RPC est executé pour savoir si le login et le mail existent déjà dans la base de données, il ne reste plus qu'a valider ou non la soumission du formulaire en fonction de la réponse du serveur. Concrétement, ça donne ça (je snip les require en tout genre):
Formulaire
<form method="post" action="foo.php" onsubmit="javascript:return chkForm();"> <p> <label for="login">Login</label> <input type="text" name="login" id="login" /> </p> <p><input type="submit" /></p> </form>
Javascript
var xmlrpc = importModule('xmlrpc');
var service = new xmlrpc.ServiceProxy('http://example.com/xmlrpc/server');
function chkForm() {
message = '';
login = document.getElementById('login').value;
if (login == '') {
message += "- Vous devez spécifier un login.
";
} else {
try {
login = document.getElementById('login').value;
var result = service.user.loginExists(login);
if (result) {
message += "- L'utilisateur '" + login + "' existe déjà.
";
}
} catch (e) {
alert('Impossible de contacter le serveur xml-rpc: ' + e);
}
}
if (message != '') {
alert("La modification n'a pas pu être validée pour les raisons suivantes:
" + message);
return false;
} else {
return true;
}
}
PHP
server xml-rpc
$server = & new IXR_IntrospectionServer();
$server->addCallback('user.loginExists', 'loginExists', array('int', 'string'), 'Returns true if the specified login exists in database');
$server->serve();
fonction loginExists
function loginExists($login) {
require_once(PATH_ROOT . '/libs/UserFinder.php');
$finder = & new UserFinder();
$finder->setStatus(STATUS_INACTIVE);
$user = & $finder->findByLogin($login);
return !is_null($user);
}
Voilà voilà. Bon évidemment je ne suis pas une bête de javascript, donc le code n'est surement ce qui se fait de mieux dans le genre, mais l'idée est là. Je tiens quand même à parler du coup des deux librairies que j'utilise. Le client javascript utilise la librairie jsolait, et le serveur PHP utilise la librairie Incutio (la même que celle de dotclear). J'ai choisi Incutio pour le serveur parcequ'elle gère l'introspection, et que c'est très pratique, et jsolait, ma foi, parceque c'est la première que j'ai trouvé. Ces deux librairies sont bien documentées et enfantines à mettre en place, un vrai bonheur.
Gestion de timeout de session
La deuxième application est plus fourbe. Dans l'application que je développe (en PHP/MySQL), les utilisateurs doivent être déconnectés au bout de dix minutes. Impossible à gérer server-side (la nature de l'application fait que faire de l'idle revient au même que rester connecter), j'ai donc réfléchi a une solution client-side. Je sais, il est toujours possible de désactiver le javascript sur le navigateur, mais si vous avez une meilleure idée, je suis preneur (et vous m'aiderez en plus à justifier mon salaire ;). J'utilise donc encore un appel XML-RPC pour vérifier que la session est valide.
Javascript
var xmlrpc = importModule('xmlrpc');
var service = new xmlrpc.ServiceProxy('http://example.com/xmlrpc/server');
function chkSession() {
try {
var result = service.session.expired('<?php echo $session->get('sid'); ?>');
if (result) {
alert('Votre session à expirée.');
document.location = 'logout';
}
} catch (e) {
alert('impossible de contacter le serveur xml-rpc:' + e);
}
setTimeout('chkSession()', 30000);
}
chkSession();
PHP
server xml-rpc
$server = & new IXR_IntrospectionServer();
$server->addCallback('session.expired', 'sessionExpired', array('int', 'string'), 'Returns true if the session has expired');
$server->serve();
fonction sessionExpired
function sessionExpired($sid) {
require_once(PATH_ROOT . '/libs/SessionFinder.php');
$finder = & new SessionFinder();
$session = & $finder->findBySid($sid);
if (is_null($session)) {
return true;
}
return $session->expired();
}
Simplissime, et là encore, ça fonctionne comme un charme.
Comments
Merci :)