All links of one day
in a single page.
<Previous day - Next day>

rss_feedDaily RSS Feed
floral_left The Daily Shaarli floral_right
——————————— Sunday 25, February 2018 ———————————

WordPress, Spam Karma 2 et PHP 7

Afin de filtrer le spam dans les commentaires de mon blog, un WordPress, j'utilise l'extension « Spam Karma 2 ». Je peux consulter les critères de blocage de chaque commentaire. Je peux débloquer les commentaires si je veux. Je peux agir sur tous les critères de classification. Et je ne participe pas à une concentration malsaine en un seul service de filtrage qui, du coup, devient hyper puissant et critique.

Spam Karma est une extension vieille de 10 ans qui n'est plus maintenue depuis longtemps. PHP 7 supprime toutes les fonctions « mysql_* ». En remplacement, il faut utiliser MySQLi ou PDO, les requêtes préparées, etc. Forcément, le binôme éclate et Spam Karma 2 ne fonctionne plus avec PHP 7.

En effet, Spam Karma 2 utilise massivement mysql_error() plutôt que le code retour des fonctions de la classe wpdb (objet WordPress représentant l'interaction avec une base de données).

De plus, Spam Karma utilise mysql_real_escape_string(). Lors de mon passage à PHP 5.6 (ce qui fait que WordPress se met à utiliser MySQLi et que, donc, mysql_real_escape_string() ne trouve pas le lien vers la base de données et sort en erreur), j'avais déjà modifié les fonctions internes de Spam Karma pour qu'il utilise esc_sql() plutôt que mysql_real_escape_string() (oui, j'ai perdu en sécurité, mais je m'évite la réécriture de pans de code… notamment de portion de requêtes SQL dont on n'identifie pas rapido où la somme des portions est exécutée…) . Mais, à deux endroits du code de Spam Karma, la fonction mysql_real_escape_string() a été utilisé au lieu de la fonction interne de Spam Karma, donc mon contournement a cessé de fonctionner.

Enfin, les versions 5.6 et 7 de PHP sont plus verbeuses qu'avant quand le prototype d'une fonction dans une classe fille ne respecte pas strictement le prototype de la fonction de la classe mère. Cela journalise 5 avertissements par page affichée, donc ça rend les logs Apache httpd illisibles.

J'ai donc corrigé tout cela…

J'ai remplacé chaque mysql_error() par un test du retour de $wpdb->query() : cette fonction retourne false quand une erreur SQL a lieu. Il suffit donc d'utiliser les opérateurs de comparaison des types (« === » et « !== »). Pour afficher l'erreur SQL, j'utilise la variable $wpdb->last_error.

J'ai remplacé les deux occurrences restantes de mysql_real_escape_string() par $wpdb->prepare(), qui peut s'utiliser avec $wpdb->query(), $wpdb->get_row(), etc.

J'ai complété le prototype des fonctions dans les classes filles avec du bullshit (exemple : « function output_plugin_UI($thiscodeisuseless = true) ») pour qu'il corresponde au prototype défini dans la classe mère.



Une fois tout cela corrigé, Spam Karma 2 est fonctionnel sur une installation PHP 7. Néanmoins, je me suis aperçu qu'il ne comptabilisait plus les liens insérés dans le corps d'un commentaire. En effet, le nombre de liens dans un commentaire est l'un des critères utilisé pour estimer si un commentaire est un spam. Et c'est un critère très efficace.

Après une longue analyse, j'ai compris que le problème venait de la fonction remove_entities() appelée par la fonction parse_URIs(). En effet, celle-ci utilise la fonction PHP preg_remplace() avec le modificateur « /e » qui n'est plus implémenté. Il faut utiliser preg_replace_callback() et adapter la fonction code2utf().



Je mets à disposition ma version de Spam Karma qui fonctionne avec PHP 7. Je donne ça comme ça. À toi de l'utiliser en prenant tes responsabilités. Je ne fais pas de support. Je ne m'engage pas à maintenir quoi que ce soit.

-