user.module 80.6 KB
Newer Older
Dries's avatar
 
Dries committed
1 2 3
<?php
// $Id$

Dries's avatar
Dries committed
4 5 6 7 8 9
/**
 * Invokes hook_user() in every module.
 *
 * We cannot use module_invoke() for this, becuse the arguments need to
 * be passed by reference.
 */
Dries's avatar
 
Dries committed
10 11 12
function user_module_invoke($type, &$array, &$user) {
  foreach (module_list() as $module) {
    $function = $module .'_user';
Dries's avatar
 
Dries committed
13
    if (function_exists($function)) $function($type, $array, $user);
Dries's avatar
 
Dries committed
14 15 16
  }
}

Dries's avatar
 
Dries committed
17
function user_external_load($authname) {
Dries's avatar
 
Dries committed
18
  $result = db_query("SELECT uid FROM {authmap} WHERE authname = '%s'", $authname);
Dries's avatar
 
Dries committed
19

Dries's avatar
 
Dries committed
20 21
  if ($user = db_fetch_object($result)) {
    return user_load($user);
Dries's avatar
 
Dries committed
22 23 24 25 26 27
  }
  else {
    return 0;
  }
}

Dries's avatar
Dries committed
28 29 30 31 32 33 34 35 36 37
/**
 * Fetch a user object.
 *
 * @param $array
 *   An associative array of attributes to search for in selecting the
 *   user, such as user name or email address.
 *
 * @return
 *   A fully-loaded $user object.
 */
Dries's avatar
 
Dries committed
38
function user_load($array = array()) {
Dries's avatar
Dries committed
39 40
  // Dynamically compose a SQL query:
  $query = '';
Dries's avatar
 
Dries committed
41

Dries's avatar
 
Dries committed
42
  foreach ($array as $key => $value) {
Dries's avatar
 
Dries committed
43
    if ($key == 'pass') {
Kjartan's avatar
Kjartan committed
44
      $query .= "u.$key = '". md5($value) ."' AND ";
45
    }
Dries's avatar
 
Dries committed
46
    else {
47
      $query .= "LOWER(u.$key) = '". strtolower(check_query($value)) ."' AND ";
Dries's avatar
 
Dries committed
48 49
    }
  }
50
  $result = db_query_range("SELECT u.* FROM {users} u WHERE $query u.status < 3", 0, 1);
Dries's avatar
 
Dries committed
51 52

  $user = db_fetch_object($result);
Dries's avatar
 
Dries committed
53
  $user = drupal_unpack($user);
Dries's avatar
Dries committed
54
  user_module_invoke('load', $array, $user);
Dries's avatar
 
Dries committed
55

Dries's avatar
 
Dries committed
56
  $user->roles = array();
Dries's avatar
Dries committed
57
  $result = db_query('SELECT r.rid, r.name FROM {role} r INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid = %d', $user->uid);
Dries's avatar
 
Dries committed
58 59 60
  while ($role = db_fetch_object($result)) {
    $user->roles[$role->rid] = $role->name;
  }
Dries's avatar
 
Dries committed
61 62 63 64 65

  return $user;
}

function user_save($account, $array = array()) {
Dries's avatar
Dries committed
66
  // Dynamically compose a SQL query:
Kjartan's avatar
Kjartan committed
67
  $user_fields = user_fields();
Dries's avatar
 
Dries committed
68
  if ($account->uid) {
Dries's avatar
Dries committed
69
    user_module_invoke('update', $array, $account);
Dries's avatar
 
Dries committed
70

Dries's avatar
Dries committed
71
    $data = unserialize(db_result(db_query('SELECT data FROM {users} WHERE uid = %d', $account->uid)));
Dries's avatar
 
Dries committed
72
    foreach ($array as $key => $value) {
Dries's avatar
 
Dries committed
73
      if ($key == 'pass') {
Dries's avatar
 
Dries committed
74 75
        $query .= "$key = '%s', ";
        $v[] = md5($value);
Dries's avatar
 
Dries committed
76
      }
Dries's avatar
Dries committed
77
      else if (substr($key, 0, 4) !== 'auth') {
Kjartan's avatar
Kjartan committed
78
        if (in_array($key, $user_fields)) {
Dries's avatar
 
Dries committed
79
          // escape '%'s:
Dries's avatar
Dries committed
80
          $value = str_replace('%', '%%', $value);
Dries's avatar
 
Dries committed
81 82
          $query .= "$key = '%s', ";
          $v[] = $value;
Dries's avatar
 
Dries committed
83 84 85 86
        }
        else {
          $data[$key] = $value;
        }
Dries's avatar
 
Dries committed
87 88
      }
    }
Dries's avatar
 
Dries committed
89 90
    $query .= "data = '%s', ";
    $v[] = serialize($data);
Dries's avatar
 
Dries committed
91

Dries's avatar
 
Dries committed
92
    db_query("UPDATE {users} SET $query changed = %d WHERE uid = %d", array_merge($v, array(time(), $account->uid)));
Dries's avatar
 
Dries committed
93

94 95
    // reload user roles if provided
    if (is_array($array['rid'])) {
Dries's avatar
Dries committed
96
      db_query('DELETE FROM {users_roles} WHERE uid = %d', $account->uid);
Dries's avatar
 
Dries committed
97

98
      foreach ($array['rid'] as $rid) {
Dries's avatar
Dries committed
99
        db_query('INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)', $account->uid, $rid);
100
      }
Dries's avatar
 
Dries committed
101 102
    }

Dries's avatar
 
Dries committed
103
    $user = user_load(array('uid' => $account->uid));
Dries's avatar
 
Dries committed
104 105
  }
  else {
Dries's avatar
 
Dries committed
106 107
    $array['created'] = time();
    $array['changed'] = time();
Dries's avatar
Dries committed
108
    $array['uid'] = db_next_id('{users}_uid');
Dries's avatar
 
Dries committed
109 110

    foreach ($array as $key => $value) {
Dries's avatar
 
Dries committed
111
      if ($key == 'pass') {
Dries's avatar
 
Dries committed
112
        $fields[] = check_query($key);
Dries's avatar
 
Dries committed
113 114
        $values[] = md5($value);
        $s[] = "'%s'";
Dries's avatar
 
Dries committed
115
      }
Dries's avatar
Dries committed
116
      else if (substr($key, 0, 4) !== 'auth') {
Kjartan's avatar
Kjartan committed
117
        if (in_array($key, $user_fields)) {
Dries's avatar
 
Dries committed
118
          $fields[] = check_query($key);
Dries's avatar
 
Dries committed
119 120
          $values[] = $value;
          $s[] = "'%s'";
Dries's avatar
 
Dries committed
121 122 123 124
        }
        else {
          $data[$key] = $value;
        }
Dries's avatar
 
Dries committed
125 126 127
      }
    }

Dries's avatar
Dries committed
128
    $fields[] = 'data';
Dries's avatar
 
Dries committed
129 130
    $values[] = serialize($data);
    $s[] = "'%s'";
Dries's avatar
 
Dries committed
131

Dries's avatar
Dries committed
132
    db_query('INSERT INTO {users} ('. implode(', ', $fields) .') VALUES ('. implode(', ', $s) .')', $values);
Dries's avatar
 
Dries committed
133

Dries's avatar
Dries committed
134 135
    // Reload user roles (delete just to be safe).
    db_query('DELETE FROM {users_roles} WHERE uid = %d', $array['uid']);
Dries's avatar
 
Dries committed
136 137

    foreach ($array['rid'] as $rid) {
Dries's avatar
Dries committed
138
      db_query('INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)', $array['uid'], $rid);
Dries's avatar
 
Dries committed
139 140
    }

Dries's avatar
 
Dries committed
141
    $user = user_load(array('name' => $array['name']));
Dries's avatar
 
Dries committed
142

Dries's avatar
 
Dries committed
143
    module_invoke_all('user', 'insert', $array, $user);
Dries's avatar
 
Dries committed
144 145 146
  }

  foreach ($array as $key => $value) {
Dries's avatar
 
Dries committed
147
    if (substr($key, 0, 4) == 'auth') {
Dries's avatar
 
Dries committed
148 149 150 151 152
      $authmaps[$key] = $value;
    }
  }

  if ($authmaps) {
Dries's avatar
 
Dries committed
153
    user_set_authmaps($user, $authmaps);
Dries's avatar
 
Dries committed
154 155 156 157 158
  }

  return $user;
}

Dries's avatar
Dries committed
159 160 161
/**
 * Verify the syntax of the given name.
 */
Dries's avatar
 
Dries committed
162
function user_validate_name($name) {
Dries's avatar
Dries committed
163 164 165 166 167 168 169
  if (!$name) return t('You must enter a username.');
  if (substr($name, 0, 1) == ' ') return t('The username cannot begin with a space.');
  if (substr($name, -1) == ' ') return t('The username cannot end with a space.');
  if (ereg('  ', $name)) return t('The username cannot contain multiple spaces in a row.');
  if (ereg('[^ [:alnum:]@_.-]', $name)) return t('The username contains an illegal character.');
  if (ereg('@', $name) && !eregi('@([0-9a-z](-?[0-9a-z])*.)+[a-z]{2}([zmuvtg]|fo|me)?$', $name)) return t('The username is not a valid authentication ID.');
  if (strlen($name) > 56) return t('The username "%name" is too long: it must be less than 56 characters.', array('%name' => $name));
Dries's avatar
 
Dries committed
170 171 172
}

function user_validate_mail($mail) {
Dries's avatar
Dries committed
173
  if (!$mail) return t('You must enter an e-mail address.');
Dries's avatar
 
Dries committed
174
  if ($mail && !valid_email_address($mail)) {
Dries's avatar
Dries committed
175
    return t('The e-mail address "%mail" is not valid.', array('%mail' => $mail));
Dries's avatar
 
Dries committed
176 177 178
  }
}

Dries's avatar
 
Dries committed
179
function user_validate_picture($file, &$edit, $user) {
Dries's avatar
Dries committed
180
  // Initialize the picture:
Dries's avatar
 
Dries committed
181 182
  $edit['picture'] = $user->picture;

Dries's avatar
Dries committed
183 184 185
  // Check that uploaded file is an image, with a maximum file size
  // and maximum height/width.
  $extension = strtolower(strrchr($file->name, '.'));
Dries's avatar
 
Dries committed
186
  $size = getimagesize($file->path);
Dries's avatar
Dries committed
187
  list($maxwidth, $maxheight) = explode('x', variable_get('user_picture_dimensions', '85x85'));
Dries's avatar
 
Dries committed
188

Dries's avatar
Dries committed
189
  if ((!in_array($size[2], array(1, 2, 3))) || (!in_array($extension, array('.gif', '.jpg', '.png', '.jpeg')))) {
Dries's avatar
 
Dries committed
190
    form_set_error('picture', t('The uploaded file was not an image.'));
Dries's avatar
 
Dries committed
191
  }
Dries's avatar
Dries committed
192
  else if ($file->size > (variable_get('user_picture_file_size', '30') * 1000)) {
Dries's avatar
 
Dries committed
193
    form_set_error('picture', t('The uploaded image is too large; the maximum file size is %a kB.', array('%a' => variable_get('user_picture_file_size', '30'))));
Dries's avatar
 
Dries committed
194 195
  }
  else if ($size[0] > $maxwidth || $size[1] > $maxheight) {
Dries's avatar
 
Dries committed
196
    form_set_error('picture', t('The uploaded image is too large; the maximum dimensions are %a pixels.', array('%a' => variable_get('user_picture_dimensions', '85x85'))));
Dries's avatar
 
Dries committed
197
  }
Dries's avatar
Dries committed
198
  else if ($file = file_save_upload('picture', variable_get('user_picture_path', 'pictures') . FILE_SEPARATOR .'picture-'. $user->uid . $extension, 1)) {
Dries's avatar
 
Dries committed
199 200 201
    $edit['picture'] = $file->path;
  }
  else {
Dries's avatar
 
Dries committed
202
    form_set_error('picture', t('Failed to upload the picture image; the "%directory" directory doesn\'t exist.', array('%directory' => variable_get('user_picture_path', 'pictures'))));
Dries's avatar
 
Dries committed
203 204 205
  }
}

206
function user_validate_authmap($account, $authname, $module) {
Dries's avatar
 
Dries committed
207
  $result = db_query("SELECT COUNT(*) from {authmap} WHERE uid != %d AND authname = '%s'", $account->uid, $authname);
Dries's avatar
 
Dries committed
208
  if (db_result($result) > 0) {
Dries's avatar
 
Dries committed
209
    $name = module_invoke($module, 'info', 'name');
Dries's avatar
Dries committed
210
    return t('The %u ID %s is already taken.', array('%u' => ucfirst($name), '%s' => "<i>$authname</i>"));
Dries's avatar
 
Dries committed
211
  }
Dries's avatar
 
Dries committed
212 213
}

Dries's avatar
Dries committed
214 215 216
/**
 * Generate a random alphanumeric password.
 */
Dries's avatar
 
Dries committed
217 218 219 220 221
function user_password($length = 10) {
  // This variable contains the list of allowable characters for the
  // password.  Note that the number 0 and the letter 'O' have been
  // removed to avoid confusion between the two.  The same is true
  // of 'I' and 1.
Dries's avatar
Dries committed
222 223
  $allowable_characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789';

Dries's avatar
 
Dries committed
224 225 226
  // We see how many characters are in the allowable list:
  $len = strlen($allowable_characters);

Dries's avatar
Dries committed
227
  // Seed the random number generator with the microtime stamp.
Dries's avatar
 
Dries committed
228
  mt_srand((double)microtime() * 1000000);
Dries's avatar
 
Dries committed
229

Dries's avatar
Dries committed
230 231
  // Declare the password as a blank string.
  $pass = '';
Dries's avatar
 
Dries committed
232

Dries's avatar
Dries committed
233
  // Loop the number of times specified by $length.
Dries's avatar
 
Dries committed
234 235 236 237 238 239 240 241
  for ($i = 0; $i < $length; $i++) {

    // Each iteration, pick a random character from the
    // allowable string and append it to the password:
    $pass .= $allowable_characters[mt_rand(0, $len - 1)];
  }

  return $pass;
Dries's avatar
 
Dries committed
242 243
}

Dries's avatar
Dries committed
244 245 246 247 248 249 250 251 252 253 254 255 256
/**
 * Determine whether the user has a given privilege.
 *
 * @param $string
 *   The permission, such as "administer nodes", being checked for.
 *
 * @return
 *   TRUE iff the current user has the requested permission.
 *
 * All permission checks in Drupal should go through this function. This
 * way, we guarantee consistent behavior, and ensure that the superuser
 * can perform all actions.
 */
Dries's avatar
 
Dries committed
257 258
function user_access($string) {
  global $user;
Dries's avatar
 
Dries committed
259
  static $perm = 0;
Dries's avatar
 
Dries committed
260

Dries's avatar
 
Dries committed
261
  // User #1 has all priveleges:
Dries's avatar
 
Dries committed
262 263 264 265
  if ($user->uid == 1) {
    return 1;
  }

Dries's avatar
Dries committed
266 267
  // To reduce the number of SQL queries, we cache the user's permissions
  // in a static variable.
Dries's avatar
 
Dries committed
268
  if ($perm === 0) {
Dries's avatar
Dries committed
269
    $result = db_query('SELECT DISTINCT p.perm FROM {role} r INNER JOIN {permission} p ON p.rid = r.rid INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid = %d', $user->uid);
Dries's avatar
 
Dries committed
270 271 272 273

    while ($row = db_fetch_object($result)) {
      $perm .= "$row->perm, ";
    }
Dries's avatar
 
Dries committed
274 275
  }

Dries's avatar
 
Dries committed
276
  return strstr($perm, "$string, ");
Dries's avatar
 
Dries committed
277 278
}

Dries's avatar
Dries committed
279 280 281
/**
 * Send an e-mail message.
 */
Dries's avatar
 
Dries committed
282
function user_mail($mail, $subject, $message, $header) {
Dries's avatar
Dries committed
283 284
  if (variable_get('smtp_library', '') && file_exists(variable_get('smtp_library', ''))) {
    include_once variable_get('smtp_library', '');
285
    return user_mail_wrapper($mail, $subject, $message, $header);
Dries's avatar
 
Dries committed
286 287
  }
  else {
288 289 290 291 292 293 294
    /*
    ** Note: if you are having problems with sending mail, or mails look wrong
    ** when they are recieved you may have to modify the str_replace to suit
    ** your systems.
    **  - \r\n will work under dos and windows.
    **  - \n will work for linux, unix and BSDs.
    **  - \r will work for macs.
Dries's avatar
 
Dries committed
295 296 297 298 299 300 301 302 303 304 305 306
    **
    ** According to RFC 2646, it's quite rude to not wrap your e-mails:
    **
    ** "The Text/Plain media type is the lowest common denominator of
    ** Internet email, with lines of no more than 997 characters (by
    ** convention usually no more than 80), and where the CRLF sequence
    ** represents a line break [MIME-IMT]."
    **
    ** CRLF === \r\n
    **
    ** http://www.rfc-editor.org/rfc/rfc2646.txt
    **
307
    */
Dries's avatar
 
Dries committed
308 309 310
    return mail(
      $mail,
      user_mail_encode($subject),
Dries's avatar
Dries committed
311
      str_replace("\r", '', $message),
Dries's avatar
 
Dries committed
312
      "MIME-Version: 1.0\nContent-Type: text/plain; charset=UTF-8; format=flowed\nContent-transfer-encoding: 8Bit\n" . $header
Dries's avatar
 
Dries committed
313
    );
Dries's avatar
 
Dries committed
314 315 316
  }
}

Dries's avatar
Dries committed
317
function user_mail_encode($string, $charset = 'UTF-8') {
Kjartan's avatar
Kjartan committed
318 319 320 321
  /*
  ** Used to encodes mail headers that contain non US- ASCII
  ** characters.
  ** http://www.rfc-editor.org/rfc/rfc2047.txt
Kjartan's avatar
Kjartan committed
322 323
  **
  ** Notes:
324
  **   - Only encode strings that contain non-ASCII characters.
Kjartan's avatar
Kjartan committed
325 326 327 328 329 330
  **   - The chunks come in groupings of 4 bytes when using base64
  **     encoded.
  **   - trim() is used to ensure that no extra spacing is added by
  **     chunk_split() or preg_replace().
  **   - Using \n as the chunk separator may cause problems on some
  **     systems and may have to be changed to \r\n or \r.
Kjartan's avatar
Kjartan committed
331
  */
332 333 334 335 336 337
  if (!preg_match('/^[\x20-\x7E]*$/', $string)) {
    $chunk_size = 75 - 7 - strlen($charset);
    $chunk_size -= $chunk_size % 4;
    $string = trim(chunk_split(base64_encode($string), $chunk_size, "\n"));
    $string = trim(preg_replace('/^(.*)$/m', " =?$charset?B?\\1?=", $string));
  }
Kjartan's avatar
Kjartan committed
338
  return $string;
Dries's avatar
 
Dries committed
339 340
}

Dries's avatar
 
Dries committed
341
function user_deny($type, $mask) {
Dries's avatar
Dries committed
342 343
  $allow = db_fetch_object(db_query("SELECT * FROM {access} WHERE status = 1 AND type = '%s' AND LOWER('%s') LIKE LOWER(mask)", $type, $mask));
  $deny = db_fetch_object(db_query("SELECT * FROM {access} WHERE status = 0 AND type = '%s' AND LOWER('%s') LIKE LOWER(mask)", $type, $mask));
Dries's avatar
 
Dries committed
344

Dries's avatar
 
Dries committed
345
  return $deny && !$allow;
Dries's avatar
 
Dries committed
346 347
}

Dries's avatar
 
Dries committed
348 349
function user_fields() {
  static $fields;
Dries's avatar
 
Dries committed
350

Dries's avatar
 
Dries committed
351
  if (!$fields) {
Dries's avatar
Dries committed
352
    $result = db_query('SELECT * FROM {users} WHERE uid = 1');
Kjartan's avatar
Kjartan committed
353 354 355
    if (db_num_rows($result)) {
      $fields = array_keys(db_fetch_array($result));
    }
Dries's avatar
 
Dries committed
356 357
    else {
      // Make sure we return the default fields at least
Dries's avatar
 
Dries committed
358
      $fields = array('uid', 'name', 'pass', 'mail', 'picture', 'mode', 'sort', 'threshold', 'theme', 'signature', 'created', 'changed', 'status', 'timezone', 'language', 'init', 'data');
Dries's avatar
 
Dries committed
359
    }
Dries's avatar
 
Dries committed
360
  }
Dries's avatar
 
Dries committed
361

Dries's avatar
 
Dries committed
362
  return $fields;
Dries's avatar
 
Dries committed
363 364
}

Dries's avatar
Dries committed
365 366 367
/**
 * Implementation of hook_perm().
 */
Dries's avatar
 
Dries committed
368
function user_perm() {
Dries's avatar
Dries committed
369
  return array('administer users', 'access user list');
Dries's avatar
 
Dries committed
370 371
}

Dries's avatar
Dries committed
372 373 374 375 376
/**
 * Implementation of hook_file_download().
 *
 * Ensure that user pictures (avatars) are always downloadable.
 */
Dries's avatar
 
Dries committed
377
function user_file_download($file) {
Dries's avatar
Dries committed
378
  if (strpos($file, variable_get('user_picture_path', 'pictures') . FILE_SEPARATOR . 'picture-') === 0) {
Dries's avatar
 
Dries committed
379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
    list($width, $height, $type, $attr) = getimagesize(file_create_path($file));
    $types = array(
      IMAGETYPE_GIF => 'image/gif',
      IMAGETYPE_JPEG => 'image/jpeg',
      IMAGETYPE_PNG => 'image/png',
      IMAGETYPE_SWF => 'application/x-shockwave-flash',
      IMAGETYPE_PSD => 'image/psd',
      IMAGETYPE_BMP => 'image/bmp',
      IMAGETYPE_TIFF_II => 'image/tiff',
      IMAGETYPE_TIFF_MM  => 'image/tiff',
      IMAGETYPE_JPC => 'application/octet-stream',
      IMAGETYPE_JP2 => 'image/jp2',
      IMAGETYPE_JPX => 'application/octet-stream',
      IMAGETYPE_JB2 => 'application/octet-stream',
      IMAGETYPE_SWC => 'application/x-shockwave-flash',
      IMAGETYPE_IFF => 'image/iff',
      IMAGETYPE_WBMP => 'image/vnd.wap.wbmp',
      IMAGETYPE_XBM => 'image/xbm'
    );
    return array('Content-type: '. $types[$type]);
  }
}

Dries's avatar
Dries committed
402 403 404
/**
 * Implementation of hook_search().
 */
Dries's avatar
 
Dries committed
405
function user_search($keys) {
Dries's avatar
 
Dries committed
406
  $find = array();
407

Dries's avatar
Dries committed
408 409
  // Replace wildcards with MySQL/PostgreSQL wildcards.
  $keys = str_replace('*', '%', $keys);
410

411
  $result = db_query_range("SELECT * FROM {users} WHERE LOWER(name) LIKE '%%%s%%'", strtolower($keys), 0, 20);
Dries's avatar
 
Dries committed
412
  while ($account = db_fetch_object($result)) {
Dries's avatar
 
Dries committed
413
    $find[] = array('title' => $account->name, 'link' => url("user/$account->uid/view"), 'user' => $account->name);
Dries's avatar
 
Dries committed
414
  }
Dries's avatar
Dries committed
415
  return array(t('Matching users'), $find);
Dries's avatar
 
Dries committed
416 417
}

Dries's avatar
Dries committed
418 419 420
/**
 * Implementation of hook_user().
 */
Dries's avatar
Dries committed
421
function user_user($type, &$edit, &$user) {
Dries's avatar
Dries committed
422
  if ($type == 'view') {
Dries's avatar
Dries committed
423
    return array(t('History') => form_item(t('Member for'), format_interval(time() - $user->created)));
Dries's avatar
Dries committed
424 425 426
  }
}

Dries's avatar
Dries committed
427 428 429 430
/**
 * Implementation of hook_block().
 */
function user_block($op = 'list', $delta = 0) {
Dries's avatar
 
Dries committed
431 432
  global $user;

Dries's avatar
Dries committed
433 434 435 436 437
  if ($op == 'list') {
     $blocks[0]['info'] = t('User login');
     $blocks[1]['info'] = t('Navigation');
     $blocks[2]['info'] = t('Who\'s new');
     $blocks[3]['info'] = t('Who\'s online');
438

439
     return $blocks;
440 441
  }
  else {
Dries's avatar
 
Dries committed
442 443
    $block = array();

Dries's avatar
 
Dries committed
444 445
    switch ($delta) {
      case 0:
Dries's avatar
 
Dries committed
446

447
        if (!$user->uid) {
Dries's avatar
Dries committed
448 449
          // For usability's sake, avoid showing two login forms on one page.
          if (arg(0) == 'user' && arg(1) != 'view') {
Dries's avatar
 
Dries committed
450 451 452
            return;
          }

Dries's avatar
Dries committed
453
          $edit = $_POST['edit'];
Dries's avatar
 
Dries committed
454

Dries's avatar
 
Dries committed
455 456
          $output = "<div class=\"user-login-block\">\n";

Dries's avatar
Dries committed
457 458
          // Save the referer.  We record where the user came from such
          // that we can redirect him after having completed the login form.
Dries's avatar
Dries committed
459

460
          if (empty($edit)) {
Dries's avatar
Dries committed
461
            $edit['destination'] = $_GET['q'];
462
          }
Dries's avatar
Dries committed
463 464 465 466 467 468 469 470
          // NOTE: special care needs to be taken because on pages with forms,
          // such as node and comment submission pages, the $edit variable
          // might already be set.

          $output .= form_hidden('destination', $edit['destination']);
          $output .= form_textfield(t('Username'), 'name', $edit['name'], 15, 64);
          $output .= form_password(t('Password'), 'pass', $pass, 15, 64);
          $output .= form_submit(t('Log in'));
Dries's avatar
 
Dries committed
471
          $output .= "</div>\n";
Dries's avatar
 
Dries committed
472

Dries's avatar
Dries committed
473
          $output  = form($output, 'post', url('user/login'));
Dries's avatar
 
Dries committed
474

Dries's avatar
Dries committed
475 476
          if (variable_get('user_register', 1)) {
            $items[] = l(t('Create new account'), 'user/register', array('title' => t('Create a new user account.')));
Dries's avatar
 
Dries committed
477
          }
Dries's avatar
Dries committed
478
          $items[] = l(t('Request new password'), 'user/password', array('title' => t('Request new password via e-mail.')));
Dries's avatar
 
Dries committed
479

Dries's avatar
Dries committed
480
          $output .= theme('item_list', $items);
481

Dries's avatar
Dries committed
482 483
          $block['subject'] = t('User login');
          $block['content'] = $output;
Dries's avatar
 
Dries committed
484
        }
Dries's avatar
Dries committed
485
        return $block;
486
      case 1:
Dries's avatar
 
Dries committed
487
        if ($menu = theme('menu_tree')) {
Dries's avatar
Dries committed
488 489
           $block['subject'] = $user->uid ? $user->name : t('Navigation');
           $block['content'] = '<div class="menu">'. $menu .'</div>';
Dries's avatar
 
Dries committed
490
        }
491
        return $block;
Dries's avatar
 
Dries committed
492
      case 2:
Dries's avatar
Dries committed
493 494
        if (user_access('access content')) {
          $result = db_query_range('SELECT uid, name FROM {users} WHERE status != 0 ORDER BY uid DESC', 0, 5);
495
          while ($account = db_fetch_object($result)) {
496
            $items[] = format_name($account);
497
          }
Dries's avatar
 
Dries committed
498

Dries's avatar
Dries committed
499
          $output = theme('user_list', $items);
Dries's avatar
 
Dries committed
500

Dries's avatar
Dries committed
501 502
          $block['subject'] = t('Who\'s new');
          $block['content'] = $output;
503 504
          return $block;
        }
Dries's avatar
 
Dries committed
505
      case 3:
Dries's avatar
Dries committed
506 507 508
        if (user_access('access content')) {
          // Count users with activity in the past defined period.
          $time_period = variable_get('user_block_seconds_online', 2700);
Dries's avatar
 
Dries committed
509

Dries's avatar
Dries committed
510 511 512
          // Perform database queries to gather online user lists.
          $guests = db_fetch_object(db_query('SELECT COUNT(DISTINCT sid) AS count FROM {sessions} WHERE timestamp >= %d AND uid = 0', time() - $time_period));
          $users = db_query('SELECT DISTINCT uid, MAX(timestamp) AS max_timestamp FROM {sessions} WHERE timestamp >= %d AND uid != 0 GROUP BY uid ORDER BY max_timestamp DESC', time() - $time_period );
Dries's avatar
 
Dries committed
513
          $total_users = db_num_rows($users);
Dries's avatar
 
Dries committed
514

Dries's avatar
Dries committed
515
          // Format the output with proper grammar.
Dries's avatar
 
Dries committed
516
          if ($total_users == 1 && $guests->count == 1) {
Dries's avatar
Dries committed
517
            $output = t('There is currently %members and %visitors online.', array('%members' => format_plural($total_users, '1 user', '%count users'), '%visitors' => format_plural($guests->count, '1 guest', '%count guests')));
Dries's avatar
 
Dries committed
518 519
          }
          else {
Dries's avatar
Dries committed
520
            $output = t('There are currently %members and %visitors online.', array('%members' => format_plural($total_users, '1 user', '%count users'), '%visitors' => format_plural($guests->count, '1 guest', '%count guests')));
Dries's avatar
 
Dries committed
521 522
          }

Dries's avatar
Dries committed
523
          if (user_access('access user list') && $total_users) {
Dries's avatar
 
Dries committed
524

Dries's avatar
Dries committed
525 526
            // Display a list of currently online users.
            $max_users = variable_get('user_block_max_list_count', 10);
Dries's avatar
 
Dries committed
527 528
            if ($max_users) {
              $items = array();
Dries's avatar
 
Dries committed
529

Dries's avatar
 
Dries committed
530
              while ($max_users-- && $uid = db_fetch_object($users)) {
Dries's avatar
 
Dries committed
531
                $items[] = format_name(user_load(array('uid' => $uid->uid)));
Dries's avatar
 
Dries committed
532 533 534
              }

              if ($items) {
Dries's avatar
 
Dries committed
535
                if (db_fetch_object($users)) {
Dries's avatar
Dries committed
536
                  $items[] = '...';
Dries's avatar
 
Dries committed
537
                }
Dries's avatar
Dries committed
538
                $output .= theme('item_list', $items, t('Online users:'));
Dries's avatar
 
Dries committed
539
              }
Dries's avatar
 
Dries committed
540
            }
Dries's avatar
 
Dries committed
541
          }
Dries's avatar
Dries committed
542 543
          $block['subject'] = t('Who\'s online');
          $block['content'] = $output;
Dries's avatar
 
Dries committed
544
        }
Dries's avatar
 
Dries committed
545
        return $block;
Dries's avatar
 
Dries committed
546 547
    }
  }
548 549
}

Dries's avatar
 
Dries committed
550 551 552 553 554 555 556 557 558 559
function theme_user_picture($account) {
  if (variable_get('user_pictures', 0)) {
    if ($account->picture && file_exists($account->picture)) {
      $picture = file_create_url($account->picture);
    }
    else if (variable_get('user_picture_default', '')) {
      $picture = variable_get('user_picture_default', '');
    }

    if ($picture) {
Dries's avatar
Dries committed
560
      $picture = "<img src=\"$picture\" alt=\"" . t('%user\'s picture', array('%user' => $account->name ? $account->name : t(variable_get('anonymous', 'Anonymous')))) . '" />';
Dries's avatar
 
Dries committed
561
      if ($account->uid) {
Dries's avatar
Dries committed
562
        $picture = l($picture, "user/view/$account->uid", array('title' => t('View user profile.')));
Dries's avatar
 
Dries committed
563 564 565 566 567 568 569
      }

      return "<div class=\"picture\">$picture</div>";
    }
  }
}

Dries's avatar
Dries committed
570
function theme_user_profile($account, $fields) {
Dries's avatar
 
Dries committed
571 572
  $output = "<div class=\"profile\">\n";
  $output .= theme('user_picture', $account);
Dries's avatar
Dries committed
573 574 575
  foreach ($fields as $category => $value) {
    $output .= "<h2>$category</h2>$value";
  }
Dries's avatar
 
Dries committed
576 577 578 579 580
  $output .= "</div>\n";

  return $output;
}

Dries's avatar
 
Dries committed
581
function theme_user_list($items, $title = NULL) {
Dries's avatar
Dries committed
582
  return theme('item_list', $items, $title);
Dries's avatar
 
Dries committed
583 584
}

Dries's avatar
 
Dries committed
585
/**
Dries's avatar
 
Dries committed
586
 * Implementation of hook_menu().
Dries's avatar
 
Dries committed
587
 */
Dries's avatar
 
Dries committed
588
function user_menu() {
Dries's avatar
 
Dries committed
589
  global $user;
Dries's avatar
 
Dries committed
590

Dries's avatar
 
Dries committed
591
  $items = array();
Dries's avatar
 
Dries committed
592

Dries's avatar
 
Dries committed
593 594 595 596 597 598 599
  $access = user_access('administer users');

  if (arg(0) == 'user' && is_numeric(arg(1))) {
    $items[] = array('path' => 'user/'. arg(1), 'title' => t('user'),
      'callback' => 'user_page', 'access' => TRUE);
    // Add the edit menu:
    if ($access) $function = 'user_admin_edit';
Dries's avatar
 
Dries committed
600
    else $function = 'user_page';
Dries's avatar
 
Dries committed
601 602 603
    $items[] = array('path' => 'user/'. arg(1) .'/edit', 'title' => t('edit'),
      'callback' => $function, 'access' => $access || $user->uid == arg(1),
      'type' => MENU_LOCAL_TASK);
Dries's avatar
 
Dries committed
604
  }
Dries's avatar
 
Dries committed
605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622

  if ($user->uid) {
    $items[] = array('path' => "user/$user->uid", 'title' => t('my account'),
      'callback' => 'user_page', 'access' => TRUE);
    $items[] = array('path' => 'logout', 'title' => t('log out'),
      'access' => TRUE,
      'callback' => 'user_logout',
      'weight' => 10);
  }
  else {
    $items[] = array('path' => 'logout', 'title' => t('log out'),
      'callback' => 'user_logout', 'access' => FALSE);
  }

  $items[] = array('path' => 'user', 'title' => t('user'),
    'callback' => 'user_page', 'access' => TRUE,
    'type' => MENU_CALLBACK);
  $items[] = array('path' => 'user/login', 'title' => t('log in'),
Dries's avatar
 
Dries committed
623 624 625 626 627
    'callback' => 'user_page', 'access' => TRUE, 'type' => MENU_CALLBACK);
  $items[] = array('path' => 'user/register', 'title' => t('register'),
    'callback' => 'user_page', 'access' => TRUE, 'type' => MENU_CALLBACK);
  $items[] = array('path' => 'user/password', 'title' => t('request new password'),
    'callback' => 'user_page', 'access' => TRUE, 'type' => MENU_CALLBACK);
Dries's avatar
 
Dries committed
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665

  $items[] = array('path' => 'admin/user', 'title' => t('users'),
    'callback' => 'user_admin', 'access' => $access);

  // Tabs:
  $items[] = array('path' => 'admin/user/create', 'title' => t('add user'),
    'callback' => 'user_admin', 'access' => $access,
    'type' => MENU_LOCAL_TASK);
  $items[] = array('path' => 'admin/user/configure', 'title' => t('configure'),
    'callback' => 'user_configure', 'access' => $access,
    'type' => MENU_LOCAL_TASK);
  if (module_exist('search')) {
    $items[] = array('path' => 'admin/user/search', 'title' => t('search'),
      'callback' => 'user_admin', 'access' => $access,
      'type' => MENU_LOCAL_TASK);
  }

  // Sub-tabs:
  $items[] = array('path' => 'admin/user/configure/settings', 'title' => t('settings'),
    'callback' => 'user_configure', 'access' => $access,
    'type' => MENU_LOCAL_SUBTASK);
  $items[] = array('path' => 'admin/user/configure/access', 'title' => t('access rules'),
    'callback' => 'user_configure', 'access' => $access,
    'type' => MENU_LOCAL_SUBTASK);
  $items[] = array('path' => 'admin/user/configure/access/mail', 'title' => t('e-mail rules'),
    'callback' => 'user_configure', 'access' => $access,
    'type' => MENU_LOCAL_SUBTASK);
  $items[] = array('path' => 'admin/user/configure/access/user', 'title' => t('name rules'),
    'callback' => 'user_configure', 'access' => $access,
    'type' => MENU_LOCAL_SUBTASK);
  $items[] = array('path' => 'admin/user/configure/role', 'title' => t('roles'),
    'callback' => 'user_configure', 'access' => $access,
    'type' => MENU_LOCAL_SUBTASK);
  $items[] = array('path' => 'admin/user/configure/permission', 'title' => t('permissions'),
    'callback' => 'user_configure', 'access' => $access,
    'type' => MENU_LOCAL_SUBTASK);

  return $items;
Dries's avatar
 
Dries committed
666 667
}

Dries's avatar
Dries committed
668 669 670
/**
 * Called by authentication modules in order to edit/view their authmap information.
 */
671
function user_get_authname($account, $module) {
Dries's avatar
 
Dries committed
672
  $result = db_query("SELECT authname FROM {authmap} WHERE uid = %d AND module = '%s'", $account->uid, $module);
673 674 675
  return db_result($result);
}

Dries's avatar
Dries committed
676 677 678 679
/**
 * Accepts an user object, $account, or a DA name and returns an associative
 * array of modules and DA names. Called at external login.
 */
680
function user_get_authmaps($authname = NULL) {
Dries's avatar
 
Dries committed
681
  $result = db_query("SELECT authname, module FROM {authmap} WHERE authname = '%s'", $authname);
Dries's avatar
 
Dries committed
682 683 684 685 686 687 688 689 690 691 692 693 694
  if (db_num_rows($result) > 0) {
    while ($authmap = db_fetch_object($result)) {
      $authmaps[$authmap->module] = $authmap->authname;
    }
    return $authmaps;
  }
  else {
    return 0;
  }
}

function user_set_authmaps($account, $authmaps) {
  foreach ($authmaps as $key => $value) {
Dries's avatar
Dries committed
695
    $module = explode('_', $key, 2);
Dries's avatar
 
Dries committed
696
    if ($value) {
Dries's avatar
Dries committed
697
      db_query("UPDATE {authmap} SET authname = '%s' WHERE uid = %d AND module = '%s'", $value, $account->uid, $module['1']);
Dries's avatar
 
Dries committed
698 699
      if (!db_affected_rows()) {
        db_query("INSERT INTO {authmap} (authname, uid, module) VALUES ('%s', %d, '%s')", $value, $account->uid, $module[1]);
Dries's avatar
 
Dries committed
700 701 702
      }
    }
    else {
Dries's avatar
Dries committed
703
      db_query("DELETE FROM {authmap} WHERE uid = %d AND module = '%s'", $account->uid, $module['1']);
Dries's avatar
 
Dries committed
704 705 706 707 708
    }
  }
}

function user_auth_help_links() {
709
  $links = array();
Dries's avatar
 
Dries committed
710
  foreach (module_list() as $module) {
Dries's avatar
Dries committed
711
    if (module_hook($module, 'auth')) {
Dries's avatar
 
Dries committed
712
      $links[] = l(module_invoke($module, 'info', 'name'), "user/help#$module");
Dries's avatar
 
Dries committed
713 714 715 716 717 718 719
    }
  }
  return $links;
}

/*** User features *********************************************************/

Dries's avatar
Dries committed
720
function user_login($edit = array(), $msg = '') {
Dries's avatar
 
Dries committed
721
  global $user, $base_url;
Dries's avatar
 
Dries committed
722

Dries's avatar
Dries committed
723
  // If we are already logged on, go to the user page instead.
Dries's avatar
 
Dries committed
724
  if ($user->uid) {
Dries's avatar
Dries committed
725
    drupal_goto('user');
Dries's avatar
 
Dries committed
726 727
  }

Dries's avatar
 
Dries committed
728
  if (user_deny('user', $edit['name'])) {
Dries's avatar
Dries committed
729
    $error = t('The name "%s" has been denied access.', array('%s' => $edit['name']));
Dries's avatar
 
Dries committed
730
  }
Dries's avatar
 
Dries committed
731
  else if ($edit['name'] && $edit['pass']) {
Dries's avatar
 
Dries committed
732

Dries's avatar
Dries committed
733
    // Try to log in the user locally:
Dries's avatar
 
Dries committed
734
    if (!$user->uid) {
Dries's avatar
 
Dries committed
735 736
      $name = $edit['name'];
      $pass = $edit['pass'];
Dries's avatar
Dries committed
737
      $user = user_load(array('name' => $name, 'pass' => $pass, 'status' => 1));
Dries's avatar
 
Dries committed
738 739
    }

Dries's avatar
Dries committed
740 741
    // Strip name and server from ID:
    if ($server = strrchr($edit['name'], '@')) {
Dries's avatar
 
Dries committed
742
      $name = substr($edit['name'], 0, strlen($edit['name']) - strlen($server));
743
      $server = substr($server, 1);
Dries's avatar
 
Dries committed
744
      $pass = $edit['pass'];
Dries's avatar
 
Dries committed
745
    }
Dries's avatar
 
Dries committed
746

Dries's avatar
Dries committed
747 748
    // When possible, determine corresponding external auth source. Invoke
    // source, and log in user if successful:
Dries's avatar
 
Dries committed
749
    if (!$user->uid && $server && $result = user_get_authmaps("$name@$server")) {
Dries's avatar
Dries committed
750
      if (module_invoke(key($result), 'auth', $name, $pass, $server)) {
Dries's avatar
 
Dries committed
751
        $user = user_external_load("$name@$server");
Dries's avatar
 
Dries committed
752
        watchdog('user', "external load: $name@$server, module: ". key($result));
Dries's avatar
 
Dries committed
753 754
      }
      else {
Dries's avatar
Dries committed
755
        $error = t('Invalid password for %s.', array('%s' => "<i>$name@$server</i>"));
Dries's avatar
 
Dries committed
756 757 758
      }
    }

Dries's avatar
Dries committed
759 760
    // Try each external authentication source in series. Register user if
    // successful.
Dries's avatar
 
Dries committed
761
    else if (!$user->uid && $server) {
Dries's avatar
 
Dries committed
762
      foreach (module_list() as $module) {
Dries's avatar
Dries committed
763 764 765
        if (module_hook($module, 'auth')) {
          if (module_invoke($module, 'auth', $name, $pass, $server)) {
            if (variable_get('user_register', 1) == 1 && !user_load(array('name' => "$name@$server"))) { // Register this new user.
Dries's avatar
 
Dries committed
766
              $user = user_save('', array('name' => "$name@$server", 'pass' => user_password(), 'init' => "$name@$server", 'status' => 1, "authname_$module" => "$name@$server", 'rid' => array(_user_authenticated_id())));
Dries's avatar
 
Dries committed
767
              watchdog('user', "new user: $name@$server ($module ID)", l(t('edit user'), "user/$user->uid/edit"));
Dries's avatar
 
Dries committed
768 769 770 771 772 773 774 775
              break;
            }
          }
        }
      }
    }

    if ($user->uid) {
Dries's avatar
Dries committed
776
      watchdog('user', 'session opened for "'. $user->name .'"');
Dries's avatar
 
Dries committed
777

Dries's avatar
Dries committed
778
      // Update the user table timestamp noting user has logged in.
Dries's avatar
 
Dries committed
779
      db_query("UPDATE {users} SET changed = '%d' WHERE uid = '%s'", time(), $user->uid);
Dries's avatar
 
Dries committed
780

Dries's avatar
Dries committed
781
      user_module_invoke('login', $edit, $user);
Dries's avatar
 
Dries committed
782

Dries's avatar
Dries committed
783 784
      // If the user wants to be remembered, set the proper cookie such
      // that the session won't expire.
Dries's avatar
 
Dries committed
785
      $path = preg_replace("/.+\/\/[^\/]+(.*)/", "\$1/", $base_url);
Dries's avatar
 
Dries committed
786
      setcookie(session_name(), session_id(), FALSE, $path);
Dries's avatar
 
Dries committed
787

Dries's avatar
Dries committed
788 789
      // Redirect the user to the page he logged on from.
      drupal_goto($edit['destination']);
Dries's avatar
 
Dries committed
790 791 792
    }
    else {
      if (!$error) {
Dries's avatar
Dries committed
793
        $error = t('Sorry.  Unrecognized username or password.') .' '. l(t('Have you forgotten your password?'), 'user/password');
Dries's avatar
 
Dries committed
794 795
      }
      if ($server) {
Dries's avatar
 
Dries committed
796
        watchdog('user', "failed login for '$name@$server': $error");
Dries's avatar
 
Dries committed
797 798
      }
      else {
Dries's avatar
 
Dries committed
799
        watchdog('user', "failed login for '$name': $error");
Dries's avatar
 
Dries committed
800 801 802 803
      }
    }
  }

Dries's avatar
Dries committed
804
  // Display error message (if any):
Dries's avatar
 
Dries committed
805
  if ($error) {
Dries's avatar
 
Dries committed
806
    drupal_set_message($error, 'error');
Dries's avatar
 
Dries committed
807 808
  }

Dries's avatar
Dries committed
809 810
  // Save the referrer.  We record where the user came from such that we
  // can redirect him after having completed the login form.
811
  if (empty($edit)) {
Dries's avatar
Dries committed
812
    $edit['destination'] = $_GET['q'];
Dries's avatar
 
Dries committed
813
  }
Dries's avatar
Dries committed
814
  $output .= form_hidden('destination', $edit['destination']);
Dries's avatar
 
Dries committed
815

Dries's avatar
Dries committed
816
  // Display login form:
Dries's avatar
 
Dries committed
817 818 819
  if ($msg) {
    $output .= "<p>$msg</p>";
  }
Dries's avatar
 
Dries committed
820
  if (count(user_auth_help_links()) > 0) {
Dries's avatar
Dries committed
821
    $output .= form_textfield(t('Username'), 'name', $edit['name'], 30, 64, t('Enter your %s username, or an ID from one of our affiliates: %a.', array('%s' => variable_get('site_name', 'local'), '%a' => implode(', ', user_auth_help_links()))));
Dries's avatar
 
Dries committed
822 823
  }
  else {
Dries's avatar
Dries committed
824
    $output .= form_textfield(t('Username'), 'name', $edit['name'], 30, 64, t('Enter your %s username.', array('%s' => variable_get('site_name', 'local'))));
Dries's avatar
 
Dries committed
825
  }
Dries's avatar
Dries committed
826 827 828 829 830
  $output .= form_password(t('Password'), 'pass', $pass, 30, 64, t('Enter the password that accompanies your username.'));
  $output .= form_submit(t('Log in'));
  $items[] = l(t('Request new password'), 'user/password');
  if (variable_get('user_register', 1)) {
    $items[] = l(t('Create new account'), 'user/register');
831
  }
Dries's avatar
Dries committed
832
  $output .= theme('item_list', $items);
Dries's avatar
 
Dries committed
833

Dries's avatar
 
Dries committed
834 835
  $output  = form_group(t('User login'), $output);

Dries's avatar
Dries committed
836
  return form($output, 'post', url('user/login'));
Dries's avatar
 
Dries committed
837 838
}

839
function _user_authenticated_id() {
Dries's avatar
 
Dries committed
840
  return db_result(db_query("SELECT rid FROM {role} WHERE name = 'authenticated user'"));
841 842
}

Dries's avatar
Dries committed
843 844 845
/**
 * Menu callback; logs the current user out, and redirects to the home page.
 */
Dries's avatar
 
Dries committed
846 847 848 849
function user_logout() {
  global $user;

  if ($user->uid) {
Dries's avatar
Dries committed
850
    watchdog('user', 'session closed for "'. $user->name .'"');
Dries's avatar
 
Dries committed
851

Dries's avatar
Dries committed
852
    // Destroy the current session:
Dries's avatar
 
Dries committed
853
    session_destroy();
Dries's avatar
 
Dries committed
854
    module_invoke_all('user', 'logout', NULL, $user);
Dries's avatar
 
Dries committed
855 856 857
    unset($user);
  }

Dries's avatar
Dries committed
858
  drupal_goto();
Dries's avatar
 
Dries committed
859 860 861
}

function user_pass($edit = array()) {
Dries's avatar
 
Dries committed
862 863
  global $base_url;

Dries's avatar
 
Dries committed
864
  if ($edit['name']) {
865
    $account = db_fetch_object(db_query("SELECT uid, name, mail FROM {users} WHERE status = 1 AND LOWER(name) = '%s'", strtolower($edit['name'])));
Dries's avatar
 
Dries committed
866
    if (!$account) form_set_error('name', t('Sorry. The username "<i>%s</i>" is not recognized.', array('%s' => $edit['name'])));
867
  }
Dries's avatar
 
Dries committed
868
  else if ($edit['mail']) {
869
    $account = db_fetch_object(db_query("SELECT uid, name, mail FROM {users} WHERE status = 1 AND LOWER(mail) = '%s'", strtolower($edit['mail'])));
Dries's avatar
 
Dries committed
870
    if (!$account) form_set_error('name', t('Sorry. The e-mail address "<i>%s</i>" is not recognized.', array('%s' => $edit['mail'])));
Kjartan's avatar
Kjartan committed
871 872
  }
  if ($account) {
Dries's avatar
 
Dries committed
873

Dries's avatar
Dries committed
874
      $from = variable_get('site_mail', ini_get('sendmail_from'));
Dries's avatar
 
Dries committed
875 876