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) {
if (user_access("access administration pages")) {
admin_page($mod);
}
?>
\ No newline at end of file
......@@ -18,5 +18,5 @@
foreach (module_list() as $module) {
module_invoke($module, "cron");
}
?>
\ No newline at end of file
This diff is collapsed.
......@@ -13,5 +13,5 @@
else {
drupal_goto("index.php");
}
?>
\ No newline at end of file
......@@ -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"));
}
else {
node_view(node_get_object(array("nid" => $id)));
node_view(node_load(array("nid" => $id)));
$pid = 0;
}
......@@ -351,5 +351,5 @@ function comment_render($lid, $cid) {
}
}
?>
......@@ -89,6 +89,14 @@ function drupal_goto($url) {
else {
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) {
......@@ -209,7 +217,7 @@ function format_interval($timestamp) {
function format_date($timestamp, $type = "medium", $format = "") {
global $user;
$timestamp += ($user->timezone) ? $user->timezone - date("Z") : 0;
// $timestamp += ($user->timezone) ? $user->timezone - date("Z") : 0;
switch ($type) {
case "small":
......@@ -327,7 +335,6 @@ function field_merge($a, $b) {
function link_page() {
$links[] = "<a href=\"index.php\">". t("home") ."</a>";
$links[] = "<a href=\"submit.php\">". t("submit") ."</a>";
foreach (module_list() as $name) {
if (module_hook($name, "link")) {
......
......@@ -5,8 +5,10 @@
# Database settings:
#
# $db_url = "pgsql://userer:password@hostname/database";
# $db_url = "mysql://userer:password@hostname/database";
# $db_url = "pgsql://user:password@hostname/database";
# $db_url = "mysql://user:password@hostname/database";
$db_url = "mysql://drop:drop@localhost/drop";
#
# PHP settings:
......
......@@ -10,5 +10,5 @@ function t($string) {
global $languages;
return ($languages && function_exists("locale") ? locale($string) : $string);
}
?>
\ No newline at end of file
......@@ -24,17 +24,18 @@ function module_list() {
static $list;
if (!$list) {
$handle = opendir("modules");
$list = array();
while ($file = readdir($handle)) {
if (".module" == substr($file, -7)) {
$filename = substr($file, 0, -7);
include "modules/$filename.module";
$list[$filename] = $filename;
if ($handle = @opendir("modules")) {
$list = array();
while ($file = readdir($handle)) {
if (".module" == substr($file, -7)) {
$filename = substr($file, 0, -7);
include "modules/$filename.module";
$list[$filename] = $filename;
}
}
closedir($handle);
asort($list);
}
closedir($handle);
asort($list);
}
return $list;
......@@ -90,5 +91,5 @@ function module_rehash($name) {
db_query("DELETE FROM blocks WHERE module = '$name'");
}
}
?>
<?php
// $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) {
foreach ($conditions as $key=>$value) {
$cond[] = "n.". check_query($key) ." = '". check_query($value) ."'";
}
function node_access($node) {
global $user;
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]) {
$type = $conditions[type];
$size = 400;
/*
** 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) {
$status = array("Disabled", "Enabled");
return $index < 0 ? $status : $status[$index];
if (function_exists($function)) {
return ($arg ? $function($node, $arg) : $function($node));
}
}
function node_promote_status($index = -1) {
$status = array("Disabled", "Enabled");
return $index < 0 ? $status : $status[$index];
}
function node_object($node) {
function node_submission_status($index = -1) {
$status = array("Auto-post new submissions", "Moderate new submissions");
return $index < 0 ? $status : $status[$index];
}
if (is_array($node)) {
foreach ($node as $key => $value) {
$object->$key = $value;
}
}
else {
$object = $node;
}
function node_get_object($conditions) {
return db_fetch_object(_node_get($conditions));
return $object;
}
function node_get_array($conditions) {
return db_fetch_array(_node_get($conditions));
}
function node_array($node) {
function node_del($conditions) {
global $status;
if ($node = node_get_object($conditions)) {
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'");
db_query("DELETE FROM comments WHERE lid = '$node->nid'");
db_query("DELETE FROM moderate WHERE nid = '$node->nid'");
watchdog("special", "node: deleted '$node->title'");
return $node;
if (is_object($node)) {
foreach ($node as $key => $value) {
$array[$key] = $value;
}
}
else {
$array = $node;
}
}
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;
return $array;
}
function node_save($node, $filter) {
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);
function node_load($conditions) {
if ($node[nid] > 0) {
$n = node_get_object(array("nid" => $node[nid]));
// prepare query:
foreach ($conditions as $key => $value) {
$cond[] = "n.". check_query($key) ." = '". check_query($value) ."'";
}
foreach ($filter as $field=>$value) {
$f = check_input(is_numeric($field) ? $value : $field);
$v = check_input(is_numeric($field) ? $node[$value] : $filter[$field]);
// retrieve the node:
$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)));
if (in_array($f, $rows)) {
$u1[] = check_input($f) ." = '". check_input($v) ."'";
}
else {
$u2[] = check_input($f) ." = '". check_input($v) ."'";
}
// call the node specific callback (if any):
if ($extra = module_invoke($node->type, "load", $node)) {
foreach ($extra as $key => $value) {
$node->$key = $value;
}
}
if ($u1) db_query("UPDATE node SET ". implode(", ", $u1) ." WHERE nid = '$node[nid]'");
if ($u2) db_query("UPDATE $n->type SET ". implode(", ", $u2) ." WHERE nid = '$node[nid]'");
return $node;
if ($node[nid]) module_invoke($n->type, "update", node_get_object(array(nid => $n->nid)));
}
return $node[nid];
}
else {
$duplicate = node_get_object(array("title" => $node[title]));
function node_save($node, $filter) {
$fields = array("nid", "uid", "type", "title", "teaser", "body", "status", "comment", "promote", "moderate", "created", "changed");
if ($duplicate && (time() - $duplicate->timestamp < 60)) {
watchdog("warning", "node: duplicate '$node[title]'");
foreach ($filter as $key => $value) {
/*
** 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 {
// verify submission rate:
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'";
}
}
$edit->$key = $value;
}
}
$f1 = implode(", ", $f1);
$v1 = implode(", ", $v1);
$f2 = implode(", ", $f2);
$v2 = implode(", ", $v2);
$node = $edit;
if (empty($node->nid)) {
/*
** Verify a user's submission rate and avoid duplicate nodes being
** inserted:
*/
$result = db_query("BEGIN");
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]'");
}
}
}
}
throttle("node", variable_get("max_node_rate", 900));
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) {
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";
if (function_exists($function)) return ($arg ? $function($node, $arg) : $function($node));
}
// prepare the query:
foreach ($node as $key => $value) {
if (in_array($key, $fields)) {
$k[] = check_query($key);
$v[] = "'". check_query($value) ."'";
}
}
function node_view($node, $main = 0) {
return node_invoke($node, "view", $main);
}
// insert the node into the database:
db_query("INSERT INTO node (". implode(", ", $k) .") VALUES (". implode(", ", $v) .")");
function node_form($node) {
return node_invoke($node, "form");
}
// call the node specific callback (if any):
module_invoke($node->type, "insert", $node);
function node_status($value) {
$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];
watchdog("special", "node: added '$node->title'");
}
else {
return $status[$value];
}
}
function node_control($node) {
global $user, $REQUEST_URI;
?>
<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"));
}
/*
** Update an existing node:
*/
$output .= "<FORM METHOD=\"get\" ACTION=\"\">\n";
foreach ($choices as $key => $value) $options .= "<OPTION VALUE=\"$key\"". (strstr($REQUEST_URI, "/$key") ? " SELECTED" : "") .">". check_form($value) ."</OPTION>\n";
$output .= " <SELECT NAME=\"op\" ONCHANGE=\"visit(this.options[this.selectedIndex].value)\">$options</SELECT>\n";
$output .= "</FORM>\n";
// set some required fields:
$node->changed = time();
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) {
foreach ($node as $key=>$value) {
if ($value) $node[$key] = is_array($value) ? node_preview($value) : check_preview($value);
}
return $node;
}
// update the node in the database:
db_query("UPDATE node SET ". implode(", ", $q) ." WHERE nid = '". check_query($node->nid) ."'");
// call the node specific callback (if any):
module_invoke($node->type, "update", $node);
function node_attributes_edit($type, $edit) {
return meta_form($type, $edit);
}
watchdog("special", "node: updated '$node->title'");
}
function node_attributes_save($type, $edit) {
return meta_save($type, $edit);
}
/*
** Return the node ID:
*/
function node_attributes_view($string) {
foreach (explode(",", $string) as $attribute) {
if ($attribute = trim($attribute)) {
$array[] = "<a href=\"index.php?meta=". urlencode($attribute) ."\">$attribute</a>";
}
}
return $array ? $array : array();
}
return $node->nid;
function node_index($node) {
return $node->attributes ? implode(" / ", node_attributes_view($node->attributes)) : "&nbsp;";
}
function node_access($node) {
global $user, $status;
return ($node->status == $status[posted]) || ($node->status == $status[queued] && $user->uid) || user_access("administer nodes");
}
function node_delete($conditions) {
function node_moderate($moderate) {
global $user;
if ($node = node_load($conditions)) {
if ($user->uid && $moderate) {
foreach ($moderate as $nid => $score) {
if ($score > 0 && $score < 6) {
if (db_fetch_object(db_query("SELECT * FROM moderate WHERE uid = '". check_query($user->uid) ."' AND nid = '". check_query($nid) ."'"))) {
db_query("UPDATE moderate SET score = '". check_query($score) ."' WHERE uid = '". check_query($user->uid) ."' AND nid = '". check_query($nid) ."'");
}
else {
db_query("INSERT INTO moderate (uid, nid, score, timestamp) VALUES ('". check_query($user->uid) ."', '". check_query($nid) ."', '". check_query($score) ."', '". time() ."')");
}
}
}
}
}
// delete the node and its comments:
db_query("DELETE FROM node WHERE nid = '$node->nid'");
db_query("DELETE FROM comments WHERE lid = '$node->nid'");
db_query("DELETE FROM moderate WHERE nid = '$node->nid'");
function node_moderation($nid) {
global $user;
// call the node specific callback (if any):
module_invoke($node->type, "delete", &$node);
$node = node_get_object(array("nid" => $nid));
watchdog("special", "node: deleted '$node->title'");
}
$values = array("--", 1, 2, 3, 4, 5);
}
$moderate = db_fetch_object(db_query("SELECT * FROM moderate WHERE nid = '$node->nid' AND uid = '$user->uid'"));
function node_view($node, $main = 0) {
global $theme;
foreach ($values as $key => $value) {
$options .= " <option value=\"$key\"". ($moderate->score == $key ? " selected=\"selected\"" : "") .">$value</option>\n";
if (is_array($node)) {
$node = node_object($node);
}
$output .= "accumulated rating: ". ($node->score ? $node->score : "--") ." / $node->votes<br />";
$output .= "<select name=\"moderate[node][$node->nid]\">$options</select>";
/*
** The "view" hook can be implemented to overwrite the default function
** to display nodes.
*/
return $output;
if (module_hook($node->type, "view")) {
node_invoke($node, "view", $main);
}
else {
$theme->node($node, $main);
}
}
?>