93 lines
3.2 KiB
PHP
93 lines
3.2 KiB
PHP
<?php
|
|
// /messages/api/fetch_messages.php
|
|
declare(strict_types=1);
|
|
require_once __DIR__ . '/../_bootstrap.php';
|
|
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
|
|
$role = $GLOBALS['MESSAGES_CTX']['role'];
|
|
$meId = $GLOBALS['MESSAGES_CTX']['me_id'];
|
|
|
|
$convId = (int)($_GET['conversation_id'] ?? 0);
|
|
$sinceId = (int)($_GET['since_id'] ?? 0); // pour récupérer les NOUVEAUX messages (id > since_id)
|
|
$beforeId = (int)($_GET['before_id'] ?? 0); // pour paginer vers le HAUT (id < before_id)
|
|
$limit = (int)($_GET['limit'] ?? 50); // taille de page (max 100)
|
|
|
|
if ($convId <= 0) json_response(['error' => 'bad_params'], 400);
|
|
if ($limit <= 0) $limit = 50;
|
|
if ($limit > 100) $limit = 100;
|
|
|
|
// Vérifie droits et récupère la conversation
|
|
$conv = assert_conversation_access($pdo, $convId, $role, $meId);
|
|
|
|
// Filtre de visibilité selon le rôle (suppression “pour moi”)
|
|
$hideCol = ($role === 'praticien') ? 'deleted_for_praticien' : 'deleted_for_client';
|
|
|
|
// Stratégie de tri:
|
|
// - On interroge en DESC (plus récents en premier) pour limiter efficacement,
|
|
// - puis on reverse en PHP pour renvoyer ASC (du plus ancien au plus récent) côté client.
|
|
$params = [$convId];
|
|
$where = "conversation_id = ? AND $hideCol = 0";
|
|
$order = "ORDER BY id DESC";
|
|
$limitSql = "LIMIT $limit";
|
|
|
|
if ($sinceId > 0 && $beforeId > 0) {
|
|
// Cas ambigu — on privilégie since_id (nouveaux messages)
|
|
$beforeId = 0;
|
|
}
|
|
|
|
if ($sinceId > 0) {
|
|
$where .= " AND id > ?";
|
|
$params[] = $sinceId;
|
|
} elseif ($beforeId > 0) {
|
|
$where .= " AND id < ?";
|
|
$params[] = $beforeId;
|
|
} else {
|
|
// premier chargement (pas de since/before) → rien à ajouter
|
|
}
|
|
|
|
$sql = "SELECT id, conversation_id, sender_role, sender_id, body,
|
|
attachment_path, attachment_name, retracted_for_all, created_at
|
|
FROM messages
|
|
WHERE $where
|
|
$order
|
|
$limitSql";
|
|
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute($params);
|
|
$rowsDesc = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
// Transformations + placeholder “(Message supprimé)”
|
|
$rows = array_reverse($rowsDesc); // renvoyer ASC
|
|
foreach ($rows as &$m) {
|
|
$m['id'] = (int)$m['id'];
|
|
$m['conversation_id'] = (int)$m['conversation_id'];
|
|
$m['sender_id'] = (int)$m['sender_id'];
|
|
if (!empty($m['retracted_for_all'])) {
|
|
$m['body'] = '(' . ($translations['msg_message_supprime'] ?? 'Message supprimé') . ')';
|
|
$m['attachment_path'] = null;
|
|
$m['attachment_name'] = null;
|
|
}
|
|
unset($m['retracted_for_all']);
|
|
}
|
|
unset($m);
|
|
|
|
// Calcul du “has_more” pour la pagination vers le haut (before_id)
|
|
$hasMore = false;
|
|
$nextBeforeId = null;
|
|
if (!empty($rows)) {
|
|
// Si on a utilisé beforeId (ou premier load), vérifier s'il reste des messages plus anciens
|
|
// On prend le plus ancien renvoyé (premier en ASC) et teste s'il existe plus ancien
|
|
$oldestId = $rows[0]['id'];
|
|
$stmt2 = $pdo->prepare("SELECT 1 FROM messages WHERE conversation_id = ? AND $hideCol = 0 AND id < ? LIMIT 1");
|
|
$stmt2->execute([$convId, $oldestId]);
|
|
$hasMore = (bool)$stmt2->fetchColumn();
|
|
$nextBeforeId = $oldestId; // pour l'appel suivant: before_id = oldestId
|
|
}
|
|
|
|
json_response([
|
|
'items' => $rows,
|
|
'has_more' => $hasMore,
|
|
'next_before_id'=> $hasMore ? $nextBeforeId : null,
|
|
]);
|