backup: estado antes de limpieza de defaults
This commit is contained in:
530
admin/pages/main.php
Normal file
530
admin/pages/main.php
Normal file
@@ -0,0 +1,530 @@
|
||||
<?php
|
||||
/**
|
||||
* Admin Panel - Main Page
|
||||
*
|
||||
* Interfaz de administración de componentes del tema
|
||||
*
|
||||
* @package Apus_Theme
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="wrap apus-admin-panel">
|
||||
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
|
||||
<p class="description">Configure los componentes del tema Apus</p>
|
||||
|
||||
<!-- Navigation Tabs -->
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-bs-toggle="tab" data-bs-target="#topBarTab" href="#topBarTab" role="tab">
|
||||
<i class="bi bi-megaphone-fill me-2"></i>
|
||||
Top Bar
|
||||
</a>
|
||||
</li>
|
||||
<!-- Más tabs aquí: Navbar, Hero, Footer, etc. -->
|
||||
</ul>
|
||||
|
||||
<!-- Tab Content -->
|
||||
<div class="tab-content mt-3">
|
||||
<!-- ============================= -->
|
||||
<!-- TAB: TOP BAR - VERSIÓN MEJORADA -->
|
||||
<!-- ============================= -->
|
||||
<div id="topBarTab" class="tab-pane fade show active" role="tabpanel">
|
||||
<!-- Header del Tab -->
|
||||
<div class="tab-header mb-4">
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<h3 class="mb-1 text-navy-primary">
|
||||
<i class="bi bi-megaphone-fill me-2 text-orange-primary"></i>
|
||||
Configuración Top Bar
|
||||
</h3>
|
||||
<p class="text-neutral-600 mb-0">
|
||||
Personaliza la barra de anuncios superior de tu sitio
|
||||
</p>
|
||||
</div>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary" id="resetTopBarDefaults">
|
||||
<i class="bi bi-arrow-counterclockwise me-1"></i>
|
||||
Restaurar valores por defecto
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Row para 2 cards por fila -->
|
||||
<div class="row">
|
||||
<!-- ============================= -->
|
||||
<!-- GRUPO 1: ACTIVACIÓN -->
|
||||
<!-- ============================= -->
|
||||
<div class="col-md-6">
|
||||
<div class="form-section card shadow-sm border-0 mb-4 h-100">
|
||||
<div class="card-body">
|
||||
<h4 class="section-title">
|
||||
<span class="title-icon">
|
||||
<i class="bi bi-toggle-on"></i>
|
||||
</span>
|
||||
Activación y Visibilidad
|
||||
</h4>
|
||||
|
||||
<!-- Enabled -->
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-neutral-700 fw-medium mb-3">
|
||||
<i class="bi bi-power text-orange-primary me-1"></i>
|
||||
Estado del Componente
|
||||
</label>
|
||||
<div class="toggle-container">
|
||||
<div class="form-check form-switch form-switch-lg">
|
||||
<input class="form-check-input"
|
||||
type="checkbox"
|
||||
id="topBarEnabled"
|
||||
role="switch"
|
||||
checked>
|
||||
<label class="form-check-label" for="topBarEnabled">
|
||||
Activar Top Bar
|
||||
</label>
|
||||
</div>
|
||||
<small class="form-text text-neutral-700 d-block mt-2">
|
||||
Activa o desactiva el Top Bar en todo el sitio
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Show on Mobile -->
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-neutral-700 fw-medium mb-3">
|
||||
<i class="bi bi-phone text-orange-primary me-1"></i>
|
||||
Visibilidad Mobile
|
||||
</label>
|
||||
<div class="toggle-container">
|
||||
<div class="form-check form-switch form-switch-lg">
|
||||
<input class="form-check-input"
|
||||
type="checkbox"
|
||||
id="topBarShowOnMobile"
|
||||
role="switch"
|
||||
checked>
|
||||
<label class="form-check-label" for="topBarShowOnMobile">
|
||||
Mostrar en dispositivos móviles
|
||||
</label>
|
||||
</div>
|
||||
<small class="form-text text-neutral-700 d-block mt-2">
|
||||
Pantallas menores a 768px
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Show on Desktop -->
|
||||
<div class="mb-0">
|
||||
<label class="form-label text-neutral-700 fw-medium mb-3">
|
||||
<i class="bi bi-display text-orange-primary me-1"></i>
|
||||
Visibilidad Desktop
|
||||
</label>
|
||||
<div class="toggle-container">
|
||||
<div class="form-check form-switch form-switch-lg">
|
||||
<input class="form-check-input"
|
||||
type="checkbox"
|
||||
id="topBarShowOnDesktop"
|
||||
role="switch"
|
||||
checked>
|
||||
<label class="form-check-label" for="topBarShowOnDesktop">
|
||||
Mostrar en desktop
|
||||
</label>
|
||||
</div>
|
||||
<small class="form-text text-neutral-700 d-block mt-2">
|
||||
Pantallas de 768px en adelante
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<!-- ============================= -->
|
||||
<!-- GRUPO 2: CONTENIDO -->
|
||||
<!-- ============================= -->
|
||||
<div class="col-md-6">
|
||||
<div class="form-section card shadow-sm border-0 mb-4 h-100">
|
||||
<div class="card-body">
|
||||
<h4 class="section-title">
|
||||
<span class="title-icon">
|
||||
<i class="bi bi-card-text"></i>
|
||||
</span>
|
||||
Contenido y Mensajes
|
||||
</h4>
|
||||
|
||||
<!-- Icono -->
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="col-md-8">
|
||||
<div class="form-group">
|
||||
<label for="topBarIconClass" class="form-label text-neutral-700 fw-medium">
|
||||
<i class="bi bi-emoji-smile text-orange-primary me-1"></i>
|
||||
Clase del icono
|
||||
<span class="badge bg-neutral-100 text-neutral-600 ms-2">Bootstrap Icons</span>
|
||||
</label>
|
||||
<div class="input-group input-group-merge">
|
||||
<span class="input-group-text bg-neutral-50 border-end-0">
|
||||
<i class="bi bi-code-slash text-neutral-600"></i>
|
||||
</span>
|
||||
<input type="text"
|
||||
id="topBarIconClass"
|
||||
class="form-control border-start-0 ps-0"
|
||||
placeholder="Ej: bi bi-megaphone-fill"
|
||||
maxlength="50"
|
||||
value="bi bi-megaphone-fill">
|
||||
</div>
|
||||
<small class="form-text text-neutral-700 d-flex align-items-center mt-2">
|
||||
<i class="bi bi-info-circle me-1"></i>
|
||||
Ver iconos disponibles:
|
||||
<a href="https://icons.getbootstrap.com/" target="_blank" class="ms-1 text-orange-primary">
|
||||
Bootstrap Icons <i class="bi bi-box-arrow-up-right ms-1"></i>
|
||||
</a>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label class="form-label text-neutral-700 fw-medium mb-3">
|
||||
Opciones de Icono
|
||||
</label>
|
||||
<div class="toggle-container">
|
||||
<div class="form-check form-switch form-switch-lg">
|
||||
<input class="form-check-input"
|
||||
type="checkbox"
|
||||
id="topBarShowIcon"
|
||||
role="switch"
|
||||
checked>
|
||||
<label class="form-check-label" for="topBarShowIcon">
|
||||
Mostrar icono
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Texto destacado -->
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="col-md-12">
|
||||
<div class="form-group">
|
||||
<label for="topBarHighlightText" class="form-label text-neutral-700 fw-medium">
|
||||
<i class="bi bi-bookmark-star text-orange-primary me-1"></i>
|
||||
Texto destacado
|
||||
<span class="badge bg-warning-subtle text-warning-emphasis ms-2">Opcional</span>
|
||||
</label>
|
||||
<input type="text"
|
||||
id="topBarHighlightText"
|
||||
class="form-control form-control-lg"
|
||||
placeholder='Ej: "Nuevo:" o "Promoción:"'
|
||||
maxlength="30"
|
||||
value="Nuevo:">
|
||||
<small class="form-text text-neutral-700 d-flex align-items-center mt-2">
|
||||
<i class="bi bi-lightbulb text-warning me-1"></i>
|
||||
Se muestra en <strong class="mx-1">negritas</strong> y con <span class="text-orange-primary fw-bold mx-1">color destacado</span>. Dejar vacío para omitir.
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mensaje principal -->
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="col-md-12">
|
||||
<div class="form-group">
|
||||
<label for="topBarMessageText" class="form-label text-neutral-700 fw-medium">
|
||||
<i class="bi bi-chat-left-text text-orange-primary me-1"></i>
|
||||
Mensaje principal
|
||||
<span class="badge bg-danger-subtle text-danger-emphasis ms-2">Requerido</span>
|
||||
</label>
|
||||
<textarea id="topBarMessageText"
|
||||
class="form-control form-control-lg"
|
||||
rows="3"
|
||||
maxlength="250"
|
||||
placeholder="Ej: Accede a más de 200,000 Análisis de Precios Unitarios actualizados para 2025."
|
||||
required>Accede a más de 200,000 Análisis de Precios Unitarios actualizados para 2025.</textarea>
|
||||
<div class="d-flex justify-content-between align-items-center mt-2">
|
||||
<small class="form-text text-neutral-700">
|
||||
<i class="bi bi-info-circle me-1"></i>
|
||||
Mensaje que se mostrará en la barra superior
|
||||
</small>
|
||||
<small class="form-text">
|
||||
<span id="topBarMessageTextCount" class="fw-bold">75</span><span class="text-neutral-600">/250 caracteres</span>
|
||||
</small>
|
||||
</div>
|
||||
<div class="progress mt-2" style="height: 4px;">
|
||||
<div id="topBarMessageTextProgress"
|
||||
class="progress-bar bg-orange-primary"
|
||||
role="progressbar"
|
||||
style="width: 30%"
|
||||
aria-valuenow="75"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="250"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Enlace -->
|
||||
<div class="row g-4">
|
||||
<div class="col-md-5">
|
||||
<div class="form-group">
|
||||
<label for="topBarLinkText" class="form-label text-neutral-700 fw-medium">
|
||||
<i class="bi bi-link-45deg text-orange-primary me-1"></i>
|
||||
Texto del enlace
|
||||
</label>
|
||||
<input type="text"
|
||||
id="topBarLinkText"
|
||||
class="form-control"
|
||||
placeholder="Ej: Ver Catálogo"
|
||||
maxlength="50"
|
||||
value="Ver Catálogo →">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-5">
|
||||
<div class="form-group">
|
||||
<label for="topBarLinkUrl" class="form-label text-neutral-700 fw-medium">
|
||||
<i class="bi bi-globe text-orange-primary me-1"></i>
|
||||
URL del enlace
|
||||
</label>
|
||||
<input type="url"
|
||||
id="topBarLinkUrl"
|
||||
class="form-control"
|
||||
placeholder="Ej: /catalogo o https://ejemplo.com"
|
||||
value="/catalogo">
|
||||
<small class="form-text text-neutral-700 mt-2 d-block">
|
||||
URLs relativas (/page) o absolutas (https://...)
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label for="topBarLinkTarget" class="form-label text-neutral-700 fw-medium">
|
||||
<i class="bi bi-window text-orange-primary me-1"></i>
|
||||
Target
|
||||
</label>
|
||||
<select id="topBarLinkTarget" class="form-select">
|
||||
<option value="_self" selected>Misma ventana</option>
|
||||
<option value="_blank">Nueva ventana</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-12">
|
||||
<div class="form-group">
|
||||
<div class="toggle-container">
|
||||
<div class="form-check form-switch form-switch-lg">
|
||||
<input class="form-check-input"
|
||||
type="checkbox"
|
||||
id="topBarShowLink"
|
||||
role="switch"
|
||||
checked>
|
||||
<label class="form-check-label" for="topBarShowLink">
|
||||
<strong>Mostrar enlace</strong>
|
||||
<span class="text-neutral-700 ms-2">- Activa para incluir un botón de acción</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Row para segunda fila de cards -->
|
||||
<div class="row">
|
||||
<!-- ============================= -->
|
||||
<!-- GRUPO 3: ESTILOS AVANZADOS -->
|
||||
<!-- ============================= -->
|
||||
<div class="col-md-6">
|
||||
<div class="form-section card shadow-sm border-0 mb-4 h-100">
|
||||
<div class="card-body">
|
||||
<h4 class="section-title">
|
||||
<span class="title-icon">
|
||||
<i class="bi bi-palette"></i>
|
||||
</span>
|
||||
Estilos Personalizados
|
||||
</h4>
|
||||
|
||||
<!-- Colores (4 en una fila) -->
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label for="topBarBgColor" class="form-label text-neutral-700 fw-medium mb-3">
|
||||
<i class="bi bi-paint-bucket text-orange-primary me-1"></i>
|
||||
Color de fondo
|
||||
</label>
|
||||
<div class="color-picker-wrapper">
|
||||
<input type="color"
|
||||
id="topBarBgColor"
|
||||
class="form-control form-control-color"
|
||||
value="#0E2337"
|
||||
title="Seleccionar color de fondo">
|
||||
<div class="color-preview-text mt-2">
|
||||
<code class="text-neutral-600 small">#0E2337</code>
|
||||
<small class="text-neutral-700 d-block">Navy Dark (Default)</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label for="topBarTextColor" class="form-label text-neutral-700 fw-medium mb-3">
|
||||
<i class="bi bi-fonts text-orange-primary me-1"></i>
|
||||
Color de texto
|
||||
</label>
|
||||
<div class="color-picker-wrapper">
|
||||
<input type="color"
|
||||
id="topBarTextColor"
|
||||
class="form-control form-control-color"
|
||||
value="#ffffff"
|
||||
title="Seleccionar color de texto">
|
||||
<div class="color-preview-text mt-2">
|
||||
<code class="text-neutral-600 small">#ffffff</code>
|
||||
<small class="text-neutral-700 d-block">White (Default)</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label for="topBarHighlightColor" class="form-label text-neutral-700 fw-medium mb-3">
|
||||
<i class="bi bi-star text-orange-primary me-1"></i>
|
||||
Color destacado
|
||||
</label>
|
||||
<div class="color-picker-wrapper">
|
||||
<input type="color"
|
||||
id="topBarHighlightColor"
|
||||
class="form-control form-control-color"
|
||||
value="#FF8600"
|
||||
title="Seleccionar color destacado">
|
||||
<div class="color-preview-text mt-2">
|
||||
<code class="text-neutral-600 small">#FF8600</code>
|
||||
<small class="text-neutral-700 d-block">Orange Primary (Default)</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label for="topBarLinkHoverColor" class="form-label text-neutral-700 fw-medium mb-3">
|
||||
<i class="bi bi-cursor text-orange-primary me-1"></i>
|
||||
Hover enlace
|
||||
</label>
|
||||
<div class="color-picker-wrapper">
|
||||
<input type="color"
|
||||
id="topBarLinkHoverColor"
|
||||
class="form-control form-control-color"
|
||||
value="#FF6B35"
|
||||
title="Seleccionar color hover del enlace">
|
||||
<div class="color-preview-text mt-2">
|
||||
<code class="text-neutral-600 small">#FF6B35</code>
|
||||
<small class="text-neutral-700 d-block">Orange Hover (Default)</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tamaño de fuente -->
|
||||
<div class="row g-4">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label for="topBarFontSize" class="form-label text-neutral-700 fw-medium">
|
||||
<i class="bi bi-type text-orange-primary me-1"></i>
|
||||
Tamaño de fuente
|
||||
</label>
|
||||
<select id="topBarFontSize" class="form-select form-select-lg">
|
||||
<option value="small">
|
||||
Pequeño - 0.8rem (ideal para mucho texto)
|
||||
</option>
|
||||
<option value="normal" selected>
|
||||
Normal - 0.9rem (recomendado)
|
||||
</option>
|
||||
<option value="large">
|
||||
Grande - 1rem (máxima legibilidad)
|
||||
</option>
|
||||
</select>
|
||||
<small class="form-text text-neutral-700 d-block mt-2">
|
||||
<i class="bi bi-info-circle me-1"></i>
|
||||
El tamaño afecta la altura total de la barra
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-8">
|
||||
<div class="alert alert-info-custom d-flex align-items-start" role="alert">
|
||||
<i class="bi bi-lightbulb-fill text-orange-primary me-3 fs-4"></i>
|
||||
<div>
|
||||
<h6 class="alert-heading mb-1">Tip de Diseño</h6>
|
||||
<p class="mb-0 small">
|
||||
Para mejor legibilidad, usa <strong>fondos oscuros</strong> (Navy Dark) con <strong>texto claro</strong> (White)
|
||||
y <strong>acentos naranjas</strong> para las acciones importantes.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ============================= -->
|
||||
<!-- VISTA PREVIA INTERACTIVA -->
|
||||
<!-- ============================= -->
|
||||
<div class="col-md-6">
|
||||
<div class="form-section card shadow-sm border-0 mb-4 bg-neutral-50 h-100">
|
||||
<div class="card-body">
|
||||
<h4 class="section-title">
|
||||
<span class="title-icon">
|
||||
<i class="bi bi-eye"></i>
|
||||
</span>
|
||||
Vista Previa en Tiempo Real
|
||||
</h4>
|
||||
|
||||
<div class="preview-container border border-2 border-neutral-100 rounded-3 p-4 bg-white">
|
||||
<!-- Top Bar Preview -->
|
||||
<div id="topBarPreview" class="top-bar-preview" style="background-color: #0E2337; color: #ffffff; padding: 12px 20px; border-radius: 8px; display: flex; align-items: center; justify-content: center; gap: 15px; flex-wrap: wrap;">
|
||||
<i class="bi bi-megaphone-fill" style="font-size: 1.2rem; color: #FF8600;"></i>
|
||||
<span style="font-weight: 700; color: #FF8600;">Nuevo:</span>
|
||||
<span style="flex: 1; min-width: 300px; text-align: center;">Accede a más de 200,000 Análisis de Precios Unitarios actualizados para 2025.</span>
|
||||
<a href="#" style="color: #ffffff; text-decoration: underline; white-space: nowrap; transition: color 0.3s;">Ver Catálogo →</a>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-4">
|
||||
<small class="text-neutral-700">
|
||||
<i class="bi bi-info-circle me-1"></i>
|
||||
La vista previa se actualiza automáticamente al modificar los campos
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 d-flex gap-2 justify-content-end">
|
||||
<button type="button" class="btn btn-outline-secondary">
|
||||
<i class="bi bi-phone me-1"></i>
|
||||
Ver en Mobile
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary">
|
||||
<i class="bi bi-display me-1"></i>
|
||||
Ver en Desktop
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<div class="admin-actions mt-4">
|
||||
<button type="button" id="saveSettings" class="button button-primary" disabled>
|
||||
<i class="bi bi-save me-2"></i>Guardar Cambios
|
||||
</button>
|
||||
<span class="spinner" style="display: none; float: none; margin-left: 10px;"></span>
|
||||
</div>
|
||||
</div>
|
||||
281
admin/pages/migration.php
Normal file
281
admin/pages/migration.php
Normal file
@@ -0,0 +1,281 @@
|
||||
<?php
|
||||
/**
|
||||
* Admin Panel - Theme Options Migration Page
|
||||
*
|
||||
* Interfaz para migrar Theme Options de wp_options a tabla personalizada
|
||||
*
|
||||
* @package Apus_Theme
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Instanciar migrator
|
||||
$migrator = new APUS_Theme_Options_Migrator();
|
||||
|
||||
// Obtener estadísticas
|
||||
$stats = $migrator->get_migration_stats();
|
||||
|
||||
// Procesar acciones
|
||||
$message = '';
|
||||
$message_type = '';
|
||||
|
||||
if (isset($_POST['apus_migrate_action'])) {
|
||||
check_admin_referer('apus_migration_action', 'apus_migration_nonce');
|
||||
|
||||
$action = sanitize_text_field($_POST['apus_migrate_action']);
|
||||
|
||||
switch ($action) {
|
||||
case 'migrate':
|
||||
$result = $migrator->migrate();
|
||||
$message = $result['message'];
|
||||
$message_type = $result['success'] ? 'success' : 'error';
|
||||
|
||||
// Actualizar estadísticas
|
||||
$stats = $migrator->get_migration_stats();
|
||||
break;
|
||||
|
||||
case 'rollback':
|
||||
$backup_name = isset($_POST['backup_name']) ? sanitize_text_field($_POST['backup_name']) : null;
|
||||
$result = $migrator->rollback($backup_name);
|
||||
$message = $result['message'];
|
||||
$message_type = $result['success'] ? 'success' : 'error';
|
||||
|
||||
// Actualizar estadísticas
|
||||
$stats = $migrator->get_migration_stats();
|
||||
break;
|
||||
|
||||
case 'delete_backup':
|
||||
$backup_name = isset($_POST['backup_name']) ? sanitize_text_field($_POST['backup_name']) : '';
|
||||
if ($backup_name && $migrator->delete_backup($backup_name)) {
|
||||
$message = 'Backup eliminado correctamente';
|
||||
$message_type = 'success';
|
||||
} else {
|
||||
$message = 'Error al eliminar backup';
|
||||
$message_type = 'error';
|
||||
}
|
||||
|
||||
// Actualizar estadísticas
|
||||
$stats = $migrator->get_migration_stats();
|
||||
break;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="wrap">
|
||||
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
|
||||
<p class="description">Migración de Theme Options desde wp_options a tabla personalizada wp_apus_theme_components</p>
|
||||
|
||||
<?php if ($message): ?>
|
||||
<div class="notice notice-<?php echo esc_attr($message_type); ?> is-dismissible">
|
||||
<p><?php echo esc_html($message); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Migration Status Card -->
|
||||
<div class="card mt-4" style="max-width: 800px;">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h5 class="mb-0">
|
||||
<i class="bi bi-info-circle me-2"></i>
|
||||
Estado de la Migración
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<strong>Estado:</strong>
|
||||
<?php if ($stats['is_migrated']): ?>
|
||||
<span class="badge bg-success">
|
||||
<i class="bi bi-check-circle me-1"></i>
|
||||
Migrado
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<span class="badge bg-warning text-dark">
|
||||
<i class="bi bi-exclamation-triangle me-1"></i>
|
||||
Pendiente
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<strong>Backups disponibles:</strong>
|
||||
<span class="badge bg-info"><?php echo esc_html($stats['backups_count']); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<strong>Opciones en wp_options:</strong>
|
||||
<span class="badge bg-secondary"><?php echo esc_html($stats['old_options_count']); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<strong>Configs en tabla nueva:</strong>
|
||||
<span class="badge bg-primary"><?php echo esc_html($stats['new_config_count']); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Progress Bar (si hay migración parcial) -->
|
||||
<?php if (!$stats['is_migrated'] && $stats['new_config_count'] > 0): ?>
|
||||
<div class="progress mt-3" style="height: 25px;">
|
||||
<?php
|
||||
$total = max($stats['old_options_count'], $stats['new_config_count']);
|
||||
$percentage = $total > 0 ? ($stats['new_config_count'] / $total) * 100 : 0;
|
||||
?>
|
||||
<div class="progress-bar bg-warning" role="progressbar"
|
||||
style="width: <?php echo esc_attr($percentage); ?>%;"
|
||||
aria-valuenow="<?php echo esc_attr($percentage); ?>"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100">
|
||||
<?php echo esc_html(round($percentage, 1)); ?>%
|
||||
</div>
|
||||
</div>
|
||||
<small class="text-muted">Migración parcial detectada</small>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Action Buttons Card -->
|
||||
<div class="card mt-4" style="max-width: 800px;">
|
||||
<div class="card-header bg-secondary text-white">
|
||||
<h5 class="mb-0">
|
||||
<i class="bi bi-gear me-2"></i>
|
||||
Acciones
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php if (!$stats['is_migrated']): ?>
|
||||
<!-- Migrate Button -->
|
||||
<form method="post" style="display: inline;">
|
||||
<?php wp_nonce_field('apus_migration_action', 'apus_migration_nonce'); ?>
|
||||
<input type="hidden" name="apus_migrate_action" value="migrate">
|
||||
<button type="submit" class="btn btn-primary" onclick="return confirm('¿Está seguro de ejecutar la migración? Se creará un backup automático.');">
|
||||
<i class="bi bi-arrow-right-circle me-1"></i>
|
||||
Ejecutar Migración
|
||||
</button>
|
||||
</form>
|
||||
<p class="text-muted mt-2 mb-0">
|
||||
<small>
|
||||
<i class="bi bi-info-circle me-1"></i>
|
||||
Se creará un backup automático antes de la migración. Total de configuraciones: <?php echo esc_html($stats['old_options_count']); ?>
|
||||
</small>
|
||||
</p>
|
||||
<?php else: ?>
|
||||
<div class="alert alert-success mb-0">
|
||||
<i class="bi bi-check-circle me-2"></i>
|
||||
La migración ya ha sido completada. Las opciones del tema ahora se leen desde la tabla personalizada.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Backups Card -->
|
||||
<?php if ($stats['backups_count'] > 0): ?>
|
||||
<div class="card mt-4" style="max-width: 800px;">
|
||||
<div class="card-header bg-info text-white">
|
||||
<h5 class="mb-0">
|
||||
<i class="bi bi-archive me-2"></i>
|
||||
Backups Disponibles (<?php echo esc_html($stats['backups_count']); ?>)
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Nombre del Backup</th>
|
||||
<th>Acciones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($stats['backups'] as $backup): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<code><?php echo esc_html($backup); ?></code>
|
||||
</td>
|
||||
<td>
|
||||
<!-- Rollback -->
|
||||
<form method="post" style="display: inline;" class="me-2">
|
||||
<?php wp_nonce_field('apus_migration_action', 'apus_migration_nonce'); ?>
|
||||
<input type="hidden" name="apus_migrate_action" value="rollback">
|
||||
<input type="hidden" name="backup_name" value="<?php echo esc_attr($backup); ?>">
|
||||
<button type="submit" class="btn btn-sm btn-warning" onclick="return confirm('¿Está seguro de restaurar este backup? Esto revertirá la migración.');">
|
||||
<i class="bi bi-arrow-counterclockwise me-1"></i>
|
||||
Restaurar
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<!-- Delete -->
|
||||
<form method="post" style="display: inline;">
|
||||
<?php wp_nonce_field('apus_migration_action', 'apus_migration_nonce'); ?>
|
||||
<input type="hidden" name="apus_migrate_action" value="delete_backup">
|
||||
<input type="hidden" name="backup_name" value="<?php echo esc_attr($backup); ?>">
|
||||
<button type="submit" class="btn btn-sm btn-danger" onclick="return confirm('¿Está seguro de eliminar este backup?');">
|
||||
<i class="bi bi-trash me-1"></i>
|
||||
Eliminar
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Technical Information -->
|
||||
<div class="card mt-4" style="max-width: 800px;">
|
||||
<div class="card-header bg-light">
|
||||
<h5 class="mb-0">
|
||||
<i class="bi bi-code-square me-2"></i>
|
||||
Información Técnica
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<dl class="row mb-0">
|
||||
<dt class="col-sm-4">Componente:</dt>
|
||||
<dd class="col-sm-8"><code>theme</code></dd>
|
||||
|
||||
<dt class="col-sm-4">Tabla antigua:</dt>
|
||||
<dd class="col-sm-8"><code>wp_options</code> (opción: <code>apus_theme_options</code>)</dd>
|
||||
|
||||
<dt class="col-sm-4">Tabla nueva:</dt>
|
||||
<dd class="col-sm-8"><code>wp_apus_theme_components</code></dd>
|
||||
|
||||
<dt class="col-sm-4">Versión Admin Panel:</dt>
|
||||
<dd class="col-sm-8"><code><?php echo esc_html(APUS_ADMIN_PANEL_VERSION); ?></code></dd>
|
||||
|
||||
<dt class="col-sm-4">Archivo Helper:</dt>
|
||||
<dd class="col-sm-8"><code>inc/theme-settings.php</code></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.card {
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 0.375rem;
|
||||
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
padding: 0.75rem 1rem;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.125);
|
||||
border-radius: calc(0.375rem - 1px) calc(0.375rem - 1px) 0 0;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 1rem;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user