MENU_NORMAL_ITEM, 'title' => 'Session expire', 'description' => 'Settings for session expiry', 'page callback' => 'drupal_get_form', 'page arguments' => array('session_expire_settings'), 'access arguments' => array('administer site configuration'), ); return $items; } function session_expire_settings() { $form['session_expire_desc'] = array( '#type' => 'markup', '#value' => t('This module requires cron to be correctly configured and running for Drupal.'), ); $interval = drupal_map_assoc(array(0, 7200, 10800, 21600, 43200, 86400, 172800, 259200, 604800), 'format_interval'); $interval['0'] = t('Everytime'); $form[SESSION_EXPIRE_INTERVAL] = array( '#type' => 'select', '#title' => t('Interval'), '#default_value' => variable_get(SESSION_EXPIRE_INTERVAL, 86400), '#options' => $interval, '#description' => t('Run the cleanup at the specified interval. This tells Drupal how often to run the cleanup. On a busy site, you want that to be more frequent (e.g. every day at a minimum). You don\'t want it to be too frequent though (e.g. every hour), as it can tie up the sessions table for a long time. Cron must be configured to run more frequently than the value you chose here.') ); $period = drupal_map_assoc(array(1800, 3600, 7200, 10800, 21600, 43200, 86400, 172800, 259200, 604800, 1209600, 2419200), 'format_interval'); $period['1000000000'] = t('Never'); $form[SESSION_EXPIRE_AGE] = array( '#type' => 'select', '#title' => t('Age'), '#default_value' => variable_get(SESSION_EXPIRE_AGE, 604800), '#options' => $period, '#description' => t(' Expire sessions that are older than the specified age. Older entries will be discarded.') ); $form[SESSION_EXPIRE_MODE] = array( '#type' => 'radios', '#title' => t('Session types'), '#default_value' => variable_get(SESSION_EXPIRE_MODE, 0), '#options' => array( t('Anonymous'), t('Anonymous and authenticated user'), t('Anonymous and users of specific roles'), t('Anonymous and authenticated user, except users of specific roles'), ), '#description' => t('Types of sessions to discard. This option indicates whether only anonymous users, or all users, or anonymous and users of specific role are expired, or anonymous and authenticated users without users of a specific role. Note that if you choose authenticated users, they will be logged off and have to login again after the "age" specified above.'), ); $form[SESSION_EXPIRE_ROLES] = array( '#type' => 'fieldset', '#title' => t('Select specific roles'), '#collapsible' => FALSE, '#disabled' => TRUE, ); foreach (user_roles(TRUE) as $key => $role) { // all roles without anonyous and without authenticated if ($key < 3) continue; $form[SESSION_EXPIRE_ROLES][SESSION_EXPIRE_ROLE . $key] = array( '#type' => 'checkbox', '#title' => $role, '#default_value' => variable_get(SESSION_EXPIRE_ROLE . $key, FALSE) ); } $form[SESSION_EXPIRE_LOGGING] = array( '#type' => 'radios', '#title' => t('Logging mode'), '#default_value' => variable_get(SESSION_EXPIRE_LOGGING, 0), '#options' => array( t('Logging off'), t('Only log summary of discarded session'), t('Log discarded session per role'), ), ); return system_settings_form($form); } /** * Implementation of hook_cron(). */ function session_expire_cron() { // Check if it is the first time this hook fires $last_run_time = variable_get(SESSION_EXPIRE_LAST, 0); if (!$last_run_time) { // Set the time variable_set(SESSION_EXPIRE_LAST, time()); } // Check Logging Mode $log_mode = variable_get(SESSION_EXPIRE_LOGGING, 1); // Check if we should run, this should only be once a day if (time() > $last_run_time + variable_get(SESSION_EXPIRE_INTERVAL, 86400)) { $timestamp = time() - variable_get(SESSION_EXPIRE_AGE, 604800); // Check if we should delete anonymous only or both anonymous and authenticated users $extra_cond = ''; $mode = variable_get(SESSION_EXPIRE_MODE, 0); // Perform the deletion of anonymous sessions db_query("DELETE FROM {sessions} WHERE timestamp < %d AND uid = 0", $timestamp); // Write to the watchdog if ($log_mode == 1) { $deleted_sessions = db_affected_rows(); } elseif ($log_mode == 2) { $deleted_sessions = db_affected_rows(); if ($deleted_sessions > 0) watchdog('cron', 'Number of anonymous sessions deleted: '. $deleted_sessions); } switch ($mode) { case 1: foreach (user_roles(TRUE) as $key => $role) { // all roles without anonyous and without authenticated if ($key < 3) continue; // for each role one sql-query if (variable_get(SESSION_EXPIRE_ROLE . $key, FALSE)) { db_query("DELETE FROM {sessions} WHERE timestamp < %d AND uid IN (SELECT uid FROM {users_roles} WHERE rid = %d)", $timestamp, $key); // Write to the watchdog if ($log_mode == 1) $deleted_sessions += db_affected_rows(); elseif ($log_mode == 2) { $deleted_sessions = db_affected_rows(); if ($deleted_sessions > 0) watchdog('cron', 'Number of sessions of role "' . $role . '" deleted: ' . $deleted_sessions); } } } break; case 2: $exceptions = ''; // delete all sessions with uid <> 0 db_query("DELETE FROM {sessions} WHERE timestamp < %d AND uid <> 0", $timestamp); // Write to the watchdog if ($log_mode == 1) $deleted_sessions += db_affected_rows(); elseif ($log_mode == 2) { $deleted_sessions = db_affected_rows(); if ($deleted_sessions > 0) watchdog('cron', 'Number of authenticated user sessions deleted: ' . $deleted_sessions); } break; case 3: $exceptions = ''; // build a comma seperated list of roles, which are excepted foreach (user_roles(TRUE) as $key => $role) { // all roles without anonyous and without authenticated if ($key < 3) continue; if (variable_get(SESSION_EXPIRE_ROLE . $key, FALSE)) $exceptions .= ", $key"; } // if any exception add additional sql query if (strlen($exceptions) > 2) db_query("DELETE FROM {sessions} WHERE timestamp < %d AND uid <> 0 AND NOT uid IN (SELECT uid FROM {users_roles} WHERE rid IN (%s))", $timestamp, substr($exceptions, 2)); // else delete all sessions with uid <> 0 else db_query("DELETE FROM {sessions} WHERE timestamp < %d AND uid <> 0", $timestamp); // Write to the watchdog if ($log_mode == 1) $deleted_sessions += db_affected_rows(); elseif ($log_mode == 2) { $deleted_sessions = db_affected_rows(); if ($deleted_sessions > 0) watchdog('cron', 'Number of authenticated user sessions deleted: ' . $deleted_sessions); } break; } // Write to the watchdog if (($log_mode == 1) && ($deleted_sessions > 0)) watchdog('cron', 'Number of sessions deleted: ' . $deleted_sessions); // Set the last time we deleted variable_set(SESSION_EXPIRE_LAST, time()); } }