Files
portal-epromos/admin/cartas.php
T

187 lines
9.2 KiB
PHP

<?php
// admin/cartas.php
session_start();
require_once __DIR__ . '/db.php';
if (empty($_SESSION['admin_id'])) { header('Location: ../index.php'); exit; }
$UPLOAD_DIR = __DIR__ . '/../uploads/memoria';
$PUBLIC_DIR = '/ruleta/uploads/memoria'; // 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.");
$mime=(new finfo(FILEINFO_MIME_TYPE))->file($f['tmp_name']);
$allowed=['image/png'=>'png','image/jpeg'=>'jpg','image/webp'=>'webp']; if(!isset($allowed[$mime])) throw new RuntimeException("Formato no permitido.");
if($f['size']>5*1024*1024) throw new RuntimeException("Archivo muy grande (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 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);
}
function get_carta(mysqli $conn,$id){
$stmt=$conn->prepare("SELECT * FROM cartas WHERE id=?"); $stmt->bind_param("i",$id); $stmt->execute();
return $stmt->get_result()->fetch_assoc();
}
$msg=$err=''; $action=$_GET['action']??''; $id=(int)($_GET['id']??0);
$juegos=all_juegos($conn);
$juego_id=(int)($_GET['juego_id'] ?? ($juegos[0]['juego_id'] ?? 1));
// CREATE/UPDATE
if ($_SERVER['REQUEST_METHOD']==='POST') {
$cid=(int)($_POST['id']??0);
$juego_id=(int)($_POST['juego_id']??0);
$nombre=trim($_POST['nombre']??'');
$activo=isset($_POST['activo'])?1:0;
$old_front=$_POST['old_imagen_frontal']??'';
$old_back =$_POST['old_imagen_trasera']??'';
if ($juego_id<=0 || $nombre==='') {
$err="Selecciona juego y nombre.";
} else {
try{
$new_front=upload_image('imagen_frontal',$UPLOAD_DIR,$PUBLIC_DIR);
$new_back =upload_image('imagen_trasera',$UPLOAD_DIR,$PUBLIC_DIR);
$front=$new_front?:($old_front?:null);
$back =$new_back ?:($old_back ?:null);
if ($cid>0) {
$stmt=$conn->prepare("UPDATE cartas SET juego_id=?, nombre=?, imagen_frontal=?, imagen_trasera=?, activo=? WHERE id=?");
$stmt->bind_param("isssii",$juego_id,$nombre,$front,$back,$activo,$cid);
$stmt->execute(); $msg="Carta actualizada.";
} else {
if(!$back){ throw new RuntimeException("La imagen trasera es obligatoria."); }
$stmt=$conn->prepare("INSERT INTO cartas (juego_id,nombre,imagen_frontal,imagen_trasera,activo) VALUES (?,?,?,?,?)");
$stmt->bind_param("isssi",$juego_id,$nombre,$front,$back,$activo);
$stmt->execute(); $msg="Carta creada.";
}
}catch(Throwable $e){ $err=$e->getMessage(); }
}
}
// DELETE
if ($action==='delete' && $id>0) {
$stmt=$conn->prepare("DELETE FROM cartas WHERE id=?"); $stmt->bind_param("i",$id); $stmt->execute(); $msg="Carta eliminada.";
}
// EDIT
$edit=null;
if ($action==='edit' && $id>0) { $edit=get_carta($conn,$id); if($edit) $juego_id=(int)$edit['juego_id']; }
// LIST
$stmt=$conn->prepare("SELECT c.*, gc.nombre AS juego FROM cartas c LEFT JOIN juegos_config gc ON gc.juego_id=c.juego_id WHERE c.juego_id=? ORDER BY c.id DESC");
$stmt->bind_param("i",$juego_id); $stmt->execute();
$items=$stmt->get_result()->fetch_all(MYSQLI_ASSOC);
?>
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>Memoria | Cartas</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">
<div class="d-flex align-items-center justify-content-between">
<h3 class="mb-3">Cartas</h3>
<form class="d-flex" method="get">
<select name="juego_id" class="form-select me-2" onchange="this.form.submit()">
<?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>
<noscript><button class="btn btn-primary">Cambiar</button></noscript>
</form>
</div>
<?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 carta' : 'Nueva carta' ?></h5>
<form method="post" enctype="multipart/form-data" class="row g-3">
<input type="hidden" name="id" value="<?= (int)($edit['id'] ?? 0) ?>">
<input type="hidden" name="old_imagen_frontal" value="<?= htmlspecialchars($edit['imagen_frontal'] ?? '') ?>">
<input type="hidden" name="old_imagen_trasera" value="<?= htmlspecialchars($edit['imagen_trasera'] ?? '') ?>">
<div class="col-md-3">
<label class="form-label">Juego</label>
<select name="juego_id" class="form-select" required>
<?php foreach($juegos as $j): ?>
<option value="<?= (int)$j['juego_id'] ?>" <?= ($juego_id===$j['juego_id'])?'selected':'' ?>><?= htmlspecialchars($j['nombre']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-3">
<label class="form-label">Nombre</label>
<input name="nombre" class="form-control" required value="<?= htmlspecialchars($edit['nombre'] ?? '') ?>">
</div>
<div class="col-md-3">
<label class="form-label">Imagen trasera (obligatoria)</label>
<input type="file" name="imagen_trasera" class="form-control" accept=".png,.jpg,.jpeg,.webp">
<?php if (!empty($edit['imagen_trasera'])): ?><div class="mt-2"><img src="<?= htmlspecialchars($edit['imagen_trasera']) ?>" class="thumb"></div><?php endif; ?>
</div>
<div class="col-md-3">
<label class="form-label">Imagen frontal (opcional)</label>
<input type="file" name="imagen_frontal" class="form-control" accept=".png,.jpg,.jpeg,.webp">
<?php if (!empty($edit['imagen_frontal'])): ?><div class="mt-2"><img src="<?= htmlspecialchars($edit['imagen_frontal']) ?>" class="thumb"></div><?php endif; ?>
</div>
<div class="col-md-2">
<label class="form-label">Activo</label><br>
<input type="checkbox" name="activo" value="1" <?= !empty($edit['activo'])?'checked':'' ?>>
</div>
<div class="col-12">
<button class="btn btn-primary"><?= $edit ? 'Actualizar' : 'Crear' ?></button>
<?php if ($edit): ?><a href="cartas.php?juego_id=<?= (int)$juego_id ?>" 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>ID</th><th>Juego</th><th>Nombre</th><th>Trasera</th><th>Frontal</th><th>Activo</th><th>Acciones</th></tr></thead>
<tbody>
<?php foreach($items as $it): ?>
<tr>
<td><?= (int)$it['id'] ?></td>
<td><?= htmlspecialchars($it['juego'].' ('.$it['juego_id'].')') ?></td>
<td><?= htmlspecialchars($it['nombre']) ?></td>
<td><?= $it['imagen_trasera']?'<img class="thumb" src="'.htmlspecialchars($it['imagen_trasera']).'">':'—' ?></td>
<td><?= $it['imagen_frontal']?'<img class="thumb" src="'.htmlspecialchars($it['imagen_frontal']).'">':'—' ?></td>
<td><?= $it['activo']?'Sí':'No' ?></td>
<td class="text-nowrap">
<a class="btn btn-sm btn-outline-primary" href="cartas.php?action=edit&id=<?= (int)$it['id'] ?>&juego_id=<?= (int)$juego_id ?>">Editar</a>
<a class="btn btn-sm btn-outline-danger" href="cartas.php?action=delete&id=<?= (int)$it['id'] ?>&juego_id=<?= (int)$juego_id ?>" onclick="return confirm('¿Eliminar carta?')">Eliminar</a>
</td>
</tr>
<?php endforeach; ?>
<?php if (!$items): ?><tr><td colspan="7" class="text-center text-muted">Sin cartas</td></tr><?php endif; ?>
</tbody>
</table>
</div></div>
</div>
</body>
</html>