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

/*** Common functions ******************************************************/

Dries's avatar
 
Dries committed
6 7 8 9
// we cannot use module_invoke because we need passing by reference
function user_module_invoke($type, &$array, &$user) {
  foreach (module_list() as $module) {
    $function = $module .'_user';
Dries's avatar
 
Dries committed
10
    if (function_exists($function)) $function($type, $array, $user);
Dries's avatar
 
Dries committed
11 12 13
  }
}

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

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

function user_load($array = array()) {
  /*
  ** Dynamically compose a SQL query:
  */

Dries's avatar
 
Dries committed
30 31
  $query = "";

Dries's avatar
 
Dries committed
32
  foreach ($array as $key => $value) {
Dries's avatar
 
Dries committed
33
    if ($key == 'pass') {
Kjartan's avatar
Kjartan committed
34
      $query .= "u.$key = '". md5($value) ."' AND ";
35
    }
Dries's avatar
 
Dries committed
36
    else {
Dries's avatar
 
Dries committed
37
      $query .= "u.$key = '". check_query($value) ."' AND ";
Dries's avatar
 
Dries committed
38 39
    }
  }
Dries's avatar
 
Dries committed
40
  $result = db_query_range("SELECT u.*, r.name AS role FROM {role} r INNER JOIN {users} u ON r.rid = u.rid WHERE $query u.status < 3", 0, 1);
Dries's avatar
 
Dries committed
41 42

  $user = db_fetch_object($result);
Dries's avatar
 
Dries committed
43 44
  $user = drupal_unpack($user);

Dries's avatar
 
Dries committed
45

Dries's avatar
 
Dries committed
46 47
  user_module_invoke("load", $array, $user);

Dries's avatar
 
Dries committed
48 49 50 51 52 53 54 55
  return $user;
}

function user_save($account, $array = array()) {
  /*
  ** Dynamically compose a SQL query:
  */

Kjartan's avatar
Kjartan committed
56
  $user_fields = user_fields();
Dries's avatar
 
Dries committed
57
  if ($account->uid) {
Dries's avatar
 
Dries committed
58 59
    user_module_invoke("update", $array, $account);

Dries's avatar
 
Dries committed
60
    $data = unserialize(db_result(db_query("SELECT data FROM {users} WHERE uid = %d", $account->uid)));
Dries's avatar
 
Dries committed
61
    foreach ($array as $key => $value) {
Dries's avatar
 
Dries committed
62
      if ($key == 'pass') {
Dries's avatar
 
Dries committed
63 64
        $query .= "$key = '%s', ";
        $v[] = md5($value);
Dries's avatar
 
Dries committed
65 66
      }
      else if (substr($key, 0, 4) !== "auth") {
Kjartan's avatar
Kjartan committed
67
        if (in_array($key, $user_fields)) {
Dries's avatar
 
Dries committed
68 69
          // escape '%'s:
          $value = str_replace("%", "%%", $value);
Dries's avatar
 
Dries committed
70 71
          $query .= "$key = '%s', ";
          $v[] = $value;
Dries's avatar
 
Dries committed
72 73 74 75
        }
        else {
          $data[$key] = $value;
        }
Dries's avatar
 
Dries committed
76 77
      }
    }
Dries's avatar
 
Dries committed
78 79
    $query .= "data = '%s', ";
    $v[] = serialize($data);
Dries's avatar
 
Dries committed
80

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

Dries's avatar
 
Dries committed
83
    $user = user_load(array('uid' => $account->uid));
Dries's avatar
 
Dries committed
84 85
  }
  else {
Dries's avatar
 
Dries committed
86 87
    $array['created'] = time();
    $array['changed'] = time();
Dries's avatar
 
Dries committed
88
    $array['uid'] = db_next_id("{users}_uid");
Dries's avatar
 
Dries committed
89 90

    foreach ($array as $key => $value) {
Dries's avatar
 
Dries committed
91
      if ($key == 'pass') {
Dries's avatar
 
Dries committed
92
        $fields[] = check_query($key);
Dries's avatar
 
Dries committed
93 94
        $values[] = md5($value);
        $s[] = "'%s'";
Dries's avatar
 
Dries committed
95 96
      }
      else if (substr($key, 0, 4) !== "auth") {
Kjartan's avatar
Kjartan committed
97
        if (in_array($key, $user_fields)) {
Dries's avatar
 
Dries committed
98
          $fields[] = check_query($key);
Dries's avatar
 
Dries committed
99 100
          $values[] = $value;
          $s[] = "'%s'";
Dries's avatar
 
Dries committed
101 102 103 104
        }
        else {
          $data[$key] = $value;
        }
Dries's avatar
 
Dries committed
105 106 107
      }
    }

Dries's avatar
 
Dries committed
108
    $fields[] = "data";
Dries's avatar
 
Dries committed
109 110
    $values[] = serialize($data);
    $s[] = "'%s'";
Dries's avatar
 
Dries committed
111

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

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

Dries's avatar
 
Dries committed
116
    module_invoke_all('user', 'insert', $array, $user);
Dries's avatar
 
Dries committed
117 118 119
  }

  foreach ($array as $key => $value) {
Dries's avatar
 
Dries committed
120
    if (substr($key, 0, 4) == 'auth') {
Dries's avatar
 
Dries committed
121 122 123 124 125
      $authmaps[$key] = $value;
    }
  }

  if ($authmaps) {
Dries's avatar
 
Dries committed
126
    user_set_authmaps($user, $authmaps);
Dries's avatar
 
Dries committed
127 128 129 130 131 132 133 134 135 136
  }

  return $user;
}

function user_validate_name($name) {
  /*
  ** Verify the syntax of the given name:
  */

Dries's avatar
 
Dries committed
137
  if (!$name) return t("You must enter a username.");
Dries's avatar
 
Dries committed
138 139
  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.");
Dries's avatar
 
Dries committed
140
  if (ereg('  ', $name)) return t("The username cannot contain multiple spaces in a row.");
Dries's avatar
 
Dries committed
141 142
  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.");
Dries's avatar
 
Dries committed
143
  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
144 145 146
}

function user_validate_mail($mail) {
Dries's avatar
 
Dries committed
147
  if (!$mail) return t("You must enter an e-mail address.");
Dries's avatar
 
Dries committed
148
  if ($mail && !valid_email_address($mail)) {
Dries's avatar
 
Dries committed
149
    return t("The e-mail address '%mail' is not valid.", array("%mail" => $mail));
Dries's avatar
 
Dries committed
150 151 152
  }
}

Dries's avatar
 
Dries committed
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
function user_validate_picture($file, &$edit, $user) {

  // initialize the picture:
  $edit['picture'] = $user->picture;

  // check that uploaded file is an image, with a maximum file size and maximum height/width
  $extension = strtolower(strrchr($file->name, "."));
  $size = getimagesize($file->path);
  list($maxwidth, $maxheight) = explode("x", variable_get('user_picture_dimensions', "85x85"));

  if ((!in_array($size[2], array(1, 2, 3))) || (!in_array($extension, array(".gif", ".jpg", ".png", ".jpeg")))) {
    $error = t("The uploaded file was not an image.");
  }
  else if ($file->size > (variable_get('user_picture_file_size', "30") * 1000)) {
    $error = t("The uploaded image is too large; the maximum file size is %a kB.", array("%a" => variable_get('user_picture_file_size', "30")));
  }
  else if ($size[0] > $maxwidth || $size[1] > $maxheight) {
    $error = t("The uploaded image is too large; the maximum dimensions are %a pixels.", array("%a" => variable_get('user_picture_dimensions', "85x85")));
  }
  else if ($file = file_save_upload('picture', variable_get('user_picture_path', "pictures") . FILE_SEPARATOR .'picture-'. $user->uid . $extension, 1)) {
    $edit['picture'] = $file->path;
  }
  else {
    $error = t("Failed to upload the picture image; the '%directory' directory doesn't exist.", array("%directory" => variable_get('user_picture_path', "pictures")));
  }

  return $error;
}

182
function user_validate_authmap($account, $authname, $module) {
Dries's avatar
 
Dries committed
183
  $result = db_query("SELECT COUNT(*) from {authmap} WHERE uid != %d AND authname = '%s'", $account->uid, $authname);
Dries's avatar
 
Dries committed
184
  if (db_result($result) > 0) {
Dries's avatar
 
Dries committed
185
    $name = module_invoke($module, 'info', 'name');
Dries's avatar
 
Dries committed
186 187
    return t("The %u ID %s is already taken.", array("%u" => ucfirst($name), "%s" => "<i>$authname</i>"));
  }
Dries's avatar
 
Dries committed
188 189
}

Dries's avatar
 
Dries committed
190
function user_password($length = 10) {
Dries's avatar
 
Dries committed
191
  /*
Dries's avatar
 
Dries committed
192
  ** Generate a random alphanumeric password.
Dries's avatar
 
Dries committed
193 194
  */

Dries's avatar
 
Dries committed
195 196 197 198 199 200 201 202 203
  // 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.
  $allowable_characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789";
  // We see how many characters are in the allowable list:
  $len = strlen($allowable_characters);

  // Seed the random number generator with the microtime stamp:
Dries's avatar
 
Dries committed
204
  mt_srand((double)microtime() * 1000000);
Dries's avatar
 
Dries committed
205 206 207 208 209 210 211 212 213 214 215 216 217

  // Declare the password as a blank string:
  $pass = "";

  // Loop the number of times specified by $length:
  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
218 219 220 221
}

function user_access($string) {
  global $user;
Dries's avatar
 
Dries committed
222
  static $perm = 0;
Dries's avatar
 
Dries committed
223

Dries's avatar
 
Dries committed
224
  // User #1 has all priveleges:
Dries's avatar
 
Dries committed
225 226 227 228
  if ($user->uid == 1) {
    return 1;
  }

Dries's avatar
 
Dries committed
229 230 231 232
  /*
  ** To reduce the number of SQL queries, we cache the user's permissions
  ** in a static variable.
  */
Dries's avatar
 
Dries committed
233

Dries's avatar
 
Dries committed
234 235
  if ($perm === 0) {
    $perm = db_result(db_query("SELECT p.perm FROM {role} r, {permission} p WHERE r.rid = p.rid AND r.rid = %d", $user->rid), 0);
Dries's avatar
 
Dries committed
236 237
  }

Dries's avatar
 
Dries committed
238
  return strstr($perm, $string);
Dries's avatar
 
Dries committed
239 240 241 242 243
}

function user_mail($mail, $subject, $message, $header) {
  if (variable_get("smtp_library", "") && file_exists(variable_get("smtp_library", ""))) {
    include_once variable_get("smtp_library", "");
244
    return user_mail_wrapper($mail, $subject, $message, $header);
Dries's avatar
 
Dries committed
245 246
  }
  else {
247 248 249 250 251 252 253
    /*
    ** 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
254 255 256 257 258 259 260 261 262 263 264 265
    **
    ** 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
    **
266
    */
Dries's avatar
 
Dries committed
267 268 269 270
    return mail(
      $mail,
      user_mail_encode($subject),
      str_replace("\r", "", $message),
Dries's avatar
 
Dries committed
271
      "MIME-Version: 1.0\nContent-Type: text/plain; charset=UTF-8; format=flowed\nContent-transfer-encoding: 8Bit\n" . $header
Dries's avatar
 
Dries committed
272
    );
Dries's avatar
 
Dries committed
273 274 275
  }
}

Kjartan's avatar
Kjartan committed
276 277 278 279 280
function user_mail_encode($string, $charset = "UTF-8") {
  /*
  ** Used to encodes mail headers that contain non US- ASCII
  ** characters.
  ** http://www.rfc-editor.org/rfc/rfc2047.txt
Kjartan's avatar
Kjartan committed
281 282
  **
  ** Notes:
283
  **   - Only encode strings that contain non-ASCII characters.
Kjartan's avatar
Kjartan committed
284 285 286 287 288 289
  **   - 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
290
  */
291 292 293 294 295 296
  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
297
  return $string;
Dries's avatar
 
Dries committed
298 299
}

Dries's avatar
 
Dries committed
300
function user_deny($type, $mask) {
Dries's avatar
 
Dries committed
301 302
  $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
303

Dries's avatar
 
Dries committed
304
  return $deny && !$allow;
Dries's avatar
 
Dries committed
305 306
}

Dries's avatar
 
Dries committed
307 308
function user_fields() {
  static $fields;
Dries's avatar
 
Dries committed
309

Dries's avatar
 
Dries committed
310
  if (!$fields) {
Dries's avatar
 
Dries committed
311
    $result = db_query("SELECT * FROM {users} WHERE uid = 1");
Kjartan's avatar
Kjartan committed
312 313 314
    if (db_num_rows($result)) {
      $fields = array_keys(db_fetch_array($result));
    }
Dries's avatar
 
Dries committed
315 316
    else {
      // Make sure we return the default fields at least
Dries's avatar
 
Dries committed
317
      $fields = array('uid', 'name', 'pass', "mail", "picture", "mode", "sort", "threshold", "theme", "signature", "created", "changed", "status", "timezone", "language", "init", "data", "rid");
Dries's avatar
 
Dries committed
318
    }
Dries's avatar
 
Dries committed
319
  }
Dries's avatar
 
Dries committed
320

Dries's avatar
 
Dries committed
321
  return $fields;
Dries's avatar
 
Dries committed
322 323
}

Dries's avatar
 
Dries committed
324 325 326
/*** Module hooks **********************************************************/

function user_perm() {
Dries's avatar
 
Dries committed
327
  return array("administer users", "access user list");
Dries's avatar
 
Dries committed
328 329
}

Dries's avatar
 
Dries committed
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
function user_file_download($file) {
  if (strpos($file, variable_get('user_picture_path', "pictures") . FILE_SEPARATOR . 'picture-') === 0) {
    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
355
function user_search($keys) {
Dries's avatar
 
Dries committed
356
  $find = array();
357 358 359 360

  // Replace wildcards with mysql wildcards
  $keys = str_replace("*", "%", $keys);

Dries's avatar
 
Dries committed
361
  $result = db_query_range("SELECT * FROM {users} WHERE name LIKE '%%%s%%'", $keys, 0, 20);
Dries's avatar
 
Dries committed
362
  while ($account = db_fetch_object($result)) {
Dries's avatar
 
Dries committed
363
    $find[] = array("title" => $account->name, "link" => (strstr(request_uri(), "admin") ? url("admin/user/edit/$account->uid") : url("user/view/$account->uid")), 'user' => $account->name);
Dries's avatar
 
Dries committed
364
  }
Dries's avatar
 
Dries committed
365
  return array(t("Matching users"), $find);
Dries's avatar
 
Dries committed
366 367
}

Dries's avatar
Dries committed
368
function user_user($type, &$edit, &$user) {
Dries's avatar
Dries committed
369
  if ($type == 'view') {
Dries's avatar
Dries committed
370
    return array(t('History') => form_item(t('Member for'), format_interval(time() - $user->created)));
Dries's avatar
Dries committed
371 372 373
  }
}

Dries's avatar
 
Dries committed
374
function user_block($op = "list", $delta = 0) {
Dries's avatar
 
Dries committed
375 376
  global $user;

Dries's avatar
 
Dries committed
377
  if ($op == "list") {
Dries's avatar
 
Dries committed
378 379 380 381
     $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");
382

383
     return $blocks;
384 385
  }
  else {
Dries's avatar
 
Dries committed
386 387
    $block = array();

Dries's avatar
 
Dries committed
388 389
    switch ($delta) {
      case 0:
Dries's avatar
 
Dries committed
390

391
        if (!$user->uid) {
Dries's avatar
 
Dries committed
392 393 394 395 396
          /*
          ** For usability's sake, avoid showing two login forms on one
          ** page.
          */

Dries's avatar
 
Dries committed
397
          if (arg(0) == 'user' && arg(1) != "view") {
Dries's avatar
 
Dries committed
398 399 400
            return;
          }

Dries's avatar
 
Dries committed
401 402
          $edit = $_POST["edit"];

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

405
          /*
Dries's avatar
Dries committed
406 407
          ** Save the referer.  We record where the user came from such
          ** that we/ can redirect him after having completed the login
408 409
          ** form.
          */
Dries's avatar
Dries committed
410

411
          if (empty($edit)) {
Dries's avatar
Dries committed
412
            $edit["destination"] = $_GET["q"];
413 414
          }
          // 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.
Dries's avatar
Dries committed
415

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

Dries's avatar
 
Dries committed
422 423
          $output  = form($output, "post", url("user/login"));

Dries's avatar
 
Dries committed
424
          if (variable_get("user_register", 1)) {
Dries's avatar
 
Dries committed
425
            $items[] = l(t("Create new account"), "user/register", array("title" => t("Create a new user account.")));
Dries's avatar
 
Dries committed
426
          }
Dries's avatar
 
Dries committed
427
          $items[] = l(t("Request new password"), "user/password", array("title" => t("Request new password via e-mail.")));
Dries's avatar
 
Dries committed
428

Dries's avatar
 
Dries committed
429
          $output .= theme("item_list", $items);
430

Dries's avatar
 
Dries committed
431
          $block["subject"] = t("User login");
Dries's avatar
 
Dries committed
432
          $block["content"] = $output;
Dries's avatar
 
Dries committed
433
        }
Dries's avatar
Dries committed
434
        return $block;
435
      case 1:
Dries's avatar
 
Dries committed
436 437
        if ($menu = menu_tree()) {
           $block["subject"] = $user->uid ? $user->name : t("Navigation");
Dries's avatar
 
Dries committed
438
           $block["content"] = "<div class=\"menu\">". $menu ."</div>";
Dries's avatar
 
Dries committed
439
        }
440
        return $block;
Dries's avatar
 
Dries committed
441
      case 2:
442 443 444
        if (user_access("access content")) {
          $result = db_query_range("SELECT uid, name FROM {users} WHERE status != '0' ORDER BY uid DESC", 0, 5);
          while ($account = db_fetch_object($result)) {
445
            $items[] = format_name($account);
446
          }
Dries's avatar
 
Dries committed
447

Dries's avatar
 
Dries committed
448
          $output = theme("user_list", $items);
Dries's avatar
 
Dries committed
449

450 451 452 453
          $block["subject"] = t("Who's new");
          $block["content"] = $output;
          return $block;
        }
Dries's avatar
 
Dries committed
454 455
      case 3:
        if (user_access("access content")) {
Dries's avatar
 
Dries committed
456 457
          /* count users with activity in the past defined period */
          $time_period = variable_get("user_block_seconds_online", 2700);
Dries's avatar
 
Dries committed
458

Dries's avatar
 
Dries committed
459 460 461
          /* 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
462
          $total_users = db_num_rows($users);
Dries's avatar
 
Dries committed
463 464 465 466

          /* format the output with proper grammar */
          if ($total_users == 1 && $guests->count == 1) {
            $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
467 468
          }
          else {
Dries's avatar
 
Dries committed
469 470 471 472
            $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")));
          }

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

Dries's avatar
 
Dries committed
474
            // Display a list of currently online users
Dries's avatar
 
Dries committed
475
            $max_users = variable_get("user_block_max_list_count", 10);
Dries's avatar
 
Dries committed
476 477
            if ($max_users) {
              $items = array();
Dries's avatar
 
Dries committed
478

Dries's avatar
 
Dries committed
479
              while ($max_users-- && $uid = db_fetch_object($users)) {
Dries's avatar
 
Dries committed
480
                $items[] = format_name(user_load(array('uid' => $uid->uid)));
Dries's avatar
 
Dries committed
481 482 483
              }

              if ($items) {
Dries's avatar
 
Dries committed
484 485 486
                if (db_fetch_object($users)) {
                  $items[] = "...";
                }
Dries's avatar
 
Dries committed
487 488
                $output .= theme("item_list", $items, t("Online users:"));
              }
Dries's avatar
 
Dries committed
489
            }
Dries's avatar
 
Dries committed
490
          }
Dries's avatar
 
Dries committed
491 492
          $block["subject"] = t("Who's online");
          $block["content"] = $output;
Dries's avatar
 
Dries committed
493
        }
Dries's avatar
 
Dries committed
494
        return $block;
Dries's avatar
 
Dries committed
495 496
    }
  }
497 498
}

Dries's avatar
 
Dries committed
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518
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) {
      $picture = "<img src=\"$picture\" alt=\"" . t("%user's picture", array("%user" => $account->name ? $account->name : t(variable_get("anonymous", "Anonymous")))) . "\" />";
      if ($account->uid) {
        $picture = l($picture, "user/view/$account->uid", array("title" => t("View user profile.")));
      }

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

Dries's avatar
Dries committed
519
function theme_user_profile($account, $fields) {
Dries's avatar
 
Dries committed
520 521
  $output = "<div class=\"profile\">\n";
  $output .= theme('user_picture', $account);
Dries's avatar
Dries committed
522 523 524
  foreach ($fields as $category => $value) {
    $output .= "<h2>$category</h2>$value";
  }
Dries's avatar
 
Dries committed
525 526 527 528 529 530 531 532 533 534

  if (user_access("administer users")) {
    $output .= form_item(t("Administration"), l(t("edit account"), "admin/user/edit/$account->uid"));
  }

  $output .= "</div>\n";

  return $output;
}

Dries's avatar
 
Dries committed
535
function theme_user_list($items, $title = NULL) {
Dries's avatar
 
Dries committed
536
  return theme("item_list", $items, $title);
Dries's avatar
 
Dries committed
537 538
}

Dries's avatar
 
Dries committed
539 540 541
/**
 * Implementation of hook_link().
 */
Dries's avatar
 
Dries committed
542
function user_link($type) {
Dries's avatar
 
Dries committed
543
  global $user;
Dries's avatar
 
Dries committed
544

Dries's avatar
 
Dries committed
545
  if ($type == 'system') {
546 547 548 549 550 551 552 553 554
    if ($user->uid) {
      menu('user', t('my account'), 'user_page', 0);
      menu('user/edit', t('edit account'), 'user_page', 0);
      menu('logout', t('log out'), 'user_logout', 10);
    }
    else {
      menu('user', t('user'), 'user_page', 0, MENU_HIDE);
      menu('user/edit', t('edit account'), MENU_DENIED);
      menu('logout', t('log out'), MENU_DENIED);
Dries's avatar
 
Dries committed
555
    }
Dries's avatar
 
Dries committed
556 557 558 559 560 561 562 563 564 565 566 567 568

    $access = user_access('administer users');
    menu('admin/user', t('accounts'), $access ? 'user_admin' : MENU_DENIED, 2);
    menu('admin/user/create', t('new user'), $access ? 'user_admin' : MENU_DENIED, 1);
    menu('admin/user/access', t('access rules'), $access ? 'user_admin' : MENU_DENIED, 3);
    menu('admin/user/access/mail', t('e-mail rules'), $access ? 'user_admin' : MENU_DENIED);
    menu('admin/user/access/user', t('name rules'), $access ? 'user_admin' : MENU_DENIED);
    menu('admin/user/role', t('roles'), $access ? 'user_admin' : MENU_DENIED, 4);
    menu('admin/user/permission', t('permissions'), $access ? 'user_admin' : MENU_DENIED, 5);
    menu('admin/user/help', t('help'), $access ? 'user_help_page' : MENU_DENIED, 9);
    menu('admin/user/edit', t('edit user account'), $access ? 'user_admin' : MENU_DENIED, 0, MENU_HIDE, MENU_LOCKED);
    if (module_exist('search')) {
      menu('admin/user/search', t('search'), $access ? 'user_admin' : MENU_DENIED, 8);
Dries's avatar
 
Dries committed
569
    }
Dries's avatar
 
Dries committed
570 571 572 573 574
  }
}

/*** Authentication methods ************************************************/

575
function user_get_authname($account, $module) {
Dries's avatar
 
Dries committed
576 577

  /*
578
  **  Called by authentication modules in order to edit/view their authmap information.
Dries's avatar
 
Dries committed
579 580
  */

Dries's avatar
 
Dries committed
581
  $result = db_query("SELECT authname FROM {authmap} WHERE uid = %d AND module = '%s'", $account->uid, $module);
582 583 584
  return db_result($result);
}

Dries's avatar
 
Dries committed
585

586 587 588 589 590 591 592
function user_get_authmaps($authname = NULL) {

  /*
  ** Accepts an user object, $account, or an DA name and returns an
  ** associtive array of modules and DA names. Called at external login.
  */

Dries's avatar
 
Dries committed
593
  $result = db_query("SELECT authname, module FROM {authmap} WHERE authname = '%s'", $authname);
Dries's avatar
 
Dries committed
594 595 596 597 598 599 600 601 602 603 604 605 606 607 608
  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) {
    $module = explode("_", $key, 2);
    if ($value) {
Dries's avatar
 
Dries committed
609 610 611
      db_query("UPDATE {authmap} SET authname = '%s' WHERE uid = %d AND module = '%s'", $value, $account->uid, $module["1"]);
      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
612 613 614
      }
    }
    else {
Dries's avatar
 
Dries committed
615
      db_query("DELETE FROM {authmap} WHERE uid = %d AND module = '%s'", $account->uid, $module["1"]);
Dries's avatar
 
Dries committed
616 617 618 619 620
    }
  }
}

function user_auth_help_links() {
621
  $links = array();
Dries's avatar
 
Dries committed
622
  foreach (module_list() as $module) {
Dries's avatar
 
Dries committed
623
    if (module_hook($module, "auth")) {
Dries's avatar
 
Dries committed
624
      $links[] = l(module_invoke($module, 'info', 'name'), "user/help#$module");
Dries's avatar
 
Dries committed
625 626 627 628 629 630 631
    }
  }
  return $links;
}

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

Dries's avatar
 
Dries committed
632
function user_login($edit = array(), $msg = "") {
Dries's avatar
 
Dries committed
633
  global $user, $base_url;
Dries's avatar
 
Dries committed
634 635 636 637 638 639

  /*
  ** If we are already logged on, go to the user page instead.
  */

  if ($user->uid) {
Dries's avatar
Dries committed
640
    drupal_goto('user');
Dries's avatar
 
Dries committed
641 642
  }

Dries's avatar
 
Dries committed
643 644
  if (user_deny('user', $edit['name'])) {
    $error = t("The name '%s' has been denied access.", array("%s" => $edit['name']));
Dries's avatar
 
Dries committed
645
  }
Dries's avatar
 
Dries committed
646
  else if ($edit['name'] && $edit['pass']) {
Dries's avatar
 
Dries committed
647 648

    /*
Dries's avatar
 
Dries committed
649
    ** Try to log in the user locally:
Dries's avatar
 
Dries committed
650 651
    */

Dries's avatar
 
Dries committed
652
    if (!$user->uid) {
Dries's avatar
 
Dries committed
653 654 655
      $name = $edit['name'];
      $pass = $edit['pass'];
      $user = user_load(array('name' => $name, 'pass' => $pass, "status" => 1));
Dries's avatar
 
Dries committed
656 657 658 659 660 661
    }

    /*
    ** Strip name and server from ID:
    */

Dries's avatar
 
Dries committed
662 663
    if ($server = strrchr($edit['name'], "@")) {
      $name = substr($edit['name'], 0, strlen($edit['name']) - strlen($server));
664
      $server = substr($server, 1);
Dries's avatar
 
Dries committed
665
      $pass = $edit['pass'];
Dries's avatar
 
Dries committed
666
    }
Dries's avatar
 
Dries committed
667

Dries's avatar
 
Dries committed
668
    /*
Dries's avatar
 
Dries committed
669
    ** When possible, determine corresponding external auth source. Invoke
Dries's avatar
 
Dries committed
670
    ** source, and login user if successful:
Dries's avatar
 
Dries committed
671 672
    */

Dries's avatar
 
Dries committed
673
    if (!$user->uid && $server && $result = user_get_authmaps("$name@$server")) {
Dries's avatar
 
Dries committed
674 675
      if (module_invoke(key($result), "auth", $name, $pass, $server)) {
        $user = user_external_load("$name@$server");
Dries's avatar
 
Dries committed
676
        watchdog('user', "external load: $name@$server, module: ". key($result));
Dries's avatar
 
Dries committed
677 678
      }
      else {
Dries's avatar
 
Dries committed
679
        $error = t("Invalid password for %s.", array("%s" => "<i>$name@$server</i>"));
Dries's avatar
 
Dries committed
680 681 682
      }
    }

Dries's avatar
 
Dries committed
683
    /*
Dries's avatar
 
Dries committed
684
    ** Try each external authentication source in series. Register user if
Dries's avatar
 
Dries committed
685
    ** successful.
Dries's avatar
 
Dries committed
686 687
    */

Dries's avatar
 
Dries committed
688
    else if (!$user->uid && $server) {
Dries's avatar
 
Dries committed
689 690 691
      foreach (module_list() as $module) {
        if (module_hook($module, "auth")) {
          if (module_invoke($module, "auth", $name, $pass, $server)) {
Dries's avatar
 
Dries committed
692 693 694
            if (variable_get("user_register", 1) == 1 && !user_load(array('name' => "$name@$server"))) { //register this new user
              $user = user_save("", array('name' => "$name@$server", 'pass' => user_password(), "init" => "$name@$server", "status" => 1, "authname_$module" => "$name@$server", "rid" => _user_authenticated_id()));
              watchdog('user', "new user: $name@$server ($module ID)", l(t("edit user"), "admin/user/edit/$user->uid"));
Dries's avatar
 
Dries committed
695 696 697 698 699 700 701 702
              break;
            }
          }
        }
      }
    }

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

Dries's avatar
 
Dries committed
705
      // update the user table timestamp noting user has logged in
Dries's avatar
 
Dries committed
706
      db_query("UPDATE {users} SET changed = '%d' WHERE uid = '%s'", time(), $user->uid);
Dries's avatar
 
Dries committed
707

Dries's avatar
 
Dries committed
708 709
      user_module_invoke("login", $edit, $user);

Dries's avatar
 
Dries committed
710 711 712 713 714
      /*
      ** If the user wants to be remembered, set the proper cookie such
      ** that the session won't expire.
      */

Dries's avatar
 
Dries committed
715
      $path = preg_replace("/.+\/\/[^\/]+(.*)/", "\$1/", $base_url);
Dries's avatar
 
Dries committed
716
      setcookie(session_name(), session_id(), FALSE, $path);
Dries's avatar
 
Dries committed
717 718

      /*
Dries's avatar
 
Dries committed
719
      ** Redirect the user to the page he logged on from.
Dries's avatar
 
Dries committed
720 721
      */

Dries's avatar
 
Dries committed
722
      drupal_goto($edit["destination"]);
Dries's avatar
 
Dries committed
723 724 725
    }
    else {
      if (!$error) {
Dries's avatar
 
Dries committed
726
        $error = t("Sorry.  Unrecognized username or password.") ." ". l(t("Have you forgotten your password?"), "user/password");
Dries's avatar
 
Dries committed
727 728
      }
      if ($server) {
Dries's avatar
 
Dries committed
729
        watchdog('user', "failed login for '$name@$server': $error");
Dries's avatar
 
Dries committed
730 731
      }
      else {
Dries's avatar
 
Dries committed
732
        watchdog('user', "failed login for '$name': $error");
Dries's avatar
 
Dries committed
733 734 735 736 737 738 739 740 741
      }
    }
  }

  /*
  ** Display error message (if any):
  */

  if ($error) {
Dries's avatar
 
Dries committed
742
    drupal_set_message($error, 'error');
Dries's avatar
 
Dries committed
743 744
  }

Dries's avatar
 
Dries committed
745
  /*
Dries's avatar
 
Dries committed
746
  ** Save the referrer.  We record where the user came from such that we
Dries's avatar
 
Dries committed
747 748 749
  ** can redirect him after having completed the login form.
  */

750
  if (empty($edit)) {
Dries's avatar
Dries committed
751
    $edit["destination"] = $_GET["q"];
Dries's avatar
 
Dries committed
752 753 754
  }
  $output .= form_hidden("destination", $edit["destination"]);

Dries's avatar
 
Dries committed
755 756 757 758
  /*
  ** Display login form:
  */

Dries's avatar
 
Dries committed
759 760 761
  if ($msg) {
    $output .= "<p>$msg</p>";
  }
Dries's avatar
 
Dries committed
762
  if (count(user_auth_help_links()) > 0) {
Dries's avatar
 
Dries committed
763
    $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
764 765
  }
  else {
Dries's avatar
 
Dries committed
766
    $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
767
  }
Dries's avatar
 
Dries committed
768
  $output .= form_password(t("Password"), 'pass', $pass, 30, 64, t("Enter the password that accompanies your username."));
Dries's avatar
 
Dries committed
769
  $output .= form_submit(t("Log in"));
Dries's avatar
 
Dries committed
770
  $items[] = l(t("Request new password"), "user/password");
771
  if (variable_get("user_register", 1)) {
Dries's avatar
 
Dries committed
772
    $items[] = l(t("Create new account"), "user/register");
773
  }
Dries's avatar
 
Dries committed
774
  $output .= theme("item_list", $items);
Dries's avatar
 
Dries committed
775

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

778
  return form($output, "post", url('user/login'));
Dries's avatar
 
Dries committed
779 780
}

781
function _user_authenticated_id() {
Dries's avatar
 
Dries committed
782
  return db_result(db_query("SELECT rid FROM {role} WHERE name = 'authenticated user'"));
783 784
}

Dries's avatar
 
Dries committed
785 786 787 788
function user_logout() {
  global $user;

  if ($user->uid) {
Dries's avatar
 
Dries committed
789
    watchdog('user', "session closed for '$user->name'");
Dries's avatar
 
Dries committed
790 791 792 793 794 795

    /*
    ** Destroy the current session:
    */

    session_destroy();
Dries's avatar
 
Dries committed
796
    module_invoke_all('user', 'logout', NULL, $user);
Dries's avatar
 
Dries committed
797 798 799
    unset($user);
  }

Dries's avatar
Dries committed
800
  drupal_goto();
Dries's avatar
 
Dries committed
801 802 803
}

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

Dries's avatar
 
Dries committed
806 807 808
  if ($edit['name']) {
    $account = db_fetch_object(db_query("SELECT uid, name, mail FROM {users} WHERE status = 1 AND name = '%s'", $edit['name']));
    if (!$account) $error = t("Sorry. The username <i>%s</i> is not recognized.", array("%s" => $edit['name']));
809
  }
Dries's avatar
 
Dries committed
810 811 812
  else if ($edit['mail']) {
    $account = db_fetch_object(db_query("SELECT uid, name, mail FROM {users} WHERE status = 1 AND mail = '%s'", $edit['mail']));
    if (!$account) $error = t("Sorry. The e-mail address <i>%s</i> is not recognized.", array("%s" => $edit['mail']));
Kjartan's avatar
Kjartan committed
813 814
  }
  if ($account) {
Dries's avatar
 
Dries committed
815

816
      $from = variable_get("site_mail", ini_get("sendmail_from"));
Dries's avatar
 
Dries committed
817 818 819 820 821 822
      $pass = user_password();

      /*
      ** Save new password:
      */

Dries's avatar
 
Dries committed
823
      user_save($account, array('pass' => $pass));
Dries's avatar
 
Dries committed
824 825 826 827 828

      /*
      ** Mail new password:
      */

Dries's avatar
Dries committed
829
      $variables = array("%username" => $account->name, "%site" => variable_get("site_name", "drupal"), "%password" => $pass, "%uri" => $base_url, "%uri_brief" => substr($base_url, strlen("http://")), "%mailto" => $account->mail, "%date" => format_date(time()), '%login_uri' => url('user/login', NULL, NULL, TRUE), '%edit_uri' => url('user/edit', NULL, NULL, TRUE));
Dries's avatar
 
Dries committed
830 831
      $subject = _user_mail_text("pass_subject", $variables);
      $body = _user_mail_text("pass_body", $variables);
832
      $headers = "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from";
Dries's avatar
 
Dries committed
833
      $mail_success = user_mail($account->mail, $subject, $body, $headers);
Dries's avatar
 
Dries committed
834

Dries's avatar
 
Dries committed
835
      if ($mail_success) {
Dries's avatar
 
Dries committed
836
        watchdog('user', "mail password: '". $account->name ."' &lt;". $account->mail ."&gt;");
Dries's avatar
 
Dries committed
837 838 839
        return t("Your password and further instructions have been sent to your e-mail address.");
      }
      else {
Dries's avatar
 
Dries committed
840
        watchdog('error', "error mailing new password: '". $account->name ."' &lt;". $account->mail ."&gt;");
Dries's avatar
 
Dries committed
841 842
        return t("Unable to send mail. Please contact the site admin.");
      }
Dries's avatar
 
Dries committed
843 844
    }
    else {
845

Kjartan's avatar
Kjartan committed
846 847
    // Display error message if necessary.
    if ($error) {
Dries's avatar
 
Dries committed
848
      drupal_set_message($error, 'error');
Dries's avatar
 
Dries committed
849 850 851 852 853 854
    }

    /*
    ** Display form:
    */

Dries's avatar
 
Dries committed
855
    $output .= "<p>". t("Enter your username <strong><em>or</em></strong> your e-mail address.") ."</p>";
Dries's avatar
 
Dries committed
856 857
    $output .= form_textfield(t("Username"), 'name', $edit['name'], 30, 64);
    $output .= form_textfield(t("E-mail address"), "mail", $edit['mail'], 30, 64);
Dries's avatar
 
Dries committed
858
    $output .= form_submit(t("E-mail new password"));
Dries's avatar
 
Dries committed
859
    $items[] = l(t("Log in"), "user/login");
860
    if (variable_get("user_register", 1)) {
Dries's avatar
 
Dries committed
861
      $items[] = l(t("Create new account"), "user/register");
862
    }
Dries's avatar
 
Dries committed
863
    $output .= theme("item_list", $items);
Dries's avatar
 
Dries committed
864
    $output  = form_group(t('Request new password'), $output);
865
    return form($output, "post", url('user/password'));
Dries's avatar
 
Dries committed
866 867 868 869
  }
}

function user_register($edit = array()) {
Dries's avatar
 
Dries committed
870
  global $user, $base_url;
871 872 873 874 875 876

  /*
  ** If we are already logged on, go to the user page instead.
  */

  if ($user->uid) {
Dries's avatar
Dries committed
877
    drupal_goto("user/edit");
878
  }
Dries's avatar
 
Dries committed
879

Dries's avatar
 
Dries committed
880 881
  if (!(is_null($edit['name']) && is_null($edit['mail']))) {
    if ($error = user_validate_name($edit['name'])) {
Dries's avatar
 
Dries committed
882 883
      // do nothing
    }
Dries's avatar
 
Dries committed
884
    else if ($error = user_validate_mail($edit['mail'])) {
Dries's avatar
 
Dries committed
885 886
      // do nothing
    }
Dries's avatar
 
Dries committed
887 888
    else if (user_deny('user', $edit['name'])) {
      $error = t("The name '%s' has been denied access.", array("%s" => $edit['name']));
Dries's avatar
 
Dries committed
889
    }
Dries's avatar
 
Dries committed
890 891
    else if (user_deny("mail", $edit['mail'])) {
      $error = t("The e-mail address '%s' has been denied access.", array("%s" => $edit['mail']));
Dries's avatar
 
Dries committed
892
    }
Dries's avatar
 
Dries committed
893 894
    else if (db_num_rows(db_query("SELECT name FROM {users} WHERE LOWER(name) = LOWER('%s')", $edit['name'])) > 0) {
      $error = t("The name '%s' is already taken.", array("%s" => $edit['name']));
Dries's avatar
 
Dries committed
895
    }
Dries's avatar
 
Dries committed
896 897
    else if (db_num_rows(db_query("SELECT mail FROM {users} WHERE LOWER(mail) = LOWER('%s') OR LOWER(init) = LOWER('%s')", $edit['mail'], $edit['mail'])) > 0) {
      $error = t("The e-mail address '%s' is already taken.", array("%s" => $edit['mail']));
Dries's avatar
 
Dries committed
898
    }
Dries's avatar
 
Dries committed
899
    else if (variable_get("user_register", 1) == 0) {
Dries's avatar
 
Dries committed
900 901
      $error = t("Public registrations have been disabled by the site administrator.");
    }
902
    else {
903 904 905 906 907 908 909 910 911 912 913 914 915 916 917
      foreach (module_list() as $module) {
        if (module_hook($module, 'user')) {
          $result = module_invoke($module, 'user', 'validate', $edit, $user);
          if (is_array($result)) {
            $data = array_merge($data, $result);
          }
          elseif (is_string($result)) {
            $error = $result;
            break;
          }
        }
      }
      if (!$error) {
        $success = true;
      }
918
    }
Dries's avatar
 
Dries committed
919 920 921 922
  }

  if ($success) {

923
    $from = variable_get("site_mail", ini_get("sendmail_from"));
Dries's avatar
 
Dries committed
924 925
    $pass = user_password();

926 927
    // TODO: is this necessary? Won't session_write replicate this?
    unset($edit["session"]);
Dries's avatar
 
Dries committed
928 929
    $account = user_save("", array_merge(array('name' => $edit['name'], 'pass' => $pass, "init" => $edit['mail'], "mail" => $edit['mail'], "rid" => _user_authenticated_id(), "status" => (variable_get("user_register", 1) == 1 ? 1 : 0)), $data));
    watchdog('user', "new user: '". $edit['name'] ."' &lt;". $edit['mail'] ."&gt;", l(t("edit user"), "admin/user/edit/$account->uid"));
Dries's avatar
 
Dries committed
930

Dries's avatar
Dries committed
931
    $variables = array("%username" => $edit['name'], "%site" => variable_get("site_name", "drupal"), "%password" => $pass, "%uri" => $base_url, "%uri_brief" => substr($base_url, strlen("http://")), "%mailto" => $edit['mail'], "%date" => format_date(time()), "%login_uri" => url('user/login', NULL, NULL, TRUE), "%edit_uri" => url("user/edit", NULL, NULL, TRUE));
932

Dries's avatar
 
Dries committed
933
    //the first user may login immediately, and receives a customized welcome e-mail.
934
    if ($account->uid == 1) {
Dries's avatar
 
Dries committed
935
      user_mail($edit['mail'], t("drupal user account details for %s", array