Code coverage for /20080809/modules/user/user.pages.inc

Line #Times calledCode
1
<?php
2
// $Id: user.pages.inc,v 1.14 2008/07/16 21:59:29 dries 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
 */
12779
function user_autocomplete($string = '') {
130
  $matches = array();
140
  if ($string) {
150
    $result = db_query_range("SELECT name FROM {users} WHERE LOWER(name)
LIKE LOWER('%s%%')", $string, 0, 10);
160
    while ($user = db_fetch_object($result)) {
170
      $matches[$user->name] = check_plain($user->name);
180
    }
190
  }
20
210
  drupal_json($matches);
220
}
23
24
/**
25
 * Form builder; Request a password reset.
26
 *
27
 * @ingroup forms
28
 * @see user_pass_validate()
29
 * @see user_pass_submit()
30
 */
31779
function user_pass() {
320
  $form['name'] = array(
330
    '#type' => 'textfield',
340
    '#title' => t('Username or e-mail address'),
350
    '#size' => 60,
360
    '#maxlength' => max(USERNAME_MAX_LENGTH, EMAIL_MAX_LENGTH),
370
    '#required' => TRUE,
38
  );
390
  $form['submit'] = array('#type' => 'submit', '#value' => t('E-mail new
password'));
40
410
  return $form;
420
}
43
44779
function user_pass_validate($form, &$form_state) {
450
  $name = trim($form_state['values']['name']);
46
  // Try to load by email.
470
  $account = user_load(array('mail' => $name, 'status' => 1));
480
  if (!$account) {
49
    // No success, try to load by name.
500
    $account = user_load(array('name' => $name, 'status' => 1));
510
  }
520
  if (isset($account->uid)) {
530
    form_set_value(array('#parents' => array('account')), $account,
$form_state);
540
  }
55
  else {
560
    form_set_error('name', t('Sorry, %name is not recognized as a user name
or an e-mail address.', array('%name' => $name)));
57
  }
580
}
59
60779
function user_pass_submit($form, &$form_state) {
610
  global $language;
62
630
  $account = $form_state['values']['account'];
64
  // Mail one time login URL and instructions using current language.
650
  _user_mail_notify('password_reset', $account, $language);
660
  watchdog('user', 'Password reset instructions mailed to %name at
%email.', array('%name' => $account->name, '%email' => $account->mail));
670
  drupal_set_message(t('Further instructions have been sent to your e-mail
address.'));
68
690
  $form_state['redirect'] = 'user';
700
  return;
710
}
72
73
/**
74
 * Menu callback; process one time login link and redirects to the user
page on success.
75
 */
76779
function user_pass_reset(&$form_state, $uid, $timestamp, $hashed_pass,
$action = NULL) {
772
  global $user;
78
79
  // Check if the user is already logged in. The back button is often the
culprit here.
802
  if ($user->uid) {
810
    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.'));
820
    drupal_goto();
830
  }
84
  else {
85
    // Time out, in seconds, until login URL expires. 24 hours = 86400
seconds.
862
    $timeout = 86400;
872
    $current = time();
88
    // Some redundant checks for extra security ?
892
    if ($timestamp < $current && $account = user_load(array('uid' => $uid,
'status' => 1)) ) {
90
      // No time out for first time login.
912
      if ($account->login && $current - $timestamp > $timeout) {
920
        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.'));
930
        drupal_goto('user/password');
940
      }
952
      else if ($account->uid && $timestamp > $account->login && $timestamp
< $current && $hashed_pass == user_pass_rehash($account->pass, $timestamp,
$account->login)) {
96
        // First stage is a confirmation form, then login
972
        if ($action == 'login') {
981
          watchdog('user', 'User %name used one-time login link at time
%timestamp.', array('%name' => $account->name, '%timestamp' =>
$timestamp));
99
          // Set the new user.
1001
          $user = $account;
101
          // user_authenticate_finalize() also updates the login timestamp
of the
102
          // user, which invalidates further use of the one-time login
link.
1031
          user_authenticate_finalize($form_state['values']);
1041
          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.'));
1051
          drupal_goto('user/' . $user->uid . '/edit');
1060
        }
107
        else {
1081
          $form['message'] = array('#markup' => 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))));
1091
          $form['help'] = array('#markup' => '<p>' . t('This login can be
used only once.') . '</p>');
1101
          $form['submit'] = array('#type' => 'submit', '#value' => t('Log
in'));
1111
          $form['#action'] =
url("user/reset/$uid/$timestamp/$hashed_pass/login");
1121
          return $form;
113
        }
1140
      }
115
      else {
1160
        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.'));
1170
        drupal_goto('user/password');
118
      }
1190
    }
120
    else {
121
      // Deny access, no more clues.
122
      // Everything will be in the watchdog's URL for the administrator to
check.
1230
      drupal_access_denied();
124
    }
125
  }
1260
}
127
128
/**
129
 * Menu callback; logs the current user out, and redirects to the home
page.
130
 */
131779
function user_logout() {
13283
  global $user;
133
13483
  watchdog('user', 'Session closed for %name.', array('%name' =>
$user->name));
135
136
  // Destroy the current session:
13783
  session_destroy();
13883
  module_invoke_all('user', 'logout', NULL, $user);
139
140
  // Load the anonymous user
14183
  $user = drupal_anonymous_user();
142
14383
  drupal_goto();
1440
}
145
146
/**
147
 * Menu callback; Displays a user or user profile page.
148
 */
149779
function user_view($account) {
150163
  drupal_set_title(check_plain($account->name));
151
  // Retrieve all profile fields and attach to $account->content.
152163
  user_build_content($account);
153
154
  // To theme user profiles, copy modules/user/user_profile.tpl.php
155
  // to your theme directory, and edit it as instructed in that file's
comments.
156163
  return theme('user_profile', $account);
1570
}
158
159
/**
160
 * Process variables for user-profile.tpl.php.
161
 *
162
 * The $variables array contains the following arguments:
163
 * - $account
164
 *
165
 * @see user-picture.tpl.php
166
 */
167779
function template_preprocess_user_profile(&$variables) {
168163
  $variables['profile'] = array();
169
  // Sort sections by weight
170163
  uasort($variables['account']->content, 'element_sort');
171
  // Provide keyed variables so themers can print each section
independantly.
172163
  foreach (element_children($variables['account']->content) as $key) {
173163
    $variables['profile'][$key] =
drupal_render($variables['account']->content[$key]);
174163
  }
175
  // Collect all profiles to make it easier to print all items at once.
176163
  $variables['user_profile'] = implode($variables['profile']);
177163
}
178
179
/**
180
 * Process variables for user-profile-item.tpl.php.
181
 *
182
 * The $variables array contains the following arguments:
183
 * - $element
184
 *
185
 * @see user-profile-item.tpl.php
186
 */
187779
function template_preprocess_user_profile_item(&$variables) {
188163
  $variables['title'] = $variables['element']['#title'];
189163
  $variables['value'] = $variables['element']['#markup'];
190163
  $variables['attributes'] = '';
191163
  if (isset($variables['element']['#attributes'])) {
192163
    $variables['attributes'] =
drupal_attributes($variables['element']['#attributes']);
193163
  }
194163
}
195
196
/**
197
 * Process variables for user-profile-category.tpl.php.
198
 *
199
 * The $variables array contains the following arguments:
200
 * - $element
201
 *
202
 * @see user-profile-category.tpl.php
203
 */
204779
function template_preprocess_user_profile_category(&$variables) {
205163
  $variables['title'] = check_plain($variables['element']['#title']);
206163
  $variables['profile_items'] = $variables['element']['#children'];
207163
  $variables['attributes'] = '';
208163
  if (isset($variables['element']['#attributes'])) {
209163
    $variables['attributes'] =
drupal_attributes($variables['element']['#attributes']);
210163
  }
211163
}
212
213
/**
214
 * Form builder; Present the form to edit a given user or profile
category.
215
 *
216
 * @ingroup forms
217
 * @see user_edit_validate()
218
 * @see user_edit_submit()
219
 */
220779
function user_edit($account, $category = 'account') {
22153
  drupal_set_title(check_plain($account->name));
22253
  return drupal_get_form('user_profile_form', $account, $category);
2230
}
224
225
/**
226
 * Form builder; edit a user account or one of their profile categories.
227
 *
228
 * @ingroup forms
229
 * @see user_profile_form_validate()
230
 * @see user_profile_form_submit()
231
 * @see user_edit_delete_submit()
232
 */
233779
function user_profile_form($form_state, $account, $category = 'account') {
234
23553
  $edit = (empty($form_state['values'])) ? (array)$account :
$form_state['values'];
236
23753
  $form = _user_forms($edit, $account, $category);
23853
  $form['_category'] = array('#type' => 'value', '#value' => $category);
23953
  $form['_account'] = array('#type' => 'value', '#value' => $account);
24053
  $form['submit'] = array('#type' => 'submit', '#value' => t('Save'),
'#weight' => 30);
24153
  if (user_access('administer users')) {
24239
    $form['delete'] = array(
24339
      '#type' => 'submit',
24439
      '#value' => t('Delete'),
24539
      '#weight' => 31,
24639
      '#submit' => array('user_edit_delete_submit'),
247
    );
24839
  }
24953
  $form['#attributes']['enctype'] = 'multipart/form-data';
250
25153
  return $form;
2520
}
253
254
/**
255
 * Validation function for the user account and profile editing form.
256
 */
257779
function user_profile_form_validate($form, &$form_state) {
25811
  user_module_invoke('validate', $form_state['values'],
$form_state['values']['_account'], $form_state['values']['_category']);
259
  // Validate input to ensure that non-privileged users can't alter
protected data.
26011
  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']))) {
2610
    watchdog('security', 'Detected malicious attempt to alter protected
user fields.', array(), WATCHDOG_WARNING);
262
    // set this to a value type field
2630
    form_set_error('category', t('Detected malicious attempt to alter
protected user fields.'));
2640
  }
26511
}
266
267
/**
268
 * Submit function for the user account and profile editing form.
269
 */
270779
function user_profile_form_submit($form, &$form_state) {
27113
  $account = $form_state['values']['_account'];
27213
  $category = $form_state['values']['_category'];
27313
  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'],
$form_state['values']['form_build_id']);
27413
  user_module_invoke('submit', $form_state['values'], $account,
$category);
27513
  user_save($account, $form_state['values'], $category);
276
277
  // Clear the page cache because pages can contain usernames and/or
profile information:
27813
  cache_clear_all();
279
28013
  drupal_set_message(t('The changes have been saved.'));
28113
  return;
2820
}
283
284
/**
285
 * Submit function for the 'Delete' button on the user edit form.
286
 */
287779
function user_edit_delete_submit($form, &$form_state) {
2881
  $destination = '';
2891
  if (isset($_REQUEST['destination'])) {
2900
    $destination = drupal_get_destination();
2910
    unset($_REQUEST['destination']);
2920
  }
293
  // Note: We redirect from user/uid/edit to user/uid/delete to make the
tabs disappear.
2941
  $form_state['redirect'] = array("user/" .
$form_state['values']['_account']->uid . "/delete", $destination);
2951
}
296
297
/**
298
 * Form builder; confirm form for user deletion.
299
 *
300
 * @ingroup forms
301
 * @see user_confirm_delete_submit()
302
 */
303779
function user_confirm_delete(&$form_state, $account) {
304
3052
  $form['_account'] = array('#type' => 'value', '#value' => $account);
306
3072
  return confirm_form($form,
3082
    t('Are you sure you want to delete the account %name?', array('%name'
=> $account->name)),
3092
    'user/' . $account->uid,
3102
    t('All submissions made by this user will be attributed to the
anonymous account. This action cannot be undone.'),
3112
    t('Delete'), t('Cancel'));
3120
}
313
314
/**
315
 * Submit function for the confirm form for user deletion.
316
 */
317779
function user_confirm_delete_submit($form, &$form_state) {
3181
  user_delete($form_state['values'],
$form_state['values']['_account']->uid);
3191
  drupal_set_message(t('%name has been deleted.', array('%name' =>
$form_state['values']['_account']->name)));
320
3211
  if (!isset($_REQUEST['destination'])) {
3221
    $form_state['redirect'] = 'admin/user/user';
3231
  }
3241
}
325
326779
function user_edit_validate($form, &$form_state) {
3270
  user_module_invoke('validate', $form_state['values'],
$form_state['values']['_account'], $form_state['values']['_category']);
328
  // Validate input to ensure that non-privileged users can't alter
protected data.
3290
  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']))) {
3300
    watchdog('security', 'Detected malicious attempt to alter protected
user fields.', array(), WATCHDOG_WARNING);
331
    // set this to a value type field
3320
    form_set_error('category', t('Detected malicious attempt to alter
protected user fields.'));
3330
  }
3340
}
335
336779
function user_edit_submit($form, &$form_state) {
3370
  $account = $form_state['values']['_account'];
3380
  $category = $form_state['values']['_category'];
3390
  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'],
$form_state['values']['form_build_id']);
3400
  user_module_invoke('submit', $form_state['values'], $account,
$category);
3410
  user_save($account, $form_state['values'], $category);
342
343
  // Clear the page cache because pages can contain usernames and/or
profile information:
3440
  cache_clear_all();
345
3460
  drupal_set_message(t('The changes have been saved.'));
3470
  return;
3480
}
349
350
/**
351
 * Access callback for path /user.
352
 *
353
 * Displays user profile if user is logged in, or login form for anonymous
354
 * users.
355
 */
356779
function user_page() {
357385
  global $user;
358385
  if ($user->uid) {
3591
    menu_set_active_item('user/' . $user->uid);
3601
    return menu_execute_active_handler();
3610
  }
362
  else {
363384
    return drupal_get_form('user_login');
364
  }
3650
}
366779