realname.module 6.12 KB
Newer Older
1
<?php
2

3
4
5
6
/**
 * @file
 * Provides token-based name displays for users.
 *
7
 * @todo Add a 'view realname' permission enabled by default
8
9
10
11
12
13
14
15
16
 * @todo Alter the username autocomplete
 * @todo Allow users to login with their real name
 * @todo Disable the username field
 * @todo Allow users to override their real name
 */

/**
 * @defgroup realname Real name API
 */
17
18

/**
19
 * Implements hook_permission().
20
 */
21
22
23
24
25
26
function realname_permission() {
  $permissions['administer realname'] = array(
    'title' => t('Administer Real Name configuration.'),
  );
  return $permissions;
}
27

28
/**
29
 * Implements hook_menu().
30
 */
31
32
33
function realname_menu() {
  $items['admin/config/people/realname'] = array(
    'title' => 'Real name',
34
    'description' => 'Use tokens to configure how user names are displayed.',
35
36
37
38
39
    'page callback' => 'drupal_get_form',
    'page arguments' => array('realname_settings_form'),
    'access arguments' => array('administer realname'),
    'file' => 'realname.admin.inc',
  );
40

41
  return $items;
42
43
}

44
/**
45
 * Implements hook_username_alter().
46
 */
47
function realname_username_alter(&$name, $account) {
48
  static $in_username_alter = FALSE;
49

50
51
52
53
54
55
  if (empty($account->uid)) {
    // Don't alter anonymous users or objects that do not have any user ID.
    return;
  }

  // Real name was loaded/generated via hook_user_load(), so re-use it.
56
  if (isset($account->realname)) {
57
    if (drupal_strlen($account->realname)) {
58
      // Only if the real name is a non-empty string is $name actually altered.
59
60
      $name = $account->realname;
    }
61
    return;
62
  }
63
64
65
66

  // Real name was not yet available for the account so we need to generate it.
  // Because tokens may call format_username() we need to prevent recursion.
  if (!$in_username_alter) {
67
    $in_username_alter = TRUE;
68
69

    // If $account->realname was undefined, then the user account object was
70
71
72
    // not properly loaded. We must enforce calling user_load().
    if ($realname_account = user_load($account->uid)) {
      realname_username_alter($name, $realname_account);
73
    }
74

75
    $in_username_alter = FALSE;
76
  }
77
78
79
}

/**
80
 * Implements hook_user_load().
81
 */
82
83
84
85
function realname_user_load(array $accounts) {
  $realnames = realname_load_multiple($accounts);
  foreach ($realnames as $uid => $realname) {
    $accounts[$uid]->realname = $realname;
86
87
88
89
  }
}

/**
90
 * Implements hook_user_update().
91
 */
92
93
94
function realname_user_update(array &$edit, stdClass $account, $category) {
  // Since user data may have changed, delete the existing realname.
  realname_delete($account->uid);
95
96
}

97
98
99
100
101
102
/**
 * Implements hook_user_delete().
 */
function realname_user_delete(stdClass $account) {
  realname_delete($account->uid);
}
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
/**
 * Implements hook_user_operations().
 */
function realname_user_operations() {
  $operations['realname_update'] = array(
    'label' => t('Update real name'),
    'callback' => 'realname_user_operations_realname_update',
  );
  return $operations;
}

/**
 * Callback function for admin mass generating user real names.
 *
 * @param $uids
 *   An array of user IDs.
 */
function realname_user_operations_realname_update(array $uids) {
  $accounts = user_load_multiple($uids);
  foreach ($accounts as $account) {
    realname_update($account);
  }
}

/**
 * @addtogroup realname
 * @{
 */

133
/**
134
 * Loads a real name.
135
 *
136
137
 * @param $uid
 *   A user account object.
138
 * @return
139
 *   The user's generated real name.
140
 */
141
142
143
144
function realname_load(stdClass $account) {
  $realnames = realname_load_multiple(array($account->uid => $account));
  return reset($realnames);
}
145

146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/**
 * Loads multiple real names.
 *
 * @param $accounts
 *   An array of user account objects keyed by user ID.
 * @return
 *   An array of real names keyed by user ID.
 */
function realname_load_multiple(array $accounts) {
  $realnames = &drupal_static(__FUNCTION__, array());

  if ($new_accounts = array_diff_key($accounts, $realnames)) {
    // Attempt to fetch realnames from the database first.
    $realnames += db_query("SELECT uid, realname FROM {realname} WHERE uid IN (:uids)", array(':uids' => array_keys($new_accounts)))->fetchAllKeyed();

    // For each account that was not present in the database, generate its
    // real name.
    foreach ($new_accounts as $uid => $account) {
164
      if (!isset($realnames[$uid])) {
165
        $realnames[$uid] = realname_update($account);
166
      }
167
    }
168
169
  }

170
  return array_intersect_key($realnames, $accounts);
171
172
}

173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/**
 * Update the realname for a user account.
 *
 * @param $account
 *   A user account object.
 *
 * @see hook_realname_pattern_alter()
 * @see hook_realname_alter()
 * @see hook_realname_update()
 */
function realname_update($account) {
  // Get the default pattern and allow other modules to alter it.
  $pattern = variable_get('realname_pattern', '[user:name-raw]');
  drupal_alter('realname_pattern', $pattern, $account);

  // Perform token replacement on the real name pattern.
189
  $realname = token_replace($pattern, array('user' => $account), array('clear' => TRUE, 'sanitize' => FALSE));
190
191
192
193
  $realname = trim(strip_tags($realname));

  // The name must be trimmed to 255 characters before inserting into the database.
  $realname = truncate_utf8($realname, 255);
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

  // Allow other modules to alter the generated realname.
  drupal_alter('realname', $realname, $account);

  // Save to the database and the static cache.
  db_merge('realname')
    ->key(array('uid' => $account->uid))
    ->fields(array(
      'realname' => $realname,
      'created' => REQUEST_TIME,
    ))
    ->execute();

  // Allow modules to react to the realname being updated.
  module_invoke_all('realname_update', $realname, $account);

  $account->realname = $realname;
  return $realname;
}

214
/**
215
 * Delete a real name.
216
 *
217
218
 * @param $uid
 *   A user ID.
219
 */
220
221
function realname_delete($uid) {
  return realname_delete_multiple(array($uid));
222
223
224
}

/**
225
226
227
228
 * Delete multiple real names.
 *
 * @param $uids
 *   An array of user IDs.
229
 */
230
231
232
function realname_delete_multiple(array $uids) {
  db_delete('realname')->condition('uid', $uids, 'IN')->execute();
  drupal_static_reset('realname_load_multiple');
233
234
235
}

/**
236
 * Delete all real names.
237
 */
238
239
240
function realname_delete_all() {
  db_delete('realname')->execute();
  drupal_static_reset('realname_load_multiple');
241
}
242
243
244
245

/**
 * @} End of "addtogroup realname".
 */