diff options
author | Dries Buytaert <dries@buytaert.net> | 2000-10-10 10:52:19 +0000 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2000-10-10 10:52:19 +0000 |
commit | 4a6c6de758960a2f98ba58f20a1c17c6ee67111c (patch) | |
tree | d0466a04feb29ce5769d90ffb8041b78412faa82 /includes | |
parent | 73077e8778cfd890f51023f6683e70904317cc6f (diff) | |
download | brdo-4a6c6de758960a2f98ba58f20a1c17c6ee67111c.tar.gz brdo-4a6c6de758960a2f98ba58f20a1c17c6ee67111c.tar.bz2 |
Huge update - I don't have time to write everything down but the directory
structure changes, some sections are expanded. Take a look at the source
code or ask me to elaborate on certain issues/topics.
Diffstat (limited to 'includes')
-rw-r--r-- | includes/admin.inc | 78 | ||||
-rw-r--r-- | includes/backend.inc | 241 | ||||
-rw-r--r-- | includes/ban.inc | 52 | ||||
-rw-r--r-- | includes/calendar.inc | 76 | ||||
-rw-r--r-- | includes/config.inc | 115 | ||||
-rw-r--r-- | includes/database.inc | 62 | ||||
-rw-r--r-- | includes/function.inc | 106 | ||||
-rw-r--r-- | includes/log.inc | 17 | ||||
-rw-r--r-- | includes/submission.inc | 35 | ||||
-rw-r--r-- | includes/template.inc | 128 | ||||
-rw-r--r-- | includes/theme.inc | 11 | ||||
-rw-r--r-- | includes/user.inc | 83 |
12 files changed, 1004 insertions, 0 deletions
diff --git a/includes/admin.inc b/includes/admin.inc new file mode 100644 index 000000000..4d0ed0dda --- /dev/null +++ b/includes/admin.inc @@ -0,0 +1,78 @@ +<? + + +function admin_icon($name) { + global $section; + if ($name == $section) print " <TD ALIGN=\"center\" BGCOLOR=\"#CCCCCC\"><A HREF=\"admin.php?section=$name\"><IMG SRC=\"images/admin-$name.png\" BORDER=\"0\"></A><BR>$name</TD>\n"; + else print " <TD ALIGN=\"center\" VALIGN=\"middle\"><A HREF=\"admin.php?section=$name\"><IMG SRC=\"images/admin-$name.png\" BORDER=\"0\"></A><BR>$name</TD>\n"; +} + +function admin_header() { + global $sitename, $section, $status; + + ?> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> + <HTML> + <HEAD><TITLE><? echo $sitename; ?> administration center</TITLE></HEAD> + <STYLE> + body { font-family: helvetica, arial; } + h1 { font-size: 14pt; font-weight: bold; color: #006699; } + h2 { font-family: helvetica, arial; font-size: 12pt; font-weight: bold; } + h3 { font-family: helvetica, arial; font-size: 14pt; font-weight: bold; } + th { font-family: helvetica, arial; text-align: center; background-color: #CCCCCC; color: #885555; } + td { font-family: helvetica, arial; } + </STYLE> + <BODY BGCOLOR="#FFFFFF" LINK="#006699" VLINK="#004499" ALINK="#FF0000"> + <TABLE BORDER="0" CELLPADDING="0" CELLSPACING="2" WIDTH="780"> + <TR><TD COLSPAN="10"><H1><? echo "$sitename"; ?> administration center</H1></TD></TR> + <TR><TD BGCOLOR="#000000" COLSPAN="10" WIDTH="100%"><IMG SRC="images/pixel.gif" WIDTH="1" HEIGHT="1" ALT=""></TD></TR> + <TR> + <? + admin_icon("stories"); + admin_icon("comments"); + admin_icon("diaries"); + admin_icon("accounts"); + admin_icon("misc"); + admin_icon("bans"); + admin_icon("logs"); + admin_icon("stats"); + admin_icon("info"); + admin_icon("home"); + ?> + </TR> + <TR><TD BGCOLOR="#000000" COLSPAN="10" WIDTH="100%"><IMG SRC="images/pixel.gif" WIDTH="1" HEIGHT="0" ALT=""></TD></TR> + <TR><TD COLSPAN="10"> </TD></TR> + <? + if ($status) { + ?> + <TR><TD COLSPAN="10"><BIG><B>status:</B> <? echo $status; ?></BIG></TD></TR> + <TR><TD COLSPAN="10"> </TD></TR> + <? + } + ?> + <TR> + <TD COLSPAN="10"> + <? +} + +function admin_box($title, $body) { + print "<TABLE BORDER=\"0\" CELLPADDING=\"0\" CELLSPACING=\"2\" WIDTH=\"100%\">\n"; + print " <TR><TD><FONT COLOR=\"#83997A\"><B>$title</B></A></TD></TR>\n"; + print " <TR><TD BGCOLOR=\"#000000\" WIDTH=\"100%\"><IMG SRC=\"images/pixel.gif\" WIDTH=\"1\" HEIGHT=\"0\" ALT=\"\"></TD></TR>\n"; + print " <TR><TD> </TD></TR>\n"; + print " <TR><TD>$body</TD></TR>\n"; + print "</TABLE>\n"; + print "<BR><BR>\n"; +} + +function admin_footer() { + ?> + </TD> + </TR> + </TABLE> + </BODY> + </HTML> + <? +} + +?>
\ No newline at end of file diff --git a/includes/backend.inc b/includes/backend.inc new file mode 100644 index 000000000..30f39c942 --- /dev/null +++ b/includes/backend.inc @@ -0,0 +1,241 @@ +<? + +include "includes/function.inc"; + +class backend { + + // Channel properties: + var $id; + var $url; + var $site; + var $file; + var $contact; + var $timestamp; + + // Contains the raw rdf/rss/xml file: + var $data; + + // Contains the parsed rdf/rss/xml file: + var $headlines = array(); // latest headlines + + + ##### + # Syntax.......: backend(...); + # Description..: Constructor - initializes the internal variables. + # + function backend($id, $site, $url, $file, $contact, $timout = 1800) { + ### Get channel info: + $result = db_query("SELECT * FROM channel WHERE id = '$id' OR site = '$site'"); + + if ($channel = db_fetch_object($result)) { + ### Initialize internal variables: + $this->id = $channel->id; + $this->site = $channel->site; + $this->file = $channel->file; + $this->url = $channel->url; + $this->contact = $channel->contact; + $this->timestamp = $channel->timestamp; + + ### Check to see whether we have to update our headlines first: + if (time() - $this->timestamp > $timout) $this->url2sql(); + + ### Read headlines: + $result = db_query("SELECT * FROM headlines WHERE id = $this->id ORDER BY number"); + while ($headline = db_fetch_object($result)) { + array_push($this->headlines, "<A HREF=\"$headline->link\">$headline->title</A>"); + } + + } + else { + $this->site = $site; + $this->url = $url; + $this->file = $file; + $this->contact = $contact; + } + } + + ##### + # Syntax.......: rdf2sql(optional timout value in seconds); + # Description..: Reads a RDF file from a server, parses it and inserts + # the fresh data in a MySQL table. + # + function rdf2sql($timout = 10) { + if ($this->file) { + ### Decode URL: + $url = parse_url($this->file); + $host = $url[host]; + $port = $url[port] ? $url[port] : 80; + $path = $url[path]; + + // print "<PRE><B>Debug:</B> $url - $host - $port - $path</PRE>"; + + ### Retrieve data from website: + $fp = fsockopen($host, $port, &$errno, &$errstr, $timout); + + if ($fp) { + ### Get data from URL: + fputs($fp, "GET $path HTTP/1.0\n"); + fputs($fp, "User-Agent: headline grabber\n"); + fputs($fp, "Host: ". $host ."\n"); + fputs($fp, "Accept: */*\n\n"); + + while(!feof($fp)) $data .= fgets($fp, 128); + + // print "<PRE>$data</PRE><HR>"; + + if (strstr($data, "200 OK")) { + + ### Remove existing entries: + $result = db_query("DELETE FROM headlines WHERE id = $this->id"); + + ### Strip all 'junk': + $data = ereg_replace("<?xml.*/image>", "", $data); + $data = ereg_replace("</rdf.*", "", $data); + $data = chop($data); + + ### Iterating through our data processing each entry/item: + $items = explode("</item>", $data); + $number = 0; + + for (reset($items); $item = current($items); next($items)) { + ### Extract data: + $link = ereg_replace(".*<link>", "", $item); + $link = ereg_replace("</link>.*", "", $link); + $title = ereg_replace(".*<title>", "", $item); + $title = ereg_replace("</title>.*", "", $title); + + ### Clean headlines: + $title = stripslashes(fixquotes($title)); + + ### Count the number of stories: + $number += 1; + + ### Insert item in database: + $result = db_query("INSERT INTO headlines (id, title, link, number) VALUES('$this->id', '$title', '$link', '$number')"); + } + + ### Mark channels as being updated: + $result = db_query("UPDATE channel SET timestamp = '". time() ."' WHERE id = $this->id"); + $this->timestamp = time(); + } + else print "<HR>RDF parser: 404 error?<BR><BR><PRE>$data</PRE><HR>"; + } + } + } + + + ##### + # Syntax.......: rss2sql(optional timout value in seconds); + # Description..: Reads a RSS file from a server, parses it and inserts + # the fresh data in a MySQL table. + # + function rss2sql($timout = 10) { + print "backend->rss2sql : TODO<BR>"; + } + + + ##### + # Syntax.......: xml2sql(optional timout value in seconds); + # Description..: Reads a XML file from a server, parses it and inserts + # the fresh data in a MySQL table. + # + function xml2sql($timout = 10) { + print "backend->xml2sql : TODO<BR>"; + } + + + ##### + # Syntax.......: url2sql(optional timout value in seconds); + # Description..: Generic function to fetch fresh headlines. It checks whether + # we are dealing with a remote RDF, RSS or XML file and calls + # the appropriate function to fetch the headline. The function + # is an abstraction towards the programmer as he doesn't need + # to know with what file extension we are dealing. + # + function url2sql($timout = 10) { + if (strstr($this->file, ".rdf")) $this->rdf2sql($timout); + if (strstr($this->file, ".rss")) $this->rss2sql($timout); + if (strstr($this->file, ".xml")) $this->xml2sql($timout); + } + + + ##### + # Syntax.......: + # Description..: + # + function displayHeadlines($timout = 1800) { + global $theme; + + ### Get channel info: + $result = db_query("SELECT * FROM channel WHERE site = '$this->site'"); + + if ($this->id) { + + ### Check to see whether we have to update our headlines first: + if (time() - $this->timestamp > $timout) $this->url2sql(); + + ### Grab headlines from database: + $result = db_query("SELECT * FROM headlines WHERE id = $this->id ORDER BY number"); + while ($headline = db_fetch_object($result)) { + $content .= "<LI><A HREF=\"$headline->link\">$headline->title</A></LI>"; + } + ### Add timestamp: + $update = round((time() - $this->timestamp) / 60); + $content .= "<P ALIGN=\"right\">[ <A HREF=\"backend.php?op=reset&site=$this->site\"><FONT COLOR=\"$theme->hlcolor2\">reset</FONT></A> | updated $update min. ago ]</P>"; + + ### Display box: + $theme->box("$this->site", $content); + } + else print "<P>Warning: something whiched happened: specified channel could not be found in database.</P>"; + } + + + ##### + # Syntax.......: add() + # Description..: Adds this backend to the database. + # + function add() { + ### Add channel: + $result = db_query("INSERT INTO channel (site, file, url, contact, timestamp) VALUES ('$this->site', '$this->file', '$this->url', '$this->contact', 42)"); + } + + + ##### + # Syntax.......: delete() + # Description..: Deletes this backend + # + function delete() { + ### Delete channel: + $result = db_query("DELETE FROM channel WHERE id = $this->id"); + + ### Delete headlines: + $result = db_query("DELETE FROM headlines WHERE id = $this->id"); + } + + ##### + # Syntax.......: refresh() + # Description..: Deletes all headlines associated with this backend. + # + function refresh() { + ### Delete headlines: + $result = db_query("DELETE FROM headlines WHERE id = $this->id"); + + ### Mark channel as invalid to enforce an update: + $result = db_query("UPDATE channel SET timestamp = 42 WHERE id = $this->id"); + } + + ##### + # Syntax.......: dump() + # Description..: Dumps the content of this class to screen. + # + function dump() { + print "<B>Dump backend:</B><BR>"; + print "Id: $this->id<BR>"; + print "Site: $this->site<BR>"; + print "URL: $this->url<BR>"; + print "File: $this->file<BR>"; + print "Contact: $this->contact<BR>"; + } +} + +?> diff --git a/includes/ban.inc b/includes/ban.inc new file mode 100644 index 000000000..1d9fa095e --- /dev/null +++ b/includes/ban.inc @@ -0,0 +1,52 @@ +<? + +$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); +} + +function ban_add($mask, $category, $reason, $message = "") { + 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(1, "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(1, "removed ban `$ban->mask' from category `". $index2type[$ban->type] ."'."); + } +} + +?> diff --git a/includes/calendar.inc b/includes/calendar.inc new file mode 100644 index 000000000..561363c33 --- /dev/null +++ b/includes/calendar.inc @@ -0,0 +1,76 @@ +<? + +class calendar { + var $date; + + function calendar($date) { + $this->date = $date; + } + + function display() { + global $PHP_SELF; + + ### Extract information from the given date: + $month = date("n", $this->date); + $year = date("Y", $this->date); + $day = date("d", $this->date); + + ### Extract first day of the month: + $first = date("w", mktime(0, 0, 0, $month, 1, $year)); + + ### Extract last day of the month: + $last = date("t", mktime(0, 0, 0, $month, 1, $year)); + + ### Calculate previous and next months dates: + $prev = mktime(0, 0, 0, $month - 1, $day, $year); + $next = mktime(0, 0, 0, $month + 1, $day, $year); + + ### Generate calendar header: + $output .= "\n<!-- calendar -->\n"; + $output .= "<TABLE WIDTH=\"100%\" BORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"1\">\n"; + $output .= " <TR><TD ALIGN=\"center\" COLSPAN=\"7\"><SMALL><A HREF=\"$PHP_SELF?date=$prev\"><</A> ". date("F Y", $this->date) ." <A HREF=\"$PHP_SELF?date=$next\">></A></SMALL></TD></TR>\n"; + $output .= " <TR><TD ALIGN=\"center\"><SMALL>S</SMALL></TD><TD ALIGN=\"center\"><SMALL>M</SMALL></TD><TD ALIGN=\"center\"><SMALL>T</SMALL></TD><TD ALIGN=\"center\"><SMALL>W</SMALL></TD><TD ALIGN=\"center\"><SMALL>T</SMALL></TD><TD ALIGN=\"center\"><SMALL>F</SMALL></TD><TD ALIGN=\"center\"><SMALL>S</SMALL></TD></TR>\n"; + + ### Initialize temporary variables: + $nday = 1; + $sday = $first; + + ### Loop through all the days of the month: + while ($nday <= $last) { + ### Set up blank days for first week of the month: + if ($first) { + $output .= " <TR><TD COLSPAN=\"$first\"> </TD>\n"; + $first = 0; + } + + ### Start every week on a new line: + if ($sday == 0) $output .= " <TR>\n"; + + ### Print one cell: + $date = mktime(24, 0, 0, $month, $nday, $year); + if ($nday == $day) $output .= " <TD ALIGN=\"center\"><SMALL><B>$nday</B></SMALL></TD>\n"; + else if ($date > time()) $output .= " <TD ALIGN=\"center\"><SMALL>$nday</SMALL></TD>\n"; + else $output .= " <TD ALIGN=\"center\"><SMALL><A HREF=\"$PHP_SELF?date=$date\" STYLE=\"text-decoration: none;\">$nday</A></SMALL></TD>\n"; + + ### Start every week on a new line: + if ($sday == 6) $output .= " </TR>\n"; + + ### Update temporary variables: + $sday++; + $sday = $sday % 7; + $nday++; + } + + ### Complete the calendar: + if ($sday) { + $end = 7 - $sday; + $output .= " <TD COLSPAN=\"$end\"> </TD>\n </TR>\n"; + } + $output .= "</TABLE>\n\n"; + + ### Return calendar: + return $output; + } +} + +?> diff --git a/includes/config.inc b/includes/config.inc new file mode 100644 index 000000000..4d54bca98 --- /dev/null +++ b/includes/config.inc @@ -0,0 +1,115 @@ +<? + +# +# MySQL settings: +# + +$dbhost = "zind.net"; +$dbuname = "dries"; +$dbpass = "Abc123"; +$dbname = "dries"; + +#$dbhost = "localhost"; +#$dbuname = "dries"; +#$dbpass = "oakley"; +#$dbname = "dries"; + +# +# Name of the site +# +$sitename = "drop.org"; + +# +# Contact information: +# The contact information will be used to send out automated mails +# to users, account holders or visitors. +$contact_email = "droppies@zind.net"; +$contact_signature = "Kind regards,\n\n-- the drop.org crew\nhttp://beta.drop.org/"; + +# +# Notify: +# Set to '1' to receive an e-mail when news has been submitted +# through submit.php +# +$notify = 0; + +# +# Notify information: +# The notify information will be used to send out automated mails +# for internal purpose. +# +$notify_email = $contact_email; +$notify_subject = "submission: "; +$notify_message = "New submission: '$subject'\n\n$story"; +$notify_from = "droppies@zind.net"; + +# +# Comment meta reasons: +# +$comment_votes = array("none" => "none", "-1" => "-1", "0" => "0", "+1" => "+ 1", "+2" => "+ 2", "+3" => "+ 3", "+4" => "+ 4", "+5" => "+ 5"); + +# +# Categories: +# +$categories = array("Announcements", + "Arts & Humanities", + "Business & Economy", + "Coding & Webdesign", + "Computers & Internet", + "Drop.org", + "Entertainment", + "Freedom", + "Government", + "News & Media", + "Science", + "Society & Culture"); + +# +# Allowed HTML tags: +# +$allowed_html = "<A><B><BR><DD><DL><DT><EM><HR><I><IL><SMALL><OL><U><UL>"; + +# +# Name of the 'anonymous' user account: +# +$anonymous = "Anonymous Chicken"; + + +# +# Themes: +# +$themes = array("Marvin" => array( + "themes/marvin/marvin.theme", + "white, simple"), + "Zaphod" => array( + "themes/zaphod/zaphod.theme", + "yellow, simple"), + "UnConeD" => array( + "themes/unconed/unconed.theme", + "gray, flashy")); + +# +# Submission moderation votes: +# changing $submission_votes will affect the integrity of your +# database. In short, the database field user.history will +# become invalid, and will need to be reset! Please, do not +# change this setting unless you have an empty database or +# unless you know what you are doing. +$submission_votes = array("neutral (+0)" => "+ 0", + "post it (+1)" => "+ 1", + "dump it (-1)" => "- 1"); + +# +# Submission moderation thresholds: +# +$submission_post_threshold = "2"; +$submission_dump_threshold = "-2"; + +# +# Debug flag: +# Set to '1' if you are using Windows so the engine won't try +# to send out mails and such. When using Unix or Linux, set +# to '0' +$mail = 0; + +?>
\ No newline at end of file diff --git a/includes/database.inc b/includes/database.inc new file mode 100644 index 000000000..3721fbd65 --- /dev/null +++ b/includes/database.inc @@ -0,0 +1,62 @@ +<? +/* + * These functions build the foundation for accessing the database: + * it is a general database abstraction layer suitable for several + * databases. Currently, the only supported database is MySQL but + * it should be straightforward to port it to any other database: + * just adjust the handlers to your needs. + */ + +function db_connect() { + global $dbhost, $dbuname, $dbpass, $dbname; + mysql_pconnect($dbhost, $dbuname, $dbpass) or die(mysql_Error()); + mysql_select_db($dbname) or die ("Unable to select database"); + // NOTE: we are using a persistent connection! +} + +function db_insert($query, $debug = false) { + // NOTE: + // add spam- and/or flood-checks + + db_query($query, $debug); +} + +function db_query($query, $debug = false) { + ### perform query: + $qid = mysql_query($query); + + ### debug output (if required): + if ($debug || empty($qid)) { + print "<PRE>query: ". htmlspecialchars($query) ."<BR>error message: ". mysql_error() ."</PRE>"; + } + + ### return result from query: + return $qid; +} + +function db_fetch_object($qid) { + if ($qid) return mysql_fetch_object($qid); +} + +function db_num_rows($qid) { + if ($qid) return mysql_num_rows($qid); +} + +function db_fetch_row($qid) { + if ($qid) return mysql_fetch_row($qid); +} + +function db_fetch_array($qid) { + if ($qid) return mysql_fetch_array($qid); +} + +function db_result($qid, $field) { + if ($qid) return mysql_result($qid, $field); +} + +# +# Automatically connect to database: +# +db_connect(); + +?>
\ No newline at end of file diff --git a/includes/function.inc b/includes/function.inc new file mode 100644 index 000000000..de2dbaac0 --- /dev/null +++ b/includes/function.inc @@ -0,0 +1,106 @@ +<? + +include "includes/database.inc"; +include "includes/log.inc"; + +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 dbsave($dbase, $data, $id=0) { + foreach ($data as $key=>$value) { + if ($key == "passwd") { $query .= "$key=PASSWORD('". addslashes($value) ."'), "; } + else { $query .= "$key='". addslashes($value) ."', "; } + } + $query = substr($query, 0, -2); + + if (!empty($id)) { db_query("UPDATE $dbase SET $query WHERE id=$id") or die(mysql_error()); return $id; } + else { db_query("INSERT INTO $dbase SET $query") or die(mysql_error()); return mysql_insert_id(); } +} + +function load_theme() { + global $user, $themes; + + if ($user->theme && file_exists($themes[$user->theme][0])) { + include $themes[$user->theme][0]; + } + else { + include $themes[key($themes)][0]; + } + + return new Theme(); +} + +function check_input($message) { + return str_replace("\"", """, stripslashes($message)); +} + +function check_output($message) { + global $allowed_html; + return nl2br(strip_tags(stripslashes($message), $allowed_html)); +} + +function discussion_num_replies($id, $count = 0) { + $result = db_query("SELECT COUNT(cid) FROM comments WHERE pid = $id"); + return ($result) ? mysql_result($result, 0) : 0; +} + +function format_plural($count, $one, $more) { + return ($count == 1) ? "$count $one" : "$count $more"; +} + +function format_date($timestamp, $type = "medium") { + switch ($type) { + case "small": + $date = date("D, m/d/y - H:i", $timestamp); + break; + case "medium": + $date = date("l, m/d/Y - H:i", $timestamp); + break; + case "large": + $date = date("D, M d, Y - H:i", $timestamp); + break; + case "extra large": + $date = date("l, F dS, Y - H:i", $timestamp); + break; + default: + $date = date("D, M d, Y - H:i", $timestamp); + } + return $date; +} + +function format_data($field, $replacement = "<I>n/a</I>") { + return ($field) ? $field : $replacement; +} + +function format_username($username, $admin = 0) { + if ($username) return ($admin) ? "<A HREF=\"admin.php?section=accounts&op=view&name=$username\">$username</A>" : "<A HREF=\"account.php?op=view&name=$username\">$username</A>"; + else { global $anonymous; return $anonymous; } +} + +function format_email_address($address) { + return ($address) ? "<A HREF=\"mailto:$address\">$address</A>" : format_data($address); +} + +function format_url($address, $description = "") { + // POSSIBLE EXTENSIONS: + // 1. add `http://' in case it's missing. + // 2. add a trailing `/' in case it's missing. + // 3. remove any parameters in the URI. + $description = ($description) ? $description : $address; + return ($address) ? "<A HREF=\"$address\">$description</A>" : format_data($address); +} + +function format_story_link($story, $subject = "") { + global $user; + $output .= "<A HREF=\"discussion.php?id=$story->id"; + $output .= ($user->umode) ? "&mode=$user->umode" : "&mode=threaded"; + $output .= ($user->uorder) ? "&order=$user->uorder" : "&order=0"; + $output .= ($user->thold) ? "&thold=$user->thold" : "&thold=0"; + $output .= ($subject) ? "\">$subject</A>" : "\">$story->subject</A>"; + return $output; +} + +?> diff --git a/includes/log.inc b/includes/log.inc new file mode 100644 index 000000000..2883a8d84 --- /dev/null +++ b/includes/log.inc @@ -0,0 +1,17 @@ +<? + + +function watchdog($level, $message) { + global $user; + + ### Perform query to add new log entry: + db_query("INSERT INTO logs (level, timestamp, user, message, hostname) VALUES ($level, '". time() ."', '". addslashes($user->id) ."', '". addslashes($message) ."', '". getenv("REMOTE_ADDR") ."')"); + + ### Periodically remove old log entries: + if (time() % 20 == 0) { + $timestamp = time() - 1209600; // 2 weeks + db_query("DELETE FROM logs WHERE timestamp < $timestamp"); + } +} + +?> diff --git a/includes/submission.inc b/includes/submission.inc new file mode 100644 index 000000000..376c84059 --- /dev/null +++ b/includes/submission.inc @@ -0,0 +1,35 @@ +<? + +function submission_count() { + $result = db_query("SELECT COUNT(id) FROM stories WHERE status = 1"); + return ($result) ? mysql_result($result, 0) : 0; +} + +function submission_score($id) { + $result = db_query("SELECT score FROM stories WHERE id = $id"); + return ($result) ? mysql_result($result, 0) : 0; +} + +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: + db_query("UPDATE stories SET score = score $vote, votes = votes + 1 WHERE id = $id"); + + ### Update the comments (if required): + if ($comment) db_query("INSERT INTO comments (sid, author, subject, comment, hostname, timestamp) VALUES($id, $user->id, '". addslashes(substr($comment, 0, 29)) ." ...', '". addslashes($comment) ."', '". getenv("REMOTE_ADDR") ."', '". time() ."')"); + + ### Update user's history record: + user_setHistory($user, "s$id", $vote); // s = submission + + ### 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) db_query("UPDATE stories SET status = 2, timestamp = '". time() ."' WHERE id = $id"); + if ($submission->score <= $submission_dump_threshold) db_query("UPDATE stories SET status = 0, timestamp = '". time() ."' WHERE id = $id"); + } + } +} + +?>
\ No newline at end of file diff --git a/includes/template.inc b/includes/template.inc new file mode 100644 index 000000000..08d469d94 --- /dev/null +++ b/includes/template.inc @@ -0,0 +1,128 @@ +<? +include "includes/user.inc"; + +function display_morelink($theme, $story) { + return ($story->article) ? "[ <A HREF=\"discussion.php?id=$story->id\"><FONT COLOR=\"$theme->hlcolor2\"><B>read more</B></FONT></A> | ". strlen($story->article) ." bytes | <A HREF=\"discussion.php?id=$story->id\"><FONT COLOR=\"$theme->hlcolor2\">". format_plural($story->comments, "comment", "comments") ."</FONT></A> ]" : "[ <A HREF=\"discussion.php?id=$story->id\"><FONT COLOR=\"$theme->hlcolor2\">". format_plural($story->comments, "comment", "comments") ."</FONT></A> ]"; +} + +function display_moderation_results($theme, $story) { + global $user; + + if ($user->id && $story->id && $vote = user_getHistory($user->history, "s$story->id")) { + $output .= "<P><B>You voted `$vote'.</B></P>\n"; + $output .= "<P>\n"; + $output .= "<B>Other people voted:</B><BR>\n"; + + $result = db_query("SELECT * FROM users WHERE history LIKE '%s$story->id%'"); + while ($account = db_fetch_object($result)) { + $output .= "". format_username($account->userid) ." voted `". user_getHistory($account->history, "s$story->id") ."'.<BR>"; + } + + $theme->box("Moderation results", $output); + } +} + +function display_related_links($theme, $story) { + ### 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); + $text = stristr($text, "</A>"); + if (!stristr($link, "mailto:")) $content .= "<LI>$link</LI>"; + } + + ### 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: + 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 display_old_headlines($theme, $num = 10) { + global $user; + + if ($user->storynum) $result = db_query("SELECT id, subject, timestamp FROM stories WHERE status = 2 ORDER BY timestamp DESC LIMIT $user->storynum, $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>". format_story_link($story) ."</LI>\n"; + } + $content .= "<P ALIGN=\"right\">[ <A HREF=\"search.php\"><FONT COLOR=\"$theme->hlcolor2\">more</FONT></A> ]</P>"; + + $theme->box("Older headlines", $content); +} + +function display_comment_moderation($id, $author, $score, $votes) { + global $user, $comment_votes; + + if ($user && $user->userid != $author && !user_getHistory($user->history, "c$id")) { + $output .= "<SELECT NAME=\"moderate[$id]\">\n"; + foreach ($comment_votes as $key=>$value) $output .= " <OPTION VALUE=\"$value\">$key</OPTION>\n"; + $output .= "</SELECT>\n"; + } + else { + $output .= "<TABLE BORDER=\"0\" CELLSPACING=\"1\" CELLPADDING=\"0\"><TR><TD>score:</TD><TD>$score</TD></TR><TR><TD>votes:</TD><TD>$votes</TR></TABLE>"; + } + + print $output; +} + +function display_new_diaries($theme, $num = 20) { + $result = db_query("SELECT u.userid, d.timestamp FROM diaries d LEFT JOIN users u ON d.author = u.id ORDER BY timestamp DESC LIMIT $num"); + + while ($diary = db_fetch_object($result)) { + if ($time != date("F jS", $diary->timestamp)) { + $content .= "<P><B>". date("l, M jS", $diary->timestamp) ."</B></P>\n"; + $time = date("F jS", $diary->timestamp); + } + $content .= "<LI><A HREF=\"diary.php?op=view&name=$diary->userid\">$diary->userid</A></LI>\n"; + } + $content .= "<P ALIGN=\"right\">[ <A HREF=\"diary.php\"><FONT COLOR=\"$theme->hlcolor2\">more</FONT></A> ]</P>"; + $theme->box("Recent diary entries", $content); +} + +function display_new_headlines($theme, $num = 10) { + global $user; + + $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>". format_story_link($story) ."</LI>\n"; + $content .= "<P ALIGN=\"right\">[ <A HREF=\"search.php\"><FONT COLOR=\"$theme->hlcolor2\">more</FONT></A> ]</P>"; + $theme->box("Latest headlines", $content); +} + +function display_calendar($theme, $date) { + include "includes/calendar.inc"; + $calendar = new calendar($date); + $theme->box("Browse archives", $calendar->display()); +} + +function display_account($theme) { + global $user; + + if ($user && $user->userid) { + function submission_number() { + $result = db_query("SELECT COUNT(id) FROM stories WHERE status = 1"); + return ($result) ? mysql_result($result, 0) : 0; + } + + ### Display account settings: + $content = "<LI><A HREF=\"account.php\">view your information</A></LI>"; + $content .= "<LI><A HREF=\"account.php?op=user\">edit your information</A></LI>"; + $content .= "<LI><A HREF=\"account.php?op=page\">customize your page</A></LI>"; + $content .= "<LI><A HREF=\"account.php?op=discussion\">track your comments</A></LI>"; + $content .= "<LI><A HREF=\"submission.php\">moderate submissions</A> (<FONT COLOR=\"red\">". submission_number() ."</FONT>)</LI>"; + $content .= "<LI><A HREF=\"diary.php?op=view&name=$user->userid\">update your diary</A></LI>"; + $content .= "<LI><A HREF=\"account.php?op=logout\">logout</A></LI>"; + + $theme->box("$user->userid's account", "$content"); + } +} + +?> diff --git a/includes/theme.inc b/includes/theme.inc new file mode 100644 index 000000000..93c6b62ff --- /dev/null +++ b/includes/theme.inc @@ -0,0 +1,11 @@ +<? + +include "includes/config.inc"; +include "includes/function.inc"; +include "includes/template.inc"; + +global $user; + +$theme = load_theme(); + +?>
\ No newline at end of file diff --git a/includes/user.inc b/includes/user.inc new file mode 100644 index 000000000..115c940c0 --- /dev/null +++ b/includes/user.inc @@ -0,0 +1,83 @@ +<? + +$access = array("Administrator" => 0x00000001, + "User manager" => 0x00000002, + "News manager" => 0x00000004); + +class User { + function User($userid, $passwd="") { + $result = db_query("SELECT * FROM users WHERE LOWER(userid) = LOWER('$userid') && passwd = PASSWORD('$passwd') && STATUS = 0"); + if (db_num_rows($result) == 1) { + foreach (db_fetch_row($result) as $key=>$value) { $field = mysql_field_name($result, $key); $this->$field = stripslashes($value); $this->field[] = $field; } + } + } +} + +function user_save() { + global $user; + ### Compose query to update user record: +} + +function user_rehash() { + global $user; + $result = db_query("SELECT * FROM users WHERE id=$user->id"); + if (db_num_rows($result) == 1) { + foreach (db_fetch_array($result) as $key=>$value) { $user->$key = stripslashes($value); } + } +} + +function user_valid($access = 0) { + global $user; + if ($user->userid) { + user_rehash(); // synchronisation purpose + $user->last_access = time(); + $user->last_host = ($GLOBALS[REMOTE_HOST]) ? $GLOBALS[REMOTE_HOST] : $GLOBALS[REMOTE_ADDR]; + db_query("UPDATE users SET last_access = '$user->last_access', last_host = '$user->last_host' WHERE id = $user->id"); + if ($user->access & $access || $access == 0) return 1; + } + return 0; +} + +function user_getHistory($history, $field) { + $data = explode(";", $history); + for (reset($data); current($data); next($data)) { + $entry = explode(":", current($data)); + if (reset($entry) == $field) $rval = end($entry); + } + return $rval; +} + +function user_setHistory(&$user, $field, $value) { + + $history = $user->history; + if (!$value) { + ### remove entry: + $data = explode(";", $history); + for (reset($data); current($data); next($data)) { + $entry = explode(":", current($data)); + if ($entry[0] != $field) $rval .= "$entry[0]:$entry[1];"; + } + } + else if (strstr($history, "$field:")) { + ### found: update exsisting entry: + $data = explode(";", $history); + for (reset($data); current($data); next($data)) { + $entry = explode(":", current($data)); + if ($entry[0] == $field) $entry[1] = $value; + $rval .= "$entry[0]:$entry[1];"; + } + } + else { + ### not found: add new entry: + $rval = "$history$field:$value;"; + } + $user->history = $rval; + + ### 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"; + db_query($query); +} + +?> |