• 15 hours
  • Easy

Free online content available in this course.

Paperback available in this course

course.header.alt.is_certifying

You can get support and mentoring from a private teacher via videoconference on this course.

Got it!

Last updated on 3/13/18

L'administration

Log in or subscribe for free to enjoy all this course has to offer!

Les fonctionnalités de notre plugin sont presque complètes ! Il nous reste cependant un point important à finaliser : le plugin doit pouvoir être configuré dans l’administration, notamment pour lui définir des options mais aussi pour exécuter l’envoi de la newsletter lorsque l’administrateur le décide.

Il nous faut donc ajouter un menu spécifique pour la gestion du module, dans lequel nous disposerons des paramètres éditables ainsi que d'un bouton d’envoi des emails aux adresses enregistrées.

Ajouter des menus

Menu principal

Commençons par créer un élément de premier niveau qui apparaîtra dans le menu principal de l'administration, c'est-à-dire directement dans la colonne de gauche. Cet ajout se fait lors du chargement des menus de WordPress, un événement identifié par le déclenchement de l'action admin_menu. Dans le constructeur de la classe Zero_Plugin, il nous faut donc brancher une fonction add_admin_menu() que l'on définira plus bas.

<?php
add_action('admin_menu', array($this, 'add_admin_menu'));

La création d'un menu s'effectue avec  la fonction add_menu_page(), qui peut prendre jusqu'à sept paramètres :

  • le titre de la page sur laquelle nous serons redirigés ;

  • le libellé du menu ;

  • l'intitulé des droits que doit posséder l'utilisateur pour pouvoir accéder au menu. Si les droits sont insuffisants, le menu sera masqué ;

  • la clé d'identifiant du menu qui doit être unique (mettre le nom du plugin est une bonne option) ;

  • la fonction à appeler pour le rendu de la page pointée par le menu ;

  • l'icône à utiliser pour le lien (vous pouvez laisser les valeurs par défaut) ;

  • la position dans le menu (vous pouvez laisser les valeurs par défaut).

<?php
public function add_admin_menu()
{
    add_menu_page('Notre premier plugin', 'Zero plugin', 'manage_options', 'zero', array($this, 'menu_html'));
}

Une fois que cette fonction est définie dans la classe Zero_Plugin, le menu doit apparaître dans l'interface d'administration (voir la figure suivante).

Le lien du plugin dans le menu
Le lien du plugin dans le menu

Il nous reste à définir la méthode Zero_Plugin::menu_html() pour l'affichage de la page. Ce sera la page d'accueil du plugin, placez donc un contenu très simple simplement pour vérifier son bon fonctionnement (voir la figure suivante).

<?php
public function menu_html()
{
    echo '<h1>'.get_admin_page_title().'</h1>';
    echo '<p>Bienvenue sur la page d\'accueil du plugin</p>';
}
La page principale du plugin
La page principale du plugin

Les sous-menus

Ajoutons immédiatement un sous-menu « Newsletter » à notre élément du menu principal, afin de pouvoir gérer plusieurs sections si besoin.

Pour cela, nous devons passer par la fonction add_submenu_page(), qui comprend elle aussi de nombreux arguments. Le premier d'entre eux est l'identifiant du menu parent dans lequel devra apparaître le sous-menu, c'est donc la valeur que nous avions choisie précédemment. Notez que si vous voulez ajouter un sous-menu à l'un des menus natifs de WordPress, vous devrez ici mettre le nom du fichier PHP utilisé pour le rendu du menu en question, par exemple users.php pour le menu « Utilisateurs ». Les détails sont disponibles sur la page de référence de la fonction.

Les arguments suivants de la fonction sont respectivement :

  • le titre de la nouvelle page ;

  • le libellé du menu ;

  • les droits requis pour y accéder ;

  • l'identifiant du sous-menu ;

  • la fonction d'affichage.

Tout est donc très similaire à l'ajout d'un menu de premier niveau.

Nous allons déléguer la création du sous-menu à la classe Zero_Newsletter, il faut donc connecter une action à l'événement admin_menu et écrire la méthode correspondante.

<?php
class Zero_Newsletter
{
    public function __construct()
    {
        //...
        add_action('admin_menu', array($this, 'add_admin_menu'), 20);
    }

    public function add_admin_menu()
    {
        add_submenu_page('zero', 'Newsletter', 'Newsletter', 'manage_options', 'zero_newsletter', array($this, 'menu_html'));
    }
}

Pourquoi avoir mis une priorité à 20 dans la méthode add_action() ?

Ici, la priorité augmentée (la valeur par défaut est 10) permet de s'assurer que la fonction sera exécutée après celle qui ajoute le menu parent du plugin. Il faut en effet que celui-ci ait été créé avant de pouvoir créer les sous-menus correspondants.

Rafraîchissez votre interface d'administration, vous devriez avoir, comme sur la figure suivante, le sous-menu affiché au survol du menu parent (si le menu parent était déjà sélectionné, alors le sous-menu sera visible par défaut).

Le sous-menu contient le nouvel élément
Le sous-menu contient le nouvel élément

Deux menus on été créés ! Pourtant il n'y a qu'un seul appel à add_submenu_page() !

En effet, lors de la création d'un sous-menu, WordPress ajoute par défaut un premier lien identique au menu parent. Vous pouvez cependant en changer le libellé en créant un sous-menu donc l'identifiant est égal à l'identifiant parent (voir la figure suivante). Par exemple, nous pouvons ajouter une ligne juste après la génération du menu parent dans le fichier zero.php :

<?php
class Zero_Plugin
{
    //...
    public function add_admin_menu()
    {
        add_menu_page('Zero plugin', 'Zero plugin', 'manage_options', 'zero', array($this, 'menu_html'));
        add_submenu_page('zero', 'Apercu', 'Apercu', 'manage_options', 'zero', array($this, 'menu_html'));
    }
}
Le menu mis à jour
Le menu mis à jour

Avant de continuer, créons la fonction d'affichage du sous-menu « Newsletter » qui se contentera pour l'instant d'afficher le titre de la page (voir la figure suivante).

<?php
class Zero_Newsletter
{
    //...
    public function menu_html()
    {
        echo '<h1>'.get_admin_page_title().'</h1>';
    }
}
La page newsletter
La page newsletter

Créer des options

Nos pages sont maintenant créées, il nous faut donc écrire le formulaire permettant de renseigner les différentes options de notre choix via la méthode menu_html(). Dans un premier temps, nous allons travailler avec un seul champ pour comprendre la démarche à effectuer, puis nous en ajouterons de nouveaux.

Le fonctionnement des options

Pour conserver un maximum de souplesse, WordPress inscrit un grand nombre de valeurs de configuration dans la base de données, dont un certain nombre sont éditables au travers du menu « Réglages » de l'administration. Ce fonctionnement permet d'avoir des attributs facilement modifiables par l'administrateur pour ne pas avoir à modifier le code PHP lorsqu'il désire modifier des paramètres comme le titre du site, le format des dates, la taille des médias…

Ces différents paramètres sont appelés des options et sont stockés dans la base de données dans la table wp_options, l'identifiant de l'option étant rangé dans la colonne option_name et sa valeur dans option_value. Ainsi, rien ne nous empêche de définir nos propres valeurs de configuration, notamment lorsque l'on veut pouvoir paramétrer un plugin. Il suffit pour cela d'ajouter une ligne à la table avec l'identifiant et la valeur désirés.

Pour récupérer la valeur d'une option, il faut utiliser la fonction get_option() en lui indiquant l'identifiant de l'option à récupérer. Si l'option n'existe pas, la fonction retourne false ou bien la valeur du second paramètre s'il a été fourni.

L'ajout d'une option dans la base de données se fait avec la méthode add_option(), à laquelle il faut envoyer l'identifiant ainsi que la valeur de l'option. Toutefois, cette fonction ne permet pas de mettre à jour une option déjà existante, il faut alors utiliser update_option(), dont les paramètres sont identiques. Notez qu'en utilisant update_option(), l'option sera créée si elle n'existe pas encore. Elle est donc utilisée dans la majorité des cas car elle convient aux deux usages.

Enfin, pour supprimer une option, on utilise la fonction delete_option() qui ne prend en paramètre que le nom de l'option. Elle renvoie la valeur true si l'option a été correctement supprimée, ou bien false si l'opération à échoué ou que l'option n'existait pas.

Le formulaire

Le code HTML

Lorsque l'on crée un formulaire destiné à enregistrer des données dans la table des options, celui-ci doit appeler le fichier wp-admin/options.php lors de la soumission des données. Commencez donc à compléter la méthode Zero_Newsletter::menu_html() comme ceci :

<?php
public function menu_html()
{
    echo '<h1>'.get_admin_page_title().'</h1>';
    ?>
    <form method="post" action="options.php">

    </form>
    <?php
}

Rajoutons tout de suite le champ de texte permettant l'enregistrement de l'adresse email de l'expéditeur de la newsletter, ainsi que le bouton de validation du formulaire grâce à la fonction submit_button(). Cette dernière permet de générer un bouton de validation avec les classes CSS nécessaires à un affichage homogène dans l'interface d'administration. Le libellé du bouton peut être modifié en passant une nouvelle valeur en paramètre.

<label>Expéditeur de la newsletter</label>
<input type="text" name="zero_newsletter_sender" value="<?php echo get_option('zero_newsletter_sender')?>"/>
<?php submit_button(); ?>

Le formulaire doit maintenant s'afficher correctement, mais si vous l'envoyez, vous verrez qu'aucune valeur n'est sauvegardée dans la base de données (le champ apparaît vide lorsque vous revenez sur la page). Ceci est du au fait que nous n'avons pas encore autorisé WordPress à enregistrer la valeur de l'option zero_newsleter_sender.

Enregistrer les options modifiables

La première chose à rajouter à l'intérieur du formulaire est un appel à la fonction settings_fields(), qui affiche un certain nombre de champs cachés permettant notamment à l'application de savoir à quel groupe d'option les champs que vous allez rajouter appartiennent.

Qu'est-ce qu'un groupe d'options ?

Un groupe d'options correspond à l'ensemble des options modifiables sur une page donnée. WordPress a besoin de connaître le groupe auquel appartiennent les options afin de décider si vous avez le droit de modifier ces valeurs. Pour déterminer si les options peuvent être mises à jour, il sera nécessaire de déclarer l'ensemble des options modifiables dans un groupe d'options donné avec la fonction register_setting(). Nous appellerons notre groupe d'options zero_newsletter_settings, c'est donc l'argument à utiliser pour l'appel à settings_fields().

<form method="post" action="options.php">
<?php settings_fields('zero_newsletter_settings') ?>

Il nous faut ensuite enregistrer le champ zero_newsletter_sender dans le groupe d'options. Ceci doit impérativement se faire lorsque le système d'administration est initialisé, c'est-à-dire au déclenchement de l'événement admin_init. Ajoutons donc une fonction register_settings dans la classe Zero_Newsletter, ainsi que l'enregistrement de l'action dans son constructeur.

<?php
add_action('admin_init', array($this, 'register_settings'));
<?php
public function register_settings()
{
    register_setting('zero_newsletter_settings', 'zero_newsletter_sender');
}

Le formulaire est en place, l'option que nous souhaitons enregistrer est déclarée comme autorisée, nous pouvons donc vérifier que l'enregistrement fonctionne. Pour cela, entrez une adresse et validez le formulaire. La page doit se réafficher et le champ être pré-rempli avec la valeur envoyée (voir la figure suivante).

Sauvegarde de la valeur du champ
Sauvegarde de la valeur du champ

Génération automatique des champs

Il reste deux options à rajouter dans notre formulaire : l'objet du mail et son contenu. Pour ces deux nouveaux champs, nous allons utiliser un autre moyen de création du code HTML, en nous reposant un peu plus sur l'API de WordPress. L'idée consiste à déclarer des champs avec leurs propriétés, puis à demander l'affichage de tous les champs associés à un formulaire donné. Chaque champ doit être ajouté à une section, c'est à dire un groupe d'option, elle-même étant appelée depuis le formulaire final.

L'intérêt de ce fonctionnement est de pouvoir rajouter de nouveaux champs dans le formulaire sans pour autant devoir modifier la méthode de rendu de celui-ci, simplement en enregistrant une nouvelle section ou un nouveau champ. Il est donc tout à fait possible, grâce à ce mécanisme, de rajouter de nouvelles options dans un formulaire natif de WordPress ou créé par un autre plugin.

La création d'une section se fait par la fonction add_settings_section(), que l'on peut appeler directement dans la méthode Zero_Newsletter::register_settings().

<?php
add_settings_section('zero_newsletter_section', 'Paramètres d\'envoi', array($this, 'section_html'), 'zero_newsletter_settings');

Les paramètres de cette fonction sont l'identifiant de la section, son titre, une fonction appelée au début du rendu de la section et enfin la page sur laquelle devra s'afficher la section.

Nous allons créer immédiatement la méthode section_html() afin d'afficher une description de la section au début de celle-ci.

<?php
public function section_html()
{
    echo 'Renseignez les paramètres d\'envoi de la newsletter.';
}

Même si la section ne contient pour l'instant aucun champ, nous pouvons en activer son affichage. Pour cela, il suffit d'appeler la fonction do_settings_sections() avec comme argument l'identifiant de la page pour laquelle la section a été créée. Si plusieurs sections on été déclarées pour une page donnée, elle seront toutes affichées consécutivement (voir la figure suivante). Modifiez donc le formulaire en supprimant le champ « Expéditeur » pour le remplacer par l'appel de cette nouvelle fonction.

<form method="post" action="options.php">
<?php settings_fields('zero_newsletter_settings') ?>
<?php do_settings_sections('zero_newsletter_settings') ?>
<?php submit_button(); ?>
</form>
Affichage de la section avec sa description
Affichage de la section avec sa description

Pour déclarer le champ "Expéditeur" ainsi que les deux champs supplémentaires, il faut passer par la fonction add_settings_field() qui se charge de l'ajout d'un champ à une section donnée.

<?php
add_settings_field('zero_newsletter_sender', 'Expéditeur', array($this, 'sender_html'), 'zero_newsletter_settings', 'zero_newsletter_section');

Les paramètres de cette fonction sont l'identifiant du champ, le libellé à afficher, la fonction de rendu du champ, pour terminer par la page concernée et la section à laquelle il appartient. La méthode de rendu est très simple et ne doit se charger d'afficher que le champ en lui même comme nous l'avions fait précédemment (voir la figure suivante).

<?php
public function sender_html()
{?>
    <input type="text" name="zero_newsletter_sender" value="<?php echo get_option('zero_newsletter_sender')?>"/>
    <?php
}
Retour du champ expéditeur dans une section
Retour du champ expéditeur dans une section

Le formulaire est maintenant revenu à l'état précédent, il ne reste plus qu'à déclarer les deux nouveaux champs en passant par add_settings_field() et register_setting() et le formulaire sera mis à jour automatiquement, sans modifier la méthode menu_html(). Voici donc un récapitulatif des méthodes mises à jour avec les deux nouveaux champs « Objet » et « Contenu ».

<?php
public function register_settings()
{
    register_setting('zero_newsletter_settings', 'zero_newsletter_sender');
    register_setting('zero_newsletter_settings', 'zero_newsletter_object');
    register_setting('zero_newsletter_settings', 'zero_newsletter_content');

    add_settings_section('zero_newsletter_section', 'Newsletter parameters', array($this, 'section_html'), 'zero_newsletter_settings');
    add_settings_field('zero_newsletter_sender', 'Expéditeur', array($this, 'sender_html'), 'zero_newsletter_settings', 'zero_newsletter_section');
    add_settings_field('zero_newsletter_object', 'Objet', array($this, 'object_html'), 'zero_newsletter_settings', 'zero_newsletter_section');
    add_settings_field('zero_newsletter_content', 'Contenu', array($this, 'content_html'), 'zero_newsletter_settings', 'zero_newsletter_section');
}

public function object_html()
{?>
    <input type="text" name="zero_newsletter_object" value="<?php echo get_option('zero_newsletter_object')?>"/>
    <?php
}

public function content_html()
{?>
    <textarea name="zero_newsletter_content"><?php echo get_option('zero_newsletter_content')?></textarea>
    <?php
}

Vous pouvez maintenant rafraîchir la page pour renseigner les valeurs de ces nouvelles options (voir la figure suivante).

Le formulaire final
Le formulaire final

Traiter des actions

Lorsque l’ensemble des options sont configurées, il ne manque plus qu’un bouton afin d’envoyer la newsletter aux adresses inscrites. Ce bouton doit donc déclencher l’appel d’une fonction spécifique qui envoie l’email à tous les destinataires souhaités.

Nous avons deux solutions pour arriver à nos fins. Nous pouvons utiliser un lien vers un fichier spécifique de notre plugin qui traitera directement l’envoi des emails avant de nous rediriger vers l’interface d’administration de notre plugin. C’est une solution qui paraît assez simple mais qui implique de charger les fonctionnalités de WordPress manuellement dans le fichier cible, c’est pourquoi elle n’a pas ma préférence. Au lieu de cela, nous allons simplement rafraîchir la page en cours et brancher une nouvelle action se chargeant de vérifier si l’envoi a été demandé et de l’exécuter le cas échéant.

Nous allons pour cela insérer un second formulaire dans la page, à la fin de la méthode menu_html().

<form method="post" action="">
    <input type="hidden" name="send_newsletter" value="1"/>
    <?php submit_button('Envoyer la newsletter') ?>
</form>

Le formulaire contient simplement un champ caché qui sera envoyé en POST afin de demander l’envoi des emails. Au clic sur le bouton, la page actuelle sera rafraîchie avec le paramètre send_newsletter présent dans la requête.

Nous devons donc intercepter la présence de ce paramètre au chargement de la page. Pour cela, il existe dans WordPress un événement déclenché au chargement de toutes les pages d’administration, de la forme load-[identifiant de la page]. L’identifiant de la page est récupérable lors de la création du menu qui permet d’accéder à la page : c’est le retour de la fonction add_submenu_page() (cela fonctionne aussi avec add_menu_page()).

Nous modifions donc la méthode Zero_Newsletter::add_admin_menu() :

<?php
public function add_admin_menu()
{
    $hook = add_submenu_page('zero', 'Newsletter', 'Newsletter', 'manage_options', 'zero_newsletter', array($this, 'menu_html'));
    add_action('load-'.$hook, array($this, 'process_action'));
}

Dans cette méthode process_action(), nous vérifions la présence du paramètre send_newsletter avant d’appeler la méthode d’envoi.

<?php
public function process_action()
{
    if (isset($_POST['send_newsletter'])) {
        $this->send_newsletter();
    }
}

Il ne reste plus maintenant qu’à écrire la méthode send_newsletter() pour envoyer les emails à nos visiteurs inscrits. Nous allons donc devoir récupérer les paramètres de configuration choisis ainsi que la liste des emails, puis appeler la fonction wp_mail() qui permet de construire un email.

<?php
public function send_newsletter()
{
    global $wpdb;
    $recipients = $wpdb->get_results("SELECT email FROM {$wpdb->prefix}zero_newsletter_email");
    $object = get_option('zero_newsletter_object', 'Newsletter');
    $content = get_option('zero_newsletter_content', 'Mon contenu');
    $sender = get_option('zero_newsletter_sender', 'no-reply@example.com');
    $header = array('From: '.$sender);

    foreach ($recipients as $_recipient) {
        $result = wp_mail($_recipient->email, $object, $content, $header);
    }
}

Et voilà ! Le site est prêt à envoyer des newsletters à ses inscrits en un seul clic sur le bouton d'envoi !

  • De nouvelles pages peuvent être ajoutées dans l'interface d'administration, accessibles avec des menus spécifiques.

  • Les options permettent de sauvegarder les valeurs de vos paramètres de configuration.

  • Vous pouvez créer des options spécifiques à votre plugin et les éditer dans l'administration.

  • L'enregistrement des sections et des champs pour les formulaires permet plus de souplesse que la construction manuelle.

Example of certificate of achievement
Example of certificate of achievement