208 lines
10 KiB
PHP
208 lines
10 KiB
PHP
<?php
|
|
// admin/juegos_config.php
|
|
session_start();
|
|
require_once __DIR__ . '/db.php';
|
|
if (empty($_SESSION['admin_id'])) { header('Location: ../index.php'); exit; }
|
|
|
|
$UPLOAD_DIR = __DIR__ . '/../uploads/memoria'; // físico
|
|
$PUBLIC_DIR = '/ruleta/uploads/memoria'; // público: AJUSTA si tu base no es /ruleta
|
|
|
|
if (!is_dir($UPLOAD_DIR)) { @mkdir($UPLOAD_DIR, 0775, true); }
|
|
|
|
function sanitize_filename($name) {
|
|
$name = preg_replace('/[^A-Za-z0-9._-]/', '_', $name);
|
|
return substr($name, 0, 180);
|
|
}
|
|
function upload_image($field, $UPLOAD_DIR, $PUBLIC_DIR) {
|
|
if (!isset($_FILES[$field]) || $_FILES[$field]['error'] === UPLOAD_ERR_NO_FILE) return null;
|
|
$f = $_FILES[$field];
|
|
if ($f['error'] !== UPLOAD_ERR_OK) throw new RuntimeException("Error subiendo $field (código {$f['error']}).");
|
|
$finfo = new finfo(FILEINFO_MIME_TYPE); $mime = $finfo->file($f['tmp_name']);
|
|
$allowed = ['image/png'=>'png','image/jpeg'=>'jpg','image/webp'=>'webp'];
|
|
if (!isset($allowed[$mime])) throw new RuntimeException("Formato no permitido para $field. Usa PNG/JPG/WEBP.");
|
|
if ($f['size'] > 5 * 1024 * 1024) throw new RuntimeException("Archivo muy grande para $field (máx 5MB).");
|
|
$ext = $allowed[$mime];
|
|
$base = sanitize_filename(pathinfo($f['name'], PATHINFO_FILENAME));
|
|
$fname = $base . '-' . uniqid() . '.' . $ext;
|
|
$dest = rtrim($UPLOAD_DIR, "/\\") . DIRECTORY_SEPARATOR . $fname;
|
|
if (!move_uploaded_file($f['tmp_name'], $dest)) throw new RuntimeException("No se pudo guardar $field.");
|
|
return rtrim($PUBLIC_DIR, '/') . '/' . $fname;
|
|
}
|
|
function get_config(mysqli $conn, $juego_id) {
|
|
$stmt = $conn->prepare("SELECT * FROM juegos_config WHERE juego_id=?");
|
|
$stmt->bind_param("i", $juego_id); $stmt->execute();
|
|
return $stmt->get_result()->fetch_assoc();
|
|
}
|
|
|
|
$msg = $err = '';
|
|
$action = $_GET['action'] ?? '';
|
|
$juego_id = (int)($_GET['juego_id'] ?? 0);
|
|
|
|
// CREATE/UPDATE
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$jid = (int)($_POST['juego_id'] ?? 0);
|
|
$nombre = trim($_POST['nombre'] ?? '');
|
|
$ruleta_id = (int)($_POST['ruleta_id'] ?? 0);
|
|
|
|
$olds = [
|
|
'banner_1' => $_POST['old_banner_1'] ?? '',
|
|
'banner_2' => $_POST['old_banner_2'] ?? '',
|
|
'banner_3' => $_POST['old_banner_3'] ?? '',
|
|
'banner_4' => $_POST['old_banner_4'] ?? '',
|
|
'background_image' => $_POST['old_background_image'] ?? '',
|
|
'fullscreen_icon' => $_POST['old_fullscreen_icon'] ?? '',
|
|
'reverso_default' => $_POST['old_reverso_default'] ?? ''
|
|
];
|
|
|
|
if ($jid <= 0 || $nombre === '') {
|
|
$err = "Debes indicar un juego_id (entero) y un nombre.";
|
|
} else {
|
|
try {
|
|
$new = [
|
|
'banner_1' => upload_image('banner_1', $UPLOAD_DIR, $PUBLIC_DIR),
|
|
'banner_2' => upload_image('banner_2', $UPLOAD_DIR, $PUBLIC_DIR),
|
|
'banner_3' => upload_image('banner_3', $UPLOAD_DIR, $PUBLIC_DIR),
|
|
'banner_4' => upload_image('banner_4', $UPLOAD_DIR, $PUBLIC_DIR),
|
|
'background_image' => upload_image('background_image', $UPLOAD_DIR, $PUBLIC_DIR),
|
|
'fullscreen_icon' => upload_image('fullscreen_icon', $UPLOAD_DIR, $PUBLIC_DIR),
|
|
'reverso_default' => upload_image('reverso_default', $UPLOAD_DIR, $PUBLIC_DIR),
|
|
];
|
|
foreach ($new as $k=>$v) { $new[$k] = $v ?: ($olds[$k] ?: null); }
|
|
|
|
// upsert por juego_id
|
|
$stmt = $conn->prepare("INSERT INTO juegos_config
|
|
(juego_id, nombre, ruleta_id, banner_1,banner_2,banner_3,banner_4, background_image, fullscreen_icon, reverso_default)
|
|
VALUES (?,?,?,?,?,?,?,?,?,?)
|
|
ON DUPLICATE KEY UPDATE nombre=VALUES(nombre), ruleta_id=VALUES(ruleta_id),
|
|
banner_1=VALUES(banner_1), banner_2=VALUES(banner_2), banner_3=VALUES(banner_3), banner_4=VALUES(banner_4),
|
|
background_image=VALUES(background_image), fullscreen_icon=VALUES(fullscreen_icon), reverso_default=VALUES(reverso_default)");
|
|
$stmt->bind_param("isisssssss", $jid, $nombre, $ruleta_id,
|
|
$new['banner_1'], $new['banner_2'], $new['banner_3'], $new['banner_4'],
|
|
$new['background_image'], $new['fullscreen_icon'], $new['reverso_default']);
|
|
$stmt->execute();
|
|
$msg = "Configuración guardada.";
|
|
} catch (Throwable $e) {
|
|
$err = $e->getMessage();
|
|
}
|
|
}
|
|
}
|
|
|
|
// DELETE
|
|
if ($action === 'delete' && $juego_id > 0) {
|
|
$stmt = $conn->prepare("DELETE FROM juegos_config WHERE juego_id=?");
|
|
$stmt->bind_param("i", $juego_id); $stmt->execute();
|
|
$msg = "Configuración eliminada.";
|
|
}
|
|
|
|
// EDIT
|
|
$edit = null;
|
|
if ($action === 'edit' && $juego_id > 0) {
|
|
$edit = get_config($conn, $juego_id);
|
|
}
|
|
|
|
// LIST
|
|
$list = $conn->query("SELECT * FROM juegos_config ORDER BY juego_id ASC");
|
|
?>
|
|
<!doctype html>
|
|
<html lang="es">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Memoria | Configuración de Juegos</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">
|
|
<style>.thumb{width:70px;height:70px;object-fit:cover;border-radius:.5rem;}</style>
|
|
</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">Config. Juegos de Memoria</h3>
|
|
<?php if ($msg): ?><div class="alert alert-success py-2"><?= htmlspecialchars($msg) ?></div><?php endif; ?>
|
|
<?php if ($err): ?><div class="alert alert-danger py-2"><?= htmlspecialchars($err) ?></div><?php endif; ?>
|
|
|
|
<div class="card shadow-sm mb-4"><div class="card-body">
|
|
<h5 class="mb-3"><?= $edit ? 'Editar juego' : 'Nuevo/Actualizar juego (por juego_id)' ?></h5>
|
|
<form method="post" enctype="multipart/form-data" class="row g-3">
|
|
<div class="col-md-2">
|
|
<label class="form-label">Juego ID</label>
|
|
<input type="number" name="juego_id" class="form-control" required value="<?= htmlspecialchars($edit['juego_id'] ?? '') ?>">
|
|
</div>
|
|
<div class="col-md-5">
|
|
<label class="form-label">Nombre</label>
|
|
<input name="nombre" class="form-control" required value="<?= htmlspecialchars($edit['nombre'] ?? '') ?>">
|
|
</div>
|
|
|
|
<?php
|
|
// hidden olds
|
|
$fields = ['banner_1','banner_2','banner_3','banner_4','background_image','fullscreen_icon','reverso_default'];
|
|
foreach ($fields as $f) {
|
|
echo '<input type="hidden" name="old_'.$f.'" value="'.htmlspecialchars($edit[$f] ?? '').'">';
|
|
}
|
|
?>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Background</label>
|
|
<input type="file" name="background_image" class="form-control" accept=".png,.jpg,.jpeg,.webp">
|
|
<?php if (!empty($edit['background_image'])): ?><div class="mt-2"><img src="<?= htmlspecialchars($edit['background_image']) ?>" class="thumb"></div><?php endif; ?>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Ícono Fullscreen</label>
|
|
<input type="file" name="fullscreen_icon" class="form-control" accept=".png,.jpg,.jpeg,.webp">
|
|
<?php if (!empty($edit['fullscreen_icon'])): ?><div class="mt-2"><img src="<?= htmlspecialchars($edit['fullscreen_icon']) ?>" class="thumb"></div><?php endif; ?>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Reverso por defecto</label>
|
|
<input type="file" name="reverso_default" class="form-control" accept=".png,.jpg,.jpeg,.webp">
|
|
<?php if (!empty($edit['reverso_default'])): ?><div class="mt-2"><img src="<?= htmlspecialchars($edit['reverso_default']) ?>" class="thumb"></div><?php endif; ?>
|
|
</div>
|
|
|
|
<div class="col-12">
|
|
<button class="btn btn-primary">Guardar</button>
|
|
<?php if ($edit): ?><a href="juegos_config.php" class="btn btn-secondary">Cancelar</a><?php endif; ?>
|
|
</div>
|
|
</form>
|
|
</div></div>
|
|
|
|
<div class="card shadow-sm"><div class="card-body table-responsive">
|
|
<table class="table table-striped table-sm align-middle">
|
|
<thead><tr>
|
|
<th>Juego ID</th><th>Nombre</th><th>Ruleta</th>
|
|
<th>B1</th><th>B2</th><th>B3</th><th>B4</th>
|
|
<th>BG</th><th>FS</th><th>Reverso</th><th>Acciones</th>
|
|
</tr></thead>
|
|
<tbody>
|
|
<?php while($r = $list->fetch_assoc()): ?>
|
|
<tr>
|
|
<td><?= (int)$r['juego_id'] ?></td>
|
|
<td><?= htmlspecialchars($r['nombre']) ?></td>
|
|
<td><?= htmlspecialchars($r['ruleta_id'] ?? '') ?></td>
|
|
<td><?= $r['banner_1']?'<img class="thumb" src="'.htmlspecialchars($r['banner_1']).'">':'—' ?></td>
|
|
<td><?= $r['banner_2']?'<img class="thumb" src="'.htmlspecialchars($r['banner_2']).'">':'—' ?></td>
|
|
<td><?= $r['banner_3']?'<img class="thumb" src="'.htmlspecialchars($r['banner_3']).'">':'—' ?></td>
|
|
<td><?= $r['banner_4']?'<img class="thumb" src="'.htmlspecialchars($r['banner_4']).'">':'—' ?></td>
|
|
<td><?= $r['background_image']?'<img class="thumb" src="'.htmlspecialchars($r['background_image']).'">':'—' ?></td>
|
|
<td><?= $r['fullscreen_icon']?'<img class="thumb" src="'.htmlspecialchars($r['fullscreen_icon']).'">':'—' ?></td>
|
|
<td><?= $r['reverso_default']?'<img class="thumb" src="'.htmlspecialchars($r['reverso_default']).'">':'—' ?></td>
|
|
<td class="text-nowrap">
|
|
<a class="btn btn-sm btn-outline-primary" href="juegos_config.php?action=edit&juego_id=<?= (int)$r['juego_id'] ?>">Editar</a>
|
|
<a class="btn btn-sm btn-outline-danger" href="juegos_config.php?action=delete&juego_id=<?= (int)$r['juego_id'] ?>" onclick="return confirm('¿Eliminar config?')">Eliminar</a>
|
|
<a class="btn-outline-warning" href="/../ruleta/memoria/index.php?juego_id=<?= (int)$r['id'] ?>" target="_blank" rel="noopener noreferrer">Ver</a>
|
|
</td>
|
|
</tr>
|
|
<?php endwhile; ?>
|
|
</tbody>
|
|
</table>
|
|
</div></div>
|
|
</div>
|
|
</body>
|
|
</html>
|