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