render_cache_page.module in Render cache 7.2
Hook implementations and frequently used functions for render cache page module.
File
modules/controller/render_cache_page/render_cache_page.moduleView source
<?php
/**
* @file
* Hook implementations and frequently used functions for render cache page module.
*/
use Drupal\render_cache_page\RenderCache\Controller\PageControllerInterface;
// -----------------------------------------------------------------------
// Core Hooks
/**
* Implements hook_init().
*
* As menu_execute_active_handler() runs before the page delivery, we fake the recursion
* level to prevent #post_render_cache functions to be called before.
*/
function render_cache_page_init() {
$rcc = render_cache_get_controller('page');
if (!$rcc instanceof PageControllerInterface) {
return;
}
// Delegate hook_init() to the render cache controller.
$rcc
->hook_init();
}
/**
* Implements hook_page_delivery_callback_alter().
*
* We hijack the page delivery callback to provide full page caching.
*
* This also allows to call the #post_render_cache callbacks at the
* latest possible point.
*
* @param callback $callback
*/
function render_cache_page_page_delivery_callback_alter(&$callback) {
if ($callback != 'drupal_deliver_html_page') {
return;
}
// Store the original callback.
$original_callback =& drupal_static(__FUNCTION__, '');
$original_callback = $callback;
// Use our own page deliver callback.
$callback = 'render_cache_page_deliver_html_page';
}
/**
* Implements hook_module_implements_alter().
*
* Moves our hook_page_page_delivery_callback_alter() implementation to occur
* last so that we can consistently hijack the delivery callback.
*
* @param array $implementations
* Format: $[$module] = string|false
* @param string $hook
*/
function render_cache_page_module_implements_alter(&$implementations, $hook) {
if ($hook === 'page_delivery_callback_alter') {
// Move our hook implementation to the bottom.
$group = $implementations['render_cache_page'];
unset($implementations['render_cache_page']);
$implementations['render_cache_page'] = $group;
}
}
// -----------------------------------------------------------------------
// Contrib Hooks
/**
* Implements hook_ctools_plugin_directory().
*
* @param string $owner
* @param string $plugin_type
*
* @return null|string
*/
function render_cache_page_ctools_plugin_directory($owner, $plugin_type) {
if ($owner == 'render_cache') {
return 'src/RenderCache/' . $plugin_type;
}
return NULL;
}
// -----------------------------------------------------------------------
// Public API
/**
* Overrides drupal_deliver_html_page().
*
* @param mixed $page_callback_result
*/
function render_cache_page_deliver_html_page($page_callback_result) {
// Menu status constants are integers; page content is a string or array.
if (is_int($page_callback_result)) {
// Never cache 403 or 404 pages.
render_cache_call_is_cacheable(FALSE);
// Early return for status codes.
drupal_deliver_html_page($page_callback_result);
return;
}
// Copied code from drupal_deliver_html_page:
// Emit the correct charset HTTP header, but not if the page callback
// result is NULL, since that likely indicates that it printed something
// in which case, no further headers may be sent, and not if code running
// for this page request has already set the content type header.
if (isset($page_callback_result) && is_null(drupal_get_http_header('Content-Type'))) {
drupal_add_http_header('Content-Type', 'text/html; charset=utf-8');
}
// Send appropriate HTTP-Header for browsers and search engines.
global $language;
drupal_add_http_header('Content-Language', $language->language);
if (isset($page_callback_result)) {
// Print anything besides a menu constant, assuming it's not NULL or
// undefined.
// The function does the printing.
render_cache_page_drupal_render_page($page_callback_result);
}
// Perform end-of-request tasks.
drupal_page_footer();
}
/**
* Called instead of drupal_render_page().
*
* @param array $page
*/
function render_cache_page_drupal_render_page($page) {
// We could retrieve this also from $_REQUEST, but this is cleaner as it
// matches the Drupal 8 request object closer.
$page_callback =& drupal_static('render_cache_page_page_delivery_callback_alter', '');
$context = array(
'page_callback' => $page_callback,
'request' => $_REQUEST,
);
// The view() method always takes multiple objects.
$pages = array(
'page' => (object) array(
'content' => $page,
),
);
// Delegate to render cache controller.
$rcc = render_cache_get_controller('page');
$rcc
->setContext($context);
$build = $rcc
->view($pages);
// Now that we have build the page succesfully and ran post_render functions,
// lets add the HTML back to it.
if (!empty($build['page']['#render_cache_page_theme_wrappers'])) {
$build['page']['#theme_wrappers'] = $build['page']['#render_cache_page_theme_wrappers'];
unset($build['page']['#render_cache_page_theme_wrappers']);
}
// If the #theme_wrappers is still empty, then just put back the default from
// element_info('page').
if (empty($build['page']['#theme_wrappers'])) {
$element_info = element_info('page');
$build['page']['#theme_wrappers'] = $element_info['#theme_wrappers'];
}
// Process the assets.
drupal_process_attached($build['page']);
// And restore properties.
$build['page'] += $build['page']['#render_cache_original'];
unset($build['page']['#render_cache_original']);
unset($build['page']['#attached']);
unset($build['page']['#printed']);
unset($build['page']['#children']);
// We need to unset #type and #theme to only render the #markup.
unset($build['page']['#type']);
unset($build['page']['#theme']);
// Call drupal_render() like the original function, but allow other modules
// to alter the output before and after rendering.
drupal_alter('render_cache_page_pre_render', $build);
$output = drupal_render($build);
drupal_alter('render_cache_page_post_render', $output, $build);
// Allow other modules to alter the output before and after sending, to
// enable them to e.g. replace placeholders via Javascript.
drupal_alter('render_cache_page_pre_send', $output, $build);
print $output;
drupal_alter('render_cache_page_post_send', $output, $build);
}
/**
* Overrides drupal_render_page().
*
* This function is identical to drupal_render_page(), but does not drupal_render()
* at the end to allow render caching.
*
* @param array $page
*
* @return array
*/
function render_cache_page_drupal_render_page_helper($page) {
$main_content_display =& drupal_static('system_main_content_added', FALSE);
// Allow menu callbacks to return strings or arbitrary arrays to render.
// If the array returned is not of #type page directly, we need to fill
// in the page with defaults.
if (is_string($page) || is_array($page) && (!isset($page['#type']) || $page['#type'] != 'page')) {
drupal_set_page_content($page);
$page = element_info('page');
}
// Modules can add elements to $page as needed in hook_page_build().
foreach (module_implements('page_build') as $module) {
$function = $module . '_page_build';
$function($page);
}
// Modules alter the $page as needed. Blocks are populated into regions like
// 'sidebar_first', 'footer', etc.
drupal_alter('page', $page);
// If no module has taken care of the main content, add it to the page now.
// This allows the site to still be usable even if no modules that
// control page regions (for example, the Block module) are enabled.
if (!$main_content_display) {
$page['content']['system_main'] = drupal_set_page_content();
}
// --- These lines were changed.
// Remove the #theme_wrappers to remove the chicken-egg-situation of page and html
// for #post_render_cache and script adding. Store it in another var, in
// case some module tries to alter it in hook_page_alter().
if (!empty($page['#theme_wrappers'])) {
$page['#render_cache_page_theme_wrappers'] = $page['#theme_wrappers'];
}
$page['#theme_wrappers'] = array();
return $page;
}
Functions
Name | Description |
---|---|
render_cache_page_ctools_plugin_directory | Implements hook_ctools_plugin_directory(). |
render_cache_page_deliver_html_page | Overrides drupal_deliver_html_page(). |
render_cache_page_drupal_render_page | Called instead of drupal_render_page(). |
render_cache_page_drupal_render_page_helper | Overrides drupal_render_page(). |
render_cache_page_init | Implements hook_init(). |
render_cache_page_module_implements_alter | Implements hook_module_implements_alter(). |
render_cache_page_page_delivery_callback_alter | Implements hook_page_delivery_callback_alter(). |