account.php 25.2 KB
Newer Older
Dries's avatar
Dries committed
1
<?
Dries's avatar
 
Dries committed
2

3
include_once "includes/common.inc";
Dries's avatar
Dries committed
4

Dries's avatar
Dries committed
5
function account_get_user($uname) {
Dries's avatar
 
Dries committed
6 7 8 9
  $result = db_query("SELECT * FROM users WHERE userid = '$uname'");
  return db_fetch_object($result);
}

Dries's avatar
Dries committed
10
function account_email() {
Dries's avatar
 
Dries committed
11
  $output .= "<P>". t("Lost your password?  Fill out your username and e-mail address, and your password will be mailed to you.") ."</P>\n";
Dries's avatar
Dries committed
12
  $output .= "<FORM ACTION=\"account.php\" METHOD=\"post\">\n";
Dries's avatar
 
Dries committed
13
  $output .= "<P>\n";
Dries's avatar
 
Dries committed
14
  $output .= " <B>". t("Username") .":</B><BR>\n";
Dries's avatar
 
Dries committed
15 16 17
  $output .= " <INPUT NAME=\"userid\"><BR>\n";
  $output .= "</P>\n";
  $output .= "<P>\n";
Dries's avatar
 
Dries committed
18
  $output .= " <B>". t("E-mail address") .":</B><BR>\n";
Dries's avatar
 
Dries committed
19 20 21
  $output .= " <INPUT NAME=\"email\"><BR>\n";
  $output .= "</P>\n";
  $output .= "<P>\n";
Dries's avatar
 
Dries committed
22
  $output .= " <INPUT NAME=\"op\" TYPE=\"submit\" VALUE=\"E-mail new password\">\n";
Dries's avatar
 
Dries committed
23
  $output .= "</P>\n";
Dries's avatar
Dries committed
24 25 26 27 28 29 30 31
  $output .= "</FORM>\n";

  return $output;
}

function account_create($user = "", $error = "") {
  global $theme;

Dries's avatar
 
Dries committed
32
  if ($error) $output .= "<B><FONT COLOR=\"red\">Failed to create account:</FONT>$error</B>\n";
Dries's avatar
 
Dries committed
33
  else $output .= "<P>". t("Registering allows you to comment on stories, to moderate comments and pending stories, to customize the look and feel of the site and generally helps you interact with the site more efficiently.") ."</P><P>". t("To create an account, simply fill out this form an click the 'Create account' button below.  An e-mail will then be sent to you with instructions on how to validate your account.") ."</P>\n";
Dries's avatar
Dries committed
34 35

  $output .= "<FORM ACTION=\"account.php\" METHOD=\"post\">\n";
Dries's avatar
 
Dries committed
36 37 38 39 40 41 42
  $output .= "<B>". t("Username") .":</B><BR>\n";
  $output .= "<INPUT NAME=\"userid\"><BR>\n";
  $output .= "<SMALL><I>". t("Enter your desired username: only letters, numbers and common special characters are allowed.") ."</I></SMALL><P>\n";
  $output .= "<B>". t("E-mail address") .":</B><BR>\n";
  $output .= "<INPUT NAME=\"email\"><BR>\n";
  $output .= "<SMALL><I>". t("You will be sent instructions on how to validate your account via this e-mail address - please make sure it is accurate.") ."</I></SMALL><P>\n";
  $output .= "<INPUT NAME=\"op\" TYPE=\"submit\" VALUE=\"Create account\">\n";
Dries's avatar
Dries committed
43
  $output .= "</FORM>\n";
Dries's avatar
 
Dries committed
44

Dries's avatar
 
Dries committed
45
  return $output;
46
}
Dries's avatar
 
Dries committed
47

Dries's avatar
Dries committed
48 49
function account_session_start($userid, $passwd) {
  global $user;
Dries's avatar
 
Dries committed
50

Dries's avatar
Dries committed
51
  $user = new User($userid, $passwd);
Dries's avatar
 
Dries committed
52
  if ($user->id) {
Dries's avatar
Dries committed
53
    session_register("user");
Dries's avatar
 
Dries committed
54
    watchdog("message", "session opened for user `$user->userid'");
Dries's avatar
Dries committed
55 56
  }
  else {
Dries's avatar
 
Dries committed
57
    watchdog("warning", "failed login for user `$userid'");
Dries's avatar
Dries committed
58 59 60 61
  }
}

function account_session_close() {
Dries's avatar
 
Dries committed
62
  global $user;
Dries's avatar
 
Dries committed
63
  watchdog("message", "session closed for user `$user->userid'");
Dries's avatar
Dries committed
64 65 66 67 68 69
  session_unset();
  session_destroy();
  unset($user);
}

function account_user_edit() {
Dries's avatar
 
Dries committed
70
  global $allowed_html, $theme, $user;
Dries's avatar
Dries committed
71

Dries's avatar
 
Dries committed
72
  if ($user->id) {
Dries's avatar
 
Dries committed
73
    // Generate output/content:
Dries's avatar
Dries committed
74
    $output .= "<FORM ACTION=\"account.php\" METHOD=\"post\">\n";
Dries's avatar
 
Dries committed
75
    $output .= "<B>". t("Username") .":</B><BR>\n";
Dries's avatar
 
Dries committed
76
    $output .= "&nbsp; $user->userid<P>\n";
Dries's avatar
 
Dries committed
77 78
    $output .= "<I>". t("Required, unique, and can not be changed.") ."</I><P>\n";
    $output .= "<B>". t("Real name") .":</B><BR>\n";
Dries's avatar
Dries committed
79
    $output .= "<INPUT NAME=\"edit[name]\" MAXLENGTH=\"55\" SIZE=\"30\" VALUE=\"$user->name\"><BR>\n";
Dries's avatar
 
Dries committed
80 81
    $output .= "<I>". t("Optional.") ."</I><P>\n";
    $output .= "<B>". t("Real e-mail address") .":</B><BR>\n";
Dries's avatar
 
Dries committed
82
    $output .= "&nbsp; $user->real_email<P>\n";
Dries's avatar
 
Dries committed
83 84
    $output .= "<I>". t("Required, unique, can not be changed.") ." ". t("Your real e-mail address is never displayed publicly: only needed in case you lose your password.") ."</I><P>\n";
    $output .= "<B>". t("Fake e-mail address") .":</B><BR>\n";
Dries's avatar
 
Dries committed
85
    $output .= "<INPUT NAME=\"edit[fake_email]\" MAXLENGTH=\"55\" SIZE=\"30\" VALUE=\"$user->fake_email\"><BR>\n";
Dries's avatar
 
Dries committed
86 87
    $output .= "<I>". t("Optional.") ." ". t("Displayed publicly so you may spam proof your real e-mail address if you want.") ."</I><P>\n";
    $output .= "<B>". t("Homepage") .":</B><BR>\n";
Dries's avatar
Dries committed
88
    $output .= "<INPUT NAME=\"edit[url]\" MAXLENGTH=\"55\" SIZE=\"30\" VALUE=\"$user->url\"><BR>\n";
Dries's avatar
 
Dries committed
89 90
    $output .= "<I>". t("Optional.") ." ". t("Make sure you enter fully qualified URLs only.  That is, remember to include \"http://\".") ."</I><P>\n";
    $output .= "<B>". t("Bio") .":</B> (". t("maximal 255 characters") .")<BR>\n";
Dries's avatar
Dries committed
91
    $output .= "<TEXTAREA NAME=\"edit[bio]\" COLS=\"35\" ROWS=\"5\" WRAP=\"virtual\">$user->bio</TEXTAREA><BR>\n";
Dries's avatar
 
Dries committed
92 93
    $output .= "<I>". t("Optional.") ." ". t("This biographical information is publicly displayed on your user page.") ."<BR>". t("Allowed HTML tags") .": ". htmlspecialchars($allowed_html) .".</I><P>\n";
    $output .= "<B>". t("Signature") .":</B> (". t("maximal 255 characters") .")<BR>\n";
Dries's avatar
Dries committed
94
    $output .= "<TEXTAREA NAME=\"edit[signature]\" COLS=\"35\" ROWS=\"5\" WRAP=\"virtual\">$user->signature</TEXTAREA><BR>\n";
Dries's avatar
 
Dries committed
95 96
    $output .= "<I>". t("Optional.") ." ". t("This information will be publicly displayed at the end of your comments.") ."<BR>". t("Allowed HTML tags") .": ". htmlspecialchars($allowed_html) .".</I><P>\n";
    $output .= "<B>". t("Password") .":</B><BR>\n";
Dries's avatar
 
Dries committed
97
    $output .= "<INPUT TYPE=\"password\" NAME=\"edit[pass1]\" SIZE=\"10\" MAXLENGTH=\"20\"> <INPUT TYPE=\"password\" NAME=\"edit[pass2]\" SIZE=\"10\" MAXLENGTH=\"20\"><BR>\n";
Dries's avatar
 
Dries committed
98
    $output .= "<I>". t("Enter your new password twice if you want to change your current password or leave it blank if you are happy with your current password.") ."</I><P>\n";
Dries's avatar
Dries committed
99 100 101
    $output .= "<INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Save user information\"><BR>\n";
    $output .= "</FORM>\n";

Dries's avatar
 
Dries committed
102
    // Display output/content:
Dries's avatar
Dries committed
103
    $theme->header();
Dries's avatar
 
Dries committed
104
    $theme->box(t("Edit user information"), $output);
Dries's avatar
Dries committed
105 106 107 108
    $theme->footer();
  }
  else {
    $theme->header();
Dries's avatar
 
Dries committed
109 110
    $theme->box(t("Create user account"), account_create());
    $theme->box(t("E-mail new password"), account_email());
Dries's avatar
Dries committed
111 112 113 114 115 116
    $theme->footer();
  }
}

function account_user_save($edit) {
  global $user;
Dries's avatar
 
Dries committed
117

Dries's avatar
 
Dries committed
118
  if ($user->id) {
Dries's avatar
Dries committed
119
    $data[name] = $edit[name];
Dries's avatar
 
Dries committed
120
    $data[fake_email] = $edit[fake_email];
Dries's avatar
Dries committed
121 122 123
    $data[url] = $edit[url];
    $data[bio] = $edit[bio];
    $data[signature] = $edit[signature];
Dries's avatar
 
Dries committed
124 125 126 127

    if ($edit[pass1] && $edit[pass1] == $edit[pass2]) $data[passwd] = $edit[pass1];

    user_save($data, $user->id);
Dries's avatar
Dries committed
128 129 130
  }
}

Dries's avatar
 
Dries committed
131
function account_site_edit() {
Dries's avatar
 
Dries committed
132
  global $cmodes, $corder, $theme, $themes, $user;
Dries's avatar
Dries committed
133

Dries's avatar
 
Dries committed
134
  if ($user->id) {
Dries's avatar
Dries committed
135
    $output .= "<FORM ACTION=\"account.php\" METHOD=\"post\">\n";
Dries's avatar
 
Dries committed
136 137
    $output .= "<B>". t("Theme" ) .":</B><BR>\n";
    foreach ($themes as $key=>$value) $options1 .= " <OPTION VALUE=\"$key\"". (($user->theme == $key) ? " SELECTED" : "") .">$key - $value[1]</OPTION>\n";
Dries's avatar
 
Dries committed
138
    $output .= "<SELECT NAME=\"edit[theme]\">\n$options1</SELECT><BR>\n";
Dries's avatar
 
Dries committed
139 140
    $output .= "<I>". t("Selecting a different theme will change the look and feel of the site.") ."</I><P>\n";
    $output .= "<B>". t("Timezone") .":</B><BR>\n";
Dries's avatar
 
Dries committed
141
    $date = time() - date("Z");
Dries's avatar
 
Dries committed
142
    for ($zone = -43200; $zone <= 46800; $zone += 3600) $options2 .= " <OPTION VALUE=\"$zone\"". (($user->timezone == $zone) ? " SELECTED" : "") .">". date("l, F dS, Y - h:i A", $date + $zone) ." (GMT ". $zone / 3600 .")</OPTION>\n";
Dries's avatar
 
Dries committed
143
    $output .= "<SELECT NAME=\"edit[timezone]\">\n$options2</SELECT><BR>\n";
Dries's avatar
 
Dries committed
144 145 146
    $output .= "<I>". t("Select what time you currently have and your timezone settings will be set appropriate.") ."</I><P>\n";
    $output .= "<B>". t("Maximum number of stories to display") .":</B><BR>\n";
    for ($stories = 10; $stories <= 30; $stories += 5) $options3 .= "<OPTION VALUE=\"$stories\"". (($user->stories == $stories) ? " SELECTED" : "") .">$stories</OPTION>\n";
Dries's avatar
 
Dries committed
147
    $output .= "<SELECT NAME=\"edit[stories]\">\n$options3</SELECT><BR>\n";
Dries's avatar
 
Dries committed
148 149 150
    $output .= "<I>". t("The maximum number of stories that will be displayed on the main page.") ."</I><P>\n";
    foreach ($cmodes as $key=>$value) $options4 .= "<OPTION VALUE=\"$key\"". ($user->mode == $key ? " SELECTED" : "") .">$value</OPTION>\n";
    $output .= "<B>". t("Comment display mode") .":</B><BR>\n";
Dries's avatar
 
Dries committed
151
    $output .= "<SELECT NAME=\"edit[mode]\">$options4</SELECT><P>\n";
Dries's avatar
 
Dries committed
152 153
    foreach ($corder as $key=>$value) $options5 .= "<OPTION VALUE=\"$key\"". ($user->sort == $key ? " SELECTED" : "") .">$value</OPTION>\n";
    $output .= "<B>". t("Comment sort order") .":</B><BR>\n";
Dries's avatar
 
Dries committed
154
    $output .= "<SELECT NAME=\"edit[sort]\">$options5</SELECT><P>\n";
Dries's avatar
 
Dries committed
155 156
    for ($i = -1; $i < 6; $i++) $options6 .= " <OPTION VALUE=\"$i\"". ($user->threshold == $i ? " SELECTED" : "") .">Filter - $i</OPTION>";
    $output .= "<B>". t("Comment filter") .":</B><BR>\n";
Dries's avatar
 
Dries committed
157
    $output .= "<SELECT NAME=\"edit[threshold]\">$options6</SELECT><BR>\n";
Dries's avatar
 
Dries committed
158
    $output .= "<I>". t("Comments that scored less than this threshold setting will be ignored.  Anonymous comments start at 0, comments of people logged on start at 1 and moderators can add and subtract points.") ."</I><P>\n";
Dries's avatar
 
Dries committed
159
    $output .= "<INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Save site settings\"><BR>\n";
Dries's avatar
Dries committed
160 161 162
    $output .= "</FORM>\n";

    $theme->header();
Dries's avatar
 
Dries committed
163
    $theme->box(t("Edit your preferences"), $output);
Dries's avatar
Dries committed
164 165 166 167
    $theme->footer();
  }
  else {
    $theme->header();
Dries's avatar
 
Dries committed
168 169
    $theme->box(t("Create user account"), account_create());
    $theme->box(t("E-mail new password"), account_email());
Dries's avatar
Dries committed
170 171 172 173
    $theme->footer();
  }
}

Dries's avatar
 
Dries committed
174
function account_site_save($edit) {
Dries's avatar
Dries committed
175
  global $user;
Dries's avatar
 
Dries committed
176

Dries's avatar
 
Dries committed
177
  if ($user->id) {
Dries's avatar
Dries committed
178
    $data[theme] = $edit[theme];
Dries's avatar
 
Dries committed
179
    $data[timezone] = $edit[timezone];
Dries's avatar
 
Dries committed
180 181 182 183 184
    $data[stories] = $edit[stories];
    $data[mode] = $edit[mode];
    $data[sort] = $edit[sort];
    $data[threshold] = $edit[threshold];
    user_save($data, $user->id);
Dries's avatar
Dries committed
185
  }
186
}
Dries's avatar
 
Dries committed
187

Dries's avatar
 
Dries committed
188
function account_content_edit() {
Dries's avatar
 
Dries committed
189 190 191 192
  global $theme, $user;

  if ($user->id) {
    $output .= "<FORM ACTION=\"account.php\" METHOD=\"post\">\n";
Dries's avatar
 
Dries committed
193
    $output .= "<B>". t("Blocks in side bars") .":</B><BR>\n";
Dries's avatar
 
Dries committed
194
    $result = db_query("SELECT * FROM blocks WHERE status = 1 ORDER BY module");
Dries's avatar
 
Dries committed
195 196
    while ($block = db_fetch_object($result)) {
      $entry = db_fetch_object(db_query("SELECT * FROM layout WHERE block = '$block->name' AND user = '$user->id'"));
Dries's avatar
 
Dries committed
197
      $output .= "<INPUT TYPE=\"checkbox\" NAME=\"edit[$block->name]\"". ($entry->user ? " CHECKED" : "") ."> ". t($block->name) ."<BR>\n";
Dries's avatar
 
Dries committed
198
    }
Dries's avatar
 
Dries committed
199
    $output .= "<P><I>". t("Enable the blocks you would like to see displayed in the side bars.") ."</I></P>\n";
Dries's avatar
 
Dries committed
200
    $output .= "<P><INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Save content settings\"></P>\n";
Dries's avatar
 
Dries committed
201 202 203
    $output .= "</FORM>\n";

    $theme->header();
Dries's avatar
 
Dries committed
204
    $theme->box(t("Edit your content"), $output);
Dries's avatar
 
Dries committed
205 206 207 208
    $theme->footer();
  }
  else {
    $theme->header();
Dries's avatar
 
Dries committed
209 210
    $theme->box(t("Create user account"), account_create());
    $theme->box(t("E-mail new password"), account_email());
Dries's avatar
 
Dries committed
211 212 213 214
    $theme->footer();
  }
}

Dries's avatar
 
Dries committed
215
function account_content_save($edit) {
Dries's avatar
 
Dries committed
216 217 218
  global $user;
  if ($user->id) {
    db_query("DELETE FROM layout WHERE user = $user->id");
Dries's avatar
 
Dries committed
219 220
    foreach (($edit ? $edit : array()) as $block=>$weight) {
      db_query("INSERT INTO layout (user, block) VALUES ('". check_input($user->id) ."', '". check_input($block) ."')");
Dries's avatar
 
Dries committed
221 222 223 224
    }
  }
}

Dries's avatar
Dries committed
225
function account_user($uname) {
Dries's avatar
 
Dries committed
226
  global $user, $theme;
Dries's avatar
 
Dries committed
227

Dries's avatar
 
Dries committed
228 229 230 231 232 233 234
  function module($name, $module, $username) {
    global $theme;
    if ($module["user"] && $block = $module["user"]($username, "user", "view")) {
      if ($block["content"]) $theme->box($block["subject"], $block["content"]);
    }
  }

Dries's avatar
 
Dries committed
235
  if ($user->id && $user->userid == $uname) {
Dries's avatar
 
Dries committed
236
    $output .= "<TABLE BORDER=\"0\" CELLPADDING=\"2\" CELLSPACING=\"2\">\n";
Dries's avatar
 
Dries committed
237 238 239 240 241
    $output .= " <TR><TD ALIGN=\"right\"><B>". t("Username") .":</B></TD><TD>$user->userid</TD></TR>\n";
    $output .= " <TR><TD ALIGN=\"right\"><B>". t("E-mail") .":</B></TD><TD>". format_email($user->fake_email) ."</A></TD></TR>\n";
    $output .= " <TR><TD ALIGN=\"right\"><B>". t("Homepage") .":</B></TD><TD>". format_url($user->url) ."</TD></TR>\n";
    $output .= " <TR><TD ALIGN=\"right\" VALIGN=\"top\"><B>". t("Bio") .":</B></TD><TD>". check_output($user->bio) ."</TD></TR>\n";
    $output .= " <TR><TD ALIGN=\"right\" VALIGN=\"top\"><B>". t("Signature") .":</B></TD><TD>". check_output($user->signature) ."</TD></TR>\n";
Dries's avatar
 
Dries committed
242
    $output .= "</TABLE>\n";
Dries's avatar
 
Dries committed
243

Dries's avatar
 
Dries committed
244
    // Display account information:
Dries's avatar
 
Dries committed
245
    $theme->header();
Dries's avatar
 
Dries committed
246
    $theme->box("Personal information", $output);
Dries's avatar
 
Dries committed
247 248
    $theme->footer();
  }
Dries's avatar
Dries committed
249
  elseif ($uname && $account = account_get_user($uname)) {
Dries's avatar
 
Dries committed
250
    $block1 .= "<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"1\">\n";
Dries's avatar
 
Dries committed
251 252 253 254
    $block1 .= " <TR><TD ALIGN=\"right\"><B>". t("Username") .":</B></TD><TD>$account->userid</TD></TR>\n";
    $block1 .= " <TR><TD ALIGN=\"right\"><B>". t("E-mail") .":</B></TD><TD>". format_email($account->fake_email) ."</TD></TR>\n";
    $block1 .= " <TR><TD ALIGN=\"right\"><B>". t("Homepage") .":</B></TD><TD>". format_url($account->url) ."</TD></TR>\n";
    $block1 .= " <TR><TD ALIGN=\"right\"><B>". t("Bio") .":</B></TD><TD>". check_output($account->bio) ."</TD></TR>\n";
Dries's avatar
 
Dries committed
255
    $block1 .= "</TABLE>\n";
256

Dries's avatar
 
Dries committed
257
    $result = db_query("SELECT c.cid, c.pid, c.lid, c.subject, c.timestamp, s.subject AS story FROM comments c LEFT JOIN users u ON u.id = c.author LEFT JOIN stories s ON s.id = c.lid WHERE u.userid = '$uname' AND s.status = 2 AND c.link = 'story' AND s.timestamp > ". (time() - 1209600) ." ORDER BY cid DESC LIMIT 10");
258
    while ($comment = db_fetch_object($result)) {
Dries's avatar
 
Dries committed
259
      $block2 .= "<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"1\">\n";
Dries's avatar
 
Dries committed
260 261 262
      $block2 .= " <TR><TD ALIGN=\"right\"><B>". t("Comment") .":</B></TD><TD><A HREF=\"story.php?id=$comment->lid&cid=$comment->cid&pid=$comment->pid#$comment->cid\">". check_output($comment->subject) ."</A></TD></TR>\n";
      $block2 .= " <TR><TD ALIGN=\"right\"><B>". t("Date") .":</B></TD><TD>". format_date($comment->timestamp) ."</TD></TR>\n";
      $block2 .= " <TR><TD ALIGN=\"right\"><B>". t("Story") .":</B></TD><TD><A HREF=\"story.php?id=$comment->lid\">". check_output($comment->story) ."</A></TD></TR>\n";
Dries's avatar
 
Dries committed
263 264
      $block2 .= "</TABLE>\n";
      $block2 .= "<P>\n";
265 266
      $comments++;
    }
Dries's avatar
 
Dries committed
267

Dries's avatar
 
Dries committed
268
    // Display account information:
Dries's avatar
 
Dries committed
269
    $theme->header();
Dries's avatar
 
Dries committed
270 271
    if ($block1) $theme->box(strtr(t("%s's user information"), array("%s" => $uname)), $block1);
    if ($block2) $theme->box(strtr(t("%a has posted %b recently"), array("%a" => $uname, "%b" => format_plural($comments, "comment", "comments"))), $block2);
Dries's avatar
 
Dries committed
272
    module_iterate("module", $uname);
Dries's avatar
 
Dries committed
273 274
    $theme->footer();
  }
Dries's avatar
 
Dries committed
275
  else {
Dries's avatar
 
Dries committed
276
    // Display login form:
Dries's avatar
 
Dries committed
277
    $theme->header();
Dries's avatar
 
Dries committed
278 279
    $theme->box(t("Create user account"), account_create());
    $theme->box(t("E-mail new password"), account_email());
Dries's avatar
 
Dries committed
280
    $theme->footer();
Dries's avatar
Dries committed
281 282
  }
}
Dries's avatar
 
Dries committed
283

Dries's avatar
 
Dries committed
284
function account_validate($user) {
Dries's avatar
 
Dries committed
285 286
  global $type2index;

Dries's avatar
 
Dries committed
287
  // Verify username and e-mail address:
Dries's avatar
 
Dries committed
288 289 290
  if (empty($user[real_email]) || (!eregi("^[_\.0-9a-z-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,3}$", $user[real_email]))) $error .= "<LI>". t("the specified e-mail address is not valid") .".</LI>\n";
  if (empty($user[userid]) || (ereg("[^a-zA-Z0-9_-]", $user[userid]))) $error .= "<LI>". t("the specified username is not valid") .".</LI>\n";
  if (strlen($user[userid]) > 15) $error .= "<LI>". t("the specified username is too long: it must be less than 15 characters") .".</LI>\n";
Dries's avatar
 
Dries committed
291

Dries's avatar
 
Dries committed
292
  // Check to see whether the username or e-mail address are banned:
Dries's avatar
 
Dries committed
293 294
  if ($ban = ban_match($user[userid], $type2index[usernames])) $error .= "<LI>". t("the specified username is banned  for the following reason") .": <I>$ban->reason</I>.</LI>\n";
  if ($ban = ban_match($user[real_email], $type2index[addresses])) $error .= "<LI>". t("the specified e-mail address is banned for the following reason") .": <I>$ban->reason</I>.</LI>\n";
Dries's avatar
 
Dries committed
295

Dries's avatar
 
Dries committed
296
  // Verify whether username and e-mail address are unique:
Dries's avatar
 
Dries committed
297 298
  if (db_num_rows(db_query("SELECT userid FROM users WHERE LOWER(userid) = LOWER('$user[userid]')")) > 0) $error .= "<LI>". t("the specified username is already taken") .".</LI>\n";
  if (db_num_rows(db_query("SELECT real_email FROM users WHERE LOWER(real_email)=LOWER('$user[real_email]')")) > 0) $error .= "<LI>". t("the specified e-mail address is already registered") .".</LI>\n";
Dries's avatar
 
Dries committed
299 300

  return $error;
Dries's avatar
Dries committed
301 302
}

Dries's avatar
Dries committed
303
function account_email_submit($userid, $email) {
Dries's avatar
 
Dries committed
304
  global $theme, $site_name, $site_url;
305

Dries's avatar
Dries committed
306
  $result = db_query("SELECT id FROM users WHERE userid = '". check_output($userid) ."' AND real_email = '". check_output($email) ."'");
Dries's avatar
 
Dries committed
307

Dries's avatar
Dries committed
308
  if ($account = db_fetch_object($result)) {
Dries's avatar
 
Dries committed
309 310
    $passwd = account_password();
    $hash = substr(md5("$userid. ". time() .""), 0, 12);
Dries's avatar
 
Dries committed
311
    $status = 1;
Dries's avatar
 
Dries committed
312

Dries's avatar
 
Dries committed
313
    db_query("UPDATE users SET passwd = PASSWORD('$passwd'), hash = '$hash', status = '$status' WHERE userid = '$userid'");
Dries's avatar
Dries committed
314

Dries's avatar
 
Dries committed
315 316
    $link = $site_url ."account.php?op=confirm&name=$userid&hash=$hash";
    $message = "$userid,\n\n\nyou requested us to e-mail you a new password for your $site_name account.  Note that you will need to re-activate your account before you can login.  You can do so simply by visiting the URL below:\n\n    $link\n\nVisiting this URL will automatically re-activate your account.  Once activated you can login using the following information:\n\n    username: $userid\n    password: $passwd\n\n\n-- $site_name crew\n";
Dries's avatar
Dries committed
317 318 319

    watchdog("message", "new password: `$userid' &lt;$email&gt;");

Dries's avatar
 
Dries committed
320
    mail($email, "Account details for $site_name", $message, "From: noreply");
Dries's avatar
Dries committed
321 322 323 324 325

    $output = "Your password and further instructions have been sent to your e-mail address.";
  }
  else {
    watchdog("warning", "new password: '$userid' and &lt;$email&gt; do not match");
Dries's avatar
 
Dries committed
326
    $output = t("Could not sent password: no match for the specified username and e-mail address.");
Dries's avatar
Dries committed
327
  }
Dries's avatar
 
Dries committed
328

Dries's avatar
Dries committed
329
  $theme->header();
Dries's avatar
 
Dries committed
330
  $theme->box(t("E-mail new password"), $output);
Dries's avatar
Dries committed
331 332
  $theme->footer();
}
Dries's avatar
 
Dries committed
333

Dries's avatar
Dries committed
334 335
function account_create_submit($userid, $email) {
  global $theme, $site_name, $site_url;
Dries's avatar
 
Dries committed
336

Dries's avatar
 
Dries committed
337 338
  $new[userid] = trim($userid);
  $new[real_email] = trim($email);
Dries's avatar
 
Dries committed
339 340

  if ($error = account_validate($new)) {
Dries's avatar
Dries committed
341
    $theme->header();
Dries's avatar
 
Dries committed
342
    $theme->box(t("Create user account"), account_create($new, $error));
Dries's avatar
Dries committed
343
    $theme->footer();
Dries's avatar
 
Dries committed
344 345 346 347 348
  }
  else {
    $new[passwd] = account_password();
    $new[status] = 1;
    $new[hash] = substr(md5("$new[userid]. ". time() .""), 0, 12);
Dries's avatar
 
Dries committed
349

Dries's avatar
 
Dries committed
350
    user_save($new);
Dries's avatar
Dries committed
351

Dries's avatar
 
Dries committed
352 353
    $link = $site_url ."account.php?op=confirm&name=$new[userid]&hash=$new[hash]";
    $message = "$new[userid],\n\n\nsomeone signed up for a user account on $site_name and supplied this email address as their contact.  If it wasn't you, don't get your panties in a knot and simply ignore this mail.\n\nIf this was you, you have to activate your account first before you can login.  You can do so simply by visiting the URL below:\n\n    $link\n\nVisiting this URL will automatically activate your account.  Once activated you can login using the following information:\n\n    username: $new[userid]\n    password: $new[passwd]\n\n\n-- $site_name crew\n";
Dries's avatar
 
Dries committed
354

Dries's avatar
Dries committed
355
    watchdog("message", "new account: `$new[userid]' &lt;$new[real_email]&gt;");
Dries's avatar
 
Dries committed
356

Dries's avatar
 
Dries committed
357
    mail($new[real_email], "Account details for $site_name", $message, "From: noreply");
Dries's avatar
 
Dries committed
358

Dries's avatar
 
Dries committed
359
    $theme->header();
Dries's avatar
 
Dries committed
360
    $theme->box(t("Create user account"), t("Congratulations!  Your member account has been successfully created and further instructions on how to activate your account have been sent to your e-mail address."));
Dries's avatar
 
Dries committed
361 362 363 364
    $theme->footer();
  }
}

Dries's avatar
Dries committed
365
function account_create_confirm($name, $hash) {
Dries's avatar
 
Dries committed
366 367 368 369 370 371 372 373
  global $theme;

  $result = db_query("SELECT userid, hash, status FROM users WHERE userid = '$name'");

  if ($account = db_fetch_object($result)) {
    if ($account->status == 1) {
      if ($account->hash == $hash) {
        db_query("UPDATE users SET status = 2, hash = '' WHERE userid = '$name'");
Dries's avatar
 
Dries committed
374 375
        $output .= "Your account has been successfully confirmed.  You can click <A HREF=\"account.php?op=login\">here</A> to login.\n";
        watchdog("message", "$name: account confirmation successful");
Dries's avatar
 
Dries committed
376 377 378
      }
      else {
        $output .= "Confirmation failed: invalid confirmation hash.\n";
Dries's avatar
Dries committed
379
        watchdog("warning", "$name: invalid confirmation hash");
Dries's avatar
 
Dries committed
380 381 382 383
      }
    }
    else {
      $output .= "Confirmation failed: your account has already been confirmed.  You can click <A HREF=\"account.php?op=login\">here</A> to login.\n";
Dries's avatar
Dries committed
384
      watchdog("warning", "$name: attempt to re-confirm account");
Dries's avatar
 
Dries committed
385 386 387 388
    }
  }
  else {
    $output .= "Confirmation failed: no such account found.<BR>";
Dries's avatar
Dries committed
389
    watchdog("warning", "$name: attempt to confirm non-existing account");
Dries's avatar
 
Dries committed
390 391 392
  }

  $theme->header();
Dries's avatar
 
Dries committed
393
  $theme->box(t("Create user account"), $output);
Dries's avatar
 
Dries committed
394
  $theme->footer();
Dries's avatar
Dries committed
395
}
Dries's avatar
 
Dries committed
396

Dries's avatar
Dries committed
397
function account_password($min_length=6) {
398
  mt_srand((double)microtime() * 1000000);
Dries's avatar
 
Dries committed
399
  $words = array("foo","bar","guy","neo","tux","moo","sun","asm","dot","god","axe","geek","nerd","fish","hack","star","mice","warp","moon","hero","cola","girl","fish","java","perl","boss","dark","sith","jedi","drop","mojo");
Dries's avatar
 
Dries committed
400
  while(strlen($password) < $min_length) $password .= $words[mt_rand(0, count($words))];
401
  return $password;
Dries's avatar
Dries committed
402 403
}

Dries's avatar
 
Dries committed
404
function account_track_comments() {
Dries's avatar
Dries committed
405
  global $theme, $user;
Dries's avatar
 
Dries committed
406

Dries's avatar
 
Dries committed
407
  $sresult = db_query("SELECT s.id, s.subject, COUNT(s.id) as count FROM comments c LEFT JOIN stories s ON c.lid = s.id WHERE c.author = $user->id GROUP BY s.id DESC LIMIT 5");
Dries's avatar
 
Dries committed
408

Dries's avatar
 
Dries committed
409
  while ($story = db_fetch_object($sresult)) {
Dries's avatar
 
Dries committed
410
    $output .= "<LI>". format_plural($story->count, "comment", "comments") ." ". t("attached to story") ." `<A HREF=\"story.php?id=$story->id\">". check_output($story->subject) ."</A>`:</LI>\n";
Dries's avatar
 
Dries committed
411
    $output .= " <UL>\n";
Dries's avatar
 
Dries committed
412

Dries's avatar
 
Dries committed
413
    $cresult = db_query("SELECT * FROM comments WHERE author = $user->id AND lid = $story->id");
Dries's avatar
 
Dries committed
414
    while ($comment = db_fetch_object($cresult)) {
Dries's avatar
 
Dries committed
415
      $output .= "  <LI><A HREF=\"story.php?id=$story->id&cid=$comment->cid&pid=$comment->pid#$comment->cid\">". check_output($comment->subject) ."</A> - ". t("replies") .": ". comment_num_replies($comment->cid) ." - ". t("score") .": ". comment_score($comment) ."</LI>\n";
Dries's avatar
 
Dries committed
416 417 418
    }
    $output .= " </UL>\n";
  }
Dries's avatar
 
Dries committed
419

Dries's avatar
Dries committed
420
  $theme->header();
Dries's avatar
 
Dries committed
421
  $theme->box(t("Track your comments"), ($output ? $output : t("You have not posted any comments recently.")));
Dries's avatar
Dries committed
422
  $theme->footer();
Dries's avatar
 
Dries committed
423 424
}

Dries's avatar
 
Dries committed
425 426 427
function account_track_stories() {
  global $theme, $user;

Dries's avatar
 
Dries committed
428
  $result = db_query("SELECT s.id, s.subject, s.timestamp, s.section, COUNT(c.cid) as count FROM stories s LEFT JOIN comments c ON c.lid = s.id WHERE s.status = 2 AND s.author = $user->id GROUP BY s.id DESC");
Dries's avatar
 
Dries committed
429

Dries's avatar
 
Dries committed
430 431
  while ($story = db_fetch_object($result)) {
    $output .= "<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"1\">\n";
Dries's avatar
 
Dries committed
432 433 434
    $output .= " <TR><TD ALIGN=\"right\"><B>". t("Subject") .":</B></TD><TD><A HREF=\"story.php?id=$story->id\">". check_output($story->subject) ."</A> (". format_plural($story->count, "comment", "comments") .")</TD></TR>\n";
    $output .= " <TR><TD ALIGN=\"right\"><B>". t("Section") .":</B></TD><TD><A HREF=\"search.php?section=". urlencode($story->section) ."\">". check_output($story->section) ."</A></TD></TR>\n";
    $output .= " <TR><TD ALIGN=\"right\"><B>". t("Date") .":</B></TD><TD>". format_date($story->timestamp) ."</TD></TR>\n";
Dries's avatar
 
Dries committed
435 436 437 438 439
    $output .= "</TABLE>\n";
    $output .= "<P>\n";
  }

  $theme->header();
Dries's avatar
 
Dries committed
440
  $theme->box(t("Track your stories"), ($output ? $output : t("You have not posted any stories.")));
Dries's avatar
 
Dries committed
441 442 443 444 445 446
  $theme->footer();
}

function account_track_site() {
  global $theme, $user, $site_name;

Dries's avatar
 
Dries committed
447
  $period = 259200; // 3 days
Dries's avatar
 
Dries committed
448

Dries's avatar
 
Dries committed
449 450
  $sresult = db_query("SELECT s.subject, s.id, COUNT(c.lid) AS count FROM comments c LEFT JOIN stories s ON c.lid = s.id WHERE s.status = 2 AND c.link = 'story' AND ". time() ." - c.timestamp < $period GROUP BY c.lid ORDER BY count DESC LIMIT 10");
  while ($story = db_fetch_object($sresult)) {
Dries's avatar
 
Dries committed
451
    $output .= "<LI>". format_plural($story->count, "comment", "comments") ." ". t("attached to story") ." '<A HREF=\"story.php?id=$story->id\">". check_output($story->subject) ."</A>':</LI>";
Dries's avatar
 
Dries committed
452

Dries's avatar
 
Dries committed
453 454 455
    $cresult = db_query("SELECT c.subject, c.cid, c.pid, u.userid FROM comments c LEFT JOIN users u ON u.id = c.author WHERE c.lid = $story->id AND c.link = 'story' ORDER BY timestamp DESC LIMIT $story->count");
    $output .= "<UL>\n";
    while ($comment = db_fetch_object($cresult)) {
Dries's avatar
 
Dries committed
456
      $output .= " <LI>'<A HREF=\"story.php?id=$story->id&cid=$comment->cid&pid=$comment->pid#$comment->cid\">". check_output($comment->subject) ."</A>' ". t("by") ." ". format_username($comment->userid) ."</LI>\n";
Dries's avatar
 
Dries committed
457 458 459
    }
    $output .= "</UL>\n";
  }
Dries's avatar
 
Dries committed
460

Dries's avatar
 
Dries committed
461
  $theme->header();
Dries's avatar
 
Dries committed
462
  $theme->box(t("Track $site_name"), $output);
Dries's avatar
 
Dries committed
463 464 465
  $theme->footer();
}

Dries's avatar
 
Dries committed
466
// Security check:
Dries's avatar
 
Dries committed
467 468 469 470 471
if (strstr($name, " ") || strstr($hash, " ")) {
  watchdog("error", "account: attempt to provide malicious input through URI");
  exit();
}

472
switch ($op) {
Dries's avatar
Dries committed
473
  case "Login":
Dries's avatar
Dries committed
474 475
    account_session_start($userid, $passwd);
    header("Location: account.php?op=info");
Dries's avatar
Dries committed
476
    break;
Dries's avatar
 
Dries committed
477
  case "E-mail new password":
Dries's avatar
Dries committed
478 479 480 481
    account_email_submit($userid, $email);
    break;
  case "Create account":
    account_create_submit($userid, $email);
Dries's avatar
Dries committed
482
    break;
Dries's avatar
 
Dries committed
483 484
  case "confirm":
    account_create_confirm($name, $hash);
Dries's avatar
Dries committed
485
    break;
486
  case "Save user information":
Dries's avatar
Dries committed
487 488
    account_user_save($edit);
    account_user($user->userid);
Dries's avatar
Dries committed
489
    break;
Dries's avatar
 
Dries committed
490 491
  case "Save site settings":
    account_site_save($edit);
492
    header("Location: account.php?op=info");
Dries's avatar
Dries committed
493
    break;
Dries's avatar
 
Dries committed
494 495
  case "Save content settings":
    account_content_save($edit);
Dries's avatar
 
Dries committed
496 497
    account_user($user->userid);
    break;
Dries's avatar
 
Dries committed
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524
  case "logout":
    account_session_close();
    header("Location: account.php?op=info");
    break;
  case "view":
    switch ($topic) {
      case "info":
        account_user($user->userid);
        break;
      default:
        account_user($name);
    }
    break;
  case "track":
    switch ($topic) {
      case "site":
        account_track_site();
        break;
      case "stories":
        account_track_stories();
        break;
      default:
        account_track_comments();
    }
    break;
  case "edit":
    switch ($topic) {
Dries's avatar
 
Dries committed
525 526
      case "content":
        account_content_edit();
Dries's avatar
 
Dries committed
527
        break;
Dries's avatar
 
Dries committed
528 529 530
      case "site":
        account_site_edit();
        break;
Dries's avatar
 
Dries committed
531
      default:
Dries's avatar
 
Dries committed
532
        account_user_edit();
Dries's avatar
 
Dries committed
533 534
    }
    break;
Dries's avatar
 
Dries committed
535
  default:
Dries's avatar
Dries committed
536
    account_user($user->userid);
Dries's avatar
Dries committed
537
}
Dries's avatar
 
Dries committed
538

Dries's avatar
Dries committed
539
?>