Boost Expire for Drupal 7: a revision of the module

This is a revision of Boost Expire for Drupal 7 thanks to which the Boost's cache is flushed only when a node or a comments goes from unpublished to published or viceversa and when editing a node or a comment that is already published.

Here there is the code:

<?php

/**
 * @file
 *
 * Expires Boost caches automatically when certain Drupal actions are taken.
 */

/**
 * Implements hook_menu().
 */
function boost_expire_menu() {
  $items['admin/config/system/boost_expire'] = array(
    'title' => 'Boost Expire',
    'description' => 'Configuration for Boost Expire.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('boost_expire_admin_settings'),
    'access arguments' => array('administer site configuration'),
    'type' => MENU_NORMAL_ITEM,
  );

  return $items;
}

/**
 * Implements hook_node_insert().
 */
function boost_expire_node_insert($node) {
	if($node->status == 1) {
		boost_expire_flush_boost_cache(array('scope' => 'all'));
	}
}

/**
 * Implements hook_node_publish(), hook_node_update() and hook_node_unpublish().
 */
function boost_expire_node_update($node) {
	if($node->status == 1) {
		boost_expire_flush_boost_cache(array('scope' => 'all'));
	}
	elseif (isset($node->original->status) && $node->original->status == 1 && $node->status == 0){
		boost_expire_flush_boost_cache(array('scope' => 'all'));
	}
}

/**
 * Implements hook_node_delete().
 */
function boost_expire_node_delete($node) {
	if($node->status == 1) {
		boost_expire_flush_boost_cache(array('scope' => 'all'));
	}
}

/**
 * Implements hook_comment_insert().
 */
function boost_expire_comment_insert($comment) {
	if(node_load($comment->nid)->status == 1) {
		if($comment->status == 1) {
			boost_expire_flush_boost_cache(array('scope' => 'all'));
		}
	}
}

/**
 * Implements hook_comment_publish(), hook_comment_update() and hook_commento_unpublish().
 */
function boost_expire_comment_update($comment) {
	if(node_load($comment->nid)->status == 1) {
		if ($comment->status == 1){
			boost_expire_flush_boost_cache(array('scope' => 'all'));
		}
		elseif (isset($comment->original->status) && $comment->original->status == 1 && $comment->status == 0){
			boost_expire_flush_boost_cache(array('scope' => 'all'));
		}
	}
}

/**
 * Implements hook_comment_delete().
 */
function boost_expire_comment_delete($comment) {
	if(node_load($comment->nid)->status == 1) {
		if($comment->status == 1) {
			boost_expire_flush_boost_cache(array('scope' => 'all'));
		}
	}
}

/**
 * Function to clear Boost's cache.
 *
 * At this time, this is a pretty stupid function, but that's because there are
 * no easy ways to expire certain parts of the Boost cache, while Boost is still
 * in development for Drupal 7. But it does it's job.
 *
 * Clearing the entire Boost cache every time a comment is saved/updated, a node
 * is saved/updated, etc. is definitely not ideal, but it's better than having
 * to constantly hit the 'clear all caches' button or wait for cron expiration.
 *
 * @param $options
 *   Associative array of options for this flush. Currently, only supported
 *   option are:
 *   boost_expire_flush_boost_cache(array('scope' => 'all'));
 *   boost_expire_flush_boost_cache(array('scope' => 'node/' . $node->nid));
 */
function boost_expire_flush_boost_cache($options = array()) {
  global $_boost, $base_path, $base_root;

  // If configured to respect the site's minimum cache lifetime, don't flush
  // cache until that much time has passed.
  if (variable_get('boost_expire_respect_minimum_cache_lifetime', 0)) {
    // Check if the minimum amount of time has passed.
    $lifetime = variable_get('cache_lifetime');
    $last_flush = variable_get('boost_expire_last_flush_time', 0);
    // If the last flush happened before the minimum lifetime has passed, exit.
    if ($last_flush > (time() - $lifetime)) {
      return;
    }
    // Otherwise, update the last flush time and continue.
    else {
      variable_set('boost_expire_last_flush_time', time());
    }
  }

  // Borrow some logic from boost_htaccess_cache_dir_put() to build our base
  // directory path.
  if (empty($_boost['base_dir'])) {
    $url = $base_root . request_uri();
    $parts = parse_url($url);
    $_boost['base_dir'] = boost_get_normal_cache_dir() . '/' . $parts['host'] . $base_path;
  }

  if (!empty($options['scope']) && isset($_boost['base_dir'])) {
    // Borrow some logic from boost_flush_caches() to clear all the contents of
    // the boost directory for this site.
    if ($options['scope'] == 'all') {
      $count = _boost_rmdir($_boost['base_dir'], TRUE);
      $count = empty($count) ? 0 : $count;

      // Log the cache flush if configured.
      if (variable_get('boost_expire_log_flushes', 1)) {
        watchdog('boost_expire', 'Flushed all files (%count) from static page cache.', array('%count' => $count), WATCHDOG_NOTICE);
      }
    }
    // If the scope is not 'all', clear the cache for the current page.
    else {
      $count = boost_expire_flush_boost_page($_boost['base_dir'], $options['scope']);
      if (variable_get('boost_expire_log_flushes', 1) && $count) {
        watchdog('boost_expire', 'Flushed current page (%path) from static page cache.', array('%path' => $options['scope']), WATCHDOG_NOTICE);
      }
    }
  }
}

/**
 * Function to clear the current page from Boost's static cache.
 *
 * @param $base_dir
 *   Path to Boost's base directory.
 * @param $path
 *   Path of the page to be expired.
 *
 * @return $count
 *   Count of deleted files. Normally either 0 (if the file didn't exist) or 1.
 */
function boost_expire_flush_boost_page($base_dir, $path) {
  global $language;
  $result = 0;
  if (!language_negotiation_get_any(LOCALE_LANGUAGE_NEGOTIATION_URL)) {

  // TODO - $path doesn't work with url like node?page=1
  // Special handling for front page.
  if ($path == variable_get('site_frontpage', 'node')) {
    $file_to_del = $base_dir . '_.html';
  }
  // Node page
  else {
    //$file_to_del = $base_dir . $path . '_.html';
    $file_to_del = $base_dir .  drupal_get_path_alias($path) . '_.html';
  }

  // Delete the corresponding cached file, if it exists.
  if (file_exists($file_to_del)) {
    $result = unlink($file_to_del);
  }

  return $result;
  }
  else {
  
  // TODO - $path doesn't work with url like node?page=1
  // Special handling for front page.
  if ($path == variable_get('site_frontpage', 'node')) {
    $file_to_del = $base_dir . $language->language . '/' . '_.html';
  }
  // Node page
  else {
	$file_to_find = $base_dir . $language->language . '/' . drupal_get_path_alias($path) . '_.html';
    }
  }

  // Delete the corresponding cached file, if it exists.
  if (file_exists($file_to_find)) {
	$file_to_del = $base_dir . $language->language . '/' . drupal_get_path_alias($path) . '*' . '.html';
	foreach (glob($file_to_del) as $filename) {
		$result = unlink($filename);
	}
  }

  return $result;
}

/**
 * Configuration form for Boost Expire.
 */
function boost_expire_admin_settings() {
  $minimum_cache_lifetime = variable_get('cache_lifetime') / 60; // Minutes
  $performance_page = l('performance', 'admin/config/development/performance');
  $form['boost_expire_respect_minimum_cache_lifetime'] = array(
    '#type' => 'checkbox',
    '#title' => format_plural($minimum_cache_lifetime, 'Respect Minimum cache lifetime (1 minute)', 'Respect Minimum cache lifetime (@count minutes)'),
    '#default_value' => variable_get('boost_expire_respect_minimum_cache_lifetime', 0),
    '#description' => t('Only flush caches after the minimum cache lifetime has passed. Minimum cache lifetime can be set on the !performance page.', array('!performance' => $performance_page)),
  );

  $form['boost_expire_log_flushes'] = array(
    '#type' => 'checkbox',
    '#title' => t('Log Cache Flushes'),
    '#default_value' => variable_get('boost_expire_log_flushes', 1),
    '#description' => t('Writes an entry to the watchdog log every time Boost Expire flushes the Boost static cache.'),
  );

  return system_settings_form($form);
}
AttachmentSize
Package icon boost_expire-7.x-1.1-revisited.zip10.07 KB
Section: 

Comments

Add new comment