getConnection(); // --- ID insegnante loggato ------------------------------------------------- // headscript.php popola $iduserlogin da Auth::user()->present()->id $currentUserId = $iduserlogin ?? ($_SESSION['iduserlogin'] ?? null); // --- Helper ---------------------------------------------------------------- function slugify(string $text): string { $text = trim($text); if (function_exists('iconv')) { $conv = @iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $text); if ($conv !== false) { $text = $conv; } } $text = strtolower($text); $text = preg_replace('/[^a-z0-9]+/', '-', $text); $text = trim($text, '-'); return $text !== '' ? $text : 'evento'; } function uniqueSlug(PDO $pdo, string $base, int $excludeId): string { $slug = $base; $i = 2; while (true) { if ($excludeId > 0) { $st = $pdo->prepare("SELECT COUNT(*) FROM events WHERE slug = ? AND id <> ?"); $st->execute([$slug, $excludeId]); } else { $st = $pdo->prepare("SELECT COUNT(*) FROM events WHERE slug = ?"); $st->execute([$slug]); } if ((int) $st->fetchColumn() === 0) { return $slug; } $slug = $base . '-' . $i; $i++; } } function toDateTime(?string $v): ?string { if (!$v) { return null; } $v = str_replace('T', ' ', $v); $ts = strtotime($v); return $ts ? date('Y-m-d H:i:s', $ts) : null; } // --- Lettura e validazione input ------------------------------------------- $id = isset($_POST['id']) ? (int) $_POST['id'] : 0; $title = trim($_POST['title'] ?? ''); $startsAt = toDateTime($_POST['starts_at'] ?? null); $maxSeats = (int) ($_POST['max_seats'] ?? 0); $redirectOnError = $id > 0 ? "event_form.php?id={$id}&message=error" : "event_form.php?message=error"; if ($title === '' || $startsAt === null || $maxSeats < 1) { header("Location: {$redirectOnError}"); exit(); } $slugInput = trim($_POST['slug'] ?? ''); $slugBase = slugify($slugInput !== '' ? $slugInput : $title); $slug = uniqueSlug($pdo, $slugBase, $id); $endsAt = toDateTime($_POST['ends_at'] ?? null); $address = trim($_POST['address'] ?? ''); $organizer = trim($_POST['organizer_name'] ?? ''); $description = $_POST['description'] ?? ''; $cost = round((float) ($_POST['cost'] ?? 0), 2); $maxPerBooking = max(1, (int) ($_POST['max_per_booking'] ?? 1)); $coverImage = trim($_POST['cover_image'] ?? ''); $lat = ($_POST['lat'] ?? '') !== '' ? (float) $_POST['lat'] : null; $lng = ($_POST['lng'] ?? '') !== '' ? (float) $_POST['lng'] : null; $currency = strtoupper(trim($_POST['currency'] ?? 'EUR')); if (!in_array($currency, ['EUR', 'USD', 'GBP', 'CHF'], true)) { $currency = 'EUR'; } $color = trim($_POST['color'] ?? '#4CAF50'); if (!preg_match('/^#[0-9a-fA-F]{6}$/', $color)) { $color = '#4CAF50'; } $status = $_POST['status'] ?? 'draft'; if (!in_array($status, ['draft', 'published', 'cancelled'], true)) { $status = 'draft'; } // Apertura programmata: se attiva con data futura -> stato 'scheduled' + publish_at $scheduleEnabled = isset($_POST['schedule_enabled']) && $_POST['schedule_enabled'] === 'Y'; $publishAt = toDateTime($_POST['publish_at'] ?? null); if ($scheduleEnabled && $publishAt && strtotime($publishAt) > time()) { $status = 'scheduled'; } else { $publishAt = null; // niente programmazione (o data giĆ  passata) } // Campi facoltativi (testo) $instructions = trim($_POST['instructions'] ?? ''); $whatToBring = trim($_POST['what_to_bring'] ?? ''); $suitableFor = trim($_POST['suitable_for'] ?? ''); $waitlistEnabled = (isset($_POST['waitlist_enabled']) && $_POST['waitlist_enabled'] === 'Y') ? 'Y' : 'N'; // Override per-evento (NULL = usa default scuola) $reminderEnabled = (isset($_POST['reminder_enabled']) && in_array($_POST['reminder_enabled'], ['Y', 'N'], true)) ? $_POST['reminder_enabled'] : null; $reminderHours = (($_POST['reminder_hours'] ?? '') !== '') ? max(1, min(168, (int) $_POST['reminder_hours'])) : null; $offerHours = (($_POST['offer_expiry_hours'] ?? '') !== '') ? max(1, min(336, (int) $_POST['offer_expiry_hours'])) : null; // Galleria: array JSON di path -> validazione e re-encode pulito $gallery = null; $galleryRaw = $_POST['gallery'] ?? ''; if ($galleryRaw !== '') { $decoded = json_decode($galleryRaw, true); if (is_array($decoded)) { $clean = []; foreach ($decoded as $p) { if (is_string($p) && $p !== '') { $clean[] = $p; } } $gallery = !empty($clean) ? json_encode(array_values($clean), JSON_UNESCAPED_SLASHES) : null; } } // --- Insert / Update ------------------------------------------------------- try { if ($id > 0) { $sql = "UPDATE events SET title = :title, slug = :slug, description = :description, instructions = :instructions, what_to_bring = :what_to_bring, suitable_for = :suitable_for, organizer_name = :organizer_name, starts_at = :starts_at, ends_at = :ends_at, address = :address, lat = :lat, lng = :lng, cost = :cost, currency = :currency, max_seats = :max_seats, max_per_booking = :max_per_booking, color = :color, waitlist_enabled = :waitlist_enabled, reminder_enabled = :reminder_enabled, reminder_hours = :reminder_hours, offer_expiry_hours = :offer_expiry_hours, cover_image = :cover_image, gallery = :gallery, status = :status, publish_at = :publish_at, updated_at = NOW() WHERE id = :id"; $params = [':id' => $id]; } else { $sql = "INSERT INTO events (user_id, title, slug, description, instructions, what_to_bring, suitable_for, organizer_name, starts_at, ends_at, address, lat, lng, cost, currency, max_seats, max_per_booking, color, waitlist_enabled, reminder_enabled, reminder_hours, offer_expiry_hours, cover_image, gallery, status, publish_at, created_at, updated_at) VALUES (:user_id, :title, :slug, :description, :instructions, :what_to_bring, :suitable_for, :organizer_name, :starts_at, :ends_at, :address, :lat, :lng, :cost, :currency, :max_seats, :max_per_booking, :color, :waitlist_enabled, :reminder_enabled, :reminder_hours, :offer_expiry_hours, :cover_image, :gallery, :status, :publish_at, NOW(), NOW())"; $params = [':user_id' => $currentUserId]; } $params += [ ':title' => $title, ':slug' => $slug, ':description' => $description !== '' ? $description : null, ':instructions' => $instructions !== '' ? $instructions : null, ':what_to_bring' => $whatToBring !== '' ? $whatToBring : null, ':suitable_for' => $suitableFor !== '' ? $suitableFor : null, ':organizer_name' => $organizer !== '' ? $organizer : null, ':starts_at' => $startsAt, ':ends_at' => $endsAt, ':address' => $address !== '' ? $address : null, ':lat' => $lat, ':lng' => $lng, ':cost' => $cost, ':currency' => $currency, ':max_seats' => $maxSeats, ':max_per_booking' => $maxPerBooking, ':waitlist_enabled' => $waitlistEnabled, ':reminder_enabled' => $reminderEnabled, ':reminder_hours' => $reminderHours, ':offer_expiry_hours' => $offerHours, ':color' => $color, ':cover_image' => $coverImage !== '' ? $coverImage : null, ':gallery' => $gallery, ':publish_at' => $publishAt, ':status' => $status, ]; $stmt = $pdo->prepare($sql); $stmt->execute($params); header('Location: events.php?message=success'); exit(); } catch (Throwable $ex) { error_log('[event_save] ' . $ex->getMessage()); header("Location: {$redirectOnError}"); exit(); }