public function save_image_settings_callback(): void { if ( ! check_ajax_referer('opnv_admin_nonce', 'nonce', false) ) { wp_send_json_error(['message' => __('Violación de seguridad: Nonce inválido.', 'optimizador-pro-notoriusvision')], 403); } if ( ! current_user_can('manage_options') ) { wp_send_json_error(['message' => __('Permisos insuficientes.', 'optimizador-pro-notoriusvision')], 403); } try { $post = wp_unslash($_POST); update_option('opnv_auto_convert', isset($post['auto_convert'])); update_option('opnv_enable_webp', isset($post['enable_webp'])); update_option('opnv_enable_avif', isset($post['enable_avif'])); update_option('opnv_reverse_convert', isset($post['reverse_convert'])); update_option('opnv_backup_original', isset($post['backup_original'])); update_option('opnv_strip_exif', isset($post['strip_exif'])); $quality = isset($post['image_quality']) ? (int) $post['image_quality'] : 82; $quality = max(50, min(100, $quality)); update_option('opnv_image_quality', $quality); $max_width = isset($post['max_width']) ? absint($post['max_width']) : 1920; $max_width = min($max_width, 10000); // tope razonable update_option('opnv_max_image_width', $max_width); SafeLogger::info('wpo_settings_updated', ['user_id' => get_current_user_id()]); wp_send_json_success(['message' => __('Ajustes WPO guardados correctamente.', 'optimizador-pro-notoriusvision')]); } catch (\Throwable $e) { SafeLogger::error('ajax_save_wpo_failed', ['msg' => $e->getMessage()]); wp_send_json_error(['message' => 'Error crítico: ' . $e->getMessage()], 500); } }