mostra pagina di conferma (NON annulla: * evita che gli scanner email prefetchino il link e annullino da soli) * POST (token + confirm=1) -> annulla e, se la prenotazione occupava posti, * promuove automaticamente la prima in lista d'attesa. */ $pdo = pdo_conn(); $token = trim($_POST['token'] ?? $_GET['token'] ?? ''); $isPost = ($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST'; $booking = null; if ($token !== '') { $q = $pdo->prepare("SELECT b.*, e.title AS ev_title, e.starts_at AS ev_starts, e.id AS eid FROM event_bookings b JOIN events e ON e.id = b.event_id WHERE b.token = ?"); $q->execute([$token]); $booking = $q->fetch(PDO::FETCH_ASSOC); } $state = 'form'; // form | notfound | already | toolate | done $promotedCount = 0; $didCancel = false; if (!$booking) { $state = 'notfound'; } elseif ($booking['status'] === 'cancelled') { $state = 'already'; } elseif (strtotime($booking['ev_starts']) <= time()) { $state = 'toolate'; } elseif ($isPost && !empty($_POST['confirm'])) { try { $pdo->beginTransaction(); // Lock evento per serializzare con eventuali prenotazioni concorrenti $pdo->prepare("SELECT id FROM events WHERE id = ? FOR UPDATE")->execute([(int) $booking['eid']]); // Rileggo lo stato aggiornato della prenotazione $bl = $pdo->prepare("SELECT * FROM event_bookings WHERE id = ?"); $bl->execute([(int) $booking['id']]); $fresh = $bl->fetch(PDO::FETCH_ASSOC); if ($fresh && $fresh['status'] !== 'cancelled') { $wasOccupying = in_array($fresh['status'], ['confirmed', 'pending'], true); $pdo->prepare("UPDATE event_bookings SET status = 'cancelled', updated_at = NOW() WHERE id = ?") ->execute([(int) $fresh['id']]); if ($wasOccupying) { $promoted = promoteFromWaitlist($pdo, (int) $booking['eid']); $promotedCount = count($promoted); // Nota: l'email di promozione (E, con riconferma) si attiva nel secondo tempo. } $didCancel = true; } $pdo->commit(); $state = 'done'; // Email di conferma disdetta all'utente (best-effort) if ($didCancel) { try { $evStmt = pdo_conn()->prepare("SELECT * FROM events WHERE id = ?"); $evStmt->execute([(int) $booking['eid']]); $evRow = $evStmt->fetch(PDO::FETCH_ASSOC); if ($evRow) { yse_mail_user_cancel($booking, $evRow); } } catch (Throwable $mailEx) { error_log('[cancel mail] ' . $mailEx->getMessage()); } } } catch (Throwable $ex) { if ($pdo->inTransaction()) { $pdo->rollBack(); } error_log('[apiwp/cancel] ' . $ex->getMessage()); $state = 'error'; } } if (!function_exists('e')) { function e($v): string { return htmlspecialchars((string) $v, ENT_QUOTES, 'UTF-8'); } } ?> Disdetta prenotazione — YogaSoul
✕

Link non valido

Questa prenotazione non esiste o il link è errato.

✓

Già annullata

Questa prenotazione risulta già annullata.

⏱

Non più annullabile

L'evento è già iniziato: non è più possibile annullare online. Contattaci per assistenza.

!

Si è verificato un errore

Riprova tra poco. Se il problema persiste, contattaci.

✓

Prenotazione annullata

La tua prenotazione per è stata annullata.

0) : ?>

Un posto è stato assegnato alla prima persona in lista d'attesa.

?

Annullare la prenotazione?

· post

Confermi di voler annullare la prenotazione a nome di ?

Se hai cambiato idea, chiudi pure questa pagina.

mostra pagina di conferma (NON annulla: * evita che gli scanner email prefetchino il link e annullino da soli) * POST (token + confirm=1) -> annulla e, se la prenotazione occupava posti, * promuove automaticamente la prima in lista d'attesa. */ $pdo = pdo_conn(); $token = trim($_POST['token'] ?? $_GET['token'] ?? ''); $isPost = ($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST'; $booking = null; if ($token !== '') { $q = $pdo->prepare("SELECT b.*, e.title AS ev_title, e.starts_at AS ev_starts, e.id AS eid FROM event_bookings b JOIN events e ON e.id = b.event_id WHERE b.token = ?"); $q->execute([$token]); $booking = $q->fetch(PDO::FETCH_ASSOC); } $state = 'form'; // form | notfound | already | toolate | done $promotedCount = 0; $didCancel = false; $promoted = []; if (!$booking) { $state = 'notfound'; } elseif ($booking['status'] === 'cancelled') { $state = 'already'; } elseif (strtotime($booking['ev_starts']) <= time()) { $state = 'toolate'; } elseif ($isPost && !empty($_POST['confirm'])) { try { $pdo->beginTransaction(); // Lock evento per serializzare con eventuali prenotazioni concorrenti $pdo->prepare("SELECT id FROM events WHERE id = ? FOR UPDATE")->execute([(int) $booking['eid']]); // Rileggo lo stato aggiornato della prenotazione $bl = $pdo->prepare("SELECT * FROM event_bookings WHERE id = ?"); $bl->execute([(int) $booking['id']]); $fresh = $bl->fetch(PDO::FETCH_ASSOC); if ($fresh && $fresh['status'] !== 'cancelled') { $wasOccupying = in_array($fresh['status'], ['confirmed', 'pending', 'offered'], true); $pdo->prepare("UPDATE event_bookings SET status = 'cancelled', updated_at = NOW() WHERE id = ?") ->execute([(int) $fresh['id']]); if ($wasOccupying) { $promoted = promoteFromWaitlist($pdo, (int) $booking['eid']); $promotedCount = count($promoted); } $didCancel = true; } $pdo->commit(); $state = 'done'; // Email dopo il commit (best-effort) if ($didCancel) { try { $evStmt = pdo_conn()->prepare("SELECT * FROM events WHERE id = ?"); $evStmt->execute([(int) $booking['eid']]); $evRow = $evStmt->fetch(PDO::FETCH_ASSOC); if ($evRow) { yse_mail_user_cancel($booking, $evRow); // B: conferma disdetta foreach ($promoted as $pr) { // E: promozione con riconferma try { yse_mail_promotion($pr, $evRow); } catch (Throwable $pe) { error_log('[promo mail] ' . $pe->getMessage()); } } } } catch (Throwable $mailEx) { error_log('[cancel mail] ' . $mailEx->getMessage()); } } } catch (Throwable $ex) { if ($pdo->inTransaction()) { $pdo->rollBack(); } error_log('[apiwp/cancel] ' . $ex->getMessage()); $state = 'error'; } } function e($v): string { return htmlspecialchars((string) $v, ENT_QUOTES, 'UTF-8'); } ?> Disdetta prenotazione — YogaSoul
✕

Link non valido

Questa prenotazione non esiste o il link è errato.

✓

Già annullata

Questa prenotazione risulta già annullata.

⏱

Non più annullabile

L'evento è già iniziato: non è più possibile annullare online. Contattaci per assistenza.

!

Si è verificato un errore

Riprova tra poco. Se il problema persiste, contattaci.

✓

Prenotazione annullata

La tua prenotazione per è stata annullata.

0) : ?>

Un posto è stato assegnato alla prima persona in lista d'attesa.

?

Annullare la prenotazione?

· post

Confermi di voler annullare la prenotazione a nome di ?

Se hai cambiato idea, chiudi pure questa pagina.