cancel lesson api
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
<?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);
|
||||
Reference in New Issue
Block a user