403-error

Des images qui renvoient une erreur 403

Aujourd’hui, j’édite un ancien article et le prévisualise pour voir les changements : je m’aperçois alors que l’image de l’article ne s’affiche plus.

Ni une ni deux, je sors mon terminal et tente de récupérer l’image avec wget. Erreur 403. Je vérifie la configuration Apache et Varnish, rien à signaler (et surtout rien n’avait été modifié).

Je vérifie alors le fichier via FTP : il se trouve qu’il ne possédait pas les bons droits!

Evidemment, avec un chmod 600, cela ne risque pas de s’afficher… Les autres images, celles qui s’affichaient bien et renvoyaient un code 200, étaient bien chmodées en 644.

Solution : CHMOD

Il faut donc chmoder l’ensemble des fichiers du répertoires, 640 pour les images ce sera parfait :

find /home/public_html/wp-content/uploads -type f -exec chmod 640 {} \;

et pour les répertoires, 750 c’est correct :

find /home/public_html/wp-content/uploads -type d -exec chmod 750 {} \;

Notez la différence de syntaxe : on utilise f pour les fichiers (files) et d pour les répertoires (directory).

WordPress : récupérer la liste emails des membres et commentateurs photo

WordPress : afficher la date en français dans le thème (sans utiliser le pack de langue ou setlocale())

Wordpress icon

Cela fait des années que j’utilise le même thème graphique pour mon site et je n’ai jamais vraiment pris le temps de traduire la date de publication ou de mise à jour des articles en français.

Le tutoriel qui suit ne s’adresse qu’à un cercle réduit de développeurs : il est évidemment bien plus aisé d’installer WordPress en français (avec le langage pack qui convient) ou d’utiliser la fonction PHP setlocale() comme je l’avais fait précédemment avec WP-Date FR.

Dans mon cas bien précis, je n’ai pas accès aux locales étant donné que le serveur est installé en anglais.

Je ne souhaite pas non plus installer la locale française, qui serait alors ajoutée à tous mes paquets Debian.

Et je ne souhaite pas non plus utiliser la traduction française de WordPress. It’s coding time !

La fonction sky_date_french()

Vous pouvez placer cette fonction dans le fichier functions.php de votre thème :

/*
|-----------------------------------------------------------------------
| Sky Date in French by Matt - www.skyminds.net
|-----------------------------------------------------------------------
|
| Returns or echoes the date in French format (dd/mm/YYYY) for WordPress themes.
|
*/
function sky_date_french($format, $timestamp = null, $echo = null) {
	$param_D = array('', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam', 'Dim');
	$param_l = array('', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi', 'Dimanche');
	$param_F = array('', 'Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre');
	$param_M = array('', 'Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Jun', 'Jul', 'Aoû', 'Sep', 'Oct', 'Nov', 'Déc');
	$return = '';
	if(is_null($timestamp)) { $timestamp = mktime(); }
	for($i = 0, $len = strlen($format); $i < $len; $i++) {
		switch($format[$i]) {
			case '\\' : // fix.slashes
				$i++;
				$return .= isset($format[$i]) ? $format[$i] : '';
				break;
			case 'D' :
				$return .= $param_D[date('N', $timestamp)];
				break;
			case 'l' :
				$return .= $param_l[date('N', $timestamp)];
				break;
			case 'F' :
				$return .= $param_F[date('n', $timestamp)];
				break;
			case 'M' :
				$return .= $param_M[date('n', $timestamp)];
				break;
			default :
				$return .= date($format[$i], $timestamp);
				break;
		}
	}
	if(is_null($echo)) { return $return;} else { echo $return;}
}Code language: PHP (php)

Lire la suite

WordPress : récupérer la liste emails des membres et commentateurs photo

WordPress : retourner et exécuter un shortcode dans une fonction

Wordpress icon

Pour les besoins du Centre de Kriya Yoga France, j’ai écrit une fonction qui doit afficher une vidéo automatiquement.

Or je voulais juste renvoyer un shortcode vidéo qui prendrait en charge toute la partie code du lecteur vidéo.

On ne peut pas juste renvoyer la valeur, il faut utiliser la fonction do_shortcode() de WordPress.

Cas 1 : exécuter un shortcode dans une fonction

La solution réside dans l’utilisation de la fonction do_shortcode(). Voici un petit exemple :

<?php
/*
|-----------------------------------------------------------------------
| Sky Show Video by Matt - www.skyminds.net
|-----------------------------------------------------------------------
|
| Returns shortcode to be executed in WordPress.
|
*/
function sky_show_video($content) {
   // do stuff
   // return video
   return do_shortcode("[video src='$vid_url' width='600' height='480' type='video/mp4' preload='true']");
}Code language: HTML, XML (xml)

Cet exemple exécute le shortcode [video].

Lire la suite

WordPress : des images qui ont perdu leur chemin photo

WordPress : des images qui ont perdu leur chemin

Problème : chemin erroné pour certaines images

lost-sign

En allant faire un tour sur Google Search Console, je me suis aperçu qu’il y a avait des erreurs sur la page Si je pouvais (vraiment) choisir ma voiture… et effectivement, les images ne s’affichaient pas!

Après vérification, il se trouve que le chemin des images était totalement inexistant : c’était un mélange d’URL publique et de chemin privé, donc aucun moyen que les images d’affichent comme il faut avec le chemin privé. Et bien sûr, on ne peut pas éditer le chemin des fichiers depuis WordPress.

Solution : MySQL

En faisant une petite requête sur la table postmeta, je me suis aperçu que ce n’était pas le seul article touché. J’ai donc purement et simplement supprimé le chemin privé dans la table, via une requête SQL :

Query:

UPDATE wp_postmeta SET meta_value = replace(meta_value, '/home/public_html/images/', '') WHERE meta_key='_wp_attached_file';Code language: JavaScript (javascript)

Résultat : 173 rows affected.

Ah oui quand même, 173 enregistrements affectés, cela fait quand même quelques dizaines d’articles sur lesquels les images ne s’affichaient pas. Je n’ai aucune explication à ce phénomène, d’autant que certains de ces articles ont plusieurs années. Sûrement une mauvaise configuration de ma part à un moment donné, je suppose.

Enfin, tout cela pour dire que garder un oeil sur GWT, cela peut être utile pour débugger aussi.

pagespeed-99-201301

Performance du site : PageSpeed à 99%

Ah, ce moment magique durant lequel tu constates que ta note PageSpeed monte à 99%, via GTmetrix :

pagespeed-99-201301

C’est beau, sachant qu’au niveau CSS, c’est la barre WordPress du haut qui génère l’overhead.

Prochaine étape : mettre les fichiers statiques sur un sous-domaine cookieless.

Bash : réparer les tables MySQL en cas de crash photo

Bash : réparer les tables MySQL en cas de crash

Bash Il arrive que parfois une table SQL soit complètement plantée, ce qui peut bloquer l’accès à la base de données et donc l’accès au site.

Pour éviter cela, j’ai écrit un petit script bash qui me permet de stopper le serveur MySQL, procéder à la réparation de toutes les tables de toutes les bases de données puis relancer le serveur MySQL, Apache et Varnish.

#!/bin/sh
# MySQL Auto-Repair
# Written by Matt - skyminds.net

# stop the MySQL server
/etc/init.d/mysql stop

# check for errors
myisamchk /var/lib/mysql/*/*.MYI

# ask permission to repair
read -p "Repair tables ? (y/n)" -n 1 -r
if [[ $REPLY =~ ^[Yy]$ ]]
then
	# repair everything
	myisamchk -r /var/lib/mysql/*/*.MYI

	# restart servers
	/etc/init.d/mysql restart
	/etc/init.d/apache2 restart
	/etc/init.d/varnish restart
else
	/etc/init.d/mysql restart
fi

C’est le genre de petit fichier bash à garder au frais sur le serveur, facile à lancer en SSH depuis n’importe quel terminal en cas de besoin.

HTML5 : corriger l'erreur "The frameborder attribute on the iframe element is obsolete. Use CSS instead." photo

WordPress : valider le code oEmbed Youtube en HTML5

Le problème : le code des vidéos n’est pas valide en HTML5

Maintenant que nous avons mis à jour le code des oEmbed Youtube, nous allons rendre le code de l’iframe valide. Voici ce que le code oEmbed de WordPress donne par défaut avec un lien Youtube :

<iframe src="https://www.youtube.com/embed/Gvh2Zo7UL6E" width="660" height="371" frameborder="0" allowfullscreen="allowfullscreen"></iframe>Code language: HTML, XML (xml)

Résultat:

Or le petit problème, c’est que tout cela n’est pas vraiment valide au niveau W3C et je commence à me lasser de voir ces erreurs de validation sur toutes les pages du site avec des vidéos :

Erreur 1 : Attribute allowfullscreen not allowed on element iframe at this point.
Erreur 2 : The frameborder attribute on the iframe element is obsolete. Use CSS instead.Code language: JavaScript (javascript)

La solution : filtrer le rendu oEmbed de WordPress pour purifier le code

HTML5 logo

Voici donc la solution que j’ai mise en place sur le site : je filtre le code oEmbed de WordPress de manière à retirer le tag allowfullscreen qui n’a rien à faire là et à supprimer l’attribut frameborder, que je remplace par un style="border: none".

Éditez le fichier functions.php de votre thème et ajoutez-y cette fonction:

<?php
/*
|-----------------------------------------------------------------------
| Sky oEmbed Filter by Matt - www.skyminds.net
|-----------------------------------------------------------------------
|
| The sky_oembed_filter() function attempts to validate WordPress 
| video oEmbeds for HTML5.
| $return is the normal HTML that the oEmbed process would return. 
| $data is the data received from the oEmbed call, in an object format. 
| $url is the original URL being queried for oEmbed info. 
|
*/
add_filter('oembed_dataparse', 'sky_oembed_filter', 90, 3 );
function sky_oembed_filter( $return, $data, $url ) {
 	$return = str_replace('frameborder="0" allowfullscreen', 'style="border: none"', $return);
	return $return;
}Code language: HTML, XML (xml)

Notez que WordPress cache les résultats oEmbed dans la table postmeta donc après avoir installé ce code et si vous voulez vérifier que cela fonctionne, éditez un article pour que le postmeta se mette à jour.

Voilà, vos pages avec vidéos YouTube devraient maintenant être valides.

HTML5 : corriger l'erreur "The frameborder attribute on the iframe element is obsolete. Use CSS instead." photo

HTML5 : résoudre l’erreur “keyword publisher is not registered” (validateur W3C)

HTML5 logo

Sur votre site ou blog, vous avez peut-être ajouté le widget ou bouton +1 de Google+, le réseau social de Google. Or le petit problème, c’est que le code fourni empêche la bonne validation du document.

Voici le code fourni par Google :

<a title="Google+" href="https://plus.google.com/114535411372700844744" rel="publisher nofollow">Google+</a>Code language: HTML, XML (xml)

et voici l’erreur renvoyée par le validateur W3C :

Keyword publisher is not registered

HTML5 étant toujours en cours de réalisation, les valeurs de la balise rel sont assez restreintes et on ne peut pas mettre tout ce que l’on veut sans déclencher l’erreur.

La solution est toute simple : il faut ajouter la valeur du rel en argument dans le lien, comme ceci :

<a title="Google+" href="https://plus.google.com/114535411372700844744?rel=publisher" rel="nofollow">Google+</a>Code language: HTML, XML (xml)

Et voilà, plus d’erreur lors de la validation.

WordPress : récupérer la liste emails des membres et commentateurs photo

WordPress : nettoyage de la base de données

wordpress_icon_blue Avec le temps, les mises à jour successives et l’installation de différents plugins, la base de données de WordPress a tendance à prendre du poids, ce qui nuit aux performances. Voici donc comment lui faire bénéficier d’un petit régime.

N’oubliez pas de faire une sauvegarde de votre base de données avant de lancer ces requêtes. Backup now.

Nettoyage de wp_postmeta

Avant optimisation, ma table wp-postmeta faisait 12 403 enregistrements.

DELETE FROM wp_postmeta WHERE meta_key = '_edit_lock';
DELETE FROM wp_postmeta WHERE meta_key = '_edit_last';
DELETE FROM wp_postmeta WHERE meta_key = '_wp_old_slug';

Maintenant : 12 240.

Nettoyage de wp_commentmeta

On supprime tout ce qu’Akismet nous a mis dans la table wp_commentmeta :

DELETE FROM wp_commentmeta WHERE meta_key LIKE '%akismet%';

et on supprime toutes les entrées qui n’ont aucune relation avec wp_comments :

DELETE FROM wp_commentmeta WHERE comment_id NOT IN (SELECT comment_id FROM wp_comments);

Nettoyage de wp_options

Passage de 880 enregistrements à 476. WordPress crée ces entrées automatiquement et les purge occasionnellement, autant l’aider un peu.

DELETE FROM wp_options WHERE option_name LIKE '_site_transient_browser_%';
DELETE FROM wp_options WHERE option_name LIKE '_site_transient_timeout_browser_%';
DELETE FROM wp_options WHERE option_name LIKE '_transient_%';

Lire la suite

PHP: résoudre l'erreur "file_get_contents(): SSL operation failed with code 1" photo

PHP : les bons en-têtes pour permettre la mise en cache d’une page

Je me suis rendu compte qu’un des fichiers javascript d’un plugin WordPress est appelé sur chaque article du site et qu’il n’est pas mis en cache par défaut…

C’est très moyen au niveau optimisation étant donné que c’est typiquement le genre de fichier statique qui n’est pas prêt d’être modifié.

Voici donc les en-têtes (headers) qui vont nous permettre de mettre un fichier en cache en PHP :

<?php
/*
|--------------------------------------------------------------------------
| Enable Caching with PHP headers by Matt - www.skyminds.net
|--------------------------------------------------------------------------
|
| Let's set it to 90 days caching.
| seconds, minutes, hours, days 
|
*/
$expires = 60*60*24*90;

header('Pragma: public');
header('Cache-Control: maxage='.$expires);
header('Expires: ' . gmdate('D, d M Y H:i:s', time()+$expires) . ' GMT');Code language: HTML, XML (xml)

Et voilà, page mise en cache.

Cela fait moins de requêtes sur le serveur puisque le navigateur n’a pas besoin de redemander la page à chaque visite.

WordPress : éditer les liens de la base de données pour refléter le changement de structure des permaliens photo 1

WordPress : éditer les liens de la base de données pour refléter le changement de structure des permaliens

wordpress_icon_blue

Il y a quelques mois, je vous ai montré comment changer la structure des permaliens WordPress. Cela fonctionne très bien et tout le trafic des anciennes URL est bien redirigé vers les nouvelles.

Il est toutefois encore possible de faire mieux que cela : éditer toutes les URL de la base de données pour afficher les bons liens directement et éviter les redirections Apache à chaque fois qu’un visiteur clique sur un lien de vos anciens articles.

Cela évite une redirection donc permet d’afficher la bonne page directement, sans le temps de latence dû à l’exécution de mod_rewrite.

Etape 1 : sauvegarder votre base de données

On n’insistera jamais assez sur l’importance de sauvegarder les données avant d’effectuer une quelconque manipulation des données.

Commancez donc par faire une sauvegarde de votre base WordPress, vu que nous allons l’éditer en direct.

Lire la suite

WordPress : récupérer la liste emails des membres et commentateurs photo

Nouveau plugin WordPress : Sky Login Redirect

Le problème : redirection durant le login WordPress

wordpress_icon_blue Il y a quelques jours, Monty m’a envoyé un petit mail en me disant qu’elle avait du mal à s’identifier sur le site. Comme je suis loggué en permanence avec Firefox, je croyais que c’était un bug du navigateur.

Or, après avoir changé de navigateur deux fois (Chromium et Opéra), je me suis vite rendu compte que quelque chose clochait : une fois que l’on cliquait sur le bouton login, il y avait comme une redirection qui ne se faisait pas bien. Le navigateur moulinait et finissait par cracher un bout de page avec seulement quelques éléments HTML.

La solution : un plugin WordPress maison

Du coup, je me suis dit que l’on pouvait peut-être arranger les choses, c’est ainsi que j’ai écrit un nouveau plugin WordPress : Sky Login Redirect.

Lire la suite