/src/Symfony/Component/Cache/CacheItem.php

https://github.com/pulzarraider/symfony · PHP · 186 lines · 117 code · 20 blank · 49 comment · 16 complexity · b3351bd9ce136568a0eac66ddd208dcc MD5 · raw file

  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Cache;
  11. use Psr\Log\LoggerInterface;
  12. use Symfony\Component\Cache\Exception\InvalidArgumentException;
  13. use Symfony\Component\Cache\Exception\LogicException;
  14. use Symfony\Contracts\Cache\ItemInterface;
  15. /**
  16. * @author Nicolas Grekas <p@tchwork.com>
  17. */
  18. final class CacheItem implements ItemInterface
  19. {
  20. private const METADATA_EXPIRY_OFFSET = 1527506807;
  21. protected $key;
  22. protected $value;
  23. protected $isHit = false;
  24. protected $expiry;
  25. protected $defaultLifetime;
  26. protected $metadata = [];
  27. protected $newMetadata = [];
  28. protected $innerItem;
  29. protected $poolHash;
  30. protected $isTaggable = false;
  31. /**
  32. * {@inheritdoc}
  33. */
  34. public function getKey()
  35. {
  36. return $this->key;
  37. }
  38. /**
  39. * {@inheritdoc}
  40. */
  41. public function get()
  42. {
  43. return $this->value;
  44. }
  45. /**
  46. * {@inheritdoc}
  47. */
  48. public function isHit()
  49. {
  50. return $this->isHit;
  51. }
  52. /**
  53. * {@inheritdoc}
  54. */
  55. public function set($value)
  56. {
  57. $this->value = $value;
  58. return $this;
  59. }
  60. /**
  61. * {@inheritdoc}
  62. */
  63. public function expiresAt($expiration)
  64. {
  65. if (null === $expiration) {
  66. $this->expiry = $this->defaultLifetime > 0 ? microtime(true) + $this->defaultLifetime : null;
  67. } elseif ($expiration instanceof \DateTimeInterface) {
  68. $this->expiry = (float) $expiration->format('U.u');
  69. } else {
  70. throw new InvalidArgumentException(sprintf('Expiration date must implement DateTimeInterface or be null, "%s" given', \is_object($expiration) ? \get_class($expiration) : \gettype($expiration)));
  71. }
  72. return $this;
  73. }
  74. /**
  75. * {@inheritdoc}
  76. */
  77. public function expiresAfter($time)
  78. {
  79. if (null === $time) {
  80. $this->expiry = $this->defaultLifetime > 0 ? microtime(true) + $this->defaultLifetime : null;
  81. } elseif ($time instanceof \DateInterval) {
  82. $this->expiry = microtime(true) + \DateTime::createFromFormat('U', 0)->add($time)->format('U.u');
  83. } elseif (\is_int($time)) {
  84. $this->expiry = $time + microtime(true);
  85. } else {
  86. throw new InvalidArgumentException(sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given', \is_object($time) ? \get_class($time) : \gettype($time)));
  87. }
  88. return $this;
  89. }
  90. /**
  91. * {@inheritdoc}
  92. */
  93. public function tag($tags): ItemInterface
  94. {
  95. if (!$this->isTaggable) {
  96. throw new LogicException(sprintf('Cache item "%s" comes from a non tag-aware pool: you cannot tag it.', $this->key));
  97. }
  98. if (!\is_iterable($tags)) {
  99. $tags = [$tags];
  100. }
  101. foreach ($tags as $tag) {
  102. if (!\is_string($tag)) {
  103. throw new InvalidArgumentException(sprintf('Cache tag must be string, "%s" given', \is_object($tag) ? \get_class($tag) : \gettype($tag)));
  104. }
  105. if (isset($this->newMetadata[self::METADATA_TAGS][$tag])) {
  106. continue;
  107. }
  108. if ('' === $tag) {
  109. throw new InvalidArgumentException('Cache tag length must be greater than zero');
  110. }
  111. if (false !== strpbrk($tag, '{}()/\@:')) {
  112. throw new InvalidArgumentException(sprintf('Cache tag "%s" contains reserved characters {}()/\@:', $tag));
  113. }
  114. $this->newMetadata[self::METADATA_TAGS][$tag] = $tag;
  115. }
  116. return $this;
  117. }
  118. /**
  119. * {@inheritdoc}
  120. */
  121. public function getMetadata(): array
  122. {
  123. return $this->metadata;
  124. }
  125. /**
  126. * Validates a cache key according to PSR-6.
  127. *
  128. * @param string $key The key to validate
  129. *
  130. * @return string
  131. *
  132. * @throws InvalidArgumentException When $key is not valid
  133. */
  134. public static function validateKey($key)
  135. {
  136. if (!\is_string($key)) {
  137. throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given', \is_object($key) ? \get_class($key) : \gettype($key)));
  138. }
  139. if ('' === $key) {
  140. throw new InvalidArgumentException('Cache key length must be greater than zero');
  141. }
  142. if (false !== strpbrk($key, '{}()/\@:')) {
  143. throw new InvalidArgumentException(sprintf('Cache key "%s" contains reserved characters {}()/\@:', $key));
  144. }
  145. return $key;
  146. }
  147. /**
  148. * Internal logging helper.
  149. *
  150. * @internal
  151. */
  152. public static function log(LoggerInterface $logger = null, $message, $context = [])
  153. {
  154. if ($logger) {
  155. $logger->warning($message, $context);
  156. } else {
  157. $replace = [];
  158. foreach ($context as $k => $v) {
  159. if (is_scalar($v)) {
  160. $replace['{'.$k.'}'] = $v;
  161. }
  162. }
  163. @trigger_error(strtr($message, $replace), E_USER_WARNING);
  164. }
  165. }
  166. }