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