Commit 44c48004 authored by Dries's avatar Dries

- here a bunch of changes to make "drupal" (for now) work with PHP 4.0.4

- tidied up some of the code and mainly working on the documentation
parent 83f6495c
......@@ -33,7 +33,7 @@ ErrorDocument 500 /error.php
php_value magic_quotes_runtime 0
php_value magic_quotes_sybase 0
php_value session.name DROPID
php_value session.auto_start 1
php_value session.auto_start 0
php_value session.cookie_lifetime 2000000
php_value session.gc_maxlifetime 2000000
php_value session.cache_expire 200000
......
......@@ -77,7 +77,7 @@ function account_user_edit() {
global $theme, $user;
if ($user->id) {
### Generate output/content:
// Generate output/content:
$output .= "<FORM ACTION=\"account.php\" METHOD=\"post\">\n";
$output .= "<B>Username:</B><BR>\n";
$output .= "&nbsp; $user->userid<P>\n";
......@@ -106,7 +106,7 @@ function account_user_edit() {
$output .= "<INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Save user information\"><BR>\n";
$output .= "</FORM>\n";
### Display output/content:
// Display output/content:
$theme->header();
$theme->box("Edit user settings", $output);
$theme->footer();
......@@ -276,7 +276,7 @@ function account_user($uname) {
$output .= " <TR><TD ALIGN=\"right\" VALIGN=\"top\"><B>Signature:</B></TD><TD>". format_data($user->signature) ."</TD></TR>\n";
$output .= "</TABLE>\n";
### Display account information:
// Display account information:
$theme->header();
$theme->box("View user settings", $output);
$theme->footer();
......@@ -306,7 +306,7 @@ function account_user($uname) {
$diaries++;
}
### Display account information:
// Display account information:
$theme->header();
if ($box1) $theme->box("User information for $uname", $box1);
if ($box2) $theme->box("$uname has posted ". format_plural($comments, "comment", "comments") ." recently", $box2);
......@@ -314,7 +314,7 @@ function account_user($uname) {
$theme->footer();
}
else {
### Display login form:
// Display login form:
$theme->header();
$theme->box("Create user account", account_create());
$theme->box("E-mail password", account_email());
......@@ -323,18 +323,16 @@ function account_user($uname) {
}
function account_validate($user) {
include "includes/ban.inc";
### Verify username and e-mail address:
// 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 .= "<LI>the specified e-mail address is not valid.</LI>\n";
if (empty($user[userid]) || (ereg("[^a-zA-Z0-9_-]", $user[userid]))) $error .= "<LI>the specified username is not valid.</LI>\n";
if (strlen($user[userid]) > 15) $error .= "<LI>the specified username is too long: it must be less than 15 characters.</LI>\n";
### Check to see whether the username or e-mail address are banned:
// Check to see whether the username or e-mail address are banned:
if ($ban = ban_match($user[userid], $type2index[usernames])) $error .= "<LI>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>the specified e-mail address is banned for the following reason: <I>$ban->reason</I>.</LI>\n";
### Verify whether username and e-mail address are unique:
// 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 .= "<LI>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>the specified e-mail address is already registered.</LI>\n";
......@@ -537,7 +535,7 @@ function account_track_site() {
$theme->footer();
}
### Security check:
// Security check:
if (strstr($name, " ") || strstr($hash, " ")) {
watchdog("error", "account: attempt to provide malicious input through URI");
exit();
......
<?
include "includes/common.inc";
// validate user permission:
if (!$user->id || ($user->permissions != 1 && $user->id > 1)) exit();
include "includes/common.inc";
function admin_page($mod) {
global $repository, $menu, $modules;
......
......@@ -8,10 +8,10 @@ function discussion_moderate($moderate) {
foreach ($moderate as $id=>$vote) {
if ($vote != $comment_votes[$none] && !user_getHistory($user->history, "c$id")) {
### Update the comment's score:
// Update the comment's score:
$result = db_query("UPDATE comments SET score = score $vote, votes = votes + 1 WHERE cid = $id");
### Update the user's history:
// Update the user's history:
user_setHistory($user, "c$id", $vote);
}
}
......@@ -52,7 +52,7 @@ function discussion_kids($cid, $mode, $threshold, $level = 0, $dummy = 0) {
function discussion_childs($cid, $threshold, $level = 0, $thread) {
global $theme, $user;
### Perform SQL query:
// Perform SQL query:
$result = db_query("SELECT c.*, u.* FROM comments c LEFT JOIN users u ON c.author = u.id WHERE c.pid = $cid AND (c.votes = 0 OR c.score / c.votes >= $threshold) ORDER BY c.timestamp, c.cid");
if ($level == 0) $thread = "";
......@@ -64,10 +64,10 @@ function discussion_childs($cid, $threshold, $level = 0, $thread) {
$comments++;
### Compose link:
// Compose link:
$thread .= "<LI><A HREF=\"discussion.php?id=$comment->sid&cid=$comment->cid&pid=$comment->pid#$comment->cid\">". check_output($comment->subject) ."</A> by ". format_username($comment->userid) ." <SMALL>(". discussion_score($comment) .")<SMALL></LI>";
### Recursive:
// Recursive:
discussion_childs($comment->cid, $threshold, $level + 1, &$thread);
}
......@@ -93,25 +93,25 @@ function discussion_settings($mode, $order, $threshold) {
function discussion_display($sid, $pid, $cid, $level = 0) {
global $user, $theme;
### Pre-process variables:
// Pre-process variables:
$pid = (empty($pid)) ? 0 : $pid;
$cid = (empty($cid)) ? 0 : $cid;
$mode = ($user->id) ? $user->mode : "threaded";
$order = ($user->id) ? $user->sort : "1";
$threshold = ($user->id) ? $user->threshold : "0";
### Compose story-query:
// Compose story-query:
$result = db_query("SELECT s.*, u.userid FROM stories s LEFT JOIN users u ON s.author = u.id WHERE s.status != 0 AND s.id = $sid");
$story = db_fetch_object($result);
### Display story:
// Display story:
if ($story->status == 1) $theme->article($story, "[ <A HREF=\"submission.php\"><FONT COLOR=\"$theme->hlcolor2\">submission queue</FONT></A> | <A HREF=\"discussion.php?op=reply&sid=$story->id&pid=0\"><FONT COLOR=\"$theme->hlcolor2\">add a comment</FONT></A> ]");
else $theme->article($story, "[ <A HREF=\"\"><FONT COLOR=\"$theme->hlcolor2\">home</FONT></A> | <A HREF=\"discussion.php?op=reply&sid=$story->id&pid=0\"><FONT COLOR=\"$theme->hlcolor2\">add a comment</FONT></A> ]");
### Display `comment control'-box:
// Display `comment control'-box:
if ($user->id) $theme->commentControl($sid, $title, $threshold, $mode, $order);
### Compose query:
// Compose query:
$query .= "SELECT c.*, u.* FROM comments c LEFT JOIN users u ON c.author = u.id WHERE c.sid = $sid AND c.pid = $pid AND (c.votes = 0 OR c.score / c.votes >= $threshold)";
if ($order == 1) $query .= " ORDER BY c.timestamp DESC";
if ($order == 2) $query .= " ORDER BY c.score DESC";
......@@ -119,9 +119,9 @@ function discussion_display($sid, $pid, $cid, $level = 0) {
print "<FORM METHOD=\"post\" ACTION=\"discussion.php\">\n";
### Display the comments:
// Display the comments:
while ($comment = db_fetch_object($result)) {
### Dynamically compose the `reply'-link:
// Dynamically compose the `reply'-link:
if ($pid != 0) {
list($pid) = db_fetch_row(db_query("SELECT pid FROM comments WHERE cid = $comment->pid"));
$link = "<A HREF=\"discussion.php?id=$comment->sid&pid=$pid#$pid\"><FONT COLOR=\"$theme->hlcolor2\">return to parent</FONT></A> | <A HREF=\"discussion.php?op=reply&sid=$comment->sid&pid=$comment->cid\"><FONT COLOR=\"$theme->hlcolor2\">reply to this comment</FONT></A>";
......@@ -130,7 +130,7 @@ function discussion_display($sid, $pid, $cid, $level = 0) {
$link = "<A HREF=\"discussion.php?op=reply&sid=$comment->sid&pid=$comment->cid\"><FONT COLOR=\"$theme->hlcolor2\">reply to this comment</FONT></A> ";
}
### Display the comments:
// Display the comments:
if (empty($mode) || $mode == "threaded") {
$thread = discussion_childs($comment->cid, $threshold);
$theme->comment(new Comment($comment->userid, $comment->subject, $comment->comment, $comment->timestamp, $comment->url, $comment->fake_email, discussion_score($comment), $comment->votes, $comment->cid), $link, $thread);
......@@ -149,7 +149,7 @@ function discussion_display($sid, $pid, $cid, $level = 0) {
function discussion_reply($pid, $sid) {
global $user, $theme, $allowed_html;
### Extract parent-information/data:
// Extract parent-information/data:
if ($pid) {
$item = db_fetch_object(db_query("SELECT comments.*, users.userid FROM comments LEFT JOIN users ON comments.author = users.id WHERE comments.cid = $pid"));
$theme->comment(new Comment($item->userid, $item->subject, $item->comment, $item->timestamp, $item->url, $item->fake_email, discussion_score($comment), $comment->votes, $item->cid), "reply to this comment");
......@@ -159,33 +159,33 @@ function discussion_reply($pid, $sid) {
$theme->article($item, "");
}
### Build reply form:
// Build reply form:
$output .= "<FORM ACTION=\"discussion.php\" METHOD=\"post\">\n";
### Name field:
// Name field:
$output .= "<P>\n";
$output .= " <B>Your name:</B><BR>\n";
$output .= format_username($user->userid);
$output .= "</P>\n";
### Subject field:
// Subject field:
$output .= "<P>\n";
$output .= " <B>Subject:</B><BR>\n";
$output .= " <INPUT TYPE=\"text\" NAME=\"subject\" SIZE=\"50\" MAXLENGTH=\"60\">\n";
$output .= "</P>\n";
### Comment field:
// Comment field:
$output .= "<P>\n";
$output .= " <B>Comment:</B><BR>\n";
$output .= " <TEXTAREA WRAP=\"virtual\" COLS=\"50\" ROWS=\"10\" NAME=\"comment\">". check_output(check_field($user->signature)) ."</TEXTAREA><BR>\n";
$output .= " <SMALL><I>Allowed HTML tags: ". htmlspecialchars($allowed_html) .".</I></SMALL>\n";
$output .= "</P>\n";
### Hidden fields:
// Hidden fields:
$output .= "<INPUT TYPE=\"hidden\" NAME=\"pid\" VALUE=\"$pid\">\n";
$output .= "<INPUT TYPE=\"hidden\" NAME=\"sid\" VALUE=\"$sid\">\n";
### Preview button:
// Preview button:
$output .= "<INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Preview comment\"> (You must preview at least once before you can submit.)\n";
$output .= "</FORM>\n";
......@@ -195,32 +195,32 @@ function discussion_reply($pid, $sid) {
function comment_preview($pid, $sid, $subject, $comment) {
global $user, $theme, $allowed_html;
### Preview comment:
// Preview comment:
$theme->comment(new Comment($user->userid, $subject, $comment, time(), $user->url, $user->fake_email, "", "", ""), "reply to this comment");
### Build reply form:
// Build reply form:
$output .= "<FORM ACTION=\"discussion.php\" METHOD=\"post\">\n";
### Name field:
// Name field:
$output .= "<P>\n";
$output .= " <B>Your name:</B><BR>\n";
$output .= format_username($user->userid);
$output .= "</P>\n";
### Subject field:
// Subject field:
$output .= "<P>\n";
$output .= " <B>Subject:</B><BR>\n";
$output .= " <INPUT TYPE=\"text\" NAME=\"subject\" SIZE=\"50\" MAXLENGTH=\"60\" VALUE=\"". check_output(check_field($subject)) ."\">\n";
$output .= "</P>\n";
### Comment field:
// Comment field:
$output .= "<P>\n";
$output .= " <B>Comment:</B><BR>\n";
$output .= " <TEXTAREA WRAP=\"virtual\" COLS=\"50\" ROWS=\"10\" NAME=\"comment\">". check_output(check_field($comment)) ."</TEXTAREA><BR>\n";
$output .= " <SMALL><I>Allowed HTML tags: ". htmlspecialchars($allowed_html) .".</I></SMALL>\n";
$output .= "</P>\n";
### Hidden fields:
// Hidden fields:
$output .= "<INPUT TYPE=\"hidden\" NAME=\"pid\" VALUE=\"$pid\">\n";
$output .= "<INPUT TYPE=\"hidden\" NAME=\"sid\" VALUE=\"$sid\">\n";
......@@ -230,7 +230,7 @@ function comment_preview($pid, $sid, $subject, $comment) {
$outout .= "</P>\n";
}
### Preview and submit button:
// Preview and submit button:
$output .= "<P>\n";
$output .= " <INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Preview comment\">\n";
$output .= " <INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Post comment\">\n";
......@@ -243,10 +243,10 @@ function comment_preview($pid, $sid, $subject, $comment) {
function comment_post($pid, $sid, $subject, $comment) {
global $user, $theme;
### Check for fake threads:
// Check for fake threads:
$fake = db_result(db_query("SELECT COUNT(id) FROM stories WHERE id = $sid"), 0);
### Check for duplicate comments:
// Check for duplicate comments:
$duplicate = db_result(db_query("SELECT COUNT(cid) FROM comments WHERE pid = '$pid' AND sid = '$sid' AND subject = '". check_input($subject) ."' AND comment = '". check_input($comment) ."'"), 0);
if ($fake != 1) {
......@@ -258,16 +258,16 @@ function comment_post($pid, $sid, $subject, $comment) {
$theme->box("duplicate comment", "duplicate comment: $duplicate");
}
else {
### Validate subject:
// Validate subject:
$subject = ($subject) ? $subject : substr($comment, 0, 29);
### Add watchdog entry:
// Add watchdog entry:
watchdog("comment", "discussion: added comment with subject '$subject'");
### Add comment to database:
// Add comment to database:
db_query("INSERT INTO comments (pid, sid, author, subject, comment, hostname, timestamp) VALUES ($pid, $sid, '$user->id', '". check_input($subject) ."', '". check_input($comment) ."', '". getenv("REMOTE_ADDR") ."', '". time() ."')");
### Compose header:
// Compose header:
header("Location: discussion.php?id=$sid");
}
}
......@@ -275,7 +275,7 @@ function comment_post($pid, $sid, $subject, $comment) {
include "includes/common.inc";
include "includes/comment.inc";
### Security check:
// Security check:
if (strstr($id, " ") || strstr($pid, " ") || strstr($sid, " ") || strstr($mode, " ") || strstr($order, " ") || strstr($threshold, " ")) {
watchdog("error", "discussion: attempt to provide malicious input through URI");
exit();
......
......@@ -12,10 +12,10 @@
function ban_match($mask, $category) {
### Perform query:
// Perform query:
$result = db_query("SELECT * FROM bans WHERE type = $category AND LOWER('$mask') LIKE LOWER(mask)");
### Return result:
// Return result:
return db_fetch_object($result);
}
......@@ -32,7 +32,7 @@ function ban_add($mask, $category, $reason, $message = "") {
$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:
// Add log entry:
watchdog("message", "added new ban `$mask' to category `". $index2type[$category] ."' with reason `$reason'.");
}
}
......@@ -43,10 +43,10 @@ function ban_delete($id) {
$result = db_query("SELECT * FROM bans WHERE id = $id");
if ($ban = db_fetch_object($result)) {
### Perform query:
// Perform query:
$result = db_query("DELETE FROM bans WHERE id = $id");
### Deleted log entry:
// Deleted log entry:
watchdog("message", "removed ban `$ban->mask' from category `". $index2type[$ban->type] ."'.");
}
}
......
......@@ -8,8 +8,8 @@
include_once "includes/theme.inc";
include_once "includes/user.inc";
global $user;
session_start();
$theme = load_theme();
?>
?>
\ No newline at end of file
......@@ -41,7 +41,7 @@ function db_fetch_array($qid) {
if ($qid) return mysql_fetch_array($qid);
}
function db_result($qid, $field) {
function db_result($qid, $field = 0) {
if ($qid) return mysql_result($qid, $field);
}
......
<?
function id2story($id) {
### Perform query:
$result = db_query("SELECT s.*, u.userid FROM stories s LEFT JOIN users u ON s.author = u.id WHERE s.id = $id");
return db_fetch_object($result);
}
function load_theme() {
global $user, $themes;
......
......@@ -14,20 +14,20 @@ function submission_vote($id, $vote, $comment) {
global $user, $submission_post_threshold, $submission_dump_threshold;
if (!user_getHistory($user->history, "s$id")) {
### Update submission's score- and votes-field:
// Update submission's score- and votes-field:
db_query("UPDATE stories SET score = score $vote, votes = votes + 1 WHERE id = $id");
### Update the comments (if required):
// Update the comments (if required):
if ($comment) {
watchdog("comment", "moderation: added comment with subject '$subject'");
db_query("INSERT INTO comments (sid, author, subject, comment, hostname, timestamp) VALUES($id, $user->id, '". check_input(substr($comment, 0, 29)) ." ...', '". check_input($comment) ."', '". getenv("REMOTE_ADDR") ."', '". time() ."')");
}
### Update user's history record:
// Update user's history record:
user_setHistory($user, "s$id", $vote); // s = submission
### Update story table (if required):
// Update story table (if required):
$result = db_query("SELECT * FROM stories WHERE id = $id");
if ($submission = db_fetch_object($result)) {
if ($submission->score >= $submission_post_threshold) {
......
......@@ -10,7 +10,7 @@ function submission_number() {
return ($result) ? db_result($result, 0) : 0;
}
### Display account settings:
// Display account settings:
$content .= "<LI><A HREF=\"account.php?op=track&topic=comments\">track your comments</A></LI>\n";
$content .= "<LI><A HREF=\"account.php?op=track&topic=stories\">track your stories</A></LI>\n";
$content .= "<LI><A HREF=\"account.php?op=track&topic=site\">track $site_name</A></LI>\n";
......@@ -99,7 +99,7 @@ function theme_moderation_results($theme, $story) {
}
function theme_related_links($theme, $story) {
### Parse story for <A HREF="">-tags:
// Parse story for <A HREF="">-tags:
$text = stripslashes("$story->abstract $story->updates $story->article");
while ($text = stristr($text, "<A HREF=")) {
$link = substr($text, 0, strpos(strtolower($text), "</a>") + 4);
......@@ -107,33 +107,15 @@ function theme_related_links($theme, $story) {
if (!stristr($link, "mailto:")) $content .= "<LI>$link</LI>";
}
### Stories in the same category:
// Stories in the same category:
$content .= " <LI>More about <A HREF=\"search.php?category=". urlencode($story->category) ."\">$story->category</A>.</LI>";
### Stories from the same author:
// Stories from the same author:
if ($story->userid) $content .= " <LI>Also by <A HREF=\"search.php?author=". urlencode($story->userid) ."\">$story->userid</A>.</LI>";
$theme->box("Related links", $content);
}
function theme_old_headlines($theme, $num = 10) {
global $user;
if ($user->stories) $result = db_query("SELECT id, subject, timestamp FROM stories WHERE status = 2 ORDER BY timestamp DESC LIMIT $user->stories, $num");
else $result = db_query("SELECT id, subject, timestamp FROM stories WHERE status = 2 ORDER BY timestamp DESC LIMIT $num, $num");
while ($story = db_fetch_object($result)) {
if ($time != date("F jS", $story->timestamp)) {
$content .= "<P><B>". date("l, M jS", $story->timestamp) ."</B></P>\n";
$time = date("F jS", $story->timestamp);
}
$content .= "<LI><A HREF=\"discussion.php?id=$story->id\">$story->subject</A></LI>\n";
}
$content .= "<P ALIGN=\"right\">[ <A HREF=\"search.php\"><FONT COLOR=\"$theme->hlcolor2\">more</FONT></A> ]</P>";
$theme->box("Older headlines", $content);
}
function theme_comment_moderation($id, $author, $score, $votes) {
global $user, $comment_votes;
......@@ -154,9 +136,28 @@ function theme_new_headlines($theme, $num = 10) {
$content = "";
$result = db_query("SELECT id, subject FROM stories WHERE status = 2 ORDER BY id DESC LIMIT $num");
while ($story = db_fetch_object($result)) $content .= "<LI><A HREF=\"discussion.php?id=$story->id\">$story->subject</A></LI>\n";
while ($story = db_fetch_object($result)) $content .= "<LI><A HREF=\"discussion.php?id=$story->id\">". check_output($story->subject) ."</A></LI>\n";
$content .= "<P ALIGN=\"right\">[ <A HREF=\"search.php\"><FONT COLOR=\"$theme->hlcolor2\">more</FONT></A> ]</P>";
$theme->box("Latest headlines", $content);
}
function theme_old_headlines($theme, $num = 10) {
global $user;
if ($user->stories) $result = db_query("SELECT id, subject, timestamp FROM stories WHERE status = 2 ORDER BY timestamp DESC LIMIT $user->stories, $num");
else $result = db_query("SELECT id, subject, timestamp FROM stories WHERE status = 2 ORDER BY timestamp DESC LIMIT $num, $num");
while ($story = db_fetch_object($result)) {
if ($time != date("F jS", $story->timestamp)) {
$content .= "<P><B>". date("l, M jS", $story->timestamp) ."</B></P>\n";
$time = date("F jS", $story->timestamp);
}
$content .= "<LI><A HREF=\"discussion.php?id=$story->id\">". check_output($story->subject) ."</A></LI>\n";
}
$content .= "<P ALIGN=\"right\">[ <A HREF=\"search.php\"><FONT COLOR=\"$theme->hlcolor2\">more</FONT></A> ]</P>";
$theme->box("Older headlines", $content);
}
?>
......@@ -42,7 +42,7 @@ function user_setHistory(&$user, $field, $value) {
$history = $user->history;
if (!$value) {
### remove entry:
// remove entry:
$data = explode(";", $history);
for (reset($data); current($data); next($data)) {
$entry = explode(":", current($data));
......@@ -50,7 +50,7 @@ function user_setHistory(&$user, $field, $value) {
}
}
else if (strstr($history, "$field:")) {
### found: update exsisting entry:
// found: update exsisting entry:
$data = explode(";", $history);
for (reset($data); current($data); next($data)) {
$entry = explode(":", current($data));
......@@ -59,12 +59,12 @@ function user_setHistory(&$user, $field, $value) {
}
}
else {
### not found: add new entry:
// not found: add new entry:
$rval = "$history$field:$value;";
}
$user->history = $rval;
### save new history:
// save new history:
$query .= "UPDATE users SET ";
foreach ($user->field as $key=>$field) { $value = $user->$field; $query .= "$field = '". addslashes($value) ."', "; }
$query .= " id = $user->id WHERE id = $user->id";
......@@ -75,4 +75,4 @@ function user_clean() {
// todo - called by cron job
}
?>
?>
\ No newline at end of file
......@@ -10,7 +10,7 @@ function submission_number() {
return ($result) ? db_result($result, 0) : 0;
}
### Display account settings:
// Display account settings:
$content .= "<LI><A HREF=\"account.php?op=track&topic=comments\">track your comments</A></LI>\n";
$content .= "<LI><A HREF=\"account.php?op=track&topic=stories\">track your stories</A></LI>\n";
$content .= "<LI><A HREF=\"account.php?op=track&topic=site\">track $site_name</A></LI>\n";
......@@ -91,7 +91,7 @@ function display_moderation_results($theme, $story) {
}
function display_related_links($theme, $story) {
### Parse story for <A HREF="">-tags:
// Parse story for <A HREF="">-tags:
$text = stripslashes("$story->abstract $story->updates $story->article");
while ($text = stristr($text, "<A HREF=")) {
$link = substr($text, 0, strpos(strtolower($text), "</a>") + 4);
......@@ -99,10 +99,10 @@ function display_related_links($theme, $story) {
if (!stristr($link, "mailto:")) $content .= "<LI>$link</LI>";
}
### Stories in the same category:
// Stories in the same category:
$content .= " <LI>More about <A HREF=\"search.php?category=". urlencode($story->category) ."\">$story->category</A>.</LI>";
### Stories from the same author:
// Stories from the same author:
if ($story->userid) $content .= " <LI>Also by <A HREF=\"search.php?author=". urlencode($story->userid) ."\">$story->userid</A>.</LI>";
$theme->box("Related links", $content);
......
......@@ -2,20 +2,20 @@
include "includes/common.inc";
### Security check:
// Security check:
if (strstr($number, " ") || strstr($date, " ")) {
watchdog("error", "main page: attempt to provide malicious input through URI");
exit();
}
### Initialize/pre-process variables:
// Initialize/pre-process variables:
$number = ($user->stories) ? $user->stories : 10;
$date = ($date) ? $date : time();
### Perform query:
// Perform query:
$result = db_query("SELECT stories.*, users.userid, COUNT(comments.sid) AS comments FROM stories LEFT JOIN comments ON stories.id = comments.sid LEFT JOIN users ON stories.author = users.id WHERE stories.status = 2 AND stories.timestamp <= $date GROUP BY stories.id ORDER BY stories.timestamp DESC LIMIT $number");
### Display stories:
// Display stories:
$theme->header();
while ($story = db_fetch_object($result)) $theme->abstract($story);
$theme->footer();
......
<?
$module = array("block" => "ab_block",
$module = array("help" => "ab_help",
"block" => "ab_block",
"admin" => "ab_admin");
function ab_help() {
?>
<P>The content of the site can be almost entirely altered by means of blocks. Simply put, <I>admin blocks</I> are small bit of PHP code which will get plugged into the site. Admin blocks are typically used to add custom blocks to the site.</P>
<P>If you know how to script in PHP, admin blocks are pretty simple to create. Don't get your panties in a knot if you are not confident with PHP: simply use the standard admin blocks (i.e. those available by default) as they are just fine or ask an expert 'admin blocker' to help you creating custom admin blocks that fit your need.</P>
<P>Each admin block consists of a key of maximum 255 characters and an associated block of PHP code which can be as long as you want it to be. You can use any piece of PHP code to make up an admin block. A admin block's code is stored in the database and the engine or a particular module will use the key to find the associated piece of PHP code which will then be dynamically embedded in the engine or the module just-in-time for execution.</P>
<P>There are however some factors to keep in mind when using and creating admin blocks: admin blocks can be extremly useful and flexible, yet be dangerous and insecure if not properly used. If you are not confident with PHP, SQL or even with the site engine for that matter, avoid experimenting with admin blocks because you can - and you probably will - corrupt your database or even break your site! If you don't plan to do fancy stuff with admin blocks then you are probably save.</P>
<P>Remember that the code within each admin block must be valid PHP code, including things like terminating statements with a semicolon so the parser won't die. Therefore, it is highly recommended to test your admin blocks seperatly using a simple test script on top of a test database before migrating to your production environment running your real database.</P>
<P>Note that you can use any global variables, such as configuration parameters within the scope of an admin block and keep in mind that variables that have been given values in an admin block will retain these values in the engine or module afterwards.</P>
<P>You may as well use the <CODE>return</CODE> statement to return the actual content of the block.</P>
<P><U>A basic example:</U></P>
<P>Given the admin block with subject "Welcome", used to create a Welcome-block. The content for this admin block could be created by using:</P>
<PRE>
return "Welcome visitor, ... welcome message goes here ...";
</PRE>
<P>If we are however dealing with a registered user, we can customize the message by using:
<PRE>
if ($user) {
return "Welcome $user->userid, ... weclome message goes here ...";
}
else {
return "Welcome visitor, ... welcome message goes here ...";
}
</PRE>
<P>For more in depth example, we recommand you to check any of the available admin blocks and to go from there.</P>
<P>As said above, you can virtually use any piece of PHP code in an admin block: you can declare and use functions, consult the SQL database, access configuration settings and so on.</P>
<?
}
function ab_block() {
$result = db_query("SELECT * FROM admin_blocks");
$i = 0;
......
......@@ -2,8 +2,6 @@
$module = array("admin" => "cron_admin");
include_once "includes/function.inc";
function cron_save($edit) {
foreach ($edit as $key=>$value) {
db_query("UPDATE crons SET scheduled = '$value' WHERE module = '$key'");
......
......@@ -3,164 +3,241 @@
$module = array("page" => "documentation",
"admin" => "documentation");
function documentation_module($name, $module) {
print "<H2>". ucfirst($name) ."</H2>\n";
if ($module["help"]) $module["help"]();
else print "<I>No documentation available for module '$name'.</I>\n";
}
function documentation() {
?>
<SMALL><I>$Id$</I></SMALL>
<H2>Chapter 1: installation guide</H2>
<H3>System requirements</H3>
<P>We assume that you have some working experience with Apache, MySQL and PHP. The installation of these required packages is beyond the scope of this document.</P>
<H1>Chapter 1: introduction</H1>
<P>Drupal (which is the English pronounciation of the dutch word 'druppel' that stands for 'drop') is a full-featured content management/discussion engine suitable to setup a news-driven community or portal site. Drupal aims towards easy installation, exessive configuration and fine-grained maintainance capabilities.</P>
<P>Drupal build after Slash (<A HREF="http://slashcode.com/">http://slashcode.com/</A>) and Scoop (<A HREF="http://scoop.kuro5hin.org/">http://scoop.kuro5hin.org/</A>).</P>
<H1>Chapter 2: installation</H1>
<H2>System requirements</H2>
MySQL<BLOCKQUOTE><A HREF="http://mysql.com/">http://mysql.com/</A><BR>(development with version 3.22.32)</BLOCKQUOTE>
PHP4<BLOCKQUOTE><A HREF="http://php.net/">http://php.net/</A><BR>(development with version 4.0.0 and 4.0.4)</BLOCKQUOTE>
Apache<BLOCKQUOTE><A HREF="http://apache.org/">http://apache.org/</A><BR>(development with version 1.3.14)</BLOCKQUOTE>
<H2>Installation process</H2>
<P><B>1.</B> We assume that you have some working experience with Apache, MySQL and PHP. If you still need to install Apache, MySQL or PHP, please install them now. The installation of these required packages is beyond the scope of this document but make sure your Apache is setup to allow <CODE>.htaccess</CODE> files so that we can override Apache options from within the drupal directories.</P>
<P><B>2.</B> Unzip the distribution tarball into the directory you want to serve web files from:</P>
<BLOCKQUOTE>$ tar -zxvf drupal-x.x.x.tar.gz</BLOCKQUOTE>
<P><B>3.</B> Create a MySQL database for your drupal site (if not already done so):</P>
<BLOCKQUOTE>$ mysqladmin create &lt;database&gt;</BLOCKQUOTE>
<P>Make sure to check the MySQL documentation on how to setup the right access rights and permissions in your MySQL grant table.</P>
<P><B>4.</B> Once you have a proper database, dump the required tables into your database:</P>
<BLOCKQUOTE>$ mysql -h &lt;hostname&gt; -u &lt;username&gt; -p&lt;password&gt; &lt;database&gt; < ./database/databasy.mysql </BLOCKQUOTE>
<P><B>5.</B> Copy the file <CODE>includes/hostname.conf</CODE> to match your server's hostname:</P>
<BLOCKQUOTE>$ cp ./includes/hostname.conf ./includes/www.yourdomain.com.conf</BLOCKQUOTE>
<P><B>6.</B> Edit your configuration file to set the required settings such as the database options and to customize your site to your likings.</P>
<P><B>7.</B> Launch your browser and point it to http://yourdomain.com/, create an account, log in and head on to http://yourdomain.com/admin.php. The first user will automatically have administrator permissions. Play with it for a bit and spend some time getting used to the administration interfaces.</P>
<P><B>8. (optional)</B> Optionally (yet recommended for a smooth operation) setup a crontab to periodically visit http://yourdomain.com/cron.php.</P>
<P>Use a browser like lynx or wget but make sure the process terminates: either use /usr/bin/lynx -source http://yourdomain.com/cron.php or /usr/bin/wget -O /dev/null http://yourdomain.com/cron.php. Take a look at the example scripts in the <CODE>scripts</CODE>-directory and make sure to adjust them to your needs.</P>
<P>A good crontab-line to run the cron-script once every hour would be:</P>
<PRE>
MySQL - http://mysql.com/
(development with version 3.22.32)
PHP4 - http://php.net/
(development with version 4.0.0)
Apache - http://apache.org/
(development with version 1.3.14)
00 * * * * /home/www/drupal/scripts/cron-lynx
</PRE>
<P><B>9. (optional)</B> Create your site's theme or at least customize the existing themes. To get started, head on to the <CODE>themes</CODE>-directory and make a custom logo for each theme.
<P><B>10. (optional)</B> Add and remove modules to customize the functionality of your site. Adding and removing modules is plain easy. You can add a module by copying the files into the <CODE>modules</CODE>-directory and you can remove a module by removing a module's file from the <CODE>modules</CODE>-directory. The drupal engine will then automatically include or exclude this module. If for some reason, this seems to fail, "manually" rehash the modules list from http://yourdomain.com/admin.php?mod=module.</P>
<P><B>11.</B> If you get is to run, let us know at <A HREF="mailto:info@drop.org">info@drop.org</A> so we can add your site to our list of drupal sites. If you can't get it to run, you can find support at the drupal site or you can contact us by e-mail at <A HREF="mailto:info@drop.org">info@drop.org</A>.</P>
<H3>Installation process</H3>
<H2>More than one (sub)domain on one machine</H2>
<H3>More than one engines on one machine</H3>
<H3>Multiple (sub)domains using the same database</H3>
<P>If you want to host multiple domains (or subdomains) on top of the same database (e.g. http://yourdomain.com/ and http://www.yourdomain.com/), simply use symbolic links to setup the required configuration files:</P>
<BLOCKQUOTE>$ ln -s includes/yourserver.com.conf includes/www.yourserver.com.conf</BLOCKQUOTE>
<PRE>
$ ls -l includes/*.conf
-rw-rw-r-- 1 drupal drupal includes/yourdomain.com.conf
lrwxrwxrrx 1 drupal drupal includes/www.yourdomain.com.conf -> includes/yourdomain.com.conf
</PRE>
<H3>Multiple (sub)domains using different databases</H3>
<P>Apache supports both IP- and name-based virtual hosts (vhosts). While running more than one engine (by using vhosts) can be very useful for development and testing purpose, it might even be more interesting for hosting companies. Therefore, we tried to support vhosts in the best possible way in order to make life of any administrator easier. We do so by making it possible to run an unlimited amount of vhosts on the same physical source tree, though by using different configuration files. Moreover, you can setup multiple configuration files in your <CODE>includes</CODE>-directory.</P>
<PRE>
[drop@localhost drop]$ ls -l includes/*.conf
-rw-rw-r-- 1 drop drop includes/www.yourdomain1.com.conf
-rw-rw-r-- 1 drop drop includes/www.yourdomain2.com.conf
$ ls -l includes/*.conf
-rw-rw-r-- 1 drupal drupal includes/www.yourdomain1.com.conf
-rw-rw-r-- 1 drupal drupal includes/www.yourdomain2.com.conf
</PRE>