|
| 1 | +<?php |
| 2 | + |
| 3 | +namespace Bottledcode\SwytchFramework\Cache\Control; |
| 4 | + |
| 5 | +readonly class Tokenizer |
| 6 | +{ |
| 7 | + public function __construct( |
| 8 | + /** |
| 9 | + * @var int|null Indicates that caches can store this response and reuse it for subsequent requests while it's fresh. |
| 10 | + */ |
| 11 | + public int|null $maxAge = null, |
| 12 | + |
| 13 | + /** |
| 14 | + * @var int|null indicates how long the response remains fresh in a shared cache. |
| 15 | + */ |
| 16 | + public int|null $sMaxAge = null, |
| 17 | + |
| 18 | + /** |
| 19 | + * @var bool indicates that the response can be stored in caches, but the response must be validated with the origin |
| 20 | + * server before each reuse, even when the cache is disconnected from the origin server. |
| 21 | + */ |
| 22 | + public bool $noCache = false, |
| 23 | + |
| 24 | + /** |
| 25 | + * @var bool indicates that the response can be stored in caches and can be reused while fresh. If the response |
| 26 | + * becomes stale, it must be validated with the origin server before reuse. |
| 27 | + */ |
| 28 | + public bool $mustRevalidate = false, |
| 29 | + |
| 30 | + /** |
| 31 | + * @var bool same as must-revalidate, but for proxies |
| 32 | + */ |
| 33 | + public bool $proxyRevalidate = false, |
| 34 | + |
| 35 | + /** |
| 36 | + * @var bool indicates that any caches of any kind (public or shared) should not store this response. |
| 37 | + */ |
| 38 | + public bool $noStore = false, |
| 39 | + |
| 40 | + /** |
| 41 | + * @var bool indicates that any caches of any kind (public or shared) should not store this response. |
| 42 | + */ |
| 43 | + public bool $public = true, |
| 44 | + |
| 45 | + /** |
| 46 | + * @var bool indicates that the response will not be updated while it's fresh. |
| 47 | + */ |
| 48 | + public bool $immutable = false, |
| 49 | + |
| 50 | + /** |
| 51 | + * @var int|null indicates that the cache could reuse a stale response while it revalidates it to a cache. |
| 52 | + */ |
| 53 | + public int|null $staleWhileRevalidating = null, |
| 54 | + |
| 55 | + /** |
| 56 | + * @var int|null indicates that the cache can reuse a stale response when an upstream server generates an error, or |
| 57 | + * when the error is generated locally |
| 58 | + */ |
| 59 | + public int|null $staleIfError = null, |
| 60 | + ) { |
| 61 | + } |
| 62 | + |
| 63 | + public function with( |
| 64 | + int|null|false $maxAge = false, |
| 65 | + int|null|false $sMaxAge = false, |
| 66 | + bool|null $noCache = null, |
| 67 | + bool|null $mustRevalidate = null, |
| 68 | + bool|null $proxyRevalidate = null, |
| 69 | + bool|null $noStore = null, |
| 70 | + bool|null $public = null, |
| 71 | + bool|null $immutable = null, |
| 72 | + int|null|false $staleWhileRevalidating = false, |
| 73 | + int|null|false $staleIfError = false, |
| 74 | + ): self { |
| 75 | + return new self( |
| 76 | + maxAge: $this->withInt($this->maxAge, $maxAge), |
| 77 | + sMaxAge: $this->withInt($this->sMaxAge, $sMaxAge), |
| 78 | + noCache: $this->withBool($this->noCache, $noCache), |
| 79 | + mustRevalidate: $this->withBool($this->mustRevalidate, $mustRevalidate), |
| 80 | + proxyRevalidate: $this->withBool($this->proxyRevalidate, $proxyRevalidate), |
| 81 | + noStore: $this->withBool($this->noStore, $noStore), |
| 82 | + public: $this->withBool($this->public, $public), |
| 83 | + immutable: $this->withBool($this->immutable, $immutable), |
| 84 | + staleWhileRevalidating: $this->withInt($this->staleWhileRevalidating, $staleWhileRevalidating), |
| 85 | + staleIfError: $this->withInt($this->staleIfError, $staleIfError), |
| 86 | + ); |
| 87 | + } |
| 88 | + |
| 89 | + private function withInt(int|null $original, int|null|false $var): int|null |
| 90 | + { |
| 91 | + return $var === false ? $original : $var; |
| 92 | + } |
| 93 | + |
| 94 | + private function withBool(bool $original, bool|null $var): bool |
| 95 | + { |
| 96 | + return $var ?? $original; |
| 97 | + } |
| 98 | + |
| 99 | + public function render(): string |
| 100 | + { |
| 101 | + $header = [ |
| 102 | + $this->public ? 'public' : 'private', |
| 103 | + ...$this->header($this->maxAge, "max-age=$this->maxAge"), |
| 104 | + ...$this->header($this->sMaxAge, "s-maxage=$this->sMaxAge"), |
| 105 | + ...$this->header($this->noCache, "no-cache"), |
| 106 | + ...$this->header($this->mustRevalidate, "must-revalidate"), |
| 107 | + ...$this->header($this->proxyRevalidate, "proxy-revalidate"), |
| 108 | + ...$this->header($this->noStore, "no-store"), |
| 109 | + ...$this->header($this->immutable, "immutable"), |
| 110 | + ...$this->header($this->staleWhileRevalidating, "stale-while-revalidate=$this->staleWhileRevalidating"), |
| 111 | + ...$this->header($this->staleIfError, "stale-if-error=$this->staleIfError"), |
| 112 | + ]; |
| 113 | + |
| 114 | + return implode(' ', $header); |
| 115 | + } |
| 116 | + |
| 117 | + private function header($prop, $value): array |
| 118 | + { |
| 119 | + return $prop ? [$value] : []; |
| 120 | + } |
| 121 | +} |
0 commit comments