Created
March 10, 2025 11:08
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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