Skip to content

Instantly share code, notes, and snippets.

@thierrypigot
Created March 10, 2025 11:08
Show Gist options
  • Save thierrypigot/7b5e0cca6ef4792c205159e0f675a094 to your computer and use it in GitHub Desktop.
Save thierrypigot/7b5e0cca6ef4792c205159e0f675a094 to your computer and use it in GitHub Desktop.
Script pour nettoyer les shortcodes Divi dans la base de données WordPress
<?php
/**
* Script pour nettoyer les shortcodes Divi dans la base de données WordPress
*
* Ce script doit être placé à la racine de votre installation WordPress et exécuté via le navigateur
* ou en ligne de commande.
*
* Il analyse tous les contenus de posts/pages et nettoie les shortcodes Divi tout en préservant le contenu.
*
* Important: FAIRE UNE SAUVEGARDE DE VOTRE BASE DE DONNÉES AVANT D'EXÉCUTER CE SCRIPT !
*/
// Charger l'environnement WordPress
require_once('wp-load.php');
// Vérification de sécurité - décommentez cette section en production
/*
if (!current_user_can('administrator')) {
die('Vous devez être administrateur pour exécuter ce script.');
}
*/
// Configuration
$dry_run = true; // Mettre à false pour effectuer les modifications réelles
$log_file = 'divi-cleanup-log.txt';
$log_handle = fopen($log_file, 'w');
// Compteurs pour le rapport
$total_posts = 0;
$modified_posts = 0;
log_message("=== Début du nettoyage des shortcodes Divi ===");
log_message("Mode: " . ($dry_run ? 'Simulation' : 'Modification réelle'));
// Récupérer tous les posts et pages
$args = array(
'post_type' => array('post'),
'posts_per_page' => -1,
'post_status' => 'any'
);
$query = new WP_Query($args);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
$post_id = get_the_ID();
$title = get_the_title();
$original_content = get_post_field('post_content', $post_id);
$total_posts++;
// Approche plus sûre : extraire le contenu entre les shortcodes Divi
$new_content = clean_divi_shortcodes($original_content);
// Vérifier si le contenu a été modifié
if ($new_content !== $original_content) {
$modified_posts++;
log_message("Post modifié: #{$post_id} - {$title}");
// Enregistrer un échantillon avant/après pour vérification
log_message(" → Avant (extrait): " . substr(strip_tags($original_content), 0, 100) . "...");
log_message(" → Après (extrait): " . substr(strip_tags($new_content), 0, 100) . "...");
// Enregistrer les modifications si ce n'est pas un dry run
if (!$dry_run) {
wp_update_post(array(
'ID' => $post_id,
'post_content' => $new_content
));
log_message(" → Modifications enregistrées");
} else {
log_message(" → Modifications simulées (non enregistrées)");
}
}
}
wp_reset_postdata();
}
// Rapport final
log_message("\n=== Rapport de nettoyage ===");
log_message("Total de posts/pages analysés: $total_posts");
log_message("Posts/pages modifiés: $modified_posts");
log_message("Mode: " . ($dry_run ? "Simulation" : "Modification réelle"));
log_message("=== Fin du nettoyage ===");
// Fermer le fichier de log
fclose($log_handle);
// Afficher le résultat
echo "<h1>Nettoyage des shortcodes Divi</h1>";
echo "<p>Total de posts/pages analysés: <strong>$total_posts</strong></p>";
echo "<p>Posts/pages modifiés: <strong>$modified_posts</strong></p>";
echo "<p>Mode: <strong>" . ($dry_run ? "Simulation" : "Modification réelle") . "</strong></p>";
echo "<p>Consultez le fichier <code>$log_file</code> pour plus de détails.</p>";
if ($dry_run) {
echo "<p style='color:red;'><strong>Ceci était une simulation.</strong> Pour effectuer les modifications réelles, modifiez la variable \$dry_run à false dans le script.</p>";
}
/**
* Fonction pour nettoyer les shortcodes Divi tout en préservant le contenu
*/
function clean_divi_shortcodes($content) {
// Première étape: préserver le contenu entre les shortcodes Divi tout en supprimant les balises
// Traiter les shortcodes imbriqués du plus intérieur vers l'extérieur
$divi_shortcodes = array(
// Conteneurs principaux (à traiter en dernier)
'et_pb_section' => array('start' => '[et_pb_section', 'end' => '[/et_pb_section]'),
'et_pb_row' => array('start' => '[et_pb_row', 'end' => '[/et_pb_row]'),
'et_pb_column' => array('start' => '[et_pb_column', 'end' => '[/et_pb_column]'),
// Éléments de contenu qui contiennent du texte (à traiter en premier)
'et_pb_text' => array('start' => '[et_pb_text', 'end' => '[/et_pb_text]'),
'et_pb_blurb' => array('start' => '[et_pb_blurb', 'end' => '[/et_pb_blurb]'),
'et_pb_testimonial' => array('start' => '[et_pb_testimonial', 'end' => '[/et_pb_testimonial]'),
'et_pb_toggle' => array('start' => '[et_pb_toggle', 'end' => '[/et_pb_toggle]'),
'et_pb_tab' => array('start' => '[et_pb_tab', 'end' => '[/et_pb_tab]'),
'et_pb_accordion_item' => array('start' => '[et_pb_accordion_item', 'end' => '[/et_pb_accordion_item]'),
'et_pb_pricing_table' => array('start' => '[et_pb_pricing_table', 'end' => '[/et_pb_pricing_table]'),
'et_pb_slide' => array('start' => '[et_pb_slide', 'end' => '[/et_pb_slide]'),
'et_pb_counter' => array('start' => '[et_pb_counter', 'end' => '[/et_pb_counter]'),
'et_pb_cta' => array('start' => '[et_pb_cta', 'end' => '[/et_pb_cta]'),
// Éléments de contenu sans texte (à traiter au milieu)
'et_pb_image' => array('start' => '[et_pb_image', 'end' => '[/et_pb_image]'),
'et_pb_button' => array('start' => '[et_pb_button', 'end' => '[/et_pb_button]'),
'et_pb_gallery' => array('start' => '[et_pb_gallery', 'end' => '[/et_pb_gallery]'),
'et_pb_video' => array('start' => '[et_pb_video', 'end' => '[/et_pb_video]'),
'et_pb_map' => array('start' => '[et_pb_map', 'end' => '[/et_pb_map]'),
'et_pb_map_pin' => array('start' => '[et_pb_map_pin', 'end' => '[/et_pb_map_pin]'),
'et_pb_sidebar' => array('start' => '[et_pb_sidebar', 'end' => '[/et_pb_sidebar]'),
'et_pb_divider' => array('start' => '[et_pb_divider', 'end' => '[/et_pb_divider]'),
'et_pb_blog' => array('start' => '[et_pb_blog', 'end' => '[/et_pb_blog]'),
'et_pb_shop' => array('start' => '[et_pb_shop', 'end' => '[/et_pb_shop]'),
'et_pb_countdown_timer' => array('start' => '[et_pb_countdown_timer', 'end' => '[/et_pb_countdown_timer]'),
'et_pb_circle_counter' => array('start' => '[et_pb_circle_counter', 'end' => '[/et_pb_circle_counter]'),
'et_pb_number_counter' => array('start' => '[et_pb_number_counter', 'end' => '[/et_pb_number_counter]'),
'et_pb_portfolio' => array('start' => '[et_pb_portfolio', 'end' => '[/et_pb_portfolio]'),
'et_pb_filterable_portfolio' => array('start' => '[et_pb_filterable_portfolio', 'end' => '[/et_pb_filterable_portfolio]'),
// Conteneurs intermédiaires (à traiter en avant-dernier)
'et_pb_accordion' => array('start' => '[et_pb_accordion', 'end' => '[/et_pb_accordion]'),
'et_pb_tabs' => array('start' => '[et_pb_tabs', 'end' => '[/et_pb_tabs]'),
'et_pb_counters' => array('start' => '[et_pb_counters', 'end' => '[/et_pb_counters]'),
'et_pb_slider' => array('start' => '[et_pb_slider', 'end' => '[/et_pb_slider]'),
'et_pb_pricing_tables' => array('start' => '[et_pb_pricing_tables', 'end' => '[/et_pb_pricing_tables]'),
'et_pb_contact_form' => array('start' => '[et_pb_contact_form', 'end' => '[/et_pb_contact_form]'),
'et_pb_contact_field' => array('start' => '[et_pb_contact_field', 'end' => '[/et_pb_contact_field]'),
);
// Traiter chaque shortcode
foreach ($divi_shortcodes as $shortcode_info) {
$start_tag = $shortcode_info['start'];
$end_tag = $shortcode_info['end'];
// Tant que le shortcode existe dans le contenu
while (strpos($content, $start_tag) !== false && strpos($content, $end_tag) !== false) {
// Trouver la position du shortcode d'ouverture
$start_pos = strpos($content, $start_tag);
if ($start_pos === false) break;
// Trouver la position de fermeture correspondante
$end_pos = strpos($content, $end_tag, $start_pos);
if ($end_pos === false) break;
$end_pos += strlen($end_tag);
// Extraire le shortcode complet
$shortcode_full = substr($content, $start_pos, $end_pos - $start_pos);
// Extraire le contenu entre les balises (après la première balise fermante ">" et avant la dernière balise ouvrante "<")
$inner_start = strpos($shortcode_full, ']');
if ($inner_start === false) {
// Si pas de ']', on passe au shortcode suivant
$replacement = '';
} else {
$inner_start += 1; // Position après ']'
$inner_end = strrpos($shortcode_full, '[');
if ($inner_end === false || $inner_end <= $inner_start) {
// Soit pas de '[' final, soit il est avant le ']' initial (cas étrange)
$replacement = '';
} else {
// Extraire le contenu intérieur
$inner_content = substr($shortcode_full, $inner_start, $inner_end - $inner_start);
// Nettoyer le contenu intérieur en préservant le HTML important
$replacement = trim($inner_content);
}
}
// Remplacer le shortcode complet par son contenu
$content = substr_replace($content, $replacement, $start_pos, $end_pos - $start_pos);
}
}
// Nettoyer les éventuels shortcodes restants avec les crochets (approche plus conservatrice)
$content = preg_replace('/\[\/?et_pb_[^\]]*\]/', '', $content);
// Nettoyer le HTML et les espaces superflus
$content = preg_replace('/<div\s+class="et_pb_[^>]*>\s*<\/div>/s', '', $content); // Divs vides avec classes Divi
$content = preg_replace('/\s{3,}/', "\n\n", $content); // Espaces multiples
$content = preg_replace('/\n\s*\n\s*\n/', "\n\n", $content); // Lignes vides multiples
return $content;
}
// Fonction pour enregistrer les messages dans le log
function log_message($message) {
global $log_handle;
$timestamp = date('Y-m-d H:i:s');
$log_line = "[$timestamp] $message\n";
fwrite($log_handle, $log_line);
// Afficher aussi dans la console si exécuté en ligne de commande
if (php_sapi_name() === 'cli') {
echo $log_line;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment