false, 'error' => 'Método no permitido']); exit; } try { $input = json_decode(file_get_contents('php://input'), true); if (!$input || !isset($input['name'])) { http_response_code(400); echo json_encode(['success' => false, 'error' => 'Nombre del menú es requerido']); exit; } $db = Database::getInstance(); // Iniciar transacción $db->beginTransaction(); try { // Verificar si es actualización o creación $isUpdate = isset($input['id']) && !empty($input['id']); $menuId = $isUpdate ? intval($input['id']) : null; if ($isUpdate) { // Verificar que el menú existe $existingMenu = $db->fetch("SELECT id FROM menus WHERE id = ?", [$menuId]); if (!$existingMenu) { throw new Exception('Menú no encontrado para actualizar'); } } // Verificar estructura de tabla antes de insertar/actualizar $tableStructure = $db->fetchAll("DESCRIBE menus"); $availableColumns = array_column($tableStructure, 'Field'); error_log("Columnas disponibles en tabla menus: " . json_encode($availableColumns)); // Adaptar datos a la estructura real de la tabla $menuData = []; // La tabla usa 'name' para la clave del menú if (in_array('name', $availableColumns)) { $menuData['name'] = $input['menu_key'] ?? $input['name'] ?? 'menu_' . time(); } // La tabla usa 'title' para el nombre visible del menú if (in_array('title', $availableColumns)) { $menuData['title'] = $input['name'] ?? $input['title'] ?? 'Nuevo Menú'; } if (in_array('description', $availableColumns)) { $menuData['description'] = $input['description'] ?? ''; } if (in_array('parent_id', $availableColumns)) { $menuData['parent_id'] = empty($input['parent_id']) ? null : (int)$input['parent_id']; } if (in_array('is_root', $availableColumns)) { $menuData['is_root'] = empty($input['parent_id']) ? 1 : 0; } if (in_array('is_active', $availableColumns)) { // Mapear status a is_active: 'active' -> 1, cualquier otra cosa -> 0 $menuData['is_active'] = (($input['status'] ?? 'active') === 'active') ? 1 : 0; } if (in_array('order_position', $availableColumns) && !$isUpdate) { // Solo establecer order_position para menús nuevos $maxOrder = $db->fetch("SELECT COALESCE(MAX(order_position), 0) as max_order FROM menus"); $menuData['order_position'] = ($maxOrder['max_order'] ?? 0) + 1; } if (in_array('created_at', $availableColumns) && !$isUpdate) { $menuData['created_at'] = date('Y-m-d H:i:s'); } if (in_array('updated_at', $availableColumns)) { $menuData['updated_at'] = date('Y-m-d H:i:s'); } // Crear o actualizar menú if ($isUpdate) { $result = $db->update('menus', $menuData, 'id = :menu_id', ['menu_id' => $menuId]); if (!$result || $result->rowCount() === 0) { throw new Exception('No se pudo actualizar el menú'); } } else { $menuId = $db->insert('menus', $menuData); if (!$menuId) { throw new Exception('Error insertando menú'); } } // Procesar opciones si las hay $optionsCount = 0; if (isset($input['options']) && is_array($input['options'])) { foreach ($input['options'] as $option) { if (!empty($option['key']) && !empty($option['text'])) { $optionData = [ 'menu_id' => $menuId, 'option_key' => $option['key'], 'option_text' => $option['text'], 'option_action' => $option['action'] ?? 'message', 'option_value' => $option['value'] ?? '', 'order_index' => $option['order_index'] ?? $optionsCount + 1, 'is_active' => true, 'created_at' => date('Y-m-d H:i:s') ]; $optionId = $db->insert('menu_options', $optionData); if ($optionId) { $optionsCount++; } } } } // Actualizar contador de opciones solo si la columna existe if (in_array('options_count', $availableColumns)) { $db->execute("UPDATE menus SET options_count = :count WHERE id = :id", [ 'count' => $optionsCount, 'id' => $menuId ]); } $db->commit(); echo json_encode([ 'success' => true, 'message' => $isUpdate ? 'Menú actualizado correctamente' : 'Menú guardado correctamente', 'menu_id' => $menuId, 'options_created' => $optionsCount, 'action' => $isUpdate ? 'updated' : 'created' ]); } catch (Exception $e) { $db->rollback(); throw $e; } } catch (Exception $e) { error_log("Error in save_menu.php: " . $e->getMessage()); http_response_code(500); echo json_encode([ 'success' => false, 'error' => 'Error interno del servidor', 'debug' => $e->getMessage() ]); } ?>