You are here

cleaner.module in Cleaner 6

Same filename and directory in other branches
  1. 8.2 cleaner.module
  2. 8 cleaner.module
  3. 5 cleaner.module
  4. 7 cleaner.module

Allows the admin to set a schedule for clearing caches and other stuff.

File

cleaner.module
View source
<?php

/**
 * @file
 * Allows the admin to set a schedule for clearing caches and other stuff.
 */

/**
 * Implementation of hook_help().
 */
function cleaner_help($path, $args) {
  switch ($path) {
    case 'admin/help#cleaner':
      $output = '<p>' . t('Cleaner runs when the Cron job tells it to. It will clean the cache tables and other things as configured.') . '</p>';
      return $output;
  }
}

/**
 * Implementation of hook_menu().
 */
function cleaner_menu() {
  $items = array();
  $items['admin/settings/cleaner'] = array(
    'title' => 'Cleaner module settings',
    'description' => 'Configure time-based clean up functions.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'cleaner_settings_form',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
  );
  return $items;
}

/**
 * This module can be hooked into to extend its functionality.
 * I'm not sure why you would want to do this rather than code your own, but it's there.
 *
 * hook_cleaner_settings()
 *   Returns the useful part of a settings form as a keyed array, with the key being the module name.
 *   @see cleaner_cleaner_settings().
 *
 * hook_cleaner_run()
 *   Called when Cron triggers the site (run-time).
 *   There are no calling parameters or returns.
 *   @see cleaner_cleaner_run().
 */

/**
 * Define a form to control the settings.
 */
function cleaner_settings_form() {

  // Pull in our form's style sheet.
  drupal_add_css(drupal_get_path('module', 'cleaner') . '/cleaner.css');
  $form = array();
  $ret = module_invoke_all('cleaner_settings');
  foreach ($ret as $module => $elements) {
    $mod = drupal_ucfirst($module);
    $form[$mod] = array(
      '#type' => 'fieldset',
      '#title' => $mod,
      '#collapsible' => TRUE,
      '#collapsed' => FALSE,
    );
    $form[$mod]['stuff'] = $elements;
  }
  return system_settings_form($form);
}

/**
 * Implementation of hook_cleaner_settings().
 */
function cleaner_cleaner_settings() {
  drupal_add_css(drupal_get_path('module', 'cleaner') . '/cleaner.css');
  global $db_type;
  $form = $ret = array();
  $yesno = array(
    t('No'),
    t('Yes'),
  );
  $inline = array(
    'class' => 'container-inline',
  );

  // Time intervals.
  $min = 60;
  $hour = 3600;
  $day = 86400;
  $interval = array(
    0 => t('Every time'),
  );
  $interval += drupal_map_assoc(array(
    15 * $min,
    30 * $min,
    $hour,
    2 * $hour,
    4 * $hour,
    6 * $hour,
    12 * $hour,
    $day,
    2 * $day,
    3 * $day,
    7 * $day,
  ), 'format_interval');
  $form['cleaner_cron'] = array(
    '#type' => 'radios',
    '#title' => t('Run interval'),
    '#options' => $interval,
    '#default_value' => variable_get('cleaner_cron', $hour),
    '#description' => t('This is how often the options below will occur. The actions will occur on the next Cron run after this interval expires. "Every time" means on every Cron run.'),
    '#attributes' => $inline,
  );
  $list = array();
  $result = db_query("SHOW TABLES LIKE 'cache\\_%'");
  while ($table = db_result($result)) {
    $list[] = $table;
  }
  $form['cleaner_clear_cache'] = array(
    '#type' => 'radios',
    '#options' => $yesno,
    '#title' => t('Clear cache'),
    '#default_value' => variable_get('cleaner_clear_cache', 0),
    '#description' => t('The current cache tables are: @list.', array(
      '@list' => implode(', ', $list),
    )),
    '#attributes' => $inline,
  );
  $form['cleaner_empty_watchdog'] = array(
    '#type' => 'radios',
    '#options' => $yesno,
    '#title' => t('Empty Watchdog'),
    '#default_value' => variable_get('cleaner_empty_watchdog', 0),
    '#description' => t('There is a standard setting for controlling Watchdog contents. This is more useful for test sites.'),
    '#attributes' => $inline,
  );
  $cookie = session_get_cookie_params();
  $lifetime = $cookie['lifetime'];
  $start = (isset($_SERVER['REQUEST_TIME']) ? $_SERVER['REQUEST_TIME'] : time()) - $lifetime;
  $count = db_result(db_query("SELECT COUNT(sid) FROM {sessions} WHERE timestamp < %d", $start));
  $form['cleaner_clean_sessions'] = array(
    '#type' => 'radios',
    '#options' => $yesno,
    '#title' => t('Clean up Sessions table'),
    '#default_value' => variable_get('cleaner_clean_sessions', 0),
    '#description' => t('The sessions table can quickly become full with old, abandoned sessions. This will delete all sessions older than @interval (as set by your site administrator). There are currently @count such sessions.', array(
      '@interval' => format_interval($lifetime),
      '@count' => $count,
    )),
    '#attributes' => $inline,
  );
  $form['cleaner_clean_cssdir'] = array(
    '#type' => 'radios',
    '#options' => $yesno,
    '#title' => t('Clean up CSS files'),
    '#default_value' => variable_get('cleaner_clean_cssdir', 0),
    '#description' => t('The CSS directory can become full with stale and outdated cache files.  This will delete all CSS cache files but the latest.'),
    '#attributes' => $inline,
  );
  $form['cleaner_clean_jsdir'] = array(
    '#type' => 'radios',
    '#options' => $yesno,
    '#title' => t('Clean up JS files'),
    '#default_value' => variable_get('cleaner_clean_jsdir', 0),
    '#description' => t('The JS directory can become full with stale and outdated cache files.  This will delete all JS cache files but the latest.'),
    '#attributes' => $inline,
  );

  // We can only offer OPTIMIZE to MySQL users.
  $dbtype = drupal_strtolower(drupal_substr($db_type, 0, 5));
  if ($dbtype == 'mysql') {
    $form['cleaner_optimize_db'] = array(
      '#type' => 'radios',
      '#options' => $yesno + array(
        '2' => 'Local only',
      ),
      '#title' => t('Optimize tables with "overhead" space'),
      '#default_value' => variable_get('cleaner_optimize_db', 0),
      '#description' => t('The module will compress (optimize) all database tables with unused space. <strong>NOTE</strong>: During an optimization, the table will locked against any other activity; on a high vloume site, this may be undesirable. "Local only" means do not replicate the optimization (if it is being done).'),
      '#attributes' => $inline,
    );
  }
  else {

    // If not MySql, delete (reset) the variable.
    variable_del('cleaner_optimize_db');
  }
  $ret['cleaner'] = $form;
  return $ret;
}

/**
 * Implementation of hook_cron().
 */
function cleaner_cron() {
  $interval = variable_get('cleaner_cron', 3600);
  $last = variable_get('cleaner_last_cron', 0);
  $now = time();
  if ($now >= $last + $interval) {
    $ret = module_invoke_all('cleaner_run');
  }
  variable_set('cleaner_last_cron', $now);
}

/**
 * Deletes all cache files in a specified subdirectory of the Drupal files directory.
 *
 * @param $ext: the file extension of the file type, can be css or js
 * @param $seconds: number of seconds old to delete down to, defaulted to 3600 (1 hour)
 */
function cleaner_delete_files($ext, $seconds = 3600) {
  $count = 0;
  $dir = file_directory_path() . "/{$ext}";
  $mask = $ext . '_(.*)\\.' . $ext . '$';
  if (file_check_directory($dir) != 1) {
    return;
  }
  $files = file_scan_directory($dir, $mask);
  foreach ($files as $obj) {
    $filepath = $obj->filename;
    if (filemtime($filepath) < time() - $seconds) {
      file_delete($filepath);
      $count++;
    }
  }
  if ($count) {
    watchdog('Cleaner', 'Deleted @count cached @type files.', array(
      '@count' => $count,
      '@type' => $ext,
    ), WATCHDOG_NOTICE, url('admin/settings/cleaner'));
  }
}

/**
 * Implementation of hook_cleaner_run().
 */
function cleaner_cleaner_run() {
  if (variable_get('cleaner_clear_cache', FALSE)) {

    // Clear out the cache tables.
    $list = array();
    $result = db_query("SHOW TABLES LIKE 'cache\\_%'");
    while ($table = db_result($result)) {

      // Note that use of '*' means the entire table is cleared, not just expired entries.
      cache_clear_all('*', $table, TRUE);
      $list[] = drupal_substr($table, 6);
    }
    watchdog('Cleaner', 'Cleared caches. (@list)', array(
      '@list' => implode(', ', $list),
    ), WATCHDOG_NOTICE, url('admin/settings/cleaner'));
  }
  if (variable_get('cleaner_empty_watchdog', FALSE)) {

    // Clear out the watchdog table.
    db_query("TRUNCATE {watchdog}");
    watchdog('Cleaner', 'Cleared watchdog.', NULL, WATCHDOG_NOTICE, url('admin/settings/cleaner'));
  }
  if (variable_get('cleaner_clean_sessions', 0)) {

    // Delete sessions that are older than the lifetime.
    $cookie = session_get_cookie_params();
    $lifetime = $cookie['lifetime'];
    $start = (isset($_SERVER['REQUEST_TIME']) ? $_SERVER['REQUEST_TIME'] : time()) - $lifetime;
    db_query("DELETE FROM {sessions} WHERE timestamp < %d", $start);
    $count = db_affected_rows();
    if ($count) {
      watchdog('Cleaner', 'Cleared @count sessions.', array(
        '@count' => $count,
      ), WATCHDOG_NOTICE, url('admin/settings/cleaner'));
    }
  }
  if (variable_get('cleaner_clean_cssdir', FALSE)) {

    // Delete css files older than 1 hour.
    cleaner_delete_files('css');
  }
  if (variable_get('cleaner_clean_jsdir', FALSE)) {

    // Delete js files older than 1 hour.
    cleaner_delete_files('js');
  }
  if ($opt = variable_get('cleaner_optimize_db', FALSE)) {

    // Optimize tables.
    cleaner_optimize_table($opt);
  }
}
function cleaner_optimize_table($opt = 0) {
  global $db_type;

  // Make sure the db type hasn't changed.
  if (drupal_strtolower(drupal_substr($db_type, 0, 5)) == 'mysql') {
    $result = db_query('SHOW TABLE STATUS');
    $list = array();
    while ($table = db_fetch_object($result)) {
      if ($table->Data_free) {
        $list[] = $table->Name;
      }
    }
    $query = 'OPTIMIZE ' . ($opt == 2 ? 'LOCAL ' : '') . 'TABLE ' . '{' . implode('}, {', $list) . '}';
    timer_start('cleaner_opt');
    db_query($query);
    $time = timer_read('cleaner_opt') / 1000;
    watchdog('Cleaner', 'Optimized tables: !opts. This required !time seconds.', array(
      '!opts' => implode(', ', $list),
      '!time' => number_format($time, 3),
    ), WATCHDOG_INFO);
  }
  else {
    watchdog('Cleaner', 'Database type (!type) not allowed to be optimized.', array(
      '!type' => $db_type,
    ), WATCHDOG_ERROR);
  }
  return;
}

Functions

Namesort descending Description
cleaner_cleaner_run Implementation of hook_cleaner_run().
cleaner_cleaner_settings Implementation of hook_cleaner_settings().
cleaner_cron Implementation of hook_cron().
cleaner_delete_files Deletes all cache files in a specified subdirectory of the Drupal files directory.
cleaner_help Implementation of hook_help().
cleaner_menu Implementation of hook_menu().
cleaner_optimize_table
cleaner_settings_form Define a form to control the settings.