annotate core/lib/Drupal/Core/Cache/Cache.php @ 13:5fb285c0d0e3

Update Drupal core to 8.4.7 via Composer. Security update; I *think* we've been lucky to get away with this so far, as we don't support self-registration which seems to be used by the so-called "drupalgeddon 2" attack that 8.4.5 was vulnerable to.
author Chris Cannam
date Mon, 23 Apr 2018 09:33:26 +0100
parents 4c8ae668cc8c
children 1fec387a4317
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Core\Cache;
Chris@0 4
Chris@0 5 use Drupal\Core\Database\Query\SelectInterface;
Chris@0 6
Chris@0 7 /**
Chris@0 8 * Helper methods for cache.
Chris@0 9 *
Chris@0 10 * @ingroup cache
Chris@0 11 */
Chris@0 12 class Cache {
Chris@0 13
Chris@0 14 /**
Chris@0 15 * Indicates that the item should never be removed unless explicitly deleted.
Chris@0 16 */
Chris@0 17 const PERMANENT = CacheBackendInterface::CACHE_PERMANENT;
Chris@0 18
Chris@0 19 /**
Chris@0 20 * Merges arrays of cache contexts and removes duplicates.
Chris@0 21 *
Chris@0 22 * @param array $a
Chris@0 23 * Cache contexts array to merge.
Chris@0 24 * @param array $b
Chris@0 25 * Cache contexts array to merge.
Chris@0 26 *
Chris@0 27 * @return string[]
Chris@0 28 * The merged array of cache contexts.
Chris@0 29 */
Chris@0 30 public static function mergeContexts(array $a = [], array $b = []) {
Chris@0 31 $cache_contexts = array_unique(array_merge($a, $b));
Chris@0 32 assert('\Drupal::service(\'cache_contexts_manager\')->assertValidTokens($cache_contexts)');
Chris@0 33 sort($cache_contexts);
Chris@0 34 return $cache_contexts;
Chris@0 35 }
Chris@0 36
Chris@0 37 /**
Chris@0 38 * Merges arrays of cache tags and removes duplicates.
Chris@0 39 *
Chris@0 40 * The cache tags array is returned in a format that is valid for
Chris@0 41 * \Drupal\Core\Cache\CacheBackendInterface::set().
Chris@0 42 *
Chris@0 43 * When caching elements, it is necessary to collect all cache tags into a
Chris@0 44 * single array, from both the element itself and all child elements. This
Chris@0 45 * allows items to be invalidated based on all tags attached to the content
Chris@0 46 * they're constituted from.
Chris@0 47 *
Chris@0 48 * @param array $a
Chris@0 49 * Cache tags array to merge.
Chris@0 50 * @param array $b
Chris@0 51 * Cache tags array to merge.
Chris@0 52 *
Chris@0 53 * @return string[]
Chris@0 54 * The merged array of cache tags.
Chris@0 55 */
Chris@0 56 public static function mergeTags(array $a = [], array $b = []) {
Chris@0 57 assert('\Drupal\Component\Assertion\Inspector::assertAllStrings($a) && \Drupal\Component\Assertion\Inspector::assertAllStrings($b)', 'Cache tags must be valid strings');
Chris@0 58
Chris@0 59 $cache_tags = array_unique(array_merge($a, $b));
Chris@0 60 sort($cache_tags);
Chris@0 61 return $cache_tags;
Chris@0 62 }
Chris@0 63
Chris@0 64 /**
Chris@0 65 * Merges max-age values (expressed in seconds), finds the lowest max-age.
Chris@0 66 *
Chris@0 67 * Ensures infinite max-age (Cache::PERMANENT) is taken into account.
Chris@0 68 *
Chris@0 69 * @param int $a
Chris@0 70 * Max age value to merge.
Chris@0 71 * @param int $b
Chris@0 72 * Max age value to merge.
Chris@0 73 *
Chris@0 74 * @return int
Chris@0 75 * The minimum max-age value.
Chris@0 76 */
Chris@0 77 public static function mergeMaxAges($a = Cache::PERMANENT, $b = Cache::PERMANENT) {
Chris@0 78 // If one of the values is Cache::PERMANENT, return the other value.
Chris@0 79 if ($a === Cache::PERMANENT) {
Chris@0 80 return $b;
Chris@0 81 }
Chris@0 82 if ($b === Cache::PERMANENT) {
Chris@0 83 return $a;
Chris@0 84 }
Chris@0 85
Chris@0 86 // If none or the values are Cache::PERMANENT, return the minimum value.
Chris@0 87 return min($a, $b);
Chris@0 88 }
Chris@0 89
Chris@0 90 /**
Chris@0 91 * Validates an array of cache tags.
Chris@0 92 *
Chris@0 93 * Can be called before using cache tags in operations, to ensure validity.
Chris@0 94 *
Chris@0 95 * @param string[] $tags
Chris@0 96 * An array of cache tags.
Chris@0 97 *
Chris@0 98 * @deprecated
Chris@0 99 * Use assert('\Drupal\Component\Assertion\Inspector::assertAllStrings($tags)');
Chris@0 100 *
Chris@0 101 * @throws \LogicException
Chris@0 102 */
Chris@0 103 public static function validateTags(array $tags) {
Chris@0 104 if (empty($tags)) {
Chris@0 105 return;
Chris@0 106 }
Chris@0 107 foreach ($tags as $value) {
Chris@0 108 if (!is_string($value)) {
Chris@0 109 throw new \LogicException('Cache tags must be strings, ' . gettype($value) . ' given.');
Chris@0 110 }
Chris@0 111 }
Chris@0 112 }
Chris@0 113
Chris@0 114 /**
Chris@0 115 * Build an array of cache tags from a given prefix and an array of suffixes.
Chris@0 116 *
Chris@0 117 * Each suffix will be converted to a cache tag by appending it to the prefix,
Chris@0 118 * with a colon between them.
Chris@0 119 *
Chris@0 120 * @param string $prefix
Chris@0 121 * A prefix string.
Chris@0 122 * @param array $suffixes
Chris@0 123 * An array of suffixes. Will be cast to strings.
Chris@0 124 * @param string $glue
Chris@0 125 * A string to be used as glue for concatenation. Defaults to a colon.
Chris@0 126 *
Chris@0 127 * @return string[]
Chris@0 128 * An array of cache tags.
Chris@0 129 */
Chris@0 130 public static function buildTags($prefix, array $suffixes, $glue = ':') {
Chris@0 131 $tags = [];
Chris@0 132 foreach ($suffixes as $suffix) {
Chris@0 133 $tags[] = $prefix . $glue . $suffix;
Chris@0 134 }
Chris@0 135 return $tags;
Chris@0 136 }
Chris@0 137
Chris@0 138 /**
Chris@0 139 * Marks cache items from all bins with any of the specified tags as invalid.
Chris@0 140 *
Chris@0 141 * @param string[] $tags
Chris@0 142 * The list of tags to invalidate cache items for.
Chris@0 143 */
Chris@0 144 public static function invalidateTags(array $tags) {
Chris@0 145 \Drupal::service('cache_tags.invalidator')->invalidateTags($tags);
Chris@0 146 }
Chris@0 147
Chris@0 148 /**
Chris@0 149 * Gets all cache bin services.
Chris@0 150 *
Chris@0 151 * @return \Drupal\Core\Cache\CacheBackendInterface[]
Chris@0 152 * An array of cache backend objects keyed by cache bins.
Chris@0 153 */
Chris@0 154 public static function getBins() {
Chris@0 155 $bins = [];
Chris@0 156 $container = \Drupal::getContainer();
Chris@0 157 foreach ($container->getParameter('cache_bins') as $service_id => $bin) {
Chris@0 158 $bins[$bin] = $container->get($service_id);
Chris@0 159 }
Chris@0 160 return $bins;
Chris@0 161 }
Chris@0 162
Chris@0 163 /**
Chris@0 164 * Generates a hash from a query object, to be used as part of the cache key.
Chris@0 165 *
Chris@0 166 * This smart caching strategy saves Drupal from querying and rendering to
Chris@0 167 * HTML when the underlying query is unchanged.
Chris@0 168 *
Chris@0 169 * Expensive queries should use the query builder to create the query and then
Chris@0 170 * call this function. Executing the query and formatting results should
Chris@0 171 * happen in a #pre_render callback.
Chris@0 172 *
Chris@0 173 * @param \Drupal\Core\Database\Query\SelectInterface $query
Chris@0 174 * A select query object.
Chris@0 175 *
Chris@0 176 * @return string
Chris@0 177 * A hash of the query arguments.
Chris@0 178 */
Chris@0 179 public static function keyFromQuery(SelectInterface $query) {
Chris@0 180 $query->preExecute();
Chris@0 181 $keys = [(string) $query, $query->getArguments()];
Chris@0 182 return hash('sha256', serialize($keys));
Chris@0 183 }
Chris@0 184
Chris@0 185 }