From bb71da081b53c0487721140bf26b55ffdbf793cb Mon Sep 17 00:00:00 2001 From: isUnknown Date: Thu, 15 Jan 2026 11:42:20 +0100 Subject: [PATCH] =?UTF-8?q?Ajout=20du=20syst=C3=A8me=20de=20cache=20pour?= =?UTF-8?q?=20les=20notifications?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problème : Les notifications étaient collectées à chaque requête sur projects.json, causant des problèmes de performance et de mémoire. Solution : Mise en cache des notifications par projet et par utilisateur - Nouvelle méthode getNotificationsLight() dans ProjectPage avec cache - Cache invalidé automatiquement via les hooks existants (page/file update) - Cache par utilisateur pour inclure le isRead spécifique Performance : Les notifications sont calculées une fois puis servies depuis le cache jusqu'à ce qu'un changement survienne (commentaire, brief, etc.) Co-Authored-By: Claude Sonnet 4.5 --- ...update--regenerate-project-steps-cache.php | 6 ++- public/site/models/project.php | 54 +++++++++++++++++-- public/site/templates/projects.json.php | 22 ++++---- 3 files changed, 62 insertions(+), 20 deletions(-) diff --git a/public/site/config/hooks/page-update--regenerate-project-steps-cache.php b/public/site/config/hooks/page-update--regenerate-project-steps-cache.php index bde728d..f8d9675 100644 --- a/public/site/config/hooks/page-update--regenerate-project-steps-cache.php +++ b/public/site/config/hooks/page-update--regenerate-project-steps-cache.php @@ -1,9 +1,11 @@ template() == 'project' ? $newPage : $newPage->parents()->findBy('template', 'project'); if ($project) { - $steps = $project->rebuildStepsCache(); + $project->rebuildStepsCache(); + // Invalider aussi le cache des notifications (briefs validés, etc.) + $project->invalidateNotificationsCache(); } }; \ No newline at end of file diff --git a/public/site/models/project.php b/public/site/models/project.php index 1152945..583bfeb 100644 --- a/public/site/models/project.php +++ b/public/site/models/project.php @@ -3,18 +3,62 @@ use adrienpayet\notifications\NotificationsPage; class ProjectPage extends NotificationsPage { - public function getSteps() { + public function getSteps() { $apiCache = kirby()->cache('api'); - $stepsData = $apiCache?->get($this->slug() . '_' . 'steps'); - + $stepsData = $apiCache?->get($this->slug() . '_' . 'steps'); + if ($stepsData === null || count($stepsData) === 0) { $this->rebuildStepsCache(); }; - - $stepsData = $apiCache->get($this->slug() . '_' . 'steps'); + + $stepsData = $apiCache->get($this->slug() . '_' . 'steps'); return $stepsData; } + + /** + * Récupère les notifications pour ce projet (version allégée avec cache). + * Cache par utilisateur pour inclure le isRead. + */ + public function getNotificationsLight($user) { + if (!$user) { + return []; + } + + $apiCache = kirby()->cache('api'); + $cacheKey = $this->slug() . '_notifications_' . $user->uuid(); + $notifications = $apiCache?->get($cacheKey); + + // Si pas en cache, collecter et cacher + if ($notifications === null) { + $collector = kirby()->option('adrienpayet.pdc-notifications.collector'); + if (!$collector) { + return []; + } + + try { + $notifications = $collector->collectLight($this, $user); + $apiCache->set($cacheKey, $notifications); + } catch (\Throwable $e) { + error_log("Error caching notifications for {$this->slug()}: " . $e->getMessage()); + return []; + } + } + + return $notifications; + } + + /** + * Invalide le cache des notifications de ce projet pour tous les utilisateurs. + */ + public function invalidateNotificationsCache() { + $apiCache = kirby()->cache('api'); + // Invalider pour tous les users + foreach (kirby()->users() as $user) { + $cacheKey = $this->slug() . '_notifications_' . $user->uuid(); + $apiCache->remove($cacheKey); + } + } public function rebuildStepsCache() { // Create steps diff --git a/public/site/templates/projects.json.php b/public/site/templates/projects.json.php index 222e86a..2b2eaad 100644 --- a/public/site/templates/projects.json.php +++ b/public/site/templates/projects.json.php @@ -7,17 +7,15 @@ if (!$kirby->user()) { ]); } -function getProjectData($project, $user, $collector) +function getProjectData($project, $user) { - // Utiliser collectLight() pour économiser la mémoire (seulement id, type, isRead, date) + // Utiliser getNotificationsLight() avec cache pour optimiser les performances $notifications = []; - if ($collector) { - try { - $notifications = $collector->collectLight($project, $user); - } catch (\Throwable $e) { - error_log("Error collecting light notifications for project {$project->uri()}: " . $e->getMessage()); - $notifications = []; - } + try { + $notifications = $project->getNotificationsLight($user); + } catch (\Throwable $e) { + error_log("Error getting notifications for project {$project->uri()}: " . $e->getMessage()); + $notifications = []; } $data = [ @@ -43,14 +41,12 @@ function getProjectData($project, $user, $collector) return $data; } -// Récupérer le collector de notifications -$notificationCollector = $kirby->option('adrienpayet.pdc-notifications.collector'); $currentUser = $kirby->user(); try { $children = $currentUser->role() == 'admin' - ? $page->childrenAndDrafts()->map(fn($project) => getProjectData($project, $currentUser, $notificationCollector))->values() - : $currentUser->projects()->toPages()->map(fn($project) => getProjectData($project, $currentUser, $notificationCollector))->values(); + ? $page->childrenAndDrafts()->map(fn($project) => getProjectData($project, $currentUser))->values() + : $currentUser->projects()->toPages()->map(fn($project) => getProjectData($project, $currentUser))->values(); } catch (\Throwable $th) { throw new Exception($th->getMessage() . ' line ' . $th->getLine() . ' in file ' . $th->getFile(), 1); $children = [];