From c9a0cc6034538e6c6c805dba1f01e1d467b03dae Mon Sep 17 00:00:00 2001 From: solocla Date: Fri, 18 Sep 2026 10:13:36 +0200 Subject: [PATCH] fixed cancel 2 --- public/apiwp/cancel.php | 295 ++------------------------------------- public/apiwp/confirm.php | 8 +- 2 files changed, 14 insertions(+), 289 deletions(-) diff --git a/public/apiwp/cancel.php b/public/apiwp/cancel.php index af56c02..c48fd3c 100644 --- a/public/apiwp/cancel.php +++ b/public/apiwp/cancel.php @@ -27,6 +27,7 @@ if ($token !== '') { $state = 'form'; // form | notfound | already | toolate | done $promotedCount = 0; $didCancel = false; +$promoted = []; if (!$booking) { $state = 'notfound'; @@ -46,28 +47,34 @@ if (!$booking) { $fresh = $bl->fetch(PDO::FETCH_ASSOC); if ($fresh && $fresh['status'] !== 'cancelled') { - $wasOccupying = in_array($fresh['status'], ['confirmed', 'pending'], true); + $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); - // 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) + // 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); + 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()); @@ -273,284 +280,4 @@ if (!function_exists('e')) { - 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.

- -
- - \ No newline at end of file diff --git a/public/apiwp/confirm.php b/public/apiwp/confirm.php index 7bbb995..bf0d467 100644 --- a/public/apiwp/confirm.php +++ b/public/apiwp/confirm.php @@ -59,11 +59,9 @@ if (!$booking) { } } -if (!function_exists('e')) { - function e($v): string - { - return htmlspecialchars((string) $v, ENT_QUOTES, 'UTF-8'); - } +function e($v): string +{ + return htmlspecialchars((string) $v, ENT_QUOTES, 'UTF-8'); } ?>