Chris@0: assertValidTokens($cache_contexts)); Chris@0: sort($cache_contexts); Chris@0: return $cache_contexts; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Merges arrays of cache tags and removes duplicates. Chris@0: * Chris@0: * The cache tags array is returned in a format that is valid for Chris@0: * \Drupal\Core\Cache\CacheBackendInterface::set(). Chris@0: * Chris@0: * When caching elements, it is necessary to collect all cache tags into a Chris@0: * single array, from both the element itself and all child elements. This Chris@0: * allows items to be invalidated based on all tags attached to the content Chris@0: * they're constituted from. Chris@0: * Chris@0: * @param array $a Chris@0: * Cache tags array to merge. Chris@0: * @param array $b Chris@0: * Cache tags array to merge. Chris@0: * Chris@0: * @return string[] Chris@0: * The merged array of cache tags. Chris@0: */ Chris@0: public static function mergeTags(array $a = [], array $b = []) { Chris@14: assert(Inspector::assertAllStrings($a) && Inspector::assertAllStrings($b), 'Cache tags must be valid strings'); Chris@0: Chris@0: $cache_tags = array_unique(array_merge($a, $b)); Chris@0: sort($cache_tags); Chris@0: return $cache_tags; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Merges max-age values (expressed in seconds), finds the lowest max-age. Chris@0: * Chris@0: * Ensures infinite max-age (Cache::PERMANENT) is taken into account. Chris@0: * Chris@0: * @param int $a Chris@0: * Max age value to merge. Chris@0: * @param int $b Chris@0: * Max age value to merge. Chris@0: * Chris@0: * @return int Chris@0: * The minimum max-age value. Chris@0: */ Chris@0: public static function mergeMaxAges($a = Cache::PERMANENT, $b = Cache::PERMANENT) { Chris@0: // If one of the values is Cache::PERMANENT, return the other value. Chris@0: if ($a === Cache::PERMANENT) { Chris@0: return $b; Chris@0: } Chris@0: if ($b === Cache::PERMANENT) { Chris@0: return $a; Chris@0: } Chris@0: Chris@0: // If none or the values are Cache::PERMANENT, return the minimum value. Chris@0: return min($a, $b); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Validates an array of cache tags. Chris@0: * Chris@0: * Can be called before using cache tags in operations, to ensure validity. Chris@0: * Chris@0: * @param string[] $tags Chris@0: * An array of cache tags. Chris@0: * Chris@0: * @deprecated Chris@14: * Use assert(Inspector::assertAllStrings($tags)); Chris@0: * Chris@0: * @throws \LogicException Chris@0: */ Chris@0: public static function validateTags(array $tags) { Chris@0: if (empty($tags)) { Chris@0: return; Chris@0: } Chris@0: foreach ($tags as $value) { Chris@0: if (!is_string($value)) { Chris@0: throw new \LogicException('Cache tags must be strings, ' . gettype($value) . ' given.'); Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Build an array of cache tags from a given prefix and an array of suffixes. Chris@0: * Chris@0: * Each suffix will be converted to a cache tag by appending it to the prefix, Chris@0: * with a colon between them. Chris@0: * Chris@0: * @param string $prefix Chris@0: * A prefix string. Chris@0: * @param array $suffixes Chris@0: * An array of suffixes. Will be cast to strings. Chris@0: * @param string $glue Chris@0: * A string to be used as glue for concatenation. Defaults to a colon. Chris@0: * Chris@0: * @return string[] Chris@0: * An array of cache tags. Chris@0: */ Chris@0: public static function buildTags($prefix, array $suffixes, $glue = ':') { Chris@0: $tags = []; Chris@0: foreach ($suffixes as $suffix) { Chris@0: $tags[] = $prefix . $glue . $suffix; Chris@0: } Chris@0: return $tags; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Marks cache items from all bins with any of the specified tags as invalid. Chris@0: * Chris@0: * @param string[] $tags Chris@0: * The list of tags to invalidate cache items for. Chris@0: */ Chris@0: public static function invalidateTags(array $tags) { Chris@0: \Drupal::service('cache_tags.invalidator')->invalidateTags($tags); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets all cache bin services. Chris@0: * Chris@0: * @return \Drupal\Core\Cache\CacheBackendInterface[] Chris@0: * An array of cache backend objects keyed by cache bins. Chris@0: */ Chris@0: public static function getBins() { Chris@0: $bins = []; Chris@0: $container = \Drupal::getContainer(); Chris@0: foreach ($container->getParameter('cache_bins') as $service_id => $bin) { Chris@0: $bins[$bin] = $container->get($service_id); Chris@0: } Chris@0: return $bins; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Generates a hash from a query object, to be used as part of the cache key. Chris@0: * Chris@0: * This smart caching strategy saves Drupal from querying and rendering to Chris@0: * HTML when the underlying query is unchanged. Chris@0: * Chris@0: * Expensive queries should use the query builder to create the query and then Chris@0: * call this function. Executing the query and formatting results should Chris@0: * happen in a #pre_render callback. Chris@0: * Chris@0: * @param \Drupal\Core\Database\Query\SelectInterface $query Chris@0: * A select query object. Chris@0: * Chris@0: * @return string Chris@0: * A hash of the query arguments. Chris@0: */ Chris@0: public static function keyFromQuery(SelectInterface $query) { Chris@0: $query->preExecute(); Chris@0: $keys = [(string) $query, $query->getArguments()]; Chris@0: return hash('sha256', serialize($keys)); Chris@0: } Chris@0: Chris@0: }