Skip to content

Commit b0db8e9

Browse files
committed
Add purge on events "GlobalSetSaved" and "GlobalSetDeleted"
1 parent 4101e1e commit b0db8e9

5 files changed

Lines changed: 133 additions & 0 deletions

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ Once configured, the addon will automatically purge the Cloudflare cache when co
7575
- Entry saved/deleted
7676
- Term saved/deleted
7777
- Asset saved/deleted
78+
- Global set saved/deleted (purges everything via `purge_everything_fallback`)
7879

7980
You can configure which events trigger cache purging in the config file.
8081

@@ -133,6 +134,8 @@ return [
133134
'asset_deleted' => true,
134135
'collection_tree_saved' => true,
135136
'nav_tree_saved' => true,
137+
'global_set_saved' => true,
138+
'global_set_deleted' => true,
136139
],
137140

138141
// Dispatch purge jobs to the queue instead of running synchronously

config/cloudflare-cache.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
'asset_deleted' => true,
4646
'collection_tree_saved' => true,
4747
'nav_tree_saved' => true,
48+
'global_set_saved' => true,
49+
'global_set_deleted' => true,
4850
],
4951

5052
'queue_purge' => env('CLOUDFLARE_CACHE_QUEUE_PURGE', false), // Dispatch purge jobs to the queue

src/CloudflareCacheServiceProvider.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
use Statamic\Events\AssetDeleted;
1414
use Statamic\Events\CollectionTreeSaved;
1515
use Statamic\Events\NavTreeSaved;
16+
use Statamic\Events\GlobalSetSaved;
17+
use Statamic\Events\GlobalSetDeleted;
1618

1719
class CloudflareCacheServiceProvider extends AddonServiceProvider
1820
{
@@ -45,6 +47,12 @@ class CloudflareCacheServiceProvider extends AddonServiceProvider
4547
NavTreeSaved::class => [
4648
PurgeCloudflareCache::class,
4749
],
50+
GlobalSetSaved::class => [
51+
PurgeCloudflareCache::class,
52+
],
53+
GlobalSetDeleted::class => [
54+
PurgeCloudflareCache::class,
55+
],
4856
];
4957

5058
/**

src/Listeners/PurgeCloudflareCache.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
use Statamic\Events\AssetDeleted;
1414
use Statamic\Events\CollectionTreeSaved;
1515
use Statamic\Events\NavTreeSaved;
16+
use Statamic\Events\GlobalSetSaved;
17+
use Statamic\Events\GlobalSetDeleted;
1618
use Statamic\Facades\URL;
1719
use Illuminate\Support\Facades\Log; // Already present, but good to confirm
1820

@@ -113,6 +115,8 @@ protected function shouldHandleEvent(Event $event): bool
113115
'Statamic\Events\AssetDeleted' => 'asset_deleted',
114116
'Statamic\Events\CollectionTreeSaved' => 'collection_tree_saved',
115117
'Statamic\Events\NavTreeSaved' => 'nav_tree_saved',
118+
'Statamic\Events\GlobalSetSaved' => 'global_set_saved',
119+
'Statamic\Events\GlobalSetDeleted' => 'global_set_deleted',
116120
];
117121

118122
$configKey = $eventMap[$eventClass] ?? null;
@@ -173,6 +177,12 @@ protected function getUrlsToPurge(Event $event): array
173177
// If purge_everything_fallback is disabled, this will do nothing (intended behavior)
174178
}
175179

180+
if ($event instanceof GlobalSetSaved || $event instanceof GlobalSetDeleted) {
181+
// Global sets can affect many pages (headers, footers, shared blocks, etc.).
182+
// We intentionally do not return any URLs here so the listener follows the
183+
// existing purge_everything_fallback logic (sync or queued).
184+
}
185+
176186
$urls = array_filter($urls);
177187

178188
return array_unique($urls);

tests/Feature/PurgeCacheListenerTest.php

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
use Eminos\StatamicCloudflareCache\Http\Client;
77
use Eminos\StatamicCloudflareCache\Listeners\PurgeCloudflareCache;
88
use Statamic\Events\EntrySaved;
9+
use Statamic\Events\GlobalSetSaved;
10+
use Statamic\Events\GlobalSetDeleted;
911
use Statamic\Contracts\Entries\Entry;
1012
use Statamic\Contracts\Entries\Collection;
1113
use Illuminate\Support\Facades\Http;
@@ -49,6 +51,11 @@ protected function mockEntry($url = '/test-entry', $collectionUrl = '/test-colle
4951
return $entry;
5052
}
5153

54+
protected function mockGlobals()
55+
{
56+
return new stdClass();
57+
}
58+
5259
#[Test]
5360
public function it_purges_cache_synchronously_when_entry_is_saved_and_queue_disabled()
5461
{
@@ -199,4 +206,107 @@ public function it_does_not_dispatch_job_when_queue_enabled_but_no_urls_and_no_f
199206

200207
Queue::assertNothingPushed();
201208
}
209+
210+
#[Test]
211+
public function it_purges_everything_synchronously_when_global_set_is_saved_and_queue_disabled()
212+
{
213+
config([
214+
'cloudflare-cache.queue_purge' => false,
215+
'cloudflare-cache.purge_everything_fallback' => true,
216+
'cloudflare-cache.purge_urls' => true,
217+
'cloudflare-cache.purge_on.global_set_saved' => true,
218+
]);
219+
220+
$globals = $this->mockGlobals();
221+
$event = new GlobalSetSaved($globals);
222+
223+
$clientMock = $this->mock(Client::class);
224+
$clientMock->shouldReceive('purgeEverything')->once();
225+
$clientMock->shouldNotReceive('purgeUrls');
226+
227+
$listener = $this->app->make(PurgeCloudflareCache::class);
228+
$listener->handle($event);
229+
230+
Queue::assertNothingPushed();
231+
}
232+
233+
#[Test]
234+
public function it_purges_everything_synchronously_when_global_set_is_deleted_and_queue_disabled()
235+
{
236+
config([
237+
'cloudflare-cache.queue_purge' => false,
238+
'cloudflare-cache.purge_everything_fallback' => true,
239+
'cloudflare-cache.purge_urls' => true,
240+
'cloudflare-cache.purge_on.global_set_deleted' => true,
241+
]);
242+
243+
$globals = $this->mockGlobals();
244+
$event = new GlobalSetDeleted($globals);
245+
246+
$clientMock = $this->mock(Client::class);
247+
$clientMock->shouldReceive('purgeEverything')->once();
248+
$clientMock->shouldNotReceive('purgeUrls');
249+
250+
$listener = $this->app->make(PurgeCloudflareCache::class);
251+
$listener->handle($event);
252+
253+
Queue::assertNothingPushed();
254+
}
255+
256+
#[Test]
257+
public function it_dispatches_purge_everything_job_when_global_set_is_saved_and_queue_enabled()
258+
{
259+
config([
260+
'cloudflare-cache.queue_purge' => true,
261+
'cloudflare-cache.purge_everything_fallback' => true,
262+
'cloudflare-cache.purge_urls' => true,
263+
'cloudflare-cache.purge_on.global_set_saved' => true,
264+
]);
265+
266+
$globals = $this->mockGlobals();
267+
$event = new GlobalSetSaved($globals);
268+
269+
$clientMock = $this->mock(Client::class);
270+
$clientMock->shouldNotReceive('purgeUrls');
271+
$clientMock->shouldNotReceive('purgeEverything');
272+
273+
$listener = $this->app->make(PurgeCloudflareCache::class);
274+
$listener->handle($event);
275+
276+
Queue::assertPushed(PurgeCloudflareCacheJob::class, function ($job) {
277+
$reflection = new \ReflectionClass($job);
278+
$urlsProp = $reflection->getProperty('urls');
279+
$urlsProp->setAccessible(true);
280+
$urls = $urlsProp->getValue($job);
281+
282+
$purgeEverythingProp = $reflection->getProperty('purgeEverything');
283+
$purgeEverythingProp->setAccessible(true);
284+
$purgeEverything = $purgeEverythingProp->getValue($job);
285+
286+
return is_null($urls) && $purgeEverything;
287+
});
288+
}
289+
290+
#[Test]
291+
public function it_does_not_purge_when_global_set_saved_event_is_disabled_in_config()
292+
{
293+
config([
294+
'cloudflare-cache.queue_purge' => false,
295+
'cloudflare-cache.purge_everything_fallback' => true,
296+
'cloudflare-cache.purge_on.global_set_saved' => false,
297+
]);
298+
299+
$globals = $this->mockGlobals();
300+
$event = new GlobalSetSaved($globals);
301+
302+
$clientMock = $this->mock(Client::class);
303+
$clientMock->shouldNotReceive('purgeUrls');
304+
$clientMock->shouldNotReceive('purgeEverything');
305+
306+
$listener = $this->app->make(PurgeCloudflareCache::class);
307+
$listener->handle($event);
308+
309+
Queue::assertNothingPushed();
310+
Http::assertNothingSent();
311+
}
202312
}

0 commit comments

Comments
 (0)