beginTransaction(); // Get current product's order_position $stmt = $db->prepare("SELECT order_position FROM products WHERE id = :id"); $stmt->bindParam(':id', $productId, PDO::PARAM_INT); $stmt->execute(); $currentPosition = $stmt->fetchColumn(); if ($currentPosition === false) { throw new Exception('Producto no encontrado.'); } // Find adjacent product $adjacentProduct = null; if ($direction === 'up') { $stmt = $db->prepare("SELECT id, order_position FROM products WHERE order_position < :pos ORDER BY order_position DESC LIMIT 1"); } else { // 'down' $stmt = $db->prepare("SELECT id, order_position FROM products WHERE order_position > :pos ORDER BY order_position ASC LIMIT 1"); } $stmt->bindParam(':pos', $currentPosition, PDO::PARAM_INT); $stmt->execute(); $adjacentProduct = $stmt->fetch(PDO::FETCH_ASSOC); if ($adjacentProduct) { $adjacentProductId = $adjacentProduct['id']; $adjacentPosition = $adjacentProduct['order_position']; // Swap positions $stmtUpdate = $db->prepare("UPDATE products SET order_position = :new_pos WHERE id = :id"); // Move current product to adjacent position $stmtUpdate->bindValue(':new_pos', $adjacentPosition, PDO::PARAM_INT); $stmtUpdate->bindValue(':id', $productId, PDO::PARAM_INT); $stmtUpdate->execute(); // Move adjacent product to current position $stmtUpdate->bindValue(':new_pos', $currentPosition, PDO::PARAM_INT); $stmtUpdate->bindValue(':id', $adjacentProductId, PDO::PARAM_INT); $stmtUpdate->execute(); } // If no adjacent product, do nothing, just commit. $db->commit(); echo json_encode(['success' => true]); } catch (Exception $e) { if (isset($db) && $db->inTransaction()) { $db->rollBack(); } // Send a proper error response echo json_encode(['success' => false, 'message' => $e->getMessage()]); }