132 lines
4.4 KiB
PHP
132 lines
4.4 KiB
PHP
<?php
|
|
|
|
/**
|
|
* cancel_lesson.php
|
|
* --------------------------------------------------------------------------
|
|
* Cancella una prenotazione dell'utente autenticato.
|
|
*
|
|
* Posizione: public/api/cancel_lesson.php
|
|
* Metodo: POST
|
|
* Auth: Bearer token (Sanctum, gestito da _bootstrap.php)
|
|
*
|
|
* Body (JSON o form):
|
|
* - booking_id (int, richiesto) -> 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);
|