Commit 805107cd authored by Dries's avatar Dries

Commiting my work of last Sunday:

 - removed ban.inc and ban.module and integrated it in account.module
   under the name "access control" --> the ban code was not really up
   to standard so this has now been dealt with.  This refactoring and
   reintegration cuts down the code size with 100 lines too.  :-)
   (The ban.module code was really old and it showed.)

 - added node.module and made the other modules reuse some of this
   code --> cut down the code size of modules by at least 100 lines
   and adds stability.

 - added a status() function to admin.php to display a conform status
   message where appropriate.  See admin.php for usage.

 - removed $theme->control() and made comments.inc handle this itself
   wrapped in a $theme->box().  No need to clutter the themes with
   such complexity --> updated all themes already. :-)

 - some small visual changes to some administration pages to be more
   consistent across different modules.
parent 1f5bc83d
drupal x.xx, xx/xx/xxxx
-----------------------
- major overhaul of the entire underlying design:
* everything is based on nodes
* introduced links/drupal tags
* everything is based on nodes: nodes are a conceptual "black box" to couple and manage different types of content and that promotes reusing existing code, thus reducing the complexity and size of drupal as well as improving long-term stability.
* introduced links/drupal tags: [[link]]
- rewrote submission/moderation queue:
* renamed submission.module to moderation.module
* updated submission forms
- added a "book module":
* merged documentation and FAQ module into a book module
- removed FAQ and documentation module and merged them into a "book module":
* allows collaborative book writing
- removed ban module and integrated it in account.module as "access control":
* access control is based on much more powerful regular expressions (regex) now rather than on MySQL pattern matching.
- various updates:
* added preview functionality when submitting new content (such as a story) from the administration pages.
* made the administration section only show those links a user has access to.
* improved account module
* improved account module:
+ added "acess control" to allow/deny certain usernames/e-mail addresses/hostnames
* improved comment module
* improved story module:
+ stories can now be permanently deleted
+ added preview functionality for administrators
+ made it possible to permanently delete stories
* improved themes:
+ W3C validation on a best effort basis
+ added goofy theme
+ added theme "goofy"
- revised documentation
drupal 2.00, 15/03/2001
......@@ -56,10 +60,10 @@ drupal 2.00, 15/03/2001
* improved database abstraction layer
* improved themes:
+ W3C validation on a best effort basis
+ added example theme
* added CREDITS file
* added directory "misc"
+ added theme "example" (alas "Stone Age")
* added new scripts to directory "scripts"
* added directory "misc"
* added CREDITS file
- revised documentation
drupal 1.00, 15/01/2001
......
......@@ -24,7 +24,7 @@ function account_create($error = "") {
global $theme;
if ($error) {
$output .= "<P><FONT COLOR=\"red\">". t("Failed to create account: $error.") ."</FONT></P>\n";
$output .= "<P><FONT COLOR=\"red\">". t("Failed to create account") .": ". check_output($error) .".</FONT></P>\n";
watchdog("message", "failed to create account: $error.");
}
else {
......@@ -47,8 +47,19 @@ function account_create($error = "") {
function account_session_start($userid, $passwd) {
global $user;
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'"));
if ($user->id) {
if ($rule = user_ban($user->userid, "username")) {
watchdog("message", "failed to login for '$user->userid': banned by $rule->type rule '$rule->mask'");
}
else if ($rule = user_ban($user->last_host, "hostname")) {
watchdog("message", "failed to login for '$user->userid': banned by $rule->type rule '$rule->mask'");
}
else {
session_register("user");
watchdog("message", "session opened for '$user->userid'");
}
}
else watchdog("message", "failed to login for '$userid': invalid username - password combination");
}
function account_session_close() {
......@@ -283,20 +294,18 @@ function module($name, $module, $username) {
}
function account_validate($user) {
global $type2index;
// Verify username and e-mail address:
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");
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 e-mail address '$user[real_email]' is not valid");
if (empty($user[userid]) || (ereg("[^a-zA-Z0-9_-]", $user[userid]))) $error = t("the username '$user[userid]' is not valid");
if (strlen($user[userid]) > 15) $error = t("the username '$user[userid]' is too long: it must be less than 15 characters");
// Check to see whether the username or e-mail address are banned:
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>";
if ($ban = user_ban($user[userid], "username")) $error = t("the username '$user[userid]' is banned") .": <I>$ban->reason</I>";
if ($ban = user_ban($user[real_email], "e-mail address")) $error = t("the e-mail address '$user[real_email]' is banned") .": <I>$ban->reason</I>";
// Verify whether username and e-mail address are unique:
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 in use by another account");
if (db_num_rows(db_query("SELECT userid FROM users WHERE LOWER(userid) = LOWER('$user[userid]')")) > 0) $error = t("the username '$user[userid]' 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 e-mail address '$user[real_email]' is already in use by another account");
return $error;
}
......
......@@ -5,6 +5,10 @@
// validate user access:
if (!user_access($user)) exit();
function status($message) {
if ($message) return "<B>Status:</B> $message<HR>\n";
}
function admin_page($mod) {
global $repository, $site_name, $menu, $modules, $user;
......
<?php
$type2index = array("addresses" => 0x01,
"profanity" => 0x02,
"hostnames" => 0x03,
"usernames" => 0x04);
$index2type = array(0x01 => "addresses",
0x02 => "profanity",
0x03 => "hostnames",
0x04 => "usernames");
function ban_match($mask, $category) {
// Perform query:
$result = db_query("SELECT * FROM bans WHERE type = '$category' AND LOWER('$mask') LIKE LOWER(mask)");
// Return result:
return db_fetch_object($result);
}
// TODO --> $message by reference
function ban_add($mask, $category, $reason, $message = 0) {
global $index2type;
if (empty($mask)) {
$message = "failed: empty banmasks are not allowed.<P>\n";
}
else if ($ban = db_fetch_object(db_query("SELECT * FROM bans WHERE type = '$category' AND '$mask' LIKE mask"))) {
$message = "failed: ban is already matched by '$ban->mask'.<P>\n";
}
else {
$result = db_query("INSERT INTO bans (mask, type, reason, timestamp) VALUES ('$mask', '$category', '$reason', '". time() ."')");
$message = "added new ban with mask '$mask'.<P>\n";
// Add log entry:
watchdog("message", "added new ban '$mask' to category '". $index2type[$category] ."' with reason '$reason'.");
}
}
function ban_delete($id) {
global $index2type;
$result = db_query("SELECT * FROM bans WHERE id = '$id'");
if ($ban = db_fetch_object($result)) {
// Perform query:
$result = db_query("DELETE FROM bans WHERE id = '$id'");
// Deleted log entry:
watchdog("message", "removed ban '$ban->mask' from category '". $index2type[$ban->type] ."'.");
}
}
?>
......@@ -184,14 +184,12 @@ function comment_moderation($comment) {
function comment_controls($threshold = 1, $mode = 3, $order = 1) {
global $REQUEST_URI, $user;
$output .= "<FONT SIZE=\"2\">\n";
$output .= "<FORM METHOD=\"post\" ACTION=\"$REQUEST_URI\">\n";
$output .= comment_mode(($user->id ? $user->mode : $mode));
$output .= comment_order(($user->id ? $user->sort : $order));
$output .= comment_threshold(($user->id ? $user->threshold : $threshold));
$output .= "<INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"". t("Update settings") ."\">\n";
$output .= "</FORM>\n";
$output .= "</FONT>\n";
return $output;
}
......@@ -289,7 +287,7 @@ function comment_render($lid, $cid) {
if ($user->id) {
// Comment control:
$theme->controls($threshold, $mode, $order);
$theme->box(t("Comment control"), "<DIV ALIGN=\"center\">". comment_controls($threshold, $mode, $order) ."</DIV>");
// Print moderation form:
print "<FORM METHOD=\"post\" ACTION=\"$REQUEST_URI\">\n";
......
......@@ -36,6 +36,8 @@ function node_save($node) {
$rows = array(nid, pid, lid, log, type, title, score, votes, author, status, timestamp);
if ($node[nid] > 0) {
$n = node_get_object("nid", $node[nid]);
$u1 = array();
$u2 = array();
......@@ -49,10 +51,10 @@ function node_save($node) {
}
if ($u1 = implode(", ", $u1)) db_query("UPDATE node SET $u1 WHERE nid = '$node[nid]'");
if ($u2 = implode(", ", $u2)) db_query("UPDATE $node[type] SET $u2 WHERE nid = '$node[nid]'");
if (($node[pid]) && ($node[status] == $status[posted])) db_query("UPDATE node SET status = '$status[expired]' WHERE nid = '$node[pid]'");
if ($u2 = implode(", ", $u2)) db_query("UPDATE $n->type SET $u2 WHERE nid = '$node[nid]'");
if ($n->pid && ($node[status] == $status[posted])) db_query("UPDATE node SET status = '$status[expired]' WHERE nid = '$node[pid]'");
watchdog("message", "node: modified '$node[title]'");
watchdog("message", "node: modified '$n->title'");
}
else {
$duplicate = node_get_object("title", $node[title]);
......
......@@ -95,4 +95,9 @@ function user_access($account, $section = 0) {
else return ($account->access || $account->id == 1);
}
function user_ban($mask, $type) {
$result = db_query("SELECT * FROM access WHERE type = '$type' AND '$mask' REGEXP mask");
return db_fetch_object($result);
}
?>
\ No newline at end of file
......@@ -6,9 +6,33 @@
function account_help() {
?>
<P>The account-module is responsible for maintaining the user database. It automatically handles tasks like registration, authentication, access rights, password retrieval, user settings and much more.</P>
<P>The account-module is responsible for maintaining the user database. It automatically handles tasks like registration, authentication, access control, password retrieval, user settings and much more.</P>
<P>The required administration can be accomplished through the "account" interface of the administration section. From here administrators can get a quick overview of all registered users and view/edit specific accounts using the links provided. Some useful operations include blocking specific accounts (e.g. a troublesome user) and giving/taking administration permissions. Note that you should only give these permissions to people you trust!</P>
<P>Check the documentation page for detailed information about user management.</P>
<H3>Regular expressions</H3>
<P>A <I>regular expression</I> (or <I>regexp</I>, or <I>pattern</I>) is a text string that describes some (mathematical) set of strings. A regexp <CODE>R</CODE> "matches" a string <CODE>S</CODE> if <CODE>S</CODE> is in the set of strings described by <CODE>R</CODE>.</P>
<P>Regular expressions are very powerful but often get complicated and nothing in this write-up can change that.
<P>A complete explanation of regular expressions is beyond the scope of this help system. A regular expression may use any of the following special characters/constructs:</P>
<TABLE BORDER="1">
<TR><TD>^</TD><TD>Matches the beginning of a string.<TD></TR>
<TR><TD>$</TD><TD>Matches the end of a string.<TD></TR>
<TR><TD>.</TD><TD>Matches any character (including newline). For example the regular expression a.c would match the strings abc, adb, axb, but not axxc.<TD></TR>
<TR><TD>a*</TD><TD>Matches any sequence of zero or more a characters.</TD></TR>
<TR><TD>a+</TD><TD>Matches any sequence of one or more a characters.</TD></TR>
<TR><TD>a?</TD><TD>Matches either zero or one a character.</TD></TR>
<TR><TD>ab|cd</TD><TD>Matches either of the sequences "ab" or "cd".</TD></TR>
<TR><TD>(abc)*</TD><TD>Matches zero or more instances of the sequence abc.</TD></TR>
<TR><TD>[abc]</TD><TD>Matches any one of the characters between the brackets: a, b or c. Ranges of characters can specified by using a hyphen. For example, the regular expression [0-9] means match any digit. Multiple ranges can be specified as well. The regular expression [A-Za-z] means match any upper or lower case letter. To match any character except those in the range, the complement range, use the caret as the first character after the opening bracket. For example, the expression [^269A-Z] will match any characters except 2, 6, 9, and upper case letters.</TD></TR>
<TR><TD>{num}</TD><TD>Matches the preceding element num times.</TD></TR>
<TR><TD>{min, max}</TD><TD>Matches the preceding element at least min times, but not more than max times.</TD></TR>
</TABLE>
<P><B>Examples:</B></P>
<TABLE BORDER="1">
<TR><TD>apple</TD><TD>Matches any string that has the text "apple" in it.<TD></TR>
<TR><TD>^apple$</TD><TD>Matches the exact string "apple".<TD></TR>
<TR><TD>^apple</TD><TD>Matches any string that starts with "apple".<TD></TR>
<TR><TD>domain\.com$</TD><TD>Matches any string that ends with "@domain.com". Note that you have to escape the dot in domain.com.</TD></TR>
</TABLE>
<?php
}
......@@ -28,17 +52,55 @@ function account_search() {
print search_data($keys, $mod);
}
function account_display($order = "username") {
function account_ac_add($edit) {
db_query("INSERT INTO access (mask, type, reason) VALUES ('". check_input($edit[mask]) ."', '". check_input($edit[type]) ."', '". check_input($edit[reason]) ."')", 1);
}
function account_ac_del($id) {
db_query("DELETE FROM access WHERE id = '$id'");
}
function account_ac_check($edit) {
return "\"$edit[text]\" ". (($rule = user_ban($edit[text], $edit[category])) ? "matched with access rule '$rule->mask'" : "did not match any of the existing access rules") .".";
}
function account_ac() {
$access = array("e-mail address", "hostname", "username");
$result = db_query("SELECT * FROM access");
foreach ($access as $value) $type .= " <OPTION VALUE=\"$value\">$value</OPTION>\n";
$output .= "<FORM ACTION=\"admin.php?mod=account&op=access\" METHOD=\"post\">\n";
$output .= "<TABLE BORDER=\"1\" CELLPADDING=\"3\" CELLSPACING=\"0\">\n";
$output .= " <TR><TH>mask</TH><TH>type</TH><TH>reason</TH><TH>oparations</TH></TR>\n";
while ($rule = db_fetch_object($result)) {
$output .= " <TR><TD>$rule->mask</TD><TD ALIGN=\"center\">$rule->type</TD><TD>". check_output($rule->reason) ."</TD><TD><A HREF=\"admin.php?mod=account&op=delete+rule&id=$rule->id\">delete rule</A></TD></TR>\n";
}
$output .= " <TR><TD><INPUT TYPE=\"text\" NAME=\"edit[mask]\"></TD><TD><SELECT NAME=\"edit[type]\">\n$type</SELECT></TD><TD><INPUT TYPE=\"text\" NAME=\"edit[reason]\"></TD><TD><INPUT NAME=\"op\" TYPE=\"submit\" VALUE=\"Add rule\"></TD></TR>\n";
$output .= " <TR><TD COLSPAN=\"4\"><SMALL><I>Use <A HREF=\"admin.php?mod=account&op=help\">regular expressions</A> (regexs) to specify the mask pattern.</I></SMALL></TD></TR>\n";
$output .= "</TABLE>\n";
$output .= "<BR><BR>\n";
$output .= "<TABLE BORDER=\"1\" CELLPADDING=\"3\" CELLSPACING=\"0\">\n";
$output .= " <TR><TH COLSPAN=\"3\">check access rules</TH></TR>\n";
$output .= " <TR><TD><INPUT TYPE=\"text\" NAME=\"edit[text]\"></TD><TD><SELECT NAME=\"edit[category]\">\n$type</SELECT></TD><TD><INPUT NAME=\"op\" TYPE=\"submit\" VALUE=\"Check\"></TD></TR>\n";
$output .= "</TABLE>\n";
$output .= "</FORM>\n";
return $output;
}
function account_overview() {
$result = db_query("SELECT id, userid, last_access FROM users ORDER BY last_access DESC LIMIT 50");
$output .= "<TABLE BORDER=\"1\" CELLPADDING=\"2\" CELLSPACING=\"2\">\n";
$output .= " <TR><TH>username</TH><TH>last access</TH><TH COLSPAN=\"3\">operations</TH></TR>\n";
$output .= " <TR><TH>username</TH><TH>last access</TH><TH COLSPAN=\"2\">operations</TH></TR>\n";
while ($account = db_fetch_object($result)) {
$output .= " <TR><TD>". format_username($account->userid) ."</TD><TD>". format_date($account->last_access) ."</TD><TD ALIGN=\"center\"><A HREF=\"admin.php?mod=account&op=view&name=$account->userid\">view</A></TD><TD ALIGN=\"center\"><A HREF=\"admin.php?mod=account&op=edit&name=$account->userid\">edit</A></TD><TD ALIGN=\"center\"><A HREF=\"admin.php?mod=account&op=delete&name=$account->userid\">delete</A></TD></TR>\n";
$output .= " <TR><TD>". format_username($account->userid) ."</TD><TD>". format_date($account->last_access) ."</TD><TD ALIGN=\"center\"><A HREF=\"admin.php?mod=account&op=view&name=$account->userid\">view account</A></TD><TD ALIGN=\"center\"><A HREF=\"admin.php?mod=account&op=edit&name=$account->userid\">edit account</A></TD></TR>\n";
}
$output .= "</TABLE>\n";
print $output;
return $output;
}
function account_access($account) {
......@@ -80,7 +142,7 @@ function account_delete($name) {
db_query("DELETE FROM users WHERE id = '$account->id'");
}
else {
print "<P>Failed to delete account '". format_username($name) ."': the account must be blocked first.</P>";
return "failed to delete account '". format_username($name) ."': the account must be blocked first.";
}
}
......@@ -126,7 +188,7 @@ function access($name, $module) {
$output .= "<INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"View account\">\n";
$output .= "<INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Save account\">\n";
$output .= "</FORM>\n";
print "$output";
return $output;
}
}
......@@ -158,41 +220,56 @@ function account_view($name) {
$output .= " <TR><TD ALIGN=\"center\" COLSPAN=\"2\"><INPUT TYPE=\"hidden\" NAME=\"name\" VALUE=\"$account->userid\"><INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Edit account\"><INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Delete account\"></TD></TR>\n";
$output .= "</TABLE>\n";
$output .= "</FORM>\n";
print "$output";
return $output;
}
}
function account_admin() {
global $op, $edit, $order, $name;
global $op, $edit, $id, $order, $name;
print "<SMALL><A HREF=\"admin.php?mod=account\">overview</A> | <A HREF=\"admin.php?mod=account&op=search\">search account</A> | <A HREF=\"admin.php?mod=account&op=help\">help</A></SMALL><HR>\n";
print "<SMALL> <A HREF=\"admin.php?mod=account&op=access\">access control</A> | <A HREF=\"admin.php?mod=account&op=search\">search account</A> | <A HREF=\"admin.php?mod=account\">overview</A> | <A HREF=\"admin.php?mod=account&op=help\">help</A></SMALL><HR>\n";
switch ($op) {
case "access":
print account_ac();
break;
case "Add rule":
print status(account_ac_add($edit));
print account_ac();
break;
case "Check":
print status(account_ac_check($edit));
print account_ac();
break;
case "delete rule":
print status(account_ac_del($id));
print account_ac();
break;
case "Delete account":
case "delete":
account_delete(check_input($name));
account_display();
print status(account_delete(check_input($name)));
print account_overview();
break;
case "Edit account":
case "edit":
account_edit(check_input($name));
print account_edit(check_input($name));
break;
case "help":
account_help();
print account_help();
break;
case "search":
account_search();
print account_search();
break;
case "View account":
case "view":
account_view($name);
print account_view($name);
break;
case "Save account":
account_edit_save(check_input($name), $edit);
account_view(check_input($name));
print status(account_edit_save(check_input($name), $edit));
print account_view(check_input($name));
break;
default:
account_display();
print account_overview();
}
}
......
<?php
$module = array("help" => "ban_help",
"admin" => "ban_admin");
include_once "includes/ban.inc";
function ban_help() {
?>
<P>The ban module keeps a list of bans in four categories:</P>
<UL>
<LI>Email bans: this type of ban specifies which email addresses will be rejected when registering new users. Can be used to prevent users from using a free email account (e.g. userid@hotmail.com).</LI>
<LI>Profanity bans: <I>under construction</I></LI>
<LI>Hostname bans: this type of ban allows you to block certain hostnames from access to your site or from registering as a new user.</LI>
<LI>Username bans: this ban will block certain usernames from registration. Typical examples include <I>admin</I>, <I>anonymous</I>, <I>root</I>, <I>webmaster</I>, etc.</LI>
</UL>
<P>The ban module allows you to use a flexible wild-card ban system. This means you can block all email addresses from a certain domain name, block every username starting with "guest", etc. To do this, use the following wild-card characters:</P>
<UL>
<LI>&nbsp;% : matches any number of characters, including zero characters.</LI>
<LI>&nbsp;_ : matches exactly one character.</LI>
</UL>
<P><U>Examples:</U></P>
<UL>
<LI>Email address bans <CODE>%@hotmail.com</CODE>, <CODE>%@altavista.%</CODE>, <CODE>%@usa.net</CODE>, etc. Used to prevent users from using free email accounts, which might be used to cause trouble.</LI>
<LI>Username bans <CODE>root</CODE>, <CODE>webmaster</CODE>, <CODE>admin%</CODE>, etc. Used to prevent administrator impersonators.</LI>
</UL>
<?php
}
function ban_admin_new($mask, $category, $reason) {
ban_add($mask, $category, $reason, $message);
$output .= "$message\n";
print $output;
}
function ban_display($category = "") {
global $type2index;
$category = $category ? $category : 1;
$result = db_query("SELECT * FROM bans WHERE type = $category ORDER BY mask");
$output .= "<TABLE BORDER=\"1\" CELLPADDING=\"2\" CELLSPACING=\"2\">\n";
$output .= " <TR>\n";
$output .= " <TH COLSPAN=\"3\">\n";
$output .= " <FORM ACTION=\"admin.php?mod=ban\" METHOD=\"post\">\n";
$output .= " <SELECT NAME=\"category\">\n";
for (reset($type2index); $cur = current($type2index); next($type2index)) {
$output .= " <OPTION VALUE=\"$cur\"". ($cur == $category ? " SELECTED" : "") .">Bans by ". key($type2index) ."</OPTION>\n";
}
$output .= " </SELECT>\n";
$output .= " <INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Update\">\n";
$output .= " </FORM>\n";
$output .= " </TH>\n";
$output .= " </TR>\n";
$output .= " <TR><TH>mask</TH><TH>reason</TH><TH>operations</TH></TR>\n";
while ($ban = db_fetch_object($result)) {
$output .= " <TR><TD>$ban->mask</TD><TD>$ban->reason</TD><TD ALIGN=\"center\"><A HREF=\"admin.php?mod=ban&op=delete&category=$category&id=$ban->id\">delete</A></TD></TR>\n";
}
$output .= " <TR><TD COLSPAN=\"3\"><SMALL>%: matches any number of characters, even zero characters.<BR>_: matches exactly one character.</SMALL></TD></TR>\n";
$output .= "</TABLE>\n";
print $output;
}
function ban_admin_add() {
global $type2index;
$output .= "<H3>Add new ban:</H3>\n";
$output .= "<FORM ACTION=\"admin.php?mod=ban\" METHOD=\"post\">\n";
$output .= "<B>Banmask:</B><BR>\n";
$output .= "<INPUT TYPE=\"text\" NAME=\"mask\" SIZE=\"35\"><P>\n";
$output .= "<B>Type:</B><BR>\n";
for (reset($type2index); $cur = current($type2index); next($type2index)) $options .= "<OPTION VALUE=\"$cur\"". ($cur == $category ? " SELECTED" : "") .">". key($type2index) ."</OPTION>\n";
$output .= "<SELECT NAME=\"category\"\">$options</SELECT><P>\n";
$output .= "<B>Reason:</B><BR>\n";
$output .= "<TEXTAREA NAME=\"reason\" COLS=\"50\" ROWS=\"5\"></TEXTAREA><P>\n";
$output .= "<INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Add ban\"><BR>\n";
$output .= "</FORM>\n";
print $output;
}
function ban_check($mask, $category) {
$ban = ban_match($mask, $category);
$output .= "". ($ban ? "Matched ban '<B>$ban->mask</B>' with reason: <I>$ban->reason</I>.<P>\n" : "No matching bans for '$mask'.<P>\n") ."";
print $output;
}
function ban_admin_check() {
global $type2index;
$output .= "<H3>Ban check:</H3>\n";
$output .= "<FORM ACTION=\"admin.php?mod=ban\" METHOD=\"post\">\n";
$output .= "<B>Banmask:</B><BR>\n";
$output .= "<INPUT TYPE=\"text\" NAME=\"mask\" SIZE=\"35\"><P>\n";
$output .= "<B>Type:</B><BR>\n";
for (reset($type2index); $cur = current($type2index); next($type2index)) $options .= "<OPTION VALUE=\"$cur\"". ($cur == $category ? " SELECTED" : "") .">". key($type2index) ."</OPTION>\n";
$output .= "<SELECT NAME=\"category\"\">$options</SELECT><P>\n";
$output .= "<INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Check ban\"><BR>\n";
$output .= "</FORM>\n";
print $output;
}
function ban_admin() {
global $op, $id, $mask, $category, $reason;
print "<SMALL><A HREF=\"admin.php?mod=ban&op=add\">add ban</A> | <A HREF=\"admin.php?mod=ban&op=check\">check ban</A> | <A HREF=\"admin.php?mod=ban\">overview</A> | <A HREF=\"admin.php?mod=ban&op=help\">help</A></SMALL><HR>\n";
switch ($op) {
case "Add ban":
ban_admin_new(check_input($mask), check_input($category), check_input($reason));
ban_display(check_input($category));
break;
case "Check ban":
ban_check(check_input($mask), check_input($category));
break;
case "add":
ban_admin_add();
break;
case "help":
ban_help();
break;
case "check":
ban_admin_check();
break;
case "delete":
ban_delete(check_input($id));
default:
ban_display(check_input($category));
}
}
?>
......@@ -154,10 +154,6 @@ function book_save($edit) {
node_save(array_diff(array_merge($edit, array(nid => $edit[nid], type => "book")), array(userid => $edit[userid])));
}
function book_delete($id) {
return ($node = node_del("nid", $id) ? "book page has been deleted" : "failed to delete book page: change status to 'dumped' first");
}
function book_tree($parent = "") {
global $PHP_SELF, $status;
......@@ -166,7 +162,7 @@ function book_tree($parent = "") {
$output .= "<UL>";
while ($node = db_fetch_object($result)) {
$output .= "<LI><A HREF=\"node.php?id=$node->nid\">". check_output($node->title) ."</A>";
if ($PHP_SELF == "/admin.php") $output .= " <SMALL>(weight: $node->weight/$node->parent, status: $node->status) (<A HREF=\"admin.php?mod=book&op=edit&id=$node->nid\">edit</A>, <A HREF=\"admin.php?mod=book&op=delete&id=$node->nid\">delete</A>)</SMALL>\n";
if ($PHP_SELF == "/admin.php") $output .= " <SMALL>(weight: $node->weight/$node->parent, status: $node->status) (<A HREF=\"admin.php?mod=book&op=edit&id=$node->nid\">edit</A>)</SMALL>\n";
if ($node->pid) $output .= book_tree($node->pid);
$output .= book_tree($node->nid);
}
......@@ -175,17 +171,7 @@ function book_tree($parent = "") {
}
function book_list() {
global $status;
$result = db_query("SELECT n.*, b.* FROM node n LEFT JOIN book b ON n.nid = b.nid AND n.lid = b.lid WHERE n.type = 'book' AND n.status != '$status[expired]' ORDER BY n.timestamp DESC");
$output .= "<TABLE BORDER=\"1\" CELLPADDING=\"2\" CELLSPACING=\"2\">\n";
$output .= " <TR><TH>node</TH><TH>status</TH><TH>date</TH><TH COLSPAN=\"3\">operations</TH></TR>\n";
while ($node = db_fetch_object($result)) {
$output .= " <TR><TD><A HREF=\"node.php?id=$node->nid\">". check_output($node->title) ."</A></TD><TD>$node->status</TD><TD>". format_date($node->timestamp, "small") ."</TD><TD><A HREF=\"node.php?id=$node->nid\">view</A></TD><TD><A HREF=\"admin.php?mod=book&op=edit&id=$node->nid\">edit</A></TD><TD><A HREF=\"admin.php?mod=book&op=delete&id=$node->nid\">delete</A></TD>";
}
$output .= "</TABLE>\n";
return $output;
return node_overview("type = 'book'");
}