feat(cache): implement centralized caching layer for improved performance and reduced API calls
feat(microsoft-integration): enhance inbox and events fetching with caching support feat(auth): include theme and notification settings in user data retrieval feat(profile): improve password visibility toggle functionality feat(planner): optimize event synchronization with Outlook using caching fix(notifications): update mail badge handling for mobile and desktop
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
/**
|
||||
* Centrale Caching Laag voor Fociz
|
||||
* Biedt een supersnelle database- én in-memory transiënte cache voor externe API-aanroepen (Microsoft Graph, Jira Cloud).
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/../config/database.php';
|
||||
|
||||
function ensure_app_cache_table(?PDO $db = null): void {
|
||||
static $ensured = false;
|
||||
if ($ensured) return;
|
||||
|
||||
try {
|
||||
$pdo = $db ?: get_db_connection();
|
||||
$pdo->exec("
|
||||
CREATE TABLE IF NOT EXISTS `app_cache` (
|
||||
`cache_key` VARCHAR(128) NOT NULL PRIMARY KEY,
|
||||
`cache_value` MEDIUMTEXT NOT NULL,
|
||||
`expires_at` INT UNSIGNED NOT NULL,
|
||||
INDEX `idx_app_cache_expires` (`expires_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
");
|
||||
$ensured = true;
|
||||
} catch (Throwable $e) {
|
||||
error_log("ensure_app_cache_table error: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Haalt een item op uit de cache.
|
||||
* Controleert eerst het runtime statisch geheugen, vervolgens MariaDB.
|
||||
*/
|
||||
function fociz_cache_get(string $key, $default = null) {
|
||||
static $memoryCache = [];
|
||||
|
||||
$now = time();
|
||||
|
||||
// 1. Runtime memory check (0ms)
|
||||
if (isset($memoryCache[$key])) {
|
||||
if ($memoryCache[$key]['expires_at'] > $now) {
|
||||
return $memoryCache[$key]['value'];
|
||||
}
|
||||
unset($memoryCache[$key]);
|
||||
}
|
||||
|
||||
// 2. Database check (< 0.5ms)
|
||||
try {
|
||||
$db = get_db_connection();
|
||||
ensure_app_cache_table($db);
|
||||
|
||||
$stmt = $db->prepare("SELECT cache_value, expires_at FROM app_cache WHERE cache_key = ?");
|
||||
$stmt->execute([$key]);
|
||||
$row = $stmt->fetch();
|
||||
|
||||
if ($row) {
|
||||
if ((int)$row['expires_at'] > $now) {
|
||||
$decoded = json_decode($row['cache_value'], true);
|
||||
$val = ($decoded !== null || $row['cache_value'] === 'null') ? $decoded : $row['cache_value'];
|
||||
$memoryCache[$key] = [
|
||||
'value' => $val,
|
||||
'expires_at' => (int)$row['expires_at']
|
||||
];
|
||||
return $val;
|
||||
} else {
|
||||
// Verlopen item direct opruimen
|
||||
$del = $db->prepare("DELETE FROM app_cache WHERE cache_key = ?");
|
||||
$del->execute([$key]);
|
||||
}
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
error_log("fociz_cache_get error for {$key}: " . $e->getMessage());
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Slaat een item op in de cache met een bepaalde levensduur in seconden.
|
||||
*/
|
||||
function fociz_cache_set(string $key, $value, int $ttlSeconds = 60): bool {
|
||||
static $memoryCache = [];
|
||||
|
||||
$now = time();
|
||||
$expiresAt = $now + max(1, $ttlSeconds);
|
||||
|
||||
// 1. Sla op in runtime memory
|
||||
$memoryCache[$key] = [
|
||||
'value' => $value,
|
||||
'expires_at' => $expiresAt
|
||||
];
|
||||
|
||||
// 2. Sla op in database
|
||||
try {
|
||||
$db = get_db_connection();
|
||||
ensure_app_cache_table($db);
|
||||
|
||||
$valToStore = is_string($value) ? $value : json_encode($value, JSON_UNESCAPED_UNICODE);
|
||||
|
||||
$stmt = $db->prepare("
|
||||
INSERT INTO app_cache (cache_key, cache_value, expires_at)
|
||||
VALUES (?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
cache_value = VALUES(cache_value),
|
||||
expires_at = VALUES(expires_at)
|
||||
");
|
||||
return $stmt->execute([$key, $valToStore, $expiresAt]);
|
||||
} catch (Throwable $e) {
|
||||
error_log("fociz_cache_set error for {$key}: " . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verwijdert een specifiek item uit de cache.
|
||||
*/
|
||||
function fociz_cache_delete(string $key): bool {
|
||||
try {
|
||||
$db = get_db_connection();
|
||||
ensure_app_cache_table($db);
|
||||
$stmt = $db->prepare("DELETE FROM app_cache WHERE cache_key = ?");
|
||||
return $stmt->execute([$key]);
|
||||
} catch (Throwable $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verwijdert alle items met een bepaald voorvoegsel (bijv. 'ms_events_1_')
|
||||
*/
|
||||
function fociz_cache_delete_pattern(string $prefix): bool {
|
||||
try {
|
||||
$db = get_db_connection();
|
||||
ensure_app_cache_table($db);
|
||||
$stmt = $db->prepare("DELETE FROM app_cache WHERE cache_key LIKE ?");
|
||||
return $stmt->execute([$prefix . '%']);
|
||||
} catch (Throwable $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user