Automatisation des opérations en base suite au déplacement des fichiers de médias

Dans mon dernier article, je présentais la manière dont j’ai procédé pour déplacer les fichiers de ma bibliothèque de médias WordPress.

Toutes les différentes opérations des étapes décrites dans cet article étaient faites à la main, ce qui peut être long, et une faute de frappe ou un oubli peut être source d’erreurs.

Mais n’ayez pas peur, j’ai créé un script PHP permettant d’automatiser les étapes concernant les actions en base de données.

Je vais vous présenter ici la manière de procéder en PHP pour l’automatisation des modifications des deux tables à modifier :

  • la table contenant les meta données : wp_postmeta
  • la table contenant les articles et pages : wp_posts

Quelle que soit la table à modifier, on va procéder de la même manière : on lit chaque ligne de la table devant être modifiée, et pour chaque ligne on modifie la valeur à l’aide de preg_replace() avant de la mettre à jour.

Le même pattern/masque d’expression régulière et la même chaîne de remplacement sont utilisés pour tout appel à preg_replace().

Table wp_postmeta

Pour cette table, selon la meta donnée traitée il faut procéder de manière différente :

  • dans le cas de la clé « _wp_attached_file », on se contente d’un appel simple : preg_replace('@<pattern>@', '<chaîne de remplacement>', '<valeur de la clé>') avant de faire la mise à jour
  • dans le cas de la clé « _wp_attachment_metadata », il faut préalablement désérialiser l’array (avec unserialize()) avant de faire appel à preg_replace(), et il faut bien penser à à nouveau sérialiser le tableau (avec serialize()) avant la mise à jour.

Table wp_posts

Pour cette table, seul un appel à preg_replace() est nécessaire, mais avec une légère différence : il faut préfixer le masque de recherche et la chaîne de remplacement avec « uploads/ », car les liens vers les pages de votre site WordPress peuvent également contenir le pattern recherché (« <année>/<mois> » surtout).

L’appel à preg_replace() devient donc : preg_replace('@uploads/<pattern>@', 'uploads/<chaîne de remplacement>', '<valeur de la clé>').

Bonus

Voici un petit script, à placer à la racine de votre installation WordPress :

<?php

$search_pattern = '[0-9]{4}/[0-9]{2}/';

$replace = '';

/***********************************
 *
 *	/!\ NE PAS MODIFIER AU-DELA /!\
 *
 ***********************************/

include_once('./wp-config.php'); // pour récupérer la configuration de BDD de l'installation WordPress

$dsn = sprintf('mysql:host=%s;dbname=%s;charset=%s', DB_HOST, DB_NAME, DB_CHARSET);

$db = new PDO($dsn, DB_USER, DB_PASSWORD);

// Modification des posts
$read_posts = $db->query('SELECT ID, post_content FROM '.$table_prefix.'posts WHERE post_type IN ("post", "page")');

$write_post = $db->prepare('UPDATE '.$table_prefix.'posts SET post_content=:post_content WHERE ID=:post_id');

while ($post = $read_posts->fetch(PDO::FETCH_ASSOC)) {
	// Pour ne réécrire que les appels aux médias et pas les liens (qui peuvent aussi contenir une structure AAAA/MM)
	if ( !preg_match('@uploads/'.$search_pattern.'@', $post['post_content']) ) {
		continue;
	}

	$write_post->bindParam(':post_content', preg_replace('@uploads/'.$search_pattern.'@', 'uploads/'.$replace, $post['post_content']), PDO::PARAM_STR);
	$write_post->bindParam(':post_id', $post['ID'], PDO::PARAM_INT);
	$write_post->execute();
}

$read_posts->closeCursor();

// Modification des meta données
$read_metas = $db->query('SELECT meta_id, meta_key, meta_value FROM '.$table_prefix.'postmeta WHERE meta_key IN ("_wp_attached_file", "_wp_attachment_metadata")');

$write_meta = $db->prepare('UPDATE '.$table_prefix.'postmeta SET meta_value=:meta_value WHERE meta_id=:meta_id');

while ($meta = $read_metas->fetch(PDO::FETCH_ASSOC)) {
	if($meta['meta_key'] == '_wp_attached_file') {
		$meta_value = preg_replace('@'.$search_pattern.'@', $replace, $meta['meta_value']);
	} else {
		$meta_array = unserialize($meta['meta_value']);

		$meta_array['file'] = preg_replace('@'.$search_pattern.'@', $replace, $meta_array['file']);

		$meta_value = serialize($meta_array);
	}

	$write_meta->bindParam(':meta_value', $meta_value, PDO::PARAM_STR);
	$write_meta->bindParam(':meta_id', $meta['meta_id'], PDO::PARAM_INT);
	$write_meta->execute();
}

$read_metas->closeCursor();

⚠ Attention, ce script n’a été testé que sur une version de test locale. Pensez bien à faire une sauvegarde de votre base avant de l’exécuter. ⚠

Laisser un commentaire