book.module 11.3 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 7 8 9 10 11 12
function book_node($field) {
  global $user;

  $info = array("name" => "book page");

  return $info[$field];
}

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

  if ($op == "view") {
Dries's avatar
 
Dries committed
16 17 18 19 20 21 22 23
    /*
    ** 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
24 25 26 27 28 29 30 31
  }

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

  if ($op == "update") {

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

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

Dries's avatar
 
Dries committed
43 44 45
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
46
  }
Dries's avatar
 
Dries committed
47 48

  return $links ? $links : array();
Dries's avatar
 
Dries committed
49 50
}

Dries's avatar
 
Dries committed
51
function book_load($node) {
Dries's avatar
 
Dries committed
52
  $book = db_fetch_object(db_query("SELECT parent, weight, revision FROM book WHERE nid = '$node->nid'"));
Dries's avatar
 
Dries committed
53
  return $book;
Dries's avatar
 
Dries committed
54 55
}

Dries's avatar
 
Dries committed
56
function book_insert($node) {
Dries's avatar
 
Dries committed
57
  db_query("INSERT INTO book (nid, parent, weight) VALUES ('$node->nid', '$node->parent', '$node->weight')");
Dries's avatar
 
Dries committed
58
}
Dries's avatar
 
Dries committed
59

Dries's avatar
 
Dries committed
60
function book_update($node) {
Dries's avatar
 
Dries committed
61
  db_query("UPDATE book SET parent = '$node->parent', weight = '$node->weight' WHERE nid = '$node->nid'");
Dries's avatar
 
Dries committed
62
}
Dries's avatar
 
Dries committed
63

Dries's avatar
 
Dries committed
64 65
function book_delete($node) {
  db_query("DELETE FROM book WHERE nid = '$node->nid'");
Dries's avatar
 
Dries committed
66 67
}

Dries's avatar
 
Dries committed
68
function book_save($node) {
Dries's avatar
 
Dries committed
69 70 71 72
  if ($node->nid) {
    if (user_access("administer nodes")) {
      /*
      ** If a node administrator updates a book page, we don't create a
Dries's avatar
 
Dries committed
73
      ** new revision unless we are explicitly instructed to.
Dries's avatar
 
Dries committed
74 75 76 77 78 79 80
      */

      return array("parent", "weight");
    }
    else {
      /*
      ** If a regular user updates a book page, we always create a new
Dries's avatar
 
Dries committed
81 82
      ** revision.  All new revisions have to be approved (moderation)
      ** and are not promoted by derault.
Dries's avatar
 
Dries committed
83 84 85 86
      */

      return array("created" => time(), "moderate" => 1, "parent", "promote" => 0, "score" => 0, "status" => 1, "users" => "", "revisions", "votes" => 0, "weight");
    }
Dries's avatar
 
Dries committed
87 88
  }
  else {
Dries's avatar
 
Dries committed
89
    return array("moderate" => 1, "parent", "promote" => 0, "status" => 1, "weight");
Dries's avatar
 
Dries committed
90
  }
Dries's avatar
 
Dries committed
91 92
}

Dries's avatar
 
Dries committed
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
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 = t("\"update book page\"-help: to be written!  It should explain the basic idea behind our collaborative book and how their update helps to improve the quality of the book.  Also mention that all updates are subject to moderation or review.  Any who can put this into a fluent English help text?");

    /*
    ** 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
118
    $node->uid = $user->uid;    // $node is passed by reference
Dries's avatar
 
Dries committed
119 120 121 122 123 124 125
    $node->name = $user->name;

  }

  return $output;
}

Dries's avatar
 
Dries committed
126
function book_location($node, $nodes = array()) {
Dries's avatar
 
Dries committed
127
  $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
128 129 130 131 132 133 134
  if ($parent->title) {
    $nodes = book_location($parent, $nodes);
    array_push($nodes, $parent);
  }
  return $nodes;
}

Dries's avatar
 
Dries committed
135
function book_view($node, $main = 0) {
Dries's avatar
 
Dries committed
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
  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->revisions[sizeof($node->revisions) - 1]["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.
  */
Dries's avatar
 
Dries committed
153

Dries's avatar
 
Dries committed
154 155
  if ($main) {
    $theme->node($node, $main);
Dries's avatar
 
Dries committed
156
  }
Dries's avatar
 
Dries committed
157 158
  else {
    if ($node->nid && $node->parent) {
Dries's avatar
 
Dries committed
159 160
      $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
161
    }
Dries's avatar
 
Dries committed
162

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

Dries's avatar
 
Dries committed
165 166
    if ($node->title) {
      foreach (book_location($node) as $level) {
Dries's avatar
 
Dries committed
167
        $location .= "$indent <a href=\"node.php?id=$level->nid\">$level->title</a><br />";
Dries's avatar
 
Dries committed
168 169
        $indent .= "-";
      }
Dries's avatar
 
Dries committed
170

Dries's avatar
 
Dries committed
171 172 173
      $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
174
    }
Dries's avatar
 
Dries committed
175

Dries's avatar
 
Dries committed
176
    if ($node->body) {
Dries's avatar
 
Dries committed
177
      $output .= " <tr><td colspan=\"3\"><br />". check_output($node->body, 1) ."</td></tr>";
Dries's avatar
 
Dries committed
178
    }
Dries's avatar
 
Dries committed
179

Dries's avatar
 
Dries committed
180
    if ($node->nid) {
Dries's avatar
 
Dries committed
181
      $output .= " <tr><td colspan=\"3\"><br />". book_tree($node->nid) ."</td></tr>";
Dries's avatar
 
Dries committed
182
    }
Dries's avatar
 
Dries committed
183

Dries's avatar
 
Dries committed
184 185 186 187
    $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
188

Dries's avatar
 
Dries committed
189 190
    $theme->box(t("Handbook"), $output);
  }
Dries's avatar
 
Dries committed
191 192
}

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

Dries's avatar
 
Dries committed
195 196 197 198 199 200 201 202 203
  /*
  ** 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
204

Dries's avatar
 
Dries committed
205
  if (user_access("administer nodes")) {
Dries's avatar
 
Dries committed
206
    $toc[0] = "<root>";
Dries's avatar
 
Dries committed
207 208
  }

Dries's avatar
 
Dries committed
209 210 211 212
  /*
  ** Build the table of contents:
  */

Dries's avatar
 
Dries committed
213
  while ($node = db_fetch_object($result)) {
Dries's avatar
 
Dries committed
214 215
    $toc[$node->nid] = "$indent $node->title";
    $toc = book_toc($node->nid, "$indent-", $toc);
Dries's avatar
 
Dries committed
216
  }
Dries's avatar
 
Dries committed
217

Dries's avatar
 
Dries committed
218 219 220
  return $toc;
}

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

Dries's avatar
 
Dries committed
223
  if ($depth < 3) {
Dries's avatar
 
Dries committed
224 225 226 227 228
    /*
    ** 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
229

Dries's avatar
 
Dries committed
230 231 232 233 234 235 236 237 238 239
    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->revisions[sizeof($node->revisions) - 1]["node"];
      }

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

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

Dries's avatar
 
Dries committed
246
    $output = "<ul>$output</ul>";
Dries's avatar
 
Dries committed
247
  }
Dries's avatar
 
Dries committed
248

Dries's avatar
 
Dries committed
249 250 251
  return $output;
}

Dries's avatar
 
Dries committed
252
function book_render() {
Dries's avatar
 
Dries committed
253
  global $theme;
Dries's avatar
Dries committed
254

Dries's avatar
 
Dries committed
255
  $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
256

Dries's avatar
 
Dries committed
257 258 259 260 261 262 263 264 265 266
  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->revisions[sizeof($node->revisions) - 1]["node"];
    }

    // output the content:
Dries's avatar
 
Dries committed
267
    $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
268 269 270
  }

  $theme->header();
Dries's avatar
 
Dries committed
271
  $theme->box(t("Handbook"), "<dl>$output</dl>");
Dries's avatar
 
Dries committed
272 273 274 275 276 277
  $theme->footer();
}

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

Dries's avatar
 
Dries committed
278
  if (user_access("access content")) {
Dries's avatar
 
Dries committed
279 280
    switch ($op) {
      case "feed":
Dries's avatar
 
Dries committed
281
        print book_export_html($id, $depth = 1);
Dries's avatar
 
Dries committed
282 283 284
        break;
      default:
        book_render();
Dries's avatar
 
Dries committed
285 286 287 288 289 290 291
    }
  }
  else {
    $theme->header();
    $theme->box(t("Access denied"), message_access());
    $theme->footer();
  }
Dries's avatar
 
Dries committed
292 293
}

Dries's avatar
 
Dries committed
294
function book_export_html($id = "", $depth = 1) {
Dries's avatar
 
Dries committed
295
  $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
296

Dries's avatar
 
Dries committed
297 298 299
  while ($page = db_fetch_object($result)) {
    // load the node:
    $node = node_load(array("nid" => $page->nid));
Dries's avatar
 
Dries committed
300

Dries's avatar
 
Dries committed
301 302 303 304 305 306
    // take the most recent approved revision:
    if ($node->moderate) {
      $node = $node->revisions[sizeof($node->revisions) - 1]["node"];
    }

    // output the content:
Dries's avatar
 
Dries committed
307
    $output .= "<h$depth>". check_output($node->title) ."</h$depth>";
Dries's avatar
 
Dries committed
308 309 310 311

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

Dries's avatar
 
Dries committed
314 315 316 317 318 319
  $output .= book_export_html_recursive($id, $depth);

  return $output;
}

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

Dries's avatar
 
Dries committed
322 323 324 325 326 327 328 329 330 331
  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->revisions[sizeof($node->revisions) - 1]["node"];
    }

    // output the content:
Dries's avatar
 
Dries committed
332
    $output .= "<h$depth>". check_output($node->title) ."</h$depth>";
Dries's avatar
 
Dries committed
333 334 335 336 337

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

Dries's avatar
 
Dries committed
338
    $output .= book_export_html_recursive($node->nid, $depth + 1);
Dries's avatar
 
Dries committed
339
  }
Dries's avatar
 
Dries committed
340

Dries's avatar
 
Dries committed
341 342
  return $output;
}
Dries's avatar
 
Dries committed
343

Dries's avatar
 
Dries committed
344
?>