getConnection(); // Verifica che iduserlogin sia definito if (!isset($iduserlogin)) { die("Errore: ID utente non definito."); } // Recupera i dati della scuola in base all'utente loggato $stmt = $pdo->prepare(" SELECT id, name, website, email, phone, description, address_street, address_city, address_postal_code, address_province, address_country, logo, status FROM schools WHERE owner_id = ? "); $stmt->execute([$iduserlogin]); $school = $stmt->fetch(); if (!$school) { die("Errore: Nessuna scuola trovata per l'utente loggato."); } $school_id = $school['id']; $school_name = $school['name']; // Recupera tutte le categorie disponibili $stmt = $pdo->prepare("SELECT id, name FROM class_categories WHERE status = 'active' ORDER BY name"); $stmt->execute(); $categories = $stmt->fetchAll(); // Recupera tutti gli insegnanti della scuola $stmt = $pdo->prepare("SELECT id, first_name, last_name FROM teachers WHERE user_id = ? AND status = 'active' ORDER BY first_name, last_name"); $stmt->execute([$iduserlogin]); $teachers = $stmt->fetchAll(); // Funzione per ridimensionare l'immagine function resizeImage($source_path, $dest_path, $max_width = 800) { list($width, $height, $type) = getimagesize($source_path); if ($width <= $max_width) { copy($source_path, $dest_path); return; } $new_width = $max_width; $new_height = (int)(($height * $new_width) / $width); switch ($type) { case IMAGETYPE_JPEG: $source = imagecreatefromjpeg($source_path); break; case IMAGETYPE_PNG: $source = imagecreatefrompng($source_path); break; case IMAGETYPE_GIF: $source = imagecreatefromgif($source_path); break; default: throw new Exception("Formato immagine non supportato."); } $dest = imagecreatetruecolor($new_width, $new_height); if ($type == IMAGETYPE_PNG) { imagealphablending($dest, false); imagesavealpha($dest, true); } imagecopyresampled($dest, $source, 0, 0, 0, 0, $new_width, $new_height, $width, $height); switch ($type) { case IMAGETYPE_JPEG: imagejpeg($dest, $dest_path, 90); break; case IMAGETYPE_PNG: imagepng($dest, $dest_path); break; case IMAGETYPE_GIF: imagegif($dest, $dest_path); break; } imagedestroy($source); imagedestroy($dest); } // Gestione delle azioni (aggiunta, modifica, cancellazione) if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (isset($_POST['action'])) { $action = $_POST['action']; // Aggiunta di una nuova classe if ($action === 'add') { $class_category_id = $_POST['class_category_id'] ?? 0; $name = $_POST['name'] ?? ''; $description = $_POST['description'] ?? null; $requirements = $_POST['requirements'] ?? null; $level = in_array($_POST['level'], ['beginner', 'intermediate', 'advanced']) ? $_POST['level'] : 'beginner'; $typical_duration = $_POST['typical_duration'] ? (int)$_POST['typical_duration'] : null; $max_capacity = $_POST['max_capacity'] ? (int)$_POST['max_capacity'] : 0; // Nuovo campo $days_of_week = $_POST['days_of_week'] ?? ''; $start_time = $_POST['start_time'] ?? ''; $status = $_POST['status'] === 'active' ? 'active' : 'inactive'; // Rimossi period_start e period_end dai controlli if (empty($name) || $class_category_id <= 0 || empty($days_of_week) || empty($start_time)) { $error = "I campi obbligatori non sono stati compilati."; } else { $photo = null; if (isset($_FILES['photo']) && $_FILES['photo']['error'] === UPLOAD_ERR_OK) { $file = $_FILES['photo']; $timestamp = time(); $original_name = basename($file['name']); $extension = strtolower(pathinfo($original_name, PATHINFO_EXTENSION)); $allowed_extensions = ['jpg', 'jpeg', 'png', 'gif']; if (in_array($extension, $allowed_extensions)) { $new_filename = "photoclass/{$school_id}-{$timestamp}-{$original_name}"; $temp_path = $file['tmp_name']; try { resizeImage($temp_path, $new_filename); $photo = $new_filename; } catch (Exception $e) { $error = "Errore durante il ridimensionamento della foto: " . $e->getMessage(); } } else { $error = "Estensione del file non consentita. Usa JPG, JPEG, PNG o GIF."; } } if (!isset($error)) { $stmt = $pdo->prepare(" INSERT INTO class_types (school_id, class_category_id, name, description, photo, requirements, level, typical_duration, max_capacity, days_of_week, start_time, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) "); $success = $stmt->execute([ $school_id, $class_category_id, $name, $description, $photo, $requirements, $level, $typical_duration, $max_capacity, // Nuovo campo $days_of_week, $start_time, $status ]); if ($success) { $success_message = "Classe aggiunta con successo!"; } else { $error = "Errore durante l'aggiunta della classe."; } } } } // Modifica di una classe esistente if ($action === 'edit') { $id = $_POST['id'] ?? 0; $class_category_id = $_POST['class_category_id'] ?? 0; $name = $_POST['name'] ?? ''; $description = $_POST['description'] ?? null; $requirements = $_POST['requirements'] ?? null; $level = in_array($_POST['level'], ['beginner', 'intermediate', 'advanced']) ? $_POST['level'] : 'beginner'; $typical_duration = $_POST['typical_duration'] ? (int)$_POST['typical_duration'] : null; $max_capacity = $_POST['max_capacity'] ? (int)$_POST['max_capacity'] : 0; // Nuovo campo $days_of_week = $_POST['days_of_week'] ?? ''; $start_time = $_POST['start_time'] ?? ''; $status = $_POST['status'] === 'active' ? 'active' : 'inactive'; // Rimossi period_start e period_end dai controlli if (empty($name) || $class_category_id <= 0 || empty($days_of_week) || empty($start_time)) { $error = "I campi obbligatori non sono stati compilati."; } else { // Recupera la classe esistente per ottenere il percorso della foto attuale $stmt = $pdo->prepare("SELECT photo FROM class_types WHERE id = ? AND school_id = ?"); $stmt->execute([$id, $school_id]); $class = $stmt->fetch(); if (!$class) { $error = "Classe non trovata."; } else { $photo = $class['photo']; if (isset($_FILES['photo']) && $_FILES['photo']['error'] === UPLOAD_ERR_OK) { $file = $_FILES['photo']; $timestamp = time(); $original_name = basename($file['name']); $extension = strtolower(pathinfo($original_name, PATHINFO_EXTENSION)); $allowed_extensions = ['jpg', 'jpeg', 'png', 'gif']; if (in_array($extension, $allowed_extensions)) { $new_filename = "photoclass/{$school_id}-{$timestamp}-{$original_name}"; $temp_path = $file['tmp_name']; try { resizeImage($temp_path, $new_filename); $photo = $new_filename; if ($class['photo'] && file_exists($class['photo'])) { unlink($class['photo']); } } catch (Exception $e) { $error = "Errore durante il ridimensionamento della foto: " . $e->getMessage(); } } else { $error = "Estensione del file non consentita. Usa JPG, JPEG, PNG o GIF."; } } if (!isset($error)) { $stmt = $pdo->prepare(" UPDATE class_types SET class_category_id = ?, name = ?, description = ?, photo = ?, requirements = ?, level = ?, typical_duration = ?, max_capacity = ?, days_of_week = ?, start_time = ?, status = ? WHERE id = ? AND school_id = ? "); $success = $stmt->execute([ $class_category_id, $name, $description, $photo, $requirements, $level, $typical_duration, $max_capacity, // Nuovo campo $days_of_week, $start_time, $status, $id, $school_id ]); if ($success) { $success_message = "Classe aggiornata con successo!"; } else { $error = "Errore durante l'aggiornamento della classe."; } } } } } // Cancellazione di una classe if ($action === 'delete') { $id = $_POST['id'] ?? 0; $stmt = $pdo->prepare("SELECT photo FROM class_types WHERE id = ? AND school_id = ?"); $stmt->execute([$id, $school_id]); $class = $stmt->fetch(); if ($class) { if ($class['photo'] && file_exists($class['photo'])) { unlink($class['photo']); } $stmt = $pdo->prepare("DELETE FROM class_types WHERE id = ? AND school_id = ?"); $success = $stmt->execute([$id, $school_id]); if ($success) { $success_message = "Classe eliminata con successo!"; } else { $error = "Errore durante l'eliminazione della classe."; } } else { $error = "Classe non trovata."; } } // Assegnazione di un insegnante if ($action === 'assign_teacher') { $class_id = $_POST['class_id'] ?? 0; $teacher_id = !empty($_POST['teacher_id']) ? (int)$_POST['teacher_id'] : null; // Verifica che la classe appartenga alla scuola $stmt = $pdo->prepare("SELECT id FROM class_types WHERE id = ? AND school_id = ?"); $stmt->execute([$class_id, $school_id]); if (!$stmt->fetch()) { $error = "Classe non trovata."; } else { // Se teacher_id è null, rimuoviamo l'assegnazione; altrimenti, assegniamo l'insegnante $stmt = $pdo->prepare("UPDATE class_types SET teacher_id = ? WHERE id = ?"); $success = $stmt->execute([$teacher_id, $class_id]); if ($success) { $success_message = "Insegnante assegnato con successo!"; } else { $error = "Errore durante l'assegnazione dell'insegnante."; } } } // Propagazione delle sessioni if ($action === 'propagate_sessions') { $class_id = $_POST['class_id'] ?? 0; $start_date = $_POST['start_date'] ?? ''; $end_date = $_POST['end_date'] ?? ''; // Validazione delle date if (empty($start_date) || empty($end_date)) { $error = "Le date di inizio e fine sono obbligatorie."; } elseif (strtotime($end_date) < strtotime($start_date)) { $error = "La data di fine non può essere precedente alla data di inizio."; } else { // Verifica che la classe appartenga alla scuola $stmt = $pdo->prepare(" SELECT days_of_week, start_time, typical_duration, teacher_id FROM class_types WHERE id = ? AND school_id = ? "); $stmt->execute([$class_id, $school_id]); $class = $stmt->fetch(); if (!$class) { $error = "Classe non trovata."; } else { // Recupera i giorni di chiusura della scuola $stmt = $pdo->prepare(" SELECT start_date, end_date FROM day_off WHERE school_id = ? AND ( (start_date BETWEEN ? AND ?) OR (end_date BETWEEN ? AND ?) OR (start_date <= ? AND end_date >= ?) ) "); $stmt->execute([ $school_id, $start_date, $end_date, $start_date, $end_date, $start_date, $end_date ]); $days_off = $stmt->fetchAll(); // Crea un array di giorni di chiusura $off_dates = []; foreach ($days_off as $day_off) { $current = new DateTime($day_off['start_date']); $end = new DateTime($day_off['end_date']); while ($current <= $end) { $off_dates[] = $current->format('Y-m-d'); $current->modify('+1 day'); } } // Converti i giorni della settimana in un array $days_of_week = array_map('trim', explode(',', $class['days_of_week'])); $days_map = [ 'Lun' => 'Monday', 'Mar' => 'Tuesday', 'Mer' => 'Wednesday', 'Gio' => 'Thursday', 'Ven' => 'Friday', 'Sab' => 'Saturday', 'Dom' => 'Sunday' ]; // Converti i giorni in formato inglese per il confronto $days_of_week_english = []; foreach ($days_of_week as $day) { if (isset($days_map[$day])) { $days_of_week_english[] = $days_map[$day]; } } // Calcola l'orario di fine $start_time = new DateTime($class['start_time']); $end_time = clone $start_time; if ($class['typical_duration']) { $end_time->modify("+{$class['typical_duration']} minutes"); } else { $end_time->modify("+60 minutes"); // Default: 1 ora se la durata non è specificata } // Genera un propagation_id univoco $propagation_id = uniqid('prop_', true); // Genera le sessioni $current_date = new DateTime($start_date); $end_date_dt = new DateTime($end_date); $end_date_dt->setTime(23, 59, 59); // Include l'ultimo giorno $stmt = $pdo->prepare(" INSERT INTO class_sessions (class_type_id, session_date, start_time, end_time, teacher_id, status, propagation_id) VALUES (?, ?, ?, ?, ?, 'scheduled', ?) "); $sessions_created = 0; while ($current_date <= $end_date_dt) { $day_of_week = $current_date->format('l'); // Giorno della settimana in inglese (es. Monday) $current_date_str = $current_date->format('Y-m-d'); // Verifica se il giorno è un giorno di chiusura e se è nei giorni della settimana della classe if (!in_array($current_date_str, $off_dates) && in_array($day_of_week, $days_of_week_english)) { $session_date = $current_date->format('Y-m-d'); $start_time_str = $start_time->format('H:i:s'); $end_time_str = $end_time->format('H:i:s'); try { $stmt->execute([ $class_id, $session_date, $start_time_str, $end_time_str, $class['teacher_id'], $propagation_id ]); $sessions_created++; } catch (PDOException $e) { // Ignora errori di chiave unica (sessioni già esistenti) if ($e->getCode() != 23000) { $error = "Errore durante la propagazione delle sessioni: " . $e->getMessage(); break; } } } $current_date->modify('+1 day'); } if (!isset($error)) { $success_message = "Propagate $sessions_created sessioni con successo! (ID Propagazione: $propagation_id)"; } } } } // Rimozione di una propagazione if ($action === 'remove_propagation') { $propagation_id = $_POST['propagation_id'] ?? ''; $class_id = $_POST['class_id'] ?? 0; if (empty($propagation_id) || $class_id <= 0) { $error = "ID di propagazione o classe non validi."; } else { // Verifica che la classe appartenga alla scuola $stmt = $pdo->prepare("SELECT id FROM class_types WHERE id = ? AND school_id = ?"); $stmt->execute([$class_id, $school_id]); if (!$stmt->fetch()) { $error = "Classe non trovata."; } else { // Elimina tutte le sessioni associate a questa propagazione $stmt = $pdo->prepare(" DELETE FROM class_sessions WHERE propagation_id = ? AND class_type_id = ? "); $stmt->execute([$propagation_id, $class_id]); $deleted_rows = $stmt->rowCount(); $success_message = "Propagazione rimossa con successo! ($deleted_rows sessioni eliminate)"; } } } // Reindirizza per evitare il doppio invio del form header("Location: school_dashboard.php"); exit; } } // Recupera tutte le classi della scuola con il nome dell'insegnante $stmt = $pdo->prepare(" SELECT ct.*, cc.name AS category_name, t.first_name AS teacher_first_name, t.last_name AS teacher_last_name FROM class_types ct LEFT JOIN class_categories cc ON ct.class_category_id = cc.id LEFT JOIN teachers t ON ct.teacher_id = t.id WHERE ct.school_id = ? ORDER BY ct.created_at DESC "); $stmt->execute([$school_id]); $classes = $stmt->fetchAll(); ?>