2025-11-20 17:00:37 +00:00
< ? php
session_start ();
require_once __DIR__ . '/../db/connect.php' ;
// Access control: solo admin
if ( ! isset ( $_SESSION [ 'role_name' ]) || $_SESSION [ 'role_name' ] !== 'admin' ) {
header ( 'Location: ../../index.php' );
exit ;
}
2025-12-04 17:16:40 +00:00
// Messaggi
$msg = null ; $error = null ;
// Gestione azioni CRUD
if ( $_SERVER [ 'REQUEST_METHOD' ] === 'POST' ) {
$azione = $_POST [ 'azione' ] ? ? '' ;
if ( $azione === 'create_user' ) {
$nome = trim ( $_POST [ 'nome' ] ? ? '' );
$cognome = trim ( $_POST [ 'cognome' ] ? ? '' );
$data_nascita = trim ( $_POST [ 'data_nascita' ] ? ? '' );
$luogo_nascita = trim ( $_POST [ 'luogo_nascita' ] ? ? '' );
$cod_fiscale = strtoupper ( trim ( $_POST [ 'cod_fiscale' ] ? ? '' ));
$telefono = preg_replace ( '/\D+/' , '' , $_POST [ 'telefono' ] ? ? '' );
$username = trim ( $_POST [ 'username' ] ? ? '' );
$password = trim ( $_POST [ 'password' ] ? ? '' );
2025-12-05 08:07:35 +00:00
$role_id = 3 ;
2025-12-04 17:16:40 +00:00
$errors = [];
if ( $nome === '' || $cognome === '' || $luogo_nascita === '' ) $errors [] = 'Campi anagrafici obbligatori' ;
if ( $data_nascita === '' || ! preg_match ( '/^\d{4}-\d{2}-\d{2}$/' , $data_nascita )) $errors [] = 'Data nascita non valida' ;
if ( $cod_fiscale === '' || strlen ( $cod_fiscale ) !== 16 ) $errors [] = 'Codice Fiscale non valido' ;
if ( $telefono === '' || ! preg_match ( '/^\d{6,10}$/' , $telefono )) $errors [] = 'Telefono non valido' ;
if ( $username === '' || strlen ( $username ) < 3 ) $errors [] = 'Username troppo corto' ;
if ( $password === '' || preg_match ( '/\s/' , $password ) || strlen ( $password ) < 8 || ! preg_match ( '/[a-z]/' , $password ) || ! preg_match ( '/[A-Z]/' , $password ) || ! preg_match ( '/[^a-zA-Z0-9]/' , $password )) {
$errors [] = 'Password non conforme ai requisiti' ;
}
2025-12-05 08:07:35 +00:00
2025-12-04 17:16:40 +00:00
$username_e = mysqli_real_escape_string ( $conn , $username );
$check = mysqli_query ( $conn , " SELECT user_id FROM `user` WHERE descrizione = ' $username_e ' LIMIT 1 " );
if ( $check && mysqli_num_rows ( $check ) > 0 ) $errors [] = 'Username già esistente' ;
if ( ! empty ( $errors )) {
$error = implode ( ' | ' , $errors );
} else {
$nome_e = mysqli_real_escape_string ( $conn , $nome );
$cognome_e = mysqli_real_escape_string ( $conn , $cognome );
$data_nascita_e = mysqli_real_escape_string ( $conn , $data_nascita );
$luogo_nascita_e = mysqli_real_escape_string ( $conn , $luogo_nascita );
$cod_fiscale_e = mysqli_real_escape_string ( $conn , $cod_fiscale );
$telefono_e = mysqli_real_escape_string ( $conn , $telefono );
$password_e = mysqli_real_escape_string ( $conn , $password );
$oggi = date ( 'Y-m-d' );
$sql_person = " INSERT INTO `person` (nome, cognome, data_nascita, luogo_nascita, cod_fiscale, telefono) VALUES (' $nome_e ', ' $cognome_e ', ' $data_nascita_e ', ' $luogo_nascita_e ', ' $cod_fiscale_e ', ' $telefono_e ') " ;
if ( ! mysqli_query ( $conn , $sql_person )) { $error = 'Errore inserimento persona' ; }
else {
$person_id = mysqli_insert_id ( $conn );
$sql_user = " INSERT INTO `user` (descrizione, data, person_id, password) VALUES (' $username_e ', ' $oggi ', $person_id , ' $password_e ') " ;
if ( ! mysqli_query ( $conn , $sql_user )) { $error = 'Errore inserimento utente' ; }
else {
$user_id = mysqli_insert_id ( $conn );
$sql_perm = " INSERT INTO `permission` (user_id, role, data) VALUES ( $user_id , $role_id , ' $oggi ') " ;
if ( ! mysqli_query ( $conn , $sql_perm )) { $error = 'Errore assegnazione ruolo' ; }
else { $msg = 'Utente creato correttamente' ; }
}
}
}
} elseif ( $azione === 'update_user' ) {
$user_id = ( int )( $_POST [ 'user_id' ] ? ? 0 );
$username = trim ( $_POST [ 'username' ] ? ? '' );
$password = trim ( $_POST [ 'password' ] ? ? '' ); // opzionale
$nome = trim ( $_POST [ 'nome' ] ? ? '' );
$cognome = trim ( $_POST [ 'cognome' ] ? ? '' );
$data_nascita = trim ( $_POST [ 'data_nascita' ] ? ? '' );
$luogo_nascita = trim ( $_POST [ 'luogo_nascita' ] ? ? '' );
$cod_fiscale = strtoupper ( trim ( $_POST [ 'cod_fiscale' ] ? ? '' ));
$telefono = preg_replace ( '/\D+/' , '' , $_POST [ 'telefono' ] ? ? '' );
if ( $user_id <= 0 ) { $error = 'ID utente non valido' ; }
else {
$username_e = mysqli_real_escape_string ( $conn , $username );
$nome_e = mysqli_real_escape_string ( $conn , $nome );
$cognome_e = mysqli_real_escape_string ( $conn , $cognome );
$data_nascita_e = mysqli_real_escape_string ( $conn , $data_nascita );
$luogo_nascita_e = mysqli_real_escape_string ( $conn , $luogo_nascita );
$cod_fiscale_e = mysqli_real_escape_string ( $conn , $cod_fiscale );
$telefono_e = mysqli_real_escape_string ( $conn , $telefono );
// Trova person_id
$res = mysqli_query ( $conn , " SELECT person_id FROM `user` WHERE user_id = $user_id " );
if ( $res && mysqli_num_rows ( $res ) === 1 ) {
$pi = ( int ) mysqli_fetch_assoc ( $res )[ 'person_id' ];
// Update person
$ok1 = mysqli_query ( $conn , " UPDATE `person` SET nome=' $nome_e ', cognome=' $cognome_e ', data_nascita=' $data_nascita_e ', luogo_nascita=' $luogo_nascita_e ', cod_fiscale=' $cod_fiscale_e ', telefono=' $telefono_e ' WHERE id_persona= $pi " );
// Update username
$ok2 = mysqli_query ( $conn , " UPDATE `user` SET descrizione=' $username_e ' WHERE user_id= $user_id " );
// Update password se valorizzata e conforme
$ok3 = true ;
if ( $password !== '' ) {
if ( preg_match ( '/\s/' , $password ) || strlen ( $password ) < 8 || ! preg_match ( '/[a-z]/' , $password ) || ! preg_match ( '/[A-Z]/' , $password ) || ! preg_match ( '/[^a-zA-Z0-9]/' , $password )) {
$ok3 = false ; $error = 'Password non conforme ai requisiti' ;
} else {
$password_e = mysqli_real_escape_string ( $conn , $password );
$ok3 = mysqli_query ( $conn , " UPDATE `user` SET password=' $password_e ' WHERE user_id= $user_id " );
}
}
if ( $ok1 && $ok2 && $ok3 ) { $msg = 'Utente aggiornato' ; }
else if ( ! $error ) { $error = 'Errore aggiornamento utente' ; }
} else { $error = 'Utente non trovato' ; }
}
} elseif ( $azione === 'delete_user' ) {
$user_id = ( int )( $_POST [ 'user_id' ] ? ? 0 );
if ( $user_id <= 0 ) { $error = 'ID utente non valido' ; }
else {
// Rimuove permission, poi utente e infine person
$res = mysqli_query ( $conn , " SELECT person_id FROM `user` WHERE user_id = $user_id " );
if ( $res && mysqli_num_rows ( $res ) === 1 ) {
$pi = ( int ) mysqli_fetch_assoc ( $res )[ 'person_id' ];
mysqli_query ( $conn , " DELETE FROM `permission` WHERE user_id = $user_id " );
$okU = mysqli_query ( $conn , " DELETE FROM `user` WHERE user_id = $user_id " );
$okP = false ;
if ( $okU ) { $okP = mysqli_query ( $conn , " DELETE FROM `person` WHERE id_persona = $pi " ); }
if ( $okU && $okP ) { $msg = 'Utente eliminato' ; }
else { $error = 'Errore eliminazione utente' ; }
} else { $error = 'Utente non trovato' ; }
}
}
}
2025-12-05 08:07:35 +00:00
// Query utenti con persona e ruolo corrente (ultimo per data, ruolo più alto in parità)
2025-11-20 17:00:37 +00:00
$sql = " SELECT u.user_id, u.descrizione AS username, u.data AS registrato_il,
p . nome , p . cognome , p . cod_fiscale , p . telefono ,
2025-12-05 08:07:35 +00:00
COALESCE ((
SELECT r . name
FROM `permission` pm
JOIN `role` r ON r . id = pm . role
WHERE pm . user_id = u . user_id
ORDER BY pm . data DESC , pm . role ASC
LIMIT 1
), 'utente' ) AS role_name
2025-11-20 17:00:37 +00:00
FROM `user` u
JOIN `person` p ON p . id_persona = u . person_id
ORDER BY u . user_id ASC " ;
$result = mysqli_query ( $conn , $sql );
if ( ! $result ) {
$error = mysqli_error ( $conn );
}
2025-12-04 17:16:40 +00:00
// Se editing
$editId = isset ( $_GET [ 'edit_id' ]) ? ( int ) $_GET [ 'edit_id' ] : 0 ;
$editUser = null ;
if ( $editId > 0 ) {
$resE = mysqli_query ( $conn , " SELECT u.user_id, u.descrizione AS username, u.data, u.person_id, p.nome, p.cognome, p.data_nascita, p.luogo_nascita, p.cod_fiscale, p.telefono FROM `user` u JOIN `person` p ON p.id_persona = u.person_id WHERE u.user_id = $editId LIMIT 1 " );
if ( $resE && mysqli_num_rows ( $resE ) === 1 ) { $editUser = mysqli_fetch_assoc ( $resE ); }
}
2025-11-20 17:00:37 +00:00
?>
<! DOCTYPE html >
< html lang = " it " >
< head >
< meta charset = " UTF-8 " />
< meta name = " viewport " content = " width=device-width, initial-scale=1.0 " />
< title > Amministrazione | Utenti </ title >
< script src = " https://cdn.tailwindcss.com " ></ script >
</ head >
< body class = " bg-[#f8fafc] text-[#1f2937] " >
< 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 " >
< a href = " ../../index.php " class = " font-semibold text-lg " > Biblioteca Online </ a >
< div class = " flex items-center gap-3 " >
< span class = " hidden md:inline text-sm " > Admin : < ? php echo htmlspecialchars ( $_SESSION [ 'username' ] ? ? '' ); ?> </span>
< a href = " ../auth/logout.php " class = " px-4 py-2 bg-[#84dd63] text-[#1f2937] rounded hover:bg-[#cbff4d] " > Logout </ a >
</ div >
</ div >
</ div >
</ nav >
< main class = " max-w-7xl mx-auto px-4 py-8 " >
< div class = " flex items-center justify-between mb-6 " >
< h1 class = " text-2xl font-semibold " > Utenti Registrati </ h1 >
< a href = " ../../index.php " class = " text-sm text-[#1f2937] hover:text-[#84dd63] " > ← Torna alla Home </ a >
</ div >
2025-12-04 17:16:40 +00:00
< ? php if ( ! empty ( $msg )) : ?>
< div class = " p-4 bg-green-50 text-green-700 rounded mb-4 " >< ? php echo htmlspecialchars ( $msg ); ?> </div>
< ? php endif ; ?>
2025-11-20 17:00:37 +00:00
< ? php if ( ! empty ( $error )) : ?>
< div class = " p-4 bg-red-50 text-red-700 rounded mb-4 " > Errore DB : < ? php echo htmlspecialchars ( $error ); ?> </div>
< ? php endif ; ?>
2025-12-04 17:16:40 +00:00
<!-- Crea Utente / Bibliotecario -->
< section class = " bg-white shadow rounded p-4 border border-[#e5e7eb] mb-6 " >
2025-12-05 08:07:35 +00:00
< h2 class = " text-lg font-semibold mb-3 " > Crea Utente </ h2 >
2025-12-04 17:16:40 +00:00
< form method = " post " class = " grid grid-cols-1 md:grid-cols-2 gap-3 " >
< input type = " hidden " name = " azione " value = " create_user " />
< div >
< label class = " block text-sm text-gray-600 " > Nome </ label >
< input type = " text " name = " nome " required class = " mt-1 w-full border rounded px-3 py-2 " />
</ div >
< div >
< label class = " block text-sm text-gray-600 " > Cognome </ label >
< input type = " text " name = " cognome " required class = " mt-1 w-full border rounded px-3 py-2 " />
</ div >
< div >
< label class = " block text-sm text-gray-600 " > Data di nascita </ label >
< input type = " date " name = " data_nascita " required class = " mt-1 w-full border rounded px-3 py-2 " />
</ div >
< div >
< label class = " block text-sm text-gray-600 " > Luogo di nascita </ label >
< input type = " text " name = " luogo_nascita " required class = " mt-1 w-full border rounded px-3 py-2 " />
</ div >
< div >
< label class = " block text-sm text-gray-600 " > Codice Fiscale </ label >
< input type = " text " name = " cod_fiscale " maxlength = " 16 " required class = " mt-1 w-full border rounded px-3 py-2 uppercase " />
</ div >
< div >
< label class = " block text-sm text-gray-600 " > Telefono </ label >
< input type = " tel " name = " telefono " maxlength = " 10 " required class = " mt-1 w-full border rounded px-3 py-2 " />
</ div >
< div class = " md:col-span-2 border-t pt-3 " >
< h3 class = " text-md font-semibold " > Credenziali </ h3 >
</ div >
< div >
< label class = " block text-sm text-gray-600 " > Username </ label >
< input type = " text " name = " username " required class = " mt-1 w-full border rounded px-3 py-2 " />
</ div >
< div >
< label class = " block text-sm text-gray-600 " > Password </ label >
< input type = " password " name = " password " required class = " mt-1 w-full border rounded px-3 py-2 " />
</ div >
2025-12-05 08:07:35 +00:00
2025-12-04 17:16:40 +00:00
< div class = " md:col-span-2 mt-2 " >
< button class = " px-4 py-2 bg-[#6baa75] text-white rounded hover:bg-[#84dd63] " > Crea </ button >
</ div >
</ form >
</ section >
<!-- Modifica Utente -->
< ? php if ( $editUser ) : ?>
< section class = " bg-white shadow rounded p-4 border border-[#e5e7eb] mb-6 " >
< h2 class = " text-lg font-semibold mb-3 " > Modifica Utente #<?php echo (int)$editUser['user_id']; ?></h2>
< form method = " post " class = " grid grid-cols-1 md:grid-cols-2 gap-3 " >
< input type = " hidden " name = " azione " value = " update_user " />
< input type = " hidden " name = " user_id " value = " <?php echo (int) $editUser['user_id'] ; ?> " />
< div >
< label class = " block text-sm text-gray-600 " > Nome </ label >
< input type = " text " name = " nome " required class = " mt-1 w-full border rounded px-3 py-2 " value = " <?php echo htmlspecialchars( $editUser['nome'] ); ?> " />
</ div >
< div >
< label class = " block text-sm text-gray-600 " > Cognome </ label >
< input type = " text " name = " cognome " required class = " mt-1 w-full border rounded px-3 py-2 " value = " <?php echo htmlspecialchars( $editUser['cognome'] ); ?> " />
</ div >
< div >
< label class = " block text-sm text-gray-600 " > Data di nascita </ label >
< input type = " date " name = " data_nascita " required class = " mt-1 w-full border rounded px-3 py-2 " value = " <?php echo htmlspecialchars( $editUser['data_nascita'] ); ?> " />
</ div >
< div >
< label class = " block text-sm text-gray-600 " > Luogo di nascita </ label >
< input type = " text " name = " luogo_nascita " required class = " mt-1 w-full border rounded px-3 py-2 " value = " <?php echo htmlspecialchars( $editUser['luogo_nascita'] ); ?> " />
</ div >
< div >
< label class = " block text-sm text-gray-600 " > Codice Fiscale </ label >
< input type = " text " name = " cod_fiscale " maxlength = " 16 " required class = " mt-1 w-full border rounded px-3 py-2 uppercase " value = " <?php echo htmlspecialchars( $editUser['cod_fiscale'] ); ?> " />
</ div >
< div >
< label class = " block text-sm text-gray-600 " > Telefono </ label >
< input type = " tel " name = " telefono " maxlength = " 10 " required class = " mt-1 w-full border rounded px-3 py-2 " value = " <?php echo htmlspecialchars( $editUser['telefono'] ); ?> " />
</ div >
< div class = " md:col-span-2 border-t pt-3 " >
< h3 class = " text-md font-semibold " > Credenziali </ h3 >
</ div >
< div >
< label class = " block text-sm text-gray-600 " > Username </ label >
< input type = " text " name = " username " required class = " mt-1 w-full border rounded px-3 py-2 " value = " <?php echo htmlspecialchars( $editUser['username'] ); ?> " />
</ div >
< div >
< label class = " block text-sm text-gray-600 " > Nuova Password ( opzionale ) </ label >
< input type = " password " name = " password " class = " mt-1 w-full border rounded px-3 py-2 " placeholder = " Lascia vuoto per non cambiare " />
</ div >
< div class = " md:col-span-2 mt-2 flex gap-2 " >
< button class = " px-4 py-2 bg-[#6baa75] text-white rounded hover:bg-[#84dd63] " > Salva Modifiche </ button >
< a href = " ./users.php " class = " px-4 py-2 bg-[#69747c] text-white rounded hover:bg-[#545454] " > Annulla </ a >
</ div >
</ form >
</ section >
< ? php endif ; ?>
2025-11-20 17:00:37 +00:00
< div class = " overflow-x-auto bg-white shadow rounded " >
< table class = " min-w-full divide-y divide-gray-200 " >
< thead class = " bg-gray-50 " >
< tr >
< th class = " px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider " > ID </ th >
< th class = " px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider " > Username </ th >
< th class = " px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider " > Ruolo </ th >
< th class = " px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider " > Registrato il </ th >
< th class = " px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider " > Nome </ th >
< th class = " px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider " > Cognome </ th >
< th class = " px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider " > Cod . Fiscale </ th >
< th class = " px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider " > Telefono </ th >
2025-12-04 17:16:40 +00:00
< th class = " px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider " > Azioni </ th >
2025-11-20 17:00:37 +00:00
</ tr >
</ thead >
< tbody class = " bg-white divide-y divide-gray-200 " >
< ? php if ( $result && mysqli_num_rows ( $result ) > 0 ) : ?>
< ? php while ( $row = mysqli_fetch_assoc ( $result )) : ?>
< tr class = " hover:bg-gray-50 " >
< td class = " px-4 py-2 text-sm text-gray-700 " >< ? php echo ( int ) $row [ 'user_id' ]; ?> </td>
< td class = " px-4 py-2 text-sm text-gray-700 " >< ? php echo htmlspecialchars ( $row [ 'username' ]); ?> </td>
< td class = " px-4 py-2 text-sm " >
< span class = " px-2 py-1 rounded bg-[#84dd63] text-[#1f2937] text-xs font-medium " >< ? php echo htmlspecialchars ( $row [ 'role_name' ]); ?> </span>
</ td >
< td class = " px-4 py-2 text-sm text-gray-700 " >< ? php echo htmlspecialchars ( $row [ 'registrato_il' ] ? ? '' ); ?> </td>
< td class = " px-4 py-2 text-sm text-gray-700 " >< ? php echo htmlspecialchars ( $row [ 'nome' ]); ?> </td>
< td class = " px-4 py-2 text-sm text-gray-700 " >< ? php echo htmlspecialchars ( $row [ 'cognome' ]); ?> </td>
< td class = " px-4 py-2 text-sm text-gray-700 font-mono " >< ? php echo htmlspecialchars ( $row [ 'cod_fiscale' ]); ?> </td>
< td class = " px-4 py-2 text-sm text-gray-700 " >< ? php echo htmlspecialchars ( $row [ 'telefono' ]); ?> </td>
2025-12-04 17:16:40 +00:00
< td class = " px-4 py-2 text-sm text-gray-700 " >
< div class = " flex items-center gap-2 " >
< a href = " ./users.php?edit_id=<?php echo (int) $row['user_id'] ; ?> " class = " px-3 py-1 bg-[#6baa75] text-white rounded hover:bg-[#84dd63] " > Modifica </ a >
< form method = " post " onsubmit = " return confirm('Confermi eliminazione?'); " class = " inline " >
< input type = " hidden " name = " azione " value = " delete_user " />
< input type = " hidden " name = " user_id " value = " <?php echo (int) $row['user_id'] ; ?> " />
< button class = " px-3 py-1 bg-red-600 text-white rounded hover:bg-red-700 " > Elimina </ button >
</ form >
2025-12-05 08:07:35 +00:00
2025-12-04 17:16:40 +00:00
</ div >
</ td >
2025-11-20 17:00:37 +00:00
</ tr >
< ? php endwhile ; ?>
< ? php else : ?>
< tr >
2025-12-04 17:16:40 +00:00
< td colspan = " 9 " class = " px-4 py-6 text-center text-sm text-gray-500 " > Nessun utente trovato </ td >
2025-11-20 17:00:37 +00:00
</ tr >
< ? php endif ; ?>
</ tbody >
</ table >
</ div >
</ main >
</ body >
2025-12-04 17:16:40 +00:00
</ html >