1553 lines
46 KiB
Plaintext
1553 lines
46 KiB
Plaintext
<?php
|
|
// $Id$
|
|
|
|
function node_help($section = "admin/help#node") {
|
|
global $mod;
|
|
$output = "";
|
|
|
|
switch ($section) {
|
|
|
|
case 'admin/help#node':
|
|
$output .= "<h3>Nodes</h3>";
|
|
$output .= "<p>The core of the Drupal system is the node. All of the contents of the system are placed in nodes, or extensions of nodes.";
|
|
$output .= "A base node contains:<dl>";
|
|
$output .= "<dt>A Title</dt><dd>Up to 128 characters of text that titles the node.</dd>";
|
|
$output .= "<dt>A Teaser</dt><dd>A small block of text that is meant to get you interested in the rest of node. Drupal will automatically pull a small amount of the body of the node to make the teaser (To configure how long the teaser will be %teaser). The teaser can be changed if you don't like what Drupal grabs.</dd>";
|
|
$output .= "<dt>The Body</dt><dd>The main text that comprises your content.</dd>";
|
|
$output .= "<dt>A Type</dt><dd>What kind of node is this? Blog, book, forum, comment, unextended, etc.</dd>";
|
|
$output .= "<dt>An Author</dt><dd>The author's name. It will either be \"anonymous\" or a valid user. You <i>cannot</i> set it to an arbitrary value.</dd>";
|
|
$output .= "<dt>Authored on</dt><dd>The date the node was written.</dd>";
|
|
$output .= "<dt>Changed</dt><dd>The last time this node was changed.</dd>";
|
|
$output .= "<dt>Static on front page</dt><dd>The front page is configured to show the teasers from only a few of the total nodes you have on your site (To configure how many teasers %teaser), but if you think a node is important enough that you want it to stay on the front page enable this.</dd>";
|
|
$output .= "<dt>Allow user comments</dt><dd>A node can have comments. These comments can be written by other users (Read-write), or only by admins (Read-only).</dd>";
|
|
$output .= "<dt>Attributes</dt><dd>A way to sort nodes.</dd>";
|
|
$output .= "<dt>Revisions</dt><dd>Drupal has a revision system so that you can \"roll back\" to an older version of a post if the new version is not what you want.</dd>";
|
|
$output .= "<dt>Promote to front page</dt><dd>To get people to look at the new stuff on your site you can choose to move it to the front page.</dd>";
|
|
$output .= "<dt>In moderation queue</dt><dd>Drupal has a moderation system. If it is active, a node is in one of three states: approved and published, approved and unpublished, and awaiting approval. If you are moderating a node it should be in the moderation queue.</dd>";
|
|
$output .= "<dt>Votes</dt><dd>If you are moderating a node this counts how many votes the node has gotten. Once a node gets a certain number of vote it will either be approved or dropped.";
|
|
$output .= "<dt>Score</dt><dd>The score of the node is gotten by the votes it is given.</dd>";
|
|
$output .= "<dt>Users</dt><dd>The list of users who have voted on a moderated node.</dd>";
|
|
$output .= "<dt>Published</dt><dd>When using Drupal's moderation system a node remains unpublished -- unavaliable to non-moderators -- until it is marked Published.</dd></dl>";
|
|
$output .= "<p>Now that you know what is in a node, here are some of the types of nodes available.</p>";
|
|
|
|
$output = t($output, array("%teaser" => l(t("click here"), "admin/system/modules/node")));
|
|
|
|
if ($mod == "admin") {
|
|
foreach (module_list() as $name) {
|
|
if (module_hook($name, "node") && $name != "node") {
|
|
$output .= "<h3>". t("Node type: %module", array("%module" => module_invoke($name, "node", "name"))) ."</h3>";
|
|
$output .= module_invoke($name, "node", "description");
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'admin/system/modules#description':
|
|
$output = t("The core that allows content to be submitted to the site.");
|
|
break;
|
|
case 'admin/system/modules/node':
|
|
$output = t("Settings for the core of Drupal. Almost everything is a node so these settings will affect most of the site.");
|
|
break;
|
|
case 'admin/node':
|
|
$output = t("Below is a list of all of the nodes in your site. Other forms of content are listed elsewhere (e.g. %comments).<br />Clicking a title views that node, while clicking an author's name edits their user information.<br />Other node-related tasks are available from the menu on the left.", array("%comments" => l(t("comments"), "admin/comment")));
|
|
break;
|
|
case 'admin/node/search':
|
|
$output = t("Enter a simple pattern to search for a post. This can include the wildcard character *.<br />For example, a search for \"br*\" might return \"bread bakers\", \"our daily bread\" and \"brenda\".");
|
|
break;
|
|
case 'admin/node/settings':
|
|
$output = t("This page lets you set the defaults used during creation of nodes for all the different node types.<br /><strong>comment:</strong> Read/write setting for comments.<br /><strong>publish:</strong> Is this node publicly viewable, has it been published?<br /><strong>promote:</strong> Is this node to be promoted to the front page?<br /><strong>moderate:</strong> Does this node need approval before it can be viewed?<br /><strong>static:</strong> Is this node always visible on the front page?<br /><strong>revision:</strong> Will this node go into the revision system allowing multiple versions to be saved?");
|
|
break;
|
|
|
|
}
|
|
|
|
return $output;
|
|
}
|
|
|
|
function node_help_page() {
|
|
print theme("page", node_help());
|
|
}
|
|
|
|
|
|
/*
|
|
** Accepts a DB result object which can be used to fetch node objects.
|
|
** Returns an HTML list suitable as content for a block.
|
|
*/
|
|
function node_title_list($result, $title = NULL) {
|
|
while ($node = db_fetch_object($result)) {
|
|
$number = module_invoke("comment", "num_all", $node->nid);
|
|
$items[] = l($node->title, "node/view/$node->nid", array("title" => format_plural($number, "%count comment", "%count comments")));
|
|
}
|
|
|
|
return theme("node_list", $items, $title);
|
|
}
|
|
|
|
function theme_node_list($items, $title = NULL) {
|
|
return theme("item_list", $items, $title);
|
|
}
|
|
|
|
// Update the 'last viewed' timestamp of the specified node for current user.
|
|
function node_tag_new($nid) {
|
|
global $user;
|
|
|
|
if ($user->uid) {
|
|
$result = db_query("SELECT timestamp FROM {history} WHERE uid = %d AND nid = %d", $user->uid, $nid);
|
|
if (db_fetch_object($result)) {
|
|
db_query("UPDATE {history} SET timestamp = %d WHERE uid = %d AND nid = %d", time(), $user->uid, $nid);
|
|
}
|
|
else {
|
|
db_query("INSERT INTO {history} (uid, nid, timestamp) VALUES (%d, %d, %d)", $user->uid, $nid, time());
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
** Retrieves the timestamp at which the current user last viewed the
|
|
** specified node.
|
|
*/
|
|
function node_last_viewed($nid) {
|
|
global $user;
|
|
|
|
$history = db_fetch_object(db_query("SELECT timestamp FROM {history} WHERE uid = '$user->uid' AND nid = %d", $nid));
|
|
return ($history->timestamp ? $history->timestamp : 0);
|
|
}
|
|
|
|
/**
|
|
* Determines whether the supplied timestamp is newer than the user's last view
|
|
* of a given node
|
|
*
|
|
* @param $nid node-id twhose history supplies the 'last viewed' timestamp
|
|
* @param $timestamp time which is compared against node's 'last veiwed'
|
|
* timestamp
|
|
*/
|
|
function node_is_new($nid, $timestamp) {
|
|
global $user;
|
|
static $cache;
|
|
|
|
if (!isset($cache[$nid])) {
|
|
if ($user->uid) {
|
|
$history = db_fetch_object(db_query("SELECT timestamp FROM {history} WHERE uid = %d AND nid = %d", $user->uid, $nid));
|
|
$cache[$nid] = $history->timestamp ? $history->timestamp : 0;
|
|
}
|
|
else {
|
|
$cache[$nid] = time();
|
|
}
|
|
}
|
|
|
|
if ($timestamp > $cache[$nid]) {
|
|
return 1;
|
|
}
|
|
else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
function node_teaser($body) {
|
|
|
|
$size = variable_get("teaser_length", 600);
|
|
|
|
/*
|
|
** If the size is zero, teasers are disabled so we
|
|
** return the entire body.
|
|
*/
|
|
|
|
if ($size == 0) {
|
|
return $body;
|
|
}
|
|
|
|
/*
|
|
** If a valid delimiter has been specified, use it to
|
|
** chop of the teaser. The delimiter can be outside
|
|
** the allowed range but no more than a factor two.
|
|
*/
|
|
|
|
$delimiter = strpos($body, "<!--break-->");
|
|
if ($delimiter > 0) {
|
|
return substr($body, 0, $delimiter);
|
|
}
|
|
|
|
/*
|
|
** If we have a short body, return the entire body:
|
|
*/
|
|
|
|
if (strlen($body) < $size) {
|
|
return $body;
|
|
}
|
|
|
|
/*
|
|
** In some cases no delimiter has been specified (eg.
|
|
** when posting using the Blogger API) in which case
|
|
** we try to split at paragraph boundaries.
|
|
*/
|
|
|
|
if ($length = strpos($body, "</p>", $size)) {
|
|
return substr($body, 0, $length + 4);
|
|
}
|
|
|
|
if ($length = strpos($body, "<br />", $size)) {
|
|
return substr($body, 0, $length);
|
|
}
|
|
|
|
if ($length = strpos($body, "<br>", $size)) {
|
|
return substr($body, 0, $length);
|
|
}
|
|
|
|
if ($length = strpos($body, "\n", $size)) {
|
|
return substr($body, 0, $length);
|
|
}
|
|
|
|
/*
|
|
** When even the first paragraph is too long, try to
|
|
** split at the end of the next sentence.
|
|
*/
|
|
|
|
if ($length = strpos($body, ". ", $size)) {
|
|
return substr($body, 0, $length + 1);
|
|
}
|
|
|
|
if ($length = strpos($body, "! ", $size)) {
|
|
return substr($body, 0, $length + 1);
|
|
}
|
|
|
|
if ($length = strpos($body, "? ", $size)) {
|
|
return substr($body, 0, $length + 1);
|
|
}
|
|
|
|
/*
|
|
** Nevermind, we split it the hard way ...
|
|
*/
|
|
|
|
return substr($body, 0, $size);
|
|
}
|
|
|
|
function node_invoke(&$node, $hook, $a2 = NULL, $a3 = NULL, $a4 = NULL) {
|
|
if (is_array($node)) {
|
|
$function = $node["type"] ."_$hook";
|
|
}
|
|
else if (is_object($node)) {
|
|
$function = $node->type ."_$hook";
|
|
}
|
|
else if (is_string($node)) {
|
|
$function = $node ."_$hook";
|
|
}
|
|
|
|
if (function_exists($function)) {
|
|
return ($function($node, $a2, $a3, $a4));
|
|
}
|
|
}
|
|
|
|
function node_invoke_nodeapi(&$node, $op, $arg = 0) {
|
|
$return = array();
|
|
foreach (module_list() as $name) {
|
|
$function = $name ."_nodeapi";
|
|
if (function_exists($function)) {
|
|
$result = $function($node, $op, $arg);
|
|
if (isset($result)) {
|
|
$return = array_merge($return, $result);
|
|
}
|
|
}
|
|
}
|
|
return $return;
|
|
}
|
|
|
|
function node_load($conditions, $revision = -1) {
|
|
|
|
/*
|
|
** Turn the conditions into a query:
|
|
*/
|
|
|
|
foreach ($conditions as $key => $value) {
|
|
$cond[] = "n.". check_query($key) ." = '". check_query($value) ."'";
|
|
}
|
|
|
|
/*
|
|
** Retrieve the node:
|
|
*/
|
|
|
|
$node = db_fetch_object(db_query("SELECT n.*, u.uid, u.name FROM {node} n INNER JOIN {users} u ON u.uid = n.uid WHERE ". implode(" AND ", $cond)));
|
|
|
|
/*
|
|
** Unserialize the revisions field:
|
|
*/
|
|
|
|
if ($node->revisions) {
|
|
$node->revisions = unserialize($node->revisions);
|
|
}
|
|
|
|
/*
|
|
** Call the node specific callback (if any) and piggy-back the
|
|
** results to the node or overwrite some values:
|
|
*/
|
|
|
|
if ($extra = node_invoke($node, "load")) {
|
|
foreach ($extra as $key => $value) {
|
|
$node->$key = $value;
|
|
}
|
|
}
|
|
|
|
/*
|
|
** Return the desired revision
|
|
*/
|
|
if ($revision != -1 && isset($node->revisions[$revision])) {
|
|
$node = $node->revisions[$revision]["node"];
|
|
}
|
|
|
|
return $node;
|
|
}
|
|
|
|
function node_save($node) {
|
|
|
|
/*
|
|
** Fetch fields to save to node table:
|
|
*/
|
|
$fields = node_invoke_nodeapi($node, "fields");
|
|
|
|
/*
|
|
** Serialize the revisions field:
|
|
*/
|
|
|
|
if ($node->revisions) {
|
|
$node->revisions = serialize($node->revisions);
|
|
}
|
|
|
|
/*
|
|
** Apply filters to some default node fields:
|
|
*/
|
|
|
|
if (empty($node->nid)) {
|
|
|
|
/*
|
|
** Insert a new node:
|
|
*/
|
|
|
|
// Set some required fields:
|
|
if (!$node->created) {
|
|
$node->created = time();
|
|
}
|
|
$node->changed = time();
|
|
$node->nid = db_next_id("{node}_nid");
|
|
|
|
// Prepare the query:
|
|
foreach ($node as $key => $value) {
|
|
if (in_array($key, $fields)) {
|
|
$k[] = check_query($key);
|
|
$v[] = $value;
|
|
$s[] = "'%s'";
|
|
}
|
|
}
|
|
|
|
$keysfmt = implode(", ", $s);
|
|
// need to quote the placeholders for the values
|
|
$valsfmt = "'". implode("', '", $s) ."'";
|
|
|
|
// Insert the node into the database:
|
|
db_query("INSERT INTO {node} (". implode(", ", $k) .") VALUES(". implode(", ", $s) .")", $v);
|
|
|
|
// Call the node specific callback (if any):
|
|
node_invoke($node, "insert");
|
|
node_invoke_nodeapi($node, "insert");
|
|
}
|
|
else {
|
|
|
|
/*
|
|
** Update an existing node:
|
|
*/
|
|
|
|
// Set some required fields:
|
|
$node->changed = time();
|
|
|
|
// Prepare the query:
|
|
foreach ($node as $key => $value) {
|
|
if (in_array($key, $fields)) {
|
|
$q[] = check_query($key) ." = '%s'";
|
|
$v[] = $value;
|
|
}
|
|
}
|
|
|
|
// Update the node in the database:
|
|
db_query("UPDATE {node} SET ". implode(", ", $q) ." WHERE nid = '$node->nid'", $v);
|
|
|
|
// Call the node specific callback (if any):
|
|
node_invoke($node, "update");
|
|
node_invoke_nodeapi($node, "update");
|
|
}
|
|
|
|
/*
|
|
** Clear the cache so an anonymous poster can see the node being
|
|
** added or updated.
|
|
*/
|
|
|
|
cache_clear_all();
|
|
|
|
/*
|
|
** Return the node ID:
|
|
*/
|
|
|
|
return $node->nid;
|
|
|
|
}
|
|
|
|
function node_view($node, $main = 0, $page = 0) {
|
|
|
|
$node = array2object($node);
|
|
|
|
/*
|
|
** Remove the delimiter (if any) that seperates the teaser from the
|
|
** body. TODO: this strips legitimate uses of '<!--break-->' also.
|
|
*/
|
|
|
|
$node->body = str_replace("<!--break-->", "", $node->body);
|
|
|
|
/*
|
|
** The "view" hook can be implemented to overwrite the default function
|
|
** to display nodes.
|
|
*/
|
|
|
|
if (module_hook($node->type, "view")) {
|
|
return node_invoke($node, "view", $main, $page);
|
|
}
|
|
else {
|
|
|
|
/*
|
|
** Default behavior:
|
|
*/
|
|
|
|
return theme("node", node_prepare($node), $main, $page);
|
|
}
|
|
}
|
|
|
|
function node_prepare($node) {
|
|
if ($node->teaser == $node->body) {
|
|
// Only invoke check_output() once for performance's sake:
|
|
$node->teaser = $node->body = check_output($node->teaser);
|
|
}
|
|
else {
|
|
$node->teaser = check_output($node->teaser);
|
|
$node->body = check_output($node->body);
|
|
}
|
|
return $node;
|
|
}
|
|
|
|
function node_show($node, $cid) {
|
|
|
|
if (node_access("view", $node)) {
|
|
|
|
$output = node_view($node, 0, 1);
|
|
|
|
if (function_exists("comment_render") && $node->comment) {
|
|
$output .= comment_render($node, $cid);
|
|
}
|
|
|
|
/*
|
|
** Update the history table, stating that this user viewed this node.
|
|
*/
|
|
|
|
node_tag_new($node->nid);
|
|
|
|
return $output;
|
|
}
|
|
else {
|
|
drupal_set_message(message_access());
|
|
}
|
|
}
|
|
|
|
function node_access($op, $node = 0) {
|
|
|
|
if (user_access("administer nodes")) {
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
** Convert the node to an object if necessary:
|
|
*/
|
|
|
|
$node = array2object($node);
|
|
|
|
/*
|
|
** Construct a function:
|
|
*/
|
|
|
|
if ($node->type) {
|
|
$type = $node->type;
|
|
}
|
|
else {
|
|
$type = $node;
|
|
}
|
|
|
|
// Can't use node_invoke:
|
|
// the access hook takes the $op parameter before the $node parameter.
|
|
return module_invoke($type, "access", $op, $node);
|
|
}
|
|
|
|
function node_perm() {
|
|
return array("administer nodes", "access content");
|
|
}
|
|
|
|
function node_search($keys) {
|
|
|
|
// Return the results of performing a search using the indexed search
|
|
// for this particular type of node.
|
|
//
|
|
// Pass an array to the "do_search" function which dictates what it
|
|
// will search through, and what it will search for
|
|
//
|
|
// "keys"'s value is the keywords entered by the user
|
|
//
|
|
// "type"'s value is used to identify the node type in the search
|
|
// index.
|
|
//
|
|
// "select"'s value is used to relate the data from the specific nodes
|
|
// table to the data that the search_index table has in it, and the the
|
|
// do_search functino will rank it.
|
|
//
|
|
// The select must always provide the following fields - lno, title,
|
|
// created, uid, name, count
|
|
//
|
|
$find = do_search(array("keys" => $keys, "type" => "node", "select" => "select s.lno as lno, n.title as title, n.created as created, u.uid as uid, u.name as name, s.count as count FROM {search_index} s, {node} n INNER JOIN {users} u ON n.uid = u.uid WHERE s.lno = n.nid AND s.type = 'node' AND s.word like '%' AND n.status = 1"));
|
|
|
|
return $find;
|
|
}
|
|
|
|
function node_settings() {
|
|
$output .= form_select(t("Number of posts on main page"), "default_nodes_main", variable_get("default_nodes_main", 10), array(1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9, 10 => 10, 15 => 15, 20 => 20, 25 => 25, 30 => 30), t("The default maximum number of posts to display per page on overview pages such as the main page."));
|
|
$output .= form_select(t("Length of trimmed posts"), "teaser_length", variable_get("teaser_length", 600), array(0 => t("Unlimited"), 200 => t("200 characters"), 400 => t("400 characters"), 600 => t("600 characters"), 800 => t("800 characters"), 1000 => t("1000 characters"), 1200 => t("1200 characters"), 1400 => t("1400 characters"), 1600 => t("1600 characters"), 1800 => t("1800 characters"), 2000 => t("2000 characters")), t("The maximum number of characters used in the trimmed version of a post. Drupal will use this setting to determine at which offset long posts should be trimmed. The trimmed version of a post is typically used as a teaser when displaying the post on the main page, in XML feeds, etc. To disable teasers, set to 'Unlimited'."));
|
|
$output .= form_radios(t("Preview post"), "node_preview", variable_get("node_preview", 0), array(t("Optional"), t("Required")), t("Must users preview posts before submitting?"));
|
|
|
|
return $output;
|
|
}
|
|
|
|
function node_comment_mode($nid) {
|
|
static $comment_mode;
|
|
if (!isset($comment_mode[$nid])) {
|
|
$comment_mode[$nid] = db_result(db_query("SELECT comment FROM {node} WHERE nid = %d", $nid));
|
|
}
|
|
return $comment_mode[$nid];
|
|
}
|
|
|
|
function node_link($type, $node = 0, $main = 0) {
|
|
|
|
$links = array();
|
|
|
|
if ($type == "node") {
|
|
if ($node->links) {
|
|
$links = $node->links;
|
|
}
|
|
|
|
if ($main == 1 && $node->teaser && strlen($node->teaser) != strlen($node->body)) {
|
|
$links[] = l(t("read more"), "node/view/$node->nid", array("title" => t("Read the rest of this posting."), "class" => "read-more"));
|
|
}
|
|
|
|
if (user_access("administer nodes")) {
|
|
$links[] = l(t("administer"), "admin/node/edit/$node->nid", array("title" => t("Administer this node.")));
|
|
}
|
|
|
|
if (user_access("administer nodes") && $node->revisions) {
|
|
$links[] = l(t("revisions"), "node/revisions/$node->nid", array("title" => t("Administer revisions.")));
|
|
}
|
|
}
|
|
|
|
if ($type == "system") {
|
|
menu("node/add", t("create content"), 'node_page', 1, MENU_HIDE_NOCHILD);
|
|
|
|
if (user_access("administer nodes")) {
|
|
menu("admin/node", t("content"), "node_admin");
|
|
menu("admin/node/search", t("search"), "node_admin", 8);
|
|
menu("admin/node/help", t("help"), "node_help_page", 9);
|
|
menu("admin/node/edit", t("edit post"), "node_admin", 0, MENU_HIDE);
|
|
menu("admin/node/settings", t("settings"), "node_admin", 8);
|
|
}
|
|
|
|
if (user_access("access content")) {
|
|
menu("node", t("content"), "node_page", 0, MENU_HIDE);
|
|
}
|
|
}
|
|
|
|
return $links;
|
|
}
|
|
|
|
function node_admin_edit($node) {
|
|
|
|
if (is_numeric($node)) {
|
|
$node = node_load(array("nid" => $node));
|
|
}
|
|
|
|
$output .= node_form($node);
|
|
|
|
/*
|
|
** Display the node form extensions:
|
|
*/
|
|
$output .= implode("\n", module_invoke_all("node_link", $node));
|
|
|
|
return $output;
|
|
|
|
}
|
|
|
|
function node_admin_nodes() {
|
|
$filters = array(
|
|
array(t("View posts that are new or updated"), "ORDER BY n.changed DESC"),
|
|
array(t("View posts that need approval"), "WHERE n.status = 0 OR n.moderate = 1 ORDER BY n.changed DESC"),
|
|
array(t("View posts that are promoted"), "WHERE n.status = 1 AND n.promote = 1 ORDER BY n.changed DESC"),
|
|
array(t("View posts that are not promoted"), "WHERE n.status = 1 AND n.promote = 0 ORDER BY n.changed DESC"),
|
|
array(t("View posts that are static"), "WHERE n.status = 1 AND n.static = 1 ORDER BY n.changed DESC"),
|
|
array(t("View posts that are unpublished"), "WHERE n.status = 0 AND n.moderate = 0 ORDER BY n.changed DESC")
|
|
);
|
|
|
|
$operations = array(
|
|
array(t("Approve the selected posts"), "UPDATE {node} SET status = 1, moderate = 0 WHERE nid = %d"),
|
|
array(t("Promote the selected posts"), "UPDATE {node} SET status = 1, promote = 1 WHERE nid = %d"),
|
|
array(t("Make the selected posts static"), "UPDATE {node} SET status = 1, static = 1 WHERE nid = %d"),
|
|
array(t("Demote the selected posts"), "UPDATE {node} SET promote = 0 WHERE nid = %d"),
|
|
array(t("Unpublish the selected posts"), "UPDATE {node} SET status = 0 WHERE nid = %d")
|
|
);
|
|
|
|
/*
|
|
** Handle operations:
|
|
*/
|
|
|
|
if (empty($_SESSION["node_overview_filter"])) {
|
|
$_SESSION["node_overview_filter"] = 0;
|
|
}
|
|
|
|
if (isset($_POST["edit"]["filter"])) {
|
|
$_SESSION["node_overview_filter"] = $_POST["edit"]["filter"];
|
|
}
|
|
|
|
if (isset($_POST["edit"]["operation"])) {
|
|
$operation = $operations[$_POST["edit"]["operation"]][1];
|
|
foreach ($_POST["edit"]["status"] as $nid => $value) {
|
|
if ($value) {
|
|
db_query($operation, $nid);
|
|
}
|
|
}
|
|
|
|
drupal_set_message(t("the update has been performed."));
|
|
}
|
|
|
|
$filter = $_SESSION["node_overview_filter"];
|
|
|
|
/*
|
|
** Render filter form:
|
|
*/
|
|
|
|
$options = array();
|
|
foreach ($filters as $key => $value) {
|
|
$options[] = $value[0];
|
|
}
|
|
|
|
$form = form_select(NULL, "filter", $filter, $options);
|
|
$form .= form_submit(t("Go"));
|
|
|
|
$output .= "<h3>". t("Filter options") ."</h3>";
|
|
$output .= "<div class=\"container-inline\">$form</div>";
|
|
|
|
/*
|
|
** Render operations form:
|
|
*/
|
|
|
|
$options = array();
|
|
foreach ($operations as $key => $value) {
|
|
$options[] = $value[0];
|
|
}
|
|
|
|
$form = form_select(NULL, "operation", 0, $options);
|
|
$form .= form_submit(t("Go"));
|
|
|
|
$output .= "<h3>". t("Update options") ."</h3>";
|
|
$output .= "<div class=\"container-inline\">$form</div>";
|
|
|
|
/*
|
|
** Overview table:
|
|
*/
|
|
|
|
$result = pager_query("SELECT n.*, u.name, u.uid FROM {node} n INNER JOIN {users} u ON n.uid = u.uid ". $filters[$filter][1], 50);
|
|
$header = array(NULL, t("title"), t("type"), t("author"), t("status"), array("data" => t("operations"), "colspan" => 2));
|
|
|
|
while ($node = db_fetch_object($result)) {
|
|
$rows[] = array(form_checkbox(NULL, "status][$node->nid", 1, 0), l($node->title, "node/view/$node->nid") ." ". (node_is_new($node->nid, $node->changed) ? theme_mark() : ""), module_invoke($node->type, "node", "name"), format_name($node), ($node->status ? t("published") : t("not published")), l(t("edit node"), "admin/node/edit/$node->nid"), l(t("delete node"), "admin/node/delete/$node->nid"));
|
|
}
|
|
|
|
if ($pager = theme("pager", NULL, 50, 0)) {
|
|
$rows[] = array(array("data" => $pager, "colspan" => 7));
|
|
}
|
|
|
|
$output .= "<h3>". $filters[$filter][0] ."</h3>";
|
|
$output .= theme("table", $header, $rows);
|
|
return form($output);
|
|
}
|
|
|
|
function node_admin_settings($edit) {
|
|
$op = $_POST["op"];
|
|
|
|
if ($op == t("Save configuration")) {
|
|
/*
|
|
** Save the configuration options:
|
|
*/
|
|
|
|
foreach ($edit as $name => $value) {
|
|
variable_set($name, $value);
|
|
}
|
|
drupal_set_message(t("the content settings have been saved."));
|
|
}
|
|
|
|
if ($op == t("Reset to defaults")) {
|
|
/*
|
|
** Reset the configuration options to their default value:
|
|
*/
|
|
|
|
foreach ($edit as $name => $value) {
|
|
variable_del($name);
|
|
}
|
|
drupal_set_message(t("the content settings have been reset to their default values."));
|
|
}
|
|
|
|
$header = array_merge(array(t("type")), array_keys(node_invoke_nodeapi($node, "settings")));
|
|
foreach (module_list() as $name) {
|
|
if (module_hook($name, "node")) {
|
|
$node->type = $name;
|
|
$cols = array();
|
|
foreach (node_invoke_nodeapi($node, "settings") as $setting) {
|
|
$cols[] = array("data" => $setting, "align" => "center", "width" => 55);
|
|
}
|
|
$rows[] = array_merge(array(module_invoke($name, "node", "name")), $cols);
|
|
}
|
|
}
|
|
|
|
$output .= theme("table", $header, $rows);
|
|
|
|
/* This is an idea for the future.
|
|
foreach (module_list() as $name) {
|
|
if (module_hook($name, "node")) {
|
|
$node->type = $name;
|
|
|
|
// Create theme("table", ) data:
|
|
$header = array_keys(node_invoke_nodeapi($node, "settings"));
|
|
$cols = array();
|
|
foreach (node_invoke_nodeapi($node, "settings") as $setting) {
|
|
$cols[] = array("data" => $setting, "align" => "center", "width" => 75);
|
|
}
|
|
|
|
$output .= "<h2>". module_invoke($name, "node", "name") ."</h2>";
|
|
$output .= theme("table", $header, array($cols));
|
|
$output .= "<br /><br />";
|
|
}
|
|
}
|
|
*/
|
|
|
|
$output .= form_submit(t("Save configuration"));
|
|
$output .= form_submit(t("Reset to defaults"));
|
|
|
|
return form($output);
|
|
|
|
}
|
|
|
|
function node_revision_overview($nid) {
|
|
|
|
if (user_access("administer nodes")) {
|
|
$node = node_load(array("nid" => $nid));
|
|
|
|
if ($node->revisions) {
|
|
$header = array(t("older revisions"), array("colspan" => "3", "data" => t("operations")));
|
|
|
|
foreach ($node->revisions as $key => $revision) {
|
|
$rows[] = array(t("revision #%r revised by %u on %d", array("%r" => $key, "%u" => format_name(user_load(array("uid" => $revision["uid"]))), "%d" => format_date($revision["timestamp"], "small"))) . ($revision["history"] ? "<br /><small>". $revision["history"] ."</small>" : ""), l(t("view"), "node/view/$node->nid", array(), "revision=$key"), l(t("rollback"), "node/rollback-revision/$node->nid/$key"), l(t("delete"), "node/delete-revision/$node->nid/$key"));
|
|
}
|
|
$output .= theme("table", $header, $rows);
|
|
}
|
|
}
|
|
|
|
return $output;
|
|
}
|
|
|
|
|
|
/*
|
|
** Return the revision with the specified revision number.
|
|
*/
|
|
|
|
function node_revision_load($node, $revision) {
|
|
return $node->revisions[$revision]["node"];
|
|
}
|
|
|
|
/*
|
|
** Create and return a new revision of the given node.
|
|
*/
|
|
|
|
function node_revision_create($node) {
|
|
global $user;
|
|
|
|
/*
|
|
** 'revision' is the name of the field used to indicicate that we
|
|
** have to create a new revision of a node.
|
|
*/
|
|
|
|
if ($node->nid && $node->revision) {
|
|
$prev = node_load(array("nid" => $node->nid));
|
|
$node->revisions = $prev->revisions;
|
|
unset($prev->revisions);
|
|
$node->revisions[] = array("uid" => $user->uid, "timestamp" => time(), "node" => $prev, "history" => $node->history);
|
|
}
|
|
|
|
return $node;
|
|
}
|
|
|
|
/*
|
|
** Roll-back to the revision with the specified revision number.
|
|
*/
|
|
|
|
function node_revision_rollback($nid, $revision) {
|
|
global $user;
|
|
|
|
if (user_access("administer nodes")) {
|
|
$node = node_load(array("nid" => $nid));
|
|
|
|
/*
|
|
** Extract the specified revision:
|
|
*/
|
|
|
|
$rev = $node->revisions[$revision]["node"];
|
|
|
|
/*
|
|
** Inherit all the past revisions:
|
|
*/
|
|
|
|
$rev->revisions = $node->revisions;
|
|
|
|
/*
|
|
** Save the original/current node:
|
|
*/
|
|
|
|
$rev->revisions[] = array("uid" => $user->uid, "timestamp" => time(), "node" => $node);
|
|
|
|
/*
|
|
** Remove the specified revision:
|
|
*/
|
|
|
|
unset($rev->revisions[$revision]);
|
|
|
|
/*
|
|
** Save the node:
|
|
*/
|
|
|
|
foreach ($node as $key => $value) {
|
|
$filter[] = $key;
|
|
}
|
|
|
|
node_save($rev, $filter);
|
|
|
|
drupal_set_message(t("rollbacked to revision #%revision of '%title'", array("%revision" => $revision, "%title" => $node->title)));
|
|
}
|
|
}
|
|
|
|
/*
|
|
** Delete the revision with specified revision number.
|
|
*/
|
|
|
|
function node_revision_delete($nid, $revision) {
|
|
|
|
if (user_access("administer nodes")) {
|
|
$node = node_load(array("nid" => $nid));
|
|
|
|
unset($node->revisions[$revision]);
|
|
|
|
node_save($node, array("nid", "revisions"));
|
|
|
|
drupal_set_message(t("deleted revision #%revision of '%title'", array("%revision" => $revision, "%title" => $node->title)));
|
|
}
|
|
}
|
|
|
|
/*
|
|
** Return a list of all the existing revision numbers.
|
|
*/
|
|
|
|
function node_revision_list($node) {
|
|
if (is_array($node->revisions)) {
|
|
return array_keys($node->revisions);
|
|
}
|
|
else {
|
|
return array();
|
|
}
|
|
}
|
|
|
|
function node_admin() {
|
|
$op = $_POST["op"];
|
|
$edit = $_POST["edit"];
|
|
|
|
if (user_access("administer nodes")) {
|
|
|
|
if (empty($op)) {
|
|
$op = arg(2);
|
|
}
|
|
|
|
/*
|
|
** Compile a list of the administrative links:
|
|
*/
|
|
switch ($op) {
|
|
case "search":
|
|
$output = search_type("node", url("admin/node/search"), $_POST["keys"]);
|
|
break;
|
|
case "edit":
|
|
$output = node_admin_edit(arg(3));
|
|
break;
|
|
case "delete":
|
|
$output = node_delete(array("nid" => arg(3)));
|
|
break;
|
|
case t("Preview"):
|
|
$edit = node_validate($edit, $error);
|
|
$output = node_preview($edit, $error);
|
|
break;
|
|
case t("Submit"):
|
|
$output = node_submit($edit);
|
|
break;
|
|
case t("Delete"):
|
|
$output = node_delete($edit);
|
|
break;
|
|
case t("Save configuration"):
|
|
case t("Reset to defaults"):
|
|
case "settings":
|
|
$output = node_admin_settings($edit);
|
|
break;
|
|
default:
|
|
$output = node_admin_nodes();
|
|
}
|
|
print theme("page", $output);
|
|
}
|
|
else {
|
|
print theme("page", message_access());
|
|
}
|
|
}
|
|
|
|
function node_block($op = "list", $delta = 0) {
|
|
|
|
if ($op == "list") {
|
|
$blocks[0]["info"] = t("Syndicate");
|
|
return $blocks;
|
|
}
|
|
else {
|
|
$block["subject"] = t("Syndicate");
|
|
$block["content"] = "<div class=\"xml-icon\">". l("<img src=\"". theme("image", "xml.gif") ."\" width=\"36\" height=\"14\" style=\"border: 0px;\" alt=\"XML\" title=\"XML\" />", "node/feed", array("title" => t("Read the XML version of this page."))) ."</div>";
|
|
|
|
return $block;
|
|
}
|
|
}
|
|
|
|
function node_feed($nodes = 0, $channel = array()) {
|
|
global $base_url, $languages;
|
|
|
|
/*
|
|
** A generic function for generating RSS feeds from a set of nodes.
|
|
** - $nodes should be an object as returned by db_query() which contains
|
|
** the nid field.
|
|
** - $channel is an associative array containing title, link, and
|
|
** description keys.
|
|
*/
|
|
|
|
if (!$nodes) {
|
|
$nodes = db_query_range("SELECT nid FROM {node} WHERE promote = '1' AND status = '1' ORDER BY created DESC", 0, 15);
|
|
}
|
|
|
|
while ($node = db_fetch_object($nodes)) {
|
|
/*
|
|
** Load the specified node:
|
|
*/
|
|
|
|
$item = node_load(array("nid" => $node->nid));
|
|
$link = url("node/view/$node->nid");
|
|
$items .= format_rss_item($item->title, $link, ($item->teaser ? $item->teaser : $item->body), array("pubDate" => date("r", $item->changed)));
|
|
}
|
|
|
|
$output .= "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
|
|
$output .= "<!DOCTYPE rss [<!ENTITY % HTMLlat1 PUBLIC \"-//W3C//ENTITIES Latin 1 for XHTML//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent\">]>\n";
|
|
if (!$channel["version"]) $channel["version"] = "0.92";
|
|
if (!$channel["title"]) $channel["title"] = variable_get("site_name", "drupal") ." - ". variable_get("site_slogan", "");
|
|
if (!$channel["link"]) $channel["link"] = $base_url;
|
|
if (!$channel["description"]) $channel["description"] = variable_get("site_mission", "");
|
|
foreach ($languages as $key => $value) break;
|
|
if (!$channel["language"]) $channel["language"] = $key ? $key : "en";
|
|
$output .= "<rss version=\"". $channel["version"] . "\">\n";
|
|
$output .= format_rss_channel($channel["title"], $channel["link"], $channel["description"], $items, $channel["language"]);
|
|
$output .= "</rss>\n";
|
|
|
|
header("Content-Type: text/xml");
|
|
print $output;
|
|
}
|
|
|
|
function node_validate($node, &$error) {
|
|
global $user;
|
|
$error = array();
|
|
|
|
/*
|
|
** Convert the node to an object if necessary:
|
|
*/
|
|
|
|
$node = array2object($node);
|
|
|
|
/*
|
|
** Validate the title field:
|
|
*/
|
|
|
|
if (isset($node->title)) {
|
|
$node->title = strip_tags($node->title);
|
|
if (!$node->title) {
|
|
$error["title"] = theme("error", t("You have to specify a valid title."));
|
|
}
|
|
}
|
|
|
|
/*
|
|
** Common default values:
|
|
*/
|
|
|
|
$node->teaser = node_teaser($node->body);
|
|
|
|
/*
|
|
** Create a new revision when required:
|
|
*/
|
|
|
|
$node = node_revision_create($node);
|
|
|
|
if (user_access("administer nodes")) {
|
|
|
|
/*
|
|
** Setup default values if required:
|
|
*/
|
|
|
|
if (!$node->created) {
|
|
$node->created = time();
|
|
}
|
|
|
|
if (!$node->date) {
|
|
$node->date = date("M j, Y g:i a", $node->created);
|
|
}
|
|
|
|
if (!is_numeric($node->status)) {
|
|
$node->status = 1;
|
|
}
|
|
|
|
/*
|
|
** Validate the "authored by"-field:
|
|
*/
|
|
|
|
if (empty($node->name) || empty($node->uid)){
|
|
/*
|
|
** The use of empty() is mandatory in the context of usernames
|
|
** as the empty string denotes the anonymous user. In case we
|
|
** are dealing with an anomymous user we set the user ID to 0.
|
|
*/
|
|
$node->uid = 0;
|
|
}
|
|
else if ($account = user_load(array("name" => $node->name))) {
|
|
$node->uid = $account->uid;
|
|
}
|
|
else {
|
|
$error["name"] = theme("error", t("The name '%u' does not exist.", array ("%u" => $node->name)));
|
|
}
|
|
|
|
/*
|
|
** Validate the "authored on"-field:
|
|
*/
|
|
|
|
if (strtotime($node->date) > 1000) {
|
|
$node->created = strtotime($node->date);
|
|
}
|
|
else {
|
|
$error["date"] = theme("error", t("You have to specifiy a valid date."));
|
|
}
|
|
}
|
|
else {
|
|
// Validate for normal users:
|
|
$node->uid = $user->uid ? $user->uid : 0;
|
|
// Force defaults in case people modify the form:
|
|
$node->status = variable_get("node_status_$node->type", 1);
|
|
$node->promote = variable_get("node_promote_$node->type", 1);
|
|
$node->moderate = variable_get("node_moderate_$node->type", 0);
|
|
$node->static = variable_get("node_static_$node->type", 0);
|
|
$node->revision = variable_get("node_revision_$node->type", 0);
|
|
unset($node->created);
|
|
}
|
|
|
|
/*
|
|
** Do node type specific validation checks.
|
|
*/
|
|
|
|
$result = node_invoke($node, "validate");
|
|
$error = $error + (is_array($result) ? $result : array()) + node_invoke_nodeapi($node, "validate");
|
|
|
|
return $node;
|
|
}
|
|
|
|
|
|
function node_form($edit, $error = NULL) {
|
|
|
|
/*
|
|
** Validate the node:
|
|
*/
|
|
|
|
if ($error === NULL) {
|
|
/* Only validate if we don't already know the errors. */
|
|
$edit = node_validate($edit, $error);
|
|
}
|
|
|
|
// Prepend extra node form:
|
|
$form = implode("", node_invoke_nodeapi($edit, "form pre", $error));
|
|
|
|
// Get the node specific bits:
|
|
|
|
// Can't use node_invoke:
|
|
// $error and $param must be passed by reference.
|
|
$function = $edit->type ."_form";
|
|
if (function_exists($function)) {
|
|
$form .= $function($edit, $help, $error, $param);
|
|
}
|
|
|
|
// Append extra node form:
|
|
$form .= implode("", node_invoke_nodeapi($edit, "form post", $error));
|
|
|
|
/*
|
|
** Add the help text:
|
|
*/
|
|
|
|
if ($help) {
|
|
$output .= "<p>$help</p>";
|
|
}
|
|
|
|
$output .= "<div class=\"node-form\">";
|
|
|
|
/*
|
|
** Add the admin specific parts:
|
|
*/
|
|
|
|
if (user_access("administer nodes")) {
|
|
$output .= "<div class=\"admin\">";
|
|
|
|
$author = form_textfield(t("Authored by"), "name", $edit->name, 20, 60, $error["name"]);
|
|
$author .= form_textfield(t("Authored on"), "date", $edit->date, 20, 25, $error["date"]);
|
|
|
|
$output .= "<div class=\"authored\">";
|
|
$output .= form_group(t("Authoring information"), $author);
|
|
$output .= "</div>\n";
|
|
|
|
$options .= form_checkbox(t("Published"), "status", 1, isset($edit->status) ? $edit->status : variable_get("node_status_$edit->type", 1));
|
|
$options .= form_checkbox(t("In moderation queue"), "moderate", 1, isset($edit->moderate) ? $edit->moderate : variable_get("node_moderate_$edit->type", 0));
|
|
$options .= form_checkbox(t("Promoted to front page"), "promote", 1, isset($edit->promote) ? $edit->promote : variable_get("node_promote_$edit->type", 1));
|
|
$options .= form_checkbox(t("Static on front page"), "static", 1, isset($edit->static) ? $edit->static : variable_get("node_static_$edit->type", 0));
|
|
$options .= form_checkbox(t("Create new revision"), "revision", 1, isset($edit->revision) ? $edit->revision : variable_get("node_revision_$edit->type", 0));
|
|
|
|
$output .= "<div class=\"options\">";
|
|
$output .= form_group(t("Options"), $options);
|
|
$output .= "</div>\n";
|
|
|
|
$extras .= implode("</div><div class=\"extra\">", node_invoke_nodeapi($edit, "form admin"));
|
|
$output .= $extras ? "<div class=\"extra\">$extras</div></div>" : "</div>";
|
|
}
|
|
|
|
/*
|
|
** Add the default fields:
|
|
*/
|
|
$output .= "<div class=\"standard\">";
|
|
$output .= form_textfield(t("Title"), "title", $edit->title, 60, 128, $error["title"]);
|
|
|
|
/*
|
|
** Add the node specific fields:
|
|
*/
|
|
|
|
$output .= $form;
|
|
|
|
/*
|
|
** Add the hidden fields:
|
|
*/
|
|
|
|
if ($edit->nid) {
|
|
$output .= form_hidden("nid", $edit->nid);
|
|
}
|
|
|
|
if (isset($edit->uid)) {
|
|
/*
|
|
** The use of isset() is mandatory in the context of user IDs as uid
|
|
** 0 denotes the anonymous user.
|
|
*/
|
|
$output .= form_hidden("uid", $edit->uid);
|
|
}
|
|
|
|
if ($edit->created) {
|
|
$output .= form_hidden("created", $edit->created);
|
|
}
|
|
|
|
$output .= form_hidden("type", $edit->type);
|
|
|
|
/*
|
|
** Add the buttons:
|
|
*/
|
|
|
|
$output .= form_submit(t("Preview"));
|
|
|
|
if (!$error) {
|
|
if ($edit->title && $edit->type) {
|
|
$output .= form_submit(t("Submit"));
|
|
}
|
|
elseif (!variable_get("node_preview", 0)) {
|
|
$output .= form_submit(t("Submit"));
|
|
}
|
|
}
|
|
|
|
if ($edit->nid && node_access("delete", $edit)) {
|
|
$output .= form_submit(t("Delete"));
|
|
}
|
|
|
|
$output .= "</div></div>";
|
|
|
|
return form($output, ($param["method"] ? $param["method"] : "post"), $param["action"], array_merge($param["options"], array("id" => "node-form")));
|
|
}
|
|
|
|
function node_add($type) {
|
|
global $user;
|
|
|
|
$edit = $_POST["edit"];
|
|
|
|
/*
|
|
** If a node type has been specified, validate it existence. If no
|
|
** (valid) node type has been provied, display a node type overview.
|
|
*/
|
|
|
|
if ($type && node_access("create", $type)) {
|
|
// Initialize settings:
|
|
$node = array("uid" => $user->uid, "name" => $user->name, "type" => $type);
|
|
|
|
/*
|
|
** Allow the following fields to be initialized via $_GET (eg. for use
|
|
** with a "blog it" bookmarklet):
|
|
*/
|
|
foreach (array("title", "teaser", "body") as $field) {
|
|
if ($_GET["edit"][$field]) {
|
|
$node[$field] = $_GET["edit"][$field];
|
|
}
|
|
}
|
|
$output = node_form($node);
|
|
drupal_set_breadcrumb(array(l(t("Home"), NULL), l(t("create content"), "node/add")));
|
|
}
|
|
else {
|
|
|
|
/*
|
|
** Compile a list with the different node types and their explanation:
|
|
*/
|
|
|
|
foreach (module_list() as $name) {
|
|
if (module_hook($name, "node") && node_access("create", $name)) {
|
|
$output .= "<li>";
|
|
$output .= " ". l(module_invoke($name, "node", "name"), "node/add/$name", array("title" => t("Add a new %s.", array("%s" => module_invoke($name, "node", "name")))));
|
|
$output .= " <div style=\"margin-left: 20px;\">". module_invoke($name, "node", "description") ."</div>";
|
|
$output .= "</li>";
|
|
}
|
|
}
|
|
|
|
$output = t("Choose the appropriate item from the list:") ."<ul>$output</ul>";
|
|
drupal_set_breadcrumb(array(l(t("Home"), NULL)));
|
|
}
|
|
|
|
return $output;
|
|
}
|
|
|
|
function node_edit($id) {
|
|
global $user;
|
|
|
|
$node = node_load(array("nid" => $id));
|
|
|
|
if (node_access("update", $node)) {
|
|
$output = node_form($node);
|
|
}
|
|
else {
|
|
$output = message_access();
|
|
}
|
|
|
|
return $output;
|
|
}
|
|
|
|
function node_preview($node, $error = NULL) {
|
|
|
|
/*
|
|
** Convert the array to an object:
|
|
*/
|
|
|
|
$node = array2object($node);
|
|
|
|
if (node_access("create", $node) || node_access("update", $node)) {
|
|
|
|
/*
|
|
** Load the user's name when needed:
|
|
*/
|
|
|
|
if (isset($node->name)) {
|
|
/*
|
|
** The use of isset() is mandatory in the context of user IDs as uid
|
|
** 0 denotes the anonymous user.
|
|
*/
|
|
|
|
if ($user = user_load(array("name" => $node->name))) {
|
|
$node->uid = $user->uid;
|
|
}
|
|
else {
|
|
$node->uid = 0; // anonymous user
|
|
}
|
|
}
|
|
else if ($node->uid) {
|
|
$user = user_load(array("uid" => $node->uid));
|
|
$node->name = $user->name;
|
|
}
|
|
|
|
/*
|
|
** Set the created time when needed:
|
|
*/
|
|
|
|
if (empty($node->created)) {
|
|
$node->created = time();
|
|
}
|
|
$node->changed = time();
|
|
|
|
/*
|
|
** Extract a teaser:
|
|
*/
|
|
|
|
$node->teaser = node_teaser($node->body);
|
|
|
|
/*
|
|
** Apply the required filters:
|
|
*/
|
|
|
|
if ($node->nid) {
|
|
$view = array2object(array_merge(object2array($node), module_invoke($node->type, "save", "update", $node)));
|
|
}
|
|
else {
|
|
$view = array2object(array_merge(object2array($node), module_invoke($node->type, "save", "create", $node)));
|
|
}
|
|
|
|
/*
|
|
** Display a preview of the node:
|
|
*/
|
|
|
|
if ($view->teaser && $view->teaser != $view->body) {
|
|
$output = "<h3>". t("Preview trimmed version") ."</h3>";
|
|
$output .= node_view($view, 1);
|
|
$output .= "<p><i>". t("The trimmed version of your post shows how your post looks like when promoted to the main page or when exported for syndication. You can insert a delimiter '<!--break-->' (without the quotes) to fine-tune where your post gets split.") ."</i></p>";
|
|
$output .= "<h3>". t("Preview full version") ."</h3>";
|
|
$output .= node_view($view, 0);
|
|
}
|
|
else {
|
|
$output .= node_view($view, 0);
|
|
}
|
|
|
|
$output .= node_form($node, $error);
|
|
|
|
$name = module_invoke($node->type, "node", "name");
|
|
drupal_set_breadcrumb(array(l(t("Home"), NULL), l(t("create content"), "node/add"), l(t("Submit %name", array("%name" => $name)), "node/add/$node->type")));
|
|
|
|
return $output;
|
|
}
|
|
}
|
|
|
|
function node_submit($node) {
|
|
global $user;
|
|
|
|
/*
|
|
** Fixup the node when required:
|
|
*/
|
|
|
|
$node = node_validate($node, $error);
|
|
|
|
/*
|
|
** If something went wrong, go back to the preview form:
|
|
*/
|
|
|
|
if ($error) {
|
|
return node_preview($node, $error);
|
|
}
|
|
|
|
/*
|
|
** Prepare the node's body:
|
|
*/
|
|
|
|
if ($node->nid) {
|
|
|
|
/*
|
|
** Check whether the current user has the proper access rights to
|
|
** perform this operation:
|
|
*/
|
|
|
|
if (node_access("update", $node)) {
|
|
$node->nid = node_save($node);
|
|
watchdog("special", "$node->type: updated '$node->title'", l(t("view post"), "node/view/$node->nid"));
|
|
$msg = t("the %name was updated.", array ("%name" => module_invoke($node->type, "node", "name")));
|
|
}
|
|
}
|
|
else {
|
|
|
|
/*
|
|
** Check whether the current user has the proper access rights to
|
|
** perform this operation:
|
|
*/
|
|
|
|
if (node_access("create", $node)) {
|
|
|
|
/*
|
|
** Verify a user's submission rate and avoid duplicate nodes being
|
|
** inserted:
|
|
*/
|
|
|
|
throttle("node", variable_get("max_node_rate", 900));
|
|
|
|
$node->nid = node_save($node);
|
|
watchdog("special", "$node->type: added '$node->title'", l(t("view post"), "node/view/$node->nid"));
|
|
$msg = t("your %name was created.", array ("%name" => module_invoke($node->type, "node", "name")));
|
|
}
|
|
}
|
|
|
|
$node = node_load(array("nid" => $node->nid));
|
|
drupal_set_message($msg);
|
|
drupal_set_title($node->title);
|
|
return node_show($node, NULL);
|
|
}
|
|
|
|
function node_delete($edit) {
|
|
|
|
$node = node_load(array("nid" => $edit["nid"]));
|
|
|
|
if (node_access("delete", $node)) {
|
|
|
|
if ($edit["confirm"]) {
|
|
|
|
/*
|
|
** Delete the specified node:
|
|
*/
|
|
|
|
db_query("DELETE FROM {node} WHERE nid = '$node->nid'");
|
|
|
|
/*
|
|
** Call the node specific callback (if any):
|
|
*/
|
|
|
|
node_invoke($node, "delete");
|
|
node_invoke_nodeapi($node, "delete");
|
|
|
|
/*
|
|
** Clear the cache so an anonymous poster can see the node being
|
|
** deleted.
|
|
*/
|
|
|
|
cache_clear_all();
|
|
|
|
watchdog("special", "$node->type: deleted '$node->title'");
|
|
$output = t("The node has been deleted.");
|
|
}
|
|
else {
|
|
$output .= form_item(t("Confirm deletion"), $node->title);
|
|
$output .= form_hidden("nid", $node->nid);
|
|
$output .= form_hidden("confirm", 1);
|
|
$output .= form_submit(t("Delete"));
|
|
$output = form($output);
|
|
}
|
|
}
|
|
|
|
return $output;
|
|
}
|
|
|
|
function node_page() {
|
|
global $id, $user, $or, $and;
|
|
|
|
$op = $_POST["op"];
|
|
$edit = $_POST["edit"];
|
|
|
|
if (user_access("access content")) {
|
|
if (empty($op)) {
|
|
$op = arg(1);
|
|
}
|
|
|
|
if ($op == "feed") {
|
|
node_feed();
|
|
return;
|
|
}
|
|
|
|
if ($op == "view") {
|
|
$node = node_load(array("nid" => arg(2), "status" => 1), $_GET["revision"]);
|
|
}
|
|
|
|
$name = module_invoke(arg(2), "node", "name");
|
|
|
|
switch ($op) {
|
|
case "add":
|
|
print theme("page", node_add(arg(2)), arg(2) ? t("Submit %name", array("%name" => $name)) : t("create content"));
|
|
break;
|
|
case "edit":
|
|
print theme("page", node_edit(arg(2)), t("Edit %name", array("%name" => $name)));
|
|
break;
|
|
case "view":
|
|
print theme("page", node_show($node, arg(3)), $node->title);
|
|
break;
|
|
case "revisions":
|
|
print theme("page", node_revision_overview(arg(2)), t("Revisions"));
|
|
break;
|
|
case "rollback-revision":
|
|
node_revision_rollback(arg(2), arg(3));
|
|
print theme("page", node_revision_overview(arg(2)), t("Revisions"));
|
|
break;
|
|
case "delete-revision":
|
|
node_revision_delete(arg(2), arg(3));
|
|
print theme("page", node_revision_overview(arg(2)), t("Revisions"));
|
|
break;
|
|
case t("Preview"):
|
|
$edit = node_validate($edit, $error);
|
|
print theme("page", node_preview($edit, $error), t("Preview %name", array("%name" => $name)));
|
|
break;
|
|
case t("Submit"):
|
|
drupal_set_title(t("Submit %name", array("%name" => $name)));
|
|
print theme("page", node_submit($edit));
|
|
break;
|
|
case t("Delete"):
|
|
print theme("page", node_delete($edit), t("Delete %name", array("%name" => $name)));
|
|
break;
|
|
default:
|
|
$output = "";
|
|
$result = pager_query("SELECT nid, type FROM {node} WHERE promote = '1' AND status = '1' ORDER BY static DESC, created DESC", variable_get("default_nodes_main", 10));
|
|
|
|
while ($node = db_fetch_object($result)) {
|
|
$output .= node_view(node_load(array("nid" => $node->nid, "type" => $node->type)), 1);
|
|
}
|
|
$output .= theme('pager', NULL, variable_get("default_nodes_main", 10));
|
|
print theme("page", $output, "");
|
|
}
|
|
}
|
|
else {
|
|
print theme("page", message_access());
|
|
}
|
|
|
|
}
|
|
|
|
function node_update_index() {
|
|
|
|
// Return an array of values to dictate how to update the search index
|
|
// for this particular type of node.
|
|
//
|
|
// "last_update"'s value is used with variable_set to set the
|
|
// last time this node type had an index update run.
|
|
//
|
|
// "node_type"'s value is used to identify the node type in the search
|
|
// index.
|
|
//
|
|
// "select"'s value is used to select the node id and text fields from
|
|
// the table we are indexing. In this case, we also check against the
|
|
// last run date for the nodes update.
|
|
return array("last_update" => "node_cron_last",
|
|
"node_type" => "node",
|
|
"select" => "SELECT n.nid as lno, n.title as text1, n.body as text2 FROM {node} n WHERE n.status = 1 AND moderate = 0 and (created > " . variable_get("node_cron_last", 1) . " or changed > " . variable_get("node_cron_last", 1) . ")");
|
|
}
|
|
|
|
function node_nodeapi(&$node, $op, $arg = 0) {
|
|
switch ($op) {
|
|
case "settings":
|
|
$output[t("publish")] = form_checkbox("", "node_status_$node->type", 1, variable_get("node_status_$node->type", 1));
|
|
$output[t("promote")] = form_checkbox("", "node_promote_$node->type", 1, variable_get("node_promote_$node->type", 1));
|
|
$output[t("moderate")] = form_checkbox("", "node_moderate_$node->type", 1, variable_get("node_moderate_$node->type", 0));
|
|
$output[t("static")] = form_checkbox("", "node_static_$node->type", 1, variable_get("node_static_$node->type", 0));
|
|
$output[t("revision")] = form_checkbox("", "node_revision_$node->type", 1, variable_get("node_revision_$node->type", 0));
|
|
return $output;
|
|
case "fields":
|
|
return array("nid", "uid", "type", "title", "teaser", "body", "revisions", "status", "promote", "moderate", "static", "created", "changed");
|
|
}
|
|
}
|
|
|
|
?>
|