web/drupal/modules/user/user.pages.inc
branchdrupal
changeset 74 0ff3ba646492
equal deleted inserted replaced
73:fcf75e232c5b 74:0ff3ba646492
       
     1 <?php
       
     2 // $Id: user.pages.inc,v 1.11.2.1 2008/10/08 20:12:18 goba Exp $
       
     3 
       
     4 /**
       
     5  * @file
       
     6  * User page callback file for the user module.
       
     7  */
       
     8 
       
     9 /**
       
    10  * Menu callback; Retrieve a JSON object containing autocomplete suggestions for existing users.
       
    11  */
       
    12 function user_autocomplete($string = '') {
       
    13   $matches = array();
       
    14   if ($string) {
       
    15     $result = db_query_range("SELECT name FROM {users} WHERE LOWER(name) LIKE LOWER('%s%%')", $string, 0, 10);
       
    16     while ($user = db_fetch_object($result)) {
       
    17       $matches[$user->name] = check_plain($user->name);
       
    18     }
       
    19   }
       
    20 
       
    21   drupal_json($matches);
       
    22 }
       
    23 
       
    24 /**
       
    25  * Form builder; Request a password reset.
       
    26  *
       
    27  * @ingroup forms
       
    28  * @see user_pass_validate()
       
    29  * @see user_pass_submit()
       
    30  */
       
    31 function user_pass() {
       
    32   $form['name'] = array(
       
    33     '#type' => 'textfield',
       
    34     '#title' => t('Username or e-mail address'),
       
    35     '#size' => 60,
       
    36     '#maxlength' => max(USERNAME_MAX_LENGTH, EMAIL_MAX_LENGTH),
       
    37     '#required' => TRUE,
       
    38   );
       
    39   $form['submit'] = array('#type' => 'submit', '#value' => t('E-mail new password'));
       
    40 
       
    41   return $form;
       
    42 }
       
    43 
       
    44 function user_pass_validate($form, &$form_state) {
       
    45   $name = trim($form_state['values']['name']);
       
    46   
       
    47   // Blocked accounts cannot request a new password,
       
    48   // check provided username and email against access rules.
       
    49   if (drupal_is_denied('user', $name) || drupal_is_denied('mail', $name)) {
       
    50     form_set_error('name', t('%name is not allowed to request a new password.', array('%name' => $name)));
       
    51   }
       
    52 
       
    53   // Try to load by email.
       
    54   $account = user_load(array('mail' => $name, 'status' => 1));
       
    55   if (!$account) {
       
    56     // No success, try to load by name.
       
    57     $account = user_load(array('name' => $name, 'status' => 1));
       
    58   }
       
    59   if (isset($account->uid)) {
       
    60     form_set_value(array('#parents' => array('account')), $account, $form_state);
       
    61   }
       
    62   else {
       
    63     form_set_error('name', t('Sorry, %name is not recognized as a user name or an e-mail address.', array('%name' => $name)));
       
    64   }
       
    65 }
       
    66 
       
    67 function user_pass_submit($form, &$form_state) {
       
    68   global $language;
       
    69 
       
    70   $account = $form_state['values']['account'];
       
    71   // Mail one time login URL and instructions using current language.
       
    72   _user_mail_notify('password_reset', $account, $language);
       
    73   watchdog('user', 'Password reset instructions mailed to %name at %email.', array('%name' => $account->name, '%email' => $account->mail));
       
    74   drupal_set_message(t('Further instructions have been sent to your e-mail address.'));
       
    75 
       
    76   $form_state['redirect'] = 'user';
       
    77   return;
       
    78 }
       
    79 
       
    80 /**
       
    81  * Menu callback; process one time login link and redirects to the user page on success.
       
    82  */
       
    83 function user_pass_reset(&$form_state, $uid, $timestamp, $hashed_pass, $action = NULL) {
       
    84   global $user;
       
    85 
       
    86   // Check if the user is already logged in. The back button is often the culprit here.
       
    87   if ($user->uid) {
       
    88     drupal_set_message(t('You have already used this one-time login link. It is not necessary to use this link to login anymore. You are already logged in.'));
       
    89     drupal_goto();
       
    90   }
       
    91   else {
       
    92     // Time out, in seconds, until login URL expires. 24 hours = 86400 seconds.
       
    93     $timeout = 86400;
       
    94     $current = time();
       
    95     // Some redundant checks for extra security ?
       
    96     if ($timestamp < $current && $account = user_load(array('uid' => $uid, 'status' => 1)) ) {
       
    97       // Deny one-time login to blocked accounts.
       
    98       if (drupal_is_denied('user', $account->name) || drupal_is_denied('mail', $account->mail)) {
       
    99         drupal_set_message(t('You have tried to use a one-time login for an account which has been blocked.'), 'error');
       
   100         drupal_goto();
       
   101       }
       
   102 
       
   103       // No time out for first time login.
       
   104       if ($account->login && $current - $timestamp > $timeout) {
       
   105         drupal_set_message(t('You have tried to use a one-time login link that has expired. Please request a new one using the form below.'));
       
   106         drupal_goto('user/password');
       
   107       }
       
   108       else if ($account->uid && $timestamp > $account->login && $timestamp < $current && $hashed_pass == user_pass_rehash($account->pass, $timestamp, $account->login)) {
       
   109         // First stage is a confirmation form, then login
       
   110         if ($action == 'login') {
       
   111           watchdog('user', 'User %name used one-time login link at time %timestamp.', array('%name' => $account->name, '%timestamp' => $timestamp));
       
   112           // Set the new user.
       
   113           $user = $account;
       
   114           // user_authenticate_finalize() also updates the login timestamp of the
       
   115           // user, which invalidates further use of the one-time login link.
       
   116           user_authenticate_finalize($form_state['values']);
       
   117           drupal_set_message(t('You have just used your one-time login link. It is no longer necessary to use this link to login. Please change your password.'));
       
   118           drupal_goto('user/'. $user->uid .'/edit');
       
   119         }
       
   120         else {
       
   121           $form['message'] = array('#value' => t('<p>This is a one-time login for %user_name and will expire on %expiration_date.</p><p>Click on this button to login to the site and change your password.</p>', array('%user_name' => $account->name, '%expiration_date' => format_date($timestamp + $timeout))));
       
   122           $form['help'] = array('#value' => '<p>'. t('This login can be used only once.') .'</p>');
       
   123           $form['submit'] = array('#type' => 'submit', '#value' => t('Log in'));
       
   124           $form['#action'] = url("user/reset/$uid/$timestamp/$hashed_pass/login");
       
   125           return $form;
       
   126         }
       
   127       }
       
   128       else {
       
   129         drupal_set_message(t('You have tried to use a one-time login link which has either been used or is no longer valid. Please request a new one using the form below.'));
       
   130         drupal_goto('user/password');
       
   131       }
       
   132     }
       
   133     else {
       
   134       // Deny access, no more clues.
       
   135       // Everything will be in the watchdog's URL for the administrator to check.
       
   136       drupal_access_denied();
       
   137     }
       
   138   }
       
   139 }
       
   140 
       
   141 /**
       
   142  * Menu callback; logs the current user out, and redirects to the home page.
       
   143  */
       
   144 function user_logout() {
       
   145   global $user;
       
   146 
       
   147   watchdog('user', 'Session closed for %name.', array('%name' => $user->name));
       
   148 
       
   149   // Destroy the current session:
       
   150   session_destroy();
       
   151   module_invoke_all('user', 'logout', NULL, $user);
       
   152 
       
   153   // Load the anonymous user
       
   154   $user = drupal_anonymous_user();
       
   155 
       
   156   drupal_goto();
       
   157 }
       
   158 
       
   159 /**
       
   160  * Menu callback; Displays a user or user profile page.
       
   161  */
       
   162 function user_view($account) {
       
   163   drupal_set_title(check_plain($account->name));
       
   164   // Retrieve all profile fields and attach to $account->content.
       
   165   user_build_content($account);
       
   166 
       
   167   // To theme user profiles, copy modules/user/user_profile.tpl.php
       
   168   // to your theme directory, and edit it as instructed in that file's comments.
       
   169   return theme('user_profile', $account);
       
   170 }
       
   171 
       
   172 /**
       
   173  * Process variables for user-profile.tpl.php.
       
   174  *
       
   175  * The $variables array contains the following arguments:
       
   176  * - $account
       
   177  *
       
   178  * @see user-picture.tpl.php
       
   179  */
       
   180 function template_preprocess_user_profile(&$variables) {
       
   181   $variables['profile'] = array();
       
   182   // Sort sections by weight
       
   183   uasort($variables['account']->content, 'element_sort');
       
   184   // Provide keyed variables so themers can print each section independantly.
       
   185   foreach (element_children($variables['account']->content) as $key) {
       
   186     $variables['profile'][$key] = drupal_render($variables['account']->content[$key]);
       
   187   }
       
   188   // Collect all profiles to make it easier to print all items at once.
       
   189   $variables['user_profile'] = implode($variables['profile']);
       
   190 }
       
   191 
       
   192 /**
       
   193  * Process variables for user-profile-item.tpl.php.
       
   194  *
       
   195  * The $variables array contains the following arguments:
       
   196  * - $element
       
   197  *
       
   198  * @see user-profile-item.tpl.php
       
   199  */
       
   200 function template_preprocess_user_profile_item(&$variables) {
       
   201   $variables['title'] = $variables['element']['#title'];
       
   202   $variables['value'] = $variables['element']['#value'];
       
   203   $variables['attributes'] = '';
       
   204   if (isset($variables['element']['#attributes'])) {
       
   205     $variables['attributes'] = drupal_attributes($variables['element']['#attributes']);
       
   206   }
       
   207 }
       
   208 
       
   209 /**
       
   210  * Process variables for user-profile-category.tpl.php.
       
   211  *
       
   212  * The $variables array contains the following arguments:
       
   213  * - $element
       
   214  *
       
   215  * @see user-profile-category.tpl.php
       
   216  */
       
   217 function template_preprocess_user_profile_category(&$variables) {
       
   218   $variables['title'] = check_plain($variables['element']['#title']);
       
   219   $variables['profile_items'] = $variables['element']['#children'];
       
   220   $variables['attributes'] = '';
       
   221   if (isset($variables['element']['#attributes'])) {
       
   222     $variables['attributes'] = drupal_attributes($variables['element']['#attributes']);
       
   223   }
       
   224 }
       
   225 
       
   226 /**
       
   227  * Form builder; Present the form to edit a given user or profile category.
       
   228  *
       
   229  * @ingroup forms
       
   230  * @see user_edit_validate()
       
   231  * @see user_edit_submit()
       
   232  */
       
   233 function user_edit($account, $category = 'account') {
       
   234   drupal_set_title(check_plain($account->name));
       
   235   return drupal_get_form('user_profile_form', $account, $category);
       
   236 }
       
   237 
       
   238 /**
       
   239  * Form builder; edit a user account or one of their profile categories.
       
   240  *
       
   241  * @ingroup forms
       
   242  * @see user_profile_form_validate()
       
   243  * @see user_profile_form_submit()
       
   244  * @see user_edit_delete_submit()
       
   245  */
       
   246 function user_profile_form($form_state, $account, $category = 'account') {
       
   247 
       
   248   $edit = (empty($form_state['values'])) ? (array)$account : $form_state['values'];
       
   249 
       
   250   $form = _user_forms($edit, $account, $category);
       
   251   $form['_category'] = array('#type' => 'value', '#value' => $category);
       
   252   $form['_account'] = array('#type' => 'value', '#value' => $account);
       
   253   $form['submit'] = array('#type' => 'submit', '#value' => t('Save'), '#weight' => 30);
       
   254   if (user_access('administer users')) {
       
   255     $form['delete'] = array(
       
   256       '#type' => 'submit',
       
   257       '#value' => t('Delete'),
       
   258       '#weight' => 31,
       
   259       '#submit' => array('user_edit_delete_submit'),
       
   260     );
       
   261   }
       
   262   $form['#attributes']['enctype'] = 'multipart/form-data';
       
   263 
       
   264   return $form;
       
   265 }
       
   266 
       
   267 /**
       
   268  * Validation function for the user account and profile editing form.
       
   269  */
       
   270 function user_profile_form_validate($form, &$form_state) {
       
   271   user_module_invoke('validate', $form_state['values'], $form_state['values']['_account'], $form_state['values']['_category']);
       
   272   // Validate input to ensure that non-privileged users can't alter protected data.
       
   273   if ((!user_access('administer users') && array_intersect(array_keys($form_state['values']), array('uid', 'init', 'session'))) || (!user_access('administer permissions') && isset($form_state['values']['roles']))) {
       
   274     watchdog('security', 'Detected malicious attempt to alter protected user fields.', array(), WATCHDOG_WARNING);
       
   275     // set this to a value type field
       
   276     form_set_error('category', t('Detected malicious attempt to alter protected user fields.'));
       
   277   }
       
   278 }
       
   279 
       
   280 /**
       
   281  * Submit function for the user account and profile editing form.
       
   282  */
       
   283 function user_profile_form_submit($form, &$form_state) {
       
   284   $account = $form_state['values']['_account'];
       
   285   $category = $form_state['values']['_category'];
       
   286   unset($form_state['values']['_account'], $form_state['values']['op'], $form_state['values']['submit'], $form_state['values']['delete'], $form_state['values']['form_token'], $form_state['values']['form_id'], $form_state['values']['_category']);
       
   287   user_module_invoke('submit', $form_state['values'], $account, $category);
       
   288   user_save($account, $form_state['values'], $category);
       
   289 
       
   290   // Clear the page cache because pages can contain usernames and/or profile information:
       
   291   cache_clear_all();
       
   292 
       
   293   drupal_set_message(t('The changes have been saved.'));
       
   294   return;
       
   295 }
       
   296 
       
   297 /**
       
   298  * Submit function for the 'Delete' button on the user edit form.
       
   299  */
       
   300 function user_edit_delete_submit($form, &$form_state) {
       
   301   $destination = '';
       
   302   if (isset($_REQUEST['destination'])) {
       
   303     $destination = drupal_get_destination();
       
   304     unset($_REQUEST['destination']);
       
   305   }
       
   306   // Note: We redirect from user/uid/edit to user/uid/delete to make the tabs disappear.
       
   307   $form_state['redirect'] = array("user/". $form_state['values']['_account']->uid ."/delete", $destination);
       
   308 }
       
   309 
       
   310 /**
       
   311  * Form builder; confirm form for user deletion.
       
   312  *
       
   313  * @ingroup forms
       
   314  * @see user_confirm_delete_submit()
       
   315  */
       
   316 function user_confirm_delete(&$form_state, $account) {
       
   317 
       
   318   $form['_account'] = array('#type' => 'value', '#value' => $account);
       
   319 
       
   320   return confirm_form($form,
       
   321     t('Are you sure you want to delete the account %name?', array('%name' => $account->name)),
       
   322     'user/'. $account->uid,
       
   323     t('All submissions made by this user will be attributed to the anonymous account. This action cannot be undone.'),
       
   324     t('Delete'), t('Cancel'));
       
   325 }
       
   326 
       
   327 /**
       
   328  * Submit function for the confirm form for user deletion.
       
   329  */
       
   330 function user_confirm_delete_submit($form, &$form_state) {
       
   331   user_delete($form_state['values'], $form_state['values']['_account']->uid);
       
   332   drupal_set_message(t('%name has been deleted.', array('%name' => $form_state['values']['_account']->name)));
       
   333 
       
   334   if (!isset($_REQUEST['destination'])) {
       
   335     $form_state['redirect'] = 'admin/user/user';
       
   336   }
       
   337 }
       
   338 
       
   339 function user_edit_validate($form, &$form_state) {
       
   340   user_module_invoke('validate', $form_state['values'], $form_state['values']['_account'], $form_state['values']['_category']);
       
   341   // Validate input to ensure that non-privileged users can't alter protected data.
       
   342   if ((!user_access('administer users') && array_intersect(array_keys($form_state['values']), array('uid', 'init', 'session'))) || (!user_access('administer permissions') && isset($form_state['values']['roles']))) {
       
   343     watchdog('security', 'Detected malicious attempt to alter protected user fields.', array(), WATCHDOG_WARNING);
       
   344     // set this to a value type field
       
   345     form_set_error('category', t('Detected malicious attempt to alter protected user fields.'));
       
   346   }
       
   347 }
       
   348 
       
   349 function user_edit_submit($form, &$form_state) {
       
   350   $account = $form_state['values']['_account'];
       
   351   $category = $form_state['values']['_category'];
       
   352   unset($form_state['values']['_account'], $form_state['values']['op'], $form_state['values']['submit'], $form_state['values']['delete'], $form_state['values']['form_token'], $form_state['values']['form_id'], $form_state['values']['_category']);
       
   353   user_module_invoke('submit', $form_state['values'], $account, $category);
       
   354   user_save($account, $form_state['values'], $category);
       
   355 
       
   356   // Clear the page cache because pages can contain usernames and/or profile information:
       
   357   cache_clear_all();
       
   358 
       
   359   drupal_set_message(t('The changes have been saved.'));
       
   360   return;
       
   361 }
       
   362 
       
   363 /**
       
   364  * Access callback for path /user.
       
   365  *
       
   366  * Displays user profile if user is logged in, or login form for anonymous
       
   367  * users.
       
   368  */
       
   369 function user_page() {
       
   370   global $user;
       
   371   if ($user->uid) {
       
   372     menu_set_active_item('user/'. $user->uid);
       
   373     return menu_execute_active_handler();
       
   374   }
       
   375   else {
       
   376     return drupal_get_form('user_login');
       
   377   }
       
   378 }