View source
<?php
namespace Drupal\render_cache\Cache;
use RenderCache;
class RenderCachePlaceholder implements RenderCachePlaceholderInterface {
public static function getPlaceholder($function, array $args = array(), $multiple = FALSE) {
$callback = get_called_class();
$callback .= $multiple ? '::postRenderCacheMultiCallback' : '::postRenderCacheCallback';
$context = array(
'function' => $function,
'args' => $args,
);
$placeholder = static::generatePlaceholder($context['function'], $context);
$context = array(
$context,
);
if ($multiple) {
$context = array(
$function => $context,
);
}
return array(
'#post_render_cache' => array(
$callback => $context,
),
'#markup' => $placeholder,
);
}
public static function postRenderCacheMultiCallback(array $element, array $contexts) {
if (isset($contexts['function']) || !isset($contexts[0]['function'])) {
return $element;
}
$function = $contexts[0]['function'];
$args = array();
foreach ($contexts as $context) {
$placeholder = static::generatePlaceholder($context['function'], $context);
if (strpos($element['#markup'], $placeholder) === FALSE) {
continue;
}
$args[$placeholder] = static::loadPlaceholderFunctionArgs($context);
}
$placeholders = call_user_func($function, $args);
foreach ($placeholders as $placeholder => $new_element) {
$markup = static::drupalRender($new_element);
$element['#markup'] = str_replace($placeholder, $markup, $element['#markup']);
}
return $element;
}
public static function postRenderCacheCallback(array $element, array $context) {
$placeholder = static::generatePlaceholder($context['function'], $context);
if (strpos($element['#markup'], $placeholder) === FALSE) {
return $element;
}
$function = $context['function'];
$args = static::loadPlaceholderFunctionArgs($context);
$new_element = call_user_func_array($function, $args);
$markup = static::drupalRender($new_element);
$element['#markup'] = str_replace($placeholder, $markup, $element['#markup']);
return $element;
}
public static function loadPlaceholderFunctionArgs(array $context) {
$args = array();
foreach ($context['args'] as $key => $arg) {
if (strpos($key, '%') !== 0) {
$args[$key] = $arg;
continue;
}
$prefix = substr($key, 1);
$loader_functions = array(
$prefix . '_load',
$prefix . 'Load',
);
foreach ($loader_functions as $loader_function) {
if (is_callable($loader_function)) {
$arg = call_user_func($loader_function, $arg);
}
}
$args[$key] = $arg;
}
return $args;
}
protected static function generatePlaceholder($callback, array &$context) {
return drupal_render_cache_generate_placeholder($callback, $context);
}
protected static function drupalRender(array &$elements) {
return RenderCache::drupalRender($elements);
}
}