187 lines
9.2 KiB
PHP
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>
|