|
1 <?php |
|
2 |
|
3 /** |
|
4 * @file |
|
5 * Hooks provided by the User module. |
|
6 */ |
|
7 |
|
8 /** |
|
9 * @addtogroup hooks |
|
10 * @{ |
|
11 */ |
|
12 |
|
13 /** |
|
14 * Act on user objects when loaded from the database. |
|
15 * |
|
16 * Due to the static cache in user_load_multiple() you should not use this |
|
17 * hook to modify the user properties returned by the {users} table itself |
|
18 * since this may result in unreliable results when loading from cache. |
|
19 * |
|
20 * @param $users |
|
21 * An array of user objects, indexed by uid. |
|
22 * |
|
23 * @see user_load_multiple() |
|
24 * @see profile_user_load() |
|
25 */ |
|
26 function hook_user_load($users) { |
|
27 $result = db_query('SELECT uid, foo FROM {my_table} WHERE uid IN (:uids)', array(':uids' => array_keys($users))); |
|
28 foreach ($result as $record) { |
|
29 $users[$record->uid]->foo = $record->foo; |
|
30 } |
|
31 } |
|
32 |
|
33 /** |
|
34 * Respond to user deletion. |
|
35 * |
|
36 * This hook is invoked from user_delete_multiple() before field_attach_delete() |
|
37 * is called and before users are actually removed from the database. |
|
38 * |
|
39 * Modules should additionally implement hook_user_cancel() to process stored |
|
40 * user data for other account cancellation methods. |
|
41 * |
|
42 * @param $account |
|
43 * The account that is being deleted. |
|
44 * |
|
45 * @see user_delete_multiple() |
|
46 */ |
|
47 function hook_user_delete($account) { |
|
48 db_delete('mytable') |
|
49 ->condition('uid', $account->uid) |
|
50 ->execute(); |
|
51 } |
|
52 |
|
53 /** |
|
54 * Act on user account cancellations. |
|
55 * |
|
56 * This hook is invoked from user_cancel() before a user account is canceled. |
|
57 * Depending on the account cancellation method, the module should either do |
|
58 * nothing, unpublish content, or anonymize content. See user_cancel_methods() |
|
59 * for the list of default account cancellation methods provided by User module. |
|
60 * Modules may add further methods via hook_user_cancel_methods_alter(). |
|
61 * |
|
62 * This hook is NOT invoked for the 'user_cancel_delete' account cancellation |
|
63 * method. To react on this method, implement hook_user_delete() instead. |
|
64 * |
|
65 * Expensive operations should be added to the global account cancellation batch |
|
66 * by using batch_set(). |
|
67 * |
|
68 * @param $edit |
|
69 * The array of form values submitted by the user. |
|
70 * @param $account |
|
71 * The user object on which the operation is being performed. |
|
72 * @param $method |
|
73 * The account cancellation method. |
|
74 * |
|
75 * @see user_cancel_methods() |
|
76 * @see hook_user_cancel_methods_alter() |
|
77 */ |
|
78 function hook_user_cancel($edit, $account, $method) { |
|
79 switch ($method) { |
|
80 case 'user_cancel_block_unpublish': |
|
81 // Unpublish nodes (current revisions). |
|
82 module_load_include('inc', 'node', 'node.admin'); |
|
83 $nodes = db_select('node', 'n') |
|
84 ->fields('n', array('nid')) |
|
85 ->condition('uid', $account->uid) |
|
86 ->execute() |
|
87 ->fetchCol(); |
|
88 node_mass_update($nodes, array('status' => 0)); |
|
89 break; |
|
90 |
|
91 case 'user_cancel_reassign': |
|
92 // Anonymize nodes (current revisions). |
|
93 module_load_include('inc', 'node', 'node.admin'); |
|
94 $nodes = db_select('node', 'n') |
|
95 ->fields('n', array('nid')) |
|
96 ->condition('uid', $account->uid) |
|
97 ->execute() |
|
98 ->fetchCol(); |
|
99 node_mass_update($nodes, array('uid' => 0)); |
|
100 // Anonymize old revisions. |
|
101 db_update('node_revision') |
|
102 ->fields(array('uid' => 0)) |
|
103 ->condition('uid', $account->uid) |
|
104 ->execute(); |
|
105 // Clean history. |
|
106 db_delete('history') |
|
107 ->condition('uid', $account->uid) |
|
108 ->execute(); |
|
109 break; |
|
110 } |
|
111 } |
|
112 |
|
113 /** |
|
114 * Modify account cancellation methods. |
|
115 * |
|
116 * By implementing this hook, modules are able to add, customize, or remove |
|
117 * account cancellation methods. All defined methods are turned into radio |
|
118 * button form elements by user_cancel_methods() after this hook is invoked. |
|
119 * The following properties can be defined for each method: |
|
120 * - title: The radio button's title. |
|
121 * - description: (optional) A description to display on the confirmation form |
|
122 * if the user is not allowed to select the account cancellation method. The |
|
123 * description is NOT used for the radio button, but instead should provide |
|
124 * additional explanation to the user seeking to cancel their account. |
|
125 * - access: (optional) A boolean value indicating whether the user can access |
|
126 * a method. If access is defined, the method cannot be configured as the |
|
127 * default method. |
|
128 * |
|
129 * @param $methods |
|
130 * An array containing user account cancellation methods, keyed by method id. |
|
131 * |
|
132 * @see user_cancel_methods() |
|
133 * @see user_cancel_confirm_form() |
|
134 */ |
|
135 function hook_user_cancel_methods_alter(&$methods) { |
|
136 // Limit access to disable account and unpublish content method. |
|
137 $methods['user_cancel_block_unpublish']['access'] = user_access('administer site configuration'); |
|
138 |
|
139 // Remove the content re-assigning method. |
|
140 unset($methods['user_cancel_reassign']); |
|
141 |
|
142 // Add a custom zero-out method. |
|
143 $methods['mymodule_zero_out'] = array( |
|
144 'title' => t('Delete the account and remove all content.'), |
|
145 'description' => t('All your content will be replaced by empty strings.'), |
|
146 // access should be used for administrative methods only. |
|
147 'access' => user_access('access zero-out account cancellation method'), |
|
148 ); |
|
149 } |
|
150 |
|
151 /** |
|
152 * Add mass user operations. |
|
153 * |
|
154 * This hook enables modules to inject custom operations into the mass operations |
|
155 * dropdown found at admin/people, by associating a callback function with |
|
156 * the operation, which is called when the form is submitted. The callback function |
|
157 * receives one initial argument, which is an array of the checked users. |
|
158 * |
|
159 * @return |
|
160 * An array of operations. Each operation is an associative array that may |
|
161 * contain the following key-value pairs: |
|
162 * - "label": Required. The label for the operation, displayed in the dropdown menu. |
|
163 * - "callback": Required. The function to call for the operation. |
|
164 * - "callback arguments": Optional. An array of additional arguments to pass to |
|
165 * the callback function. |
|
166 * |
|
167 */ |
|
168 function hook_user_operations() { |
|
169 $operations = array( |
|
170 'unblock' => array( |
|
171 'label' => t('Unblock the selected users'), |
|
172 'callback' => 'user_user_operations_unblock', |
|
173 ), |
|
174 'block' => array( |
|
175 'label' => t('Block the selected users'), |
|
176 'callback' => 'user_user_operations_block', |
|
177 ), |
|
178 'cancel' => array( |
|
179 'label' => t('Cancel the selected user accounts'), |
|
180 ), |
|
181 ); |
|
182 return $operations; |
|
183 } |
|
184 |
|
185 /** |
|
186 * Define a list of user settings or profile information categories. |
|
187 * |
|
188 * There are two steps to using hook_user_categories(): |
|
189 * - Create the category with hook_user_categories(). |
|
190 * - Display that category on the form ID of "user_profile_form" with |
|
191 * hook_form_FORM_ID_alter(). |
|
192 * |
|
193 * Step one builds out the category but it won't be visible on your form until |
|
194 * you explicitly tell it to do so. |
|
195 * |
|
196 * The function in step two should contain the following code in order to |
|
197 * display your new category: |
|
198 * @code |
|
199 * if ($form['#user_category'] == 'mycategory') { |
|
200 * // Return your form here. |
|
201 * } |
|
202 * @endcode |
|
203 * |
|
204 * @return |
|
205 * An array of associative arrays. Each inner array has elements: |
|
206 * - "name": The internal name of the category. |
|
207 * - "title": The human-readable, localized name of the category. |
|
208 * - "weight": An integer specifying the category's sort ordering. |
|
209 * - "access callback": Name of the access callback function to use to |
|
210 * determine whether the user can edit the category. Defaults to using |
|
211 * user_edit_access(). See hook_menu() for more information on access |
|
212 * callbacks. |
|
213 * - "access arguments": Arguments for the access callback function. Defaults |
|
214 * to array(1). |
|
215 */ |
|
216 function hook_user_categories() { |
|
217 return array(array( |
|
218 'name' => 'account', |
|
219 'title' => t('Account settings'), |
|
220 'weight' => 1, |
|
221 )); |
|
222 } |
|
223 |
|
224 /** |
|
225 * A user account is about to be created or updated. |
|
226 * |
|
227 * This hook is primarily intended for modules that want to store properties in |
|
228 * the serialized {users}.data column, which is automatically loaded whenever a |
|
229 * user account object is loaded, modules may add to $edit['data'] in order |
|
230 * to have their data serialized on save. |
|
231 * |
|
232 * @param $edit |
|
233 * The array of form values submitted by the user. Assign values to this |
|
234 * array to save changes in the database. |
|
235 * @param $account |
|
236 * The user object on which the operation is performed. Values assigned in |
|
237 * this object will not be saved in the database. |
|
238 * @param $category |
|
239 * The active category of user information being edited. |
|
240 * |
|
241 * @see hook_user_insert() |
|
242 * @see hook_user_update() |
|
243 */ |
|
244 function hook_user_presave(&$edit, $account, $category) { |
|
245 // Make sure that our form value 'mymodule_foo' is stored as |
|
246 // 'mymodule_bar' in the 'data' (serialized) column. |
|
247 if (isset($edit['mymodule_foo'])) { |
|
248 $edit['data']['mymodule_bar'] = $edit['mymodule_foo']; |
|
249 } |
|
250 } |
|
251 |
|
252 /** |
|
253 * A user account was created. |
|
254 * |
|
255 * The module should save its custom additions to the user object into the |
|
256 * database. |
|
257 * |
|
258 * @param $edit |
|
259 * The array of form values submitted by the user. |
|
260 * @param $account |
|
261 * The user object on which the operation is being performed. |
|
262 * @param $category |
|
263 * The active category of user information being edited. |
|
264 * |
|
265 * @see hook_user_presave() |
|
266 * @see hook_user_update() |
|
267 */ |
|
268 function hook_user_insert(&$edit, $account, $category) { |
|
269 db_insert('mytable') |
|
270 ->fields(array( |
|
271 'myfield' => $edit['myfield'], |
|
272 'uid' => $account->uid, |
|
273 )) |
|
274 ->execute(); |
|
275 } |
|
276 |
|
277 /** |
|
278 * A user account was updated. |
|
279 * |
|
280 * Modules may use this hook to update their user data in a custom storage |
|
281 * after a user account has been updated. |
|
282 * |
|
283 * @param $edit |
|
284 * The array of form values submitted by the user. |
|
285 * @param $account |
|
286 * The user object on which the operation is performed. |
|
287 * @param $category |
|
288 * The active category of user information being edited. |
|
289 * |
|
290 * @see hook_user_presave() |
|
291 * @see hook_user_insert() |
|
292 */ |
|
293 function hook_user_update(&$edit, $account, $category) { |
|
294 db_insert('user_changes') |
|
295 ->fields(array( |
|
296 'uid' => $account->uid, |
|
297 'changed' => time(), |
|
298 )) |
|
299 ->execute(); |
|
300 } |
|
301 |
|
302 /** |
|
303 * The user just logged in. |
|
304 * |
|
305 * @param $edit |
|
306 * The array of form values submitted by the user. |
|
307 * @param $account |
|
308 * The user object on which the operation was just performed. |
|
309 */ |
|
310 function hook_user_login(&$edit, $account) { |
|
311 // If the user has a NULL time zone, notify them to set a time zone. |
|
312 if (!$account->timezone && variable_get('configurable_timezones', 1) && variable_get('empty_timezone_message', 0)) { |
|
313 drupal_set_message(t('Configure your <a href="@user-edit">account time zone setting</a>.', array('@user-edit' => url("user/$account->uid/edit", array('query' => drupal_get_destination(), 'fragment' => 'edit-timezone'))))); |
|
314 } |
|
315 } |
|
316 |
|
317 /** |
|
318 * The user just logged out. |
|
319 * |
|
320 * Note that when this hook is invoked, the changes have not yet been written to |
|
321 * the database, because a database transaction is still in progress. The |
|
322 * transaction is not finalized until the save operation is entirely completed |
|
323 * and user_save() goes out of scope. You should not rely on data in the |
|
324 * database at this time as it is not updated yet. You should also note that any |
|
325 * write/update database queries executed from this hook are also not committed |
|
326 * immediately. Check user_save() and db_transaction() for more info. |
|
327 * |
|
328 * @param $account |
|
329 * The user object on which the operation was just performed. |
|
330 */ |
|
331 function hook_user_logout($account) { |
|
332 db_insert('logouts') |
|
333 ->fields(array( |
|
334 'uid' => $account->uid, |
|
335 'time' => time(), |
|
336 )) |
|
337 ->execute(); |
|
338 } |
|
339 |
|
340 /** |
|
341 * The user's account information is being displayed. |
|
342 * |
|
343 * The module should format its custom additions for display and add them to the |
|
344 * $account->content array. |
|
345 * |
|
346 * @param $account |
|
347 * The user object on which the operation is being performed. |
|
348 * @param $view_mode |
|
349 * View mode, e.g. 'full'. |
|
350 * @param $langcode |
|
351 * The language code used for rendering. |
|
352 * |
|
353 * @see hook_user_view_alter() |
|
354 * @see hook_entity_view() |
|
355 */ |
|
356 function hook_user_view($account, $view_mode, $langcode) { |
|
357 if (user_access('create blog content', $account)) { |
|
358 $account->content['summary']['blog'] = array( |
|
359 '#type' => 'user_profile_item', |
|
360 '#title' => t('Blog'), |
|
361 '#markup' => l(t('View recent blog entries'), "blog/$account->uid", array('attributes' => array('title' => t("Read !username's latest blog entries.", array('!username' => format_username($account)))))), |
|
362 '#attributes' => array('class' => array('blog')), |
|
363 ); |
|
364 } |
|
365 } |
|
366 |
|
367 /** |
|
368 * The user was built; the module may modify the structured content. |
|
369 * |
|
370 * This hook is called after the content has been assembled in a structured array |
|
371 * and may be used for doing processing which requires that the complete user |
|
372 * content structure has been built. |
|
373 * |
|
374 * If the module wishes to act on the rendered HTML of the user rather than the |
|
375 * structured content array, it may use this hook to add a #post_render callback. |
|
376 * Alternatively, it could also implement hook_preprocess_user_profile(). See |
|
377 * drupal_render() and theme() documentation respectively for details. |
|
378 * |
|
379 * @param $build |
|
380 * A renderable array representing the user. |
|
381 * |
|
382 * @see user_view() |
|
383 * @see hook_entity_view_alter() |
|
384 */ |
|
385 function hook_user_view_alter(&$build) { |
|
386 // Check for the existence of a field added by another module. |
|
387 if (isset($build['an_additional_field'])) { |
|
388 // Change its weight. |
|
389 $build['an_additional_field']['#weight'] = -10; |
|
390 } |
|
391 |
|
392 // Add a #post_render callback to act on the rendered HTML of the user. |
|
393 $build['#post_render'][] = 'my_module_user_post_render'; |
|
394 } |
|
395 |
|
396 /** |
|
397 * Act on a user role being inserted or updated. |
|
398 * |
|
399 * Modules implementing this hook can act on the user role object before |
|
400 * it has been saved to the database. |
|
401 * |
|
402 * @param $role |
|
403 * A user role object. |
|
404 * |
|
405 * @see hook_user_role_insert() |
|
406 * @see hook_user_role_update() |
|
407 */ |
|
408 function hook_user_role_presave($role) { |
|
409 // Set a UUID for the user role if it doesn't already exist |
|
410 if (empty($role->uuid)) { |
|
411 $role->uuid = uuid_uuid(); |
|
412 } |
|
413 } |
|
414 |
|
415 /** |
|
416 * Respond to creation of a new user role. |
|
417 * |
|
418 * Modules implementing this hook can act on the user role object when saved to |
|
419 * the database. It's recommended that you implement this hook if your module |
|
420 * adds additional data to user roles object. The module should save its custom |
|
421 * additions to the database. |
|
422 * |
|
423 * @param $role |
|
424 * A user role object. |
|
425 */ |
|
426 function hook_user_role_insert($role) { |
|
427 // Save extra fields provided by the module to user roles. |
|
428 db_insert('my_module_table') |
|
429 ->fields(array( |
|
430 'rid' => $role->rid, |
|
431 'role_description' => $role->description, |
|
432 )) |
|
433 ->execute(); |
|
434 } |
|
435 |
|
436 /** |
|
437 * Respond to updates to a user role. |
|
438 * |
|
439 * Modules implementing this hook can act on the user role object when updated. |
|
440 * It's recommended that you implement this hook if your module adds additional |
|
441 * data to user roles object. The module should save its custom additions to |
|
442 * the database. |
|
443 * |
|
444 * @param $role |
|
445 * A user role object. |
|
446 */ |
|
447 function hook_user_role_update($role) { |
|
448 // Save extra fields provided by the module to user roles. |
|
449 db_merge('my_module_table') |
|
450 ->key(array('rid' => $role->rid)) |
|
451 ->fields(array( |
|
452 'role_description' => $role->description |
|
453 )) |
|
454 ->execute(); |
|
455 } |
|
456 |
|
457 /** |
|
458 * Respond to user role deletion. |
|
459 * |
|
460 * This hook allows you act when a user role has been deleted. |
|
461 * If your module stores references to roles, it's recommended that you |
|
462 * implement this hook and delete existing instances of the deleted role |
|
463 * in your module database tables. |
|
464 * |
|
465 * @param $role |
|
466 * The $role object being deleted. |
|
467 */ |
|
468 function hook_user_role_delete($role) { |
|
469 // Delete existing instances of the deleted role. |
|
470 db_delete('my_module_table') |
|
471 ->condition('rid', $role->rid) |
|
472 ->execute(); |
|
473 } |
|
474 |
|
475 /** |
|
476 * @} End of "addtogroup hooks". |
|
477 */ |