34464-vm/index.php
2025-09-29 00:35:53 +00:00

235 lines
11 KiB
PHP

<?php
session_start();
require_once 'db/config.php';
// --- DATABASE SETUP ---
function setup_database() {
try {
$pdo = db();
$pdo->exec("CREATE TABLE IF NOT EXISTS puzzles (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) DEFAULT 'Senza Nome',
file_name VARCHAR(255) NOT NULL UNIQUE,
is_public BOOLEAN DEFAULT FALSE,
is_admin_upload BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)");
// Attempt to add 'name' column, ignore error if it already exists
try {
$pdo->exec("ALTER TABLE puzzles ADD COLUMN name VARCHAR(255) DEFAULT 'Senza Nome'");
} catch (PDOException $e) {
// Ignore error, likely "Duplicate column name"
}
} catch (PDOException $e) {
// In a real app, log this error instead of displaying it
die("Errore di connessione al database: " . $e->getMessage());
}
}
setup_database();
// --- GLOBAL VARIABLES ---
$uploaded_image = null;
$error_message = null;
$gallery_images = [];
// --- DATA FETCHING ---
try {
$pdo = db();
// Fetch puzzles
$stmt = $pdo->query("SELECT id, file_name, name FROM puzzles WHERE is_public = 1 OR is_admin_upload = 1 ORDER BY created_at DESC");
$gallery_images = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Fetch leaderboard
$leaderboard_stmt = $pdo->query("
SELECT u.username, s.score
FROM scores s
JOIN users u ON s.user_id = u.id
ORDER BY s.score DESC
LIMIT 10
");
$leaderboard_scores = $leaderboard_stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$error_message = "Impossibile caricare i dati della pagina.";
// Optionally log the error: error_log($e->getMessage());
}
// --- POST REQUEST: IMAGE UPLOAD ---
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['puzzle_image'])) {
$target_dir = 'uploads/';
$max_file_size = 5 * 1024 * 1024; // 5 MB
$allowed_types = ['image/jpeg', 'image/png', 'image/gif'];
$file = $_FILES['puzzle_image'];
if ($file['error'] !== UPLOAD_ERR_OK) {
$error_message = 'Si è verificato un errore durante il caricamento.';
} else {
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime_type = $finfo->file($file['tmp_name']);
if ($file['size'] > $max_file_size) {
$error_message = 'Il file è troppo grande. La dimensione massima è 5MB.';
} elseif (!in_array($mime_type, $allowed_types)) {
$error_message = 'Tipo di file non valido. Sono ammessi solo JPG, PNG, GIF.';
} else {
$file_extension = pathinfo($file['name'], PATHINFO_EXTENSION);
$safe_filename = uniqid('puzzle_', true) . '.' . strtolower($file_extension);
$target_file = $target_dir . $safe_filename;
if (move_uploaded_file($file['tmp_name'], $target_file)) {
// Save to database
try {
$is_public = isset($_POST['share_puzzle']) ? 1 : 0; // Ensure 1 or 0
$puzzle_name = !empty($_POST['puzzle_name']) ? trim($_POST['puzzle_name']) : 'Senza Nome';
$pdo = db();
$stmt = $pdo->prepare("INSERT INTO puzzles (name, file_name, is_public, is_admin_upload) VALUES (?, ?, ?, ?)");
$is_admin_upload = 0; // Always false for user uploads
$stmt->execute([$puzzle_name, $safe_filename, $is_public, $is_admin_upload]);
$new_puzzle_id = $pdo->lastInsertId();
} catch (PDOException $e) {
// Error saving to DB, delete file
unlink($target_file);
// Log the detailed error for developers: error_log($e->getMessage());
$error_message = "Si è verificato un errore nel salvataggio dei dati del puzzle: " . $e->getMessage();
}
if (!$error_message) {
// Redirect to the new puzzle page
header('Location: puzzle.php?id=' . $new_puzzle_id);
exit;
}
} else {
$error_message = 'Si è verificato un errore durante il salvataggio del file.';
}
}
}
}
// --- GET REQUESTS ---
// Handle New Game
if (isset($_GET['action']) && $_GET['action'] === 'new') {
unset($_SESSION['selected_puzzle']);
header('Location: ' . $_SERVER['PHP_SELF']);
exit;
}
// --- SET CURRENT IMAGE FOR DISPLAY ---
if (isset($_SESSION['selected_puzzle'])) {
$uploaded_image = $_SESSION['selected_puzzle'];
}
?>
<?php
$page_title = 'Photo Puzzle - Gioca e Crea';
$page_description = 'Crea e risolvi puzzle fotografici direttamente nel tuo browser. Scegli dalla nostra galleria o carica la tua immagine.';
require_once 'includes/header.php';
?>
<!-- Main Content -->
<main class="flex-grow-1">
<div class="main-content">
<div class="row">
<!-- Main content (Puzzles) -->
<div class="col-lg-8">
<!-- Gallery Section -->
<section class="hero-section text-center" aria-labelledby="gallery-heading">
<h1 id="gallery-heading">Scegli un Puzzle dalla Galleria</h1>
<p class="text-secondary fs-5">Oppure crea il tuo e sfida la community.</p>
</section>
<section class="puzzle-gallery mb-5" aria-label="Galleria dei Puzzle">
<?php if (!empty($gallery_images)): ?>
<div class="row row-cols-1 row-cols-sm-2 row-cols-xl-3 puzzle-grid">
<?php foreach ($gallery_images as $img): ?>
<div class="col">
<a href="puzzle.php?id=<?php echo $img['id']; ?>" class="text-decoration-none">
<div class="puzzle-card h-100">
<img src="uploads/<?php echo htmlspecialchars($img['file_name']); ?>" class="card-img-top" alt="<?php echo htmlspecialchars($img['name']); ?>" style="height: 200px; object-fit: cover;">
<div class="card-body">
<h5 class="card-title"><?php echo htmlspecialchars($img['name']); ?></h5>
</div>
</div>
</a>
</div>
<?php endforeach; ?>
</div>
<?php else: ?>
<div class="text-center p-5 rounded" style="background: var(--bg-secondary);">
<p class="text-secondary">Nessun puzzle disponibile al momento. Caricane uno tu!</p>
</div>
<?php endif; ?>
</section>
<?php if (isset($_SESSION['user_id'])): ?>
<!-- Upload Section for Logged-in Users -->
<section class="p-4 rounded" style="background: var(--bg-secondary);" aria-labelledby="upload-heading">
<h2 id="upload-heading">Crea un nuovo Puzzle</h2>
<p class="text-secondary mb-4">Carica un'immagine per iniziare una nuova sfida.</p>
<?php if ($error_message): ?>
<div class="alert alert-danger"><?php echo htmlspecialchars($error_message); ?></div>
<?php endif; ?>
<form action="index.php" method="post" enctype="multipart/form-data">
<div class="row g-3">
<div class="col-md-6">
<label for="puzzle_name" class="form-label">Nome del Puzzle</label>
<input type="text" class="form-control" id="puzzle_name" name="puzzle_name" placeholder="Es: Tramonto a Venezia" required>
</div>
<div class="col-md-6">
<label for="puzzle_image_upload" class="form-label">Seleziona immagine (max 5MB)</label>
<input class="form-control" type="file" name="puzzle_image" id="puzzle_image_upload" accept="image/jpeg,image/png,image/gif" required>
</div>
</div>
<div class="form-check form-switch my-3">
<input class="form-check-input" type="checkbox" role="switch" id="share_puzzle" name="share_puzzle" value="1" checked>
<label class="form-check-label" for="share_puzzle">Condividi nella galleria pubblica</label>
</div>
<div class="text-start">
<button type="submit" class="btn btn-primary">Crea e Gioca</button>
</div>
</form>
</section>
<?php endif; ?>
</div>
<!-- Leaderboard Sidebar -->
<div class="col-lg-4">
<aside class="leaderboard-sidebar">
<h2 class="leaderboard-title">Top 10 Giocatori</h2>
<p class="leaderboard-subtitle mb-3">La classifica dei maestri del puzzle.</p>
<?php if (!empty($leaderboard_scores)): ?>
<table class="table table-borderless">
<thead>
<tr>
<th>#</th>
<th>Utente</th>
<th>Punteggio</th>
</tr>
</thead>
<tbody>
<?php foreach ($leaderboard_scores as $index => $score): ?>
<tr>
<td><?php echo $index + 1; ?></td>
<td><?php echo htmlspecialchars($score['username']); ?></td>
<td><?php echo htmlspecialchars($score['score']); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<p class="text-secondary">Nessun punteggio ancora. Inizia a giocare!</p>
<?php endif; ?>
<div class="text-center mt-3">
<a href="leaderboard.php" class="btn btn-outline-cyan">Vedi Classifica Completa</a>
</div>
</aside>
</div>
</div>
</div>
</main>
<?php require_once 'includes/footer.php'; ?>