Rev 1 | AutorÃa | Comparar con el anterior | Ultima modificación | Ver Log |
<?phpnamespace Kevinrob\GuzzleCache;use GuzzleHttp\Psr7\PumpStream;use Psr\Http\Message\MessageInterface;use Psr\Http\Message\RequestInterface;use Psr\Http\Message\ResponseInterface;class CacheEntry implements \Serializable{/*** @var RequestInterface*/protected $request;/*** @var ResponseInterface*/protected $response;/*** @var \DateTime*/protected $staleAt;/*** @var \DateTime*/protected $staleIfErrorTo;/*** @var \DateTime*/protected $staleWhileRevalidateTo;/*** @var \DateTime*/protected $dateCreated;/*** Cached timestamp of staleAt variable.** @var int*/protected $timestampStale;/*** @param RequestInterface $request* @param ResponseInterface $response* @param \DateTime $staleAt* @param \DateTime|null $staleIfErrorTo if null, detected with the headers (RFC 5861)* @param \DateTime|null $staleWhileRevalidateTo*/public function __construct(RequestInterface $request,ResponseInterface $response,\DateTime $staleAt,?\DateTime $staleIfErrorTo = null,?\DateTime $staleWhileRevalidateTo = null) {$this->dateCreated = new \DateTime();$this->request = $request;$this->response = $response;$this->staleAt = $staleAt;$values = new KeyValueHttpHeader($response->getHeader('Cache-Control'));if ($staleIfErrorTo === null && $values->has('stale-if-error')) {$this->staleIfErrorTo = (new \DateTime('@'.($this->staleAt->getTimestamp() + (int) $values->get('stale-if-error'))));} else {$this->staleIfErrorTo = $staleIfErrorTo;}if ($staleWhileRevalidateTo === null && $values->has('stale-while-revalidate')) {$this->staleWhileRevalidateTo = new \DateTime('@'.($this->staleAt->getTimestamp() + (int) $values->get('stale-while-revalidate')));} else {$this->staleWhileRevalidateTo = $staleWhileRevalidateTo;}}/*** @return ResponseInterface*/public function getResponse(){return $this->response->withHeader('Age', $this->getAge());}/*** @return ResponseInterface*/public function getOriginalResponse(){return $this->response;}/*** @return RequestInterface*/public function getOriginalRequest(){return $this->request;}/*** @param RequestInterface $request* @return bool*/public function isVaryEquals(RequestInterface $request){if ($this->response->hasHeader('Vary')) {if ($this->request === null) {return false;}foreach ($this->getVaryHeaders() as $key => $value) {if (!$this->request->hasHeader($key)&& !$request->hasHeader($key)) {// Absent from bothcontinue;} elseif ($this->request->getHeaderLine($key)== $request->getHeaderLine($key)) {// Same contentcontinue;}return false;}}return true;}/*** Get the vary headers that should be honoured by the cache.** @return KeyValueHttpHeader*/public function getVaryHeaders(){return new KeyValueHttpHeader($this->response->getHeader('Vary'));}/*** @return \DateTime*/public function getStaleAt(){return $this->staleAt;}/*** @return bool*/public function isFresh(){return !$this->isStale();}/*** @return bool*/public function isStale(){return $this->getStaleAge() > 0;}/*** @return int positive value equal staled*/public function getStaleAge(){// This object is immutableif ($this->timestampStale === null) {$this->timestampStale = $this->staleAt->getTimestamp();}return time() - $this->timestampStale;}/*** @return bool*/public function serveStaleIfError(){return $this->staleIfErrorTo !== null&& $this->staleIfErrorTo->getTimestamp() >= (new \DateTime())->getTimestamp();}/*** @return bool*/public function staleWhileValidate(){return $this->staleWhileRevalidateTo !== null&& $this->staleWhileRevalidateTo->getTimestamp() >= (new \DateTime())->getTimestamp();}/*** @return bool*/public function hasValidationInformation(){return $this->response->hasHeader('Etag') || $this->response->hasHeader('Last-Modified');}/*** Time in seconds how long the entry should be kept in the cache** This will not give the time (in seconds) that the response will still be fresh for* from the HTTP point of view, but an upper bound on how long it is necessary and* reasonable to keep the response in a cache (to re-use it or re-validate it later on).** @return int TTL in seconds (0 = infinite)*/public function getTTL(){if ($this->hasValidationInformation()) {// No TTL if we have a way to re-validate the cachereturn 0;}$ttl = 0;// Keep it when stale if errorif ($this->staleIfErrorTo !== null) {$ttl = max($ttl, $this->staleIfErrorTo->getTimestamp() - time());}// Keep it when stale-while-revalidateif ($this->staleWhileRevalidateTo !== null) {$ttl = max($ttl, $this->staleWhileRevalidateTo->getTimestamp() - time());}// Keep it until it become stale$ttl = max($ttl, $this->staleAt->getTimestamp() - time());// Don't return 0, it's reserved for infinite TTLreturn $ttl !== 0 ? (int) $ttl : -1;}/*** @return int Age in seconds*/public function getAge(){return time() - $this->dateCreated->getTimestamp();}public function __serialize(): array{return ['request' => self::toSerializeableMessage($this->request),'response' => $this->response !== null ? self::toSerializeableMessage($this->response) : null,'staleAt' => $this->staleAt,'staleIfErrorTo' => $this->staleIfErrorTo,'staleWhileRevalidateTo' => $this->staleWhileRevalidateTo,'dateCreated' => $this->dateCreated,'timestampStale' => $this->timestampStale,];}public function __unserialize(array $data): void{$prefix = '';if (isset($data["\0*\0request"])) {// We are unserializing a cache entry which was serialized with a version < 4.1.1$prefix = "\0*\0";}$this->request = self::restoreStreamBody($data[$prefix.'request']);$this->response = $data[$prefix.'response'] !== null ? self::restoreStreamBody($data[$prefix.'response']) : null;$this->staleAt = $data[$prefix.'staleAt'];$this->staleIfErrorTo = $data[$prefix.'staleIfErrorTo'];$this->staleWhileRevalidateTo = $data[$prefix.'staleWhileRevalidateTo'];$this->dateCreated = $data[$prefix.'dateCreated'];$this->timestampStale = $data[$prefix.'timestampStale'];}/*** Stream/Resource can't be serialized... So we copy the content into an implementation of `Psr\Http\Message\StreamInterface`** @template T of MessageInterface** @param T $message* @return T*/private static function toSerializeableMessage(MessageInterface $message): MessageInterface{$bodyString = (string)$message->getBody();return $message->withBody(new PumpStream(new BodyStore($bodyString),['size' => mb_strlen($bodyString),]));}/*** @template T of MessageInterface** @param T $message* @return T*/private static function restoreStreamBody(MessageInterface $message): MessageInterface{return $message->withBody(\GuzzleHttp\Psr7\Utils::streamFor((string) $message->getBody()));}public function serialize(){return serialize($this->__serialize());}public function unserialize($data){$this->__unserialize(unserialize($data));}}