From 33654cc9e26c8686346f25ea6f0fcaa6633725ea Mon Sep 17 00:00:00 2001 From: Tim Kelty Date: Fri, 28 Aug 2026 10:20:30 -0400 Subject: [PATCH 1/7] Disable GraphQL caching during static cache collection --- src/StaticCache.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/StaticCache.php b/src/StaticCache.php index 527a82f..f1fae7c 100644 --- a/src/StaticCache.php +++ b/src/StaticCache.php @@ -141,6 +141,7 @@ private function handleInitWebApplication(Event $event): void return; } + Craft::$app->getConfig()->getGeneral()->enableGraphqlCaching = false; Craft::$app->getElements()->startCollectingCacheInfo(); $this->collectingCacheInfo = true; } From c12a6d058e0d6b2d6fc6e95b7ac0751157c5f63a Mon Sep 17 00:00:00 2001 From: Tim Kelty Date: Fri, 28 Aug 2026 10:23:30 -0400 Subject: [PATCH 2/7] Disable GraphQL caching during static cache collection --- src/StaticCache.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/StaticCache.php b/src/StaticCache.php index f1fae7c..b6cb30a 100644 --- a/src/StaticCache.php +++ b/src/StaticCache.php @@ -12,6 +12,7 @@ use craft\helpers\ElementHelper; use craft\helpers\StringHelper; use craft\services\Elements; +use craft\services\Gql; use craft\utilities\ClearCaches; use craft\web\UrlManager; use craft\web\View; @@ -78,6 +79,16 @@ public function registerEventHandlers(): void fn(Event $event) => $this->handleInitWebApplication($event), ); + Event::on( + Gql::class, + Gql::EVENT_BEFORE_EXECUTE_GQL_QUERY, + function() { + if ($this->collectingCacheInfo) { + Craft::$app->getConfig()->getGeneral()->enableGraphqlCaching = false; + } + }, + ); + Event::on( View::class, View::EVENT_BEFORE_RENDER_PAGE_TEMPLATE, @@ -141,7 +152,6 @@ private function handleInitWebApplication(Event $event): void return; } - Craft::$app->getConfig()->getGeneral()->enableGraphqlCaching = false; Craft::$app->getElements()->startCollectingCacheInfo(); $this->collectingCacheInfo = true; } From 3a48272f5df5fc8911faf254085c2850aa474256 Mon Sep 17 00:00:00 2001 From: Tim Kelty Date: Fri, 28 Aug 2026 10:41:37 -0400 Subject: [PATCH 3/7] Test GraphQL cache override --- src/StaticCache.php | 13 ++++++++----- tests/unit/StaticCacheTest.php | 26 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/StaticCache.php b/src/StaticCache.php index b6cb30a..e809f2b 100644 --- a/src/StaticCache.php +++ b/src/StaticCache.php @@ -82,11 +82,7 @@ public function registerEventHandlers(): void Event::on( Gql::class, Gql::EVENT_BEFORE_EXECUTE_GQL_QUERY, - function() { - if ($this->collectingCacheInfo) { - Craft::$app->getConfig()->getGeneral()->enableGraphqlCaching = false; - } - }, + fn(Event $event) => $this->handleBeforeExecuteGqlQuery($event), ); Event::on( @@ -175,6 +171,13 @@ private function handleAfterPrepareWebResponse(Event $event): void $this->addCacheHeadersToWebResponse(); } + private function handleBeforeExecuteGqlQuery(Event $event): void + { + if ($this->collectingCacheInfo) { + Craft::$app->getConfig()->getGeneral()->enableGraphqlCaching = false; + } + } + private function handleBeforeRenderPageTemplate(TemplateEvent $event): void { /** @var UrlManager $urlManager */ diff --git a/tests/unit/StaticCacheTest.php b/tests/unit/StaticCacheTest.php index 3ace6cd..dfea92f 100644 --- a/tests/unit/StaticCacheTest.php +++ b/tests/unit/StaticCacheTest.php @@ -125,6 +125,26 @@ public function testPostResponsesAreNotCacheable(): void $this->assertFalse($this->isCacheable($staticCache)); } + public function testGraphqlCachingIsDisabledWhileCollectingCacheInfo(): void + { + $staticCache = new StaticCache(); + $generalConfig = Craft::$app->getConfig()->getGeneral(); + $enableGraphqlCaching = $generalConfig->enableGraphqlCaching; + + try { + $generalConfig->enableGraphqlCaching = true; + $this->handleBeforeExecuteGqlQuery($staticCache); + $this->assertTrue($generalConfig->enableGraphqlCaching); + + $collectingCacheInfo = new ReflectionProperty($staticCache, 'collectingCacheInfo'); + $collectingCacheInfo->setValue($staticCache, true); + $this->handleBeforeExecuteGqlQuery($staticCache); + $this->assertFalse($generalConfig->enableGraphqlCaching); + } finally { + $generalConfig->enableGraphqlCaching = $enableGraphqlCaching; + } + } + public function testStaticCacheDirectivesPreferCdnCacheControl(): void { $staticCache = new StaticCache(); @@ -602,6 +622,12 @@ private function staticCacheDirectives(StaticCache $staticCache): Collection return $method->invoke($staticCache); } + private function handleBeforeExecuteGqlQuery(StaticCache $staticCache): void + { + $method = new ReflectionMethod($staticCache, 'handleBeforeExecuteGqlQuery'); + $method->invoke($staticCache, new \yii\base\Event()); + } + private function addCacheHeadersToWebResponse(StaticCache $staticCache): void { $method = new ReflectionMethod($staticCache, 'addCacheHeadersToWebResponse'); From 749cbb37d9ecf210abd71716e3a231a0fe1c427b Mon Sep 17 00:00:00 2001 From: Tim Kelty Date: Fri, 28 Aug 2026 10:45:50 -0400 Subject: [PATCH 4/7] Link GraphQL cache workaround cleanup --- src/StaticCache.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/StaticCache.php b/src/StaticCache.php index e809f2b..ab9505f 100644 --- a/src/StaticCache.php +++ b/src/StaticCache.php @@ -174,6 +174,7 @@ private function handleAfterPrepareWebResponse(Event $event): void private function handleBeforeExecuteGqlQuery(Event $event): void { if ($this->collectingCacheInfo) { + // TODO: Remove after https://github.com/craftcms/cms/pull/19505 reaches Cloud's minimum supported Craft version. Craft::$app->getConfig()->getGeneral()->enableGraphqlCaching = false; } } From e1a7972188d94f0e79e329add186254f7f357de6 Mon Sep 17 00:00:00 2001 From: Tim Kelty Date: Fri, 28 Aug 2026 10:48:17 -0400 Subject: [PATCH 5/7] Restore GraphQL caching after static cache collection --- src/StaticCache.php | 19 ++++++++++++++++++- tests/unit/StaticCacheTest.php | 11 ++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/StaticCache.php b/src/StaticCache.php index ab9505f..b09b7b1 100644 --- a/src/StaticCache.php +++ b/src/StaticCache.php @@ -63,6 +63,7 @@ class StaticCache extends \yii\base\Component private Collection $tagsToPurge; private Collection $fetchUrls; private bool $collectingCacheInfo = false; + private ?bool $graphqlCaching = null; public function init(): void { @@ -85,6 +86,12 @@ public function registerEventHandlers(): void fn(Event $event) => $this->handleBeforeExecuteGqlQuery($event), ); + Event::on( + Gql::class, + Gql::EVENT_AFTER_EXECUTE_GQL_QUERY, + fn(Event $event) => $this->handleAfterExecuteGqlQuery($event), + ); + Event::on( View::class, View::EVENT_BEFORE_RENDER_PAGE_TEMPLATE, @@ -175,7 +182,17 @@ private function handleBeforeExecuteGqlQuery(Event $event): void { if ($this->collectingCacheInfo) { // TODO: Remove after https://github.com/craftcms/cms/pull/19505 reaches Cloud's minimum supported Craft version. - Craft::$app->getConfig()->getGeneral()->enableGraphqlCaching = false; + $generalConfig = Craft::$app->getConfig()->getGeneral(); + $this->graphqlCaching = $generalConfig->enableGraphqlCaching; + $generalConfig->enableGraphqlCaching = false; + } + } + + private function handleAfterExecuteGqlQuery(Event $event): void + { + if ($this->graphqlCaching !== null) { + Craft::$app->getConfig()->getGeneral()->enableGraphqlCaching = $this->graphqlCaching; + $this->graphqlCaching = null; } } diff --git a/tests/unit/StaticCacheTest.php b/tests/unit/StaticCacheTest.php index dfea92f..7c33101 100644 --- a/tests/unit/StaticCacheTest.php +++ b/tests/unit/StaticCacheTest.php @@ -125,7 +125,7 @@ public function testPostResponsesAreNotCacheable(): void $this->assertFalse($this->isCacheable($staticCache)); } - public function testGraphqlCachingIsDisabledWhileCollectingCacheInfo(): void + public function testGraphqlCachingIsOnlyDisabledWhileCollectingCacheInfo(): void { $staticCache = new StaticCache(); $generalConfig = Craft::$app->getConfig()->getGeneral(); @@ -140,6 +140,9 @@ public function testGraphqlCachingIsDisabledWhileCollectingCacheInfo(): void $collectingCacheInfo->setValue($staticCache, true); $this->handleBeforeExecuteGqlQuery($staticCache); $this->assertFalse($generalConfig->enableGraphqlCaching); + + $this->handleAfterExecuteGqlQuery($staticCache); + $this->assertTrue($generalConfig->enableGraphqlCaching); } finally { $generalConfig->enableGraphqlCaching = $enableGraphqlCaching; } @@ -628,6 +631,12 @@ private function handleBeforeExecuteGqlQuery(StaticCache $staticCache): void $method->invoke($staticCache, new \yii\base\Event()); } + private function handleAfterExecuteGqlQuery(StaticCache $staticCache): void + { + $method = new ReflectionMethod($staticCache, 'handleAfterExecuteGqlQuery'); + $method->invoke($staticCache, new \yii\base\Event()); + } + private function addCacheHeadersToWebResponse(StaticCache $staticCache): void { $method = new ReflectionMethod($staticCache, 'addCacheHeadersToWebResponse'); From 2209797e5b4c60df0285e2f9e5a75a2c823bd636 Mon Sep 17 00:00:00 2001 From: Tim Kelty Date: Fri, 28 Aug 2026 12:29:11 -0400 Subject: [PATCH 6/7] Update GraphQL cache cleanup link --- src/StaticCache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/StaticCache.php b/src/StaticCache.php index b09b7b1..9375faa 100644 --- a/src/StaticCache.php +++ b/src/StaticCache.php @@ -181,7 +181,7 @@ private function handleAfterPrepareWebResponse(Event $event): void private function handleBeforeExecuteGqlQuery(Event $event): void { if ($this->collectingCacheInfo) { - // TODO: Remove after https://github.com/craftcms/cms/pull/19505 reaches Cloud's minimum supported Craft version. + // TODO: Remove after https://github.com/craftcms/cms/pull/19508 reaches Cloud's minimum supported Craft version. $generalConfig = Craft::$app->getConfig()->getGeneral(); $this->graphqlCaching = $generalConfig->enableGraphqlCaching; $generalConfig->enableGraphqlCaching = false; From 54a72277e873387bd2dc41945dcabc5dc5c73bc5 Mon Sep 17 00:00:00 2001 From: Tim Kelty Date: Fri, 28 Aug 2026 12:37:32 -0400 Subject: [PATCH 7/7] Restore GraphQL caching after nested queries --- src/StaticCache.php | 10 +++++----- tests/unit/StaticCacheTest.php | 6 ++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/StaticCache.php b/src/StaticCache.php index 9375faa..e113847 100644 --- a/src/StaticCache.php +++ b/src/StaticCache.php @@ -63,7 +63,8 @@ class StaticCache extends \yii\base\Component private Collection $tagsToPurge; private Collection $fetchUrls; private bool $collectingCacheInfo = false; - private ?bool $graphqlCaching = null; + /** @var bool[] */ + private array $graphqlCachingStack = []; public function init(): void { @@ -183,16 +184,15 @@ private function handleBeforeExecuteGqlQuery(Event $event): void if ($this->collectingCacheInfo) { // TODO: Remove after https://github.com/craftcms/cms/pull/19508 reaches Cloud's minimum supported Craft version. $generalConfig = Craft::$app->getConfig()->getGeneral(); - $this->graphqlCaching = $generalConfig->enableGraphqlCaching; + $this->graphqlCachingStack[] = $generalConfig->enableGraphqlCaching; $generalConfig->enableGraphqlCaching = false; } } private function handleAfterExecuteGqlQuery(Event $event): void { - if ($this->graphqlCaching !== null) { - Craft::$app->getConfig()->getGeneral()->enableGraphqlCaching = $this->graphqlCaching; - $this->graphqlCaching = null; + if ($this->graphqlCachingStack !== []) { + Craft::$app->getConfig()->getGeneral()->enableGraphqlCaching = array_pop($this->graphqlCachingStack); } } diff --git a/tests/unit/StaticCacheTest.php b/tests/unit/StaticCacheTest.php index 7c33101..3e38dac 100644 --- a/tests/unit/StaticCacheTest.php +++ b/tests/unit/StaticCacheTest.php @@ -141,6 +141,12 @@ public function testGraphqlCachingIsOnlyDisabledWhileCollectingCacheInfo(): void $this->handleBeforeExecuteGqlQuery($staticCache); $this->assertFalse($generalConfig->enableGraphqlCaching); + $this->handleBeforeExecuteGqlQuery($staticCache); + $this->assertFalse($generalConfig->enableGraphqlCaching); + + $this->handleAfterExecuteGqlQuery($staticCache); + $this->assertFalse($generalConfig->enableGraphqlCaching); + $this->handleAfterExecuteGqlQuery($staticCache); $this->assertTrue($generalConfig->enableGraphqlCaching); } finally {