-
Notifications
You must be signed in to change notification settings - Fork 1
/
lookup.module
374 lines (325 loc) · 10.4 KB
/
lookup.module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
<?php
const LOOKUP_HELP_PATH = 'admin/help#lookup';
const LOOKUP_HOSTNAME = 'ldap.lookup.cam.ac.uk';
const LOOKUP_BASE_DN = 'ou=people,o=University of Cambridge,dc=cam,dc=ac,dc=uk';
/**
* Implements hook_help().
*/
function lookup_help($path, $arg) {
global $base_url;
$output = '';
switch ($path) {
case LOOKUP_HELP_PATH:
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The Lookup details modules updates the details of users who have logged in using the <a href="@raven_help_path">Raven authentication module</a>.', array(
'@lookup_url' => 'http://www.lookup.cam.ac.uk/',
'@raven_help_path' => url(RAVEN_HELP_PATH),
)) . '</p>';
$output .= '<h3>' . t('Fields') . '</h3>';
$output .= '<p>' . t('All Lookup-maintained fields are shown on the user edit form, but are disabled as any changes would be overwritten.') . '</p>';
$output .= '<dl>';
$output .= '<dt>' . t('Name') . '</dt>';
$output .= '<dd>' . t('The user\'s display name in Lookup is added to the username and password section on the profile page. If the display name itself is suppressed in Lookup, the registered name is used. If that\'s suppressed, Lookup simply reverts to the CRSid.') . '</dd>';
$output .= '<dd>' . t('It is available is a token (<code>[user:lookup-name]</code>) for use in modules such as <a href="@realname_url">RealName</a>, and is also a filter in views.', array('@realname_url' => 'http://drupal.org/project/realname')) . '</dd>';
$output .= '<dt>' . t('E-mail address') . '</dt>';
$output .= '<dd>' . t('If the user\'s primary e-mail address in Lookup is available, the e-mail address in Drupal is replaced. If it is suppressed, the existing value is left unchanged.') . '</dd>';
$output .= '</dl>';
break;
}
return $output;
}
/**
* Implements hook_views_api().
*/
function lookup_views_api() {
return array('api' => 3);
}
/**
* Implements hook_form_FORM_ID_alter() for user_profile_form().
*/
function lookup_form_user_profile_form_alter(&$form, &$form_state, $form_id) {
if (is_raven_user($form['#user'])) {
// Add in extra Lookup fields
$form['account']['lookup_name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
'#maxlength' => USERNAME_MAX_LENGTH,
'#description' => t('Display name as set in Lookup.'),
'#required' => TRUE,
'#attributes' => array('class' => array('lookup_name')),
'#default_value' => $form['#user']->lookup['name'],
'#weight' => -9, // after CRSid
'#disabled' => TRUE,
);
$affiliation_defaults = array();
if ($form['#user']->lookup['staff']) {
$affiliation_defaults[] = 'staff';
}
if ($form['#user']->lookup['student']) {
$affiliation_defaults[] = 'student';
}
$form['account']['lookup_affiliation'] = array(
'#type' => 'checkboxes',
'#title' => t('Affiliations'),
'#options' => array('staff' => t('Staff'), 'student' => t('Student')),
'#default_value' => $affiliation_defaults,
'#disabled' => TRUE,
);
// Prevent editing of other Lookup-maintained fields
$form['account']['mail']['#disabled'] = TRUE;
// Tweak descriptions
$form['account']['mail']['#description'] = t('The primary e-mail address as set in Lookup.');
}
}
/**
* Implements hook_raven_register_alter().
*/
function lookup_raven_register_alter(&$edit, $account) {
// Get e-mail address from Lookup in case an e-mail's going to be sent
$details = user_lookup_details($edit['name'], array('mail'));
if (isset($details['mail'])) {
$edit['init'] = $details['mail'];
}
}
/**
* Get Lookup details for a CRSid.
*
* @param string $name
* User CRSid.
* @param array $terms
* Terms to query. Possible keys are:
* - displayName: Display name (potentially registered name or even CRSid if unavailable).
* - mail: Primary e-mail address.
* - misAffiliation: Staff and/or student.
*
* @return array
* Lookup details. Data types for possible keys are:
* - displayName: string.
* - mail: string.
* - staff: bool.
* - student: bool.
*/
function user_lookup_details($name, $terms = array('displayName', 'mail', 'misAffiliation')) {
$details = array();
$ds = ldap_connect(LOOKUP_HOSTNAME);
if ($ds) {
$r = ldap_bind($ds);
$sr = ldap_search($ds, LOOKUP_BASE_DN, 'uid=' . $name, $terms);
$info = ldap_get_entries($ds, $sr);
if ($info['count'] == 1) {
if (isset($info[0]['displayname'][0])) {
$details['displayName'] = $info[0]['displayname'][0];
}
if (isset($info[0]['mail'][0])) {
$details['mail'] = $info[0]['mail'][0];
}
if (isset($info[0]['misaffiliation'])) {
$details['staff'] = in_array('staff', $info[0]['misaffiliation']) ? 1 : 0;
$details['student'] = in_array('student', $info[0]['misaffiliation']) ? 1 : 0;
}
}
ldap_close($ds);
}
return $details;
}
function get_user_lookup_details(&$edit, $account) {
$details = user_lookup_details(isset($edit['name']) ? $edit['name'] : $account->name, array(
'displayName',
'mail',
'misAffiliation',
));
if (isset($details['mail'])) {
$edit['mail'] = $details['mail'];
}
$edit['lookup'] = array();
if (isset($details['displayName'])) {
$edit['lookup']['name'] = $details['displayName'];
$edit['lookup']['staff'] = $details['staff'];
$edit['lookup']['student'] = $details['student'];
}
}
/**
* Implements hook_user_load().
*/
function lookup_user_load(array $accounts) {
$raven_accounts = array();
foreach ($accounts as $uid => $account) {
if (is_raven_user($account)) {
$raven_accounts[$uid] = $account;
}
}
// Add in Lookup details for each user
$raven_details = lookup_load_multiple($raven_accounts);
foreach ($raven_details as $uid => $detail) {
$accounts[$uid]->lookup = $detail;
}
}
function lookup_user_presave(array &$edit, stdClass $account, $category) {
if (is_raven_user($account)) {
get_user_lookup_details($edit, $account);
}
}
/**
* Implements hook_user_insert().
*/
function lookup_user_insert(array &$edit, stdClass $account, $category) {
lookup_update($account);
}
/**
* Implements hook_user_update().
*/
function lookup_user_update(array &$edit, stdClass $account, $category) {
lookup_update($account);
}
/**
* Implements hook_user_delete().
*/
function lookup_user_delete(stdClass $account) {
if (is_raven_user($account)) {
lookup_delete($account->uid);
}
}
/**
* Implements hook_user_operations().
*/
function lookup_user_operations() {
$operations['lookup_update'] = array(
'label' => t('Update Lookup details'),
'callback' => 'lookup_user_operations_lookup_update',
);
return $operations;
}
/**
* Callback function for admin mass updating Raven user Lookup details.
*
* @param array $uids
* An array of user IDs.
*
* @see lookup_user_operations()
*/
function lookup_user_operations_lookup_update(array $uids) {
$accounts = user_load_multiple($uids);
foreach ($accounts as $account) {
if (is_raven_user($account)) {
$edit = array();
get_user_lookup_details($edit, $account);
user_save($account, $edit);
lookup_update($account);
}
}
}
/**
* Implements hook_action_info().
*/
function lookup_action_info() {
$info['lookup_action_lookup_update'] = array(
'type' => 'user',
'label' => t('Update Lookup details'),
'configurable' => FALSE,
);
return $info;
}
/**
* Action callback to update a Raven user's Lookup details.
*
* @see lookup_action_info()
*/
function lookup_action_lookup_update($account, $context = array()) {
lookup_delete($account->uid);
}
/**
* @addtogroup lookup
* @{
*/
/**
* Loads Lookup details for a user.
*
* @param StdClass $account
* A user account object.
*
* @return array
* The user's Lookup details.
*/
function lookup_load(stdClass $account) {
$details = lookup_load_multiple(array($account->uid => $account));
return reset($details);
}
/**
* Loads multiple Lookup details.
*
* @param array $accounts
* An array of Raven user account objects keyed by user ID.
*
* @return array
* An array of Lookup details keyed by user ID.
*/
function lookup_load_multiple(array $accounts) {
if (count($accounts) == 0) {
return array();
}
$details = db_select('users_lookup_detail', 'd')
->fields('d', array('uid', 'name', 'staff', 'student'))
->condition('uid', array_keys($accounts), 'IN')
->execute()
->fetchAllAssoc('uid', PDO::FETCH_ASSOC);
// Convert boolean string to real booleans, not sure why this has to be done
foreach ($details as $uid => $detail) {
$details[$uid]['staff'] = ($detail['staff'] == "1");
$details[$uid]['student'] = ($detail['student'] == "1");
}
// In the event that a row isn't found for a user, create a temporary empty array.
$new_accounts = array_diff_key($accounts, $details);
foreach ($new_accounts as $uid => $new_account) {
if (is_raven_user($new_account)) {
$details[$uid] = array(
'name' => NULL,
);
}
}
return $details;
}
/**
* Update Lookup details for a user.
*
* @param StdClass $account
*/
function lookup_update(StdClass $account) {
if (is_raven_user($account)) {
// Save to the database and the static cache.
db_merge('users_lookup_detail')
->key(array('uid' => $account->uid))
->fields($account->lookup)
->execute();
}
}
/**
* Delete a real name.
*
* @param $uid
* A user ID.
*/
function lookup_delete($uid) {
return lookup_delete_multiple(array($uid));
}
/**
* Delete multiple real names.
*
* @param $uids
* An array of user IDs.
*/
function lookup_delete_multiple(array $uids) {
db_delete('users_lookup_detail')->condition('uid', $uids, 'IN')->execute();
drupal_static_reset('lookup_load_multiple');
entity_get_controller('user')->resetCache($uids);
}
/**
* Delete all real names.
*/
function lookup_delete_all() {
db_delete('users_lookup_detail')->execute();
drupal_static_reset('lookup_load_multiple');
entity_get_controller('user')->resetCache();
}
/**
* @} End of 'addtogroup lookup'.
*/