hasUserData($context->data) && ! $this->hasVolatileData($context->data); } public function generateKey(TemplateContext $context): CacheKey { return CacheKey::fromString("page:{$context->template}:" . md5(serialize($this->getNonVolatileData($context->data)))); } public function getTtl(TemplateContext $context): int { return match($this->getPageType($context->template)) { 'layout' => 3600, // 1 hour 'static' => 7200, // 2 hours 'content' => 1800, // 30 minutes default => 900 // 15 minutes }; } private function hasUserData(array $data): bool { $userKeys = ['user', 'auth', 'session', 'current_user']; return ! empty(array_intersect(array_keys($data), $userKeys)); } private function hasVolatileData(array $data): bool { $volatileKeys = ['csrf_token', '_token', 'flash', 'errors', 'timestamp', 'now']; return ! empty(array_intersect(array_keys($data), $volatileKeys)); } private function getNonVolatileData(array $data): array { $volatileKeys = ['csrf_token', '_token', 'flash', 'errors', 'timestamp', 'now', 'user', 'auth', 'session']; return array_diff_key($data, array_flip($volatileKeys)); } private function getPageType(string $template): string { if (str_contains($template, 'layout')) { return 'layout'; } if (str_contains($template, 'static')) { return 'static'; } if (str_contains($template, 'page')) { return 'content'; } return 'default'; } public function canInvalidate(string $template): bool { return true; } }