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

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

Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
10
    if (function_exists($function)) $function($type, $array, $user);
Dries Buytaert's avatar
   
Dries Buytaert committed
11
12
13
  }
}

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

Dries Buytaert's avatar
   
Dries Buytaert committed
17
18
  if ($user = db_fetch_object($result)) {
    return user_load($user);
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
30
31
  $query = "";

Dries Buytaert's avatar
   
Dries Buytaert committed
32
  foreach ($array as $key => $value) {
Dries Buytaert's avatar
   
Dries Buytaert committed
33
    if ($key == 'pass') {
Kjartan Mannes's avatar
Kjartan Mannes committed
34
      $query .= "u.$key = '". md5($value) ."' AND ";
35
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
36
    else {
Dries Buytaert's avatar
   
Dries Buytaert committed
37
      $query .= "u.$key = '". check_query($value) ."' AND ";
Dries Buytaert's avatar
   
Dries Buytaert committed
38
39
    }
  }
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
41
42

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

Dries Buytaert's avatar
   
Dries Buytaert committed
45

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
204
  mt_srand((double)microtime() * 1000000);
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
218
219
220
221
}

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

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

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

Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
236
237
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
238
  return strstr($perm, $string);
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
267
268
269
270
    return mail(
      $mail,
      user_mail_encode($subject),
      str_replace("\r", "", $message),
Dries Buytaert's avatar
   
Dries Buytaert committed
271
      "MIME-Version: 1.0\nContent-Type: text/plain; charset=UTF-8; format=flowed\nContent-transfer-encoding: 8Bit\n" . $header
Dries Buytaert's avatar
   
Dries Buytaert committed
272
    );
Dries Buytaert's avatar
   
Dries Buytaert committed
273
274
275
  }
}

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 Mannes's avatar
Kjartan Mannes committed
281
282
  **
  ** Notes:
283
  **   - Only encode strings that contain non-ASCII characters.
Kjartan Mannes's avatar
Kjartan Mannes 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.
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));
  }
297
  return $string;
Dries Buytaert's avatar
   
Dries Buytaert committed
298
299
}

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

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

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

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

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

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

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

Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
355
function user_search($keys) {
Dries Buytaert's avatar
   
Dries Buytaert committed
356
  $find = array();
357
358
359
360

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

Dries Buytaert's avatar
   
Dries Buytaert committed
361
  $result = db_query_range("SELECT * FROM {users} WHERE name LIKE '%%%s%%'", $keys, 0, 20);
Dries Buytaert's avatar
   
Dries Buytaert committed
362
  while ($account = db_fetch_object($result)) {
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
364
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
365
  return array(t("Matching users"), $find);
Dries Buytaert's avatar
   
Dries Buytaert committed
366
367
}

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

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

Dries Buytaert's avatar
   
Dries Buytaert committed
377
  if ($op == "list") {
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
386
387
    $block = array();

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

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

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

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

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

405
          /*
Dries Buytaert's avatar
Dries Buytaert 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 Buytaert's avatar
Dries Buytaert committed
410

411
          if (empty($edit)) {
Dries Buytaert's avatar
Dries Buytaert 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 Buytaert's avatar
Dries Buytaert committed
415

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

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

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

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

Dries Buytaert's avatar
   
Dries Buytaert committed
431
          $block["subject"] = t("User login");
Dries Buytaert's avatar
   
Dries Buytaert committed
432
          $block["content"] = $output;
Dries Buytaert's avatar
   
Dries Buytaert committed
433
        }
Dries Buytaert's avatar
Dries Buytaert committed
434
        return $block;
435
      case 1:
Dries Buytaert's avatar
   
Dries Buytaert committed
436
437
        if ($menu = menu_tree()) {
           $block["subject"] = $user->uid ? $user->name : t("Navigation");
Dries Buytaert's avatar
   
Dries Buytaert committed
438
           $block["content"] = "<div class=\"menu\">". $menu ."</div>";
Dries Buytaert's avatar
   
Dries Buytaert committed
439
        }
440
        return $block;
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
447

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

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

Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
462
          $total_users = db_num_rows($users);
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
467
468
          }
          else {
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
473

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

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

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

Dries Buytaert's avatar
   
Dries Buytaert 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>";
    }
  }
}

519
function theme_user_profile($account, $fields) {
Dries Buytaert's avatar
   
Dries Buytaert committed
520
521
  $output = "<div class=\"profile\">\n";
  $output .= theme('user_picture', $account);
522
523
524
  foreach ($fields as $category => $value) {
    $output .= "<h2>$category</h2>$value";
  }
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
535
function theme_user_list($items, $title = NULL) {
Dries Buytaert's avatar
   
Dries Buytaert committed
536
  return theme("item_list", $items, $title);
Dries Buytaert's avatar
   
Dries Buytaert committed
537
538
}

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

Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
555
    }
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
569
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
570
571
572
573
574
  }
}

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

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

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

Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
593
  $result = db_query("SELECT authname, module FROM {authmap} WHERE authname = '%s'", $authname);
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
612
613
614
      }
    }
    else {
Dries Buytaert's avatar
   
Dries Buytaert committed
615
      db_query("DELETE FROM {authmap} WHERE uid = %d AND module = '%s'", $account->uid, $module["1"]);
Dries Buytaert's avatar
   
Dries Buytaert committed
616
617
618
619
620
    }
  }
}

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

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

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

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

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

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

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

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

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

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

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

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

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

Dries Buytaert's avatar
   
Dries Buytaert committed
688
    else if (!$user->uid && $server) {
Dries Buytaert's avatar
   
Dries Buytaert committed
689
690
691
      foreach (module_list() as $module) {
        if (module_hook($module, "auth")) {
          if (module_invoke($module, "auth", $name, $pass, $server)) {
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
695
696
697
698
699
700
701
702
              break;
            }
          }
        }
      }
    }

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

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

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

Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
715
      $path = preg_replace("/.+\/\/[^\/]+(.*)/", "\$1/", $base_url);
Dries Buytaert's avatar
   
Dries Buytaert committed
716
      setcookie(session_name(), session_id(), FALSE, $path);
Dries Buytaert's avatar
   
Dries Buytaert committed
717
718

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

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

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

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

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

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

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

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

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

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

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

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

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

    /*
    ** Destroy the current session:
    */

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

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

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

Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert 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 Mannes's avatar
Kjartan Mannes committed
813
814
  }
  if ($account) {
Dries Buytaert's avatar
   
Dries Buytaert committed
815

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

      /*
      ** Save new password:
      */

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

      /*
      ** Mail new password:
      */

Dries Buytaert's avatar
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
833
      $mail_success = user_mail($account->mail, $subject, $body, $headers);
Dries Buytaert's avatar
   
Dries Buytaert committed
834

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

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

    /*
    ** Display form:
    */

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

function user_register($edit = array()) {
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
Dries Buytaert committed
877
    drupal_goto("user/edit");
878
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
879

Dries Buytaert's avatar
   
Dries Buytaert committed
880
881
  if (!(is_null($edit['name']) && is_null($edit['mail']))) {
    if ($error = user_validate_name($edit['name'])) {
Dries Buytaert's avatar
   
Dries Buytaert committed
882
883
      // do nothing
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
884
    else if ($error = user_validate_mail($edit['mail'])) {
Dries Buytaert's avatar
   
Dries Buytaert committed
885
886
      // do nothing
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
887
888
    else if (user_deny('user', $edit['name'])) {
      $error = t("The name '%s' has been denied access.", array("%s" => $edit['name']));
Dries Buytaert's avatar
   
Dries Buytaert committed
889
    }
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
892
    }
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
895
    }
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
898
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
899
    else if (variable_get("user_register", 1) == 0) {
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
919
920
921
922
  }

  if ($success) {

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

926
927
    // TODO: is this necessary? Won't session_write replicate this?
    unset($edit["session"]);
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
930

Dries Buytaert's avatar
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
933
    //the first user may login immediately, and receives a customized welcome e-mail.
934
    if ($account->uid == 1) {
Dries Buytaert's avatar
   
Dries Buytaert committed
935
      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");
936
      // 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
937
      $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 Buytaert's avatar
Dries Buytaert committed
938
      $output .= form_hidden("destination", "user/edit");
Dries Buytaert's avatar
   
Dries Buytaert committed
939
940
      $output .= form_hidden('name', $account->name);
      $output .= form_hidden('pass', $pass);
941
942
943
944
      $output .= form_submit(t("Log in"));
      return form($output);
    }
    else {
945
946
947
948
949
      if ($account->status) {
        /*
        ** Create new user account, no administrator approval required:
        */

Dries Buytaert's avatar
   
Dries Buytaert committed
950
951
        $subject = _user_mail_text("welcome_subject", $variables);
        $body = _user_mail_text("welcome_body", $variables);
Dries Buytaert's avatar
   
Dries Buytaert committed
952
        user_mail($edit['mail'], $subject, $body, "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");
953
954
955
956
957
958
        return t("Your password and further instructions have been sent to your e-mail address.");
      }
      else {
        /*
        ** Create new user account, administrator approval required:
        */
Dries Buytaert's avatar
   
Dries Buytaert committed
959
960
961
        $subject = _user_mail_text("approval_subject", $variables);
        $body = _user_mail_text("approval_body", $variables);

Dries Buytaert's avatar
   
Dries Buytaert committed
962
        user_mail($edit['mail'], $subject, $body, "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");
Dries Buytaert's avatar
Dries Buytaert committed
963
        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 Buytaert's avatar
   
Dries Buytaert committed
964
        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.");
965
      }
966
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
967
968
969
  }
  else {
    if ($error) {
Dries Buytaert's avatar
   
Dries Buytaert committed
970
      drupal_set_message($error, 'error');
Dries Buytaert's avatar
   
Dries Buytaert committed
971
    }
972
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
973

974
  // display the registration form
975
  $output .= variable_get("user_registration_help", "");
976
  $affiliates = user_auth_help_links();
Dries Buytaert's avatar
   
Dries Buytaert committed
977
  if (count($affiliates) > 0) {
978
    $affiliates = implode(", ", $affiliates);
Dries Buytaert's avatar
   
Dries Buytaert committed
979
    $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>";
980
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
981
982
  $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."));
983
  $output .= _user_profile($edit, $edit);
984
  $output .= form_submit(t("Create new account"));
985
  $items[] = l(t("Request new password"), "user/password");
Dries Buytaert's avatar
   
Dries Buytaert committed
986
  $items[] = l(t("Log in"), "user/login");
Dries Buytaert's avatar
   
Dries Buytaert committed
987
  $output .= theme("item_list", $items);
Dries Buytaert's avatar
   
Dries Buytaert committed
988
  $output  = form_group(t('Create new user account'), $output);
Kjartan Mannes's avatar
Kjartan Mannes committed
989

990
  return form($output);
Dries Buytaert's avatar
   
Dries Buytaert committed
991
992
993
}

function user_edit($edit = array()) {
Dries Buytaert's avatar
   
Dries Buytaert committed
994
  global $user;
Dries Buytaert's avatar
   
Dries Buytaert committed
995
996

  if ($user->uid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
997
998
    if (!(is_null($edit['name']) && is_null($edit['mail']))) {
      if ($error = user_validate_name($edit['name'])) {
Dries Buytaert's avatar
   
Dries Buytaert committed
999
1000
        // do nothing
      }
For faster browsing, not all history is shown. View entire blame