Votre Page Builder WordPress casse lors du passage en HTTPS ou d’une migration de nom de domaine ?

Vous avez des problèmes avec votre page builder depuis que vous avez passé votre site en HTTPS ou changé de nom de domaine ?

J’ai passé plusieurs heures à remonter à la source du problème, et j’aimerais vous épargner cela.

Cet article est là pour ça.

Trouver le contenu des pages créées avec Pootle Page BUILDER

SELECT *
FROM `wp_postmeta`
WHERE meta_key="panels_data"
ORDER BY meta_id DESC

La cause du problème

Les données sont stockées sous forme d’array PHP sérialisé, qu’on peut stocker en BDD puisque l’array est converti en chaîne de caractère.

Je ne vais pas détailler la structure d’un array sérialisé, mais sachez juste que le a: annonce un tableau et le s: annonce une chaîne.

Vient ensuite la taille de l’élément. Soit le nombre d’entrée dans le tableaux, soit le nombre de caractères dans la chaîne.

C’est ce dernier point qui pose problème : en faisant des search and replace sauvages en BDD, vous avez cassé l’intégrité de l’array sérialisé : la valeur qui compte les caractères n’est plus la bonne. Je dis « vous » mais c’est aussi ce que j’ai fait hein ^_^

Résoudre le problème

Mettez votre entrée BDD dans un fichier que vous appellerez corruptedSerialization.txt

Prenez soin de vérifier qu’il n’y a pas un caractère fantôme qui traîne avant le premier a, s ou O. Pour ça, mettez vous au début du fichier, supprimez jusqu’à supprimer le premier a, s ou O, et réécrivez-le au clavier.

Mettez ce fichier dans le même répertoire qu’un fichier PHP qui contiendra le code suivant :

<?php

header('Content-type: text/html; charset=utf-8');

function fix_str_length($matches) {
$string = $matches[2];
$right_length = strlen($string); // yes, strlen even for UTF-8 characters, PHP wants the mem size, not the char count
return 's:' . $right_length . ':"' . $string . '";';
}
function fix_serialized($string) {
// securities
// if ( !preg_match('/^[aOs]:/', $string) ) return $string;
if ( @unserialize($string) !== false ) return $string;
$string = preg_replace("%\n%", "", $string);
$string = preg_replace("%\r%", "", $string);
$string = preg_replace("%\t%", "", $string);
// doublequote exploding
$data = preg_replace('%";%', "µµµ", $string);
$tab = explode("µµµ", $data);

$new_data = '';
foreach ($tab as $line) {
$new_data .= preg_replace_callback('%\bs:([0-9]+):"(.*)%', 'fix_str_length', $line);
}
return $new_data;
}

//Let's consider we store the serialization inside a txt file
$corruptedSerialization = file_get_contents('corruptedSerialization.txt');

//Try to unserialize original string
$unSerialized = unserialize($corruptedSerialization);

//In case of failure let's try to repair it
if(!$unSerialized){
$repairedSerialization = fix_serialized($corruptedSerialization);
$unSerialized = unserialize($repairedSerialization);
}

//Keep your fingers crossed
if (!$unSerialized)
{
var_dump($unSerialized);
}

var_dump($repairedSerialization);

Liens utiles