Commit 336b713a authored by Dries's avatar Dries

- A large batch of updates, amongst them a rewritten node system.  More
  information available on the mailing list.
parent aafedfb3
...@@ -51,5 +51,5 @@ function admin_page($mod) { ...@@ -51,5 +51,5 @@ function admin_page($mod) {
if (user_access("access administration pages")) { if (user_access("access administration pages")) {
admin_page($mod); admin_page($mod);
} }
?> ?>
\ No newline at end of file
...@@ -18,5 +18,5 @@ ...@@ -18,5 +18,5 @@
foreach (module_list() as $module) { foreach (module_list() as $module) {
module_invoke($module, "cron"); module_invoke($module, "cron");
} }
?> ?>
\ No newline at end of file
This diff is collapsed.
...@@ -13,5 +13,5 @@ ...@@ -13,5 +13,5 @@
else { else {
drupal_goto("index.php"); drupal_goto("index.php");
} }
?> ?>
\ No newline at end of file
...@@ -83,7 +83,7 @@ function comment_reply($pid, $id) { ...@@ -83,7 +83,7 @@ function comment_reply($pid, $id) {
comment_view(new Comment($item->uid, $item->name, $item->subject, $item->comment, $item->timestamp, $item->url, $item->cid, $item->lid), t("reply to this comment")); comment_view(new Comment($item->uid, $item->name, $item->subject, $item->comment, $item->timestamp, $item->url, $item->cid, $item->lid), t("reply to this comment"));
} }
else { else {
node_view(node_get_object(array("nid" => $id))); node_view(node_load(array("nid" => $id)));
$pid = 0; $pid = 0;
} }
...@@ -351,5 +351,5 @@ function comment_render($lid, $cid) { ...@@ -351,5 +351,5 @@ function comment_render($lid, $cid) {
} }
} }
?> ?>
...@@ -89,6 +89,14 @@ function drupal_goto($url) { ...@@ -89,6 +89,14 @@ function drupal_goto($url) {
else { else {
header("Location: $url?". SID); header("Location: $url?". SID);
} }
/*
** The "Location" header sends a REDIRECT status code to the http
** deamon. In some cases this can go wrong, so we make sure none
** of the code /below/ gets executed when we redirect.
*/
exit();
} }
function check_form($text) { function check_form($text) {
...@@ -209,7 +217,7 @@ function format_interval($timestamp) { ...@@ -209,7 +217,7 @@ function format_interval($timestamp) {
function format_date($timestamp, $type = "medium", $format = "") { function format_date($timestamp, $type = "medium", $format = "") {
global $user; global $user;
$timestamp += ($user->timezone) ? $user->timezone - date("Z") : 0; // $timestamp += ($user->timezone) ? $user->timezone - date("Z") : 0;
switch ($type) { switch ($type) {
case "small": case "small":
...@@ -327,7 +335,6 @@ function field_merge($a, $b) { ...@@ -327,7 +335,6 @@ function field_merge($a, $b) {
function link_page() { function link_page() {
$links[] = "<a href=\"index.php\">". t("home") ."</a>"; $links[] = "<a href=\"index.php\">". t("home") ."</a>";
$links[] = "<a href=\"submit.php\">". t("submit") ."</a>";
foreach (module_list() as $name) { foreach (module_list() as $name) {
if (module_hook($name, "link")) { if (module_hook($name, "link")) {
......
...@@ -5,8 +5,10 @@ ...@@ -5,8 +5,10 @@
# Database settings: # Database settings:
# #
# $db_url = "pgsql://userer:password@hostname/database"; # $db_url = "pgsql://user:password@hostname/database";
# $db_url = "mysql://userer:password@hostname/database"; # $db_url = "mysql://user:password@hostname/database";
$db_url = "mysql://drop:drop@localhost/drop";
# #
# PHP settings: # PHP settings:
......
...@@ -10,5 +10,5 @@ function t($string) { ...@@ -10,5 +10,5 @@ function t($string) {
global $languages; global $languages;
return ($languages && function_exists("locale") ? locale($string) : $string); return ($languages && function_exists("locale") ? locale($string) : $string);
} }
?> ?>
\ No newline at end of file
...@@ -24,17 +24,18 @@ function module_list() { ...@@ -24,17 +24,18 @@ function module_list() {
static $list; static $list;
if (!$list) { if (!$list) {
$handle = opendir("modules"); if ($handle = @opendir("modules")) {
$list = array(); $list = array();
while ($file = readdir($handle)) { while ($file = readdir($handle)) {
if (".module" == substr($file, -7)) { if (".module" == substr($file, -7)) {
$filename = substr($file, 0, -7); $filename = substr($file, 0, -7);
include "modules/$filename.module"; include "modules/$filename.module";
$list[$filename] = $filename; $list[$filename] = $filename;
}
} }
closedir($handle);
asort($list);
} }
closedir($handle);
asort($list);
} }
return $list; return $list;
...@@ -90,5 +91,5 @@ function module_rehash($name) { ...@@ -90,5 +91,5 @@ function module_rehash($name) {
db_query("DELETE FROM blocks WHERE module = '$name'"); db_query("DELETE FROM blocks WHERE module = '$name'");
} }
} }
?> ?>
<?php <?php
// $Id$ // $Id$
$status = array(dumped => 0, expired => 1, queued => 2, posted => 3); /*
** Loading and storing nodes:
** - load: called when a node is being loaded
** - save: called before a node gets saved and used to define default
** values
** - insert: called when inserting a node to the node table
** - delete: called when deleting a node from the node table
** - update: called when updating a node in the noe table
**
** Viewing and editing nodes:
** - view: called to display a node on the screen
** - form: called to display a node's form
**
** - status
*/
// TODO: still used by themes, yet doesn't return anything at the moment
function node_index() {
}
function _node_get($conditions) { function node_access($node) {
foreach ($conditions as $key=>$value) { global $user;
$cond[] = "n.". check_query($key) ." = '". check_query($value) ."'"; return ($node->status == 1) || user_access("administer nodes");
} }
function node_get_comments($nid) {
$comment = db_fetch_object(db_query("SELECT COUNT(c.lid) AS number FROM node n LEFT JOIN comments c ON n.nid = c.lid WHERE n.nid = '$nid' GROUP BY n.nid"));
return $comment->number ? $comment->number : 0;
}
$where = implode(" AND ", $cond); function node_teaser($body) {
if ($conditions[type]) { $size = 400;
$type = $conditions[type];
/*
** If we have a short body, return the entire body:
*/
if (strlen($body) < $size) {
return $body;
} }
else {
$node = db_fetch_object(db_query("SELECT n.type FROM node n WHERE $where")); /*
$type = $node ? $node->type : 0; ** If we have a long body, try not to split paragraphs:
*/
if ($length = strpos($body, "\n", $size)) {
return substr($body, 0, $length + 1);
} }
if ($type) { /*
** If we have a long body, try not to split sentences:
*/
// $result = db_query("SELECT n.*, l.*, u.uid, u.name FROM node n LEFT JOIN $type l ON n.nid = l.nid LEFT JOIN users u ON n.uid = u.uid WHERE $where ORDER BY n.timestamp DESC"); return substr($body, 0, strpos($body, ". ", $size) + 1);
db_query("BEGIN"); }
db_query("CREATE TEMPORARY TABLE modhole AS SELECT n.nid FROM node n LEFT JOIN $type l ON n.nid = l.nid LEFT JOIN users u ON n.uid = u.uid WHERE $where GROUP BY n.nid");
$result = db_query("SELECT n.*, l.*, u.uid, u.name FROM node n INNER JOIN modhole m ON m.nid = n.nid LEFT JOIN $type l ON n.nid = l.nid LEFT JOIN users u ON n.uid = u.uid WHERE $where ORDER BY n.timestamp DESC");
db_query("DROP TABLE modhole");
db_query("COMMIT");
return $result; function node_invoke($node, $name, $arg = 0) {
if (is_array($node)) {
$function = $node[type] ."_$name";
}
else if (is_object($node)) {
$function = $node->type ."_$name";
}
else if (is_string($node)) {
$function = $node ."_$name";
} }
}
function node_comment_status($index = -1) { if (function_exists($function)) {
$status = array("Disabled", "Enabled"); return ($arg ? $function($node, $arg) : $function($node));
return $index < 0 ? $status : $status[$index]; }
} }
function node_promote_status($index = -1) { function node_object($node) {
$status = array("Disabled", "Enabled");
return $index < 0 ? $status : $status[$index];
}
function node_submission_status($index = -1) { if (is_array($node)) {
$status = array("Auto-post new submissions", "Moderate new submissions"); foreach ($node as $key => $value) {
return $index < 0 ? $status : $status[$index]; $object->$key = $value;
} }
}
else {
$object = $node;
}
function node_get_object($conditions) { return $object;
return db_fetch_object(_node_get($conditions));
} }
function node_get_array($conditions) { function node_array($node) {
return db_fetch_array(_node_get($conditions));
}
function node_del($conditions) { if (is_object($node)) {
global $status; foreach ($node as $key => $value) {
if ($node = node_get_object($conditions)) { $array[$key] = $value;
module_invoke($node->type, "delete", $node); }
db_query("DELETE FROM node WHERE nid = '$node->nid'"); }
db_query("DELETE FROM $node->type WHERE nid = '$node->nid'"); else {
db_query("DELETE FROM comments WHERE lid = '$node->nid'"); $array = $node;
db_query("DELETE FROM moderate WHERE nid = '$node->nid'");
watchdog("special", "node: deleted '$node->title'");
return $node;
} }
}
function node_get_comments($nid) { return $array;
$comment = db_fetch_object(db_query("SELECT COUNT(c.lid) AS number FROM node n LEFT JOIN comments c ON n.nid = c.lid WHERE n.nid = '$nid' GROUP BY n.nid"));
return $comment->number ? $comment->number : 0;
} }
function node_save($node, $filter) { function node_load($conditions) {
global $db_handle;
$rows = array(nid, cid, tid, type, title, score, votes, uid, status, comment, promote, moderate, attributes, timestamp, timestamp_posted, timestamp_queued, timestamp_hidden);
if ($node[nid] > 0) { // prepare query:
$n = node_get_object(array("nid" => $node[nid])); foreach ($conditions as $key => $value) {
$cond[] = "n.". check_query($key) ." = '". check_query($value) ."'";
}
foreach ($filter as $field=>$value) { // retrieve the node:
$f = check_input(is_numeric($field) ? $value : $field); $node = db_fetch_object(db_query("SELECT n.*, u.uid, u.name FROM node n LEFT JOIN users u ON u.uid = n.uid LEFT JOIN comments c ON c.lid = n.nid WHERE ". implode(" AND ", $cond)));
$v = check_input(is_numeric($field) ? $node[$value] : $filter[$field]);
if (in_array($f, $rows)) { // call the node specific callback (if any):
$u1[] = check_input($f) ." = '". check_input($v) ."'"; if ($extra = module_invoke($node->type, "load", $node)) {
} foreach ($extra as $key => $value) {
else { $node->$key = $value;
$u2[] = check_input($f) ." = '". check_input($v) ."'";
}
} }
}
if ($u1) db_query("UPDATE node SET ". implode(", ", $u1) ." WHERE nid = '$node[nid]'"); return $node;
if ($u2) db_query("UPDATE $n->type SET ". implode(", ", $u2) ." WHERE nid = '$node[nid]'");
if ($node[nid]) module_invoke($n->type, "update", node_get_object(array(nid => $n->nid))); }
return $node[nid]; function node_save($node, $filter) {
}
else { $fields = array("nid", "uid", "type", "title", "teaser", "body", "status", "comment", "promote", "moderate", "created", "changed");
$duplicate = node_get_object(array("title" => $node[title]));
if ($duplicate && (time() - $duplicate->timestamp < 60)) { foreach ($filter as $key => $value) {
watchdog("warning", "node: duplicate '$node[title]'"); /*
** Only save those fields specified by the filter. If the filter
** does not specify a default value, use the value of the $node's
** corresponding field instead.
*/
if (is_numeric($key)) {
$edit->$value = $node->$value;
} }
else { else {
// verify submission rate: $edit->$key = $value;
throttle("node", variable_get("max_node_rate", 900)); }
}
// prepare queries:
foreach ($filter as $field=>$value) {
$f = check_input(is_numeric($field) ? $value : $field);
$v = check_input(is_numeric($field) ? $node[$value] : $filter[$field]);
if (in_array($f, $rows)) {
$f1[] = $f;
$v1[] = "'$v'";
}
else {
$f2[] = $f;
$v2[] = "'$v'";
}
}
$f1 = implode(", ", $f1); $node = $edit;
$v1 = implode(", ", $v1);
$f2 = implode(", ", $f2);
$v2 = implode(", ", $v2);
if (empty($node->nid)) {
/*
** Verify a user's submission rate and avoid duplicate nodes being
** inserted:
*/
$result = db_query("BEGIN"); throttle("node", variable_get("max_node_rate", 900));
if (db_error($result)) {
watchdog("error", "database: ". $result->getMessage() ."\nquery: ". htmlspecialchars("BEGIN"));
$db_handle->rollback();
}
else {
$nid = $db_handle->nextId("node");
$result = db_query("INSERT INTO node ($f1, nid) VALUES ($v1, '$nid')");
if (db_error($result)) {
watchdog("warning", "node: added $filter[type] '$node[title]' - failed");
$db_handle->rollback();
}
else {
$result = db_query("INSERT INTO $filter[type] ($f2, nid) VALUES ($v2, '$nid')");
if (db_error($result)) {
watchdog("warning", "node: added $filter[type] '$node[title]' - failed");
$db_handle->rollback();
}
else {
$result = db_query("COMMIT");
if (db_error($result)) {
watchdog("error", "database: ". $result->getMessage() ."\nquery: ". htmlspecialchars("COMMIT"));
$db_handle->rollback();
}
watchdog("special", "node: added $filter[type] '$node[title]'");
}
}
}
}
if ($nid) module_invoke($filter[type], "insert", node_get_object(array(nid => $nid))); /*
** Insert a new node:
*/
return $nid; // set some required fields:
} $node->created = time();
} $node->nid = db_result(db_query("SELECT MAX(nid) + 1 FROM node"));
function node_invoke($node, $name, $arg = 0) { // prepare the query:
if (is_array($node)) $function = $node[type] ."_$name"; foreach ($node as $key => $value) {
else if (is_object($node)) $function = $node->type ."_$name"; if (in_array($key, $fields)) {
else if (is_string($node)) $function = $node ."_$name"; $k[] = check_query($key);
if (function_exists($function)) return ($arg ? $function($node, $arg) : $function($node)); $v[] = "'". check_query($value) ."'";
} }
}
function node_view($node, $main = 0) { // insert the node into the database:
return node_invoke($node, "view", $main); db_query("INSERT INTO node (". implode(", ", $k) .") VALUES (". implode(", ", $v) .")");
}
function node_form($node) { // call the node specific callback (if any):
return node_invoke($node, "form"); module_invoke($node->type, "insert", $node);
}
function node_status($value) { watchdog("special", "node: added '$node->title'");
$status = array("dumped", "expired", "queued", "posted");
if (module_exist($value)) {
return array_intersect($status, node_invoke($value, "status"));
}
else if (strlen($value) > 3) {
$status = array_flip($status);
return $status[$value];
} }
else { else {
return $status[$value];
}
}
function node_control($node) { /*
global $user, $REQUEST_URI; ** Update an existing node:
*/
?>
<SCRIPT>
<!--//
function visit(site) {
if (site != "") {
parent.location = site
}
}
//-->
</SCRIPT>
<?php
if ($user->uid) {
$choices = array("node.php?id=$node->nid" => t("view node"), "submit.php?mod=$node->type" => t("add node"), "submit.php?mod=$node->type&op=update&id=$node->nid" => t("update node"), "node.php?op=history&id=$node->nid" => t("view history"));
}
else {
$choices = array("node.php?id=$node->nid" => t("view node"), "node.php?op=history&id=$node->nid" => t("view history"));
}
$output .= "<FORM METHOD=\"get\" ACTION=\"\">\n"; // set some required fields:
foreach ($choices as $key => $value) $options .= "<OPTION VALUE=\"$key\"". (strstr($REQUEST_URI, "/$key") ? " SELECTED" : "") .">". check_form($value) ."</OPTION>\n"; $node->changed = time();
$output .= " <SELECT NAME=\"op\" ONCHANGE=\"visit(this.options[this.selectedIndex].value)\">$options</SELECT>\n";
$output .= "</FORM>\n";
return $output; // prepare the query:
} foreach ($node as $key => $value) {
if (in_array($key, $fields)) {
$q[] = check_query($key) ." = '". check_query($value) ."'";
}
}
function node_preview($node) { // update the node in the database:
foreach ($node as $key=>$value) { db_query("UPDATE node SET ". implode(", ", $q) ." WHERE nid = '". check_query($node->nid) ."'");
if ($value) $node[$key] = is_array($value) ? node_preview($value) : check_preview($value);
}
return $node;
}
// call the node specific callback (if any):
module_invoke($node->type, "update", $node);
function node_attributes_edit($type, $edit) { watchdog("special", "node: updated '$node->title'");
return meta_form($type, $edit); }
}
function node_attributes_save($type, $edit) { /*
return meta_save($type, $edit); ** Return the node ID:
} */
function node_attributes_view($string) { return $node->nid;
foreach (explode(",", $string) as $attribute) {
if ($attribute = trim($attribute)) {
$array[] = "<a href=\"index.php?meta=". urlencode($attribute) ."\">$attribute</a>";
}
}
return $array ? $array : array();
}
function node_index($node) {
return $node->attributes ? implode(" / ", node_attributes_view($node->attributes)) : "&nbsp;";
} }
function node_access($node) {