diff --git a/src/StaticCaching/Cachers/AbstractCacher.php b/src/StaticCaching/Cachers/AbstractCacher.php index 34df6bd7409..fb9698f41dc 100644 --- a/src/StaticCaching/Cachers/AbstractCacher.php +++ b/src/StaticCaching/Cachers/AbstractCacher.php @@ -9,6 +9,7 @@ use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Http\Response; +use Illuminate\Support\Facades\Cache; use Statamic\Console\Commands\StaticWarmJob; use Statamic\Facades\Site; use Statamic\Facades\URL; @@ -168,6 +169,17 @@ public function flushUrls() $this->cache->forget($this->normalizeKey('domains')); } + protected function flushDedicatedStore(): void + { + if (! config()->has('cache.stores.static_cache')) { + return; + } + + if ($this->cache === Cache::store('static_cache')) { + $this->cache->flush(); + } + } + /** * Save a URL to the cache. * diff --git a/src/StaticCaching/Cachers/ApplicationCacher.php b/src/StaticCaching/Cachers/ApplicationCacher.php index 8846b595e12..28cd8ed90b1 100644 --- a/src/StaticCaching/Cachers/ApplicationCacher.php +++ b/src/StaticCaching/Cachers/ApplicationCacher.php @@ -146,6 +146,8 @@ public function flush() }); $this->flushUrls(); + + $this->flushDedicatedStore(); } /** diff --git a/src/StaticCaching/Cachers/FileCacher.php b/src/StaticCaching/Cachers/FileCacher.php index 9e1506da520..66630c2ebf1 100644 --- a/src/StaticCaching/Cachers/FileCacher.php +++ b/src/StaticCaching/Cachers/FileCacher.php @@ -133,6 +133,8 @@ public function flush() } $this->flushUrls(); + + $this->flushDedicatedStore(); } /** diff --git a/src/StaticCaching/StaticCacheManager.php b/src/StaticCaching/StaticCacheManager.php index 1e2156c10d9..549c95f065c 100644 --- a/src/StaticCaching/StaticCacheManager.php +++ b/src/StaticCaching/StaticCacheManager.php @@ -70,6 +70,8 @@ public function flush() $this->flushNocache(); + // The built-in cachers already wipe the dedicated store from their own flush(), + // but null and custom drivers don't, and flushNocache() relies on it being wiped. if ($this->hasCustomStore()) { $this->cacheStore()->flush(); } diff --git a/tests/StaticCaching/ApplicationCacherTest.php b/tests/StaticCaching/ApplicationCacherTest.php index 12694feae75..af7505107df 100644 --- a/tests/StaticCaching/ApplicationCacherTest.php +++ b/tests/StaticCaching/ApplicationCacherTest.php @@ -8,6 +8,7 @@ use Illuminate\Contracts\Cache\Repository; use Illuminate\Http\Request; use Illuminate\Routing\Events\ResponsePrepared; +use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Queue; use PHPUnit\Framework\Attributes\DataProvider; @@ -610,6 +611,31 @@ public function it_flushes() $this->assertEquals([], $cacher->getUrls('http://another.com')->all()); } + #[Test] + public function flushing_wipes_the_dedicated_static_cache_store() + { + config(['cache.stores.static_cache' => ['driver' => 'array']]); + $cache = Cache::store('static_cache'); + $cache->forever('untracked', 'value'); + $cacher = new ApplicationCacher($cache, ['base_url' => 'http://example.com']); + + $cacher->flush(); + + $this->assertNull($cache->get('untracked')); + } + + #[Test] + public function flushing_leaves_other_keys_in_a_shared_store() + { + $cache = app(Repository::class); + $cache->forever('untracked', 'value'); + $cacher = new ApplicationCacher($cache, ['base_url' => 'http://example.com']); + + $cacher->flush(); + + $this->assertEquals('value', $cache->get('untracked')); + } + #[Test] public function flushing_removes_cached_error_responses() { diff --git a/tests/StaticCaching/DefaultInvalidatorTest.php b/tests/StaticCaching/DefaultInvalidatorTest.php index fab720e4053..6d92ec0b526 100644 --- a/tests/StaticCaching/DefaultInvalidatorTest.php +++ b/tests/StaticCaching/DefaultInvalidatorTest.php @@ -6,6 +6,7 @@ use Illuminate\Http\Request; use Illuminate\Routing\Events\ResponsePrepared; use Illuminate\Support\Carbon; +use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Queue; use Mockery; use PHPUnit\Framework\Attributes\DataProvider; @@ -55,6 +56,24 @@ public function specifying_all_as_invalidation_rule_will_just_flush_the_cache() $this->assertNull($invalidator->invalidate($item)); } + #[Test] + public function specifying_all_as_invalidation_rule_flushes_the_dedicated_static_cache_store() + { + config([ + 'statamic.static_caching.strategy' => 'half', + 'statamic.static_caching.strategies.half.driver' => 'application', + 'cache.stores.static_cache' => ['driver' => 'array'], + ]); + + Cache::store('static_cache')->forever('untracked', 'value'); + + $invalidator = new Invalidator(app(Cacher::class), 'all'); + + $invalidator->invalidate(Mockery::mock(Entry::class)); + + $this->assertNull(Cache::store('static_cache')->get('untracked')); + } + #[Test] public function assets_can_trigger_url_invalidation() { diff --git a/tests/StaticCaching/FileCacherTest.php b/tests/StaticCaching/FileCacherTest.php index f8992335821..d5679b37ed5 100644 --- a/tests/StaticCaching/FileCacherTest.php +++ b/tests/StaticCaching/FileCacherTest.php @@ -4,6 +4,7 @@ use Illuminate\Contracts\Cache\Repository; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Queue; use PHPUnit\Framework\Attributes\DataProvider; @@ -167,6 +168,19 @@ public function flushing_the_cache_deletes_from_all_cache_locations() $writer->shouldHaveReceived('flush')->with('fr/test/path'); } + #[Test] + public function flushing_wipes_the_dedicated_static_cache_store() + { + config(['cache.stores.static_cache' => ['driver' => 'array']]); + $cache = Cache::store('static_cache'); + $cache->forever('untracked', 'value'); + $cacher = $this->fileCacher(['path' => 'test/path'], \Mockery::spy(Writer::class), $cache); + + $cacher->flush(); + + $this->assertNull($cache->get('untracked')); + } + #[Test] public function invalidating_a_url_thats_not_cached_will_do_nothing() { diff --git a/tests/StaticCaching/ManagerTest.php b/tests/StaticCaching/ManagerTest.php index f42d38f0ad4..7313fc40867 100644 --- a/tests/StaticCaching/ManagerTest.php +++ b/tests/StaticCaching/ManagerTest.php @@ -72,6 +72,21 @@ public function it_flushes() StaticCache::flush(); } + #[Test] + public function it_flushes_the_dedicated_store_for_drivers_that_do_not_flush_it_themselves() + { + config([ + 'statamic.static_caching.strategy' => 'null', + 'cache.stores.static_cache' => ['driver' => 'array'], + ]); + + Cache::store('static_cache')->forever('nocache::urls', ['/one']); + + StaticCache::flush(); + + $this->assertNull(Cache::store('static_cache')->get('nocache::urls')); + } + #[Test] public function it_flushes_without_static_cache_store() {