Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/HeaderEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ enum HeaderEnum: string
{
case CACHE_TAG = 'Cache-Tag';
case CACHE_PURGE_TAG = 'Cache-Purge-Tag';
case CACHE_PURGE_ELEMENT = 'Cache-Purge-Element';
case CACHE_PURGE_PREFIX = 'Cache-Purge-Prefix';
case CACHE_CONTROL = 'Cache-Control';
case CDN_CACHE_CONTROL = 'CDN-Cache-Control';
Expand Down
1 change: 1 addition & 0 deletions src/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public static function makeGatewayApiRequest(iterable $headers): ResponseInterfa
}

$headers = Collection::make($headers)
->map(fn($value) => $value instanceof Collection ? $value->join(',') : (string) $value)
->put(HeaderEnum::REQUEST_TYPE->value, 'api');

if (Module::getInstance()->getConfig()->getDevMode()) {
Expand Down
26 changes: 16 additions & 10 deletions src/StaticCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,11 @@ private function handleBeforeRenderPageTemplate(TemplateEvent $event): void

private function handleInvalidateElementCaches(InvalidateElementCachesEvent $event): void
{
$tags = Collection::make($event->tags)->map(fn(string $tag) => StaticCacheTag::create($tag)->minify(true));
$tags = Collection::make($event->tags)->map(
fn(string $tag) => StaticCacheTag::create($tag)
->withElement($event->element)
->minify(true)
);

$skip = $tags->contains(function(StaticCacheTag $tag) {
return preg_match('/element::craft\\\\elements\\\\\S+::(drafts|revisions)/', $tag->originalValue);
Expand Down Expand Up @@ -205,7 +209,8 @@ private function purgeElementUri(ElementInterface $element): void
: Path::new($uri)->withLeadingSlash()->withoutTrailingSlash();

$environmentId = Module::getInstance()->getConfig()->environmentId;
$this->tagsToPurge->prepend("$environmentId:$uri");
$tag = StaticCacheTag::create("$environmentId:$uri")->withElement($element);
$this->tagsToPurge->prepend($tag);
}

private function addCacheHeadersToWebResponse(): void
Expand Down Expand Up @@ -274,20 +279,21 @@ public function purgeTags(string|StaticCacheTag ...$tags): void
'tags' => $tags,
]), __METHOD__);

$headers = Collection::make([
HeaderEnum::CACHE_PURGE_TAG->value => $tags->map(fn(StaticCacheTag $tag) => $tag->getValue())->unique()->filter(),
HeaderEnum::CACHE_PURGE_ELEMENT->value => $tags->map(fn(StaticCacheTag $tag) => $tag->element->id ?? null)->unique()->filter(),
]);

if ($isWebResponse) {
$tags->each(fn(StaticCacheTag $tag) => $response->getHeaders()->add(
HeaderEnum::CACHE_PURGE_TAG->value,
$tag->getValue(),
));
$headers->each(function(Collection $values, string $name) use ($response) {
$values->each(fn($value) => $response->getHeaders()->add($name, $value));
});

return;
}

// TODO: make sure we don't go over max header size
Helper::makeGatewayApiRequest([
// Mapping to string because: https://github.com/laravel/framework/pull/54630
HeaderEnum::CACHE_PURGE_TAG->value => $tags->map(fn(StaticCacheTag $tag) => (string) $tag)->implode(','),
]);
Helper::makeGatewayApiRequest($headers);
}

public function purgeUrlPrefixes(string ...$urlPrefixes): void
Expand Down
14 changes: 14 additions & 0 deletions src/StaticCacheTag.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

namespace craft\cloud;

use craft\base\ElementInterface;

class StaticCacheTag implements \Stringable, \JsonSerializable
{
public readonly string $originalValue;
private bool $minify = false;
public ?ElementInterface $element = null;

public function __construct(
private string $value,
Expand All @@ -18,11 +21,22 @@ public static function create(string $value): self
return new self($value);
}

public function withElement(?ElementInterface $element): self
{
$this->element = $element;

return $this;
}

public function jsonSerialize(): false|string
{
return json_encode([
'value' => $this->getValue(),
'originalValue' => $this->originalValue,
'element' => $this->element?->getAttributes([
'id',
'url',
]),
]);
}

Expand Down
Loading