You are here

flush_page_cache.module in Flush page cache 6

Same filename and directory in other branches
  1. 7 flush_page_cache.module

Easing the pain when you need to flush...Drupal's cache.

File

flush_page_cache.module
View source
<?php

/**
 * @file
 * Easing the pain when you need to flush...Drupal's cache.
 */

/**
 * Implementation of hook_perm().
 */
function flush_page_cache_perm() {
  return array(
    'flush page cache',
  );
}

/**
 * Implementation of hook_menu().
 */
function flush_page_cache_menu() {
  $items = array();

  // Add a link under admin_menu
  $items['admin_menu/flush-page-cache'] = array(
    'page callback' => 'flush_page_cache_admin_menu_flush_cache',
    'access arguments' => array(
      'flush page cache',
    ),
    'file' => 'flush_page_cache.admin.inc',
    'type' => MENU_CALLBACK,
  );

  // Admin settings
  $items['admin/settings/flush_page_cache'] = array(
    'title' => 'Flush page cache',
    'description' => "Easing the pain when you need to flush...Drupal's cache.",
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'flush_page_cache_admin_settings',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'file' => 'flush_page_cache.admin.inc',
    'type' => MENU_NORMAL_ITEM,
  );
  $items['admin/settings/flush_page_cache/js'] = array(
    'page callback' => 'flush_page_cache_custom_settings_table_js',
    'access arguments' => array(
      'administer site configuration',
    ),
    'file' => 'flush_page_cache.admin.inc',
    'type' => MENU_CALLBACK,
  );
  return $items;
}

/**
 * Implementation of hook_admin_menu().
 */
function flush_page_cache_admin_menu($deleted) {
  $icon_path = '<front>';
  $links = array();
  $links[] = array(
    'title' => "Flush this page's cache",
    'path' => 'admin_menu/flush-page-cache',
    'query' => 'destination',
    'parent_path' => $icon_path,
  );
  return $links;
}

/**
 * Implementation of hook_init().
 *
 * Ideally we should be flushing the page's cache via hook_boot() but
 * user_access() isn't available until hook_init().
 */
function flush_page_cache_init() {
  if (!flush_page_cache_requested()) {
    return;
  }

  // Clear custom cache cid and tables based on drupal path.
  $path = $_GET['q'];
  $alias = drupal_get_path_alias($_GET['q']);
  $custom = variable_get('flush_page_cache_custom', array(
    array(
      '*',
      'variables',
      'cache',
      FALSE,
    ),
  ));
  foreach ($custom as $item) {
    if (drupal_match_path($path, $item[0]) || drupal_match_path($alias, $item[0])) {
      cache_clear_all($item[1], $item[2], $item[3]);
    }
  }
}

/**
 * Implementation of hook_block().
 */
function flush_page_cache_block($op = 'list', $delta = 0, $edit = array()) {
  switch ($op) {
    case 'list':
      $blocks['link'] = array(
        'info' => t('Flush page cache'),
        'cache' => DRUPAL_NO_CACHE,
      );
      return $blocks;
    case 'view':
      if (user_access('flush page cache')) {
        return array(
          'content' => theme('flush_page_cache_link'),
        );
      }
      else {
        return NULL;
      }
    default:
      return;
  }
}

/**
 * Implementation of hook_footer().
 */
function flush_page_cache_footer() {
  if (!flush_page_cache_requested()) {
    return;
  }

  // Get full path and URL.
  $path = flush_page_cache_get_path();
  $url = flush_page_cache_get_url();

  // Ensure that the object cache was disabled.
  if (!flush_page_cache_test_object_cache_disabled()) {
    $message = "Failed to flush all cached objects for this page. Please read this 'Flush page cache' README.txt file for more information";
    drupal_set_message(t($message), 'error');
    watchdog('flush_page_cache', t($message), array(), WATCHDOG_ERROR);
  }
  else {

    // Display message about cached objects.
    drupal_set_message(t('Successfully flushed all cached objects for this page.'));
  }

  // Purge all possible page-level caches. Generally, only one page cache
  // mechanism should be enabled but just to be safe we will check all of them.
  // Varnish
  if (module_exists('varnish')) {
    varnish_expire_cache(array(
      $path,
    ));
    drupal_set_message(t('Successfully purged this cached page from Varnish.'));
  }

  // Drupal with support for Pressflow's CACHE_EXTERNAL.
  $is_cache_disabled = variable_get('cache', CACHE_DISABLED) == CACHE_DISABLED ? TRUE : FALSE;
  $is_cache_external = defined('CACHE_EXTERNAL') && variable_get('cache', CACHE_DISABLED) == CACHE_EXTERNAL ? TRUE : FALSE;
  if (!$is_cache_disabled && !$is_cache_external) {
    cache_clear_all($url, 'cache_page');
    drupal_set_message(t('Successfully flushed this cached page from Drupal.'));
  }

  // Redirect to the URL.
  drupal_goto($url);
}

////////////////////////////////////////////////////////////////////////////////

// Helper functions

////////////////////////////////////////////////////////////////////////////////

/**
 * Determine if a flush page cache has been requested.
 */
function flush_page_cache_requested() {
  if (empty($_GET['flush_page_cache']) || !user_access('flush page cache')) {
    return FALSE;
  }
  else {
    return TRUE;
  }
}

/**
 * Get the full URL for the current page without ?flush_page_cache=1 query param.
 */
function flush_page_cache_get_url() {
  $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 'https' : 'http';
  return $protocol . '://' . $_SERVER['HTTP_HOST'] . flush_page_cache_get_path();
}

/**
 * Get the path for the current page without ?flush_page_cache=1 query param.
 */
function flush_page_cache_get_path() {
  return parse_url(request_uri(), PHP_URL_PATH);
}

/**
 * Test that the object cache is being correctly disabled and flushed.
 */
function flush_page_cache_test_object_cache_disabled() {
  $cid = 'flush-page-cache-test';
  $uuid = uniqid();

  // Purge any old test $cid;
  cache_clear_all($cid, 'cache');

  // Attempt so set $cid cache which will work.
  cache_set($cid, $uuid, 'cache');

  // If page object cache is correctly disabled this will return NULL and not the uuid.
  $cache = cache_get($cid);
  $is_disabled = empty($cache) || $cache->data != $uuid ? TRUE : FALSE;

  // Cleanup test $cid.
  cache_clear_all($cid, 'cache');
  return $is_disabled;
}

////////////////////////////////////////////////////////////////////////////////

// Theme functions

////////////////////////////////////////////////////////////////////////////////

/**
 * Implementation of hook_preprocess_page().
 */
function flush_page_cache_preprocess_page(&$variables) {
  if (user_access('flush page cache') && variable_get('flush_page_cache_footer_link', '0')) {
    $variables['footer_message'] .= $variables['footer_message'] ? '<span class="flush-page-cache-delimiter"> - </span>' : '';
    $variables['footer_message'] .= theme('flush_page_cache_link');
  }
}

/**
 * Implementation of hook_theme().
 */
function flush_page_cache_theme() {
  return array(
    'flush_page_cache_link' => array(
      'arguments' => array(),
    ),
    'flush_page_cache_custom_settings_table' => array(
      'arguments' => array(
        'form' => NULL,
      ),
      'file' => 'flush_page_cache.admin.inc',
    ),
  );
}

/**
 * Outputs 'flush page cache' link which is added to a site's footer message.
 */
function theme_flush_page_cache_link() {
  $options = array(
    'query' => 'flush_page_cache=1',
    'attributes' => array(
      'class' => 'flush-page-cache',
    ),
    'external' => TRUE,
  );
  return l(t('Flush page cache'), flush_page_cache_get_url(), $options);
}

Functions

Namesort descending Description
flush_page_cache_admin_menu Implementation of hook_admin_menu().
flush_page_cache_block Implementation of hook_block().
flush_page_cache_footer Implementation of hook_footer().
flush_page_cache_get_path Get the path for the current page without ?flush_page_cache=1 query param.
flush_page_cache_get_url Get the full URL for the current page without ?flush_page_cache=1 query param.
flush_page_cache_init Implementation of hook_init().
flush_page_cache_menu Implementation of hook_menu().
flush_page_cache_perm Implementation of hook_perm().
flush_page_cache_preprocess_page Implementation of hook_preprocess_page().
flush_page_cache_requested Determine if a flush page cache has been requested.
flush_page_cache_test_object_cache_disabled Test that the object cache is being correctly disabled and flushed.
flush_page_cache_theme Implementation of hook_theme().
theme_flush_page_cache_link Outputs 'flush page cache' link which is added to a site's footer message.