Nodes"; $output .= "

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:

"; $output .= "
A Title
Up to 128 characters of text that titles the node.
"; $output .= strtr("
A Teaser
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.
", array("%teaser" => l(t("click here"), "admin/system/modules/node") )); $output .= "
The Body
The main text that comprises your content.
"; $output .= "
A Type
What kind of node is this? Blog, book, forum, comment, unextended, etc.
"; $output .= "
An Author
The author's name. It will either be \"anonymous\" or a valid user. You cannot set it to an arbitrary value.
"; $output .= "
Authored on
The date the node was written.
"; $output .= "
Changed
The last time this node was changed.
"; $output .= strtr("
Static on front page
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.
",array("%teaser" => l(t("click here"),"admin/system/modules/node") )); $output .= "
Allow user comments
A node can have comments. These comments can be written by other users (Read-write), or only by admins (Read-only).
"; $output .= "
Attributes
A way to sort nodes.
"; $output .= "
Revisions
Drupal has a revision system so that you can \"roll back\" to an older version of a node if the new version is not what you want.
"; $output .= "
Promote to front page
To get people to look at the new stuff on your site you can choose to move it to the front page.
"; $output .= "
In moderation queue
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.
"; $output .= strtr("
Votes
If you are moderating a node this counts how many votes the node has gotten. Once a node gets a certain number of vote if will either be Approved, or Dropped (To setup the number of votes needed and the promote and dump scores %queue.).
",array("%queue" => l(t("click here"), "admin/system/modules/queue") )); $output .= "
Score
The score of the node is gotten by the votes it is given.
"; $output .= "
Users
The list of users who have voted on a moderated node.
"; $output .= "
Published
When using Drupal's moderation system a node remains unpublished -- unavaliable to non-moderators -- until it is marked Published.
"; $output .= "

Now that you know what is in a node, here are some of the types of nodes available.

"; if ($mod == "admin") { foreach (module_list() as $name) { if (module_hook($name, "node") && $name != "node") { $output .= "

". t("Node type: %module", array("%module" => module_invoke($name, "node", "name"))). "

"; $output .= module_invoke($name, "node", "description"); } } } break; case 'admin/system/modules': $output = "The core that allows content to be submitted to the site."; break; case 'admin/system/modules/node': $output = "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 = strtr("Below is a list of all of the nodes in your site. Other forms of content are listed elsewhere (e.g. %comment).
Clicking a title views that node, while clicking an author's name edits their user information.
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 = "Enter a simple pattern to search for a post. This can include the wildcard character *.
For example, a search for \"br*\" might return \"bread bakers\", \"our daily bread\" and \"brenda\"."; break; case 'admin/node/settings': $output = "This pages lets you set the defaults used during creation of nodes for all the different node types.
comment: Read/write setting for comments.
publish: Is this node publicly viewable, has it been published?
promote: Is this node to be promoted to the front page?
moderate: Does this node need approval before it can be viewed?
static: Is this node always visible on the front page?
revision: Will this node go into the revision system allowing multiple versions to be saved?"; break; } return t($output); } function node_system($field){ $output = ""; if ($field == "description") {$output = node_help("admin/system/modules"); } else if ($field == "admin-help") {$output = node_help("admin/system/modules/node");}; return $output; } /* ** 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_url($node), array("title" => format_plural($number, "%count comment", "%count comments"))); } return theme("theme_node_list", $items, $title); } function theme_node_list($items, $title = NULL) { return theme("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, ""); 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, "
", $size)) { return substr($body, 0, $length); } if ($length = strpos($body, "
", $size)) { return substr($body, 0, $length); } if ($length = strpos($body, "

", $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, $arg = 0) { 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 ($arg ? $function($node, $arg) : $function($node)); } } function node_invoke_all(&$node, $hook, $op, $arg = 0) { $return = array(); foreach (module_list() as $name) { if ((module_hook($name, "node") || module_hook($name, "nodeapi")) && module_hook($name, $hook)) { $function = $name ."_". $hook; $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 LEFT 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 = module_invoke($node->type, "load", $node)) { 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_all($node, "nodeapi", "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_all($node, "nodeapi", "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_all($node, "nodeapi", "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) { $node = array2object($node); /* ** Remove the delimiter (if any) that seperates the teaser from the ** body. TODO: this strips legitimate uses of '' also. */ $node->body = str_replace("", "", $node->body); /* ** The "view" hook can be implemented to overwrite the default function ** to display nodes. */ if (module_hook($node->type, "view")) { node_invoke($node, "view", $main); } else { /* ** Default behavior: */ $node->teaser = check_output($node->teaser); $node->body = check_output($node->body); theme("node", $node, $main); } } function node_show($node, $cid) { if (node_access("view", $node)) { node_view($node); if (function_exists("comment_render") && $node->comment) { comment_render($node, $cid); } /* ** Update the history table, stating that this user viewed this node. */ node_tag_new($node->nid); } } 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; } $function = $type ."_access"; if (function_exists($function)) { return $function($op, $node); } else { return 0; } } function node_perm() { return array("administer nodes", "access content", "create custom URLs"); } 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 LEFT 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_select(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_conf_filters() { $output .= form_select(t("Filter HTML tags"), "filter_html", variable_get("filter_html", 0), array(t("Disabled"), t("Enabled")), t("Filter HTML and PHP tags in user-contributed content.")); $output .= form_textfield(t("Allowed HTML tags"), "allowed_html", variable_get("allowed_html", "