/[drupal]/drupal/modules/user/user.module
ViewVC logotype

Diff of /drupal/modules/user/user.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph | View Patch Patch

revision 1.952 by dries, Sun Jan 4 16:10:48 2009 UTC revision 1.953 by webchick, Thu Jan 8 08:42:13 2009 UTC
# Line 1  Line 1 
1  <?php  <?php
2  // $Id: user.module,v 1.951 2008/12/30 16:43:20 dries Exp $  // $Id: user.module,v 1.952 2009/01/04 16:10:48 dries Exp $
3    
4  /**  /**
5   * @file   * @file
# Line 16  define('USERNAME_MAX_LENGTH', 60); Line 16  define('USERNAME_MAX_LENGTH', 60);
16   */   */
17  define('EMAIL_MAX_LENGTH', 64);  define('EMAIL_MAX_LENGTH', 64);
18    
19    
20  /**  /**
21   * Invokes hook_user() in every module.   * Invokes hook_user() in every module.
22   *   *
# Line 587  function user_perm() { Line 588  function user_perm() {
588         'title' => t('Change own username'),         'title' => t('Change own username'),
589         'description' => t('Select a different username.'),         'description' => t('Select a different username.'),
590       ),       ),
591         'cancel account' => array(
592           'title' => t('Cancel account'),
593           'description' => t('Remove or disable own user account and unpublish, anonymize, or remove own submissions depending on the configured <a href="@user-settings-url">user settings</a>.', array('@user-settings-url' => url('admin/user/settings'))),
594         ),
595         'select account cancellation method' => array(
596           'title' => t('Select method for cancelling own account'),
597           'description' => t('Select the method for cancelling own user account. %warning', array('%warning' => t('Warning: Give to trusted roles only; this permission has security implications.'))),
598         ),
599     );     );
600  }  }
601    
# Line 948  function user_edit_access($account) { Line 957  function user_edit_access($account) {
957    return (($GLOBALS['user']->uid == $account->uid) || user_access('administer users')) && $account->uid > 0;    return (($GLOBALS['user']->uid == $account->uid) || user_access('administer users')) && $account->uid > 0;
958  }  }
959    
960    /**
961     * Menu access callback; limit access to account cancellation pages.
962     *
963     * Limit access to users with the 'cancel account' permission or administrative
964     * users, and prevent the anonymous user from cancelling the account.
965     */
966    function user_cancel_access($account) {
967      return ((($GLOBALS['user']->uid == $account->uid) && user_access('cancel account')) || user_access('administer users')) && $account->uid > 0;
968    }
969    
970  function user_load_self($arg) {  function user_load_self($arg) {
971    $arg[1] = user_load($GLOBALS['user']->uid);    $arg[1] = user_load($GLOBALS['user']->uid);
972    return $arg;    return $arg;
# Line 1082  function user_menu() { Line 1101  function user_menu() {
1101      'weight' => -10,      'weight' => -10,
1102    );    );
1103    
1104    $items['user/%user/delete'] = array(    $items['user/%user/cancel'] = array(
1105      'title' => 'Delete',      'title' => 'Cancel account',
1106      'page callback' => 'drupal_get_form',      'page callback' => 'drupal_get_form',
1107      'page arguments' => array('user_confirm_delete', 1),      'page arguments' => array('user_cancel_confirm_form', 1),
1108      'access callback' => 'user_access',      'access callback' => 'user_cancel_access',
1109      'access arguments' => array('administer users'),      'access arguments' => array(1),
1110        'type' => MENU_CALLBACK,
1111      );
1112    
1113      $items['user/%user/cancel/confirm/%/%'] = array(
1114        'title' => 'Confirm account cancellation',
1115        'page callback' => 'user_cancel_confirm',
1116        'page arguments' => array(1, 4, 5),
1117        'access callback' => 'user_cancel_access',
1118        'access arguments' => array(1),
1119      'type' => MENU_CALLBACK,      'type' => MENU_CALLBACK,
1120    );    );
1121    
# Line 1445  function user_pass_reset_url($account) { Line 1473  function user_pass_reset_url($account) {
1473    return url("user/reset/$account->uid/$timestamp/" . user_pass_rehash($account->pass, $timestamp, $account->login), array('absolute' => TRUE));    return url("user/reset/$account->uid/$timestamp/" . user_pass_rehash($account->pass, $timestamp, $account->login), array('absolute' => TRUE));
1474  }  }
1475    
1476    /**
1477     * Generate a URL to confirm an account cancellation request.
1478     *
1479     * @see user_mail_tokens()
1480     * @see user_cancel_confirm()
1481     */
1482    function user_cancel_url($account) {
1483      $timestamp = REQUEST_TIME;
1484      return url("user/$account->uid/cancel/confirm/$timestamp/" . user_pass_rehash($account->pass, $timestamp, $account->login), array('absolute' => TRUE));
1485    }
1486    
1487  function user_pass_rehash($password, $timestamp, $login) {  function user_pass_rehash($password, $timestamp, $login) {
1488    return md5($timestamp . $password . $login);    return md5($timestamp . $password . $login);
1489  }  }
# Line 1595  function _user_edit_submit($account, &$e Line 1634  function _user_edit_submit($account, &$e
1634  }  }
1635    
1636  /**  /**
1637   * Delete a user.   * Cancel a user account.
1638   *   *
1639   * @param $edit An array of submitted form values.   * Since the user cancellation process needs to be run in a batch, either
1640   * @param $uid The user ID of the user to delete.   * Form API will invoke it, or batch_process() needs to be invoked after calling
1641     * this function and should define the path to redirect to.
1642     *
1643     * @param $edit
1644     *   An array of submitted form values.
1645     * @param $uid
1646     *   The user ID of the user account to cancel.
1647     * @param $method
1648     *   The account cancellation method to use.
1649     *
1650     * @see _user_cancel()
1651   */   */
1652  function user_delete($edit, $uid) {  function user_cancel($edit, $uid, $method) {
1653      global $user;
1654    
1655    $account = user_load(array('uid' => $uid));    $account = user_load(array('uid' => $uid));
1656    drupal_session_destroy_uid($uid);  
1657    _user_mail_notify('status_deleted', $account);    if (!$account) {
1658    module_invoke_all('user_delete', $edit, $account);      drupal_set_message(t('The user account %id does not exist.', array('%id' => $uid)), 'error');
1659    db_query('DELETE FROM {users} WHERE uid = %d', $uid);      watchdog('user', 'Attempted to cancel non-existing user account: %id.', array('%id' => $uid), WATCHDOG_ERROR);
1660    db_query('DELETE FROM {users_roles} WHERE uid = %d', $uid);      return;
1661    db_query('DELETE FROM {authmap} WHERE uid = %d', $uid);    }
1662    $variables = array('%name' => $account->name, '%email' => '<' . $account->mail . '>');  
1663    watchdog('user', 'Deleted user: %name %email.', $variables, WATCHDOG_NOTICE);    // Initialize batch (to set title).
1664      $batch = array(
1665        'title' => t('Cancelling account'),
1666        'operations' => array(),
1667      );
1668      batch_set($batch);
1669    
1670      // Allow modules to add further sets to this batch.
1671      module_invoke_all('user_cancel', $edit, $account, $method);
1672    
1673      // Finish the batch and actually cancel the account.
1674      $batch = array(
1675        'title' => t('Cancelling user account'),
1676        'operations' => array(
1677          array('_user_cancel', array($edit, $account, $method)),
1678        ),
1679      );
1680      batch_set($batch);
1681    
1682      // Batch processing is either handled via Form API or has to be invoked
1683      // manually.
1684    }
1685    
1686    /**
1687     * Last batch processing step for cancelling a user account.
1688     *
1689     * Since batch and session API require a valid user account, the actual
1690     * cancellation of a user account needs to happen last.
1691     *
1692     * @see user_cancel()
1693     */
1694    function _user_cancel($edit, $account, $method) {
1695      global $user;
1696    
1697      switch ($method) {
1698        case 'user_cancel_block':
1699        case 'user_cancel_block_unpublish':
1700        default:
1701          // Send account blocked notification if option was checked.
1702          if (!empty($edit['user_cancel_notify'])) {
1703            _user_mail_notify('status_blocked', $account);
1704          }
1705          db_update('users')->fields(array('status' => 0))->condition('uid', $account->uid)->execute();
1706          drupal_set_message(t('%name has been disabled.', array('%name' => $account->name)));
1707          break;
1708    
1709        case 'user_cancel_reassign':
1710        case 'user_cancel_delete':
1711          // Send account canceled notification if option was checked.
1712          if (!empty($edit['user_cancel_notify'])) {
1713            _user_mail_notify('status_canceled', $account);
1714          }
1715          db_delete('users')->condition('uid', $account->uid)->execute();
1716          db_delete('users_roles')->condition('uid', $account->uid)->execute();
1717          db_delete('authmap')->condition('uid', $account->uid)->execute();
1718          drupal_set_message(t('%name has been deleted.', array('%name' => $account->name)));
1719          $variables = array('%name' => $account->name, '%email' => '<' . $account->mail . '>');
1720          watchdog('user', 'Deleted user: %name %email.', $variables, WATCHDOG_NOTICE);
1721          break;
1722      }
1723    
1724      // After cancelling account, ensure that user is logged out.
1725      if ($account->uid == $user->uid) {
1726        // Destroy the current session.
1727        session_destroy();
1728        // Load the anonymous user.
1729        $user = drupal_anonymous_user();
1730      }
1731      else {
1732        drupal_session_destroy_uid($account->uid);
1733      }
1734    
1735      // Clear the cache for anonymous users.
1736      cache_clear_all();
1737  }  }
1738    
1739  /**  /**
# Line 1682  function _user_mail_text($key, $language Line 1806  function _user_mail_text($key, $language
1806          return t('Account details for !username at !site (blocked)', $variables, $langcode);          return t('Account details for !username at !site (blocked)', $variables, $langcode);
1807        case 'status_blocked_body':        case 'status_blocked_body':
1808          return t("!username,\n\nYour account on !site has been blocked.", $variables, $langcode);          return t("!username,\n\nYour account on !site has been blocked.", $variables, $langcode);
1809        case 'status_deleted_subject':  
1810          return t('Account details for !username at !site (deleted)', $variables, $langcode);        case 'cancel_confirm_subject':
1811        case 'status_deleted_body':          return t('Account cancellation request for !username at !site', $variables, $langcode);
1812          return t("!username,\n\nYour account on !site has been deleted.", $variables, $langcode);        case 'cancel_confirm_body':
1813            return t("!username,
1814    
1815    A request to cancel your account has been made at !site.
1816    
1817    You may now cancel your account on !uri_brief by clicking this link or copying and pasting it into your browser:
1818    
1819    !cancel_url
1820    
1821    NOTE: The cancellation of your account is not reversible.
1822    
1823    This link expires in one day and nothing will happen if it is not used.", $variables, $langcode);
1824    
1825          case 'status_canceled_subject':
1826            return t('Account details for !username at !site (canceled)', $variables, $langcode);
1827          case 'status_canceled_body':
1828            return t("!username,
1829    
1830    Your account on !site has been canceled.", $variables, $langcode);
1831      }      }
1832    }    }
1833  }  }
# Line 1752  function user_user_operations($form_stat Line 1894  function user_user_operations($form_stat
1894        'label' => t('Block the selected users'),        'label' => t('Block the selected users'),
1895        'callback' => 'user_user_operations_block',        'callback' => 'user_user_operations_block',
1896      ),      ),
1897      'delete' => array(      'cancel' => array(
1898        'label' => t('Delete the selected users'),        'label' => t('Cancel the selected user accounts'),
1899      ),      ),
1900    );    );
1901    
# Line 1866  function user_multiple_role_edit($accoun Line 2008  function user_multiple_role_edit($accoun
2008    }    }
2009  }  }
2010    
2011  function user_multiple_delete_confirm(&$form_state) {  function user_multiple_cancel_confirm(&$form_state) {
2012    $edit = $form_state['post'];    $edit = $form_state['post'];
2013    
2014    $form['accounts'] = array('#prefix' => '<ul>', '#suffix' => '</ul>', '#tree' => TRUE);    $form['accounts'] = array('#prefix' => '<ul>', '#suffix' => '</ul>', '#tree' => TRUE);
# Line 1875  function user_multiple_delete_confirm(&$ Line 2017  function user_multiple_delete_confirm(&$
2017      $user = db_result(db_query('SELECT name FROM {users} WHERE uid = %d', $uid));      $user = db_result(db_query('SELECT name FROM {users} WHERE uid = %d', $uid));
2018      $form['accounts'][$uid] = array('#type' => 'hidden', '#value' => $uid, '#prefix' => '<li>', '#suffix' => check_plain($user) . "</li>\n");      $form['accounts'][$uid] = array('#type' => 'hidden', '#value' => $uid, '#prefix' => '<li>', '#suffix' => check_plain($user) . "</li>\n");
2019    }    }
2020    $form['operation'] = array('#type' => 'hidden', '#value' => 'delete');  
2021      $form['operation'] = array('#type' => 'hidden', '#value' => 'cancel');
2022    
2023      module_load_include('inc', 'user', 'user.pages');
2024      $form['user_cancel_method'] = array(
2025        '#type' => 'item',
2026        '#title' => t('When cancelling these accounts'),
2027      );
2028      $form['user_cancel_method'] += user_cancel_methods();
2029      // Remove method descriptions.
2030      foreach (element_children($form['user_cancel_method']) as $element) {
2031        unset($form['user_cancel_method'][$element]['#description']);
2032      }
2033    
2034      // Allow to send the account cancellation confirmation mail.
2035      $form['user_cancel_confirm'] = array(
2036        '#type' => 'checkbox',
2037        '#title' => t('Require e-mail confirmation to cancel account.'),
2038        '#default_value' => FALSE,
2039        '#description' => t('When enabled, the user must confirm the account cancellation via e-mail.'),
2040      );
2041      // Also allow to send account canceled notification mail, if enabled.
2042      $form['user_cancel_notify'] = array(
2043        '#type' => 'checkbox',
2044        '#title' => t('Notify user when account is canceled.'),
2045        '#default_value' => FALSE,
2046        '#access' => variable_get('user_mail_status_canceled_notify', FALSE),
2047        '#description' => t('When enabled, the user will receive an e-mail notification after the account has been cancelled.'),
2048      );
2049    
2050    return confirm_form($form,    return confirm_form($form,
2051                        t('Are you sure you want to delete these users?'),                        t('Are you sure you want to cancel these user accounts?'),
2052                        'admin/user/user', t('This action cannot be undone.'),                        'admin/user/user', t('This action cannot be undone.'),
2053                        t('Delete all'), t('Cancel'));                        t('Cancel accounts'), t('Cancel'));
2054  }  }
2055    
2056  function user_multiple_delete_confirm_submit($form, &$form_state) {  /**
2057     * Submit handler for mass-account cancellation form.
2058     *
2059     * @see user_multiple_cancel_confirm()
2060     * @see user_cancel_confirm_form_submit()
2061     */
2062    function user_multiple_cancel_confirm_submit($form, &$form_state) {
2063      global $user;
2064    
2065    if ($form_state['values']['confirm']) {    if ($form_state['values']['confirm']) {
2066      foreach ($form_state['values']['accounts'] as $uid => $value) {      foreach ($form_state['values']['accounts'] as $uid => $value) {
2067        user_delete($form_state['values'], $uid);        // Prevent user administrators from deleting themselves without confirmation.
2068          if ($uid == $user->uid) {
2069            $admin_form_state = $form_state;
2070            unset($admin_form_state['values']['user_cancel_confirm']);
2071            $admin_form_state['values']['_account'] = $user;
2072            user_cancel_confirm_form_submit(array(), $admin_form_state);
2073          }
2074          else {
2075            user_cancel($form_state['values'], $uid, $form_state['values']['user_cancel_method']);
2076          }
2077      }      }
     drupal_set_message(t('The users have been deleted.'));  
2078    }    }
2079    $form_state['redirect'] = 'admin/user/user';    $form_state['redirect'] = 'admin/user/user';
2080    return;    return;
# Line 2082  function user_mail_tokens($account, $lan Line 2268  function user_mail_tokens($account, $lan
2268      '!username' => $account->name,      '!username' => $account->name,
2269      '!site' => variable_get('site_name', 'Drupal'),      '!site' => variable_get('site_name', 'Drupal'),
2270      '!login_url' => user_pass_reset_url($account),      '!login_url' => user_pass_reset_url($account),
2271        '!cancel_url' => user_cancel_url($account),
2272      '!uri' => $base_url,      '!uri' => $base_url,
2273      '!uri_brief' => preg_replace('!^https?://!', '', $base_url),      '!uri_brief' => preg_replace('!^https?://!', '', $base_url),
2274      '!mailto' => $account->mail,      '!mailto' => $account->mail,
# Line 2133  function user_preferred_language($accoun Line 2320  function user_preferred_language($accoun
2320   *  'password_reset': Password recovery request   *  'password_reset': Password recovery request
2321   *  'status_activated': Account activated   *  'status_activated': Account activated
2322   *  'status_blocked': Account blocked   *  'status_blocked': Account blocked
2323   *  'status_deleted': Account deleted   *  'cancel_confirm': Account cancellation request
2324     *  'status_canceled': Account canceled
2325   *   *
2326   * @param $account   * @param $account
2327   *  The user object of the account being notified. Must contain at   *  The user object of the account being notified. Must contain at
# Line 2144  function user_preferred_language($accoun Line 2332  function user_preferred_language($accoun
2332   *  The return value from drupal_mail_send(), if ends up being called.   *  The return value from drupal_mail_send(), if ends up being called.
2333   */   */
2334  function _user_mail_notify($op, $account, $language = NULL) {  function _user_mail_notify($op, $account, $language = NULL) {
2335    // By default, we always notify except for deleted and blocked.    // By default, we always notify except for canceled and blocked.
2336    $default_notify = ($op != 'status_deleted' && $op != 'status_blocked');    $default_notify = ($op != 'status_canceled' && $op != 'status_blocked');
2337    $notify = variable_get('user_mail_' . $op . '_notify', $default_notify);    $notify = variable_get('user_mail_' . $op . '_notify', $default_notify);
2338    if ($notify) {    if ($notify) {
2339      $params['account'] = $account;      $params['account'] = $account;

Legend:
Removed from v.1.952  
changed lines
  Added in v.1.953

  ViewVC Help
Powered by ViewVC 1.1.3