Files

225 lines
5.8 KiB
PHP
Executable File

<?php
/**
* MSPE Dashboard Stats API
*/
require_once 'config.php';
$method = $_SERVER['REQUEST_METHOD'];
if ($method !== 'GET') {
jsonResponse(['success' => false, 'message' => 'Method not allowed'], 405);
}
// Require authentication for stats
requireAuth();
$action = $_GET['action'] ?? 'all';
$forceRefresh = !empty($_GET['refresh']);
switch ($action) {
case 'all':
getAllStats();
break;
case 'bookings':
getBookingStats();
break;
case 'messages':
getMessageStats();
break;
case 'news':
getNewsStats();
break;
default:
getAllStats();
}
function getAllStats() {
$cacheKey = 'stats_all_v1';
if (!$GLOBALS['forceRefresh']) {
$cached = getStatsCache($cacheKey, 30);
if ($cached !== null) {
jsonResponse($cached);
}
}
$bookingStats = calculateBookingStats();
$messageStats = calculateMessageStats();
$newsStats = calculateNewsStats();
$subscriberStats = calculateSubscriberStats();
$payload = [
'success' => true,
'data' => [
'bookings' => $bookingStats,
'messages' => $messageStats,
'news' => $newsStats,
'subscribers' => $subscriberStats
]
];
setStatsCache($cacheKey, $payload);
jsonResponse($payload);
}
function calculateBookingStats() {
global $db;
$today = date('Y-m-d');
$weekStart = date('Y-m-d', strtotime('monday this week'));
$weekEnd = date('Y-m-d', strtotime('sunday this week'));
$totalBookings = $db->count('bookings');
$thisWeekCount = $db->countByDateRange('bookings', 'booking_date', $weekStart, $weekEnd);
// Last week's bookings (for trend)
$lastWeekStart = date('Y-m-d', strtotime('monday last week'));
$lastWeekEnd = date('Y-m-d', strtotime('sunday last week'));
$lastWeekCount = $db->countByDateRange('bookings', 'booking_date', $lastWeekStart, $lastWeekEnd);
$pendingCount = $db->count('bookings', ['status' => 'pending']);
$confirmedCount = $db->count('bookings', ['status' => 'confirmed']);
// JSON boolean true is compared as string "true" after JSON_UNQUOTE
$availableSlotsCount = $db->countByFieldComparison('availability_slots', 'date', '>=', $today, [
'is_available' => 'true'
]);
$confirmationRate = $totalBookings > 0 ? round(($confirmedCount / $totalBookings) * 100) : 0;
// Calculate trend percentages
$bookingTrend = $lastWeekCount > 0 ? round((($thisWeekCount - $lastWeekCount) / $lastWeekCount) * 100) : ($thisWeekCount > 0 ? 100 : 0);
return [
'this_week' => $thisWeekCount,
'pending' => $pendingCount,
'confirmed' => $confirmedCount,
'available_slots' => $availableSlotsCount,
'confirmation_rate' => $confirmationRate,
'trend' => $bookingTrend,
'total' => $totalBookings
];
}
function calculateMessageStats() {
global $db;
$total = $db->count('messages');
$unread = $db->count('messages', ['status' => 'unread']);
$weekStart = date('Y-m-d', strtotime('monday this week'));
$weekEnd = date('Y-m-d', strtotime('sunday this week'));
$thisWeek = $db->countByDateRange('messages', 'created_at', $weekStart . ' 00:00:00', $weekEnd . ' 23:59:59');
return [
'total' => $total,
'unread' => $unread,
'this_week' => $thisWeek
];
}
function calculateNewsStats() {
global $db;
return [
'total' => $db->count('news'),
'published' => $db->count('news', ['status' => 'published']),
'draft' => $db->count('news', ['status' => 'draft'])
];
}
function calculateSubscriberStats() {
global $db;
return [
'total' => $db->count('subscribers'),
'active' => $db->count('subscribers', ['status' => 'active'])
];
}
function getBookingStats() {
$cacheKey = 'stats_bookings_v1';
if (!$GLOBALS['forceRefresh']) {
$cached = getStatsCache($cacheKey, 30);
if ($cached !== null) {
jsonResponse($cached);
}
}
$payload = [
'success' => true,
'data' => calculateBookingStats()
];
setStatsCache($cacheKey, $payload);
jsonResponse($payload);
}
function getMessageStats() {
$cacheKey = 'stats_messages_v1';
if (!$GLOBALS['forceRefresh']) {
$cached = getStatsCache($cacheKey, 30);
if ($cached !== null) {
jsonResponse($cached);
}
}
$payload = [
'success' => true,
'data' => calculateMessageStats()
];
setStatsCache($cacheKey, $payload);
jsonResponse($payload);
}
function getNewsStats() {
$cacheKey = 'stats_news_v1';
if (!$GLOBALS['forceRefresh']) {
$cached = getStatsCache($cacheKey, 30);
if ($cached !== null) {
jsonResponse($cached);
}
}
$payload = [
'success' => true,
'data' => calculateNewsStats()
];
setStatsCache($cacheKey, $payload);
jsonResponse($payload);
}
function getStatsCache($cacheKey, $ttlSeconds) {
$cacheDir = DATA_DIR . 'cache/';
$cacheFile = $cacheDir . 'stats_' . md5($cacheKey) . '.json';
if (!file_exists($cacheFile)) {
return null;
}
$age = time() - (int)filemtime($cacheFile);
if ($age > (int)$ttlSeconds) {
return null;
}
$content = @file_get_contents($cacheFile);
if ($content === false || $content === '') {
return null;
}
$decoded = json_decode($content, true);
return is_array($decoded) ? $decoded : null;
}
function setStatsCache($cacheKey, $payload) {
$cacheDir = DATA_DIR . 'cache/';
if (!is_dir($cacheDir)) {
@mkdir($cacheDir, 0755, true);
}
$cacheFile = $cacheDir . 'stats_' . md5($cacheKey) . '.json';
@file_put_contents($cacheFile, json_encode($payload), LOCK_EX);
}