You are here

role_expire.module in Role Expire 6

Same filename and directory in other branches
  1. 8 role_expire.module
  2. 7 role_expire.module
  3. 2.x role_expire.module

Role Expire module

Enables user roles to expire on given time.

File

role_expire.module
View source
<?php

// $Id: role_expire.module,v 1.22 2010/06/20 20:47:16 stewsnooze Exp $

/**
 * @file
 * Role Expire module
 *
 * Enables user roles to expire on given time.
 */

//require_once('role_expire.inc');

/*******************************************************************************
 * API functions
 ******************************************************************************/

/**
 * API function; Get expiration time of a user role.
 * @param $uid
 *   User ID.
 * @param $rid
 *   Role ID.
 * @return
 *  Array with the expiration time.
 */
function role_expire_get_user_role_expiry_time($uid, $rid) {
  $result = db_fetch_array(db_query("SELECT expiry_timestamp FROM {role_expire} WHERE uid=%d AND rid = %d", $uid, $rid));
  return !empty($result) ? $result['expiry_timestamp'] : '';
}

/**
 * API function; Get expiration of all roles of a user.
 * @param $uid
 *   User ID.
 * @param $rid
 *   Role ID.
 * @return
 *  Array with the expiration time.
 */
function role_expire_get_all_user_records($uid) {
  $return = array();
  $result = db_query("SELECT rid, expiry_timestamp FROM {role_expire} WHERE uid=%d", $uid);
  while ($row = db_fetch_array($result)) {
    $return[$row['rid']] = $row['expiry_timestamp'];
  }
  return $return;
}

/**
 * API function; Delete a record from the database.
 *
 * @param $rid
 *   Role ID.
 * @param $uid
 *   User ID.
 * @return
 */
function role_expire_delete_record($uid, $rid) {

  // I wonder whether on every save if we are doing this?.
  db_query("DELETE FROM {role_expire} WHERE uid=%d AND rid = %d", $uid, $rid);
}

/**
 * API function; Delete all user expirations.
 *
 * @param $rid
 *   Role ID.
 * @param $uid
 *   User ID.
 * @return
 */
function role_expire_delete_user_records($uid) {
  db_query("DELETE FROM {role_expire} WHERE uid = %d", $uid);
}

/**
 * API function; Insert or update a record in the database.
 *
 * @param $rid
 *   Role ID.
 * @param $uid
 *   User ID.
 * @param $expiry_time
 *   The expiration time string.
 */
function role_expire_write_record($uid, $rid, $expiry_timestamp) {
  $existing = db_result(db_query("SELECT expiry_timestamp FROM {role_expire} WHERE uid = %d AND rid = %d", $uid, $rid));
  if ($existing && $expiry_timestamp != $existing) {
    $result = db_query("UPDATE {role_expire} SET expiry_timestamp = %d WHERE uid = %d AND rid = %d", $expiry_timestamp, $uid, $rid);
  }
  elseif ($existing == FALSE) {
    db_query("INSERT INTO {role_expire} (uid, rid, expiry_timestamp) VALUES (%d, %d, %d)", $uid, $rid, $expiry_timestamp);
  }
}

/**
 * API function; Get all the default duration for a role.
 * @param $rid
 *   Required. The role_id to check.
 * @return
 *  Int storing the default duration days of the role or an empty string if not set.
 */
function role_expire_get_default_duration($rid) {
  $result = db_result(db_query("SELECT duration FROM {role_expire_length} WHERE rid = %d", $rid));
  return $result ? $result : '';
}

/**
 * API function; Set the default expiry duration for a role.
 *
 * @param $rid
 *   Role ID.
 * @param $duration
 *   The duration integer (days).
 */
function role_expire_set_default_duration($rid, $duration) {
  $row_rid = db_fetch_array(db_query("SELECT rid FROM {role_expire_length} WHERE rid = %d", $rid));
  if ($row_rid != $rid) {
    db_query("INSERT INTO {role_expire_length} (rid, duration) VALUES (%d, %d)", $rid, $duration);
  }
  else {
    $result = db_query("UPDATE {role_expire_length} SET duration = %d WHERE rid = %d", $duration, $rid);
  }
}

/**
 * API function; Delete a default duration for a role.
 * @param $rid
 *   Required. The role_id to remove.
 */
function role_expire_delete_default_duration($rid) {
  db_query("DELETE FROM {role_expire_length} WHERE rid = %d", $rid);
}

/**
 * API function; Get all records that should be expired.
 *
 * @param $time
 *   Optional. The time to check, if not set it will check current time.
 */
function role_expire_get_expired($time = '') {
  $return = array();
  if (!$time) {
    $time = time();
  }
  $result = db_query("SELECT rid, uid, expiry_timestamp FROM {role_expire} WHERE expiry_timestamp <= %d", $time);
  while ($row = db_fetch_array($result)) {
    $return[] = $row;
  }
  return $return;
}

/*******************************************************************************
 * Hook implementations
 ******************************************************************************/

/**
 * Implementation of hook_views_api().
 */
function role_expire_views_api() {
  return array(
    "api" => views_api_version(),
  );
}

/**
 * Implementation of hook_migrate_init().
 */
function role_expire_migrate_init() {

  // Don't load migration support unless we need it
  $path = drupal_get_path('module', 'role_expire') . '/role_expire.migrate.inc';
  include_once $path;
}

/**
 * Implementation of hook_perm().
 */
function role_expire_perm() {
  return array(
    'administer role expire',
  );
}

/**
 * Implementation of hook_form_FORM-ID_alter().
 */
function role_expire_form_user_register_alter(&$form, $form_state) {
  $form = array_merge_recursive($form, role_expire_add_expiration_input());
}

/**
 * Implementation of hook_form_FORM-ID_alter().
 */
function role_expire_form_user_profile_form_alter(&$form, $form_state) {
  $form['account']['roles']['#attributes'] = array(
    'class' => 'role-expire-roles',
  );
}

/**
 * Implementation of hook_form_FORM-ID_alter().
 */
function role_expire_form_user_admin_role_alter(&$form, $form_state) {
  $form['role_expire'] = array(
    '#title' => t("Default day length for the role %role", array(
      '%role' => drupal_ucfirst($form['name']['#default_value']),
    )),
    '#type' => 'textfield',
    '#size' => 8,
    '#default_value' => role_expire_get_default_duration($form['rid']['#value']),
    '#maxlength' => 5,
    '#attributes' => array(
      'class' => 'role-expire-role-expiry',
    ),
    '#description' => t("Leave blank for no default length. Values should indicate the number of days the role should be active for."),
  );

  // Reposition the submit button and delete.
  $form['submit']['#weight'] = 2;
  if (arg(4)) {
    $form['delete']['#weight'] = 3;
  }
  $form['#validate'][] = 'role_expire_user_admin_role_validate';
  $form['#submit'][] = 'role_expire_user_admin_role_submit';
}
function role_expire_user_admin_role_validate($form, &$form_state) {
  if (isset($form_state['values']['role_expire']) && strlen($form_state['values']['role_expire']) && !is_numeric($form_state['values']['role_expire'])) {
    form_set_error('role_expire', 'Role expiry defaults needs to be numeric');
  }
}
function role_expire_user_admin_role_submit($form, &$form_state) {
  if ($form_state['values']['op'] == t('Delete role')) {
    role_expire_delete_default_duration($form_state['values']['rid']);
  }
  else {
    role_expire_set_default_duration($form_state['values']['rid'], $form_state['values']['role_expire']);
    drupal_set_message('Role expiry set.');
  }
}

/**
 * Implementation of hook_user().
 */
function role_expire_user($op, &$edit, &$account, $category = NULL) {
  switch ($op) {
    case 'form':
      if ($category == 'account' && (user_access('administer role expire') || user_access('administer users'))) {
        return role_expire_add_expiration_input($account);
      }
      break;
    case 'validate':

      //todo  Add ifs for if (user_access('administer role expire') || user_access('administer users')
      if ($category == 'account' && (user_access('administer role expire') || user_access('administer users'))) {
        if (isset($edit['roles'])) {
          $time = time();
          foreach ($edit['roles'] as $rid => $role) {
            if (is_array($edit) && array_key_exists('role_expire_' . $role, $edit) && $edit['role_expire_' . $role] != '') {
              $expiry_time = strtotime($edit['role_expire_' . $role]);
              if (!$expiry_time) {
                form_set_error('role_expire_' . $role, t("Role expiry time is not in correct format."));
              }
              if ($expiry_time <= $time) {
                form_set_error('role_expire_' . $role, t("Role expiry time must be in the future."));
              }
            }
          }
        }
      }
      break;
    case 'after_update':
      if ($category == 'account' && (user_access('administer role expire') || user_access('administer users'))) {

        // This adds any new roles that have been given to the user.
        $new_roles = array_diff($account->roles, _role_static_user_roles($account->uid));

        // We have the new roles, loop over them and see whether we need to assign expiry to them.
        foreach ($new_roles as $role_id => $role) {
          role_expire_process_default_role_duration_for_user($role_id, $account->uid);
        }

        // This removes any new roles that have been given to the user.
        $del_roles = array_diff(_role_static_user_roles($account->uid), $account->roles);

        // We have the deleted roles, loop over them and see whether we need to assign expiry to them.
        foreach ($del_roles as $role_id => $role) {
          role_expire_delete_record($account->uid, $role_id);
        }
      }
      break;
    case 'update':
    case 'insert':
      if ($category == 'account' && (user_access('administer role expire') || user_access('administer users'))) {

        // Add roles expiry information for the user role.
        // We go over all existing roles, because user might have disabled a role.
        foreach (_role_expire_get_role() as $rid => $role) {
          $role = '';
          if (array_key_exists('role_expire_' . $rid, $edit)) {
            $role = $edit['role_expire_' . $rid];
          }
          if ($role != '') {
            $expiry_timestamp = strtotime($role);
            role_expire_write_record($account->uid, $rid, $expiry_timestamp);
          }
          else {
            if ($category == NULL || $category == 'account') {

              // Handle inserts correctly
              if ($op == 'insert') {

                // Check for Role
                if (array_key_exists($rid, $edit['roles']) && $edit['roles'][$rid] == $rid) {
                  role_expire_process_default_role_duration_for_user($rid, $account->uid);
                }
              }
              else {

                // User input is blank, so delete record.
                role_expire_delete_record($account->uid, $rid);
              }
            }
          }
          $edit['role_expire_' . $rid] = NULL;
        }
      }
      break;
    case 'delete':

      // Delete user records.
      role_expire_delete_user_records($account->uid);
      break;
    case 'load':

      // We don't load the information to the user object. Other modules can use
      // our API to query the information.

      /**
       * Load the starter roles into a static cache so it is easy to
       * see what has changed later on.
       */
      _role_static_user_roles($account->uid, $account->roles);
      break;
    case 'view':
      global $user;
      if (user_access('administer role expire') || user_access('administer users') || $user->uid == $account->uid) {
        $roles = array();
        $expiry_roles = role_expire_get_all_user_records($account->uid);
        foreach ($account->roles as $key => $val) {
          if (array_key_exists($key, $expiry_roles)) {
            $roles[$key] = t("%role role - expires on %timedate", array(
              '%role' => ucfirst($val),
              '%timedate' => format_date($expiry_roles[$key]),
            ));
          }
        }
        if ($roles) {
          $account->content['summary']['role_expire'] = array(
            '#type' => 'user_profile_item',
            '#title' => t('Role expiration'),
            '#value' => theme('item_list', $roles),
            '#attributes' => array(
              'class' => 'role-expiry-roles',
            ),
          );
        }
      }
      break;
  }
}

/**
 * Implementation of hook_cron().
 */
function role_expire_cron() {
  if ($expires = role_expire_get_expired()) {
    $roles = _role_expire_get_role();
    foreach ($expires as $expire) {

      // Remove the role from the user.
      $account = user_load($expire['uid']);
      $edit = $account->roles;
      unset($edit[$expire['rid']]);

      // In the documentation for the role_expire implementation of hook_user we
      // state to use $category = 'account'.  We don't do that here because
      // that would cause the delete to occur twice.
      user_save($account, array(
        'roles' => $edit,
      ), NULL);

      // Remove the role expiration record.
      role_expire_delete_record($expire['uid'], $expire['rid']);
      watchdog('role expire', 'Remove role @role from user @account.', array(
        '@role' => $roles[$expire['rid']],
        '@account' => $account->name,
      ));
    }
  }
}

/**
 * Add form element that accepts the role expiration time.
 *
 * @param $account
 *   The user object.
 * @return
 *   Form element.
 */
function role_expire_add_expiration_input($account = NULL) {
  $form = array();
  if (user_access('administer users') || user_access('administer role expire')) {
    drupal_add_js(drupal_get_path('module', 'role_expire') . '/role_expire.js', 'module');
    $form['roles']['#attributes'] = array(
      'class' => 'role-expire-roles',
    );
    foreach (_role_expire_get_role() as $rid => $role) {
      if (is_object($account) and array_key_exists('uid', $account)) {
        $expiry_timestamp = role_expire_get_user_role_expiry_time($account->uid, $rid);
      }
      else {
        $expiry_timestamp = '';
      }
      $form['role_expire_' . $rid] = array(
        '#title' => t("%role role expiration time", array(
          '%role' => drupal_ucfirst($role),
        )),
        '#type' => 'textfield',
        '#default_value' => !empty($expiry_timestamp) ? date("d-m-Y G:i:s", $expiry_timestamp) : '',
        '#attributes' => array(
          'class' => 'role-expire-role-expiry',
        ),
        '#description' => t("Leave blank for default role expiry (never, or the duration you have set for the role), enter date and time in format: <em>yyyy-mm-dd hh:mm:ss</em> or use relative time i.e. 1 day, 2 months, 1 year, 3 years."),
      );
    }
  }
  return $form;
}

/*******************************************************************************
 * Helper functions
 ******************************************************************************/

/**
 * Helper function; Store user roles for this page request.
 * @return
 *   array of roles
 */
function _role_static_user_roles($id, $roles = '') {
  static $user_roles = array();
  if (!isset($user_roles[$id]) && is_array($roles)) {
    $user_roles[$id] = $roles;
  }
  if (!isset($user_roles[$id])) {
    return FALSE;
  }
  else {
    return $user_roles[$id];
  }
}

/**
 * Helper function; Get valid roles.
 * @return unknown_type
 */
function _role_expire_get_role() {
  $roles = user_roles(TRUE);
  unset($roles[DRUPAL_AUTHENTICATED_RID]);
  return $roles;
}
function role_expire_process_default_role_duration_for_user($role_id, $uid) {

  // Does a default expiry exist?.
  $role_day_period = role_expire_get_default_duration($role_id);
  if ($role_day_period) {
    $user_role_expiry = role_expire_get_user_role_expiry_time($uid, $role_id);

    // If the expiry is empty then we act!.
    if (!$user_role_expiry) {

      // Add the current date to the role day period and save it back to the role_expire row.
      role_expire_write_record($uid, $role_id, mktime(0, 0, 0, date("m"), date("d") + $role_day_period, date("Y")));
    }
  }
}

Functions

Namesort descending Description
role_expire_add_expiration_input Add form element that accepts the role expiration time.
role_expire_cron Implementation of hook_cron().
role_expire_delete_default_duration API function; Delete a default duration for a role.
role_expire_delete_record API function; Delete a record from the database.
role_expire_delete_user_records API function; Delete all user expirations.
role_expire_form_user_admin_role_alter Implementation of hook_form_FORM-ID_alter().
role_expire_form_user_profile_form_alter Implementation of hook_form_FORM-ID_alter().
role_expire_form_user_register_alter Implementation of hook_form_FORM-ID_alter().
role_expire_get_all_user_records API function; Get expiration of all roles of a user.
role_expire_get_default_duration API function; Get all the default duration for a role.
role_expire_get_expired API function; Get all records that should be expired.
role_expire_get_user_role_expiry_time API function; Get expiration time of a user role.
role_expire_migrate_init Implementation of hook_migrate_init().
role_expire_perm Implementation of hook_perm().
role_expire_process_default_role_duration_for_user
role_expire_set_default_duration API function; Set the default expiry duration for a role.
role_expire_user Implementation of hook_user().
role_expire_user_admin_role_submit
role_expire_user_admin_role_validate
role_expire_views_api Implementation of hook_views_api().
role_expire_write_record API function; Insert or update a record in the database.
_role_expire_get_role Helper function; Get valid roles.
_role_static_user_roles Helper function; Store user roles for this page request.