Initial commit: Proyecto Portal ePromos completo con documentación unificada y seguridad base
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
// admin/jugadas_memoria.php
|
||||
session_start();
|
||||
require_once __DIR__ . '/db.php';
|
||||
if (empty($_SESSION['admin_id'])) { header('Location: ../index.php'); exit; }
|
||||
|
||||
function all_juegos(mysqli $conn){
|
||||
$res=$conn->query("SELECT juego_id, nombre FROM juegos_config ORDER BY juego_id ASC");
|
||||
return $res->fetch_all(MYSQLI_ASSOC);
|
||||
}
|
||||
$juegos = all_juegos($conn);
|
||||
|
||||
$juego_id = (int)($_GET['juego_id'] ?? 0);
|
||||
$q = trim($_GET['q'] ?? ''); // buscar por IP o UA
|
||||
$desde = $_GET['desde'] ?? '';
|
||||
$hasta = $_GET['hasta'] ?? '';
|
||||
|
||||
$where = "1=1"; $types=""; $params=[];
|
||||
if ($juego_id) { $where.=" AND jm.juego_id=?"; $types.="i"; $params[]=$juego_id; }
|
||||
if ($q!=='') { $where.=" AND (jm.ip_address LIKE CONCAT('%',?,'%') OR jm.user_agent LIKE CONCAT('%',?,'%'))"; $types.="ss"; $params[]=$q; $params[]=$q; }
|
||||
if ($desde!==''){ $where.=" AND jm.fecha_juego >= ?"; $types.="s"; $params[]=$desde." 00:00:00"; }
|
||||
if ($hasta!==''){ $where.=" AND jm.fecha_juego <= ?"; $types.="s"; $params[]=$hasta." 23:59:59"; }
|
||||
|
||||
// Export CSV
|
||||
if (($_GET['export'] ?? '') === 'csv') {
|
||||
header('Content-Type: text/csv; charset=utf-8');
|
||||
header('Content-Disposition: attachment; filename=jugadas_memoria.csv');
|
||||
$out=fopen('php://output','w');
|
||||
fputcsv($out,['ID','Fecha','Juego','Juego ID','Aciertos','Tiempo (ms)','IP','User Agent']);
|
||||
$sql="SELECT jm.id, jm.fecha_juego, gc.nombre AS juego, jm.juego_id, jm.aciertos, jm.tiempo_ms, jm.ip_address, jm.user_agent
|
||||
FROM jugadas_memoria jm
|
||||
LEFT JOIN juegos_config gc ON gc.juego_id=jm.juego_id
|
||||
WHERE $where ORDER BY jm.id DESC";
|
||||
$stmt=$conn->prepare($sql); if($types){ $stmt->bind_param($types, ...$params); }
|
||||
$stmt->execute(); $res=$stmt->get_result();
|
||||
while($r=$res->fetch_assoc()){ fputcsv($out, [$r['id'],$r['fecha_juego'],$r['juego'],$r['juego_id'],$r['aciertos'],$r['tiempo_ms'],$r['ip_address'],$r['user_agent']]); }
|
||||
fclose($out); exit;
|
||||
}
|
||||
|
||||
// Paginación
|
||||
$page=max(1,(int)($_GET['page']??1)); $pp=25; $off=($page-1)*$pp;
|
||||
|
||||
$sqlCount="SELECT COUNT(*) c FROM jugadas_memoria jm LEFT JOIN juegos_config gc ON gc.juego_id=jm.juego_id WHERE $where";
|
||||
$stmt=$conn->prepare($sqlCount); if($types){ $stmt->bind_param($types, ...$params); } $stmt->execute();
|
||||
$total=(int)$stmt->get_result()->fetch_assoc()['c'];
|
||||
|
||||
$sql="SELECT jm.id, jm.fecha_juego, gc.nombre AS juego, jm.juego_id, jm.aciertos, jm.tiempo_ms, jm.ip_address, jm.user_agent
|
||||
FROM jugadas_memoria jm
|
||||
LEFT JOIN juegos_config gc ON gc.juego_id=jm.juego_id
|
||||
WHERE $where ORDER BY jm.id DESC LIMIT $pp OFFSET $off";
|
||||
$stmt=$conn->prepare($sql); if($types){ $stmt->bind_param($types, ...$params); } $stmt->execute();
|
||||
$rows=$stmt->get_result()->fetch_all(MYSQLI_ASSOC);
|
||||
$pages=(int)ceil($total/$pp);
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Memoria | Jugadas</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg bg-dark navbar-dark">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="dashboard.php">Home</a>
|
||||
<div class="d-flex gap-2">
|
||||
<a class="btn btn-outline-light btn-sm" href="juegos_config.php">Memoria: Juegos</a>
|
||||
<a class="btn btn-outline-light btn-sm" href="cartas.php">Memoria: Cartas</a>
|
||||
<a class="btn btn-outline-light btn-sm" href="jugadas_memoria.php">Memoria: Jugadas</a>
|
||||
<a class="btn btn-outline-light btn-sm" href="../index.php?action=logout">Salir</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container py-4">
|
||||
<h3 class="mb-3">Jugadas — Memoria</h3>
|
||||
<form class="row g-2 mb-3" method="get">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Juego</label>
|
||||
<select name="juego_id" class="form-select">
|
||||
<option value="">Todos</option>
|
||||
<?php foreach($juegos as $j): ?>
|
||||
<option value="<?= (int)$j['juego_id'] ?>" <?= $juego_id===$j['juego_id']?'selected':'' ?>><?= htmlspecialchars($j['nombre']) ?> (ID <?= (int)$j['juego_id'] ?>)</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2"><label class="form-label">Desde</label><input type="date" name="desde" class="form-control" value="<?= htmlspecialchars($desde) ?>"></div>
|
||||
<div class="col-md-2"><label class="form-label">Hasta</label><input type="date" name="hasta" class="form-control" value="<?= htmlspecialchars($hasta) ?>"></div>
|
||||
<div class="col-md-3"><label class="form-label">Buscar (IP/UA)</label><input type="text" name="q" class="form-control" value="<?= htmlspecialchars($q) ?>"></div>
|
||||
<div class="col-md-2 d-flex align-items-end gap-2">
|
||||
<button class="btn btn-primary w-100">Filtrar</button>
|
||||
<a class="btn btn-outline-secondary" href="jugadas_memoria.php">Limpiar</a>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<a class="btn btn-success btn-sm" href="jugadas_memoria.php?<?= http_build_query(array_merge($_GET,['export'=>'csv','page'=>null])) ?>">Exportar CSV</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="card shadow-sm"><div class="card-body table-responsive">
|
||||
<table class="table table-striped table-sm align-middle">
|
||||
<thead><tr>
|
||||
<th>ID</th><th>Fecha</th><th>Juego</th><th>Juego ID</th><th>Aciertos</th><th>Tiempo (s)</th><th>IP</th><th>User Agent</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<?php foreach($rows as $r): ?>
|
||||
<tr>
|
||||
<td><?= (int)$r['id'] ?></td>
|
||||
<td><?= htmlspecialchars($r['fecha_juego']) ?></td>
|
||||
<td><?= htmlspecialchars($r['juego'] ?? '—') ?></td>
|
||||
<td><?= (int)$r['juego_id'] ?></td>
|
||||
<td><?= (int)$r['aciertos'] ?></td>
|
||||
<td><?= number_format(($r['tiempo_ms'] ?? 0)/1000, 2) ?></td>
|
||||
<td><?= htmlspecialchars($r['ip_address'] ?? '—') ?></td>
|
||||
<td class="text-truncate" style="max-width:400px;" title="<?= htmlspecialchars($r['user_agent'] ?? '') ?>"><?= htmlspecialchars($r['user_agent'] ?? '') ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php if (!$rows): ?><tr><td colspan="8" class="text-center text-muted">Sin registros</td></tr><?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div></div>
|
||||
|
||||
<?php if ($pages>1): ?>
|
||||
<nav class="mt-3"><ul class="pagination pagination-sm">
|
||||
<?php for($i=1;$i<=$pages;$i++): ?>
|
||||
<li class="page-item <?= $i===$page?'active':'' ?>"><a class="page-link" href="?<?= http_build_query(array_merge($_GET,['page'=>$i])) ?>"><?= $i ?></a></li>
|
||||
<?php endfor; ?>
|
||||
</ul></nav>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user