diff --git a/README.md b/README.md index 228c1a8..c11ff13 100644 --- a/README.md +++ b/README.md @@ -78,33 +78,6 @@ $cache->purgeKeys([ Fastly domain purges invalidate the entire configured service. Use one domain per Fastly service when calling `purgeDomain()`. Cloudflare hostname purging depends on the cache-purge features enabled for your plan. -### Cache routing - -`Cache\Adapter\Proxy` routes domain and path purges: it sends the application domain to one adapter, configured network domains to another, and fans custom domains out to every custom adapter. - -```php -use Utopia\Cdn\Cache\Adapter\Proxy; - -$cache = new Cache(new Proxy( - appDomain: 'app.example.com', - appDomainAdapter: $cloudflareCache, - networkAdapter: $fastlyCache, - customDomainAdapters: [$cloudflareCache, $fastlyCache], - networkDomains: ['network.example.com'], -)); -``` - -Cache keys and tags are scoped to a Fastly service or Cloudflare zone. Consequently, `Proxy` does not route `purgeKeys()` calls. The consuming application must select the adapter using its own routing context before constructing `Cache`: - -```php -$adapter = $cdnAdapterResolver->resolve($rule); - -$cache = new Cache($adapter); -$cache->purgeKeys([ - 'domain-' . \strtolower($domain), -]); -``` - ## Certificates The current certificate provider support is focused on CDN-managed certificates through Fastly TLS subscriptions. diff --git a/src/Cdn/Cache/Adapter/Proxy.php b/src/Cdn/Cache/Adapter/Proxy.php deleted file mode 100644 index 27def0f..0000000 --- a/src/Cdn/Cache/Adapter/Proxy.php +++ /dev/null @@ -1,78 +0,0 @@ - $customDomainAdapters - * @param array $networkDomains - */ - public function __construct( - private string $appDomain, - private Adapter $appDomainAdapter, - private Adapter $networkAdapter, - private array $customDomainAdapters, - private array $networkDomains = [], - ) { - $this->appDomain = Domain::validate($this->appDomain); - $this->networkDomains = \array_map([Domain::class, 'validate'], $this->networkDomains); - } - - public function purgePaths(string $domain, array $paths): void - { - $domain = Domain::validate($domain); - $paths = Domain::validatePaths($paths); - - if ($paths === []) { - return; - } - - foreach ($this->select($domain) as $adapter) { - $adapter->purgePaths($domain, $paths); - } - } - - public function purgeDomain(string $domain): void - { - $domain = Domain::validate($domain); - - foreach ($this->select($domain) as $adapter) { - $adapter->purgeDomain($domain); - } - } - - public function purgeKeys(array $keys): void - { - if ($keys === []) { - return; - } - - throw new UnsupportedOperation( - 'Cache key purging cannot be routed by domain. Select the service or zone adapter before purging keys.' - ); - } - - /** @return array */ - private function select(string $domain): array - { - if ($domain === $this->appDomain) { - return [$this->appDomainAdapter]; - } - - if (\in_array($domain, $this->networkDomains, true)) { - return [$this->networkAdapter]; - } - - if ($this->customDomainAdapters === []) { - throw new Configuration('No cache adapters are configured for custom domains.'); - } - - return $this->customDomainAdapters; - } -} diff --git a/tests/Cdn/Cache/Adapter/ProxyTest.php b/tests/Cdn/Cache/Adapter/ProxyTest.php deleted file mode 100644 index dde0e07..0000000 --- a/tests/Cdn/Cache/Adapter/ProxyTest.php +++ /dev/null @@ -1,83 +0,0 @@ -adapter('app', $calls); - $network = $this->adapter('network', $calls); - $customA = $this->adapter('custom-a', $calls); - $customB = $this->adapter('custom-b', $calls); - $proxy = new Proxy('app.example.com', $app, $network, [$customA, $customB], ['network.example.com']); - - $proxy->purgeDomain('app.example.com'); - $proxy->purgePaths('network.example.com', ['/a']); - $proxy->purgeDomain('customer.example.com'); - - $this->assertSame(['app:domain', 'network:paths', 'custom-a:domain', 'custom-b:domain'], $calls->getArrayCopy()); - } - - public function testRejectsMissingCustomAdapters(): void - { - $adapter = $this->adapter('app', new \ArrayObject()); - $proxy = new Proxy('app.example.com', $adapter, $adapter, []); - $this->expectException(Configuration::class); - $proxy->purgeDomain('custom.example.com'); - } - - public function testRejectsKeyPurgeWithoutServiceOrZoneSelection(): void - { - $calls = new \ArrayObject(); - $app = $this->adapter('app', $calls); - $network = $this->adapter('network', $calls); - $custom = $this->adapter('custom', $calls); - $proxy = new Proxy('app.example.com', $app, $network, [$custom]); - - $this->expectException(UnsupportedOperation::class); - $this->expectExceptionMessage('Select the service or zone adapter'); - $proxy->purgeKeys(['key']); - } - - public function testEmptyKeyPurgeIsANoOp(): void - { - $calls = new \ArrayObject(); - $adapter = $this->adapter('adapter', $calls); - $proxy = new Proxy('app.example.com', $adapter, $adapter, [$adapter]); - - $proxy->purgeKeys([]); - - $this->assertSame([], $calls->getArrayCopy()); - } - - /** @param \ArrayObject $calls */ - private function adapter(string $name, \ArrayObject $calls): Adapter - { - return new class ($name, $calls) implements Adapter { - /** @param \ArrayObject $calls */ - public function __construct(private string $name, private \ArrayObject $calls) - { - } - public function purgePaths(string $domain, array $paths): void - { - $this->calls->append($this->name . ':paths'); - } - public function purgeDomain(string $domain): void - { - $this->calls->append($this->name . ':domain'); - } - public function purgeKeys(array $keys): void - { - $this->calls->append($this->name . ':keys'); - } - }; - } -}