function render_cache_entity_view_callback in Render cache 7
Same name and namespace in other branches
- 7.2 modules/controller/render_cache_entity/render_cache_entity.module \render_cache_entity_view_callback()
Override entity API rendering callback to add a caching layer.
This callback is registered as $entity_info[$type]['view callback'] with hook_entity_info_alter()
Parameters
object[] $entities:
string $view_mode:
string|null $langcode:
string $entity_type:
Return value
array
Throws
See also
render_cache_entity_info_alter()
1 string reference to 'render_cache_entity_view_callback'
- render_cache_entity_info_alter in ./
render_cache.module - Implements hook_entity_info_alter().
File
- ./
render_cache.module, line 25 - Hook implementations and frequently used functions for render cache module.
Code
function render_cache_entity_view_callback($entities, $view_mode, $langcode = NULL, $entity_type) {
// Remove any passed values that are not an object, this can happen with out
// of date Apache Solr search when entities are deleted and probably other
// situations.
foreach ($entities as $key => $entity) {
if (!is_object($entity)) {
unset($entities[$key]);
}
}
$entity_info = entity_get_info($entity_type);
$entity_order = array_keys($entities);
// Prepare context
$context = array(
'entity_type' => $entity_type,
'view_mode' => $view_mode,
'langcode' => $langcode,
);
// Setup drupal_render style cache array.
$cache_info = render_cache_cache_info_defaults();
$cache_info['keys'] = array(
'entity',
$entity_type,
$view_mode,
);
/* @see hook_render_cache_block_default_cache_info_alter() */
drupal_alter('render_cache_entity_default_cache_info', $cache_info, $context);
// Retrieve a list of cache_ids
$cid_map = array();
foreach ($entities as $id => $entity) {
list($entity_id, $entity_revision_id, $bundle) = entity_extract_ids($entity_type, $entity);
$entity_context = $context + array(
'entity_id' => $entity_id,
'entity_revision_id' => $entity_revision_id,
'bundle' => $bundle,
);
$cid_map[$id] = render_cache_get_entity_cid($entity, $cache_info, $entity_context);
}
$cids = array_values($cid_map);
$cached_entities = array();
if (isset($cache_info['granularity']) && $cache_info['granularity'] != DRUPAL_NO_CACHE) {
$cached_entities = cache_get_multiple($cids, 'cache_render');
}
// Calculate remaining entities
$cid_remaining = array_intersect($cid_map, $cids);
$entities = array_intersect_key($entities, $cid_remaining);
// Render non-cached entities.
if (!empty($entities)) {
// If this is a view callback.
if (isset($entity_info['render cache']['callback'])) {
$rendered = $entity_info['render cache']['callback']($entities, $view_mode, $langcode, $entity_type);
}
else {
// We need the $page variable from entity_view() that it does not pass us.
if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
// Get only the stack frames we need (PHP 5.4 only).
$backtrace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
}
elseif (version_compare(PHP_VERSION, '5.3.6', '>=')) {
$backtrace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT);
}
else {
// @see http://php.net/manual/en/function.debug-backtrace.php#refsect1-function.debug-backtrace-parameters
$backtrace = debug_backtrace(TRUE);
}
$page = NULL;
// As a safety, do not grab an unexpected arg for $page, check that this
// was called from entity_view().
if (isset($backtrace[1]['function']) && $backtrace[1]['function'] === 'entity_view' && isset($backtrace[1]['args'][4])) {
$page = $backtrace[1]['args'][4];
}
$rendered = entity_get_controller($entity_type)
->view($entities, $view_mode, $langcode, $page);
}
$rendered = reset($rendered);
// Store rendered entities in cache for future views.
foreach (element_children($rendered) as $id) {
// Remove #weight as it will not be accurate, we weight in the cached and
// rendered merge below.
unset($rendered[$id]['#weight']);
// Cache the entity.
$cid = $cid_map[$id];
$render = $rendered[$id];
_render_cache_pre_render($render, $cid, $cache_info);
$cached_entities[$cid] = (object) array(
'data' => $render,
);
}
}
// Not needed in rest of function.
unset($entities, $rendered);
// Return false if no entities are available, matches entity_view()'s
// functionality.
if (empty($cached_entities)) {
return FALSE;
}
// Put entities back in their request order and output.
$return = array();
// Render entities cached as render arrays.
foreach ($entity_order as $weight => $id) {
$cid = $cid_map[$id];
if (!empty($cached_entities[$cid]->data)) {
$render = $cached_entities[$cid]->data;
_render_cache_post_render($render, $id);
$return[$id] = $render;
$return[$id]['#weight'] = $weight;
}
}
// Return $return, wrap with entity type key in array to match
// entity_view()'s functionality.
return array(
$entity_type => $return,
);
}