Faire un plugin pluxml par l'exemple

 Pour les besoins de la nouvelle maquette et dans un soucis bien légitime de me retrouver avec un code un peu moins crade en revenant sur son aspect "bricolo et bricolette font du php à la pelle de chantier", j'ai été amené à me pencher sur les plug in façon pluXML.

 

J'ai bien conscience que certains me rétorqueront "si t'as des difficultés: RTFM !" mais bon... la doc de pluxml a beau être bien faite, elle ne revient pas sur certains aspects qu'une approche empirique en mode barbu les doigts dans le cambouis révèle plus clairement.

 

Je vous propose donc de reprendre étape par étape un plugin que j'ai réalisé: le WDD_BanComment... et à la fin, comme vous êtes sages, je vous ferai un cadeau...

 

la structure d'un plug-in:

Pour que le plugin soit valide, il doit y avoir au moins les fichiers suivants regroupés dans un dossier portant le nom du plugin (ici le dossier s'appellera donc WDD_BanComment):

  1. un fichier info.xml qui contient les informations sur le plugin (voir plus bas)
  2. un fichier icon.png, servant à identifier visuellement le plugin dans la partie admin
  3. un fichier config.php (peut être facultatif si le plugin ne requiert aucune configuration)
  4. un fichier portant le même nom que le dossier, suivi de php; ici: WDD_BanComment.php
  5. un sous-dossier lang/ contenant un fichier fr.php.

 

le fichier config.php

Ce fichier sert à permettre à l'administrateur de configurer le plugin. Il se charge à la fois de :

  • présenter le formulaire de configuration
  • et de charger / stocker les données en gérant le $_POST...

 

Voici le code du config.php de  WDD_BanComment:

<?php if(!defined('PLX_ROOT')) exit; ?>
<?php 
    if(!empty($_POST)) {
        $plxPlugin->setParam('name', $_POST['name'], 'string');
        $plxPlugin->setParam('mail', $_POST['mail'], 'string');
        $plxPlugin->setParam('site', $_POST['site'], 'string');
        $plxPlugin->setParam('content', $_POST['content'], 'string');
        $plxPlugin->setParam('ip', $_POST['ip'], 'string');
        $plxPlugin->saveParams();
        header('Location: parametres_plugin.php?p=WDD_BanComment');
        exit();
    }
?>
<h2><?php $plxPlugin->lang('L_TITLE') ?></h2>
<p><?php $plxPlugin->lang('L_DESCRIPTION') ?></p>
<form action="parametres_plugin.php?p=WDD_BanComment" method="post" style="font-size:16px;">
    <li><label>Mots interdits dans le nom :     <textarea style="width:100%;height:100px;" name="name"><?php  echo plxUtils::strCheck($plxPlugin->getParam('name')); ?></textarea></label></li>
    <li><label>Mots interdits dans l'email:     <textarea style="width:100%;height:100px;" name="mail" ><?php echo plxUtils::strCheck($plxPlugin->getParam('mail')) ?></textarea></label></li>
    <li><label>Mots interdits dans l'url:       <textarea style="width:100%;height:100px;" name="site" ><?php echo plxUtils::strCheck($plxPlugin->getParam('site')) ?></textarea></label></li>
    <li><label>Mots interdits dans le message:  <textarea style="width:100%;height:100px;" name="content" ><?php echo plxUtils::strCheck($plxPlugin->getParam('content')) ?></textarea></label></li>
    <li><label>IP interdites :  <textarea style="width:100%;height:100px;" name="content" ><?php echo plxUtils::strCheck($plxPlugin->getParam('ip')) ?></textarea></label></li>
    <br />
    <input type="submit" name="submit" value="Enregistrer"/>
</form>

Quelques explications:

  • la partie gérant le $_POST se charge d'écrire les données dans la config:
    $plxPlugin->setParam('name', $_POST['name'], 'string'); ( Il faudra bien préciser le type de donnée)
  • la partie suivante affiche le formulaire si aucune donnée post n'a été envoyée.



A retenir:

  • $plxPlugin->setParam pour sauver un paramètre
  • $plxPlugin->getParam pour récupérer un paramètre...

 

Dans ce plugin, on cherchera à bloquer des envois de commentaires en fonction des mots présents dans les cases du formulaire ou de l'adresse IP, il nous faut donc un paramètre pour chaque donnée du formulaire (name, mail, site, content et ip).

 

 

le fichier info.xml

<?xml version="1.0" encoding="UTF-8"?>
<document>
<title><![CDATA[WDD_BanComment]]></title>
<author><![CDATA[bronco@warriordudimanche.net]]></author>
<version>1.0</version>
<date>01/03/2014</date>
<site>http://warriordudimanche.net</site>
<description><![CDATA[Empêcher les commentaires en bloquant certains mots dans le nom/adresse/email]]></description>
</document>

Le contenu est assez simple à saisir, je passe...

 

 

le fichier "plugin".php

C'est le coeur même du plugin, la partie contenant le code proprement dit et la liste des hooks, c'est-à-dire les "interruptions" du déroulement normal de l'exécution de pluxml pour appeler votre code.

 

Selon ce principe, on peut faire cette interruption où l'on veut, à n'importe quel niveau du code, y compris au tout début. La doc contient la liste des hooks.

 

Ainsi, on peut demander à pluxml d'injecter le code juste au début du body, au début du thème ou même au tout début du code.

A noter que vous pouvez créer vous même les hooks qui ne seraient pas prévus dans pluxml et les appeler depuis une page du thème par exemple avec un eval($plxShow->callHook('Nom_de_mon_hook'))  (la doc est très claire à ce sujet.)

 

Ce système permet d'intervenir sur des procédures du coeur de pluxml sans modifier des fichiers sensibles ni perdre les bidouilles à chaque mise à jour...

 

 

Nous allons gérer le commentaire dès que quelqu'un en poste un, donc au moment du plxMotorNewCommentaire.

Si on est curieux, on ouvre les fichiers du core/lib/ pour regarder dans plxmotor... dans la fonction newcommentaire, on trouve la gestion de la création d'un commentaire et l'appel au hook:

public function newCommentaire($artId,$content) {
        # Hook plugins
        if(eval($this->plxPlugins->callHook('plxMotorNewCommentaire'))) return; // le hook est appelé ici depuis le coeur de pluxml...

 

Donc, dans notre fichier de plugin WDD_BanComment.php, nous aurons:

<?php
class WDD_BanComment extends plxPlugin {
    public function __construct($default_lang) {
        # appel du constructeur de la classe plxPlugin (obligatoire)
        parent::__construct($default_lang);
    # limite l'accès à l'écran d'administration du plugin
    # PROFIL_ADMIN , PROFIL_MANAGER , PROFIL_MODERATOR , PROFIL_EDITOR , PROFIL_WRITER
    $this-&gt;setConfigProfil(PROFIL_ADMIN);

    # Déclaration du hook
    $this-&gt;addHook('plxMotorNewCommentaire', 'plxMotorNewCommentaire');  
}   
# HOOKS
public function plxMotorNewCommentaire() { 

    echo '
    &lt;?php 
        $forbidden=array(
            "name"=&gt;explode(",","'.$this-&gt;getParam("name").'"),
            "mail"=&gt;explode(",","'.$this-&gt;getParam("mail").'"),
            "site"=&gt;explode(",","'.$this-&gt;getParam("site").'"),
            "content"=&gt;explode(",","'.$this-&gt;getParam("content").'"),
            "ip"=&gt;explode(",","'.$this-&gt;getParam("ip").'")
        );
        $content["ip"]=plxUtils::getIp();
        foreach ($forbidden as $item=&gt;$values){              
            foreach ($values as $forbidden_word){
                if (stripos($content[$item],$forbidden_word)!==false){
                    return "mod";
                }
            }

        }';
    echo '?&gt;';
}

} ?>

 

D'abord, notez que la classe porte le même nom que le fichier et le dossier: WDD_BanComment... important !

 

On déclare le ou les hooks pour que pluxml soit à même de déclencher les fonctions associées:

$this->addHook('plxMotorNewCommentaire', 'plxMotorNewCommentaire');

 

Et dans la foulée, on déclare la fonction qui sera appelée lorsque le hook aura lieu:

public function plxMotorNewCommentaire() { ... }

 

C'est à partir de là qu'il faudra être attentif, car deux cas de figure peuvent se présenter en fonction de ce qu'on attend du plugin:

  1. la fonction doit manipuler des données en interne et renvoyer des résultats: 
    On écrit le code comme d'habitude, pas de soucis majeur.
  2. la fonction doit manipuler des données qui lui sont inaccessibles à cause de la portée des variables par exemple:
    On injecte du code à l'endroit où le hook a été fait.

En effet, dans ce second cas de figure, on echo le code php: au lieu de s'exécuter au sein de la fonction, il sera exécuté par un eval() à l'endroit où le hook a été appelé.

 

C'est ainsi que WDD_BanComment va être appelé depuis la fonction du moteur qui crée un nouveau commentaire et avant que celui-ci ne soit validé; il y injectera le code suivant (en remplaçant les paramètres par leur valeur):

<?php 
            $forbidden=array(
                "name"=>explode(",","'.$this->getParam("name").'"),
                "mail"=>explode(",","'.$this->getParam("mail").'"),
                "site"=>explode(",","'.$this->getParam("site").'"),
                "content"=>explode(",","'.$this->getParam("content").'"),
                "ip"=>explode(",","'.$this->getParam("ip").'")
            );
            $content["ip"]=plxUtils::getIp();
            foreach ($forbidden as $item=>$values){              
                foreach ($values as $forbidden_word){
                    if (stripos($content[$item],$forbidden_word)!==false){
                        return "mod";
                    }
                }
        }

?>

 

En gros:

  • on récupère chaque paramètre du plugin (contenant les mots interdits pour chaque item du formulaire de contact),
  • on en fait un tableau via explode
  • puis on vérifie si le commentaire posté contient un des mots interdits ou si l'adresse ip a été bloquée...

Si c'est le cas, on coupe au traitement du commentaire par le moteur en retournant une valeur particulière.

 

C'est tout ! et ça marche

On pourrait sans doute mieux faire, optimiser ou utiliser des regex au lieu d'une liste de mots... baste ! 

Cet exemple est simple à saisir et a l'avantage de ne pas multiplier les difficultés pour un premier plugin d'exemple

 

 


Et maintenaaaaaaaaaaant ? Le cadeau le cadeau le cadeau ! Bon, d'accord !

Pour vous faciliter la vie, je vous ai fait une appli qui génèrera un zip tout prêt pour votre plugin, avec les fichiers nécessaires, configurés comme il faut dans un dossier déjà nommé, prêt à modifier... Il ne restera plus que le code proprement dit... (et la config, tout de même )

 

Alors, pour tester ce générateur: 

http://tools.warriordudimanche.net/pluxml_plugin_starter.php

 

Si vous voulez récupérer le zip de l'appli, c'est sur github: 

https://github.com/broncowdd/pluxml-plugin-generator

 

Si seul le plugin vous intéresse:

http://warriordudimanche.net/vrac/WDD_BanComment.zip

 

 


image de titre : http://www.laboiteverte.fr/parpaing-lego/

✍ Écrire un commentaire

les commentaires relevant du SPAM seront filtrés et dégagés direct...

Quelle est le quatrième caractère du mot h120zuv ?