Files
yogibook_aury_new/public/delete_lesson.php
T
2026-10-14 15:56:09 +02:00

281 lines
9.5 KiB
PHP

<?php
require_once('Connections/bkngstm.php');
require_once('webassist/mysqli/rsobj.php');
include('include/headscript.php'); // $iduserlogin
/***********************
* LOG (mail + debug)
***********************/
$logDir = __DIR__ . '/logs';
if (!is_dir($logDir)) {
@mkdir($logDir, 0755, true);
}
$mailLogFile = $logDir . '/mail_cancel.log';
function mail_log($file, $msg)
{
@file_put_contents($file, "[" . date("Y-m-d H:i:s") . "] " . $msg . PHP_EOL, FILE_APPEND);
}
/***********************
* INPUT
***********************/
if (!isset($_GET['id'])) {
die("ID non fornito.");
}
$id = (int)$_GET['id'];
$userId = (int)$iduserlogin;
/***********************
* DB
***********************/
$conn = $bkngstm;
/***********************
* 1) USER INFO (auth_users)
***********************/
$stmt = $conn->prepare("SELECT email, first_name, last_name FROM auth_users WHERE id = ? LIMIT 1");
$stmt->bind_param("i", $userId);
$stmt->execute();
$res = $stmt->get_result();
$u = $res->fetch_assoc();
$stmt->close();
$userEmail = $u['email'] ?? '';
$userName = trim(($u['first_name'] ?? '') . ' ' . ($u['last_name'] ?? ''));
/***********************
* 2) BOOKING INFO (nome classe + data) + ownership check
***********************/
$stmt = $conn->prepare("
SELECT
bc.idbookingclass,
bc.idorder,
bc.status,
bc.bookingstart,
s.servicename,
ss.dateschedule
FROM bookingclass bc
LEFT JOIN service s ON bc.idservice = s.idservice
LEFT JOIN serviceschedule ss ON bc.idserviceschedule = ss.idserviceschedule
WHERE bc.idbookingclass = ? AND bc.iduser = ?
LIMIT 1
");
$stmt->bind_param("ii", $id, $userId);
$stmt->execute();
$res = $stmt->get_result();
$bk = $res->fetch_assoc();
$stmt->close();
if (!$bk) {
header("Location: userpanel.php?deleted=0&err=notfound");
exit();
}
$className = $bk['servicename'] ?? 'Lezione';
$classDateRaw = $bk['dateschedule'] ?? null;
$classDateTxt = $classDateRaw ? date("d-m-Y H:i", strtotime($classDateRaw)) : 'N/D';
$cancelDateTxt = date("d-m-Y H:i");
/***********************
* 3) CONTROLLI (stesse regole di userpanel.php)
***********************/
// Solo prenotazioni confermate: pending e lista d'attesa hanno i loro percorsi
if (($bk['status'] ?? '') !== 'booked') {
header("Location: userpanel.php?deleted=0&err=status");
exit();
}
// Finestra oraria
$classTime = new DateTime($classDateRaw ?: $bk['bookingstart']);
$currentTime = new DateTime();
// Lezione già iniziata o passata: non si cancella
if ($classTime <= $currentTime) {
header("Location: userpanel.php?deleted=0&err=window");
exit();
}
// Lezione di oggi: fino alle 17:00 entro le 00:01, dopo le 17:00 entro le 12:00
if ($classTime->format('Y-m-d') === $currentTime->format('Y-m-d')) {
$classHour = (int) $classTime->format('H');
$classMinute = (int) $classTime->format('i');
$isBefore1700 = ($classHour < 17) || ($classHour === 17 && $classMinute === 0);
$deadline = new DateTime($classTime->format($isBefore1700 ? 'Y-m-d 00:01:00' : 'Y-m-d 12:00:00'));
if ($currentTime > $deadline) {
header("Location: userpanel.php?deleted=0&err=window");
exit();
}
}
/***********************
* 3b) STORICO + RIPROGRAMMAZIONE + CANCELLAZIONE
* Tutto in una transazione: o riesce tutto o niente.
***********************/
$idOrder = $bk['idorder'] !== null ? (int) $bk['idorder'] : null;
$ord = null;
$incremented = 'N';
$ticketLost = false;
try {
$conn->begin_transaction();
// Limite riprogrammazioni (stessa regola del pulsante Riprogramma).
// FOR UPDATE: blocca la riga dell'ordine contro doppi click.
if ($idOrder !== null) {
$stmt = $conn->prepare("SELECT reprogrammed, maxreschedule FROM orderbook WHERE idorderbook = ? FOR UPDATE");
$stmt->bind_param("i", $idOrder);
$stmt->execute();
$ord = $stmt->get_result()->fetch_assoc();
$stmt->close();
if ($ord) {
if ((int) $ord['reprogrammed'] >= (int) $ord['maxreschedule']) {
// Limite raggiunto: può cancellare (libera il posto) ma il ticket va perso
$ticketLost = true;
} else {
$incremented = 'Y';
}
}
}
// Copia nello storico (prima di eliminare)
$stmt = $conn->prepare("
INSERT INTO bookingclass_cancellations
(idbookingclass, idserviceschedule, bookingstart, status, idservice, iduser, idorder,
prevbookingstart, is_reprogrammed, is_gift, booking_created_at,
cancelled_at, cancelled_by, reprogrammed_incremented)
SELECT idbookingclass, idserviceschedule, bookingstart, status, idservice, iduser, idorder,
prevbookingstart, is_reprogrammed, is_gift, created_at,
NOW(), ?, ?
FROM bookingclass
WHERE idbookingclass = ? AND iduser = ?
");
$storicoFlag = $ticketLost ? 'L' : $incremented;
$stmt->bind_param("isii", $userId, $storicoFlag, $id, $userId);
$stmt->execute();
$copied = $stmt->affected_rows;
$stmt->close();
if ($copied !== 1) {
throw new RuntimeException('notfound');
}
// La cancellazione conta come una riprogrammazione
if ($incremented === 'Y') {
$stmt = $conn->prepare("UPDATE orderbook SET reprogrammed = reprogrammed + 1 WHERE idorderbook = ?");
$stmt->bind_param("i", $idOrder);
$stmt->execute();
$stmt->close();
}
// Limite raggiunto: la prenotazione resta come persa (status 'lost'),
// il posto in sala si libera ma il ticket non torna da programmare.
// Altrimenti eliminazione normale: il ticket torna disponibile.
if ($ticketLost) {
$stmt = $conn->prepare("UPDATE bookingclass SET status = 'lost', lostlesson = 'Y' WHERE idbookingclass = ? AND iduser = ?");
} else {
$stmt = $conn->prepare("DELETE FROM bookingclass WHERE idbookingclass = ? AND iduser = ?");
}
$stmt->bind_param("ii", $id, $userId);
$stmt->execute();
$deleted = $stmt->affected_rows;
$stmt->close();
if ($deleted !== 1) {
throw new RuntimeException('notfound');
}
$conn->commit();
} catch (Throwable $e) {
try {
$conn->rollback();
} catch (Throwable $ignored) {
}
$code = in_array($e->getMessage(), ['limit', 'notfound'], true) ? $e->getMessage() : 'db';
if ($code === 'db') {
error_log("delete_lesson #{$id} utente #{$userId}: " . $e->getMessage());
}
header("Location: userpanel.php?deleted=0&err=" . $code);
exit();
}
// Connessione $bkngstm gestita globalmente: non la chiudiamo qui
/***********************
* 4) EMAIL (TO utente + CC info@yogasoul.it)
* Usa le chiavi del tuo .env: MAIL_HOST, MAIL_PORT, MAIL_USERNAME, ...
***********************/
try {
// Carica vendor/autoload + dotenv (il tuo file esistente)
require_once(__DIR__ . '/class/mailer.php');
$mail = new \PHPMailer\PHPMailer\PHPMailer(true);
// Legge le variabili in stile Laravel (con trim per eventuali virgolette)
$host = trim($_ENV['MAIL_HOST'] ?? 'mail.yogasoul.it', "\" \t\n\r\0\x0B");
$port = (int)($_ENV['MAIL_PORT'] ?? 465);
$user = $_ENV['MAIL_USERNAME'] ?? '';
$pass = $_ENV['MAIL_PASSWORD'] ?? '';
$enc = strtolower(trim($_ENV['MAIL_ENCRYPTION'] ?? 'ssl', "\" \t\n\r\0\x0B"));
$fromEmail = trim($_ENV['MAIL_FROM_ADDRESS'] ?? 'info@yogasoul.it', "\" \t\n\r\0\x0B");
$fromName = trim($_ENV['MAIL_FROM_NAME'] ?? 'YogiBook', "\" \t\n\r\0\x0B");
// Config SMTP
$mail->isSMTP();
$mail->Host = $host;
$mail->SMTPAuth = true;
$mail->Username = $user;
$mail->Password = $pass;
$mail->Port = $port;
if (in_array($enc, ['tls', 'ssl'], true)) {
$mail->SMTPSecure = $enc;
}
// Timeout (utile su SMTP hosting)
$mail->Timeout = 20;
$mail->setFrom($fromEmail, $fromName);
$mail->CharSet = 'UTF-8';
$mail->isHTML(true);
// Destinatari
if (!empty($userEmail)) {
$mail->addAddress($userEmail, $userName ?: '');
}
$mail->addCC('info@yogasoul.it');
// Log impostazioni usate (senza password)
mail_log($mailLogFile, "SMTP in uso host={$host} porta={$port} enc={$enc} user={$user}");
// Contenuto (ITALIANO)
$mail->Subject = "Lezione cancellata - {$className}";
$mail->Body = "
<div style='font-family:Arial,sans-serif;font-size:14px;color:#222'>
<p>Ciao " . htmlspecialchars($userName ?: 'Yogi') . ",</p>
<p>La tua lezione è stata <b>cancellata</b>.</p>" . ($ticketLost ? "
<p>Avendo già usato tutte le riprogrammazioni del pacchetto, questa lezione non potrà essere recuperata.</p>" : "") . "
<p>
<b>Lezione:</b> " . htmlspecialchars($className) . "<br>
<b>Data/ora prevista:</b> " . htmlspecialchars($classDateTxt) . "<br>
<b>Data/ora cancellazione:</b> " . htmlspecialchars($cancelDateTxt) . "<br>
<b>ID prenotazione:</b> #{$id}
</p>
<p>Grazie,<br>— " . htmlspecialchars($fromName) . "</p>
</div>
";
$mail->send();
mail_log($mailLogFile, "OK inviata. booking_id={$id} user_id={$userId} to={$userEmail} lezione='" . $className . "' prevista='{$classDateTxt}' cancellata='{$cancelDateTxt}'");
} catch (Throwable $e) {
mail_log($mailLogFile, "ERRORE invio. booking_id={$id} user_id={$userId} to={$userEmail} :: " . $e->getMessage());
error_log("Mailer error (delete booking #{$id}, user #{$userId}): " . $e->getMessage());
}
// Redirect
header("Location: userpanel.php?deleted=" . ($ticketLost ? 'lost' : '1'));
exit();