176 lines
6.0 KiB
PHP
176 lines
6.0 KiB
PHP
<?php
|
|
// public/userarea/api/my_lessons.php
|
|
// GET ?school_id=3&month=2025-12
|
|
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/_bootstrap.php'; // gives $pdo, $iduserlogin, $authUser
|
|
|
|
try {
|
|
$school_id = isset($_GET['school_id']) ? (int)$_GET['school_id'] : 0;
|
|
if ($school_id <= 0) {
|
|
http_response_code(422);
|
|
echo json_encode(['success' => false, 'message' => 'Missing required parameter: school_id']);
|
|
exit;
|
|
}
|
|
|
|
$month = $_GET['month'] ?? (new DateTimeImmutable('now', new DateTimeZone('Europe/Rome')))->format('Y-m');
|
|
if (!preg_match('/^\d{4}-\d{2}$/', (string)$month)) {
|
|
http_response_code(422);
|
|
echo json_encode(['success' => false, 'message' => 'Invalid month format. Use YYYY-MM.']);
|
|
exit;
|
|
}
|
|
|
|
$tz = new DateTimeZone('Europe/Rome');
|
|
$monthDate = DateTimeImmutable::createFromFormat('Y-m', $month, $tz) ?: new DateTimeImmutable('now', $tz);
|
|
|
|
$startOfMonth = $monthDate->format('Y-m-01'); // inclusive
|
|
$endOfMonth = $monthDate->modify('first day of next month')->format('Y-m-d'); // exclusive
|
|
$prevMonth = $monthDate->modify('-1 month')->format('Y-m');
|
|
$nextMonth = $monthDate->modify('+1 month')->format('Y-m');
|
|
|
|
// --- Authorization: user must belong to that school ---
|
|
// Adjust if your authorization logic differs.
|
|
$stmt = $pdo->prepare("
|
|
SELECT 1
|
|
FROM user_schools
|
|
WHERE user_id = ?
|
|
AND school_id = ?
|
|
AND status = 'active'
|
|
LIMIT 1
|
|
");
|
|
$stmt->execute([$iduserlogin, $school_id]);
|
|
if (!$stmt->fetchColumn()) {
|
|
http_response_code(403);
|
|
echo json_encode(['success' => false, 'message' => 'Forbidden: user not allowed for this school.']);
|
|
exit;
|
|
}
|
|
|
|
// --- School info (same as your page) ---
|
|
$stmt = $pdo->prepare("
|
|
SELECT id, name, address_street, address_city, address_province
|
|
FROM schools
|
|
WHERE id = ?
|
|
LIMIT 1
|
|
");
|
|
$stmt->execute([$school_id]);
|
|
$school = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
if (!$school) {
|
|
http_response_code(404);
|
|
echo json_encode(['success' => false, 'message' => 'School not found.']);
|
|
exit;
|
|
}
|
|
|
|
// --- Main query (ported from your PHP page) ---
|
|
$stmt = $pdo->prepare("
|
|
SELECT
|
|
sb.id as booking_id,
|
|
sb.status,
|
|
sb.order_id,
|
|
cs.id as session_id,
|
|
cs.session_date,
|
|
cs.start_time,
|
|
cs.end_time,
|
|
cs.room_name,
|
|
c.name as class_name,
|
|
ct.level,
|
|
o.available_entries,
|
|
o.available_recoveries
|
|
FROM session_bookings sb
|
|
JOIN class_sessions cs ON sb.session_id = cs.id
|
|
JOIN class_types ct ON cs.class_type_id = ct.id
|
|
JOIN classes c ON ct.class_id = c.id
|
|
JOIN orders o ON sb.order_id = o.id
|
|
WHERE sb.user_id = ?
|
|
AND cs.school_id = ?
|
|
AND cs.session_date >= ?
|
|
AND cs.session_date < ?
|
|
ORDER BY cs.session_date ASC, cs.start_time ASC
|
|
");
|
|
$stmt->execute([$iduserlogin, $school_id, $startOfMonth, $endOfMonth]);
|
|
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
// Better 24h rule: compare against actual lesson start datetime
|
|
$now = new DateTimeImmutable('now', $tz);
|
|
$limit = $now->modify('+24 hours');
|
|
|
|
$lessons = [];
|
|
foreach ($rows as $r) {
|
|
$startDt = DateTimeImmutable::createFromFormat(
|
|
'Y-m-d H:i:s',
|
|
$r['session_date'] . ' ' . $r['start_time'],
|
|
$tz
|
|
);
|
|
|
|
if (!$startDt) {
|
|
// fallback if start_time is H:i
|
|
$startDt = DateTimeImmutable::createFromFormat(
|
|
'Y-m-d H:i',
|
|
$r['session_date'] . ' ' . substr((string)$r['start_time'], 0, 5),
|
|
$tz
|
|
);
|
|
}
|
|
|
|
$canModify = false;
|
|
if ($r['status'] === 'booked' && $startDt instanceof DateTimeImmutable) {
|
|
$canModify = ($startDt > $limit);
|
|
}
|
|
|
|
$lessons[] = [
|
|
'booking_id' => (int)$r['booking_id'],
|
|
'status' => (string)$r['status'],
|
|
'order_id' => (int)$r['order_id'],
|
|
|
|
'session' => [
|
|
'session_id' => (int)$r['session_id'],
|
|
'date' => (string)$r['session_date'],
|
|
'start_time' => (string)$r['start_time'],
|
|
'end_time' => (string)$r['end_time'],
|
|
'room_name' => $r['room_name'] !== null ? (string)$r['room_name'] : null,
|
|
'start_datetime_iso' => $startDt ? $startDt->format(DateTimeInterface::ATOM) : null,
|
|
],
|
|
|
|
'class' => [
|
|
'name' => (string)$r['class_name'],
|
|
'level' => ($r['level'] ?? null) ? (string)$r['level'] : null,
|
|
],
|
|
|
|
'wallet' => [
|
|
'available_entries' => (int)($r['available_entries'] ?? 0),
|
|
'available_recoveries' => (int)($r['available_recoveries'] ?? 0),
|
|
],
|
|
|
|
'can_reschedule' => $canModify,
|
|
'can_cancel' => $canModify,
|
|
'can_modify' => $canModify,
|
|
];
|
|
}
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'month' => $monthDate->format('Y-m'),
|
|
'prev_month' => $prevMonth,
|
|
'next_month' => $nextMonth,
|
|
'school' => [
|
|
'id' => (int)$school['id'],
|
|
'name' => (string)$school['name'],
|
|
'address_street' => $school['address_street'] ?? null,
|
|
'address_city' => $school['address_city'] ?? null,
|
|
'address_province' => $school['address_province'] ?? null,
|
|
'address_full' => trim(
|
|
($school['address_street'] ?? '') . ', ' .
|
|
($school['address_city'] ?? '') . ' ' .
|
|
($school['address_province'] ?? '')
|
|
),
|
|
],
|
|
'lessons' => $lessons
|
|
], JSON_UNESCAPED_UNICODE);
|
|
} catch (Throwable $e) {
|
|
http_response_code(500);
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => 'Server error.',
|
|
'error' => $e->getMessage()
|
|
]);
|
|
}
|