From 3beb2929010d63bd7b5520dda17c6421675c0f74 Mon Sep 17 00:00:00 2001 From: FrankZamora Date: Sun, 9 Nov 2025 15:32:47 -0600 Subject: [PATCH] Fix: Corregir formato AJAX WordPress en Admin Panel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Causa raíz del error 400: El código estaba usando formato JSON cuando WordPress AJAX requiere application/x-www-form-urlencoded. ## Problema **Error:** POST admin-ajax.php 400 (Bad Request) **Causas:** 1. JavaScript enviaba datos como JSON (`Content-Type: application/json`) 2. PHP usaba `json_decode(file_get_contents('php://input'))` 3. WordPress AJAX espera `$_POST` con `action` y `nonce` ## Solución ### JavaScript (admin-app.js) ```javascript // ANTES (❌ Incorrecto) data: JSON.stringify({ action: 'apus_save_settings', nonce: apusAdminData.nonce, ...formData }) // AHORA (✅ Correcto) const postData = new URLSearchParams(); postData.append('action', 'apus_save_settings'); postData.append('nonce', apusAdminData.nonce); postData.append('components', JSON.stringify(formData.components)); ``` ### PHP (class-settings-manager.php) ```php // ANTES (❌ Incorrecto) $data = json_decode(file_get_contents('php://input'), true); // AHORA (✅ Correcto) $components = json_decode(stripslashes($_POST['components']), true); ``` ### Cambios Aplicados **admin-app.js:** - Usar `URLSearchParams` en lugar de `JSON.stringify` - Header `application/x-www-form-urlencoded` - Enviar `components` como JSON string en parámetro POST **class-settings-manager.php:** - Verificar nonce con `wp_verify_nonce($_POST['nonce'])` - Parsear `$_POST['components']` como JSON - Mensajes de error más descriptivos ## WordPress AJAX Requirements 1. ✅ `action` en $_POST 2. ✅ `nonce` en $_POST 3. ✅ Content-Type: application/x-www-form-urlencoded 4. ✅ Usar $_POST, no php://input 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- admin-panel/admin/assets/js/admin-app.js | 16 ++++++----- .../includes/class-settings-manager.php | 27 ++++++++++++++----- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/admin-panel/admin/assets/js/admin-app.js b/admin-panel/admin/assets/js/admin-app.js index 3a0535d1..f3ca3f8f 100644 --- a/admin-panel/admin/assets/js/admin-app.js +++ b/admin-panel/admin/assets/js/admin-app.js @@ -119,17 +119,21 @@ const AdminPanel = { try { const formData = this.collectFormData(); + // Crear FormData para WordPress AJAX + const postData = new URLSearchParams(); + postData.append('action', 'apus_save_settings'); + postData.append('nonce', apusAdminData.nonce); + + // Agregar components como JSON string + postData.append('components', JSON.stringify(formData.components)); + const response = await axios({ method: 'POST', url: apusAdminData.ajaxUrl, headers: { - 'Content-Type': 'application/json' + 'Content-Type': 'application/x-www-form-urlencoded' }, - data: JSON.stringify({ - action: 'apus_save_settings', - nonce: apusAdminData.nonce, - ...formData - }) + data: postData }); if (response.data.success) { diff --git a/admin-panel/includes/class-settings-manager.php b/admin-panel/includes/class-settings-manager.php index d5bfa7bb..c1752d2a 100644 --- a/admin-panel/includes/class-settings-manager.php +++ b/admin-panel/includes/class-settings-manager.php @@ -144,7 +144,10 @@ class APUS_Settings_Manager { * AJAX: Obtener configuraciones */ public function ajax_get_settings() { - check_ajax_referer('apus_admin_nonce', 'nonce'); + // Verificar nonce + if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'apus_admin_nonce')) { + wp_send_json_error('Nonce inválido'); + } if (!current_user_can('manage_options')) { wp_send_json_error('Permisos insuficientes'); @@ -158,18 +161,30 @@ class APUS_Settings_Manager { * AJAX: Guardar configuraciones */ public function ajax_save_settings() { - check_ajax_referer('apus_admin_nonce', 'nonce'); + // Verificar nonce + if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'apus_admin_nonce')) { + wp_send_json_error('Nonce inválido'); + } if (!current_user_can('manage_options')) { wp_send_json_error('Permisos insuficientes'); } - $data = json_decode(file_get_contents('php://input'), true); - - if (!$data) { - wp_send_json_error('Datos inválidos'); + // Los datos vienen como JSON string en $_POST['components'] + if (!isset($_POST['components'])) { + wp_send_json_error('Datos inválidos - falta components'); } + $components = json_decode(stripslashes($_POST['components']), true); + + if (!is_array($components)) { + wp_send_json_error('Datos inválidos - components no es un array válido'); + } + + $data = array( + 'components' => $components + ); + $result = $this->save_settings($data); if ($result['success']) {