WordPress avec un SSL Let’s encrypt sur OVH mutualisé

WordPress avec un SSL Let’s encrypt sur OVH mutualisé

Les internautes, et les moteurs de recherche, attachent de plus en plus d’importance au petit cadenas vert qui indique qu’un site internet est sécurisé. Lorsque le site est sécurisé, les données bancaires, les données personnelles ou les mots de passe sont cryptés. Les données sont donc mieux protégées.

J’expérimente ici la création d’un site « https://potentiel-web.com » sur un hébergement Pro mutualisé d’OVH. Je vais utiliser un certificat gratuit « Let’s Encrypt », disponible depuis quelques mois sur OVH.

étape 0 : dans l’espace client OVH

Il faut que j’associe le domaine potentiel-web.com à un hébergement. Les éléments qui suivent sont décrits avec plus de détails dans l’article Hébergement Pro OVH avec plusieurs sites.

Dans l’hébergement cible, choisir l’onglet « multisite » et cliquer sur le bouton « Ajouter un domaine ou sous domaine ».

J’ajoute le domaine potentiel-web.com, déjà enregistré chez OVH et dans le second panneau de paramétrages, je choisis  « créer également le sous domaine www.potentiel-web.com » et je coche l’option « SSL ». Dans le dernier panneau, je choisis « configuration automatique (recommandé) » et je valide.

Mon espace client affiche successivement « La modification du ou des domaines associé(s) à votre hébergement mutualisé est en cours … » puis « La modification du ou des domaines associé(s) à votre hébergement mutualisé a été effectuée avec succès. ».

Dans la liste des domaines de l’onglet multisites, je vois maintenant apparaître les deux sites (avec et sans www) :

Ajout d'un domaine à un hébergement mutualisé OVH

Pour l’instant, je ne m’occupe pas du SSL en orange.

étape 1 : créer un site WordPress classique

Créer la base de données associée

dans l’espace client OVH, partie hébergement, je vais dans l’onglet « base de données » et je clique sur le bouton « créer une base de données ».

Pour le mot de passe, j’utilise le générateur de mot de passe de LastPass, en mode A-Z, a-z et 0-9. La base s’installe.

Une fois que j’ai reçu un mail m’informant de la création de la base, je peux continuer.

Installer le module WordPress

Toujours dans l’espace client OVH, partie hébergement, je vais dans l’onglet « modules en 1 clic » pour installer WordPress.

Je clique sur le bouton « ajouter un module ». Je choisis WordPress et potentiel-web.com comme domaine associé. Je clique sur « installer en mode avancé ».

Je reçois un mail d’OVH, avec le nom d’utilisateur et le mot de passe associé, lorsque le module est installé.

Accéder à WordPress

Je vérifie que j’accède au site http://potentiel-web.com et au tableau de bord WordPress (http://potentiel-web.com/wp-admin, avec le nom d’utilisateur et le mot de passe défini lors de l’installation du module).

J’en profite pour créer un autre utilisateur administrateur, dont le mot de passe n’aura pas été transmis par mail. Evidemment je supprime ensuite le précédent utilisateur.

étape 2 : gestion du certificat SSL

A ce stade, si je tape https://potentiel-web.com/ pour accéder à mon site, mon navigateur (chrome) m’affiche un message d’alerte.

Alerte, votre connexion n'est pas privée

Par contre, http://potentiel-web.com/ s’affiche correctement. C’est normal puisque je n’ai pas « généré de certificat SSL » lors de l’étape 0. Je ne l’ai pas fait car lorsque j’ai essayé, l’espace client d’OVH m’a affiché un message disant que si j’avais crée un nouveau site depuis moins de deux heures, le certificat ne fonctionnerait pas.

Dans mon espace client OVH, je clique sur l’hébergement de potentiel-web.com et j’accède à l’onglet « informations générales ».

OVH régénérer le certificat SSL d'un hébergement

Je clique sur « régénérer le certificat SSL ». Selon le guide OVH « Les certificats SSL sur les hébergements web« , il faut maintenant attendre le protocole HTTPS quelques heures, « le temps de le déployer sur l’ensemble de l’infrastructure ».

Nota : pour un site existant, à transformer en https, le processus est légèrement différent, et également décrit dans le guide OVH ci-dessus.

Quelques heures plus tard, le site https://potentiel-web.com/ s’affiche correctement :

Un site WordPress en https, avec un certificat SSL de "Let's encrypt"

Redirection du http vers le https

Maintenant que le site fonctionne en https, il faut que j’élimine toute possibilité d’accéder en http :

  • pour éviter les problèmes de « duplicate contents » puisque les robots des moteurs de recherche considèrent les sites en http comme distincts des sites en https.
  • pour éviter aussi qu’un internaute se retrouve sur la version non sécurisée.

Pour y arriver, j’ai trois choses à faire :

  1. régler le nom du site dans le tableau de bord WordPress ;
  2. Modifier wp-config.php pour interdire l’accès au tableau de bord hors https
  3. rediriger vers l’url en https avec .htaccess

Modifier le nom du site

Dans le tableau de bord WordPress, menu « Réglages »  > « Général », régler « Adresse web de WordPress (URL) » et « Adresse web du site (URL) » pour qu’elles démarrent avec https et pas http.

Modifier wp-config.php

Modifier wp-config.php en y ajoutant :

/* HTTPS only for admin access and login */
define( 'FORCE_SSL_ADMIN', true );
define('FORCE_SSL_LOGIN', true);

Modifier le .htaccess

Ajouter :

# direct everything to https
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{SERVER_NAME}/$1 [R=301,L]

Il n’y a plus qu’à attendre un peu et ce sera bon ! Dans un navigateur, que l’on tape potentiel-web.com ou http://potentiel-web.com, on arrive dans tous les cas à https://potentiel-web.com.

Et maintenant ?

Je pense que la transformation d’un site existant doit être un peu différente, avec des problèmes spécifiques (cf le guide OVH, « Eviter les pièges du SSL avec mon site web« ). Il va donc falloir que je fasses des essais. Ce sera l’objet d’un autre article.

Un « color picker » dans les réglages de notre extension WordPress

Un « color picker » dans les réglages de notre extension WordPress

Nous allons améliorer la page de réglage de notre extension WordPress, en y ajoutant un champ de type « color picker » et en affichant les données complémentaires définies avec les champs. Dans les articles précédents de cette série (), nous avons progressivement construit l’extension et sa page de réglage. A la fin du précédent article, l’extension correspondait au contenu de ce fichier zip : clea-add-button avec éditeur wp_editor (zip).

Que voulons-nous faire ?

Notre page de réglages est capable d’afficher tous les types de champs sauf les choix de couleur. Nous voulons donc pouvoir choisir une couleur et même définir son opacité. Et pour simplifier la vie de l’administrateur du site, il faut qu’on lui dise quelles sont les couleurs utilisées par son thème, en les intégrant dans une palette sous le color picker.

Par ailleurs, notre page de réglages devra afficher les éléments complémentaires définis pour chaque champs, tels que « helper » qui contient un texte d’aide complémentaire.

Identifier les couleurs utilisées par le site

Les paramètres du thème courant sont stockés par WordPress et récupérables avec la fonction get_theme_mods(). Cette fonction nous donne un array contenant tous les paramètres, dont certains sont des couleurs.

Nous lisons donc l’array et pour chaque valeur, nous regardons s’il s’agit d’une couleur avec la fonction sanitize_hex_color_no_hash(). Cette fonction renvoie « NULL » si elle ne trouve pas un élément en hexadécimal à 3 ou 6 caractères. A chaque fois qu’elle trouve un élément non NULL, on le place dans l’array qui sera retourné pour former notre palette de couleurs.

/**********************************************************************

* find the colors used in the website's theme

**********************************************************************/
function clea_presentation_get_current_colors() {

	// to get all the current theme data in an array
	$mods = get_theme_mods();

	$color = array() ;
	
	foreach ( $mods as $key => $values ) {
		
		if ( !is_array( $values ) ) {
			
			if ( is_string( $values ) && trim( $values ) != '' ) {
				
				$hex = sanitize_hex_color_no_hash( $values ) ;
				
				if ( trim( $hex ) != '' ) {
					
					$color[ $key ] = $hex ;

				}

			}
		} 
	}

	// remove duplicate colors
	$current_colors = array_unique( $current_colors ) ;
	
	return $color ;
	
}

Pour vérifier que c’est une bonne solution, , nous ajoutons le code suivant à la fonction clea_add_button_options_page()   :

$colors = clea_add_button_get_current_colors() ;
echo "<hr /><p>Arguments</p><pre>";
print_r( $colors ) ;	
echo "</pre><hr />";

Ce code va afficher l’array de couleurs en bas de la page d’options :

Array
(
   [background_color] => ffffff
   [color_palette_primary] => 4c858d
   [color_palette_tertiary] => 423432
   [color_palette_dark_font] => ed693b
)

Nous disposons donc des informations pour constituer notre palette par défaut.

Afficher des champs « color picker »

Nous allons utiliser le « Alpha Color Picker for WordPress » développé par Braad Martin. Pour comprendre comment l’intégrer, j’ai utilisé à la fois les explications de Braad Martin et Add an Alpha RGBa Color Picker to a WordPress Plugin Input Field.

Le code pour afficher le color picker

On ajoute le cas ‘color’ comme suit :

case 'color' :

	// get the colors used by the theme
	$current_colors = clea_presentation_get_current_colors() ;
	$data_palette = "";
	
	// the color palette must be a string with colors and | separator
	// "#222|#444|#00CC22|rgba(72,168,42,0.4)" would be ok
	foreach ( $current_colors as $color ) {
		
		$data_palette .= $color . '|' ;
		
	}
	
	$data_palette = rtrim( $data_palette, '|' ) ;
	
	
	// uses https://github.com/BraadMartin/components/tree/master/alpha-color-picker
	printf( '<input type="text" class="alpha-color-picker" name="%2$s" value="%1$s" data-palette="%5$s" data-default-color="%4$s" data-show-opacity="true" />', sanitize_text_field( $value ), $name, $field, $arguments['default'], $data_palette  ) ;
	break ;	

A ce stade, celà affiche un champs de type ‘text’ avec à l’intérieur la couleur par défaut définie dans le champs. Il nous faut maintenant ajouter la feuille de style et le programme javascript conçus par le créateur de l’Alpha color Picker et un petit script en JQuery.

Les compléments à intégrer dans notre extension

Dans le répertoire « /admin » du plugin, créer les sous-répertoires « /css  » et « /js « .

Télécharger le fichier zip du dépôt « components » de Braad Martin ici sur un PC. Décompresser le fichier zip puis dans le sous-répertoire « alpha-color-picker » copier alpha-color-picker.css   et alpha-color-picker.js  respectivement dans les répertoires /admin/css  et /admin/js  de l’extension.

Les fichiers à créer

Nous devons créer deux fichiers :

  • un fichier (clea-add-button-color-trigger.js par exemple) qui contiendra le JQuery nécessaire à l’affichage
  • un fichier (clea-add-button-admin-enqueue.php par exemple) qui sera appelé par le fichier principal de l’extension et qui chargera la feuille de style et les scripts JavaScript nécessaires.

Le fichier /admin/js/clea-add-button-color-trigger.js  contient :

// source  https://github.com/BraadMartin/components/tree/master/alpha-color-picker
jQuery( document ).ready( function( $ ) {
    $( 'input.alpha-color-picker' ).alphaColorPicker();
});

Quant au fichier /admin/js/clea-add-button-admin-enqueue.php , il contient

add_action( 'admin_enqueue_scripts',  'clea_add_button_admin_enqueue_scripts' );


function clea_add_button_admin_enqueue_scripts( $hook ) {
	

	// to find the right name, go to the settings page and inspect it
	// the name is somewhere in the <body class="">
	// it will always begin with settings_page_
	if( 'settings_page_my-plugin' != $hook ) { 
	
        // echo "not the right page, this is : " ;
		// echo $hook ;
		return;
		
    }

    // for the alpha color picker
    // source : https://github.com/BraadMartin/components/tree/master/alpha-color-picker
    wp_enqueue_style(
        'alpha-color-picker',
        CLEA_ADD_BUTTON_DIR_URL . '/admin/css/alpha-color-picker.css', 
        array( 'wp-color-picker' ) // You must include these here.
    );

	wp_enqueue_script(
        'alpha-color-picker',
        CLEA_ADD_BUTTON_DIR_URL . '/admin/js/alpha-color-picker.js', 
        array( 'jquery', 'wp-color-picker' ), // You must include these here.
        null,
        true
    );
	
    // This is the JS file that will contain the trigger script.
    // Set alpha-color-picker as a dependency here.
    wp_enqueue_script(
        'clea-add-button-admin-color-js',
        CLEA_ADD_BUTTON_DIR_URL . '/admin/js/clea-add-button-color-trigger.js', 
        array( 'alpha-color-picker' ),
        null,
        true
    );
	
}

La condition if( ‘settings_page_my-plugin’ != $hook ) permet de ne pas charger le style et le JavaScript si on n’est pas sur la page d’options de notre extension.

Enfin, dans clea-add-button.php , nous ajoutons la ligne qui démarrera clea-add-button-admin-enqueue.php   :

// load styles and scripts for the admin
require_once CLEA_ADD_BUTTON_DIR_PATH . 'admin/clea-add-button-admin-enqueue.php';

le résultat

Notre page d’option affiche maintenant la couleur par défaut sous une forme différente :

Le champ "color" affiche bien une couleur maintenant.

Le champ « color » affiche bien une couleur maintenant.

Si on clique sur la couleur, un « color picker » s’ouvre. Il affiche la couleur par défaut définie dans le champ 3. On observe qu’il y a une palette de couleur en dessous, qui correspond effectivement aux couleurs du thème sur lequel j’essaie cette extension. Et en dessous, on voit une barre qui permet de gérer la transparence de la couleur choisie.

Le champ "color" affiche un "color picker" complet.

Le champ « color » affiche un « color picker » complet.

Ici nous sélectionnons la couleur orange du thème et nous demandons à ce que sa transparence soit 71%.

Choix d'une couleur de la palette puis réglage de la transparence

Choix d’une couleur de la palette puis réglage de la transparence

Ca fonctionne parfaitement et la nouvelle couleur s’enregistre correctement.

Afficher les informations complémentaires

Chaque champ affiché dans notre page d’options est défini par un array :

array(
	'field_id' 		=> 'field-2-3', 
	'label'			=> __( 'Field three : color', 'clea-add-button' ), 
	'field_callbk'	        => 'clea_add_button_settings_field_callback', 
	'menu_slug'		=> 'my-plugin', 
	'section_name'	        => 'section-2',
	'type'			=> 'color',
	'helper'		=> __( 'help 2-3', 'clea-presentation' ),
	'default'		=> 'rgba(0,0,0,0.85)'			
)

Nous utilisons toutes les clés de cet array sauf deux (‘label’ et ‘helper’). Ces deux clés contiennent respectivement le texte à afficher systématiquement pour expliciter ce qu’il faut faire et un texte d’aide complémentaire.

Pour l’afficher, avant le champs à remplir, j’ajoute le code suivant dans la fonction clea_add_button_settings_field_callback( $arguments  )  :

// If there is a help text and / or description
printf( '<span class="field_desc">' ) ;

if( isset( $arguments['helper'] ) && $helper = $arguments['helper'] ){
	printf( '<img src="%1$s/images/question-mark.png" class="alignleft" id="helper" alt="help" title="%2$s" data-pin-nopin="true">',CLEA_ADD_BUTTON_DIR_URL, $helper ) ;
}

// If there is a description
if( isset( $arguments['label'] ) && $description = $arguments['label'] ){
	printf( ' %s', $description ); // Show it
}

printf( '</span>' ) ;

La condition if( isset( $arguments[‘helper’] ) && $helper = $arguments[‘helper’] )  vérifie que $arguments[‘helper’] est défini ET qu’il n’est pas vide.

J’ai placé un fichier question-mark.png dans le répertoire /images de l’extension.

Le résultat n’est pas très joli :

Pages d'option pas très belle....

Il faut donc que j’ajoute une feuille de style pour améliorer la page d’options.

Créer une feuille de style pour la page d’options

Dans le fichier /admin/js/clea-add-button-admin-enqueue.php , nous ajoutons une ligne pour charger la feuille de style de notre page de réglages :

// options page style
wp_enqueue_style(
	'clea-add-button-admin-style',
	CLEA_ADD_BUTTON_DIR_URL . '/admin/css/clea-add-button-admin.css'
);

et dans le fichier /admin/css/clea-add-button-admin.css

/**
 * Settings page (admin)
 */
 
span.field_desc {
	display: block;
	font-style: italic;
	margin-bottom: 5px;
}

img#helper {
	margin-right: 5px;
}

Le résultat est lisible maintenant :

Page de réglage de l'extension avec feuille de style

Et maintenant ?

A ce stade notre extension correspond au contenu de ce fichier zip : clea-add-button V0.2 (zip).

Notre page de réglages fonctionne. Il ne reste plus que quelques améliorations à apporter. Ce sera l’objet du prochain article de cette série, .

page de réglages d’une extension WordPress : formats de champs différents

page de réglages d’une extension WordPress : formats de champs différents

Notre extension a été démarrée dans les premiers articles de cette série (). A ce stade, elle affiche uniquement des champs de type « texte » et n’affiche pas le contenu des arguments supplémentaires que l’on peut ajouter au champs.

Vous pouvez récupérer l’extension à ce stade dans ce fichier zip : clea-add-button V0.1 (zip)

Nous allons donc voir maintenant comment afficher des champs de type textarea, select, checkbox, radio button, wysiwig.

Modifier la fonction de restitution des champs

Dans le fichier « /admin/clea-add-button-settings-page.php « , il faut modifier la fonction clea_add_button_settings_field_callback( $arguments  )  pour qu’elle s’adapte à différents types de champs.

Nous utilisons la commande « switch » qui choisira l’action à réaliser selon le ‘type’ de champs à restituer :

switch( $arguments['type'] ){
	
	case 'text' : 
		echo "<input type='text' name='my-plugin-settings[$field]' value='$value' />";	
		break ;
	default : 
		printf( esc_html__( 'This field is type <em>%s</em> and could not be rendered.', 'clea-add-button' ), $arguments['type']  );
}

Ca fonctionne : le champs 1-1 est restitué comme un texte mais pas les autres puisque nous n’avons pas défini leur type pour l’instant.

Il va donc falloir que je modifie l’array qui définit les champs, dans la fonction clea_add_button_settings_fields_val() . Je veux que tous les champs soient définis par un array avec la forme suivante :

array(
	'field_id' 		=> 'field-1-1', 							
	'label'			=> __( 'Field One', 'clea-add-button' ), 	
	'field_callbk'	=> 'clea_add_button_settings_field_callback', 					
	'menu_slug'		=> 'my-plugin', 							
	'section_name'	=> 'section-1',
	'type'			=> 'text',
	'helper'		=> __( 'help 1-1', 'clea-presentation' ),
	'default'		=> ''			
)

J’en profite pour créer des champs avec tous les types que je vais définir dans cet article :

  • textarea,
  • select,
  • checkbox,
  • radio,
  • wysiwig
  • color picker

Et voici maintenant le nouveau contenu de la fonction clea_add_button_settings_fields_val()  :

function clea_add_button_settings_fields_val() {

	$section_1_fields = array (
		array(
			'field_id' 		=> 'field-1-1', 							
			'label'			=> __( 'Field One', 'clea-add-button' ), 	
			'field_callbk'	=> 'clea_add_button_settings_field_callback', 					
			'menu_slug'		=> 'my-plugin', 							
			'section_name'	=> 'section-1',
			'type'			=> 'text',
			'helper'		=> __( 'help 1-1', 'clea-presentation' ),
			'default'		=> ''			
		),	
		array(
			'field_id' 		=> 'field-1-2',
			'label'			=> __( 'Field Two : textarea', 'clea-add-button' ),
			'field_callbk'	=> 'clea_add_button_settings_field_callback', 
			'menu_slug'		=> 'my-plugin', 
			'section_name'	=> 'section-1',
			'type'			=> 'textarea',
			'helper'		=> __( 'help 1-2', 'clea-presentation' ),
			'default'		=> ''			
		),
	);
	
	$section_2_fields = array (
		array(
			'field_id' 		=> 'field-2-1', 
			'label'			=> __( 'Field One : radio', 'clea-add-button' ), 
			'field_callbk'	=> 'clea_add_button_settings_field_callback', 
			'menu_slug'		=> 'my-plugin', 
			'section_name'	=> 'section-2',
			'type'			=> 'radio',
			'helper'		=> __( 'help 2-1', 'clea-presentation' ),
			'default'		=> ''						
		),
		array(
			'field_id' 		=> 'field-2-2', 
			'label'			=> __( 'Field Two : wysiwig', 'clea-add-button' ), 
			'field_callbk'	=> 'clea_add_button_settings_field_callback', 
			'menu_slug'		=> 'my-plugin', 
			'section_name'	=> 'section-2',
			'type'			=> 'wysiwig',
			'helper'		=> __( 'help 2-2', 'clea-presentation' ),
			'default'		=> ''			
		),
				array(
			'field_id' 		=> 'field-2-3', 
			'label'			=> __( 'Field three : color', 'clea-add-button' ), 
			'field_callbk'	=> 'clea_add_button_settings_field_callback', 
			'menu_slug'		=> 'my-plugin', 
			'section_name'	=> 'section-2',
			'type'			=> 'color',
			'helper'		=> __( 'help 2-3', 'clea-presentation' ),
			'default'		=> ''			
		),
	);
	

	$section_fields = array(
		'section-1'	=> $section_1_fields,
		'section-2' => $section_2_fields
	) ;	

	
	
	return $section_fields ;
}

On a défini un champs pour chaque type qu’il faudra pouvoir afficher dans notre page de réglages.

Afficher des champs « textarea »

dans la fonction clea_add_button_settings_fields_val() , à l’intérieur du « switch », j’ajoute le cas ‘textarea’.

L’affichage d’un champs de type textarea nécessite les arguments suivants :

Pour l’affichage du contenu, on utilisera quelque chose comme :

<textarea name="whatever"><?php echo esc_textarea( $description ); ?></textarea>

Noter que l’on utilise la fonction esc_textarea() pour interdire qu’un caractère présent dans la variable $description  puisse être interprété comme du HTML.

Output en sécurité avec esc_…()

Pour plus de détails, voir cette page WordPress en anglais sur la sanitation et la validation de données.

Dans notre cas, nous restituerons les valeurs de la manière suivante :

Affichage du « textarea » plus précis

Dans la référence HTML5 du W3C, la page dédiée à <textarea> indique une multitude d’arguments pour définir sa forme. Et les attributs globaux, applicables à tous les éléments HTML5 contiennent entre autre « id » et « value ». Nous allons au minimum vouloir définir « rows » et « cols », respectivement le nombre de lignes et de colonnes de la zone de texte à définir. Au final, l’expression de notre textarea sera sous la forme : 

<textarea name="whatever" id="id" rows="4" cols="80" value=""><?php echo esc_textarea( $description ); ?></textarea>

Pour tous nos champs, les attributs devront prendre une valeur liée à la définition du champs. J’utilise printf pour rendre plus simple la définition de ce qui doit être affiché.

Et voici notre fonction modifiée pour utiliser esc_attr pour le cas ‘text’ et pour afficher correctement notre zone textarea :

function clea_add_button_settings_field_callback( $arguments  ) {

	$settings = (array) get_option( 'my-plugin-settings' );
	$field = $arguments['field_id'] ;
	$value = $settings[$field] ;

	// for development only
	if ( ENABLE_DEBUG ) {
		
		echo "<hr /><pre>";
		print_r( $arguments ) ;	
		echo "</pre><hr />";
	}
	
	$name = 'my-plugin-settings['. $field . ']' ;
	
	switch( $arguments['type'] ){
		
		case 'text' : 
			printf( '<input type="text" id="%3$s" name="%2$s" value="%1$s" />', esc_attr( $value ), $name, $field );
			break ;
		case 'textarea' : 
			printf( '<textarea name="%2$s" id="%3$s" rows="4" cols="80" value="%1$s">%1$s</textarea>', esc_textarea( $value ), $name, $field );
			break ;
		
		default : 
			printf( esc_html__( 'This field is type <em>%s</em> and could not be rendered.', 'clea-add-button' ), $arguments['type']  );
	}
}

A ce stade, notre page de réglages affiche :

Affichage correct d'un champs text et d'un champs textarea

Affichage correct d’un champs text et d’un champs textarea

Correction d’une notice PHP

Query Monitor (cf l’article précédent de cette série «  » indique 3 notices PHP. Ce sont des erreurs bénignes qu’il faut corriger.

Les trois notices portent sur des index indéfinis pour field-2-1, field-2-2 et field-2-3, sous la forme « Undefined index: field-2-1 ». Ces trois champs n’ont jamais été définis puisqu’on n’a pas encore pu leur attribuer une valeur. Cependant, il n’est pas normal que notre code traite des valeurs indéfinies sans « s’en rendre compte ».

Dans cet article de code.tutsplus, je vois qu’ils font deux vérifications avant de lire la valeur de l’option. La première consiste à vérifier qu’il existe bien des options pour notre réglage (‘my-plugin-settings’ pour moi, ‘sandbox_theme_display_options’ pour eux :

if( false == get_option( 'sandbox_theme_display_options' ) ) {  
    add_option( 'sandbox_theme_display_options' );
}

Cette vérification est réalisée au moment du ‘admin_init’, dans notre cas dans la fonction clea_add_button_admin_init()  modifiée comme suit :

function clea_add_button_admin_init() {
  
	if( false == get_option( 'my-plugin-settings' ) ) {  
		add_option( 'my-plugin-settings' );
	}
	
	register_setting( 'my-settings-group', 'my-plugin-settings' ) ;
	
	$set_sections = clea_add_button_settings_sections_val() ;
 
	// add_settings_section
	foreach( $set_sections as $section ) {
		
		add_settings_section( 
			$section[ 'section_name' ], 
			$section[ 'section_title' ] ,
			$section[ 'section_callbk' ], 
			$section[ 'menu_slug' ]
		);
		
	}	

	$set_fields = clea_add_button_settings_fields_val() ;
	
	// add the fields
	foreach ( $set_fields as $section_field ) {

		foreach( $section_field as $field ){

			add_settings_field( 
				$field['field_id'], 
				$field['label'], 
				$field['field_callbk'],  
				$field['menu_slug'], 
				$field['section_name'],
				$field
			);
		}

	}	
}

La seconde vérification porte sur l’option du champs en question :

// First, we read the social options collection
$options = get_option( 'sandbox_theme_social_options' );
     
// Next, we need to make sure the element is defined in the options. If not, we'll set an empty string.
$url = '';
if( isset( $options['twitter'] ) ) {
    $url = $options['twitter'];
} // end if

Cette partie là est réalisée dans la fonction « callback » du champs ‘twitter’.

Là dessus, j’ai longtemps bloqué car je dois vérifier si $settings[ $field ] est « isset » et pour une raison que j’ignorais ce n’était jamais le cas, même lorsqu’il y avait bien une valeur… Et puis je suis tombée sur cette question dans wordpress.stackexchange et j’ai enfin compris comment faire (mais pas franchement pourquoi !).

Ma fonction clea_add_button_settings_field_callback( $arguments ) contient maintenant une vérification au début. Si $options[ « $field » ] est « set », $value  prend la valeur de $settings[ $field ] . Dans le cas contraire, elle prend la valeur par défaut du champs.

function clea_add_button_settings_field_callback( $arguments  ) {


	$settings = (array) get_option( "my-plugin-settings" );
	$field = $arguments[ 'field_id' ] ;
	
	// for development only
	if ( ENABLE_DEBUG ) {
		
		echo "<hr /><p>Arguments</p><pre>";
		print_r( $arguments ) ;	
		echo "</pre><hr />";
		echo "<hr /><p>Options</p><pre>";
		print_r( $settings ) ;	
		echo "</pre><hr />";
	}
		
	// set a $options array with the field id as it's key
	if ( !empty( $settings ) ) {
		foreach ( $settings as $key => $option ) {
			$options[$key] = $option;
		}
	}	
	
	// now check if $options[ $field ] is set
	if( isset( $options[ "$field" ] ) ) {
			$value = $settings[ $field ] ;
	} else {
			// set the value to the default value
			$value = $arguments[ 'default' ] ;
	}	

	
	$name = 'my-plugin-settings['. $field . ']' ;

	switch( $arguments['type'] ){
		
		case 'text' : 
			printf( '<input type="text" id="%3$s" name="%2$s" value="%1$s" />', esc_attr( $value ), $name, $field );
			break ;
		case 'textarea' : 
			printf( '<textarea name="%2$s" id="%3$s" rows="4" cols="80" value="%1$s">%1$s</textarea>', esc_textarea( $value ), $name, $field );
			break ;
		
		default : 
			printf( esc_html__( 'This field is type <em>%s</em> and could not be rendered.', 'clea-add-button' ), $arguments['type']  );
	}
}

Les notices PHP pour les champs qui n’ont pas encore pu être saisis ont maintenant disparu.

Afficher des champs « select »

Notre champs select sera restitué sous la forme :

<select name="lenom" id="field-id" multiple="">
  <option value="volvo">Volvo</option>
  <option value="saab">Saab</option>
  <option value="vw">VW</option>
  <option value="audi" selected>Audi</option>
</select>

Si les options ne sont pas fixes (cas où il y a plusieurs champs select), il faut pouvoir les ajouter dans l’array de définition du champs. Je crée un troisième champs dans la section 1 avec les caractéristiques suivantes :

array(
	'field_id' 		=> 'field-1-3', 
	'label'			=> __( 'Field three : select', 'clea-add-button' ), 
	'field_callbk'	=> 'clea_add_button_settings_field_callback', 
	'menu_slug'		=> 'my-plugin', 
	'section_name'	=> 'section-1',
	'type'			=> 'select',
	'helper'		=> __( 'help 1-3', 'clea-presentation' ),
	'default'		=> '',
	'options'		=> array(
						__( 'Choix 1', 'clea-add-button' ) ,
						__( 'Choix 2', 'clea-add-button' )	,
						__( 'Choix 3', 'clea-add-button' )
					),				
),

Pour le visualiser, j’ajoute le cas ‘select’ comme suit :

case 'select': // If it is a select dropdown

	if( ! empty ( $arguments['options'] ) && is_array( $arguments['options'] ) ){
	
	printf( '<select id="%2$s" name="%1$s">', $name, $field );
	foreach( $arguments['options'] as $item ) {
		$selected = ( $value	 == $item ) ? 'selected="selected"' : '';
		echo "<option value='$item' $selected>$item</option>";
	}
	echo "</select>";	
	
	} else {
		echo __( 'Indiquer les options dans la définition du champs', 'clea-add-button' ) ;
	}
	break;

Et voilà maintenant la section 1 de ma page de réglage :

Affichage d'un champs "select"

Affichage d’un champs « select »

Afficher des champs « checkbox »

Notre champs checkbox sera restitué sous la forme :

<input type="hidden" name="my-plugin-settings[field-1-4]" id="field-1-4" value="0"> 
<input id="field-1-4" name="my-plugin-settings[field-1-4]" type="checkbox">

et si le champs est coché, il prendra la forme (observer le « checked » juste après « input » :

<input checked="checked" id="field-1-4" name="my-plugin-settings[field-1-4]" type="checkbox">

J’ajoute un quatrième champs dans la section 2 avec un type checkbox :

array(
	'field_id' 		=> 'field-1-4', 
	'label'			=> __( 'Field four : checkbox', 'clea-add-button' ), 
	'field_callbk'	=> 'clea_add_button_settings_field_callback', 
	'menu_slug'		=> 'my-plugin', 
	'section_name'	=> 'section-1',
	'type'			=> 'checkbox',
	'helper'		=> __( 'help 1-4', 'clea-presentation' ),
	'default'		=> '',
)

Pour le visualiser, j’ajoute le cas ‘checkbox’ comme suit :

case 'checkbox' : 
	printf( '<input type="hidden" name="%1$s" id="%2$s" value="0" />', $name, $field ) ;			
	$checked = '' ;
        if( $value ) { $checked = ' checked="checked" ' ; }
	printf( ' <input %3$s id="%2$s" name="%1$s" type="checkbox" />', $name, $field, $checked ) ;
	break ;

Et voilà maintenant la section 1 de ma page de réglage contient un champ texte, un champ textarea, un champ select et un champ checkbox :

Affichage d'un champs "checkbox"

Affichage d’un champs « checkbox »

Afficher des champs « radio button »

Notre champs radio sera restitué sous la forme :

<span class="radio">
	<label><input type="radio" value="Choix 1" name="my-plugin-settings[field-2-1]" checked=""> Choix 1</label><br>
	<label><input type="radio" value="Choix 2" name="my-plugin-settings[field-2-1]"> Choix 2</label><br>
	<label><input type="radio" value="Choix 3" name="my-plugin-settings[field-2-1]"> Choix 3</label><br>
</span>

Si les options ne sont pas fixes, il faut pouvoir les ajouter dans l’array de définition du champs. Je modifie le premier champ de la section 2 comme pour le champs de type radio, en y ajoutant des options.

Pour le visualiser, j’ajoute le cas ‘radio’ comme suit :

case 'radio' : // radio buttons
	if( ! empty ( $arguments['options'] ) && is_array( $arguments['options'] ) ){
		
		echo "<span class='radio'>" ;
		foreach( $arguments['options'] as $key => $label ){
			
			$items[] = $label ;
		}

		foreach( $arguments['options'] as $item) {
			$checked = ( $value == $item ) ? 'checked' : '';
			printf( '<label><input type="radio" value="%2$s" name="%1$s" %3$s> %2$s</label><br />', $name, $item, $checked );
		}
		echo "</span>" ;
	}
	break ;

Et voilà maintenant la section 2 de ma page de réglage contient un premier champs radio correctement présenté :

Affichage d'un champs "radio"

Affichage d’un champs « radio »

Afficher des champs « wysiwig « 

Notre champs wisiwig correspond à un éditeur, un peu comme lorsqu’on crée un article dans WordPress. Il est restitué par la fonction wp_editor de WordPress. Ici j’ai choisi de ne pas ajouter d’arguments spécifiques.

Pour le visualiser, j’ajoute le cas ‘wysiwig’ comme suit :

case 'wysiwig' :

	// sanitize data for the wp_editor
	$content = wp_kses_post( $value ) ;
	
	$args = array(
		'textarea_name' => $name
	) ;
	
	wp_editor( $content, $field, $args );		
	break ;

Le Codex pour wp_editor() indique que l’ID de l’éditeur ne peut contenir que des minuscules et des tirets bas (underscores). J’ai donc modifié le ‘field_id’ pour qu’il devienne field_2_2.

On notera que $value est nettoyé avec la fonction wp_kses_post(), qui permet entre autres d’avoir des images dans le texte.

Et voilà maintenant la section 2 contient un éditeur de texte :

Affichage d'un champs "wp-editor"

Affichage d’un champs « wp-editor »

Et maintenant

Nous verrons dans le prochain article de cette série () comment restituer le dernier champs comme un  color picker, et aussi comment afficher les arguments supplémentaires.

L’extension à ce stade est disponible, compressée en zip : clea-add-button avec éditeur wp_editor (zip)

Extension WordPress : méthodes pour le débogage

Extension WordPress : méthodes pour le débogage

Lorsqu’on crée une extension (ou un thème) WordPress, il est indispensable de prévoir des moyens de déboguer efficacement. Nous allons voir ici quelques méthodes applicables, telles que l’affichage du contenu de variables dans une page du tableau de bord WordPress, l’utilisation de debug.log de WordPress ou l’utilisation d’extensions WordPress telles que  Debug Bar et Query Monitor.

Tous les exemples qui suivent sont utilisés pour l’extension créée au fil des articles de cette série (). La version avec le débogage testé dans cet article est dans ce fichier zip : clea-add-button V0.1 clea-add-button V0.1 (zip).

Utiliser les outils de debogage WordPress

Sur un site de développement (mais jamais sur un site de « production » utilisable par nos internautes cibles), on modifie wp-config.php pour que le debogage soit réalisé et que les erreurs s’affichent lors de l’affichage des pages du site (front ou back). Par défaut, les paramètres suivants sont réglés sur « false » :

define('WP_DEBUG', false ); 
define('WP_DEBUG_DISPLAY', false);

Dans ce cas, s’il y a une erreur importante, notre page web affiche un contenu blanc, sans aucune indication du type d’erreur rencontré. Si je met ces paramètres à ‘true’, j’aurai un affichage de l’erreur à l’écran et je pourrai y remédier :

Erreur fatale avec wp-config.php réglé pour que debug trueExemple : je crée volontairement une erreur (par exemple en enlevant un « ; » à la ligne 45 de clea-add-button-settings-page.php. Je recharge la page d’options ou je vais sur le site et le site a disparu. A la place, il y a une page blanche, avec le message « Fatal error: syntax error, unexpected ‘$set_sections’ (T_VARIABLE) in /home/cecilebo/test1/wp-content/plugins/clea-add-button/admin/clea-add-button-settings-page.php on line 47″. Je sais immédiatement dans quel fichier aller corriger l’erreur. Je regarde les lignes qui précèdent la ligne 47 : la 46 est vide et c’est plutôt simple d’ajouter le « ; » manquant en ligne 45.

Donc, dès qu’on est sur un site de développement, on régle les paramètres de wp-config.php pour afficher les erreurs :

define('WP_DEBUG', true );  
define('WP_DEBUG_DISPLAY', true);

On peut aussi régler la ligne suivante à « true » :

define('WP_DEBUG_LOG', true);

Dans ce cas, les erreurs sont stockées dans un fichier debug.log situé dans le répertoire /wp-content. C’est pratique si on doit absolument intervenir sur un site de production et qu’on ne peut pas avoir WP_DEBUG_DISPLAY réglé à « true ». Mais ça oblige à aller sans arrêt éditer le contenu de debug.log pour voir ce qui se passe. Je n’aime pas beaucoup, sauf cas particuliers comme lorsque je veux afficher des contenus de variables dans un fichier (voir plus loin).

Utilisation d’extensions spécialisées

l’extension « Debug Bar »

j’utilise depuis longtemps l’extension ‘Debug Bar‘. Elle ajoute un élément « debug » à gauche du nom Jde l’utilisateur dans le tableau de bord WordPress. Si on clique dessus, et que WP_DEBUG est réglé à ‘true’, on voit s’afficher la liste des notices et warnings auxquels il faut qu’on fasse attention. Lorsqu’il y a des warnings, l’élément « debug » devient rouge pour nous alerter.

Avantages :

Inconvénients :

  • on doit jongler entre différents écrans pour visualiser ce qui se passe dans notre site.

Debug Bar est très bien, mais il y a encore mieux !

La solution idéale : l’extension ‘Query Monitor’

Depuis que j’ai découvert cette extension, je ne lui ai pas trouvé un seul défaut. Elle permet de recueillir toutes les informations nécessaires au développement tout en étant pratique. C’est surtout l’interface utilisateur qui fait la différence.

Pour plus d’informations, voir sur WordPress.org, ici. Je note que les FAQ indiquent que les compléments de Debug Bar puvent être utilisés avec Query Monitor, sans que Debug Bar soit présent. Et il existe aussi des compléments pour Query Monitor. Je note en particulier les compléments suivants, que je n’ai jamais essayés :

Pour développer et valider selon les utilisateurs

Il arrive que j’utilise « User Switching » lorsque j’ai besoin de tester avec différents rôles d’utilisateur.

Afficher le contenu d’une variable pour aider au développement / débogage

Ce n’est pas toujours simple de savoir ce que contient une variable définie par notre programme ou par WordPress. C’est en particulier difficile lorsque la variable est un array, dont on ne connait pas la structure, ou pire une chaîne de caractères « sérialisée » (« serialized data » en anglais) comme le contenu de get_option .

Pour afficher des variables, on a plusieurs options :

Afficher la variable directement dans la page que l’on crée

C’est une solution simple. Par exemple, dans clea-add-button-settings-page.php, pour définir le contenu de la fonction clea_add_button_settings_field_callback( $arguments  ), qui affiche les différents champs, j’ai affiché le contenu de l’array $arguments :

echo "<hr /><pre>";
print_r( $arguments ) ;	
echo "</pre><hr />";

l’ajout de <pre> et </pre> permet un affichage propre de l’array.

Mais l’inconvénient d’un tel choix est qu’on doit ensuite commenter toutes les lignes de débogage. J’ai donc fait le choix de définir une constante en début de fichier :

/**********************************************************************
* DEBUG ?
***********************************************************************/

define('ENABLE_DEBUG', true);	// if true, the script will echo debug data

et ma fonction function clea_add_button_settings_field_callback( $arguments )  contient :

function clea_add_button_settings_field_callback( $arguments ) {

$settings = (array) get_option( 'my-plugin-settings' );
$field = $arguments['field_id'] ;
$value = esc_attr( $settings[$field] );

// for development only
if ( ENABLE_DEBUG ) {

echo "<hr /><pre>";
print_r( $arguments ) ; 
echo "</pre><hr />";
}

echo "<input type='text' name='my-plugin-settings[$field]' value='$value' />"; 
}

Comme ça, si j’ai réglé ENABLE_DEBUG à true, je voies le contenu de l’array et sinon je suis en mode utilisation normale de l’extension :

C’est une bonne solution, que je n’ai trouvée que récemment. Mais elle ne fonctionne pas si je n’ai pas une page dédiée à l’extension dans le tableau de bord WordPress. Il peut donc être utile d’afficher ailleurs le contenu des variables. Dans ce cas, on utilisera une extension spécialisée.

Utiliser l’extension Query Monitor Extend

Installer Query Monitor Extend à partir de son fichier zip puis l’activer.

Utiliser l’extension Query Monitor: Checking Variable

Installer Query Monitor: Checking Variable puis l’activer.

Une page de réglage « check variables » apparaît dans « Réglages ».

Pour les deux exemples de réglage qui suivent, j’ai ajouté une ligne à la fonction clea_add_button_settings_section_callback( $args  ) :

console( $args );

On peut faire apparaître les variables dans le pied de page comme dans le réglage qui suit :

On peut aussi préférer afficher les variables dans Query Monitor comme dans le réglage qui suit :

C’est pratique comme système.

Et maintenant ?

Une fois qu’on sait ce que contiennent nos variables, tout devient plus simple !

Nous allons poursuivre le développement de l’extension « Add Button » et améliorer la page de réglage pour qu’elle puisse afficher des formats de champs autres que texte. Ce sera l’objet du prochain article de cette série .