From 7a8daa72c61e8c1664bad4fc1fa67d0a72e55115 Mon Sep 17 00:00:00 2001 From: FrankZamora Date: Wed, 26 Nov 2025 21:58:28 -0600 Subject: [PATCH] chore: Add migration script for legacy theme options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Script to migrate data from wp_options (roi_theme_settings) to normalized table wp_roi_theme_component_settings 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- migrate-legacy-options.php | 194 +++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 migrate-legacy-options.php diff --git a/migrate-legacy-options.php b/migrate-legacy-options.php new file mode 100644 index 00000000..7660fc03 --- /dev/null +++ b/migrate-legacy-options.php @@ -0,0 +1,194 @@ +prefix . 'roi_theme_component_settings'; + $migrated = 0; + $skipped = 0; + $errors = 0; + + // 3. Mapeo de opciones legacy → componente/grupo/atributo + // Basado en seccion 3.4 del plan 02.02-limpieza-configuraciones-legacy.md + $mapping = [ + // Opciones de roi_theme_options + 'roi_adsense_delay_enabled' => [ + 'source' => 'roi_theme_options', + 'target' => ['adsense-delay', 'visibility', 'is_enabled'], + 'note' => 'Componente adsense-delay no existe en Admin Panel - PENDIENTE crear schema' + ], + 'show_category_badge' => [ + 'source' => 'roi_theme_options', + 'target' => ['category-badge', 'visibility', 'is_enabled'], + 'note' => 'Componente category-badge no existe en Admin Panel - PENDIENTE crear schema' + ], + 'toc_min_headings' => [ + 'source' => 'roi_theme_options', + 'target' => ['table-of-contents', 'behavior', 'min_headings'], + 'note' => 'Componente table-of-contents YA EXISTE en Admin Panel' + ], + 'roi_share_text' => [ + 'source' => 'roi_theme_options', + 'target' => ['social-share', 'content', 'share_text'], + 'note' => 'Componente social-share YA EXISTE en Admin Panel' + ], + 'roi_enable_share_buttons' => [ + 'source' => 'roi_theme_options', + 'target' => ['social-share', 'visibility', 'is_enabled'], + 'note' => 'Componente social-share YA EXISTE en Admin Panel' + ], + 'featured_image_single' => [ + 'source' => 'roi_theme_options', + 'target' => ['featured-image', 'visibility', 'show_on_single'], + 'note' => 'Componente featured-image YA EXISTE en Admin Panel' + ], + 'featured_image_page' => [ + 'source' => 'roi_theme_options', + 'target' => ['featured-image', 'visibility', 'show_on_page'], + 'note' => 'Componente featured-image YA EXISTE en Admin Panel' + ], + ]; + + // Opciones que se ELIMINAN intencionalmente (no migrar) + $intentionally_removed = [ + 'breadcrumb_separator' => 'Breadcrumbs eliminado - usar plugin si se necesita', + 'roi_social_facebook' => 'Social links eliminados - no se usa', + 'roi_social_twitter' => 'Social links eliminados - no se usa', + 'roi_social_linkedin' => 'Social links eliminados - no se usa', + 'roi_social_youtube' => 'Social links eliminados - no se usa', + 'roi_typography_heading' => 'Typography eliminado - usar Custom CSS', + 'roi_typography_body' => 'Typography eliminado - usar Custom CSS', + ]; + + $results[] = "=== Procesando Migracion ===\n\n"; + + // 4. Procesar mapeo + foreach ($mapping as $legacy_key => $config) { + $source = $config['source']; + $target = $config['target']; + $note = $config['note']; + + [$component, $group, $attribute] = $target; + + // Obtener valor segun source + $value = null; + if ($source === 'roi_theme_options' && isset($legacy_options[$legacy_key])) { + $value = $legacy_options[$legacy_key]; + } elseif ($source === 'theme_mods' && isset($theme_mods[$legacy_key])) { + $value = $theme_mods[$legacy_key]; + } + + if ($value !== null) { + // Verificar si ya existe en la nueva tabla + $existing = $wpdb->get_var($wpdb->prepare( + "SELECT COUNT(*) FROM {$table} + WHERE component_name = %s AND group_name = %s AND attribute_name = %s", + $component, + $group, + $attribute + )); + + if ($existing > 0) { + $results[] = "SKIP: {$legacy_key} -> Ya existe en {$component}/{$group}/{$attribute}\n"; + $results[] = " Nota: {$note}\n"; + $skipped++; + continue; + } + + // Insertar en nueva tabla + $result = $wpdb->replace($table, [ + 'component_name' => $component, + 'group_name' => $group, + 'attribute_name' => $attribute, + 'attribute_value' => is_bool($value) ? ($value ? '1' : '0') : (string)$value, + 'is_editable' => 1, + ]); + + if ($result !== false) { + $results[] = "OK: {$legacy_key} -> {$component}/{$group}/{$attribute} = " . var_export($value, true) . "\n"; + $results[] = " Nota: {$note}\n"; + $migrated++; + } else { + $results[] = "ERR: {$legacy_key} -> Error al insertar: " . $wpdb->last_error . "\n"; + $errors++; + } + } else { + $results[] = "SKIP: {$legacy_key} -> No encontrado en {$source}\n"; + $skipped++; + } + } + + // 5. Documentar opciones eliminadas intencionalmente + $results[] = "\n=== Opciones Eliminadas Intencionalmente ===\n\n"; + foreach ($intentionally_removed as $key => $reason) { + if (isset($legacy_options[$key])) { + $results[] = "DEL: {$key} -> {$reason}\n"; + } + } + + // 6. Resumen + $results[] = "\n=== Resumen ===\n"; + $results[] = "Migradas: {$migrated}\n"; + $results[] = "Omitidas: {$skipped}\n"; + $results[] = "Errores: {$errors}\n"; + $results[] = "\n=== Fin de Migracion ===\n"; + + $output = implode('', $results); + + // Guardar log + $log_file = get_template_directory() . '/migrate-legacy-options.log'; + file_put_contents($log_file, $output); + + return $output; +} + +// Ejecutar si se llama directamente via WP-CLI +if (defined('WP_CLI') || (defined('ABSPATH') && php_sapi_name() === 'cli')) { + echo roi_migrate_legacy_options(); +}