book.module 11.4 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
  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
145
    $node = node_revision_load($node, end(node_revision_list($node)));
Dries's avatar
   
Dries committed
146
147
148
149
150
151
152
  }

  /*
  ** 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
    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
236
        $node = node_revision_load($node, end(node_revision_list($node)));
Dries's avatar
   
Dries committed
237
238
239
      }

      // 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
  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
263
      $node = node_revision_load($node, end(node_revision_list($node)));
Dries's avatar
   
Dries committed
264
265
266
    }

    // 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
    // take the most recent approved revision:
    if ($node->moderate) {
Dries's avatar
   
Dries committed
303
      $node = node_revision_load($node, end(node_revision_list($node)));
Dries's avatar
   
Dries committed
304
305
306
    }

    // 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
  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
328
      $node = node_revision_load($node, end(node_revision_list($node)));
Dries's avatar
   
Dries committed
329
330
331
    }

    // 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
?>