Un délai pour mettre à jour automatiquement les plugins

Depuis la version 3.7 de WordPress nous avons la possibilité de mettre à jour automatiquement WordPress et ses modules.

Livré avec cette nouvelle fonctionnalité, tout un tas de hooks ont été mis à la disposition des développeurs et utilisateurs qui souhaitent paramétrer plus finement l’autoupdate du core, des plugins, des thèmes et des traductions. C’est là dessus que nous allons nous pencher, et plus particulièrement sur la mise à jour des plugins.

En ce qui concerne la mise à jour automatique des plugins, il y a deux écoles : ceux qui y sont opposés, jugeant que la mise à jour d’un plugin est une opération trop sensible pour être opérée de manière automatique, les nouvelles versions étant parfois instables, et ceux qui pensent que, pour des raisons de sécurité, l’auto-update doit être activé systématiquement afin de corriger rapidement les failles repérées dans les plugins.

Pour concilier les deux clans, j’ai envie de proposer quelque chose : et si on attendait simplement quelques jours avant d’appliquer une mise à jour de manière automatique ? Cela laisserait un peu de temps à la communauté pour remonter/corriger les bugs d’une nouvelle version de plugin, et cela garantirait tout de même la mise à jour au bout d’un certain temps.

ajout delai autoupdate WordPress
Comment faire patienter WordPress quelques jours avant l’auto-update d’un plugin

Le code pour attendre avant de mettre à jour un plugin

Sans plus tarder, voici le code qui va nous permettre d’activer la mise à jour automatique des plugins, en patientant un certain lapse de temps avant chaque mise à jour.

Ces lignes peuvent être insérées dans un mu-plugin, ou bien dans le functions.php de votre thème. Je vous laisse les lire avant de vous les détailler.

add_filter( 'auto_update_plugin', 'willy_defer_plugin_autoupdates', 10, 2 );
function willy_defer_plugin_autoupdates( $update, $item ) {
	if ( ! $update_defer_array = get_site_option( 'deferred_plugin_autoupdates' ) ) {
		$update_defer_array = array();
	}

	$name = $item->slug;
	$version = $item->new_version;

	if ( in_array( $name, array_keys( $update_defer_array ) )
	  && $version == $update_defer_array[ $name ]['version'] ) {
	  	if ( time() > $update_defer_array[ $name ]['age'] + DAY_IN_SECONDS * 3 ) {

		  	// Unset this queue
		  	unset( $update_defer_array[ $name ] );
		  	update_site_option( 'deferred_plugin_autoupdates', $update_defer_array );
		  	
			return true;
		} else {
			return false;
		}
	}

	$update_defer_array[ $name ] = array( 'version' => $version, 'age' => time() );
	update_site_option( 'deferred_plugin_autoupdates', $update_defer_array );

	return false;
}

Tout d’abord, il faut accrocher notre fonction sur le filtre auto_update_plugin ; ce filtre est appelé dans wp_maybe_auto_update() afin de savoir si un plugin doit être mis à jour automatiquement. Il prend deux paramètres :

  • $update, la valeur à renvoyer. True on met à jour / false on ne fait rien ;
  • $item, correspondant à l’objet plugin, qui contient des infos telles que le slug, ou la nouvelle version disponible.

Les plugins qui disposent d’une mise à jour seront poussés dans une option que j’ai nommé deferred_plugin_autoupdates. On la récupère si elle existe, sinon il faut la créer.

Ensuite on récupère les informations qui nous seront utiles, à savoir le slug de l’extension WordPress ainsi que le numéro de la nouvelle version disponible.

Si ce plugin (identifié par son slug) est dans notre option, avec ce numéro de version précis, de deux choses l’une :

  • Soit cela fait plus de trois jours qu’il y est, et on retourne true (ce qui mettra à jour le plugin) juste après avoir retiré le plugin de notre option ;
  • Soit ça ne fait pas trois jours, et on renvoie false pour patienter encore.

Si l’extension n’est pas dans notre option deferred_plugin_autoupdates, ou que le numéro de la version à changé : alors on pousse les nouvelles infos (slug, version, et le timestamp courant), et on attend 12H pour réessayer 🙂

Spécifier un délai différent pour certains plugins

Si jamais certains plugins vous paraissent plus sensibles que d’autres, vous avez la possibilité de préciser un délai d’attente un peu plus long.

Pour l’exemple, j’ai un peu peur que trois jours ne suffisent pas aux développeurs de WordPress SEO et Woocommerce pour corriger les retours sur leurs nouvelles versions. Je vais donc créer une variable $delay, qui sera de 10 jours pour ces deux extensions, et de 3 jours pour les autres.

Ensuite, je compare l’âge de la nouvelle version disponible dans l’option deferred_plugin_autoupdates avec cette variable. Si c’est plus vieux, on peut mettre à jour…

	$name = $item->slug;
	$version = $item->new_version;

	$delay = in_array( $name, array(
	            'wordpress-seo',
	            'woocommerce',
	            ) ) ? DAY_IN_SECONDS * 10 : DAY_IN_SECONDS * 3;

	if ( in_array( $name, array_keys( $update_defer_array ) )
	  && $version == $update_defer_array[ $name ]['version'] ) {
	  	if ( time() > $update_defer_array[ $name ]['age'] + $delay ) {

Ce code peut être adapté, si vous souhaitez définir plus de deux délais différents, selon les plugins. Il vous faudra alors faire un switch php, rien de sorcier 😉

Désactiver les mises à jour pour une extension

Bon… en fait j’ai eu beau attendre 10 jours avant de mettre à jour Woocommerce, il y a eu tellement de changement dans la nouvelle version de l’extension que ça a tout cassé ! Pour ne pas me faire avoir deux fois je peux simplement dire non à l’auto-update de ce plugin (c’est, là encore, un exemple ; ce n’est pas le genre de Woocommerce d’oublier la retro-compatibilité 😀 ).

Pour faire cela, il suffit, une fois qu’on a récupéré le slug du plugin, de retourner false directement s’il s’agit de woocommerce.

	$name = $item->slug;
	$version = $item->new_version;

	if ( in_array( $name, array(
	    'woocommerce'
	    ) ) ) {
		return false;
	}

Avec cette astuce, allez-vous franchir le pas et opter pour la mise à jour automatique de vos plugins ?

11 commentaires
Luc, il y a 2 années
Bonne idée et merci pour la technique de mise en place ! le problème c’est qu’on doit des fois faire rapidement les MAJ si ça concerne une faille de sécurité, donc mettre un délai ok, mais y bien réfléchir avant quand même..
Willy Bahuaud, il y a 2 années
rien n’empêche de procéder manuellement à la mise à jour. L’idée de la mise à jour automatique de WordPress, c’est de garantir que sans intervention, les plugins, le core ou le thème se mettront à jour tout seuls.
Dans la section où j’évoque la possibilité de préciser un délai spécifique pour certains plugins, je n’en ai pas parlé mais on peut évidemment préciser un délai court, voir pas du tout de délai 🙂
clem, il y a 2 années
Sympa, ça mérite un plugin 🙂
Willy Bahuaud, il y a 2 années
Merci, mais je ne sais pas trop si un plugin officiel sur le repository serait le bienvenue… Peut-être que j’en ferai un plugin à disposition sur Github 🙂
clem, il y a 2 années
Pourquoi ça serait pas le bienvenue ?
Willy Bahuaud, il y a 2 années
Il me semble que Julio, de BoiteAWeb, a essayé plusieurs fois de faire valider son plugin « Auto Update Manger » pour le mettre sur l’extend mais qu’il se l’ai fait refuser à chaque fois, car ça ne plait pas aux développeurs que l’on touche à ça. Voir son commentaire : commentaire de Julio. Après oui, je peux toujours tenter, je verrai bien…
ftrinite, il y a 2 années
Bonjour
Petite question, un plugin qui se met automatiquement à jour se désactive ou reste activé ? et s’il se désactive, existe-t-il un moyen de l’auto-activé ? Merci d’avance
Julien Maury, il y a 2 années
Coucou Willy,

j’avoue faire partie du clan des sceptiques en ce qui concerne la MAJ auto. J’avais tendance à vouloir automatiser avant d’entrer en agence et je me suis rendu compte que quand tu gères du code que tu n’as pas créé ce genre d’automatisation est compliquée voire impossible.

Les problèmes peuvent être multiples et nécessitent un audit donc en manuel. Donc ils sont gentils chez WP Tavern mais à confronter à la vie réelle. S’ajoutent que certaines erreurs ne sont pas transparentes et une MAJ peut amener des soucis de perf, etc.

Super article, je ne connaissais pas ou mal ce hook. Après sur le concept je pense que cela ne s’appliquera pas dans certains cas courants.

Je te donne un exemple : alerte WP SEO, faille de sécu. On va essayer de pousser la maj quoi qu’il arrive au plus tôt. Avant on va la tester etc mais on ne peut pas se permettre d’attendre plusieurs jours.

Comment distinguer une MAJ urgente d’une MAJ mineure avec ce code ?

Willy Bahuaud, il y a 2 années
malheureusement c’est actuellement impossible. En fait il suffirait que l’API update-check de wordpress.org (c’est elle qui indique à notre installation si un plugin doit être mis à jour, quelle est l’archive à télécharger, la version…) ne fournie pas l’information qui nous permettrai de différencier une mise à jour mineure d’une critique.

Cela serait utile pourtant…

Julien Maury, il y a 2 années
Willy Bahuaud, il y a 2 années
:-/ Oui, et je pense que cette feature n’est absoluement pas prioritaire. Pour eux – les core devs – chaque mise à jour devrait idéalement être exécutée sur le champ. Donc je ne pense pas qu’il nous donnerons les moyens de choisir entre les maj urgentes, et celles qui peuvent attendre…

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Publié le 06 mars 2015
par Willy Bahuaud
Catégorie Développement WordPress, Maintenance de sites WordPress