Files
pilates-platform/includes/functions.php
Francesco Picone 4e41ca9bf7 fix
2025-12-03 18:35:21 +01:00

565 lines
14 KiB
PHP

<?php
/**
* Funzioni Comuni
*
* Raccolta di funzioni utilizzate in tutta la piattaforma
*/
// ============================================
// FUNZIONI AUTENTICAZIONE E SESSIONE
// ============================================
/**
* Verifica se l'utente è loggato
*
* @return bool True se loggato, false altrimenti
*/
function is_logged_in() {
return isset($_SESSION['user_id']) && !empty($_SESSION['user_id']);
}
/**
* Verifica se l'utente è un amministratore
*
* @return bool True se admin, false altrimenti
*/
function is_admin() {
return isset($_SESSION['is_admin']) && $_SESSION['is_admin'] === true;
}
/**
* Richiede che l'utente sia loggato, altrimenti reindirizza al login
*/
function require_login() {
if (!is_logged_in()) {
$_SESSION['redirect_after_login'] = $_SERVER['REQUEST_URI'];
header('Location: ' . SITE_URL . '/login.php');
exit;
}
}
/**
* Richiede che l'utente sia amministratore, altrimenti reindirizza
*/
function require_admin() {
require_login();
if (!is_admin()) {
header('Location: ' . SITE_URL . '/index.php');
exit;
}
}
/**
* Effettua il login dell'utente
*
* @param int $user_id ID dell'utente
* @param bool $is_admin Se l'utente è admin
*/
function login_user($user_id, $is_admin = false) {
// Rigenera l'ID di sessione per sicurezza
session_regenerate_id(true);
$_SESSION['user_id'] = $user_id;
$_SESSION['is_admin'] = $is_admin;
$_SESSION['last_activity'] = time();
}
/**
* Effettua il logout dell'utente
*/
function logout_user() {
// Cancella tutte le variabili di sessione
$_SESSION = array();
// Distruggi il cookie di sessione se esiste
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '', time() - 3600, '/');
}
// Distruggi la sessione
session_destroy();
}
/**
* Verifica la validità della sessione (timeout)
*
* @return bool True se sessione valida, false se scaduta
*/
function check_session_timeout() {
if (isset($_SESSION['last_activity'])) {
$elapsed = time() - $_SESSION['last_activity'];
if ($elapsed > SESSION_LIFETIME) {
logout_user();
return false;
}
}
$_SESSION['last_activity'] = time();
return true;
}
// ============================================
// FUNZIONI SICUREZZA
// ============================================
/**
* Hash sicuro di una password
*
* @param string $password Password in chiaro
* @return string Password hashata
*/
function hash_password($password) {
return password_hash($password, PASSWORD_DEFAULT);
}
/**
* Verifica una password contro il suo hash
*
* @param string $password Password in chiaro
* @param string $hash Hash salvato nel database
* @return bool True se corrisponde, false altrimenti
*/
function verify_password($password, $hash) {
return password_verify($password, $hash);
}
/**
* Genera un token casuale sicuro
*
* @param int $length Lunghezza del token
* @return string Token generato
*/
function generate_token($length = 32) {
return bin2hex(random_bytes($length));
}
/**
* Sanitizza input utente per prevenire XSS
*
* @param string $data Dati da sanitizzare
* @return string Dati sanitizzati
*/
function sanitize_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
return $data;
}
/**
* Valida un indirizzo email
*
* @param string $email Email da validare
* @return bool True se valida, false altrimenti
*/
function validate_email($email) {
return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}
// ============================================
// FUNZIONI DATABASE - UTENTI
// ============================================
/**
* Ottiene un utente dal database tramite email
*
* @param string $email Email dell'utente
* @return array|false Dati utente o false se non trovato
*/
function get_user_by_email($email) {
$pdo = get_db_connection();
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ? AND deleted_at IS NULL");
$stmt->execute([$email]);
return $stmt->fetch();
}
/**
* Ottiene un utente dal database tramite ID
*
* @param int $user_id ID dell'utente
* @return array|false Dati utente o false se non trovato
*/
function get_user_by_id($user_id) {
$pdo = get_db_connection();
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ? AND deleted_at IS NULL");
$stmt->execute([$user_id]);
return $stmt->fetch();
}
/**
* Crea un nuovo utente nel database
*
* @param string $email Email
* @param string $password Password in chiaro (verrà hashata)
* @param string $first_name Nome
* @param string $last_name Cognome
* @param bool $is_admin Se è amministratore
* @return int|false ID del nuovo utente o false in caso di errore
*/
function create_user($email, $password, $first_name, $last_name, $is_admin = false) {
$pdo = get_db_connection();
$hashed_password = hash_password($password);
try {
$stmt = $pdo->prepare("
INSERT INTO users (email, password, first_name, last_name, is_admin, created_at)
VALUES (?, ?, ?, ?, ?, NOW())
");
$stmt->execute([
$email,
$hashed_password,
$first_name,
$last_name,
$is_admin ? 1 : 0
]);
return $pdo->lastInsertId();
} catch (PDOException $e) {
return false;
}
}
// ============================================
// FUNZIONI DATABASE - LEZIONI
// ============================================
/**
* Ottiene tutte le lezioni demo (gratuite)
*
* @return array Array di lezioni demo
*/
function get_demo_lessons() {
$pdo = get_db_connection();
$stmt = $pdo->query("
SELECT * FROM lessons
WHERE is_demo = 1 AND is_active = 1
ORDER BY created_at DESC
");
return $stmt->fetchAll();
}
/**
* Ottiene tutte le lezioni attive
*
* @param string $type Tipo di lezione: 'all', 'video', 'live'
* @return array Array di lezioni
*/
function get_all_lessons($type = 'all') {
$pdo = get_db_connection();
$sql = "SELECT * FROM lessons WHERE is_active = 1";
if ($type !== 'all') {
$sql .= " AND type = :type";
}
$sql .= " ORDER BY created_at DESC";
$stmt = $pdo->prepare($sql);
if ($type !== 'all') {
$stmt->execute(['type' => $type]);
} else {
$stmt->execute();
}
return $stmt->fetchAll();
}
/**
* Ottiene una lezione specifica tramite ID
*
* @param int $lesson_id ID della lezione
* @return array|false Dati lezione o false se non trovata
*/
function get_lesson_by_id($lesson_id) {
$pdo = get_db_connection();
$stmt = $pdo->prepare("SELECT * FROM lessons WHERE id = ?");
$stmt->execute([$lesson_id]);
return $stmt->fetch();
}
/**
* Verifica se un utente ha acquistato una lezione
*
* @param int $user_id ID utente
* @param int $lesson_id ID lezione
* @return bool True se acquistata, false altrimenti
*/
function user_owns_lesson($user_id, $lesson_id) {
$pdo = get_db_connection();
$stmt = $pdo->prepare("
SELECT COUNT(*) as count
FROM purchases
WHERE user_id = ? AND lesson_id = ? AND status = 'completed'
");
$stmt->execute([$user_id, $lesson_id]);
$result = $stmt->fetch();
return $result['count'] > 0;
}
/**
* Ottiene tutte le lezioni acquistate da un utente
*
* @param int $user_id ID utente
* @return array Array di lezioni acquistate
*/
function get_user_purchased_lessons($user_id) {
$pdo = get_db_connection();
$stmt = $pdo->prepare("
SELECT l.*, p.purchased_at, p.amount as paid_amount
FROM lessons l
INNER JOIN purchases p ON l.id = p.lesson_id
WHERE p.user_id = ? AND p.status = 'completed'
ORDER BY p.purchased_at DESC
");
$stmt->execute([$user_id]);
return $stmt->fetchAll();
}
// ============================================
// FUNZIONI RECUPERO PASSWORD
// ============================================
/**
* Crea un token per il recupero password
*
* @param int $user_id ID utente
* @return string Token generato
*/
function create_password_reset_token($user_id) {
$pdo = get_db_connection();
$token = generate_token(32);
$expires_at = date('Y-m-d H:i:s', time() + PASSWORD_RESET_TOKEN_LIFETIME);
// Cancella eventuali token precedenti per questo utente
$stmt = $pdo->prepare("DELETE FROM password_resets WHERE user_id = ?");
$stmt->execute([$user_id]);
// Crea nuovo token
$stmt = $pdo->prepare("
INSERT INTO password_resets (user_id, token, expires_at, created_at)
VALUES (?, ?, ?, NOW())
");
$stmt->execute([$user_id, $token, $expires_at]);
return $token;
}
/**
* Verifica la validità di un token di reset password
*
* @param string $token Token da verificare
* @return int|false User ID se valido, false altrimenti
*/
function verify_password_reset_token($token) {
$pdo = get_db_connection();
$stmt = $pdo->prepare("
SELECT user_id FROM password_resets
WHERE token = ? AND expires_at > NOW() AND used_at IS NULL
");
$stmt->execute([$token]);
$result = $stmt->fetch();
return $result ? $result['user_id'] : false;
}
/**
* Marca un token come utilizzato
*
* @param string $token Token da marcare
*/
function mark_token_as_used($token) {
$pdo = get_db_connection();
$stmt = $pdo->prepare("UPDATE password_resets SET used_at = NOW() WHERE token = ?");
$stmt->execute([$token]);
}
// ============================================
// FUNZIONI EMAIL
// ============================================
/**
* Invia un'email (funzione base con mail() PHP)
*
* @param string $to Destinatario
* @param string $subject Oggetto
* @param string $message Messaggio HTML
* @return bool True se inviata, false altrimenti
*/
function send_email($to, $subject, $message) {
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
$headers .= "From: " . MAIL_FROM_NAME . " <" . MAIL_FROM . ">" . "\r\n";
return mail($to, $subject, $message, $headers);
}
/**
* Invia email di recupero password
*
* @param string $email Email destinatario
* @param string $token Token di reset
* @return bool True se inviata, false altrimenti
*/
function send_password_reset_email($email, $token) {
$reset_link = SITE_URL . "/reset_password.php?token=" . $token;
$subject = "Recupero Password - " . SITE_NAME;
$message = "
<html>
<head>
<style>
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
.button {
display: inline-block;
padding: 12px 24px;
background: #4A90E2;
color: white;
text-decoration: none;
border-radius: 5px;
margin: 20px 0;
}
</style>
</head>
<body>
<div class='container'>
<h2>Recupero Password</h2>
<p>Hai richiesto il recupero della password per il tuo account su " . SITE_NAME . ".</p>
<p>Clicca sul pulsante qui sotto per reimpostare la tua password:</p>
<a href='{$reset_link}' class='button'>Reimposta Password</a>
<p>Oppure copia e incolla questo link nel tuo browser:</p>
<p>{$reset_link}</p>
<p>Questo link è valido per " . (PASSWORD_RESET_TOKEN_LIFETIME / 60) . " minuti.</p>
<p>Se non hai richiesto tu questo recupero, ignora questa email.</p>
<hr>
<p><small>Questa è un'email automatica, non rispondere a questo messaggio.</small></p>
</div>
</body>
</html>
";
return send_email($email, $subject, $message);
}
// ============================================
// FUNZIONI MESSAGGI FLASH
// ============================================
/**
* Imposta un messaggio flash da visualizzare nella prossima pagina
*
* @param string $type Tipo: 'success', 'error', 'warning', 'info'
* @param string $message Messaggio da visualizzare
*/
function set_flash_message($type, $message) {
$_SESSION['flash_message'] = [
'type' => $type,
'message' => $message
];
}
/**
* Ottiene e cancella il messaggio flash
*
* @return array|null Array con tipo e messaggio, o null se non presente
*/
function get_flash_message() {
if (isset($_SESSION['flash_message'])) {
$flash = $_SESSION['flash_message'];
unset($_SESSION['flash_message']);
return $flash;
}
return null;
}
/**
* Visualizza il messaggio flash HTML
*
* @return string HTML del messaggio o stringa vuota
*/
function display_flash_message() {
$flash = get_flash_message();
if ($flash) {
$type = htmlspecialchars($flash['type']);
$message = htmlspecialchars($flash['message']);
return "<div class='alert alert-{$type}'>{$message}</div>";
}
return '';
}
// ============================================
// FUNZIONI UTILITY
// ============================================
/**
* Formatta una data in formato italiano
*
* @param string $date Data in formato SQL
* @return string Data formattata
*/
function format_date($date) {
return date('d/m/Y', strtotime($date));
}
/**
* Formatta data e ora in formato italiano
*
* @param string $datetime Datetime in formato SQL
* @return string Datetime formattata
*/
function format_datetime($datetime) {
return date('d/m/Y H:i', strtotime($datetime));
}
/**
* Formatta un prezzo in euro
*
* @param float $price Prezzo
* @return string Prezzo formattato
*/
function format_price($price) {
return '€ ' . number_format($price, 2, ',', '.');
}
/**
* Redirect a un'altra pagina
*
* @param string $url URL di destinazione
*/
function redirect($url) {
header("Location: $url");
exit;
}
?>