account.php 25.8 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 14 15 16 17
  $output .= "<B>". t("Username") .":</B><BR>\n";
  $output .= "<INPUT NAME=\"userid\"><P>\n";
  $output .= "<B>". t("E-mail address") .":</B><BR>\n";
  $output .= "<INPUT NAME=\"email\"><P>\n";
  $output .= "<INPUT NAME=\"op\" TYPE=\"submit\" VALUE=\"". t("E-mail new password") ."\">\n";
Dries's avatar
Dries committed
18 19 20 21 22 23 24 25
  $output .= "</FORM>\n";

  return $output;
}

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

Dries's avatar
 
Dries committed
26
  if ($error) $output .= "<P><FONT COLOR=\"red\">". t("Failed to create account: $error.") ."</FONT></P>\n";
Dries's avatar
 
Dries committed
27
  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
28 29

  $output .= "<FORM ACTION=\"account.php\" METHOD=\"post\">\n";
Dries's avatar
 
Dries committed
30 31 32 33 34
  $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";
Dries's avatar
Dries committed
35
  $output .= "<SMALL><I>". t("You will be sent instructions on how to validate your account via this e-mail address: make sure it is accurate.") ."</I></SMALL><P>\n";
Dries's avatar
 
Dries committed
36
  $output .= "<INPUT NAME=\"op\" TYPE=\"submit\" VALUE=\"". t("Create account") ."\">\n";
Dries's avatar
Dries committed
37
  $output .= "</FORM>\n";
Dries's avatar
 
Dries committed
38

Dries's avatar
 
Dries committed
39
  return $output;
40
}
Dries's avatar
 
Dries committed
41

Dries's avatar
Dries committed
42 43
function account_session_start($userid, $passwd) {
  global $user;
Dries's avatar
 
Dries committed
44 45 46
  if ($userid && $passwd) $user = new User($userid, $passwd);
  if ($user->id) session_register("user");
  watchdog("message", ($user->id ? "session opened for user `$user->userid'" : "failed login for user `$userid'"));
Dries's avatar
Dries committed
47 48 49
}

function account_session_close() {
Dries's avatar
 
Dries committed
50
  global $user;
Dries's avatar
 
Dries committed
51
  watchdog("message", "session closed for user `$user->userid'");
Dries's avatar
Dries committed
52 53 54 55 56 57
  session_unset();
  session_destroy();
  unset($user);
}

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

Dries's avatar
 
Dries committed
60
  if ($user->id) {
Dries's avatar
 
Dries committed
61
    // Generate output/content:
Dries's avatar
Dries committed
62
    $output .= "<FORM ACTION=\"account.php\" METHOD=\"post\">\n";
Dries's avatar
 
Dries committed
63

Dries's avatar
 
Dries committed
64
    $output .= "<B>". t("Username") .":</B><BR>\n";
Dries's avatar
 
Dries committed
65
    $output .= "&nbsp; $user->userid<P>\n";
Dries's avatar
 
Dries committed
66
    $output .= "<I>". t("Required, unique, and can not be changed.") ."</I><P>\n";
Dries's avatar
 
Dries committed
67

Dries's avatar
 
Dries committed
68
    $output .= "<B>". t("Real name") .":</B><BR>\n";
Dries's avatar
Dries committed
69
    $output .= "<INPUT NAME=\"edit[name]\" MAXLENGTH=\"55\" SIZE=\"30\" VALUE=\"$user->name\"><BR>\n";
Dries's avatar
 
Dries committed
70 71
    $output .= "<I>". t("Optional") .".</I><P>\n";

Dries's avatar
 
Dries committed
72
    $output .= "<B>". t("Real e-mail address") .":</B><BR>\n";
Dries's avatar
 
Dries committed
73
    $output .= "&nbsp; $user->real_email<P>\n";
Dries's avatar
 
Dries committed
74
    $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";
Dries's avatar
 
Dries committed
75

Dries's avatar
 
Dries committed
76
    $output .= "<B>". t("Fake e-mail address") .":</B><BR>\n";
Dries's avatar
 
Dries committed
77
    $output .= "<INPUT NAME=\"edit[fake_email]\" MAXLENGTH=\"55\" SIZE=\"30\" VALUE=\"$user->fake_email\"><BR>\n";
Dries's avatar
 
Dries committed
78 79
    $output .= "<I>". t("Optional") .". ". t("Displayed publicly so you may spam proof your real e-mail address if you want.") ."</I><P>\n";

Dries's avatar
 
Dries committed
80
    $output .= "<B>". t("Homepage") .":</B><BR>\n";
Dries's avatar
Dries committed
81
    $output .= "<INPUT NAME=\"edit[url]\" MAXLENGTH=\"55\" SIZE=\"30\" VALUE=\"$user->url\"><BR>\n";
Dries's avatar
 
Dries committed
82 83
    $output .= "<I>". t("Optional") .". ". t("Make sure you enter fully qualified URLs only.  That is, remember to include \"http://\".") ."</I><P>\n";

Dries's avatar
 
Dries committed
84
    $output .= "<B>". t("Bio") .":</B> (". t("maximal 255 characters") .")<BR>\n";
Dries's avatar
Dries committed
85
    $output .= "<TEXTAREA NAME=\"edit[bio]\" COLS=\"35\" ROWS=\"5\" WRAP=\"virtual\">$user->bio</TEXTAREA><BR>\n";
Dries's avatar
 
Dries committed
86 87
    $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";

Dries's avatar
 
Dries committed
88
    $output .= "<B>". t("Signature") .":</B> (". t("maximal 255 characters") .")<BR>\n";
Dries's avatar
Dries committed
89
    $output .= "<TEXTAREA NAME=\"edit[signature]\" COLS=\"35\" ROWS=\"5\" WRAP=\"virtual\">$user->signature</TEXTAREA><BR>\n";
Dries's avatar
 
Dries committed
90 91
    $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";

Dries's avatar
 
Dries committed
92
    $output .= "<B>". t("Password") .":</B><BR>\n";
Dries's avatar
 
Dries committed
93
    $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
94
    $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
95 96

    $output .= "<INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"". t("Save user information") ."\"><BR>\n";
Dries's avatar
Dries committed
97 98
    $output .= "</FORM>\n";

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

function account_user_save($edit) {
  global $user;
Dries's avatar
 
Dries committed
114
  if ($user->id) {
Dries's avatar
 
Dries committed
115 116
    $user = user_save($user, array("name" => $edit[name], "fake_email" => $edit[fake_email], "url" => $edit[url], "bio" => $edit[bio], "signature" => $edit[signature]));
    if ($edit[pass1] && $edit[pass1] == $edit[pass2]) $user = user_save($user, array("passwd" => $edit[pass1]));
Dries's avatar
Dries committed
117 118 119
  }
}

Dries's avatar
 
Dries committed
120
function account_site_edit() {
Dries's avatar
 
Dries committed
121
  global $cmodes, $corder, $theme, $themes, $languages, $user;
Dries's avatar
Dries committed
122

Dries's avatar
 
Dries committed
123
  if ($user->id) {
Dries's avatar
Dries committed
124
    $output .= "<FORM ACTION=\"account.php\" METHOD=\"post\">\n";
Dries's avatar
 
Dries committed
125

Dries's avatar
 
Dries committed
126 127
    $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
128
    $output .= "<SELECT NAME=\"edit[theme]\">\n$options1</SELECT><BR>\n";
Dries's avatar
 
Dries committed
129
    $output .= "<I>". t("Selecting a different theme will change the look and feel of the site.") ."</I><P>\n";
Dries's avatar
 
Dries committed
130

Dries's avatar
 
Dries committed
131
    $output .= "<B>". t("Timezone") .":</B><BR>\n";
Dries's avatar
 
Dries committed
132
    $date = time() - date("Z");
Dries's avatar
 
Dries committed
133
    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
134
    $output .= "<SELECT NAME=\"edit[timezone]\">\n$options2</SELECT><BR>\n";
Dries's avatar
 
Dries committed
135
    $output .= "<I>". t("Select what time you currently have and your timezone settings will be set appropriate.") ."</I><P>\n";
Dries's avatar
 
Dries committed
136 137 138 139 140 141

    $output .= "<B>". t("Language" ) .":</B><BR>\n";
    foreach ($languages as $key=>$value) $options3 .= " <OPTION VALUE=\"$key\"". (($user->language == $key) ? " SELECTED" : "") .">$value - $key</OPTION>\n";
    $output .= "<SELECT NAME=\"edit[language]\">\n$options3</SELECT><BR>\n";
    $output .= "<I>". t("Selecting a different language will change the language the site.") ."</I><P>\n";

Dries's avatar
 
Dries committed
142
    $output .= "<B>". t("Maximum number of stories to display") .":</B><BR>\n";
Dries's avatar
 
Dries committed
143 144
    for ($stories = 10; $stories <= 30; $stories += 5) $options4 .= "<OPTION VALUE=\"$stories\"". (($user->stories == $stories) ? " SELECTED" : "") .">$stories</OPTION>\n";
    $output .= "<SELECT NAME=\"edit[stories]\">\n$options4</SELECT><BR>\n";
Dries's avatar
 
Dries committed
145
    $output .= "<I>". t("The maximum number of stories that will be displayed on the main page.") ."</I><P>\n";
Dries's avatar
 
Dries committed
146 147
    foreach ($cmodes as $key=>$value) $options5 .= "<OPTION VALUE=\"$key\"". ($user->mode == $key ? " SELECTED" : "") .">$value</OPTION>\n";

Dries's avatar
 
Dries committed
148
    $output .= "<B>". t("Comment display mode") .":</B><BR>\n";
Dries's avatar
 
Dries committed
149 150 151
    $output .= "<SELECT NAME=\"edit[mode]\">$options5</SELECT><P>\n";
    foreach ($corder as $key=>$value) $options6 .= "<OPTION VALUE=\"$key\"". ($user->sort == $key ? " SELECTED" : "") .">$value</OPTION>\n";

Dries's avatar
 
Dries committed
152
    $output .= "<B>". t("Comment sort order") .":</B><BR>\n";
Dries's avatar
 
Dries committed
153 154 155
    $output .= "<SELECT NAME=\"edit[sort]\">$options6</SELECT><P>\n";
    for ($i = -1; $i < 6; $i++) $options7 .= " <OPTION VALUE=\"$i\"". ($user->threshold == $i ? " SELECTED" : "") .">Filter - $i</OPTION>";

Dries's avatar
 
Dries committed
156
    $output .= "<B>". t("Comment filter") .":</B><BR>\n";
Dries's avatar
 
Dries committed
157
    $output .= "<SELECT NAME=\"edit[threshold]\">$options7</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 160

    $output .= "<INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"". t("Save site settings") ."\"><BR>\n";
Dries's avatar
Dries committed
161 162 163
    $output .= "</FORM>\n";

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

Dries's avatar
 
Dries committed
175
function account_site_save($edit) {
Dries's avatar
Dries committed
176
  global $user;
Dries's avatar
 
Dries committed
177
  if ($user->id) {
Dries's avatar
 
Dries committed
178
    $user = user_save($user, array("theme" => $edit[theme], "timezone" => $edit[timezone], "language" => $edit[language], "stories" => $edit[stories], "mode" => $edit[mode], "sort" => $edit[sort], "threshold" => $edit[threshold]));
Dries's avatar
Dries committed
179
  }
180
}
Dries's avatar
 
Dries committed
181

Dries's avatar
 
Dries committed
182
function account_content_edit() {
Dries's avatar
 
Dries committed
183 184 185 186
  global $theme, $user;

  if ($user->id) {
    $output .= "<FORM ACTION=\"account.php\" METHOD=\"post\">\n";
Dries's avatar
 
Dries committed
187
    $output .= "<B>". t("Blocks in side bars") .":</B><BR>\n";
Dries's avatar
 
Dries committed
188
    $result = db_query("SELECT * FROM blocks WHERE status = 1 ORDER BY module");
Dries's avatar
 
Dries committed
189 190
    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
191
      $output .= "<INPUT TYPE=\"checkbox\" NAME=\"edit[$block->name]\"". ($entry->user ? " CHECKED" : "") ."> ". t($block->name) ."<BR>\n";
Dries's avatar
 
Dries committed
192
    }
Dries's avatar
 
Dries committed
193
    $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
194
    $output .= "<INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"". t("Save content settings") ."\">\n";
Dries's avatar
 
Dries committed
195 196 197
    $output .= "</FORM>\n";

    $theme->header();
Dries's avatar
 
Dries committed
198
    $theme->box(t("Edit your content"), $output);
Dries's avatar
 
Dries committed
199 200 201 202
    $theme->footer();
  }
  else {
    $theme->header();
Dries's avatar
 
Dries committed
203 204
    $theme->box(t("Create user account"), account_create());
    $theme->box(t("E-mail new password"), account_email());
Dries's avatar
 
Dries committed
205 206 207 208
    $theme->footer();
  }
}

Dries's avatar
 
Dries committed
209
function account_content_save($edit) {
Dries's avatar
 
Dries committed
210 211 212
  global $user;
  if ($user->id) {
    db_query("DELETE FROM layout WHERE user = $user->id");
Dries's avatar
 
Dries committed
213 214
    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
215 216 217 218
    }
  }
}

Dries's avatar
Dries committed
219
function account_user($uname) {
Dries's avatar
 
Dries committed
220
  global $user, $theme;
Dries's avatar
 
Dries committed
221

Dries's avatar
 
Dries committed
222 223 224 225 226 227 228
  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
229
  if ($user->id && $user->userid == $uname) {
Dries's avatar
 
Dries committed
230
    $output .= "<TABLE BORDER=\"0\" CELLPADDING=\"2\" CELLSPACING=\"2\">\n";
Dries's avatar
 
Dries committed
231 232 233 234 235
    $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
236
    $output .= "</TABLE>\n";
Dries's avatar
 
Dries committed
237

Dries's avatar
 
Dries committed
238
    // Display account information:
Dries's avatar
 
Dries committed
239
    $theme->header();
Dries's avatar
 
Dries committed
240
    $theme->box(t("Personal information"), $output);
Dries's avatar
 
Dries committed
241 242
    $theme->footer();
  }
Dries's avatar
Dries committed
243
  elseif ($uname && $account = account_get_user($uname)) {
Dries's avatar
 
Dries committed
244
    $block1 .= "<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"1\">\n";
Dries's avatar
 
Dries committed
245 246 247 248
    $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
249
    $block1 .= "</TABLE>\n";
250

Dries's avatar
 
Dries committed
251
    $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");
252
    while ($comment = db_fetch_object($result)) {
Dries's avatar
 
Dries committed
253
      $block2 .= "<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"1\">\n";
Dries's avatar
 
Dries committed
254 255 256
      $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
257 258
      $block2 .= "</TABLE>\n";
      $block2 .= "<P>\n";
259 260
      $comments++;
    }
Dries's avatar
 
Dries committed
261

Dries's avatar
 
Dries committed
262
    // Display account information:
Dries's avatar
 
Dries committed
263
    $theme->header();
Dries's avatar
Dries committed
264
    if ($block1) $theme->box(strtr(t("%a's user information"), array("%a" => $uname)), $block1);
Dries's avatar
 
Dries committed
265
    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
266
    module_iterate("module", $uname);
Dries's avatar
 
Dries committed
267 268
    $theme->footer();
  }
Dries's avatar
 
Dries committed
269
  else {
Dries's avatar
 
Dries committed
270
    // Display login form:
Dries's avatar
 
Dries committed
271
    $theme->header();
Dries's avatar
 
Dries committed
272 273
    $theme->box(t("Create user account"), account_create());
    $theme->box(t("E-mail new password"), account_email());
Dries's avatar
 
Dries committed
274
    $theme->footer();
Dries's avatar
Dries committed
275 276
  }
}
Dries's avatar
 
Dries committed
277

Dries's avatar
 
Dries committed
278
function account_validate($user) {
Dries's avatar
 
Dries committed
279 280
  global $type2index;

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

Dries's avatar
 
Dries committed
286
  // Check to see whether the username or e-mail address are banned:
Dries's avatar
 
Dries committed
287 288
  if ($ban = ban_match($user[userid], $type2index[usernames])) $error = t("the specified username is banned") .": <I>$ban->reason</I>";
  if ($ban = ban_match($user[real_email], $type2index[addresses])) $error = t("the specified e-mail address is banned") .": <I>$ban->reason</I>.";
Dries's avatar
 
Dries committed
289

Dries's avatar
 
Dries committed
290
  // Verify whether username and e-mail address are unique:
Dries's avatar
 
Dries committed
291 292
  if (db_num_rows(db_query("SELECT userid FROM users WHERE LOWER(userid) = LOWER('$user[userid]')")) > 0) $error = t("the specified username is already taken");
  if (db_num_rows(db_query("SELECT real_email FROM users WHERE LOWER(real_email)=LOWER('$user[real_email]')")) > 0) $error = t("the specified e-mail address is already used for another account");
Dries's avatar
 
Dries committed
293 294

  return $error;
Dries's avatar
Dries committed
295 296
}

Dries's avatar
Dries committed
297
function account_email_submit($userid, $email) {
Dries's avatar
 
Dries committed
298
  global $theme, $site_name, $site_url;
299

Dries's avatar
Dries committed
300
  $result = db_query("SELECT id FROM users WHERE userid = '". check_input($userid) ."' AND real_email = '". check_input($email) ."'");
Dries's avatar
 
Dries committed
301

Dries's avatar
Dries committed
302
  if ($account = db_fetch_object($result)) {
Dries's avatar
 
Dries committed
303 304
    $passwd = account_password();
    $hash = substr(md5("$userid. ". time() .""), 0, 12);
Dries's avatar
 
Dries committed
305
    $status = 1;
Dries's avatar
 
Dries committed
306

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

Dries's avatar
 
Dries committed
309
    $link = $site_url ."account.php?op=confirm&name=$userid&hash=$hash";
Dries's avatar
Dries committed
310 311 312 313
    $subject = strtr(t("Account details for %a"), array("%a" => $site_name));
    $message = strtr(t("%a,\n\n\nyou requested us to e-mail you a new password for your account at %b.  You will need to re-confirm your account or you will not be able to login.  To confirm your account updates visit the URL below:\n\n   %c\n\nOnce confirmed you can login using the following username and password:\n\n   username: %a\n   password: %d\n\n\n-- %b team"), array("%a" => $userid, "%b" => $site_name, "%c" => $link, "%d" => $passwd));

    print "<PRE>$subject<BR>$message</PRE>";
Dries's avatar
Dries committed
314 315 316

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

Dries's avatar
Dries committed
317
    mail($email, $subject, $message, "From: noreply");
Dries's avatar
Dries committed
318 319 320 321 322

    $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
323
    $output = t("Could not sent password: no match for the specified username and e-mail address.");
Dries's avatar
Dries committed
324
  }
Dries's avatar
 
Dries committed
325

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

Dries's avatar
Dries committed
331 332
function account_create_submit($userid, $email) {
  global $theme, $site_name, $site_url;
Dries's avatar
 
Dries committed
333

Dries's avatar
 
Dries committed
334 335
  $new[userid] = trim($userid);
  $new[real_email] = trim($email);
Dries's avatar
 
Dries committed
336 337

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

Dries's avatar
 
Dries committed
346
    $user = user_save("", array("userid" => $new[userid], "real_email" => $new[real_email], "passwd" => $new[passwd], "status" => 1, "hash" => $new[hash]));
Dries's avatar
Dries committed
347

Dries's avatar
 
Dries committed
348
    $link = $site_url ."account.php?op=confirm&name=$new[userid]&hash=$new[hash]";
Dries's avatar
Dries committed
349 350
    $subject = strtr(t("Account details for %a"), array("%a" => $site_name));
    $message = strtr(t("%a,\n\n\nsomeone signed up for a user account on %b and supplied this e-mail address as their contact.  If it wasn't you, don't get your panties in a knot and simply ignore this mail.  If this was you, you will have to confirm your account first or you will not be able to login.  To confirm your account visit the URL below:\n\n   %c\n\nOnce confirmed you can login using the following username and password:\n\n   username: %a\n   password: %d\n\n\n-- %b team\n"), array("%a" => $new[userid], "%b" => $site_name, "%c" => $link, "%d" => $new[passwd]));
Dries's avatar
 
Dries committed
351

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

Dries's avatar
Dries committed
354
    mail($new[real_email], $subject, $message, "From: noreply");
Dries's avatar
 
Dries committed
355

Dries's avatar
 
Dries committed
356
    $theme->header();
Dries's avatar
Dries committed
357
    $theme->box(t("Create user account"), t("Congratulations!  Your member account has been successfully created and further instructions on how to confirm your account have been sent to your e-mail address.  You have to confirm your account first or you will not be able to login."));
Dries's avatar
 
Dries committed
358 359 360 361
    $theme->footer();
  }
}

Dries's avatar
Dries committed
362
function account_create_confirm($name, $hash) {
Dries's avatar
 
Dries committed
363 364 365 366 367 368 369 370
  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
371 372
        $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
373 374 375
      }
      else {
        $output .= "Confirmation failed: invalid confirmation hash.\n";
Dries's avatar
Dries committed
376
        watchdog("warning", "$name: invalid confirmation hash");
Dries's avatar
 
Dries committed
377 378 379 380
      }
    }
    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
381
      watchdog("warning", "$name: attempt to re-confirm account");
Dries's avatar
 
Dries committed
382 383 384 385
    }
  }
  else {
    $output .= "Confirmation failed: no such account found.<BR>";
Dries's avatar
Dries committed
386
    watchdog("warning", "$name: attempt to confirm non-existing account");
Dries's avatar
 
Dries committed
387 388 389
  }

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

Dries's avatar
Dries committed
394
function account_password($min_length=6) {
395
  mt_srand((double)microtime() * 1000000);
Dries's avatar
 
Dries committed
396
  $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
397
  while(strlen($password) < $min_length) $password .= $words[mt_rand(0, count($words))];
398
  return $password;
Dries's avatar
Dries committed
399 400
}

Dries's avatar
 
Dries committed
401
function account_track_comments() {
Dries's avatar
Dries committed
402
  global $theme, $user;
Dries's avatar
 
Dries committed
403

Dries's avatar
 
Dries committed
404
  $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
405

Dries's avatar
 
Dries committed
406
  while ($story = db_fetch_object($sresult)) {
Dries's avatar
 
Dries committed
407
    $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
408
    $output .= " <UL>\n";
Dries's avatar
 
Dries committed
409

Dries's avatar
 
Dries committed
410
    $cresult = db_query("SELECT * FROM comments WHERE author = $user->id AND lid = $story->id");
Dries's avatar
 
Dries committed
411
    while ($comment = db_fetch_object($cresult)) {
Dries's avatar
 
Dries committed
412
      $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
413 414 415
    }
    $output .= " </UL>\n";
  }
Dries's avatar
 
Dries committed
416

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

Dries's avatar
 
Dries committed
422 423 424
function account_track_stories() {
  global $theme, $user;

Dries's avatar
 
Dries committed
425
  $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
426

Dries's avatar
 
Dries committed
427 428
  while ($story = db_fetch_object($result)) {
    $output .= "<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"1\">\n";
Dries's avatar
 
Dries committed
429 430 431
    $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
432 433 434 435 436
    $output .= "</TABLE>\n";
    $output .= "<P>\n";
  }

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

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

Dries's avatar
 
Dries committed
444
  $period = 259200; // 3 days
Dries's avatar
 
Dries committed
445

Dries's avatar
 
Dries committed
446 447
  $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
448
    $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
449

Dries's avatar
 
Dries committed
450 451 452
    $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
453
      $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
454 455 456
    }
    $output .= "</UL>\n";
  }
Dries's avatar
 
Dries committed
457

Dries's avatar
 
Dries committed
458
  $theme->header();
Dries's avatar
 
Dries committed
459
  $theme->box(strtr(t("Track %a"), array("%a" => $site_name)), ($output ? $output : t("No comments or stories posted recently.")));
Dries's avatar
 
Dries committed
460 461 462
  $theme->footer();
}

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

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

Dries's avatar
 
Dries committed
536
?>