This commit is contained in:
Lizandro Guarnizo
2026-01-27 00:12:04 -05:00
parent a086e4a19a
commit 267805d5cd
6 changed files with 404 additions and 54 deletions
+39 -17
View File
@@ -27,6 +27,8 @@ try {
$limit = isset($_GET['limit']) ? intval($_GET['limit']) : 50;
$limit = max(1, min(200, $limit));
$before = !empty($_GET['before']) ? $_GET['before'] : null; // expect timestamp string
// We also support a 'since' parameter to fetch only messages strictly newer than a timestamp
$since = !empty($_GET['since']) ? $_GET['since'] : null;
// Validar formato de 'before' si se proporcionó (evitar SQL/parse errors por input malformado)
if (!is_null($before)) {
@@ -38,10 +40,19 @@ try {
}
}
// Validar 'since' si se pasó
if (!is_null($since)) {
if (!preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $since)) {
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'since timestamp inválido']);
exit;
}
}
$db = Database::getInstance();
// Construir consulta: obtener mensajes ordenados DESC (más recientes primero) y limitar
// Evitar ambigüedades prefijando columnas con el alias de la tabla (c)
// Construir consulta: by default paginamos hacia atrás (before) y ordenamos DESC
// Pero cuando se solicita 'since' queremos sólo mensajes más nuevos => orden ASC (para retornar cronológicamente)
$sql = "SELECT
c.id as id,
c.user_id as user_id,
@@ -65,20 +76,28 @@ try {
$beforeId = isset($_GET['before_id']) ? intval($_GET['before_id']) : null;
$params = ['user_id' => $userId];
if ($before) {
$sql .= " AND (c.created_at < :before_lt";
$params['before_lt'] = $before;
if ($beforeId) {
// Incluir mensajes con mismo timestamp pero id menor (paginación estable)
// Usamos placeholder distinto para evitar duplicar el mismo nombre en la query
$sql .= " OR (c.created_at = :before_eq AND c.id < :before_id)";
$params['before_eq'] = $before;
$params['before_id'] = $beforeId;
}
$sql .= ")";
}
$sql .= " ORDER BY c.created_at DESC, c.id DESC LIMIT " . $limit;
if (!is_null($since)) {
// If 'since' is provided, return only messages strictly newer than 'since' ordered ascending
$sql .= " AND c.created_at > :since";
$params['since'] = $since;
$sql .= " ORDER BY c.created_at ASC, c.id ASC LIMIT " . $limit;
} else {
if ($before) {
$sql .= " AND (c.created_at < :before_lt";
$params['before_lt'] = $before;
if ($beforeId) {
// Incluir mensajes con mismo timestamp pero id menor (paginación estable)
// Usamos placeholder distinto para evitar duplicar el mismo nombre en la query
$sql .= " OR (c.created_at = :before_eq AND c.id < :before_id)";
$params['before_eq'] = $before;
$params['before_id'] = $beforeId;
}
$sql .= ")";
}
$sql .= " ORDER BY c.created_at DESC, c.id DESC LIMIT " . $limit;
}
// Log params/consulta para diagnóstico si algo falla (no sensible)
error_log('get_user_messages.php - params: ' . json_encode(['user_id' => $userId, 'limit' => $limit, 'before' => $before]));
@@ -107,8 +126,11 @@ try {
exit;
}
// Queremos devolver los mensajes en orden cronológico ascendente para la UI
$conversations = array_reverse($conversations);
// Si se solicitó 'since' ya devolvimos en orden ASC (cronológico). Si no, revertimos
$sinceProvided = !is_null($since);
if (!$sinceProvided) {
$conversations = array_reverse($conversations);
}
// Recalcular usando el resultado final para decidir paginación
$finalCount = is_array($conversations) ? count($conversations) : 0;