Chris@0: placeholderGenerator = $placeholder_generator; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function get(array $elements) { Chris@0: // @todo remove this check when https://www.drupal.org/node/2367555 lands. Chris@0: if (!$this->requestStack->getCurrentRequest()->isMethodCacheable()) { Chris@0: return FALSE; Chris@0: } Chris@0: Chris@0: // When rendering placeholders, special case auto-placeholdered elements: Chris@0: // avoid retrieving them from cache again, or rendering them again. Chris@0: if (isset($elements['#create_placeholder']) && $elements['#create_placeholder'] === FALSE) { Chris@0: $cached_placeholder_result = $this->getFromPlaceholderResultsCache($elements); Chris@0: if ($cached_placeholder_result !== FALSE) { Chris@0: return $cached_placeholder_result; Chris@0: } Chris@0: } Chris@0: Chris@0: $cached_element = parent::get($elements); Chris@0: Chris@0: if ($cached_element === FALSE) { Chris@0: return FALSE; Chris@0: } Chris@0: else { Chris@0: if ($this->placeholderGenerator->canCreatePlaceholder($elements) && $this->placeholderGenerator->shouldAutomaticallyPlaceholder($cached_element)) { Chris@0: return $this->createPlaceholderAndRemember($cached_element, $elements); Chris@0: } Chris@0: Chris@0: return $cached_element; Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function set(array &$elements, array $pre_bubbling_elements) { Chris@0: $result = parent::set($elements, $pre_bubbling_elements); Chris@0: Chris@0: // @todo remove this check when https://www.drupal.org/node/2367555 lands. Chris@0: if (!$this->requestStack->getCurrentRequest()->isMethodCacheable()) { Chris@0: return FALSE; Chris@0: } Chris@0: Chris@0: if ($this->placeholderGenerator->canCreatePlaceholder($pre_bubbling_elements) && $this->placeholderGenerator->shouldAutomaticallyPlaceholder($elements)) { Chris@0: // Overwrite $elements with a placeholder. The Renderer (which called this Chris@0: // method) will update the context with the bubbleable metadata of the Chris@0: // overwritten $elements. Chris@0: $elements = $this->createPlaceholderAndRemember($this->getCacheableRenderArray($elements), $pre_bubbling_elements); Chris@0: } Chris@0: Chris@0: return $result; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Create a placeholder for a renderable array and remember in a static cache. Chris@0: * Chris@0: * @param array $rendered_elements Chris@0: * A fully rendered renderable array. Chris@0: * @param array $pre_bubbling_elements Chris@0: * A renderable array corresponding to the state (in particular, the Chris@0: * cacheability metadata) of $rendered_elements prior to the beginning of Chris@0: * its rendering process, and therefore before any bubbling of child Chris@0: * information has taken place. Only the #cache property is used by this Chris@0: * function, so the caller may omit all other properties and children from Chris@0: * this array. Chris@0: * Chris@0: * @return array Chris@0: * Renderable array with placeholder markup and the attached placeholder Chris@0: * replacement metadata. Chris@0: */ Chris@0: protected function createPlaceholderAndRemember(array $rendered_elements, array $pre_bubbling_elements) { Chris@0: $placeholder_element = $this->placeholderGenerator->createPlaceholder($pre_bubbling_elements); Chris@0: // Remember the result for this placeholder to avoid double work. Chris@0: $placeholder = (string) $placeholder_element['#markup']; Chris@0: $this->placeholderResultsCache[$placeholder] = $rendered_elements; Chris@0: return $placeholder_element; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Retrieves an auto-placeholdered renderable array from the static cache. Chris@0: * Chris@0: * @param array $elements Chris@0: * A renderable array. Chris@0: * Chris@0: * @return array|false Chris@0: * A renderable array, with the original element and all its children pre- Chris@0: * rendered, or FALSE if no cached copy of the element is available. Chris@0: */ Chris@0: protected function getFromPlaceholderResultsCache(array $elements) { Chris@0: $placeholder_element = $this->placeholderGenerator->createPlaceholder($elements); Chris@0: $placeholder = (string) $placeholder_element['#markup']; Chris@0: if (isset($this->placeholderResultsCache[$placeholder])) { Chris@0: return $this->placeholderResultsCache[$placeholder]; Chris@0: } Chris@0: return FALSE; Chris@0: } Chris@0: Chris@0: }