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'] ?? ''; ?> <?= htmlspecialchars($translations['seo_avis_title'], ENT_QUOTES, 'UTF-8') ?>

—

★★★★★
★★★★★
/5 •
★★★★★
★★★★★
•
1): ?>