diff --git a/admin/ARQUITECTURA-DATOS.md b/admin/ARQUITECTURA-DATOS.md new file mode 100644 index 00000000..8306ebc7 --- /dev/null +++ b/admin/ARQUITECTURA-DATOS.md @@ -0,0 +1,354 @@ +# Arquitectura de Datos - Apus Theme + +**Fecha:** 2025-01-14 +**VersiΓ³n:** 2.2.0 + +--- + +## πŸ“Š ARQUITECTURA FINAL IMPLEMENTADA + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ APUS_DB_MANAGER (Clase Única) β”‚ +β”‚ β”œβ”€ Maneja AMBAS tablas con misma estructura β”‚ +β”‚ β”œβ”€ ParΓ‘metro: table_type = 'components' | 'defaults' β”‚ +β”‚ └─ MΓ©todos: β”‚ +β”‚ β”œβ”€ get_config($component, $key, $table_type) β”‚ +β”‚ β”œβ”€ save_config(..., $table_type) β”‚ +β”‚ β”œβ”€ delete_config(..., $table_type) β”‚ +β”‚ └─ list_components($table_type) β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + ↓ + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ + ↓ ↓ +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ TABLA: DEFAULTS β”‚ β”‚ TABLA: COMPONENTS β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ wp_apus_theme_ β”‚ β”‚ wp_apus_theme_ β”‚ +β”‚ components_defaults β”‚ β”‚ components β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ PROPΓ“SITO: β”‚ β”‚ PROPΓ“SITO: β”‚ +β”‚ Valores por defecto β”‚ β”‚ Personalizaciones β”‚ +β”‚ del tema β”‚ β”‚ del usuario β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ ESCRITURA: β”‚ β”‚ ESCRITURA: β”‚ +β”‚ Algoritmo β”‚ β”‚ Admin Panel β”‚ +β”‚ /implementar- β”‚ β”‚ (Settings Manager) β”‚ +β”‚ componente-admin β”‚ β”‚ β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ LECTURA: β”‚ β”‚ LECTURA: β”‚ +β”‚ Settings Manager β”‚ β”‚ Settings Manager β”‚ +β”‚ Frontend β”‚ β”‚ Frontend β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +--- + +## πŸ—„οΈ ESTRUCTURA DE TABLAS (IdΓ©ntica) + +Ambas tablas tienen la misma estructura: + +```sql +CREATE TABLE wp_apus_theme_components_defaults ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + component_name VARCHAR(50) NOT NULL, + config_key VARCHAR(100) NOT NULL, + config_value TEXT NOT NULL, + data_type ENUM('string', 'boolean', 'integer', 'json') DEFAULT 'string', + version VARCHAR(10) DEFAULT NULL, + updated_at DATETIME NOT NULL, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (id), + UNIQUE KEY component_config (component_name, config_key), + INDEX idx_component (component_name), + INDEX idx_updated (updated_at) +); + +-- Misma estructura para wp_apus_theme_components +``` + +--- + +## πŸ”„ FLUJO DE DATOS + +### 1. ESCRITURA DE DEFAULTS (Algoritmo) + +```php +// Algoritmo escribe defaults a tabla defaults +$db_manager = new APUS_DB_Manager(); +$db_manager->save_config( + 'top_bar', // component_name + 'enabled', // config_key + '1', // config_value + 'boolean', // data_type + '2.0.0', // version + 'defaults' // table_type ← IMPORTANTE +); +``` + +### 2. LECTURA DE DEFAULTS (Settings Manager) + +```php +// Settings Manager lee defaults +public function get_defaults() { + $db_manager = new APUS_DB_Manager(); + $component_names = $db_manager->list_components('defaults'); + + $defaults = array( + 'version' => APUS_ADMIN_PANEL_VERSION, + 'components' => array() + ); + + foreach ($component_names as $component_name) { + $defaults['components'][$component_name] = + $db_manager->get_config($component_name, null, 'defaults'); + } + + return $defaults; +} +``` + +### 3. ESCRITURA DE PERSONALIZACIONES (Admin Panel) + +```php +// Settings Manager guarda personalizaciones en wp_options +public function save_settings($data) { + // Validar y sanitizar... + + $sanitized['version'] = APUS_ADMIN_PANEL_VERSION; + $sanitized['updated_at'] = current_time('mysql'); + + // Guardar en wp_options + update_option(self::OPTION_NAME, $sanitized, false); + + return array('success' => true); +} +``` + +### 4. MERGE DE DATOS (Settings Manager) + +```php +// Combinar defaults + personalizaciones +public function get_settings() { + $settings = get_option(self::OPTION_NAME, array()); + $defaults = $this->get_defaults(); + + // wp_parse_args combina: personalizaciones sobrescriben defaults + return wp_parse_args($settings, $defaults); +} +``` + +### 5. LECTURA EN FRONTEND + +```php +// Frontend obtiene datos combinados +$settings_manager = new APUS_Settings_Manager(); +$all_settings = $settings_manager->get_settings(); + +// Ejemplo: Top Bar +$top_bar_config = $all_settings['components']['top_bar']; +echo $top_bar_config['message_text']; // Default o personalizado +``` + +--- + +## 🎯 DECISIΓ“N ARQUITECTΓ“NICA: OPCIΓ“N A + +**Personalizaciones se guardan en:** `wp_options` (opciΓ³n `apus_theme_settings`) + +### βœ… Ventajas OpciΓ³n A (Implementada): + +- MΓ‘s simple y directo +- Ya implementado y funcionando +- Compatible con Settings Manager actual +- FΓ‘cil de migrar/exportar (una sola opciΓ³n) +- Respaldado automΓ‘ticamente con wp_options + +### ❌ OpciΓ³n B Descartada: + +- Guardar personalizaciones en `wp_apus_theme_components` +- MΓ‘s complejo +- RequerirΓ­a cambios extensos en Settings Manager +- No aporta beneficios claros sobre OpciΓ³n A + +--- + +## πŸ“ CLASES Y RESPONSABILIDADES + +### `APUS_DB_Manager` + +**UbicaciΓ³n:** `admin/includes/class-db-manager.php` + +**Responsabilidades:** +- βœ… Crear ambas tablas (components y defaults) +- βœ… CRUD en tabla defaults (algoritmo escribe) +- βœ… CRUD en tabla components (si se necesita en futuro) +- βœ… Parsear tipos de datos (boolean, integer, json, string) + +**MΓ©todos principales:** +```php +get_table_name($table_type = 'components') +create_tables() +table_exists($table_type = 'components') +save_config($component, $key, $value, $data_type, $version, $table_type = 'components') +get_config($component, $key = null, $table_type = 'components') +delete_config($component, $key = null, $table_type = 'components') +list_components($table_type = 'components') +``` + +### `APUS_Settings_Manager` + +**UbicaciΓ³n:** `admin/includes/class-settings-manager.php` + +**Responsabilidades:** +- βœ… Leer defaults desde tabla defaults (vΓ­a DB Manager) +- βœ… Leer personalizaciones desde wp_options +- βœ… Combinar defaults + personalizaciones (merge) +- βœ… Guardar personalizaciones en wp_options +- βœ… Validar datos (vΓ­a Validator) +- βœ… Sanitizar datos +- βœ… AJAX endpoints (get/save) + +**MΓ©todos principales:** +```php +get_settings() // Retorna: defaults + personalizaciones +get_defaults() // Lee desde tabla defaults +save_settings($data) // Guarda en wp_options +ajax_get_settings() // AJAX endpoint +ajax_save_settings() // AJAX endpoint +``` + +--- + +## πŸš€ ESTADO ACTUAL + +### βœ… COMPLETADO: + +1. βœ… APUS_DB_Manager mejorado para soportar ambas tablas +2. βœ… Ambas tablas creadas (vacΓ­as) +3. βœ… Settings Manager integrado con DB Manager +4. βœ… get_defaults() lee desde tabla defaults +5. βœ… MenΓΊ admin movido a nivel superior en sidebar +6. βœ… Sistema listo para leer/escribir datos + +### ⏳ PENDIENTE: + +1. ⏳ Poblar tabla defaults con datos de prueba +2. ⏳ Probar lectura de defaults +3. ⏳ Probar guardar personalizaciones +4. ⏳ Probar merge defaults + personalizaciones +5. ⏳ Probar renderizado en frontend +6. ⏳ Modificar algoritmo `/implementar-componente-admin` + +--- + +## πŸ“‹ PRΓ“XIMOS PASOS + +### PASO 5.1: Poblar tabla defaults + +Insertar datos de prueba del componente Top Bar: + +```sql +INSERT INTO wp_apus_theme_components_defaults +(component_name, config_key, config_value, data_type, version, updated_at) +VALUES +('top_bar', 'enabled', '1', 'boolean', '2.0.0', NOW()), +('top_bar', 'message_text', 'Accede a mΓ‘s de 200,000 AnΓ‘lisis...', 'string', '2.0.0', NOW()), +('top_bar', 'show_icon', '1', 'boolean', '2.0.0', NOW()), +('top_bar', 'icon_class', 'bi bi-megaphone-fill', 'string', '2.0.0', NOW()), +('top_bar', 'cta_text', 'Ver CatΓ‘logo', 'string', '2.0.0', NOW()), +('top_bar', 'cta_url', '#', 'string', '2.0.0', NOW()); +``` + +### PASO 5.2: Crear script de prueba + +Archivo: `admin/test-defaults.php` + +```php +get_defaults(); +print_r($defaults); + +// Test 2: Guardar personalizaciΓ³n +echo "\n=== TEST 2: Guardar personalizaciΓ³n ===\n"; +$custom_data = array( + 'components' => array( + 'top_bar' => array( + 'message_text' => 'Texto personalizado por usuario' + ) + ) +); +$result = $settings_manager->save_settings($custom_data); +print_r($result); + +// Test 3: Leer settings combinados +echo "\n=== TEST 3: Leer settings combinados ===\n"; +$all_settings = $settings_manager->get_settings(); +print_r($all_settings); +``` + +--- + +## πŸŽ“ CONCEPTOS CLAVE + +### ΒΏPor quΓ© UNA clase para ambas tablas? + +**RazΓ³n:** Ambas tablas tienen estructura idΓ©ntica y almacenan el mismo tipo de datos (configuraciones de componentes). La ΓΊnica diferencia es el PROPΓ“SITO: + +- **Defaults:** Valores originales del tema +- **Components:** Personalizaciones del usuario + +Usar una sola clase con parΓ‘metro `table_type` es mΓ‘s limpio y DRY (Don't Repeat Yourself). + +### ΒΏDΓ³nde se almacenan las personalizaciones? + +**wp_options** (opciΓ³n `apus_theme_settings`) + +**ΒΏPor quΓ© no en tabla components?** +- MΓ‘s simple +- Ya implementado +- FΓ‘cil de migrar/exportar +- La tabla `components` queda disponible para uso futuro si se necesita + +### ΒΏCΓ³mo funciona el merge? + +```php +wp_parse_args($personalizaciones, $defaults) +``` + +Resultado: +- Si existe personalizaciΓ³n para una clave β†’ usa personalizaciΓ³n +- Si NO existe personalizaciΓ³n β†’ usa default +- Ejemplo: + - Default: `message_text = "Accede a mΓ‘s de 200,000..."` + - PersonalizaciΓ³n: `message_text = "Texto personalizado"` + - **Resultado:** `"Texto personalizado"` + +--- + +## πŸ” VERIFICACIΓ“N DE ARQUITECTURA + +### Checklist pre-modificaciΓ³n de algoritmo: + +- βœ… Existe `APUS_DB_Manager` con soporte para ambas tablas +- βœ… DB Manager puede leer/escribir en tabla defaults +- βœ… Settings Manager usa DB Manager para get_defaults() +- βœ… Settings Manager guarda personalizaciones en wp_options +- βœ… Ambas tablas existen en la base de datos +- ⏳ Tabla defaults tiene datos de prueba +- ⏳ Tests de lectura funcionan +- ⏳ Tests de escritura funcionan +- ⏳ Frontend renderiza correctamente + +--- + +**Última actualizaciΓ³n:** 2025-01-14 +**Estado:** ARQUITECTURA IMPLEMENTADA - LISTO PARA TESTING