From f3303bb00d8bf0a8b2939be557319231bfe16430 Mon Sep 17 00:00:00 2001 From: solocla Date: Mon, 27 Jul 2026 16:10:18 +0200 Subject: [PATCH] cancel lesson api --- public/api/cancel_lesson.php | 131 +++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 public/api/cancel_lesson.php diff --git a/public/api/cancel_lesson.php b/public/api/cancel_lesson.php new file mode 100644 index 00000000..6ee72fbc --- /dev/null +++ b/public/api/cancel_lesson.php @@ -0,0 +1,131 @@ + idbookingclass da cancellare + * + * Sicurezza: + * - Verifica che la prenotazione appartenga a $user (iduser). + * - Rispetta il limite orario option.maxbeforetimecancell (se presente). + * + * Comportamento: + * - Come delete_lesson.php della webapp, ma senza email (per ora) e con + * prepared statement + ownership check. + * -------------------------------------------------------------------------- + */ + +require_once __DIR__ . '/_bootstrap.php'; +// Da qui: $user (autenticato) e $db (PDO) disponibili. + +$userId = (int) $user->id; + +// ========================================================================== +// INPUT: accetta sia JSON body sia form POST +// ========================================================================== +$raw = file_get_contents('php://input'); +$json = json_decode($raw, true); +if (is_array($json)) { + $bookingId = (int) ($json['booking_id'] ?? 0); +} else { + $bookingId = (int) ($_POST['booking_id'] ?? 0); +} + +if ($bookingId <= 0) { + http_response_code(400); + echo json_encode(['success' => false, 'error' => 'booking_id mancante']); + exit; +} + +// ========================================================================== +// 1) Recupera la prenotazione E verifica che sia dell'utente +// ========================================================================== +$stmt = $db->prepare(" + SELECT + bc.idbookingclass, + bc.status, + ss.dateschedule, + s.servicename + FROM bookingclass bc + LEFT JOIN serviceschedule ss ON bc.idserviceschedule = ss.idserviceschedule + LEFT JOIN service s ON bc.idservice = s.idservice + WHERE bc.idbookingclass = :bid + AND bc.iduser = :uid + LIMIT 1 +"); +$stmt->execute([':bid' => $bookingId, ':uid' => $userId]); +$booking = $stmt->fetch(); + +if (!$booking) { + // Non esiste, oppure non appartiene all'utente: stessa risposta (non rivelare). + http_response_code(404); + echo json_encode(['success' => false, 'error' => 'Prenotazione non trovata']); + exit; +} + +// ========================================================================== +// 2) Controllo limite orario (option.maxbeforetimecancell), difensivo +// ========================================================================== +$maxBeforeHours = null; +try { + $optStmt = $db->query("SELECT maxbeforetimecancell FROM `option` LIMIT 1"); + $optRow = $optStmt->fetch(); + if ($optRow && isset($optRow['maxbeforetimecancell'])) { + $maxBeforeHours = (int) $optRow['maxbeforetimecancell']; + } +} catch (Throwable $e) { + // Se la tabella/colonna non c'è, non blocchiamo per questo motivo. + $maxBeforeHours = null; +} + +if ($maxBeforeHours !== null && !empty($booking['dateschedule'])) { + $now = new DateTime(); + $classTime = new DateTime($booking['dateschedule']); + + // Ore mancanti alla lezione (può essere negativo se già passata). + $diffSeconds = $classTime->getTimestamp() - $now->getTimestamp(); + $hoursToClass = $diffSeconds / 3600; + + if ($hoursToClass < $maxBeforeHours) { + http_response_code(409); + echo json_encode([ + 'success' => false, + 'error' => "Troppo tardi per cancellare (minimo {$maxBeforeHours}h prima).", + 'code' => 'too_late', + ]); + exit; + } +} + +// ========================================================================== +// 3) Cancellazione (con doppio vincolo di sicurezza nella WHERE) +// ========================================================================== +$del = $db->prepare(" + DELETE FROM bookingclass + WHERE idbookingclass = :bid + AND iduser = :uid + LIMIT 1 +"); +$del->execute([':bid' => $bookingId, ':uid' => $userId]); + +if ($del->rowCount() < 1) { + http_response_code(500); + echo json_encode(['success' => false, 'error' => 'Cancellazione non riuscita']); + exit; +} + +// ========================================================================== +// OUTPUT +// ========================================================================== +echo json_encode([ + 'success' => true, + 'booking_id' => $bookingId, + 'message' => 'Lezione cancellata', +], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);