status; } if ($op == "create") { return 1; } if ($op == "update") { /* ** Everyone can upate a book page if there are no suggested updates ** of that page waiting for approval and as long as the "create new ** revision"-bit is set; that is, only updates that don't overwrite ** the current or pending information are allowed. */ return !$node->moderate && $node->revision; } } function book_save($op, $node) { global $user, $REQUEST_URI; if ($op == "approve") { return array("status" => 1); } if ($op == "create") { return array("moderate" => 1, "parent", "promote" => 0, "status" => 1, "weight"); } if ($op == "decline") { return array("status" => 0); } if ($op == "update") { if (strstr($REQUEST_URI, "module.php?mod=node&op=edit")) { /* ** If a regular user updates a book page, we always create a new ** revision. All new revisions have to be approved (moderation) ** and are not promoted by derault. See also: book_load(). */ return array("created" => time(), "moderate" => 1, "name" => $user->name, "parent", "promote" => 0, "score" => 0, "status" => 1, "uid" => $user->uid, "users" => "", "revisions", "votes" => 0, "weight"); } else if (user_access("adminster nodes")) { /* ** If a node administrator updates a book page, we don't create a ** new revision unless we are explicitly instructed to. If a node ** administrator updates a book page using the "update this book ** page"-link (like regular users do) then he'll be treated as a ** regular user. */ return array("parent", "weight"); } } } function book_link($type) { if ($type == "page" && user_access("access content")) { $links[] = "". t("collaborative book") .""; } if ($type == "admin" && user_access("administer nodes")) { $links[] = "". t("collaborative book") .""; } return $links ? $links : array(); } function book_load($node) { global $user, $REQUEST_URI; $book = db_fetch_object(db_query("SELECT parent, weight FROM book WHERE nid = '$node->nid'")); if (strstr($REQUEST_URI, "module.php?mod=node&op=edit")) { /* ** If a user is about to update a book page, we overload some ** fields to reflect the changes. We use the $REQUEST_URI to ** dectect this as we don't want to interfer with updating a ** book page through the admin pages. See also: book_save(). */ $book->name = $user->name; $book->uid = $user->uid; } /* ** We set the revision field to indicate that we have to create ** a new revision when updating this book page. */ $book->revision = 1; return $book; } function book_insert($node) { db_query("INSERT INTO book (nid, parent, weight) VALUES ('$node->nid', '$node->parent', '$node->weight')"); } function book_update($node) { db_query("UPDATE book SET parent = '$node->parent', weight = '$node->weight' WHERE nid = '$node->nid'"); } function book_delete($node) { db_query("DELETE FROM book WHERE nid = '$node->nid'"); } function book_form($node, $help, $error) { global $user; $output .= form_select(t("Parent"), "parent", $node->parent, book_toc(), t("The parent subject or category the page belongs in.")); $output .= form_textarea(t("Content"), "body", $node->body, 60, 20, t("Allowed HTML tags") .": ". htmlspecialchars(variable_get("allowed_html", ""))); $output .= form_textarea(t("Log message"), "history", $node->history, 60, 5, t("An explanation of the additions or updates being made to help the group understand your motivations.")); if (user_access("administer nodes")) { $output .= form_select(t("Weight"), "weight", $node->weight, array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30), t("The heavier nodes will sink and the lighter nodes will be positioned nearer the top.")); } else { /* ** Carry out some explanation or submission guidelines: */ $help = book_node("description"); /* ** If a regular user updates a book page, we create a new revision ** authored by that user: */ $output .= form_hidden("revision", 1); $node->uid = $user->uid; // $node is passed by reference $node->name = $user->name; } return $output; } function book_location($node, $nodes = array()) { $parent = db_fetch_object(db_query("SELECT n.nid, n.title, b.parent FROM node n LEFT JOIN book b ON n.nid = b.nid WHERE n.nid = '$node->parent'")); if ($parent->title) { $nodes = book_location($parent, $nodes); array_push($nodes, $parent); } return $nodes; } function book_view($node, $main = 0) { global $theme, $mod; /* ** Always display the most recently approved revision of a node ** unless we have to display it in the context of the moderation ** queue. */ if ($node->moderate && $mod != "queue") { $node = node_revision_load($node, end(node_revision_list($node))); } /* ** Display the node. If not displayed on the main page, we render ** the node as a page in the book with extra links to the previous ** and the next page. */ if ($main) { $theme->node($node, $main); } else { if ($node->nid && $node->parent) { $next = db_fetch_object(db_query("SELECT n.nid, n.title FROM node n LEFT JOIN book b ON n.nid = b.nid WHERE n.status = 1 AND b.parent = '$node->parent' AND (b.weight > '$node->weight' OR (b.weight = '$node->weight' AND n.title > '". check_query($node->title) ."')) ORDER BY b.weight ASC, n.title ASC")); $prev = db_fetch_object(db_query("SELECT n.nid, n.title FROM node n LEFT JOIN book b ON n.nid = b.nid WHERE n.status = 1 AND b.parent = '$node->parent' AND (b.weight < '$node->weight' OR (b.weight = '$node->weight' AND n.title < '". check_query($node->title) ."')) ORDER BY b.weight DESC, n.title DESC")); } $output .= "\n"; if ($node->title) { foreach (book_location($node) as $level) { $location .= "$indent nid\">$level->title
"; $indent .= "-"; } $output .= " "; $output .= " "; $output .= " "; } if ($node->body) { $output .= " "; } if ($node->nid) { $output .= " "; } $output .= " "; $output .= " "; $output .= " "; $output .= "
$locationnid\">". t("update this book page") ."

". check_output($node->title) ."". ($node->body ? "
". sprintf(t("Last updated by %s on %s"), format_name($node), format_date($node->created)) ." " : "") ."

". check_output($node->body, 1) ."

". book_tree($node->nid) ."

". ($prev ? "nid\">". t("previous") ."" : t("previous")) ."index". ($next ? "nid\">". t("next") ."" : t("next")) ."
". ($prev ? "". check_output($prev->title) ."" : " ") ."". ($node->parent ? "parent\">". t("up") ."" : t("up")) ."". ($next ? "". check_output($next->title) ."" : " ") ."
"; $theme->box(t("Handbook"), $output); } } function book_toc($parent = "", $indent = "", $toc = array()) { /* ** Select all child nodes: */ $result = db_query("SELECT n.nid, n.title FROM node n LEFT JOIN book b ON n.nid = b.nid WHERE n.type = 'book' AND n.status = 1 AND b.parent = '$parent' ORDER BY b.weight"); /* ** Add the root node: */ if (user_access("administer nodes")) { $toc[0] = ""; } /* ** Build the table of contents: */ while ($node = db_fetch_object($result)) { $toc[$node->nid] = "$indent $node->title"; $toc = book_toc($node->nid, "$indent-", $toc); } return $toc; } function book_tree($parent = "", $depth = 0) { if ($depth < 3) { /* ** Select all child nodes and render them into a table of contents: */ $result = db_query("SELECT n.nid FROM node n LEFT JOIN book b ON n.nid = b.nid WHERE n.type = 'book' AND b.parent = '$parent' ORDER BY b.weight, n.title"); while ($page = db_fetch_object($result)) { // load the node: $node = node_load(array("nid" => $page->nid)); // take the most recent approved revision: if ($node->moderate) { $node = node_revision_load($node, end(node_revision_list($node))); } // output the content: $output .= "
  • nid\">". check_output($node->title) ."
  • "; // build the sub-tree of each child: $output .= book_tree($node->nid, $depth + 1); } $output = ""; } return $output; } function book_render() { global $theme; $result = db_query("SELECT n.nid FROM node n LEFT JOIN book b ON n.nid = b.nid WHERE b.parent = 0 AND n.status = 1 ORDER BY b.weight"); while ($page = db_fetch_object($result)) { // load the node: $node = node_load(array("nid" => $page->nid)); // take the most recent approved revision: if ($node->moderate) { $node = node_revision_load($node, end(node_revision_list($node))); } // output the content: $output .= "
    nid\">". check_output($node->title) ."
    ". check_output($node->body, 1) ."

    "; } $theme->header(); $theme->box(t("Handbook"), "
    $output
    "); $theme->footer(); } function book_page() { global $op, $id, $theme; if (user_access("access content")) { switch ($op) { case "feed": print book_export_html($id, $depth = 1); break; default: book_render(); } } else { $theme->header(); $theme->box(t("Access denied"), message_access()); $theme->footer(); } } function book_export_html($id = "", $depth = 1) { $result = db_query("SELECT n.nid FROM node n LEFT JOIN book b ON n.nid = b.nid WHERE n.type = 'book' AND n.status = 1 AND n.nid = '". check_input($id) ."'"); while ($page = db_fetch_object($result)) { // load the node: $node = node_load(array("nid" => $page->nid)); // take the most recent approved revision: if ($node->moderate) { $node = node_revision_load($node, end(node_revision_list($node))); } // output the content: $output .= "". check_output($node->title) .""; if ($node->body) { $output .= "
    ". check_output($node->body, 1) ."
    "; } } $output .= book_export_html_recursive($id, $depth); return $output; } function book_export_html_recursive($parent = "", $depth = 1) { $result = db_query("SELECT n.nid FROM node n LEFT JOIN book b ON n.nid = b.nid WHERE n.type = 'book' AND n.status = 1 AND b.parent = '$parent' ORDER BY b.weight"); while ($page = db_fetch_object($result)) { // load the node: $node = node_load(array("nid" => $page->nid)); // take the most recent approved revision: if ($node->moderate) { $node = node_revision_load($node, end(node_revision_list($node))); } // output the content: $output .= "". check_output($node->title) .""; if ($node->body) { $output .= "
    ". check_output($node->body, 1) ."
    "; } $output .= book_export_html_recursive($node->nid, $depth + 1); } return $output; } function book_admin_page($nid, $depth = 0) { $weight = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30); $result = db_query("SELECT n.nid FROM node n LEFT JOIN book b ON n.nid = b.nid WHERE n.type = 'book' AND b.parent = '$nid' ORDER BY b.weight, n.title"); while ($node = db_fetch_object($result)) { $node = node_load(array("nid" => $node->nid)); $output .= ""; $output .= "
    $node->title
    "; $output .= " ". ($rev = end(node_revision_list($node)) ? $rev : 0) .""; $output .= " nid\">". t("edit page") .""; $output .= " nid\">". t("delete page") .""; $output .= ""; $output .= book_admin_page($node->nid, $depth + 1); } return $output; } function book_admin_view($nid, $depth = 0) { $node = node_load(array("nid" => $nid)); $output .= "

    ". check_output($node->title) ."

    "; $output .= ""; $output .= " "; $output .= book_admin_page($nid); $output .= "
    titlerevoperations
    "; return $output; } function book_admin_orphan() { $result = db_query("SELECT n.nid, n.title, b.parent FROM node n LEFT JOIN book b ON n.nid = b.nid WHERE n.type = 'book'"); while ($page = db_fetch_object($result)) { $pages[$page->nid] = $page; } $output .= ""; $output .= " "; foreach ($pages as $nid => $node) { if ($node->parent && empty($pages[$node->parent])) { $output .= ""; } } $output .= "
    titleoperations
    nid\">". check_output($node->title) ."nid\">". t("edit page") ."nid\">". t("delete page") ."
    "; return $output; } function book_admin_links() { $result = db_query("SELECT n.nid, n.title FROM node n LEFT JOIN book b ON n.nid = b.nid WHERE b.parent = 0 ORDER BY b.weight, n.title"); while ($book = db_fetch_object($result)) { $links[] = "
    nid\">". t("book") .": ". check_output($book->title) .""; } return $links; } function book_admin() { global $id, $op; if (user_access("administer nodes")) { /* ** Compile a list of the administrative links: */ $links = book_admin_links(); $links[] = "". t("orphan pages") .""; print "". implode(" · ", $links) ."
    "; switch ($op) { case "orphan": print book_admin_orphan(); break; case "view": print book_admin_view($id); break; default: } } } ?>