Skip to content

Commit

Permalink
Support navigation and globals in the static caching invalidation (#2778
Browse files Browse the repository at this point in the history
)

Co-authored-by: Duncan McClean <duncan@mcclean.co.uk>
  • Loading branch information
jasonvarga and duncanmcclean authored Oct 30, 2020
1 parent f11a5d2 commit 2840c51
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 55 deletions.
37 changes: 28 additions & 9 deletions src/StaticCaching/DefaultInvalidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace Statamic\StaticCaching;

use Statamic\Contracts\Entries\Entry;
use Statamic\Contracts\Globals\GlobalSet;
use Statamic\Contracts\Structures\Nav;
use Statamic\Contracts\Taxonomies\Term;
use Statamic\Support\Arr;

Expand All @@ -23,33 +25,50 @@ public function invalidate($item)
return $this->cacher->flush();
}

// Invalidate the item's own URL.
if ($url = $item->url()) {
$this->cacher->invalidateUrl($url);
}

if ($item instanceof Entry) {
$this->invalidateEntryUrls($item);
} elseif ($item instanceof Term) {
$this->invalidateTermUrls($item);
} elseif ($item instanceof Nav) {
$this->invalidateNavUrls($item);
} elseif ($item instanceof GlobalSet) {
$this->invalidateGlobalUrls($item);
}
}

protected function invalidateEntryUrls($entry)
{
$collection = $entry->collectionHandle();
if ($url = $entry->url()) {
$this->cacher->invalidateUrl($url);
}

$this->cacher->invalidateUrls(
Arr::get($this->rules, "collections.$collection.urls")
Arr::get($this->rules, "collections.{$entry->collectionHandle()}.urls")
);
}

protected function invalidateTermUrls($term)
{
$taxonomy = $term->taxonomyHandle();
if ($url = $term->url()) {
$this->cacher->invalidateUrl($url);
}

$this->cacher->invalidateUrls(
Arr::get($this->rules, "taxonomies.$taxonomy.urls")
Arr::get($this->rules, "taxonomies.{$term->taxonomyHandle()}.urls")
);
}

protected function invalidateNavUrls($nav)
{
$this->cacher->invalidateUrls(
Arr::get($this->rules, "navigation.{$nav->handle()}.urls")
);
}

protected function invalidateGlobalUrls($set)
{
$this->cacher->invalidateUrls(
Arr::get($this->rules, "globals.{$set->handle()}.urls")
);
}
}
18 changes: 18 additions & 0 deletions src/StaticCaching/Invalidate.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
use Illuminate\Contracts\Queue\ShouldQueue;
use Statamic\Events\EntryDeleted;
use Statamic\Events\EntrySaved;
use Statamic\Events\GlobalSetDeleted;
use Statamic\Events\GlobalSetSaved;
use Statamic\Events\NavDeleted;
use Statamic\Events\NavSaved;
use Statamic\Events\TermDeleted;
use Statamic\Events\TermSaved;

Expand All @@ -17,6 +21,10 @@ class Invalidate implements ShouldQueue
EntryDeleted::class => 'invalidateEntry',
TermSaved::class => 'invalidateTerm',
TermDeleted::class => 'invalidateTerm',
GlobalSetSaved::class => 'invalidateGlobalSet',
GlobalSetDeleted::class => 'invalidateGlobalSet',
NavSaved::class => 'invalidateNav',
NavDeleted::class => 'invalidateNav',
];

public function __construct(Invalidator $invalidator)
Expand All @@ -40,4 +48,14 @@ public function invalidateTerm($event)
{
$this->invalidator->invalidate($event->term);
}

public function invalidateGlobalSet($event)
{
$this->invalidator->invalidate($event->globals);
}

public function invalidateNav($event)
{
$this->invalidator->invalidate($event->nav);
}
}
118 changes: 72 additions & 46 deletions tests/StaticCaching/DefaultInvalidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

namespace Tests\StaticCaching;

use Statamic\Contracts\Data\Content\Content;
use Mockery;
use Statamic\Contracts\Entries\Entry;
use Statamic\Contracts\Globals\GlobalSet;
use Statamic\Contracts\Structures\Nav;
use Statamic\Contracts\Taxonomies\Term;
use Statamic\StaticCaching\Cacher;
use Statamic\StaticCaching\DefaultInvalidator as Invalidator;
Expand All @@ -12,46 +14,33 @@ class DefaultInvalidatorTest extends \PHPUnit\Framework\TestCase
{
public function tearDown(): void
{
if ($container = \Mockery::getContainer()) {
$this->addToAssertionCount($container->mockery_getExpectationCount());
}

parent::tearDown();
Mockery::close();
}

/** @test */
public function specifying_all_as_invalidation_rule_will_just_flush_the_cache()
{
$cacher = \Mockery::spy(Cacher::class);
$invalidator = new Invalidator($cacher, 'all');
$content = \Mockery::mock(Content::class);
$cacher = Mockery::mock(Cacher::class)->shouldReceive('flush')->once()->getMock();
$item = Mockery::mock(Entry::class);

$invalidator->invalidate($content);
$invalidator = new Invalidator($cacher, 'all');

$cacher->shouldHaveReceived('flush');
$this->assertNull($invalidator->invalidate($item));
}

/** @test */
public function the_entrys_url_gets_invalidated()
public function collection_urls_can_be_invalidated()
{
$cacher = \Mockery::spy(Cacher::class);
$invalidator = new Invalidator($cacher);
$cacher = tap(Mockery::mock(Cacher::class), function ($cacher) {
$cacher->shouldReceive('invalidateUrl')->with('/my/test/entry')->once();
$cacher->shouldReceive('invalidateUrls')->once()->with(['/blog/one', '/blog/two']);
});

$entry = tap(\Mockery::mock(Entry::class), function ($m) {
$entry = tap(Mockery::mock(Entry::class), function ($m) {
$m->shouldReceive('url')->andReturn('/my/test/entry');
$m->shouldReceive('collectionHandle')->andReturn('blog');
});

$invalidator->invalidate($entry);

$cacher->shouldNotHaveReceived('flush');
$cacher->shouldHaveReceived('invalidateUrl')->with('/my/test/entry');
}

/** @test */
public function collection_urls_can_be_invalidated()
{
$cacher = \Mockery::spy(Cacher::class);
$invalidator = new Invalidator($cacher, [
'collections' => [
'blog' => [
Expand All @@ -63,24 +52,22 @@ public function collection_urls_can_be_invalidated()
],
]);

$entry = tap(\Mockery::mock(Entry::class), function ($m) {
$m->shouldReceive('url')->andReturn('/my/test/entry');
$m->shouldReceive('collectionHandle')->andReturn('blog');
});

$invalidator->invalidate($entry);

$cacher->shouldNotHaveReceived('flush');
$cacher->shouldHaveReceived('invalidateUrls')->once()->with([
'/blog/one',
'/blog/two',
]);
$this->assertNull($invalidator->invalidate($entry));
}

/** @test */
public function taxonomy_urls_can_be_invalidated()
{
$cacher = \Mockery::spy(Cacher::class);
$cacher = tap(Mockery::mock(Cacher::class), function ($cacher) {
$cacher->shouldReceive('invalidateUrl')->with('/my/test/term')->once();
$cacher->shouldReceive('invalidateUrls')->once()->with(['/tags/one', '/tags/two']);
});

$term = tap(Mockery::mock(Term::class), function ($m) {
$m->shouldReceive('url')->andReturn('/my/test/term');
$m->shouldReceive('taxonomyHandle')->andReturn('tags');
});

$invalidator = new Invalidator($cacher, [
'taxonomies' => [
'tags' => [
Expand All @@ -92,17 +79,56 @@ public function taxonomy_urls_can_be_invalidated()
],
]);

$entry = tap(\Mockery::mock(Term::class), function ($m) {
$m->shouldReceive('url')->andReturn('/my/test/term');
$m->shouldReceive('taxonomyHandle')->andReturn('tags');
$this->assertNull($invalidator->invalidate($term));
}

/** @test */
public function navigation_urls_can_be_invalidated()
{
$cacher = tap(Mockery::mock(Cacher::class), function ($cacher) {
$cacher->shouldReceive('invalidateUrls')->once()->with(['/one', '/two']);
});

$invalidator->invalidate($entry);
$nav = tap(Mockery::mock(Nav::class), function ($m) {
$m->shouldReceive('handle')->andReturn('links');
});

$cacher->shouldNotHaveReceived('flush');
$cacher->shouldHaveReceived('invalidateUrls')->once()->with([
'/tags/one',
'/tags/two',
$invalidator = new Invalidator($cacher, [
'navigation' => [
'links' => [
'urls' => [
'/one',
'/two',
],
],
],
]);

$this->assertNull($invalidator->invalidate($nav));
}

/** @test */
public function globals_urls_can_be_invalidated()
{
$cacher = tap(Mockery::mock(Cacher::class), function ($cacher) {
$cacher->shouldReceive('invalidateUrls')->once()->with(['/one', '/two']);
});

$set = tap(Mockery::mock(GlobalSet::class), function ($m) {
$m->shouldReceive('handle')->andReturn('social');
});

$invalidator = new Invalidator($cacher, [
'globals' => [
'social' => [
'urls' => [
'/one',
'/two',
],
],
],
]);

$this->assertNull($invalidator->invalidate($set));
}
}

0 comments on commit 2840c51

Please sign in to comment.