CacheableMetadata.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <?php
  2. namespace Drupal\Core\Cache;
  3. /**
  4. * Defines a generic class for passing cacheability metadata.
  5. *
  6. * @ingroup cache
  7. */
  8. class CacheableMetadata implements RefinableCacheableDependencyInterface {
  9. use RefinableCacheableDependencyTrait;
  10. /**
  11. * {@inheritdoc}
  12. */
  13. public function getCacheTags() {
  14. return $this->cacheTags;
  15. }
  16. /**
  17. * Sets cache tags.
  18. *
  19. * @param string[] $cache_tags
  20. * The cache tags to be associated.
  21. *
  22. * @return $this
  23. */
  24. public function setCacheTags(array $cache_tags) {
  25. $this->cacheTags = $cache_tags;
  26. return $this;
  27. }
  28. /**
  29. * {@inheritdoc}
  30. */
  31. public function getCacheContexts() {
  32. return $this->cacheContexts;
  33. }
  34. /**
  35. * Sets cache contexts.
  36. *
  37. * @param string[] $cache_contexts
  38. * The cache contexts to be associated.
  39. *
  40. * @return $this
  41. */
  42. public function setCacheContexts(array $cache_contexts) {
  43. $this->cacheContexts = $cache_contexts;
  44. return $this;
  45. }
  46. /**
  47. * {@inheritdoc}
  48. */
  49. public function getCacheMaxAge() {
  50. return $this->cacheMaxAge;
  51. }
  52. /**
  53. * Sets the maximum age (in seconds).
  54. *
  55. * Defaults to Cache::PERMANENT
  56. *
  57. * @param int $max_age
  58. * The max age to associate.
  59. *
  60. * @return $this
  61. *
  62. * @throws \InvalidArgumentException
  63. * If a non-integer value is supplied.
  64. */
  65. public function setCacheMaxAge($max_age) {
  66. if (!is_int($max_age)) {
  67. throw new \InvalidArgumentException('$max_age must be an integer');
  68. }
  69. $this->cacheMaxAge = $max_age;
  70. return $this;
  71. }
  72. /**
  73. * Merges the values of another CacheableMetadata object with this one.
  74. *
  75. * @param \Drupal\Core\Cache\CacheableMetadata $other
  76. * The other CacheableMetadata object.
  77. *
  78. * @return static
  79. * A new CacheableMetadata object, with the merged data.
  80. */
  81. public function merge(CacheableMetadata $other) {
  82. $result = clone $this;
  83. // This is called many times per request, so avoid merging unless absolutely
  84. // necessary.
  85. if (empty($this->cacheContexts)) {
  86. $result->cacheContexts = $other->cacheContexts;
  87. }
  88. elseif (empty($other->cacheContexts)) {
  89. $result->cacheContexts = $this->cacheContexts;
  90. }
  91. else {
  92. $result->cacheContexts = Cache::mergeContexts($this->cacheContexts, $other->cacheContexts);
  93. }
  94. if (empty($this->cacheTags)) {
  95. $result->cacheTags = $other->cacheTags;
  96. }
  97. elseif (empty($other->cacheTags)) {
  98. $result->cacheTags = $this->cacheTags;
  99. }
  100. else {
  101. $result->cacheTags = Cache::mergeTags($this->cacheTags, $other->cacheTags);
  102. }
  103. if ($this->cacheMaxAge === Cache::PERMANENT) {
  104. $result->cacheMaxAge = $other->cacheMaxAge;
  105. }
  106. elseif ($other->cacheMaxAge === Cache::PERMANENT) {
  107. $result->cacheMaxAge = $this->cacheMaxAge;
  108. }
  109. else {
  110. $result->cacheMaxAge = Cache::mergeMaxAges($this->cacheMaxAge, $other->cacheMaxAge);
  111. }
  112. return $result;
  113. }
  114. /**
  115. * Applies the values of this CacheableMetadata object to a render array.
  116. *
  117. * @param array &$build
  118. * A render array.
  119. */
  120. public function applyTo(array &$build) {
  121. $build['#cache']['contexts'] = $this->cacheContexts;
  122. $build['#cache']['tags'] = $this->cacheTags;
  123. $build['#cache']['max-age'] = $this->cacheMaxAge;
  124. }
  125. /**
  126. * Creates a CacheableMetadata object with values taken from a render array.
  127. *
  128. * @param array $build
  129. * A render array.
  130. *
  131. * @return static
  132. */
  133. public static function createFromRenderArray(array $build) {
  134. $meta = new static();
  135. $meta->cacheContexts = (isset($build['#cache']['contexts'])) ? $build['#cache']['contexts'] : [];
  136. $meta->cacheTags = (isset($build['#cache']['tags'])) ? $build['#cache']['tags'] : [];
  137. $meta->cacheMaxAge = (isset($build['#cache']['max-age'])) ? $build['#cache']['max-age'] : Cache::PERMANENT;
  138. return $meta;
  139. }
  140. /**
  141. * Creates a CacheableMetadata object from a depended object.
  142. *
  143. * @param \Drupal\Core\Cache\CacheableDependencyInterface|mixed $object
  144. * The object whose cacheability metadata to retrieve. If it implements
  145. * CacheableDependencyInterface, its cacheability metadata will be used,
  146. * otherwise, the passed in object must be assumed to be uncacheable, so
  147. * max-age 0 is set.
  148. *
  149. * @return static
  150. */
  151. public static function createFromObject($object) {
  152. if ($object instanceof CacheableDependencyInterface) {
  153. $meta = new static();
  154. $meta->cacheContexts = $object->getCacheContexts();
  155. $meta->cacheTags = $object->getCacheTags();
  156. $meta->cacheMaxAge = $object->getCacheMaxAge();
  157. return $meta;
  158. }
  159. // Objects that don't implement CacheableDependencyInterface must be assumed
  160. // to be uncacheable, so set max-age 0.
  161. $meta = new static();
  162. $meta->cacheMaxAge = 0;
  163. return $meta;
  164. }
  165. }