Dans un précédent article, j'abordais une manière d'éradiquer le "SPAM de formulaires". Et la technique marche si bien que je n'ai plus une seule saleté depuis. Mais récemment, dans un autre secteur, je me suis mis à recevoir des pouriels sur artisan@karma-lab.net. J'ai mis un certain à en capter la cause : à deux reprises cette adresse appairait, en clair, sur ce site. Du coup les spammeurs ont fini par tomber dessus et voguer galère... Du coup, je me suis attelé à la mise en oeuvre du très bon système de filtres de Drupal pour régler le problème à la source...
Je ne vais pas m'amuser à comparer Drupal à ses voisins que je ne connais pas assez peu. Mais un aspect ultra-puissant de ce
CMS
est sa capacité à altérer par couche successives (filtres) un texte d'origine (billet ou commentaire) pour en arriver au résultat visible. On peut par exemple ajouter un filtre qui va permettre l'utilisation d'une syntaxe "WIKI" dans vos article, ou un filtre qui va développer des tags spéciaux pour par exemple insérer des images ou des vidéos, ou encore un filtre qui va transformer les smileys texte en image, etc...
Dans le cas qui nous intéresse, nous allons créer un filtre qui va remplacer toutes les adresses courriel par une version seulement lisible par un humain. Et ce en partant du principe que, contrairement aux formulaires, les robots qui collectent les adresses mails font comme google, lisent le texte brut de la page et n'interprète pas le JavaScript.
Nous allons maintenant jeter les base de notre filtre. Comme toujours il est plus sain de créer le dossier du module dans drupal/site/all/mes_modules. Ici nous allons créer un dossier email_address_obfuscator.
Dans ce dossier commençons par ajouter le fichier de description du module :
fichier email_address_obfuscator.info
Et ensuite le corps du module lui-même :
fichier email_address_obfuscator.module
Voilà, rien de plus n'est nécessaire pour déjà aller dans Administration du site/Constuction du site/modules et activer notre nouveau module.
Un filtre s'est tout simplement un bout de code qui va prendre en entrée le texte du billet/commentaire, et fournir en sortie sa version, éventuellement modifiée. La première chose à faire est d'implémenter le hook_filter qui va effectuer ce travail. Comme le hook_block, cette fonction a plusieurs rôles : énumérer les filtres que le module expose, fournir leur description et modifier effectivement un texte.
Dans notre cas cela va donner le code suivant, à mettre à la suite dans email_address_obfuscator.module :
à la suite dans email_address_obfuscato.moduler
La section process est assez simple. L'
expression régulière
passée à preg_replace va permettre de trouver toutes les adresses emails et les découper en trois éléments : non, domaine et tld. Pour chacune des occurrences, _email_address_obfuscator_process est appelé avec en paramètre les 3 éléments.
Il nous faut donc ajouter maintenant cette fonction qui va créer la version modifiée de notre adresse email :
à la suite dans email_address_obfuscator.module
Maintenant le plus gros est fait, il ne nous reste plus qu'à ajouter une petite fonction pour indiquer aux utilisateurs que toute adresse tapée sera protégée par le système. Pour cela, nous implémentons le hook__tips :
à la suite dans email_address_obfuscator.module
Et voilà, c'est terminé. Il ne nous reste plus qu'à aller dans administration du site/configuration du site/formats d'entrée/configurer pour activer notre nouveau filtre par défaut pour tous les formats. Vous pouvez maintenant tester en créant un nouveau billet ou un nouveau commentaire et en mettant une adresse email dans le texte. Dans les aides, en dessous de la zone de saisie, vous devriez voir apparaître notre message d'aide précédent. Et lorsque vous validez, miracle, l'adresse est transformée.
les filtres marchent pour les commentaires et les corps de node, pas pour leur titre !!!
Pour des raisons de performances, les contenus filtrés sont pré-calculés et stockés en base. Si vous voulez protéger des textes existant, il faut exécuter le code SQL suivant :
DELETE FROM cache_filter;
N'ayez crainte, j'en suis et je ne me contente pas vraiment de cette simple modification des emails qui peut être "cassée" de manière automatique. L'étape suivante est donc d'utiliser ce que nous venons de voir, mais avec un véritable encodage des adresses en PHP et leur décodage en javascript.
Techniquement c'est un encodage simple (les ultra-ultra-paranoïaques peuvent ajouter un cryptage
, la chaîne de l'adresse va être transformée en une suite de code ASCII qui, côté client, va être décodée et insérer dans le page sous la forme d'un lien HTML. L'avantage par rapport à la méthode précédente, outre la sécurité supplémentaire, est que visuellement rien ne distinguera notre version encodée de la version non sécurisée. C'est par exemple le cas de l'adresse qui se trouve en introduction de ce billet.
La premier chose que nous allons modifier est la ligne contenant l'expression régulière. Nous allons cette fois "matcher" toute l'adresse et appeler une autre méthode :
en replacement de la ligne contenant preg_replacereturn preg_replace("@([A-Za-z0-9._-]+\@[A-Za-z0-9._+-]+\.[A-Za-z]{2,4})@se", "_email_address_obfuscator_encode('$1')", $text);
Maintenant passons à la procédure qui va transformer notre adresse en un lien en HTML contenant un mailto:, que nous allons encoder sous la forme d'un petit script JavaScript :
à la suite dans email_address_obfuscator.module
A ce stade, il ne nous reste plus qu'une chose à faire, modifier la priorité des filtres dans administration du site/configuration du site/formats d'entrée/configurer/réordonner. En effet chaque filtre associé à un format dispose d'une priorité qu'il convient de régler pour qu'ils ne rentrent pas en conflit les uns avec les autres. Dans notre cas, il est primordiale que le filtre HTML passe en premier (-10), puis notre filtre à adresses (-9), puis enfin le filtre URL (-8). Car si le filtre HTML passait après notre filtre, il désactiverais notre script, ce qui serait un peu dommage
Une fois l'ordonnancement achevé, un petit coup de delete from cache_filter pour vider le cache et un F5 du côté navigateur. L'adresse de test que vous avez saisie au chapitre précédent devrait apparaître sous la forme d'un lien parfaitement visible. Pour terminer, faire un code de la page pour vérifier que l'adresse est bien illisible. On n'est jamais trop prudent
Les filtres Drupal rendent d'énormes service et font gagner un temps fou. Et comme vous l'avez vu, on ne peut pas dire qu'ils soient d'une mise en oeuvre à se tordre le cerveau. C'est à la porté de n'importe qui sais coder trois lignes de PHP. De plus, vous pouvez ajouter autant de filtre que vous le désirez vu que tout est mis en cache et qu'au final cela n'a aucun impacte sur les performances.
Les sources de ce module sont disponibles ici.