diff --git a/core/includes/common.inc b/core/includes/common.inc index 4843551..a01d47d 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -6094,9 +6094,10 @@ function drupal_render_cache_set(&$markup, $elements) { if ($attached) { $data['#attached'] = $attached; } + $tags = drupal_render_collect_cache_tags($elements, TRUE); $bin = isset($elements['#cache']['bin']) ? $elements['#cache']['bin'] : 'cache'; $expire = isset($elements['#cache']['expire']) ? $elements['#cache']['expire'] : CACHE_PERMANENT; - cache($bin)->set($cid, $data, $expire); + cache($bin)->set($cid, $data, $expire, $tags); } /** @@ -6143,6 +6144,57 @@ function drupal_render_collect_attached($elements, $return = FALSE) { } /** + * Collects cache tags for an element and its children into a single array. + * + * When caching elements, it is necessary to collect all cache tags into a + * single array, from both the element itself and all child elements. This + * allows items to be invalidated based on all tags attached to the content + * they're constituted from. + * + * @param $elements + * The element to collect #cache_tags from. + * @param $return + * Whether to return the attached elements and reset the internal static. + * + * @return + * The #attached array for this element and its descendants. + */ +function drupal_render_collect_cache_tags($elements, $return = FALSE) { + $tags = &drupal_static(__FUNCTION__, array()); + + // Collect all #attached for this element. + if (isset($elements['#cache']['tags'])) { + foreach ($elements['#cache']['tags'] as $namespace => $values) { + if (is_array($values)) { + foreach ($values as $value) { + if (!isset($tags[$namespace][$value])) { + $tags[$namespace][$value] = $value; + } + } + } + else { + if (!isset($tags[$namespace])) { + $tags[$namespace] = $values; + } + } + } + } + if ($children = element_children($elements)) { + foreach ($children as $child) { + drupal_render_collect_cache_tags($elements[$child]); + } + } + + // If this was the first call to the function, return all attached elements + // and reset the static cache. + if ($return) { + $return = $tags; + $tags = array(); + return $return; + } +} + +/** * Prepares an element for caching based on a query. * * This smart caching strategy saves Drupal from querying and rendering to HTML