205 lines
7.9 KiB
PHP
205 lines
7.9 KiB
PHP
<?php
|
|
require_once('include/headscript.php');
|
|
|
|
/**
|
|
* Handler salvataggio evento (insert + update). Riceve il POST di event_form.php,
|
|
* genera lo slug se mancante, valida i campi e fa redirect con ?message=.
|
|
*/
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
header('Location: events.php');
|
|
exit();
|
|
}
|
|
|
|
$pdo = DBHandlerSelect::getInstance()->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';
|
|
}
|
|
|
|
// 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, 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, 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, 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,
|
|
':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();
|
|
}
|