user.module 87.8 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
546
547
548
549
550
551
552
553
554
  if ($type == 'system') {
    $access = $user->uid;
    menu('user', t('my account'), $access ? 'user_page' : MENU_DENIED, 8);
    menu('user/edit', t('edit account'), $access ? 'user_page' : MENU_DENIED, 0);
    menu('logout', t('log out'), $access ? 'user_logout' : MENU_DENIED, 10);

    if (!$user->uid) {
      menu('user/login', t('log in'), 'user_page', 0, MENU_HIDE);
      menu('user/password', t('e-mail new password'), 'user_page', 0, MENU_HIDE);
      menu('user/register', t('create new account'), 'user_page', 0, MENU_HIDE);
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
903
904
    else {
      $success = true;
    }
Dries's avatar
   
Dries committed
905
906
907
908
  }

  if ($success) {

909
    $from = variable_get("site_mail", ini_get("sendmail_from"));
Dries's avatar
   
Dries committed
910
911
    $pass = user_password();

912
913
    // TODO: is this necessary? Won't session_write replicate this?
    unset($edit["session"]);
Dries's avatar
   
Dries committed
914
915
    $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
916

Dries's avatar
Dries committed
917
    $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));
918

Dries's avatar
   
Dries committed
919
    //the first user may login immediately, and receives a customized welcome e-mail.
920
    if ($account->uid == 1) {
Dries's avatar
   
Dries committed
921
      user_mail($edit['mail'], t("drupal user account details for %s", array("%s" => $edit['name'])), strtr(t("%username,\n\nYou may now login to %uri using the following username and password:\n\n  username: %username\n  password: %password\n\n%edit_uri\n\n--drupal"), $variables), "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");
922
      // This should not be t()'ed. No point as its only shown once in the sites lifetime, and it would be bad to store the password
923
      $output .= "<p>Welcome to Drupal. You are user #1, which gives you full and immediate access.  All future registrants will receive their passwords via e-mail, so please configure your e-mail settings using the Administration pages.</p><p> Your password is <strong>$pass</strong>. You may change your password on the next page.</p><p>Please login below.</p>";
Dries's avatar
Dries committed
924
      $output .= form_hidden("destination", "user/edit");
Dries's avatar
   
Dries committed
925
926
      $output .= form_hidden('name', $account->name);
      $output .= form_hidden('pass', $pass);
927
928
929
930
      $output .= form_submit(t("Log in"));
      return form($output);
    }
    else {
931
932
933
934
935
      if ($account->status) {
        /*
        ** Create new user account, no administrator approval required:
        */

Dries's avatar
   
Dries committed
936
937
        $subject = _user_mail_text("welcome_subject", $variables);
        $body = _user_mail_text("welcome_body", $variables);
Dries's avatar
   
Dries committed
938
        user_mail($edit['mail'], $subject, $body, "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");
939
940
941
942
943
944
        return t("Your password and further instructions have been sent to your e-mail address.");
      }
      else {
        /*
        ** Create new user account, administrator approval required:
        */
Dries's avatar
   
Dries committed
945
946
947
        $subject = _user_mail_text("approval_subject", $variables);
        $body = _user_mail_text("approval_body", $variables);

Dries's avatar
   
Dries committed
948
        user_mail($edit['mail'], $subject, $body, "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");
Dries's avatar
Dries committed
949
        user_mail(variable_get("site_mail", ini_get("sendmail_from")), $subject, t("%u has applied for an account.\n\n%uri", array("%u" => $account->name, "%uri" => url("admin/user/edit/$account->uid", NULL, NULL, TRUE))), "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");
Dries's avatar
   
Dries committed
950
        return t("Thank you for applying for an account. Your account is currently pending approval by the site administrator.<br />In the meantime, your password and further instructions have been sent to your e-mail address.");
951
      }
952
    }
Dries's avatar
   
Dries committed
953
954
955
  }
  else {
    if ($error) {
Dries's avatar
   
Dries committed
956
      drupal_set_message($error, 'error');
Dries's avatar
   
Dries committed
957
    }
958
  }
Dries's avatar
   
Dries committed
959

960
  // display the registration form
961
  $output .= variable_get("user_registration_help", "");
962
  $affiliates = user_auth_help_links();
Dries's avatar
   
Dries committed
963
  if (count($affiliates) > 0) {
964
    $affiliates = implode(", ", $affiliates);
Dries's avatar
   
Dries committed
965
    $output .= "<p>". t("Note: if you have an account with one of our affiliates (%s), you may <a href=\"%login_uri\">login now</a> instead of registering.", array("%s" => $affiliates, "%login_uri" => url("user/login"))) ."</p>";
966
  }
Dries's avatar
   
Dries committed
967
968
  $output .= form_textfield(t("Username"), 'name', $edit['name'], 30, 64, t("Your full name or your preferred username: only letters, numbers and spaces are allowed."));
  $output .= form_textfield(t("E-mail address"), "mail", $edit['mail'], 30, 64, t("A password and instructions will be sent to this e-mail address, so make sure it is accurate."));
969
  $output .= form_submit(t("Create new account"));
970
  $items[] = l(t("Request new password"), "user/password");
Dries's avatar
   
Dries committed
971
  $items[] = l(t("Log in"), "user/login");
Dries's avatar
   
Dries committed
972
  $output .= theme("item_list", $items);
Dries's avatar
   
Dries committed
973
  $output  = form_group(t('Create new user account'), $output);
Kjartan's avatar
Kjartan committed
974

975
  return form($output);
Dries's avatar
   
Dries committed
976
977
978
}

function user_edit($edit = array()) {
Dries's avatar
   
Dries committed
979
  global $user;
Dries's avatar
   
Dries committed
980
981

  if ($user->uid) {
Dries's avatar
   
Dries committed
982
983
    if (!(is_null($edit['name']) && is_null($edit['mail']))) {
      if ($error = user_validate_name($edit['name'])) {
Dries's avatar
   
Dries committed