user.module 90 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 {
37
      $query .= "LOWER(u.$key) = '". strtolower(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.* FROM {users} u 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
  $user = drupal_unpack($user);
Dries Buytaert's avatar
   
Dries Buytaert committed
44
  user_module_invoke("load", $array, $user);
Dries Buytaert's avatar
   
Dries Buytaert committed
45

Dries Buytaert's avatar
   
Dries Buytaert committed
46
  $user->roles = array();
Dries Buytaert's avatar
   
Dries Buytaert committed
47
48
49
50
  $result = db_query("SELECT r.rid, r.name FROM {role} r INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid = %d", $user->uid);
  while ($role = db_fetch_object($result)) {
    $user->roles[$role->rid] = $role->name;
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
51
52
53
54
55
56
57
58
59

  return $user;
}

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

60
  $user_fields = user_fields();
Dries Buytaert's avatar
   
Dries Buytaert committed
61
  if ($account->uid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
62
63
    user_module_invoke("update", $array, $account);

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

Dries Buytaert's avatar
   
Dries Buytaert committed
85
    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
86

87
88
89
    // reload user roles if provided
    if (is_array($array['rid'])) {
      db_query("DELETE FROM {users_roles} WHERE uid = %d", $account->uid);
Dries Buytaert's avatar
   
Dries Buytaert committed
90

91
92
93
      foreach ($array['rid'] as $rid) {
        db_query("INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)", $account->uid, $rid);
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
94
95
    }

Dries Buytaert's avatar
   
Dries Buytaert committed
96
    $user = user_load(array('uid' => $account->uid));
Dries Buytaert's avatar
   
Dries Buytaert committed
97
98
  }
  else {
Dries Buytaert's avatar
   
Dries Buytaert committed
99
100
    $array['created'] = time();
    $array['changed'] = time();
Dries Buytaert's avatar
   
Dries Buytaert committed
101
    $array['uid'] = db_next_id("{users}_uid");
Dries Buytaert's avatar
   
Dries Buytaert committed
102
103

    foreach ($array as $key => $value) {
Dries Buytaert's avatar
   
Dries Buytaert committed
104
      if ($key == 'pass') {
Dries Buytaert's avatar
   
Dries Buytaert committed
105
        $fields[] = check_query($key);
Dries Buytaert's avatar
   
Dries Buytaert committed
106
107
        $values[] = md5($value);
        $s[] = "'%s'";
Dries Buytaert's avatar
   
Dries Buytaert committed
108
109
      }
      else if (substr($key, 0, 4) !== "auth") {
110
        if (in_array($key, $user_fields)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
111
          $fields[] = check_query($key);
Dries Buytaert's avatar
   
Dries Buytaert committed
112
113
          $values[] = $value;
          $s[] = "'%s'";
Dries Buytaert's avatar
   
Dries Buytaert committed
114
115
116
117
        }
        else {
          $data[$key] = $value;
        }
Dries Buytaert's avatar
   
Dries Buytaert committed
118
119
120
      }
    }

Dries Buytaert's avatar
   
Dries Buytaert committed
121
    $fields[] = "data";
Dries Buytaert's avatar
   
Dries Buytaert committed
122
123
    $values[] = serialize($data);
    $s[] = "'%s'";
Dries Buytaert's avatar
   
Dries Buytaert committed
124

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

Dries Buytaert's avatar
   
Dries Buytaert committed
127
128
129
130
131
132
133
    // reload user roles (delete just to be safe)
    db_query("DELETE FROM {users_roles} WHERE uid = %d", $array['uid']);

    foreach ($array['rid'] as $rid) {
      db_query("INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)", $array['uid'], $rid);
    }

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

Dries Buytaert's avatar
   
Dries Buytaert committed
136
    module_invoke_all('user', 'insert', $array, $user);
Dries Buytaert's avatar
   
Dries Buytaert committed
137
138
139
  }

  foreach ($array as $key => $value) {
Dries Buytaert's avatar
   
Dries Buytaert committed
140
    if (substr($key, 0, 4) == 'auth') {
Dries Buytaert's avatar
   
Dries Buytaert committed
141
142
143
144
145
      $authmaps[$key] = $value;
    }
  }

  if ($authmaps) {
Dries Buytaert's avatar
   
Dries Buytaert committed
146
    user_set_authmaps($user, $authmaps);
Dries Buytaert's avatar
   
Dries Buytaert committed
147
148
149
150
151
152
153
154
155
156
  }

  return $user;
}

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

Dries Buytaert's avatar
   
Dries Buytaert committed
157
  if (!$name) return t("You must enter a username.");
Dries Buytaert's avatar
   
Dries Buytaert committed
158
159
  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
160
  if (ereg('  ', $name)) return t("The username cannot contain multiple spaces in a row.");
Dries Buytaert's avatar
   
Dries Buytaert committed
161
162
  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
163
  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
164
165
166
}

function user_validate_mail($mail) {
Dries Buytaert's avatar
   
Dries Buytaert committed
167
  if (!$mail) return t("You must enter an e-mail address.");
Dries Buytaert's avatar
   
Dries Buytaert committed
168
  if ($mail && !valid_email_address($mail)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
169
    return t("The e-mail address '%mail' is not valid.", array("%mail" => $mail));
Dries Buytaert's avatar
   
Dries Buytaert committed
170
171
172
  }
}

Dries Buytaert's avatar
   
Dries Buytaert committed
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
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;
}

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

Dries Buytaert's avatar
   
Dries Buytaert committed
210
function user_password($length = 10) {
Dries Buytaert's avatar
   
Dries Buytaert committed
211
  /*
Dries Buytaert's avatar
   
Dries Buytaert committed
212
  ** Generate a random alphanumeric password.
Dries Buytaert's avatar
   
Dries Buytaert committed
213
214
  */

Dries Buytaert's avatar
   
Dries Buytaert committed
215
216
217
218
219
220
221
222
223
  // 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
224
  mt_srand((double)microtime() * 1000000);
Dries Buytaert's avatar
   
Dries Buytaert committed
225
226
227
228
229
230
231
232
233
234
235
236
237

  // 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
238
239
240
241
}

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

Dries Buytaert's avatar
   
Dries Buytaert committed
244
  // User #1 has all priveleges:
Dries Buytaert's avatar
   
Dries Buytaert committed
245
246
247
248
  if ($user->uid == 1) {
    return 1;
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
249
250
251
252
  /*
  ** To reduce the number of SQL queries, we cache the user's permissions
  ** in a static variable.
  */
Dries Buytaert's avatar
   
Dries Buytaert committed
253

Dries Buytaert's avatar
   
Dries Buytaert committed
254
  if ($perm === 0) {
Dries Buytaert's avatar
   
Dries Buytaert committed
255
256
257
258
259
    $result = db_query("SELECT DISTINCT p.perm FROM {role} r INNER JOIN {permission} p ON p.rid = r.rid INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid = %d", $user->uid);

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

Dries Buytaert's avatar
   
Dries Buytaert committed
262
  return strstr($perm, "$string, ");
Dries Buytaert's avatar
   
Dries Buytaert committed
263
264
265
266
267
}

function user_mail($mail, $subject, $message, $header) {
  if (variable_get("smtp_library", "") && file_exists(variable_get("smtp_library", ""))) {
    include_once variable_get("smtp_library", "");
268
    return user_mail_wrapper($mail, $subject, $message, $header);
Dries Buytaert's avatar
   
Dries Buytaert committed
269
270
  }
  else {
271
272
273
274
275
276
277
    /*
    ** 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
278
279
280
281
282
283
284
285
286
287
288
289
    **
    ** 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
    **
290
    */
Dries Buytaert's avatar
   
Dries Buytaert committed
291
292
293
294
    return mail(
      $mail,
      user_mail_encode($subject),
      str_replace("\r", "", $message),
Dries Buytaert's avatar
   
Dries Buytaert committed
295
      "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
296
    );
Dries Buytaert's avatar
   
Dries Buytaert committed
297
298
299
  }
}

300
301
302
303
304
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
305
306
  **
  ** Notes:
307
  **   - Only encode strings that contain non-ASCII characters.
Kjartan Mannes's avatar
Kjartan Mannes committed
308
309
310
311
312
313
  **   - 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.
314
  */
315
316
317
318
319
320
  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));
  }
321
  return $string;
Dries Buytaert's avatar
   
Dries Buytaert committed
322
323
}

Dries Buytaert's avatar
   
Dries Buytaert committed
324
function user_deny($type, $mask) {
Dries Buytaert's avatar
   
Dries Buytaert committed
325
326
  $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
327

Dries Buytaert's avatar
   
Dries Buytaert committed
328
  return $deny && !$allow;
Dries Buytaert's avatar
   
Dries Buytaert committed
329
330
}

Dries Buytaert's avatar
   
Dries Buytaert committed
331
332
function user_fields() {
  static $fields;
Dries Buytaert's avatar
   
Dries Buytaert committed
333

Dries Buytaert's avatar
   
Dries Buytaert committed
334
  if (!$fields) {
Dries Buytaert's avatar
   
Dries Buytaert committed
335
    $result = db_query("SELECT * FROM {users} WHERE uid = 1");
336
337
338
    if (db_num_rows($result)) {
      $fields = array_keys(db_fetch_array($result));
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
339
340
    else {
      // Make sure we return the default fields at least
Dries Buytaert's avatar
   
Dries Buytaert committed
341
      $fields = array('uid', 'name', 'pass', 'mail', 'picture', 'mode', 'sort', 'threshold', 'theme', 'signature', 'created', 'changed', 'status', 'timezone', 'language', 'init', 'data');
Dries Buytaert's avatar
   
Dries Buytaert committed
342
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
343
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
344

Dries Buytaert's avatar
   
Dries Buytaert committed
345
  return $fields;
Dries Buytaert's avatar
   
Dries Buytaert committed
346
347
}

Dries Buytaert's avatar
   
Dries Buytaert committed
348
349
350
/*** Module hooks **********************************************************/

function user_perm() {
Dries Buytaert's avatar
   
Dries Buytaert committed
351
  return array("administer users", "access user list");
Dries Buytaert's avatar
   
Dries Buytaert committed
352
353
}

Dries Buytaert's avatar
   
Dries Buytaert committed
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
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
379
function user_search($keys) {
Dries Buytaert's avatar
   
Dries Buytaert committed
380
  $find = array();
381

382
  // Replace wildcards with (MySQL/PostgreSQL wildcards
383
384
  $keys = str_replace("*", "%", $keys);

385
  $result = db_query_range("SELECT * FROM {users} WHERE LOWER(name) LIKE '%%%s%%'", strtolower($keys), 0, 20);
Dries Buytaert's avatar
   
Dries Buytaert committed
386
  while ($account = db_fetch_object($result)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
387
    $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
388
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
389
  return array(t("Matching users"), $find);
Dries Buytaert's avatar
   
Dries Buytaert committed
390
391
}

Dries Buytaert's avatar
Dries Buytaert committed
392
function user_user($type, &$edit, &$user) {
393
  if ($type == 'view') {
Dries Buytaert's avatar
Dries Buytaert committed
394
    return array(t('History') => form_item(t('Member for'), format_interval(time() - $user->created)));
395
396
397
  }
}

Dries Buytaert's avatar
   
Dries Buytaert committed
398
function user_block($op = "list", $delta = 0) {
Dries Buytaert's avatar
   
Dries Buytaert committed
399
400
  global $user;

Dries Buytaert's avatar
   
Dries Buytaert committed
401
  if ($op == "list") {
Dries Buytaert's avatar
   
Dries Buytaert committed
402
403
404
405
     $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");
406

407
     return $blocks;
408
409
  }
  else {
Dries Buytaert's avatar
   
Dries Buytaert committed
410
411
    $block = array();

Dries Buytaert's avatar
   
Dries Buytaert committed
412
413
    switch ($delta) {
      case 0:
Dries Buytaert's avatar
   
Dries Buytaert committed
414

415
        if (!$user->uid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
416
417
418
419
420
          /*
          ** For usability's sake, avoid showing two login forms on one
          ** page.
          */

Dries Buytaert's avatar
   
Dries Buytaert committed
421
          if (arg(0) == 'user' && arg(1) != "view") {
Dries Buytaert's avatar
   
Dries Buytaert committed
422
423
424
            return;
          }

Dries Buytaert's avatar
   
Dries Buytaert committed
425
426
          $edit = $_POST["edit"];

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

429
          /*
Dries Buytaert's avatar
Dries Buytaert committed
430
431
          ** Save the referer.  We record where the user came from such
          ** that we/ can redirect him after having completed the login
432
433
          ** form.
          */
Dries Buytaert's avatar
Dries Buytaert committed
434

435
          if (empty($edit)) {
Dries Buytaert's avatar
Dries Buytaert committed
436
            $edit["destination"] = $_GET["q"];
437
438
          }
          // 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
439

Dries Buytaert's avatar
   
Dries Buytaert committed
440
          $output .= form_hidden("destination", $edit["destination"]);
Dries Buytaert's avatar
   
Dries Buytaert committed
441
442
          $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
443
          $output .= form_submit(t("Log in"));
Dries Buytaert's avatar
   
Dries Buytaert committed
444
          $output .= "</div>\n";
Dries Buytaert's avatar
   
Dries Buytaert committed
445

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

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

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

Dries Buytaert's avatar
   
Dries Buytaert committed
455
          $block["subject"] = t("User login");
Dries Buytaert's avatar
   
Dries Buytaert committed
456
          $block["content"] = $output;
Dries Buytaert's avatar
   
Dries Buytaert committed
457
        }
Dries Buytaert's avatar
Dries Buytaert committed
458
        return $block;
459
      case 1:
Dries Buytaert's avatar
   
Dries Buytaert committed
460
461
        if ($menu = menu_tree()) {
           $block["subject"] = $user->uid ? $user->name : t("Navigation");
Dries Buytaert's avatar
   
Dries Buytaert committed
462
           $block["content"] = "<div class=\"menu\">". $menu ."</div>";
Dries Buytaert's avatar
   
Dries Buytaert committed
463
        }
464
        return $block;
Dries Buytaert's avatar
   
Dries Buytaert committed
465
      case 2:
466
467
468
        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)) {
469
            $items[] = format_name($account);
470
          }
Dries Buytaert's avatar
   
Dries Buytaert committed
471

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

474
475
476
477
          $block["subject"] = t("Who's new");
          $block["content"] = $output;
          return $block;
        }
Dries Buytaert's avatar
   
Dries Buytaert committed
478
479
      case 3:
        if (user_access("access content")) {
Dries Buytaert's avatar
   
Dries Buytaert committed
480
481
          /* 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
482

Dries Buytaert's avatar
   
Dries Buytaert committed
483
484
485
          /* 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
486
          $total_users = db_num_rows($users);
Dries Buytaert's avatar
   
Dries Buytaert committed
487
488
489
490

          /* 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
491
492
          }
          else {
Dries Buytaert's avatar
   
Dries Buytaert committed
493
494
495
496
            $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
497

Dries Buytaert's avatar
   
Dries Buytaert committed
498
            // Display a list of currently online users
Dries Buytaert's avatar
   
Dries Buytaert committed
499
            $max_users = variable_get("user_block_max_list_count", 10);
Dries Buytaert's avatar
   
Dries Buytaert committed
500
501
            if ($max_users) {
              $items = array();
Dries Buytaert's avatar
   
Dries Buytaert committed
502

Dries Buytaert's avatar
   
Dries Buytaert committed
503
              while ($max_users-- && $uid = db_fetch_object($users)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
504
                $items[] = format_name(user_load(array('uid' => $uid->uid)));
Dries Buytaert's avatar
   
Dries Buytaert committed
505
506
507
              }

              if ($items) {
Dries Buytaert's avatar
   
Dries Buytaert committed
508
509
510
                if (db_fetch_object($users)) {
                  $items[] = "...";
                }
Dries Buytaert's avatar
   
Dries Buytaert committed
511
512
                $output .= theme("item_list", $items, t("Online users:"));
              }
Dries Buytaert's avatar
   
Dries Buytaert committed
513
            }
Dries Buytaert's avatar
   
Dries Buytaert committed
514
          }
Dries Buytaert's avatar
   
Dries Buytaert committed
515
516
          $block["subject"] = t("Who's online");
          $block["content"] = $output;
Dries Buytaert's avatar
   
Dries Buytaert committed
517
        }
Dries Buytaert's avatar
   
Dries Buytaert committed
518
        return $block;
Dries Buytaert's avatar
   
Dries Buytaert committed
519
520
    }
  }
521
522
}

Dries Buytaert's avatar
   
Dries Buytaert committed
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
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>";
    }
  }
}

543
function theme_user_profile($account, $fields) {
Dries Buytaert's avatar
   
Dries Buytaert committed
544
545
  $output = "<div class=\"profile\">\n";
  $output .= theme('user_picture', $account);
546
547
548
  foreach ($fields as $category => $value) {
    $output .= "<h2>$category</h2>$value";
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
549
550
551
552
553
554
555
556
557
558

  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
559
function theme_user_list($items, $title = NULL) {
Dries Buytaert's avatar
   
Dries Buytaert committed
560
  return theme("item_list", $items, $title);
Dries Buytaert's avatar
   
Dries Buytaert committed
561
562
}

Dries Buytaert's avatar
   
Dries Buytaert committed
563
564
565
/**
 * Implementation of hook_link().
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
566
function user_link($type) {
Dries Buytaert's avatar
   
Dries Buytaert committed
567
  global $user;
Dries Buytaert's avatar
   
Dries Buytaert committed
568

Dries Buytaert's avatar
   
Dries Buytaert committed
569
  if ($type == 'system') {
570
571
572
573
574
575
576
577
578
    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
579
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
580
581
582
583
584
585
586
587
588
589
590
591
592

    $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
593
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
594
595
596
597
598
  }
}

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

599
function user_get_authname($account, $module) {
Dries Buytaert's avatar
   
Dries Buytaert committed
600
601

  /*
602
  **  Called by authentication modules in order to edit/view their authmap information.
Dries Buytaert's avatar
   
Dries Buytaert committed
603
604
  */

Dries Buytaert's avatar
   
Dries Buytaert committed
605
  $result = db_query("SELECT authname FROM {authmap} WHERE uid = %d AND module = '%s'", $account->uid, $module);
606
607
608
  return db_result($result);
}

Dries Buytaert's avatar
   
Dries Buytaert committed
609

610
611
612
613
614
615
616
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
617
  $result = db_query("SELECT authname, module FROM {authmap} WHERE authname = '%s'", $authname);
Dries Buytaert's avatar
   
Dries Buytaert committed
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
  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
633
634
635
      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
636
637
638
      }
    }
    else {
Dries Buytaert's avatar
   
Dries Buytaert committed
639
      db_query("DELETE FROM {authmap} WHERE uid = %d AND module = '%s'", $account->uid, $module["1"]);
Dries Buytaert's avatar
   
Dries Buytaert committed
640
641
642
643
644
    }
  }
}

function user_auth_help_links() {
645
  $links = array();
Dries Buytaert's avatar
   
Dries Buytaert committed
646
  foreach (module_list() as $module) {
Dries Buytaert's avatar
   
Dries Buytaert committed
647
    if (module_hook($module, "auth")) {
Dries Buytaert's avatar
   
Dries Buytaert committed
648
      $links[] = l(module_invoke($module, 'info', 'name'), "user/help#$module");
Dries Buytaert's avatar
   
Dries Buytaert committed
649
650
651
652
653
654
655
    }
  }
  return $links;
}

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

Dries Buytaert's avatar
   
Dries Buytaert committed
656
function user_login($edit = array(), $msg = "") {
Dries Buytaert's avatar
   
Dries Buytaert committed
657
  global $user, $base_url;
Dries Buytaert's avatar
   
Dries Buytaert committed
658
659
660
661
662
663

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

  if ($user->uid) {
Dries Buytaert's avatar
Dries Buytaert committed
664
    drupal_goto('user');
Dries Buytaert's avatar
   
Dries Buytaert committed
665
666
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
667
668
  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
669
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
670
  else if ($edit['name'] && $edit['pass']) {
Dries Buytaert's avatar
   
Dries Buytaert committed
671
672

    /*
Dries Buytaert's avatar
   
Dries Buytaert committed
673
    ** Try to log in the user locally:
Dries Buytaert's avatar
   
Dries Buytaert committed
674
675
    */

Dries Buytaert's avatar
   
Dries Buytaert committed
676
    if (!$user->uid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
677
678
679
      $name = $edit['name'];
      $pass = $edit['pass'];
      $user = user_load(array('name' => $name, 'pass' => $pass, "status" => 1));
Dries Buytaert's avatar
   
Dries Buytaert committed
680
681
682
683
684
685
    }

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

Dries Buytaert's avatar
   
Dries Buytaert committed
686
687
    if ($server = strrchr($edit['name'], "@")) {
      $name = substr($edit['name'], 0, strlen($edit['name']) - strlen($server));
688
      $server = substr($server, 1);
Dries Buytaert's avatar
   
Dries Buytaert committed
689
      $pass = $edit['pass'];
Dries Buytaert's avatar
   
Dries Buytaert committed
690
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
691

Dries Buytaert's avatar
   
Dries Buytaert committed
692
    /*
Dries Buytaert's avatar
   
Dries Buytaert committed
693
    ** When possible, determine corresponding external auth source. Invoke
Dries Buytaert's avatar
   
Dries Buytaert committed
694
    ** source, and login user if successful:
Dries Buytaert's avatar
   
Dries Buytaert committed
695
696
    */

Dries Buytaert's avatar
   
Dries Buytaert committed
697
    if (!$user->uid && $server && $result = user_get_authmaps("$name@$server")) {
Dries Buytaert's avatar
   
Dries Buytaert committed
698
699
      if (module_invoke(key($result), "auth", $name, $pass, $server)) {
        $user = user_external_load("$name@$server");
Dries Buytaert's avatar
   
Dries Buytaert committed
700
        watchdog('user', "external load: $name@$server, module: ". key($result));
Dries Buytaert's avatar
   
Dries Buytaert committed
701
702
      }
      else {
Dries Buytaert's avatar
   
Dries Buytaert committed
703
        $error = t("Invalid password for %s.", array("%s" => "<i>$name@$server</i>"));
Dries Buytaert's avatar
   
Dries Buytaert committed
704
705
706
      }
    }

Dries Buytaert's avatar
   
Dries Buytaert committed
707
    /*
Dries Buytaert's avatar
   
Dries Buytaert committed
708
    ** Try each external authentication source in series. Register user if
Dries Buytaert's avatar
   
Dries Buytaert committed
709
    ** successful.
Dries Buytaert's avatar
   
Dries Buytaert committed
710
711
    */

Dries Buytaert's avatar
   
Dries Buytaert committed
712
    else if (!$user->uid && $server) {
Dries Buytaert's avatar
   
Dries Buytaert committed
713
714
715
      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
716
            if (variable_get("user_register", 1) == 1 && !user_load(array('name' => "$name@$server"))) { //register this new user
Dries Buytaert's avatar
   
Dries Buytaert committed
717
              $user = user_save('', array('name' => "$name@$server", 'pass' => user_password(), 'init' => "$name@$server", 'status' => 1, "authname_$module" => "$name@$server", 'rid' => array(_user_authenticated_id())));
Dries Buytaert's avatar
   
Dries Buytaert committed
718
              watchdog('user', "new user: $name@$server ($module ID)", l(t("edit user"), "admin/user/edit/$user->uid"));
Dries Buytaert's avatar
   
Dries Buytaert committed
719
720
721
722
723
724
725
726
              break;
            }
          }
        }
      }
    }

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

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

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

Dries Buytaert's avatar
   
Dries Buytaert committed
734
735
736
737
738
      /*
      ** 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
739
      $path = preg_replace("/.+\/\/[^\/]+(.*)/", "\$1/", $base_url);
Dries Buytaert's avatar
   
Dries Buytaert committed
740
      setcookie(session_name(), session_id(), FALSE, $path);
Dries Buytaert's avatar
   
Dries Buytaert committed
741
742

      /*
Dries Buytaert's avatar
   
Dries Buytaert committed
743
      ** Redirect the user to the page he logged on from.
Dries Buytaert's avatar
   
Dries Buytaert committed
744
745
      */

Dries Buytaert's avatar
   
Dries Buytaert committed
746
      drupal_goto($edit["destination"]);
Dries Buytaert's avatar
   
Dries Buytaert committed
747
748
749
    }
    else {
      if (!$error) {
Dries Buytaert's avatar
   
Dries Buytaert committed
750
        $error = t("Sorry.  Unrecognized username or password.") ." ". l(t("Have you forgotten your password?"), "user/password");
Dries Buytaert's avatar
   
Dries Buytaert committed
751
752
      }
      if ($server) {
Dries Buytaert's avatar
   
Dries Buytaert committed
753
        watchdog('user', "failed login for '$name@$server': $error");
Dries Buytaert's avatar
   
Dries Buytaert committed
754
755
      }
      else {
Dries Buytaert's avatar
   
Dries Buytaert committed
756
        watchdog('user', "failed login for '$name': $error");
Dries Buytaert's avatar
   
Dries Buytaert committed
757
758
759
760
761
762
763
764
765
      }
    }
  }

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

  if ($error) {
Dries Buytaert's avatar
   
Dries Buytaert committed
766
    drupal_set_message($error, 'error');
Dries Buytaert's avatar
   
Dries Buytaert committed
767
768
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
769
  /*
Dries Buytaert's avatar
   
Dries Buytaert committed
770
  ** Save the referrer.  We record where the user came from such that we
Dries Buytaert's avatar
   
Dries Buytaert committed
771
772
773
  ** can redirect him after having completed the login form.
  */

774
  if (empty($edit)) {
Dries Buytaert's avatar
Dries Buytaert committed
775
    $edit["destination"] = $_GET["q"];
Dries Buytaert's avatar
   
Dries Buytaert committed
776
777
778
  }
  $output .= form_hidden("destination", $edit["destination"]);

Dries Buytaert's avatar
   
Dries Buytaert committed
779
780
781
782
  /*
  ** Display login form:
  */

Dries Buytaert's avatar
   
Dries Buytaert committed
783
784
785
  if ($msg) {
    $output .= "<p>$msg</p>";
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
786
  if (count(user_auth_help_links()) > 0) {
Dries Buytaert's avatar
   
Dries Buytaert committed
787
    $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
788
789
  }
  else {
Dries Buytaert's avatar
   
Dries Buytaert committed
790
    $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
791
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
792
  $output .= form_password(t("Password"), 'pass', $pass, 30, 64, t("Enter the password that accompanies your username."));
Dries Buytaert's avatar
   
Dries Buytaert committed
793
  $output .= form_submit(t("Log in"));
Dries Buytaert's avatar
   
Dries Buytaert committed
794
  $items[] = l(t("Request new password"), "user/password");
795
  if (variable_get("user_register", 1)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
796
    $items[] = l(t("Create new account"), "user/register");
797
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
798
  $output .= theme("item_list", $items);
Dries Buytaert's avatar
   
Dries Buytaert committed
799

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

802
  return form($output, "post", url('user/login'));
Dries Buytaert's avatar
   
Dries Buytaert committed
803
804
}

805
function _user_authenticated_id() {
Dries Buytaert's avatar
   
Dries Buytaert committed
806
  return db_result(db_query("SELECT rid FROM {role} WHERE name = 'authenticated user'"));
807
808
}

Dries Buytaert's avatar
   
Dries Buytaert committed
809
810
811
812
function user_logout() {
  global $user;

  if ($user->uid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
813
    watchdog('user', "session closed for '$user->name'");
Dries Buytaert's avatar
   
Dries Buytaert committed
814
815
816
817
818
819

    /*
    ** Destroy the current session:
    */

    session_destroy();
Dries Buytaert's avatar
   
Dries Buytaert committed
820
    module_invoke_all('user', 'logout', NULL, $user);
Dries Buytaert's avatar
   
Dries Buytaert committed
821
822
823
    unset($user);
  }

Dries Buytaert's avatar
Dries Buytaert committed
824
  drupal_goto();
Dries Buytaert's avatar
   
Dries Buytaert committed
825
826
827
}

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

Dries Buytaert's avatar
   
Dries Buytaert committed
830
  if ($edit['name']) {
831
    $account = db_fetch_object(db_query("SELECT uid, name, mail FROM {users} WHERE status = 1 AND LOWER(name) = '%s'", strtolower($edit['name'])));
Dries Buytaert's avatar
   
Dries Buytaert committed
832
    if (!$account) $error = t("Sorry. The username <i>%s</i> is not recognized.", array("%s" => $edit['name']));
833
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
834
  else if ($edit['mail']) {
835
    $account = db_fetch_object(db_query("SELECT uid, name, mail FROM {users} WHERE status = 1 AND LOWER(mail) = '%s'", strtolower($edit['mail'])));
Dries Buytaert's avatar
   
Dries Buytaert committed
836
    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
837
838
  }
  if ($account) {
Dries Buytaert's avatar
   
Dries Buytaert committed
839

840
      $from = variable_get("site_mail", ini_get("sendmail_from"));
Dries Buytaert's avatar
   
Dries Buytaert committed
841
842
843
844
845
846
      $pass = user_password();

      /*
      ** Save new password:
      */

Dries Buytaert's avatar
   
Dries Buytaert committed
847
      user_save($account, array('pass' => $pass));
Dries Buytaert's avatar
   
Dries Buytaert committed
848
849
850
851
852

      /*
      ** Mail new password:
      */

Dries Buytaert's avatar
Dries Buytaert committed
853
      $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
854
855
      $subject = _user_mail_text("pass_subject", $variables);
      $body = _user_mail_text("pass_body", $variables);
856
      $headers = "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from";
Dries Buytaert's avatar
   
Dries Buytaert committed
857
      $mail_success = user_mail($account->mail, $subject, $body, $headers);
Dries Buytaert's avatar
   
Dries Buytaert committed
858

Dries Buytaert's avatar
   
Dries Buytaert committed
859
      if ($mail_success) {
Dries Buytaert's avatar
   
Dries Buytaert committed
860
        watchdog('user', "mail password: '". $account->name ."' &lt;". $account->mail ."&gt;");
Dries Buytaert's avatar
   
Dries Buytaert committed
861
862
863
        return t("Your password and further instructions have been sent to your e-mail address.");
      }
      else {
Dries Buytaert's avatar
   
Dries Buytaert committed
864
        watchdog('error', "error mailing new password: '". $account->name ."' &lt;". $account->mail ."&gt;");
Dries Buytaert's avatar
   
Dries Buytaert committed
865
866
        return t("Unable to send mail. Please contact the site admin.");
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
867
868
    }
    else {
869

Kjartan Mannes's avatar
Kjartan Mannes committed
870
871
    // Display error message if necessary.
    if ($error) {
Dries Buytaert's avatar
   
Dries Buytaert committed
872
      drupal_set_message($error, 'error');
Dries Buytaert's avatar
   
Dries Buytaert committed
873
874
875
876
877
878
    }

    /*
    ** Display form:
    */

Dries Buytaert's avatar
   
Dries Buytaert committed
879
    $output .= "<p>". t("Enter your username <strong><em>or</em></strong> your e-mail address.") ."</p>";
Dries Buytaert's avatar
   
Dries Buytaert committed
880
881
    $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
882
    $output .= form_submit(t("E-mail new password"));
Dries Buytaert's avatar
   
Dries Buytaert committed
883
    $items[] = l(t("Log in"), "user/login");
884
    if (variable_get("user_register", 1)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
885
      $items[] = l(t("Create new account"), "user/register");
886
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
887
    $output .= theme("item_list", $items);
Dries Buytaert's avatar
   
Dries Buytaert committed
888
    $output  = form_group(t('Request new password'), $output);
889
    return form($output, "post", url('user/password'));
Dries Buytaert's avatar
   
Dries Buytaert committed
890
891
892
893
  }
}

function user_register($edit = array()) {
Dries Buytaert's avatar
   
Dries Buytaert committed
894
  global $user, $base_url;
895
896
897
898
899
900

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

  if ($user->uid) {
Dries Buytaert's avatar
Dries Buytaert committed
901
    drupal_goto("user/edit");
902
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
903

Dries Buytaert's avatar
   
Dries Buytaert committed
904
905
  if (!(is_null($edit['name']) && is_null($edit['mail']))) {
    if ($error = user_validate_name($edit['name'])) {
Dries Buytaert's avatar
   
Dries Buytaert committed
906
907
      // do nothing
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
908
    else if ($error = user_validate_mail($edit['mail'])) {
Dries Buytaert's avatar
   
Dries Buytaert committed
909
910
      // do nothing
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
911
912
    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
913
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
914
915
    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
916
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
917
918
    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
919
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
920
921
    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
922
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
923
    else if (variable_get("user_register", 1) == 0) {
Dries Buytaert's avatar
   
Dries Buytaert committed
924
925
      $error = t("Public registrations have been disabled by the site administrator.");
    }
926
    else {
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
      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;
      }
942
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
943
944
945
946
  }

  if ($success) {

947
    $from = variable_get("site_mail", ini_get("sendmail_from"));
Dries Buytaert's avatar
   
Dries Buytaert committed
948
949
    $pass = user_password();

950
951
    // TODO: is this necessary? Won't session_write replicate this?
    unset($edit["session"]);
Dries Buytaert's avatar
   
Dries Buytaert committed
952
    $account = user_save('', array_merge(array('name' => $edit['name'], 'pass' => $pass, 'init' => $edit['mail'], 'mail' => $edit['mail'], 'rid' => array(_user_authenticated_id()), 'status' => (variable_get('user_register', 1) == 1 ? 1 : 0)), $data));
Dries Buytaert's avatar
   
Dries Buytaert committed
953
    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
954

Dries Buytaert's avatar
Dries Buytaert committed
955
    $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));
956

Dries Buytaert's avatar
   
Dries Buytaert committed
957
    //the first user may login immediately, and receives a customized welcome e-mail.
958
    if ($account->uid == 1) {
<