'
. htmlspecialchars((string)($translations['audite_access_denied'] ?? 'Accès refusé.'), ENT_QUOTES, 'UTF-8')
. '
';
return;
}
require_once __DIR__.'/_lib_audit.php';
// reauth (10 min)
$mustReauth=function(int $ttl=600){$t=(int)($_SESSION['admin_reauth_at']??0);return ($t===0||(time()-$t)>$ttl);};
if ($mustReauth()){ $qs=http_build_query(['page'=>'reauth','redir'=>($_SERVER['REQUEST_URI']??'index.php?page=maintenance')]); header('Location:?'.$qs); exit; }
if (!isset($pdo)) { $db = realpath(__DIR__.'/../../includes/db.php'); if ($db) require_once $db; }
if (!isset($pdo) || !($pdo instanceof PDO)) {
echo ''
. htmlspecialchars((string)($translations['audite_db_unavailable'] ?? 'DB indisponible.'), ENT_QUOTES, 'UTF-8')
. '
';
return;
}
try { $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch(Throwable) {}
$e = static fn($s)=>htmlspecialchars((string)$s,ENT_QUOTES,'UTF-8');
if (empty($_SESSION['csrf_token'])) $_SESSION['csrf_token']=bin2hex(random_bytes(32));
$CSRF=$_SESSION['csrf_token'];
// filtres
$qAdmin = (int)($_GET['admin_id'] ?? 0);
$qAct = trim($_GET['action'] ?? '');
$qFrom = trim($_GET['from'] ?? '');
$qTo = trim($_GET['to'] ?? '');
$page = max(1, (int)($_GET['p'] ?? 1));
$per = min(200, max(10,(int)($_GET['per'] ?? 50)));
$w=[]; $p=[];
if ($qAdmin>0){ $w[]='admin_id=:aid'; $p[':aid']=$qAdmin; }
if ($qAct!==''){ $w[]='action=:act'; $p[':act']=$qAct; }
if ($qFrom!==''){ $w[]='created_at>=:f'; $p[':f']=$qFrom.' 00:00:00'; }
if ($qTo!==''){ $w[]='created_at<=:t'; $p[':t']=$qTo.' 23:59:59'; }
$where = $w?('WHERE '.implode(' AND ',$w)):'';
$cnt = $pdo->prepare("SELECT COUNT(*) FROM admin_audit $where");
$cnt->execute($p); $total=(int)$cnt->fetchColumn();
$pages = max(1,(int)ceil($total/$per));
$off = ($page-1)*$per;
$sql = "SELECT id,admin_id,action,scope,target_table,target_id,meta_json,INET6_NTOA(ip) ip,user_agent,created_at
FROM admin_audit $where ORDER BY id DESC LIMIT $per OFFSET $off";
$stmt=$pdo->prepare($sql); $stmt->execute($p);
$rows=$stmt->fetchAll(PDO::FETCH_ASSOC);
?>
= $e($translations['audite_title'] ?? 'Journal d’audit (actions admin)') ?>
| = $e($translations['audite_th_id'] ?? '#') ?> |
= $e($translations['audite_th_admin'] ?? 'Admin') ?> |
= $e($translations['audite_th_action'] ?? 'Action') ?> |
= $e($translations['audite_th_scope'] ?? 'Scope') ?> |
= $e($translations['audite_th_target'] ?? 'Cible') ?> |
= $e($translations['audite_th_ip'] ?? 'IP') ?> |
= $e($translations['audite_th_date'] ?? 'Date') ?> |
= $e($translations['audite_th_meta'] ?? 'Meta') ?> |
| = (int)$r['id'] ?> |
= (int)$r['admin_id'] ?> |
= $e($r['action']) ?> |
= $e($r['scope'] ?? '') ?> |
= $e($r['target_table'] ?? '') ?>= $r['target_id']?(' #'.(int)$r['target_id']):'' ?> |
= $e($r['ip'] ?? '') ?> |
= $e($r['created_at']) ?> |
= $e($r['meta_json'] ?? '') ?> |
1): ?>