Aggiornato Consegna1

This commit is contained in:
Mr_sl1d3r 2025-10-23 15:19:05 +02:00
parent 0e0b34dcb8
commit 93b44fc4ae
5 changed files with 508 additions and 12 deletions

141
README.md
View File

@ -1 +1,142 @@
# Biblioteca # Biblioteca
INTRODUZIONE
Creazione di unapplicazione di gestione di una biblioteca on line. Gli utenti avranno la possibilità di vedere lelenco dei libri (distinguere tra cartaceo e digitale), prenotarli per un certo periodo pagando il noleggio, restituirli entro il periodo impostato pena aumento del noleggio. La biblioteca contiene libri e documenti di ogni tipo, dallinformazione alla storia dallo sport alla geografia e via dicendo. La biblioteca gestisce anche i film e documentari in formato digitale.
LE PARTI JAVASCRIPT DOVRANNO ESSERE SVILUPPATE IN JQUERY!
UTENTI
Gli utenti devono sempre essere assegnati ad una persona e devono avere dei ruoli/diritti sullapplicazione. Questi vengono assegnati dallutente amministratore (ossia il creatore dellapplicazione). Vediamo i diversi utenti:
Utente Admin: gestisce lintera applicazione. Inserisce lutente bibliotecario.
Utente Bibliotecario: Inserisce, modifica e cancella i libri allinterno della biblioteca. Gestisce le consegne e le restituzioni dei libri. Gestisce le penali in caso di mancata consegna. Questo utente non può effettuare prenotazioni. Altre eventuali …
Utente generico: si registra allapplicazione con la propria mail. Inserisce, modifica e cancella le proprie prenotazioni. Effettua il pagamento on line del noleggio. Inserisce una recensione sul libro/film noleggiato che sarà visibile agli altri utenti quando lo consulteranno.
Lutente potrà effettuare la prenotazione solo dopo lavvenuta registrazione.
Lutente non registrato può solo visualizzare le entità contenute allinterno dellapplicazione.
Altri eventuali …
PRENOTAZIONI
Le prenotazioni hanno un loro codice e si gestiscono attraverso i seguenti stati:
Prenotazione In attesa
Prenotazione Pagata
Prenotazione Consegnata
Prenotazione Restituita
Restituzione Verificata
Il Codice della prenotazione sarà una stringa composta da utente + il periodo di prenotazione(formato aaaammgg) + il codice del libro/film. Esempio:
UTENTE@MAIL.COM2025010120250131L001
si effettuano con i seguenti dati:
Utente + Persona
Selezione del libro/film
Scelta del periodo di noleggio con data inizio e data fine (gli orari si intendono come 00.00 per la data di inizio e 23.59 per la data di fine).
Una volta salvato il periodo il libro/film scelto non sarà disponibile agli altri utenti nel periodo selezionato (si deve pertanto gestire lerrore in caso di prenotazione “accavallata” da parte di un altro utente).
Lutente può prenotare e noleggiare al massimo 5 libri. Raggiunto questo numero non può prenotarne altri se non effettua almeno una restituzione.
Lutente bibliotecario effettuerà lavvenuta consegna del libro/film noleggiato allutente e di conseguenza la verifica dellavvenuta restituzione
Lutente bibliotecario gestisce il pagamento che deve essere effettuato prima della consegna allutente (di conseguenza non è possibile fare la consegna se il noleggio non ha lo stato “pagato”).
La cancellazione della prenotazione deve avvenire prima della consegna e annulla il pagamento.
La consegna del noleggio da parte dellutente obbliga questo ad inserire una recensione che sarà visibile agli altri utenti
altre eventuali …
LIBRI, FILM e DOCUMENTARI
Si deve gestire l elenco delle entità noleggiabili con i seguenti dati:
Immagine della copertina o locandina
Codice dellentità
Tipo (libro, film, documentario, .. )
Titolo
Autore o Regista
Breve descrizione
Costo del noleggio (le entità inserite dal bibliotecario nellanno corrente costeranno piu di quelle degli anni passati).
Argomento di appartenenza (sport, storia, cultura generale, geografia, scienze …. )
Data di inserimento allinterno dellapplicazione
Questi dati saranno selezionati dallutente bibliotecario quando inserirà il libro/film allinterno dellapplicazione.
Lutente avrà a disposizione questi dati quando effettuerà la ricerca dellentità che interessa oltre alla possibilità di visualizzarne le recensioni.
LE RECENSIONI
Può essere inserita una sola recensione per utente e libro/film.
La recensione viene inserita nella funzionalità di restituzione ed è facoltativa (lutente può decidere di non inserire nessuna recensione). Lutente che scrive la recensione può effettuarne la cancellazione FISICA dalla base dati.
Gli altri utenti possono mettere sulla recensione un “OK” o “KO” a seconda se in accordo o meno su quanto cè scritto sulla recensione. OK e KO devono essere rappresentati da unicona/emoji a piacere.
Il bibliotecario e solo lui può decidere di cancellare la recensione (cambiando lo stato da inserita a cancellata) se non la ritiene opportuna. In questo caso al posto della recensione comparirà un messaggio “Recensione Cancellata da Amministrazione”.
Lentità recensione contiene i seguenti campi:
utente
data
descrizione
stato (inserita, cancellata)
id del libro/film a cui è riferita
MENU di NAVIGAZIONE
Ogni tipologia di utente ha il suo menù di navigazione per accedere alle maschere che deve utilizzare.
ADMIN: vede tutta lapplicazione e può fare qualsiasi cosa.
BIBLIOTECARIO:
ELENCO LIBRI con funzionalità di inserimento modifica e cancellazione
ELENCO FILM (idem sopra)
ELENCO DOCUMENTARI (idem sopra)
ELENCO PRENOTAZIONI con relativa gestione descritta sopra
ELENCO UTENTI REGISTRATI con possibilità di vedere le relative prenotazioni e pagamenti
altre eventuali …
UTENTE SEMPLICE:
ELENCO LIBRI con selezione per la prenotazione
ELENCO PROPRIE PRENOTAZIONI con possibilità di modificare/cancellare
altre eventuali …
PAGAMENTI
Lutente può scegliere attraverso unopzione dellapplicazione se pagare in contanti, con bonifico o con carta di credito. Serve quindi un'entità PAGAMENTI per la loro selezione con i seguenti campi:
ID_PAGAMENTO
TIPO
DESCRIZIONE
Quando lutente conferma la prenotazione avrà la possibilità di selezionare il tipo di pagamento dallentità impostata.
7.1 PAGAMENTO CON CARTA DI CREDITO
Questo tipo di pagamento è alquanto diffuso per gli acquisti online. Creare quindi una maschera che contenga i seguenti campi (ovviamente da salvare su DB):
Nome e Cognome dellintestatario della carta
Numero della carta
Mese/Anno scadenza della carta
Codice di sicurezza del retro della carta
I dati inseriti dallutente vanno salvati nella tabella relativa al primo inserimento. I successivi salvataggi dovranno confrontare i dati inseriti negli appositi campi con il dato salvato nella base dati. Il dato salvato non deve essere duplicato ma rimane dato univoco di confronto con i successivi inserimenti. Esempio:
Al primo acquisto lutente inserisce i dati di cui sopra che vengono salvati.
Al secondo acquisto lutente inserisce nuovamente i dati di cui sopra ma al salvataggio lapplicazione confronterà questi con quelli salvati al punto 1.
In caso di corrispondenza fallita si deve restituire un messaggio di errore. Altrimenti si procede con la conclusione del noleggio.
Facoltativo: Quando lutente salva i dati al punto 1. deve utilizzare un PIN di 4 cifre. Nei tentativi successivi prima di salvare il noleggio con carta di credito si deve proporre la maschera per il controllo del PIN. Ovviamente lapplicazione dovrà verificare che il PIN inserito le volte successive corrisponda con quello salvato al primo acquisto.
BREVE DESCRIZIONE DEL PROCESSO
Lutente semplice quando accede allapplicazione ha la possibilità di navigare allinterno di questa anche se non è registrato. In questo caso pero non potrà effettuare la prenotazione.
Invece una volta registrato potrà visualizzare ed effettuare le sue prenotazioni con il controllo che non siano piu di 5 in totale. Se prova ad effettuare una prenotazione in un periodo in cui non cè disponibilità lapplicazione deve restituire un messaggio di errore.
Lutente per la prenotazione vedrà inizialmente lelenco di tutti i libri/film presenti allinterno della base dati con possibilità di filtrare la ricerca per tipo, titolo, autore.
lelenco visualizzerà in ordine copertina, titolo, descrizione, costo del noleggio, link alla maschera della prenotazione e link alla maschera delle recensioni.
La maschera della prenotazione deve permettere di inserire i dati di cui al paragrafo 3 e 7.
Bibliotecario ha accesso allelenco delle entità dellapplicazione. può decidere di inserire nuove entità, modificarle o di cancellarle. Nel caso unentità abbia dei noleggi abbinati non sarà cancellata fisicamente ma solo logicamente (cambio stato). Lentità cancellata non sarà visibile allutente semplice ma solo al bibliotecario e amministratore.
Avendo accesso alle prenotazioni può cambiarne lo stato come descritto al paragrafo 3.
Inoltre può cancellare le recensioni che ritiene non adeguate.
Non può inserire prenotazioni come bibliotecario.
Amministratore accede a tutto quanto, può modificare cancellare o inserire. Accede alla pagina degli utenti che può eventualmente cancellare se non hanno effettuato alcun noleggio. Gestisce inserimento, modifica e cancellazione dellutente bibliotecario. Ovviamente lutente bibliotecario può essere piu di uno.

138
index.php
View File

@ -1,12 +1,134 @@
<?php
session_start();
$roleName = isset($_SESSION['role_name']) ? $_SESSION['role_name'] : null;
$isLogged = isset($_SESSION['user_id']);
$username = isset($_SESSION['username']) ? $_SESSION['username'] : null;
?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="it"> <html lang="it">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Biblioteca | Home</title>
<title>Biblioteca | I5AI6</title> <script src="https://cdn.tailwindcss.com"></script>
</head> <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<body> </head>
<body class="bg-[#f8fafc] text-[#545454]">
<nav class="w-full bg-[#545454] text-white shadow">
<div class="max-w-7xl mx-auto px-4">
<div class="flex justify-between items-center h-16">
<div class="flex items-center gap-6">
<a href="/BibliotecaOnline/index.php" class="font-semibold text-lg">Biblioteca Online</a>
<div class="hidden md:flex items-center gap-4">
<a href="#" class="hover:text-[#cbff4d]">Catalogo</a>
<a href="#" class="hover:text-[#cbff4d]">Recensioni</a>
</div>
</div>
<!-- Menu basato sul ruolo -->
<div class="hidden md:flex items-center gap-4">
<?php if ($isLogged && $roleName === 'admin'): ?>
<a href="#" class="hover:text-[#cbff4d]">Gestione Utenti</a>
<a href="#" class="hover:text-[#cbff4d]">Ruoli & Permessi</a>
<a href="#" class="hover:text-[#cbff4d]">Gestione Bibliotecari</a>
<?php elseif ($isLogged && $roleName === 'bibliotecario'): ?>
<a href="#" class="hover:text-[#cbff4d]">Elenco Libri</a>
<a href="#" class="hover:text-[#cbff4d]">Elenco Film</a>
<a href="#" class="hover:text-[#cbff4d]">Elenco Documentari</a>
<a href="#" class="hover:text-[#cbff4d]">Prenotazioni</a>
<a href="#" class="hover:text-[#cbff4d]">Utenti Registrati</a>
<?php elseif ($isLogged && $roleName === 'utente'): ?>
<a href="#" class="hover:text-[#cbff4d]">Prenota</a>
<a href="#" class="hover:text-[#cbff4d]">Le mie Prenotazioni</a>
<?php endif; ?>
</div>
<div class="flex items-center gap-3">
<?php if ($isLogged): ?>
<span class="hidden md:inline text-sm">Ciao, <?php echo htmlspecialchars($username); ?></span>
<a href="/BibliotecaOnline/php/auth/logout.php" class="px-4 py-2 bg-[#84dd63] text-[#1f2937] rounded hover:bg-[#cbff4d]">Logout</a>
<?php else: ?>
<button id="openLogin" class="px-4 py-2 bg-[#84dd63] text-[#1f2937] rounded hover:bg-[#cbff4d]">Login</button>
<button class="px-4 py-2 bg-[#69747c] text-white rounded opacity-80 cursor-not-allowed">Registrati (presto)</button>
<?php endif; ?>
</div>
</div>
</div>
</nav>
</body> <!-- Hero/Intro -->
<section class="max-w-7xl mx-auto px-4 py-10">
<div class="grid md:grid-cols-2 gap-8 items-center">
<div>
<h1 class="text-3xl md:text-4xl font-bold text-[#6baa75]">Benvenuto nella Biblioteca Online</h1>
<p class="mt-3 text-[#69747c]">Esplora libri, film e documentari. Prenota facilmente e gestisci le tue recensioni. In base al tuo ruolo vedrai azioni diverse.</p>
<div class="mt-6 flex gap-3">
<a href="#" class="px-5 py-2 bg-[#6baa75] text-white rounded hover:bg-[#84dd63]">Sfoglia Catalogo</a>
<?php if (!$isLogged): ?>
<button id="openLogin2" class="px-5 py-2 bg-[#545454] text-white rounded hover:bg-[#69747c]">Accedi</button>
<?php endif; ?>
</div>
</div>
<div class="bg-white rounded-lg shadow p-6 border border-[#e5e7eb]">
<h2 class="text-xl font-semibold text-[#545454]">Cosa puoi fare</h2>
<ul class="mt-3 space-y-2 text-[#69747c] list-disc list-inside">
<li>Utente: prenotare e gestire le tue prenotazioni</li>
<li>Bibliotecario: gestire catalogo, prenotazioni e recensioni</li>
<li>Admin: gestire utenti, ruoli e permessi</li>
</ul>
</div>
</div>
</section>
<!-- Modal Login -->
<div id="loginModal" class="fixed inset-0 bg-black/40 hidden items-center justify-center">
<div class="bg-white w-full max-w-md rounded-lg shadow-lg p-6">
<div class="flex justify-between items-center mb-4">
<h3 class="text-lg font-semibold text-[#545454]">Accedi</h3>
<button id="closeLogin" class="text-[#69747c] hover:text-[#545454]"></button>
</div>
<form id="loginForm" class="space-y-4">
<div>
<label class="block text-sm text-[#69747c]">Email/Username</label>
<input type="text" name="username" required class="mt-1 w-full border rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-[#84dd63]" placeholder="es. utente@mail.com">
</div>
<div>
<label class="block text-sm text-[#69747c]">Password</label>
<input type="password" name="password" required class="mt-1 w-full border rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-[#84dd63]" placeholder="••••••••">
</div>
<div id="loginError" class="hidden text-red-600 text-sm"></div>
<button type="submit" class="w-full bg-[#6baa75] text-white rounded py-2 hover:bg-[#84dd63]">Login</button>
</form>
</div>
</div>
<script>
$(function() {
const $modal = $('#loginModal');
$('#openLogin, #openLogin2').on('click', function() { $modal.removeClass('hidden').addClass('flex'); });
$('#closeLogin').on('click', function() { $modal.addClass('hidden').removeClass('flex'); $('#loginError').addClass('hidden').text(''); });
$(document).on('keydown', function(e){ if(e.key === 'Escape'){ $('#closeLogin').click(); } });
$('#loginForm').on('submit', function(e) {
e.preventDefault();
const formData = $(this).serialize();
$.ajax({
url: '/BibliotecaOnline/php/auth/login.php',
method: 'POST',
data: formData,
headers: { 'X-Requested-With': 'XMLHttpRequest' },
success: function(resp) {
try { resp = typeof resp === 'string' ? JSON.parse(resp) : resp; } catch (_) {}
if (resp && resp.status === 'ok') {
location.reload();
} else {
$('#loginError').removeClass('hidden').text(resp && resp.message ? resp.message : 'Accesso non riuscito.');
}
},
error: function() {
$('#loginError').removeClass('hidden').text('Errore di rete. Riprovare.');
}
});
});
});
</script>
</body>
</html> </html>

View File

@ -1,8 +1,69 @@
<?php <?php
require_once "../db/connect.php"; require_once "../db/connect.php";
session_start(); session_start();
$username = $_POST['username']; // Input
$password = $_POST['password']; $username = isset($_POST['username']) ? trim($_POST['username']) : '';
$password = isset($_POST['password']) ? trim($_POST['password']) : '';
$isAjax = isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest';
header('Content-Type: application/json');
if ($username === '' || $password === '') {
$resp = ['status' => 'error', 'message' => 'Inserire username e password'];
echo json_encode($resp);
exit;
}
// Autenticazione: descrizione = username/email, password = plain text
// Recupera anche l'ultimo ruolo assegnato (permission) se presente
$sql = "SELECT u.user_id, u.descrizione, r.id AS role_id, r.name AS role_name
FROM `user` u
LEFT JOIN `permission` p ON p.user_id = u.user_id
LEFT JOIN `role` r ON r.id = p.role
WHERE u.descrizione = ? AND u.password = ?
ORDER BY p.data DESC LIMIT 1";
if ($stmt = mysqli_prepare($conn, $sql)) {
mysqli_stmt_bind_param($stmt, 'ss', $username, $password);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
if ($result && mysqli_num_rows($result) > 0) {
$row = mysqli_fetch_assoc($result);
$roleId = $row['role_id'] ?? null;
$roleName = $row['role_name'] ?? null;
// Se non c'è permission, default a utente
if (!$roleId || !$roleName) {
$roleId = 3; // utente
$roleName = 'utente';
}
$_SESSION['user_id'] = (int)$row['user_id'];
$_SESSION['username'] = $row['descrizione'];
$_SESSION['role_id'] = (int)$roleId;
$_SESSION['role_name'] = $roleName;
$resp = ['status' => 'ok', 'role' => $roleName];
echo json_encode($resp);
} else {
$resp = ['status' => 'error', 'message' => 'Credenziali non valide'];
echo json_encode($resp);
}
mysqli_stmt_close($stmt);
} else {
$resp = ['status' => 'error', 'message' => 'Errore interno'];
echo json_encode($resp);
}
// Per richieste non AJAX, effettua redirect (compatibilità)
if (!$isAjax) {
if (isset($_SESSION['user_id'])) {
header('Location: ../../index.php');
} else {
header('Location: ../../index.php?login=failed');
}
}

6
php/auth/logout.php Normal file
View File

@ -0,0 +1,6 @@
<?php
session_start();
session_unset();
session_destroy();
header('Location: ../../index.php');
exit;

166
php/db/biblioteca.sql Normal file
View File

@ -0,0 +1,166 @@
-- phpMyAdmin SQL Dump
-- version 5.0.4deb2+deb11u2
-- https://www.phpmyadmin.net/
--
-- Host: 192.168.1.38:3306
-- Creato il: Ott 22, 2025 alle 16:59
-- Versione del server: 11.8.2-MariaDB-ubu2404
-- Versione PHP: 7.4.33
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `biblioteca`
--
-- --------------------------------------------------------
--
-- Struttura della tabella `permission`
--
CREATE TABLE `permission` (
`id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`role` int(11) NOT NULL,
`data` date NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci;
-- --------------------------------------------------------
--
-- Struttura della tabella `person`
--
CREATE TABLE `person` (
`id_persona` int(11) NOT NULL,
`nome` text NOT NULL,
`cognome` text NOT NULL,
`data_nascita` date NOT NULL,
`luogo_nascita` text NOT NULL,
`cod_fiscale` varchar(16) NOT NULL,
`telefono` varchar(10) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci;
-- --------------------------------------------------------
--
-- Struttura della tabella `role`
--
CREATE TABLE `role` (
`id` int(11) NOT NULL,
`name` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci;
--
-- Dump dei dati per la tabella `role`
--
INSERT INTO `role` (`id`, `name`) VALUES
(1, 'admin'),
(2, 'bibliotecario'),
(3, 'utente');
-- --------------------------------------------------------
--
-- Struttura della tabella `user`
--
CREATE TABLE `user` (
`user_id` int(11) NOT NULL,
`descrizione` text NOT NULL,
`data` date DEFAULT NULL,
`person_id` int(11) NOT NULL,
`password` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci;
--
-- Indici per le tabelle scaricate
--
--
-- Indici per le tabelle `permission`
--
ALTER TABLE `permission`
ADD PRIMARY KEY (`id`),
ADD KEY `user_id` (`user_id`),
ADD KEY `role` (`role`);
--
-- Indici per le tabelle `person`
--
ALTER TABLE `person`
ADD PRIMARY KEY (`id_persona`);
--
-- Indici per le tabelle `role`
--
ALTER TABLE `role`
ADD PRIMARY KEY (`id`);
--
-- Indici per le tabelle `user`
--
ALTER TABLE `user`
ADD PRIMARY KEY (`user_id`),
ADD KEY `person_id` (`person_id`);
--
-- AUTO_INCREMENT per le tabelle scaricate
--
--
-- AUTO_INCREMENT per la tabella `permission`
--
ALTER TABLE `permission`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT per la tabella `person`
--
ALTER TABLE `person`
MODIFY `id_persona` int(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT per la tabella `role`
--
ALTER TABLE `role`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
--
-- AUTO_INCREMENT per la tabella `user`
--
ALTER TABLE `user`
MODIFY `user_id` int(11) NOT NULL AUTO_INCREMENT;
--
-- Limiti per le tabelle scaricate
--
--
-- Limiti per la tabella `permission`
--
ALTER TABLE `permission`
ADD CONSTRAINT `permission_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`),
ADD CONSTRAINT `permission_ibfk_2` FOREIGN KEY (`role`) REFERENCES `role` (`id`);
--
-- Limiti per la tabella `user`
--
ALTER TABLE `user`
ADD CONSTRAINT `user_ibfk_1` FOREIGN KEY (`person_id`) REFERENCES `person` (`id_persona`) ON DELETE NO ACTION ON UPDATE NO ACTION;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;