Une petite explication ? Ok, mais c'est bien parce que vous insistez.

J'utilisais le code PHP suivant :

// suppression du captcha
$query = 'delete from ' . $core->prefix . self::$table_hash . " where hash = '" . $con->escape($hash) . "'";
 
// et on en profite pour enlever les anciens
$current_datetime = date('Y-m-d H:i:s');
$query .= " or timestamp + interval '" . self::$hash_ttl_min . " min' < '" . $con->escape($current_datetime) . "'";

$hash contient le hash qui correspond à la référence du captcha à supprimer, self::$table_hash contient le nom de la table, $core->prefix est un DCism qui retourne le préfixe des tables Dotclear, $con->escape est un autre DCism qui permet d'avoir des données sécurisées, et enfin self::$hash_ttl_min est le temps en minutes avant l'expiration d'un captcha.

Ça génère une requête SQL qui ressemble à ça :

DELETE FROM dc_captcha_hash WHERE hash = 'XXX' OR timestamp + interval '60 min' < '2011-05-09 09:14:14'

Ce qui marche pas dans MySQL, c'est la partie timestamp + interval '60 min'.

Dans MySQL, il faudrait la requête suivante :

DELETE FROM dc_captcha_hash WHERE hash = 'XXX' OR timestamp + interval 60 minute < '2011-05-09 09:14:14'

On remarque : l'intervalle n'est pas mis dans une chaîne de caractères, et on utilise minute au lieu de min.

Comme je n'avais pas envie de faire un gros @@if@ qui tâche pour créer une requête ou l'autre, j'ai décidé de refaire le calcul en PHP. À partir de PHP 5.3, il y a la classe DateTime très pratique pour faire ce genre de choses, mais je voulais être compatible avec les versions plus vieilles[1]. J'y suis donc allé à l'ancienne !

// suppression du captcha
$query = 'delete from ' . $core->prefix . self::$table_hash . " where hash = '" . $con->escape($hash) . "'";
 
// et on en profite pour enlever les anciens
$expired_timestamp = gmmktime(gmdate('H'), gmdate('i') - self::$hash_ttl_min);
$expired_datetime = gmdate('Y-m-d H:i:s', $expired_timestamp);
$query .= " or timestamp < '" . $con->escape($expired_datetime) . "'";

C'est beau comme du PHP un lundi matin.

Notes

[1] car tout simplement mon blog tourne sur une version plus vieille.