~ubuntu-branches/ubuntu/jaunty/drupal6/jaunty-updates

« back to all changes in this revision

Viewing changes to modules/user/user.pages.inc

  • Committer: Bazaar Package Importer
  • Author(s): Luigi Gangitano
  • Date: 2008-10-24 23:06:15 UTC
  • Revision ID: james.westby@ubuntu.com-20081024230615-a33t46nwna16bynv
Tags: upstream-6.6
ImportĀ upstreamĀ versionĀ 6.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}