book.module 11.7 KB
Newer Older
Dries's avatar
 
Dries committed
1
<?php
2
// $Id$
Dries's avatar
 
Dries committed
3

Dries's avatar
 
Dries committed
4 5 6
function book_node($field) {
  global $user;

Dries's avatar
 
Dries committed
7
  $info["name"] = t("book page");
Dries's avatar
 
Dries committed
8
  $info["description"] = t("A book is a collaborative writing effort: users can collaborate writing the pages of the book, positioning the pages in the right order, and reviewing or modifying pages previously written.  So when you have some information to share or when you read a page of the book and you didn't like it, or if you think a certain page could have been written better, you can do something about it.");
Dries's avatar
 
Dries committed
9 10 11 12 13

  return $info[$field];
}

function book_access($op, $node) {
Dries's avatar
 
Dries committed
14
  global $user;
Dries's avatar
 
Dries committed
15 16

  if ($op == "view") {
Dries's avatar
 
Dries committed
17 18 19 20 21 22 23 24
    /*
    ** Everyone can access all published book pages whether these pages
    ** are still waiting for approval or not.  We might not always want
    ** to display pages that are waiting for approval, but we take care
    ** of that problem in the book_view() function.
    */

    return $node->status;
Dries's avatar
 
Dries committed
25 26 27 28 29 30 31 32
  }

  if  ($op == "create") {
    return 1;
  }

  if ($op == "update") {

Dries's avatar
 
Dries committed
33
    /*
Dries's avatar
 
Dries committed
34 35 36 37
    ** 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.
Dries's avatar
 
Dries committed
38 39
    */

Dries's avatar
 
Dries committed
40
    return !$node->moderate && $node->revision;
Dries's avatar
 
Dries committed
41
  }
Dries's avatar
 
Dries committed
42 43
}

Dries's avatar
 
Dries committed
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
function book_save($op, $node) {

  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 (user_access("administer nodes")) {
      /*
      ** If a node administrator updates a book page, we don't create a
      ** new revision unless we are explicitly instructed to.
      */

      return array("parent", "weight");
    }
    else {
      /*
      ** 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.
      */

      return array("created" => time(), "moderate" => 1, "parent", "promote" => 0, "score" => 0, "status" => 1, "users" => "", "revisions", "votes" => 0, "weight");
    }
  }

}

Dries's avatar
 
Dries committed
80 81 82
function book_link($type) {
  if ($type == "page" && user_access("access content")) {
    $links[] = "<a href=\"module.php?mod=book\">". t("collaborative book") ."</a>";
Dries's avatar
 
Dries committed
83
  }
Dries's avatar
 
Dries committed
84 85

  return $links ? $links : array();
Dries's avatar
 
Dries committed
86 87
}

Dries's avatar
 
Dries committed
88
function book_load($node) {
Dries's avatar
 
Dries committed
89
  $book = db_fetch_object(db_query("SELECT parent, weight, revision FROM book WHERE nid = '$node->nid'"));
Dries's avatar
 
Dries committed
90
  return $book;
Dries's avatar
 
Dries committed
91 92
}

Dries's avatar
 
Dries committed
93
function book_insert($node) {
Dries's avatar
 
Dries committed
94
  db_query("INSERT INTO book (nid, parent, weight) VALUES ('$node->nid', '$node->parent', '$node->weight')");
Dries's avatar
 
Dries committed
95
}
Dries's avatar
 
Dries committed
96

Dries's avatar
 
Dries committed
97
function book_update($node) {
Dries's avatar
 
Dries committed
98
  db_query("UPDATE book SET parent = '$node->parent', weight = '$node->weight' WHERE nid = '$node->nid'");
Dries's avatar
 
Dries committed
99
}
Dries's avatar
 
Dries committed
100

Dries's avatar
 
Dries committed
101 102
function book_delete($node) {
  db_query("DELETE FROM book WHERE nid = '$node->nid'");
Dries's avatar
 
Dries committed
103 104
}

Dries's avatar
 
Dries committed
105

Dries's avatar
 
Dries committed
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
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:
    */

Dries's avatar
 
Dries committed
122 123
    $help = book_node("description");

Dries's avatar
 
Dries committed
124 125 126 127 128 129 130 131

    /*
    ** If a regular user updates a book page, we create a new revision
    ** authored by that user:
    */

    $output .= form_hidden("revision", 1);

Dries's avatar
 
Dries committed
132
    $node->uid = $user->uid;    // $node is passed by reference
Dries's avatar
 
Dries committed
133 134 135 136 137 138 139
    $node->name = $user->name;

  }

  return $output;
}

Dries's avatar
 
Dries committed
140
function book_location($node, $nodes = array()) {
Dries's avatar
 
Dries committed
141
  $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'"));
Dries's avatar
 
Dries committed
142 143 144 145 146 147 148
  if ($parent->title) {
    $nodes = book_location($parent, $nodes);
    array_push($nodes, $parent);
  }
  return $nodes;
}

Dries's avatar
 
Dries committed
149
function book_view($node, $main = 0) {
Dries's avatar
 
Dries committed
150 151 152 153 154 155 156 157 158
  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") {
Dries's avatar
 
Dries committed
159
    $node = node_revision_load($node, end(node_revision_list($node)));
Dries's avatar
 
Dries committed
160 161 162 163 164 165 166
  }

  /*
  ** 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.
  */
Dries's avatar
 
Dries committed
167

Dries's avatar
 
Dries committed
168 169
  if ($main) {
    $theme->node($node, $main);
Dries's avatar
 
Dries committed
170
  }
Dries's avatar
 
Dries committed
171 172
  else {
    if ($node->nid && $node->parent) {
Dries's avatar
 
Dries committed
173 174
      $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"));
Dries's avatar
 
Dries committed
175
    }
Dries's avatar
 
Dries committed
176

Dries's avatar
 
Dries committed
177
    $output .= "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n";
Dries's avatar
 
Dries committed
178

Dries's avatar
 
Dries committed
179 180
    if ($node->title) {
      foreach (book_location($node) as $level) {
Dries's avatar
 
Dries committed
181
        $location .= "$indent <a href=\"node.php?id=$level->nid\">$level->title</a><br />";
Dries's avatar
 
Dries committed
182 183
        $indent .= "-";
      }
Dries's avatar
 
Dries committed
184

Dries's avatar
 
Dries committed
185 186 187
      $output .= " <tr><td colspan=\"2\">$location</td><td align=\"right\"><a href=\"module.php?mod=node&op=edit&id=$node->nid\">". t("update this book page") ."</a></td></tr>";
      $output .= " <tr><td colspan=\"3\"><hr /></td></tr>";
      $output .= " <tr><td colspan=\"3\"><b><big>". check_output($node->title) ."</big></b>". ($node->body ? "<br /><small><i>". sprintf(t("Last updated by %s on %s"), format_name($node), format_date($node->created)) ."</i></small> " : "") ."</td></tr>";
Dries's avatar
 
Dries committed
188
    }
Dries's avatar
 
Dries committed
189

Dries's avatar
 
Dries committed
190
    if ($node->body) {
Dries's avatar
 
Dries committed
191
      $output .= " <tr><td colspan=\"3\"><br />". check_output($node->body, 1) ."</td></tr>";
Dries's avatar
 
Dries committed
192
    }
Dries's avatar
 
Dries committed
193

Dries's avatar
 
Dries committed
194
    if ($node->nid) {
Dries's avatar
 
Dries committed
195
      $output .= " <tr><td colspan=\"3\"><br />". book_tree($node->nid) ."</td></tr>";
Dries's avatar
 
Dries committed
196
    }
Dries's avatar
 
Dries committed
197

Dries's avatar
 
Dries committed
198 199 200 201
    $output .= " <tr><td colspan=\"3\"><hr /></td></tr>";
    $output .= " <tr><td align=\"left\" width=\"33%\">". ($prev ? "<a href=\"node.php?id=$prev->nid\">". t("previous") ."</a>" : t("previous")) ."</td><td align=\"center\" width=\"34%\"><a href=\"module.php?mod=book\">index</a></td><td align=\"right\" width=\"33%\">". ($next ? "<a href=\"node.php?id=$next->nid\">". t("next") ."</a>" : t("next")) ."</td></tr>";
    $output .= " <tr><td align=\"left\" width=\"33%\">". ($prev ? "<small>". check_output($prev->title) ."</small>" : "&nbsp;") ."</td><td align=\"center\" width=\"34%\">". ($node->parent ? "<a href=\"node.php?id=$node->parent\">". t("up") ."</a>" : t("up")) ."</td><td align=\"right\" width=\"33%\">". ($next ? "<small>". check_output($next->title) ."</small>" : "&nbsp;") ."</td></tr>";
    $output .= "</table>";
Dries's avatar
 
Dries committed
202

Dries's avatar
 
Dries committed
203 204
    $theme->box(t("Handbook"), $output);
  }
Dries's avatar
 
Dries committed
205 206
}

Dries's avatar
 
Dries committed
207
function book_toc($parent = "", $indent = "", $toc = array()) {
Dries's avatar
 
Dries committed
208

Dries's avatar
 
Dries committed
209 210 211 212 213 214 215 216 217
  /*
  ** 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:
  */
Dries's avatar
 
Dries committed
218

Dries's avatar
 
Dries committed
219
  if (user_access("administer nodes")) {
Dries's avatar
 
Dries committed
220
    $toc[0] = "<root>";
Dries's avatar
 
Dries committed
221 222
  }

Dries's avatar
 
Dries committed
223 224 225 226
  /*
  ** Build the table of contents:
  */

Dries's avatar
 
Dries committed
227
  while ($node = db_fetch_object($result)) {
Dries's avatar
 
Dries committed
228 229
    $toc[$node->nid] = "$indent $node->title";
    $toc = book_toc($node->nid, "$indent-", $toc);
Dries's avatar
 
Dries committed
230
  }
Dries's avatar
 
Dries committed
231

Dries's avatar
 
Dries committed
232 233 234
  return $toc;
}

Dries's avatar
Dries committed
235
function book_tree($parent = "", $depth = 0) {
Dries's avatar
 
Dries committed
236

Dries's avatar
 
Dries committed
237
  if ($depth < 3) {
Dries's avatar
 
Dries committed
238 239 240 241 242
    /*
    ** 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");
Dries's avatar
 
Dries committed
243

Dries's avatar
 
Dries committed
244 245 246 247 248 249
    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) {
Dries's avatar
 
Dries committed
250
        $node = node_revision_load($node, end(node_revision_list($node)));
Dries's avatar
 
Dries committed
251 252 253
      }

      // output the content:
Dries's avatar
 
Dries committed
254
      $output .= "<li><a href=\"node.php?id=$node->nid\">". check_output($node->title) ."</a></li>";
Dries's avatar
 
Dries committed
255 256

      // build the sub-tree of each child:
Dries's avatar
 
Dries committed
257 258
      $output .= book_tree($node->nid, $depth + 1);
    }
Dries's avatar
 
Dries committed
259

Dries's avatar
 
Dries committed
260
    $output = "<ul>$output</ul>";
Dries's avatar
 
Dries committed
261
  }
Dries's avatar
 
Dries committed
262

Dries's avatar
 
Dries committed
263 264 265
  return $output;
}

Dries's avatar
 
Dries committed
266
function book_render() {
Dries's avatar
 
Dries committed
267
  global $theme;
Dries's avatar
Dries committed
268

Dries's avatar
 
Dries committed
269
  $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");
Dries's avatar
 
Dries committed
270

Dries's avatar
 
Dries committed
271 272 273 274 275 276
  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) {
Dries's avatar
 
Dries committed
277
      $node = node_revision_load($node, end(node_revision_list($node)));
Dries's avatar
 
Dries committed
278 279 280
    }

    // output the content:
Dries's avatar
 
Dries committed
281
    $output .= "<dt><a href=\"node.php?id=$node->nid\">". check_output($node->title) ."</a></dt><dd>". check_output($node->body, 1) ."<br /><br /></dd>";
Dries's avatar
 
Dries committed
282 283 284
  }

  $theme->header();
Dries's avatar
 
Dries committed
285
  $theme->box(t("Handbook"), "<dl>$output</dl>");
Dries's avatar
 
Dries committed
286 287 288 289 290 291
  $theme->footer();
}

function book_page() {
  global $op, $id, $theme;

Dries's avatar
 
Dries committed
292
  if (user_access("access content")) {
Dries's avatar
 
Dries committed
293 294
    switch ($op) {
      case "feed":
Dries's avatar
 
Dries committed
295
        print book_export_html($id, $depth = 1);
Dries's avatar
 
Dries committed
296 297 298
        break;
      default:
        book_render();
Dries's avatar
 
Dries committed
299 300 301 302 303 304 305
    }
  }
  else {
    $theme->header();
    $theme->box(t("Access denied"), message_access());
    $theme->footer();
  }
Dries's avatar
 
Dries committed
306 307
}

Dries's avatar
 
Dries committed
308
function book_export_html($id = "", $depth = 1) {
Dries's avatar
 
Dries committed
309
  $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) ."'");
Dries's avatar
 
Dries committed
310

Dries's avatar
 
Dries committed
311 312 313
  while ($page = db_fetch_object($result)) {
    // load the node:
    $node = node_load(array("nid" => $page->nid));
Dries's avatar
 
Dries committed
314

Dries's avatar
 
Dries committed
315 316
    // take the most recent approved revision:
    if ($node->moderate) {
Dries's avatar
 
Dries committed
317
      $node = node_revision_load($node, end(node_revision_list($node)));
Dries's avatar
 
Dries committed
318 319 320
    }

    // output the content:
Dries's avatar
 
Dries committed
321
    $output .= "<h$depth>". check_output($node->title) ."</h$depth>";
Dries's avatar
 
Dries committed
322 323 324 325

    if ($node->body) {
      $output .= "<blockquote>". check_output($node->body, 1) ."</blockquote>";
    }
Dries's avatar
 
Dries committed
326
  }
Dries's avatar
 
Dries committed
327

Dries's avatar
 
Dries committed
328 329 330 331 332 333
  $output .= book_export_html_recursive($id, $depth);

  return $output;
}

function book_export_html_recursive($parent = "", $depth = 1) {
Dries's avatar
 
Dries committed
334
  $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");
Dries's avatar
 
Dries committed
335

Dries's avatar
 
Dries committed
336 337 338 339 340 341
  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) {
Dries's avatar
 
Dries committed
342
      $node = node_revision_load($node, end(node_revision_list($node)));
Dries's avatar
 
Dries committed
343 344 345
    }

    // output the content:
Dries's avatar
 
Dries committed
346
    $output .= "<h$depth>". check_output($node->title) ."</h$depth>";
Dries's avatar
 
Dries committed
347 348 349 350 351

    if ($node->body) {
      $output .= "<blockquote>". check_output($node->body, 1) ."</blockquote>";
    }

Dries's avatar
 
Dries committed
352
    $output .= book_export_html_recursive($node->nid, $depth + 1);
Dries's avatar
 
Dries committed
353
  }
Dries's avatar
 
Dries committed
354

Dries's avatar
 
Dries committed
355 356
  return $output;
}
Dries's avatar
 
Dries committed
357

Dries's avatar
 
Dries committed
358
?>