ID invalide.";exit;}
function h($s)
{return htmlspecialchars((string) $s, ENT_QUOTES, 'UTF-8');}
function percent_from_5($n)
{$n = max(0, min(5, (float) $n));return (int) round($n / 5 * 100);}
function pseudo_from($prenom, $nom)
{
$p = trim((string) $prenom);
$n = trim((string) $nom);
$p = $p !== '' ? mb_convert_case($p, MB_CASE_TITLE, 'UTF-8') : 'Client';
$i = $n !== '' ? mb_strtoupper(mb_substr($n, 0, 1, 'UTF-8'), 'UTF-8') : '';
return $i ? ($p . '.' . $i) : $p;
}
// Titre + stats
$pp = $pdo->prepare("SELECT titre, prenom, nom FROM praticien WHERE id=?");
$pp->execute([$praticien_id]);
$pr = $pp->fetch(PDO::FETCH_ASSOC);
if (! $pr) {echo "
" . $translations['praticien_introuvable'] . "
";exit;}
$avg = $pdo->prepare("SELECT ROUND(AVG(note),1) AS m, COUNT(*) AS c FROM avis_praticien WHERE praticien_id=? AND statut='publie'");
$avg->execute([$praticien_id]);
$stats = $avg->fetch(PDO::FETCH_ASSOC) ?: ['m' => null, 'c' => 0];
// Form POST
$flash = null;
if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['do'] ?? '') === 'add') {
if (! hash_equals($_SESSION['csrf_token'] ?? '', $_POST['csrf'] ?? '')) {
$flash = ['type' => 'danger', 'msg' => $translations['avis_form_err']];
} elseif ($_SESSION['role'] !== 'client') {
$flash = ['type' => 'danger', 'msg' => $translations['non_autorise'] ?? 'Non autorisé'];
} else {
$note = (int) ($_POST['note'] ?? 0);
$titre = trim((string) ($_POST['titre'] ?? ''));
$commentaire = trim((string) ($_POST['commentaire'] ?? ''));
$visit_date = trim((string) ($_POST['visit_date'] ?? ''));
$ok = $note >= 1 && $note <= 5 && mb_strlen($commentaire, 'UTF-8') >= 10;
$date_ok = true;
if ($visit_date !== '') {
$ts = strtotime($visit_date . ' 00:00:00');
$date_ok = $ts && $ts <= time() + 86400; // pas dans le futur
}
if ($ok && $date_ok) {
$st = $pdo->prepare("INSERT INTO avis_praticien (praticien_id, client_id, note, titre, commentaire, visit_date, statut)
VALUES (?, ?, ?, ?, ?, ?, 'publie')");
$st->execute([$praticien_id, (int) $_SESSION['reference_id'], $note,
($titre !== '' ? $titre : null), ($commentaire !== '' ? $commentaire : null),
($visit_date !== '' ? $visit_date : null)]);
$flash = ['type' => 'success', 'msg' => $translations['avis_form_ok']];
// refresh stats
$avg->execute([$praticien_id]);
$stats = $avg->fetch(PDO::FETCH_ASSOC) ?: ['m' => null, 'c' => 0];
} else {
$flash = ['type' => 'danger', 'msg' => $translations['avis_form_err']];
}
}
}
// Pagination
$perPage = 10;
$page = max(1, (int) ($_GET['page'] ?? 1));
$offset = ($page - 1) * $perPage;
$cnt = $pdo->prepare("SELECT COUNT(*) FROM avis_praticien WHERE praticien_id = :pid AND statut = 'publie'");
$cnt->execute([':pid' => $praticien_id]);
$total = (int) $cnt->fetchColumn();
$pages = max(1, (int) ceil($total / $perPage));
$sql = "SELECT a.note, a.titre, a.commentaire, a.visit_date, a.created_at,
c.prenom, c.nom
FROM avis_praticien a
LEFT JOIN client c ON c.id = a.client_id
WHERE a.praticien_id = :pid AND a.statut = 'publie'
ORDER BY a.created_at DESC
LIMIT :o, :l";
$ls = $pdo->prepare($sql);
$ls->bindValue(':pid', $praticien_id, PDO::PARAM_INT);
$ls->bindValue(':o', (int) $offset, PDO::PARAM_INT);
$ls->bindValue(':l', (int) $perPage, PDO::PARAM_INT);
$ls->execute();
$avis = $ls->fetchAll(PDO::FETCH_ASSOC);
// ID depuis l'URL (on passe bien ?praticien_id=...)
$praticien_id = (int) ($_GET['praticien_id'] ?? 0);
if ($praticien_id <= 0) {echo "ID invalide.
";exit;}
// Charger le praticien
$pp = $pdo->prepare("SELECT titre, prenom, nom FROM praticien WHERE id = :id");
$pp->execute([':id' => $praticien_id]);
$pr = $pp->fetch(PDO::FETCH_ASSOC);
if (! $pr) {
echo "" . $translations['praticien_introuvable'] . "
";
exit;
}
// Définir $name AVANT de l'utiliser
$name = trim(
($pr['prenom'] ?? '')
. ' '
. ($pr['nom'] ?? '')
);
$CSRF = $_SESSION['csrf_token'] ?? '';
?>