user.pages.inc

  1. 7.x drupal-7.x/modules/user/user.pages.inc
  2. 6.x drupal-6.x/modules/user/user.pages.inc

User page callback file for the user module.

File

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