![child-reading-book-outside[1]](http://boiteaweb.fr/wp-content/uploads/2012/03/child-reading-book-outside1-e1367803319176-590x304.jpg)
Créer un plugin enfant dans WordPress, possible ou pas ?
J'entends par la création d'un plugin enfant, la même chose que la création d'un thème enfant, le but est de ne pas modifier le core du plugin afin que les prochaines mises à jour n'écrasent pas mes modifications.
Oui mais WordPress ne permets pas de créer un plugin pour en faire un "enfant" d'un autre ... En fait, si ... c'est tout à fait possible. La preuve, Greg m'a devancé et a créé un hack pour un plugin existant : http://www.screenfeed.fr/blog/plugin-drag-drop-for-post-thumbnails-hack-01007/
Vas y dis comment !!
Oui une seconde :p D'abord, comment ça peut fonctionner. Et bien je vois 2 choses :
- La première et la meilleure serait l'utilisation des hooks et filtres disponibles dans le plugin parent. SI ce plugin en contient assez et bien placés alors il est simple de les utiliser pour ajuster le plugin à nos besoins. C'est exactement ce que nous faisons déjà avec le core de WordPress en fait !
- La deuxième c'est la possibilité de "déhooker" et "rehooker" un hook... oula ... ok je la refait. Le plugin parent, s'il n'a pas assez (ou du tout !) de hook, il va falloir retirer les hooks qu'il a posé, créer notre fonction basé sur la sienne, puis reposer le hook sur cette même action.
Ok j'ai (un peu) compris, montre un exemple
Un exemple avec (soyons chauvins) mon plugin "More Secure Login". Je souhaite supprimer le lien "Powered by BAW More Secure Login" qui se trouve dans les champs de connexion (vilain !) et je souhaite aussi modifier le type du champ du plugin en "password" car là, il est en "text" par défaut et ça ne me plait pas.

Je regarde si le plugin fourni des hooks pour ça : Premier réflexe, je lis la FAQ qui m'invite à lire le fichier "help.html" dans les dossiers du plugin. Je l'ouvre et je lis :
Ha super ça, exactement ce dont j'avais besoin (comme par hasard ...), et pour la suppression du lien je lis :
Aïe, là, pas de filtre, au contraire, l'auteur demande de ne pas le supprimer ... Mais je suis vilain alors je vais le faire quand même, sans modifier le code, oui Môsieur.
Allez du code !!
Ok, alors créons un plugin avec une entete normale habituelle :
/*
Plugin Name: BAW More Secure Login "Child"
Description: Modifie le champ en "password" et supprime le lien dans les champs
Version: 1.0
Author: Moi
*/
[/php]
Puis ajoutons notre filtre perso sur le hook du plugin :
function modify_msl_field( $input_props )
{
$input_props['type'] = 'password';
return $input_props;
}
add_filter( 'bawmsl_inputprops', 'modify_msl_field' );[/php]
J'active le plugin et j'obtiens:

Ha super !
Supprimons le lien maintenant.
Oui oui ok. Ici il va falloir regarder dans quelle fonction est ce lien et quel hook et lié à cette fonction.
Je lis donc : Fonction "bawmsl_login_form_add_field" pour le hook "login_form". je l'ai lu ici : "add_action( 'login_form', 'bawmsl_login_form_add_field' );"
Je vais ajouter une ligne dans mon plugin enfant :
remove_action( 'login_form', 'bawmsl_login_form_add_field' );[/php]
Maintenant, le plugin parent ne pourra plus ajouter le lien. Euh mince, ni le champ ni rien d'autre. Je vais devoir copier/coller sa fonction, un peu comme si je clonais son plugin. L'avantage de faire ça plutôt que de créer mon pluginn basé sur le sien c'est que je vais profiter des mises à jour du plugin parent et de ses nouvelles fonctionnalités !
Voici donc mon copié/collé modifié :
function my_login_form_add_field()
{
global $wpdb;
$hash = md5( time() . rand() );
$table_name = $wpdb->prefix . 'moresecurelogin';
$col = chr( rand( 1, 8 ) + 64 );
$row = rand( 1, 8 );
// Insert a random hash associated with a code couple, like A1
$wpdb->insert( $table_name, array( 'timestamp' => current_time('mysql'), 'code' => $col.$row, 'hash' => $hash ) );
// Delete all hash if generated 5mn or more earlier
$wpdb->query( 'DELETE FROM ' . $table_name . ' WHERE timestamp < "' . date( 'Y-m-d H:i:s', mktime( date( 'H' ), date( 'i' ) - 5, date( 's' ), date( 'n' ), date( 'j' ), date( 'Y' ) ) ) . '"' ); // 5 mn
$input_props = array( 'type' => 'text',
'id' => 'mslcode',
'class' => 'input',
'value' => '',
'autocomplete' => 'off',
'placeholder' => __( 'Required code: ', 'bawmsl' ) . $col.$row,
'tabindex' => '89',
'style' => ''
);
$input_props = apply_filters( 'bawmsl_inputprops', $input_props );
?>
}
add_action( 'login_form', 'my_login_form_add_field' );[/php]
Remarquez que le nom de la fonction a changé en "my_login_form_add_field", en effet il m'est impossible de redéclarer une fonction avec le même nom, cela provoquerait une erreur fatale. Aussi, j'ai supprimé le lien et pour finir j'ai "rehooké" avec ma fonction.
Je réactive le plugin et j'ai ceci :

Voilà ! Plus de lien de pub (vilain !!)
Edit : Greg me fait remarquer en commentaire qu'on peut (voire, il faudrait) vérifier l'existence de la fonction pour s'assurer s'executer le code de notre plugin enfant que si le parent est acivé, pour cela ajoutons juste ceci : if ( function_exists('bawmsl_login_form_add_field') ) :
Ok et c'est tout ?
Oui et non, le problème avec ça c'est que si le plugin mets à jour une des fonctions que vous aurez clonées et modifié, soit vous ne profitez pas des nouveautés, soit vous ne profitez pas d'un correctif sécurité ou bug, soit ça bug carrément.
Pour palier à ça, je vous conseille simplement de comparer les fonctions copiées pour s'assurer que nous n'avez pas besoin de reprendre du code.
Maintenant, vous savez créer un plugin enfant, souvenez-vous : vérifier les hooks et les utiliser, puis cloner les fonctions, supprimer le hook, renommer les fonctions, hooker de nouveau. Bon codage !
Code complet de notre plugin enfant avec l'ajout de Greg :
/*
Plugin Name: BAW More Secure Login "Child"
Description: Modifie le champ en "password" et supprime le lien dans les champs
Version: 1.0
Author: Moi
*/
if ( function_exists('bawmsl_login_form_add_field') ) :
function modify_msl_field( $input_props )
{
$input_props['type'] = 'password';
return $input_props;
}
add_filter( 'bawmsl_inputprops', 'modify_msl_field' );
remove_action( 'login_form', 'bawmsl_login_form_add_field' );
function my_login_form_add_field()
{
global $wpdb;
$hash = md5( time() . rand() );
$table_name = $wpdb->prefix . 'moresecurelogin';
$col = chr( rand( 1, 8 ) + 64 );
$row = rand( 1, 8 );
// Insert a random hash associated with a code couple, like A1
$wpdb->insert( $table_name, array( 'timestamp' => current_time('mysql'), 'code' => $col.$row, 'hash' => $hash ) );
// Delete all hash if generated 5mn or more earlier
$wpdb->query( 'DELETE FROM ' . $table_name . ' WHERE timestamp < "' . date( 'Y-m-d H:i:s', mktime( date( 'H' ), date( 'i' ) - 5, date( 's' ), date( 'n' ), date( 'j' ), date( 'Y' ) ) ) . '"' ); // 5 mn
$input_props = array( 'type' => 'text',
'id' => 'mslcode',
'class' => 'input',
'value' => '',
'autocomplete' => 'off',
'placeholder' => __( 'Required code: ', 'bawmsl' ) . $col.$row,
'tabindex' => '89',
'style' => ''
);
$input_props = apply_filters( 'bawmsl_inputprops', $input_props );
?>
}
add_action( 'login_form', 'my_login_form_add_field' );
endif;[/php]
:)
Lire la suite

![Des catégories en boutons radio<br /><span class="hidden"> : </span><span class="sub_title">#jeudiconfession n°5</span> piege-de-cristal-encore-bruce-willis[1]](http://boiteaweb.fr/wp-content/uploads/2013/06/piege-de-cristal-encore-bruce-willis1-125x125.jpg)

![WordPress Bootstraps<br /><span class="hidden"> : </span><span class="sub_title">Comment bien charger WordPress</span> bootstrap1[1]](http://boiteaweb.fr/wp-content/uploads/2013/04/bootstrap11-125x125.png)






Allons allons : « exactement ce que j’avais besoin » … « ce dont j’avais besoin » ;)
En dehors de quelques soucis de français, ton article est bien tourné et c’est un excellent mémo pour la création de plugin enfants.
Merci !
J’utilise les règles de grammaire chti moi môsieur :p
Merci à toi pour le correctif que j’applique tout de même (parait-il que certaines personnes ne comprennent pas le chti ? hoooo!)
Et merci pour le compliment aussi :)
Hello,
De bon petits conseils de codage, mais c’est un peu bourrin de désactiver, copier, réécrire et réactiver ses modifications. Sur de petits plugins ça revient presque à copier le plugin, le renommer et en faire sa sauce.
Il y a aussi une forte contrainte de contrôle des plugins parents mis à jour pour ré-adapter ses plugins enfants.
Très bon article en tout cas, avec un brin d’humour fort en humilité, puisque tu nous montres comment virer le lien sous le champ, sur ton propre plugin.
Merci et au plaisir ;)
Merci !
J’ai hésité à le faire avec un « gros » plugin, mais j’ai eu peur de faire bourrin. C’est vrai que sur des petits, ça reviens presque à de la réécriture, mais comme je le dis aussi en fin d’article, l’avantage est aussi d’obtenir les mises à jour sans forcément modifier l’enfant.
Pour info, c’est la même chose avec un thème parent, si le parent change trop, l’enfant est à retoucher.
Pour un profil de dev, à lui de voir s’il préfère refaire à sa sauce ou pas, je pense aussi aux dev qui travaillent pour un client qui va mettre à jour les plugins et écraser ses modifs … « mais je vous avais dit de … ok laissez tomber je refais » ;p
ps : oui il y a possibilité d’interdire les mises à jour, mais alors vous devrez passer vous meme chez tous vos clients pour MAJ leur plugins, wow …
A bientôt !
Hello,
J’avais pas vu ta réponse.
Effectivement tu as bien raison pour l’aspect sur les mises à jour, notamment vis à vis d’un client. C’est bien plus pratique au niveau du dev et c’est moins risqué.
Je ne suis pas trop fan de bloquer les mises à jour, mais je sais que ça se fait ^^
Bonne continuation Julio ;)
Comment je t’ai grillé hahaha =D
Perso j’ajouterais juste une chose à ce plugin enfant :
if ( function_exists('bawmsl_login_form_add_field') ) :Car si le plugin parent est désactivé mais pas le plugin enfant, ce dernier continuera à ajouter le champ supplémentaire… qui ne sera pas traité.
Remarque ça peut être une arme de dissuasion pour un potentiel hackeur « Ho mince, il a renforcé son login avec un machin à code » #oupas ^^
Thx pour la mention de mon article :)
A+
Mais oui tu as totalement raison de vérifier l’existence de la fonction, je mets à jour l’article cela me semble assez important pour que ça sorte des commentaires (pas forcéments tous lus)
Bon… j’ai pas tout capté mais je garde l’article sous la main ! ;)
J’ai eu une petite frayeur une fois arrivé à cette image : http://www.boiteaweb.fr/wp-content/uploads/2012/03/baw_120313-0134501-640×115.png #BSOD