/[drupal]/contributions/modules/book_manager/book_manager.module
ViewVC logotype

Contents of /contributions/modules/book_manager/book_manager.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download) (as text)
Fri Oct 31 00:34:50 2008 UTC (12 months, 3 weeks ago) by jgraham
Branch: MAIN
CVS Tags: DRUPAL-6--1-0, HEAD
Branch point for: DRUPAL-6--1
File MIME type: text/x-php
Adding book manager module initial commit
1 <?php
2 // $Id: book_manager.module 1134 2008-10-30 23:18:53Z jgraham $
3 // @file
4 define('BOOK_MANAGER_IS_BOOK', 1); // indicates this node is the top-level in a book (includes personal books)
5 define('BOOK_MANAGER_IS_IN_BOOK', 2); // indicates this node is in A book (includes personal books)
6 define('BOOK_MANAGER_IS_IN_PERSONAL', 4); // indicates this node is in a personal book
7
8 /**
9 * Menu callback; prints a listing of all personal books.
10 *
11 * @param $user
12 * User whose personal books are being rendered. If NULL, show all personal books.
13 */
14 function book_manager_render($user = NULL) {
15 if ($user) {
16 drupal_set_title(t('Personal books for !name', array('!name' => $user->name)));
17 }
18
19 $header = array(t('Book'), t('Author'));
20 $rows = array();
21 foreach (book_manager_get_books($user) as $book) {
22 $row = array();
23 $row[] = l($book->title, $book->href, $book->options);
24 $row[] = theme('username', $book);
25 $rows[] = $row;
26 }
27 return theme('table', $header, $rows, array('id' => 'personal-books'));
28 }
29
30 /**
31 * Implementatin of hook_link()
32 */
33 function book_manager_link($type, $node = NULL, $teaser = FALSE) {
34 global $user;
35 $links = array();
36
37 if ($type == 'node' && isset($node->book) && !$teaser) {
38 $book = node_load($node->book['bid']);
39
40 if (_book_manager_outline_access($book)) {
41 $links['book_manager_outline'] = array(
42 'title' => t('Customize Book'),
43 'href' => "personal-outline/". $book->nid,
44 );
45 }
46
47 }
48 return $links;
49 }
50
51 /**
52 * Returns an array of all personal books for the specified user.
53 *
54 * This list may be used for generating a list of all the books, or for building
55 * the options for a form select.
56 *
57 * @param $user
58 * User object whose personal books are being rendered. Defaults to 0 for all personal books.
59 */
60 function book_manager_get_books($user = NULL) {
61 $books = array();
62 if ($user) {
63 $result = db_query("SELECT pb.bid FROM {book_manager} pb JOIN {node} n ON pb.bid = n.nid WHERE n.uid = %d", $user->uid);
64 }
65 else {
66 $result = db_query("SELECT pb.bid FROM {book_manager} pb");
67 }
68 $nids = array();
69 while ($book = db_fetch_array($result)) {
70 $nids[] = $book['bid'];
71 }
72 if ($nids) {
73 // This differs from the book module's query -- we added n.uid, which should be the same as book_manager.uid,
74 // and u.name for the owner's name
75 $result2 = db_query(db_rewrite_sql("SELECT n.type, n.title, n.uid, u.name, b.*, ml.* FROM {book} b INNER JOIN {node} n ON b.nid = n.nid INNER JOIN {users} u ON n.uid = u.uid INNER JOIN {menu_links} ml ON b.mlid = ml.mlid WHERE n.nid IN (". implode(',', $nids) .") AND n.status = 1 ORDER BY ml.weight, ml.link_title"));
76 while ($book = db_fetch_object($result2)) {
77 $book->href = $book->link_path;
78 $book->options = unserialize($book->options);
79 $books[$book->bid] = $book;
80 }
81 }
82 return $books;
83 }
84
85 /**
86 * Implementation of hook_perm()
87 */
88 function book_manager_perm() {
89 return array('add content to personal books', 'create personal books');
90 }
91
92 /**
93 * Implementation of hook_menu().
94 */
95 function book_manager_menu() {
96 $items['book_manager'] = array(
97 'title' => 'Book Manager',
98 'page callback' => 'book_manager_render',
99 'page arguments' => array(NULL),
100 'access arguments' => array('access content'),
101 'type' => MENU_SUGGESTED_ITEM
102 );
103
104 $items['book_manager/%user_uid_optional'] = array(
105 'title' => 'Book Manager',
106 'page callback' => 'book_manager_render',
107 'page arguments' => array(1),
108 'access arguments' => array('access content'),
109 'type' => MENU_SUGGESTED_ITEM
110 );
111
112 // we could adjust the access routine for books standard outline feature, but it is nested under admin
113 $items['personal-outline/%node'] = array(
114 'title' => 'Re-order personal book pages',
115 'page callback' => 'book_manager_outline_edit',
116 'page arguments' => array(1),
117 'access callback' => '_book_manager_outline_access',
118 'access arguments' => array(1),
119 'type' => MENU_CALLBACK,
120 );
121
122 return $items;
123 }
124
125 function book_manager_menu_alter(&$callbacks) {
126 $callbacks['node/%node/outline']['access callback'] = '_book_manager_outline_access_menu_callback';
127 $callbacks['node/%node/outline/remove']['access callback'] = '_book_manager_outline_remove_access_menu_callback';
128 }
129
130 /**
131 * This is a helper function used as a replacement callback for book's standard access to
132 * 'node/%node/outline'
133 * @see book_manager_menu_alter()
134 */
135 function _book_manager_outline_access_menu_callback($node) {
136 return (_book_manager_outline_access($node) || _book_outline_access($node));
137 }
138
139 /**
140 * This is a helper function used as a replacement callback for book's standard access to
141 * 'node/%node/outline/remove'
142 * @see book_manager_menu_alter()
143 */
144 function _book_manager_outline_remove_access_menu_callback($node) {
145 return (_book_manager_outline_remove_access($node) || _book_outline_remove_access($node));
146 }
147
148 /**
149 * Menu item access callback - determine if the user should be able to outline the book the node belongs to
150 * @param $node object the node in question
151 * @param $noadministeroutlines if TRUE then return TRUE only if the user does not have access to "administer book outlines"
152 */
153 function _book_manager_outline_access($node) {
154 global $user;
155 // if this is in a personal book AND this is their node
156 if (book_type_is_allowed($node->type) && (($node->book_manager & BOOK_MANAGER_IS_IN_PERSONAL) &&
157 ((isset($node->book) &&
158 _book_manager_get_book_owner($node->book['bid']) && $node->uid == $user->uid)) ||
159 (!isset($node->book) && $node->uid == $user->uid && user_access('add content to personal books')))) {
160 return TRUE;
161 }
162 else {
163 return FALSE;
164 }
165 }
166
167 /**
168 * Menu item access callback - determine if the user can remove nodes from the outline.
169 */
170 function _book_manager_outline_remove_access($node) {
171 return isset($node->book) && ($node->book['bid'] != $node->nid) && _book_manager_outline_access($node);
172 }
173
174 /**
175 * This function returns the uid of the author of the book corresponding to $bid
176 * @param int $bid The book id to find the author for
177 * @return int The uid of the bid author or 0 if this is not a book
178 */
179 function _book_manager_get_book_owner($bid) {
180 if ($result = db_query("SELECT n.uid FROM {book} b LEFT JOIN {node} n ON n.nid = b.bid WHERE n.nid = %d GROUP BY n.nid", $bid)) {
181 $row = db_fetch_array($result);
182 return $row['uid'];
183 }
184 return 0;
185 }
186
187 /**
188 * implementation of hook_nodeapi()
189 */
190 function book_manager_nodeapi(&$node, $op, $teaser, $page) {
191 global $user;
192 switch ($op) {
193 case 'load':
194 $node->book_manager = book_manager_status($node->nid);
195 break;
196 case 'prepare':
197 // this is necessary because book_nodeapi checks for book permissions and the parent select widget population
198 // fails without this pre-loaded data
199 // Prepare defaults for the add/edit form.
200 if (empty($node->book) && (user_access('add content to personal books'))) {
201 $node->book = array();
202 if (empty($node->nid) && isset($_GET['parent']) && is_numeric($_GET['parent'])) {
203 // Handle "Add child page" links:
204 $parent = book_link_load($_GET['parent']);
205 if ($parent && $parent['access']) {
206 $node->book['bid'] = $parent['bid'];
207 $node->book['plid'] = $parent['mlid'];
208 $node->book['menu_name'] = $parent['menu_name'];
209 }
210 }
211 // Set defaults.
212 $node->book += _book_link_defaults(!empty($node->nid) ? $node->nid : 'new');
213 }
214 else {
215 if (isset($node->book['bid']) && !isset($node->book['original_bid'])) {
216 $node->book['original_bid'] = $node->book['bid'];
217 }
218 }
219 // Find the depth limit for the parent select.
220 if (isset($node->book['bid']) && !isset($node->book['parent_depth_limit'])) {
221 $node->book['parent_depth_limit'] = _book_parent_depth_limit($node->book);
222 }
223 break;
224 case 'insert':
225 case 'update':
226 if ((!user_access('create new books') && user_access('create personal books')) || $node->book['ispersonal']) {
227 // TODO: I think this should cascade as well (think about the implications [if any] for users without book privileges.)
228 book_manager_make_personal($node, $user);
229 }
230 elseif (user_access('create new books') && !$form_state['values']['book']['ispersonal']) {
231 book_manager_make_personal($node, $user, FALSE);
232 }
233 break;
234 case 'delete':
235 // we only need to do stuff if this was a top-level node in a personal book
236 // code partially taken from book module to determine where our top-level bid goes to.
237 if (!empty($node->book['bid']) && $node->book['bid'] = $node->nid && $node->book_manager & BOOK_MANAGER_IS_IN_PERSONAL) {
238 db_query("DELETE FROM {book_manager} WHERE bid = %d", $node->book['bid']);
239 $result = db_query("SELECT b.nid FROM {menu_links} ml INNER JOIN {book} b on b.mlid = ml.mlid WHERE ml.plid = %d", $node->book['mlid']);
240 while ($child = db_fetch_array($result)) {
241 $child_node = node_load($child['nid']);
242 book_manager_make_personal($child_node, $user);
243 }
244 }
245 }
246 }
247
248 /**
249 * Implementation of hook_theme()
250 */
251 function book_manager_theme() {
252 return array('book_manager_outline_table' => array(
253 'arguments' => array('form' => NULL),
254 ),
255 );
256 }
257
258 /**
259 * This function heavily copied from theme_book_admin_table
260 * @see theme_book_admin_table
261 */
262 function theme_book_manager_outline_table($form) {
263 drupal_add_tabledrag('book-outline', 'match', 'parent', 'book-plid', 'book-plid', 'book-mlid', TRUE, MENU_MAX_DEPTH - 2);
264 drupal_add_tabledrag('book-outline', 'order', 'sibling', 'book-weight');
265
266 $header = array(t('Title'), t('Weight'), t('Parent'), array('data' => t('Operations'), 'colspan' => '3'));
267
268 $rows = array();
269 $destination = drupal_get_destination();
270 $access = user_access('administer nodes');
271
272 foreach (element_children($form) as $key) {
273 $nid = $form[$key]['nid']['#value'];
274 $href = $form[$key]['href']['#value'];
275
276 // add links for users with administer nodes permission
277 if (!$access) {
278 $node = node_load(array('nid' => $nid));
279 $edit = user_access('edit own '. $node->type .' content');
280 $delete = user_access('delete own '. $node->type .' content');
281 }
282 else {
283 $edit = TRUE;
284 $delete = TRUE;
285 }
286
287 // Add special classes to be used with tabledrag.js.
288 $form[$key]['plid']['#attributes']['class'] = 'book-plid';
289 $form[$key]['mlid']['#attributes']['class'] = 'book-mlid';
290 $form[$key]['weight']['#attributes']['class'] = 'book-weight';
291
292 $data = array(
293 theme('indentation', $form[$key]['depth']['#value'] - 2) . drupal_render($form[$key]['title']),
294 drupal_render($form[$key]['weight']),
295 drupal_render($form[$key]['plid']) . drupal_render($form[$key]['mlid']),
296 l(t('view'), $href),
297 $edit ? l(t('edit'), 'node/'. $nid .'/edit', array('query' => $destination)) : '&nbsp',
298 $delete ? l(t('delete'), 'node/'. $nid .'/delete', array('query' => $destination) ) : '&nbsp',
299 );
300
301 $edit = FALSE;
302 $delete = FALSE;
303
304 $row = array('data' => $data);
305 if (isset($form[$key]['#attributes'])) {
306 $row = array_merge($row, $form[$key]['#attributes']);
307 }
308 $row['class'] = empty($row['class']) ? 'draggable' : $row['class'] .' draggable';
309 $rows[] = $row;
310 }
311
312 return theme('table', $header, $rows, array('id' => 'book-outline'));
313 }
314
315 /**
316 * Implementation of hook_form_alter()
317 */
318 function book_manager_form_alter(&$form, $form_state, $form_id) {
319 if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] .'_node_form' == $form_id) {
320 $node = $form['#node'];
321
322 // if the book module did not already add our widgets
323 if (!isset($form['book']) && user_access('add content to personal books') && ((!empty($node->book['mlid']) && !empty($node->nid)) || book_type_is_allowed($node->type))) {
324 _book_add_form_elements($form, $node);
325 }
326
327 if (isset($form['book'])) {
328 // remove any options we need to
329 _book_manager_outline_alter($form, $node);
330 }
331 }
332 elseif ($form_id == 'book_admin_edit') {
333 if (!user_access('administer book outlines')) {
334 foreach ($form['table'] as $key => $value) {
335 if (strpos($key, '#') !== 0 && isset($form['table'][$key]['#item'])) { // not sure why #theme is getting through the isset check... so there is strpos()
336 $form['table'][$key]['title']['#type'] = 'hidden';
337 $form['table'][$key]['title']['#prefix'] = $form['table'][$key]['title']['#default_value'];
338 }
339 }
340
341 $form['table']['#theme'] = 'book_manager_outline_table';
342 // ensure the user didn't change any values (needs to run before book_admin_edit_submit)
343 array_unshift($form['#submit'], 'book_manager_admin_edit_submit');
344 }
345 }
346 elseif ($form_id == 'book_outline_form') {
347 $node = $form['#node'];
348 _book_manager_outline_alter($form, $node);
349 }
350 }
351
352 function _book_manager_outline_alter(&$form, $node) {
353 _book_manager_limit_books($form['book']['bid'], $node);
354 _book_manager_set_personal($form);
355
356 }
357
358 /**
359 * This function does the appropriate checking to;
360 * ensure this is a personal book and display appropriate output (either the outline form or "empty book")
361 * if this is in a book, but not the top-level it redirects the user to the top-level
362 * if the above criteria is not met, the user is notified it is not in a personal book
363 * @param object $node the node the user is attempting to access
364 * @return mixed text to be rendered, or user is redirected
365 */
366 function book_manager_outline_edit($node) {
367 if ($node->book_manager & BOOK_MANAGER_IS_BOOK && $node->book_manager & BOOK_MANAGER_IS_IN_PERSONAL) {
368 $result = db_query("SELECT count(*) AS pages FROM {book} WHERE bid = %d", $node->book['bid']);
369 $row = db_fetch_array($result);
370 if ($row['pages'] > 1) {
371 module_load_include('inc', 'book', 'book.admin');
372 $output = drupal_get_form('book_admin_edit', $node);
373 }
374 else {
375 $output = t('This book is currently empty. You may add content by editing other nodes and adding them to this book via the book fieldset.');
376 }
377 }
378 else if ($node->book_manager & BOOK_MANAGER_IS_IN_PERSONAL) {
379 // redirect user to top-level of the book
380 drupal_goto('personal-outline/'. $node->book['bid']);
381 }
382 else {
383 // book is not a personal book or in one (should we differentiate whether or not it is in A book?)
384 $output = t('This node is not in a personal book.');
385 }
386
387 return $output;
388 }
389
390 /**
391 * Implementation of hook_submit()
392 *
393 * This function ensures the user did not change any values via the book_admin_edit (outline form)
394 * This is necessary because we are leveraging a large amount of book code, and this required using hidden fields,
395 * a crafty user could hack the form to change the hidden field values potentially changing the node titles.
396 * This "pre-process" submit handler will revert any changes the user made if they shouldn't be allowed to
397 */
398 function book_manager_admin_edit_submit($form, &$form_state) {
399 // this function ensures the user did not change any values via the book_admin_edit (outline form);
400 foreach (element_children($form['table']) as $key) {
401 if ($form['table'][$key]['#item']) {
402 $row = $form['table'][$key];
403 $values = $form_state['values']['table'][$key];
404 if ($row['title']['#default_value'] != $values['title']) {
405 $form_state['values']['table'][$key]['title'] = $row['title']['#default_value'];
406 }
407 }
408 }
409 }
410
411 /**
412 * Turn an existing book into a personal book, or remove
413 * the personal designation.
414 *
415 * @param $node
416 * Node that is at the top level of a book
417 * @param $user
418 * The new owner of the book.
419 * @param $make_personal
420 * If true, then make the book personal, if false, remove
421 * the "personality" so that the book reverts to being a
422 * normal book.
423 * @param $cascade
424 * If true, all pages in the book change ownership to the
425 * book's owner.
426 */
427 function book_manager_make_personal($node, $user, $make_personal = TRUE, $cascade = FALSE) {
428 // Books are designated as personal by having a row in the
429 // {book_manager} table with their top-level nid as bid.
430 //
431 // If a book is already designated as personal, the INSERT
432 // will fail, but there is no need to report anything.
433 // $row = db_fetch_array(db_query("SELECT bid FROM {book} WHERE bid = %d", $node->nid));
434 if ($node->book['bid'] == $node->nid) {
435 if ($make_personal) {
436 @db_query('INSERT INTO {book_manager} (bid) VALUES (%d)', $node->nid);
437 drupal_set_message(t('The book <a href="@book_url">%book_name</a> is now a personal book.', array('@book_url' => url("node/$node->nid"), '%book_name' => $node->title)));
438 }
439 else {
440 db_query('DELETE FROM {book_manager} WHERE bid = %d', $node->nid);
441 drupal_set_message(t('The book <a href="@book_url">%book_name</a> is now a regular book', array('@book_url' => url("node/$node->nid"), '%book_name' => $node->title)));
442 }
443 }
444 }
445
446 function book_manager_change_node_ownership(&$node, $user) {
447 if ($node->nid) {
448 $node->uid = $user->uid;
449 node_save($node);
450 }
451 else {
452 watchdog('error', t('book_manager_change_node_ownership() called with unpopulated node'), array(), WATCHDOG_ERROR);
453 }
454 }
455
456 /**
457 * Returns the status of the given node
458 *
459 * This is used to populate $node->book_manager for easy access later
460 *
461 * BOOK_MANAGER_IS_IN_PERSONAL: The node in question is IN a personal book
462 * BOOK_MANAGER_IS_BOOK: The node in question is the root of a book
463 * BOOK_MANAGER_IS_IN_BOOK: The node in question is in a book
464 *
465 * @param int $nid the node id to load book status for
466 */
467 function book_manager_status($nid) {
468 $return = 0;
469 if ($result = db_query("SELECT nid, bid FROM {book} WHERE nid = %d", $nid)) {
470 $book = db_fetch_object($result);
471 if ($book->nid == $book->bid) {
472 $return += BOOK_MANAGER_IS_BOOK;
473 }
474 $return += BOOK_MANAGER_IS_IN_BOOK;
475
476 if ($result = db_query("SELECT bid FROM {book_manager} WHERE bid = %d", $book->bid)) {
477 $book = db_fetch_object($result);
478 if ($book->bid) {
479 $return += BOOK_MANAGER_IS_IN_PERSONAL;
480 }
481 }
482 }
483 return $return;
484 }
485
486 /**
487 * returns an array keyed by node pointing to the bid that the nid belongs to
488 * @param bool $personalonly if TRUE only personal books are included, if FALSE all books are included
489 */
490 function _book_manager_nodes_to_books($personalonly = TRUE) {
491 if ($personalonly) {
492 if ($result = db_query('SELECT bid FROM {book_manager}')) {
493 $books = array();
494 while ($row = db_fetch_array($result)) {
495 $books[$row['bid']] = $row['bid'];
496 }
497 if (!empty($books)) {
498 $in = "WHERE bid IN (". implode(', ', $books) .")";
499 }
500 }
501
502 if (!isset($in)) {
503 // something strange happened (let's ensure the next query will return no results)
504 $in = "WHERE 1 = -1";
505 }
506 }
507 else {
508 $in = '';
509 }
510
511 $nidstobooks = array();
512 $query = "SELECT nid, bid FROM {book}";
513 if (!empty($in)) {
514 $query .= ' '. $in;
515 }
516 $result = db_query($query);
517 while ($nidbid = db_fetch_array($result)) {
518 $nidstobooks[$nidbid['nid']] = $nidbid['bid'];
519 }
520
521 return $nidstobooks;
522 }
523
524
525 /**
526 * Given an array of book options this function prunes those entries the user should not be allowed to add
527 * This also adds the create option if the user should be able to crete books
528 *
529 * options matching any of the following criteria are removed:
530 * 1. node is in a personal book and node->author does not match current nid author
531 * 2. user does not have permission to add content from other authors (add_content_to_books)
532 * 3. node in question is in a personal book and the author does not match the current node author
533 * @param $bid array form element for the book
534 * @param $node node object the user is editing
535 */
536 function _book_manager_limit_books(&$bid, $node) {
537 $nidstobids = _book_manager_nodes_to_books(TRUE);
538 $addtobooks = user_access('add content to books');
539 foreach ($bid['#options'] as $nid => $title) {
540 if ((($node->book_manager & BOOK_MANAGER_IS_IN_PERSONAL) && !_book_manager_author_matches($nid, $node->uid)) || // node is in a personal book and node->author does not match current nid author
541 (!user_access('add content to books') && !_book_manager_author_matches($nid)) || // user does not have permission to add content from other authors
542 (in_array($nid, $nidstobids) && !_book_manager_author_matches($nid, $node->uid))) { // node in question is in a personal book and the author does not match the current node author
543 unset($bid['#options'][$nid]);
544 }
545 }
546
547 $nid = isset($node->nid) ? $node->nid : 'new';
548 if (!user_access('create new books') && user_access('create personal books') && ($nid == 'new' || ($nid != $node->book['original_bid']))) {
549 $bid['#options'] = array($nid => '<'. t('create new book') .'>') + $bid['#options'];
550 }
551
552 }
553
554 /**
555 * Returns whether or not the node author for the supplied nid matches the given uid (or the currently logged in user)
556 *
557 * @param int $nid the node it in question
558 * @param int $uid optional, if not supplied then the logged in user's id is used.
559 * @return bool whether or not the author for nid matches the given ui
560 */
561 function _book_manager_author_matches($nid, $uid = 0) {
562 if ($uid == 0) {
563 global $user;
564 $uid = $user->uid;
565 }
566
567 $result = db_query("SELECT uid FROM {node} WHERE nid = %d", $nid);
568 $dbuid = db_fetch_object($result);
569 if ($uid != $dbuid->uid) {
570 return FALSE;
571 }
572 else {
573 return TRUE;
574 }
575 }
576
577 /**
578 * Menu callback; show the outline form for a single node.
579 */
580 function book_manager_outline($node) {
581 module_load_include('inc', 'book', 'book.pages');
582
583 drupal_set_title(check_plain($node->title));
584 return drupal_get_form('book_outline_form', $node);
585 }
586
587 /**
588 * This function relies on book_outline_form to do the major form building
589 * However we need to restrict the books the user can choose to those they are
590 * the author for.
591 */
592 function book_manager_outline_form(&$form_state, $node) {
593 module_load_include('inc', 'book', 'book.pages');
594 $form = book_outline_form(&$form_state, $node);
595
596 _book_manager_limit_books($form['book']['bid'], $node);
597
598 _book_manager_set_personal($form);
599
600 return drupal_render($form);
601 }
602
603 /**
604 * This function handles the form processing for our modified book_outline_form
605 * again we rely on book code to do our processing, checking to see if the user will
606 * be redirected to outline and adjusting to personal-outline
607 */
608 function book_manager_outline_form_submit($form, &$form_state) {
609 $node = $form['#node'];
610 book_outline_form_submit($form, &$form_state);
611
612 if ($form_state['redirect'] == "node/". $node->nid ."/outline") {
613 $form_state['redirect'] = "node/". $node->nid ."/personal-outline";
614 }
615 }
616
617
618
619 /**
620 * This function adds a checkbox if the user has both "create new books" and "create personal books"
621 * That allows the user to check the box and create a personal book rather than a global book
622 */
623 function _book_manager_set_personal(&$form) {
624 if (user_access('create new books') && user_access('create personal books')) {
625 $node = $form['#node'];
626 if ($node->nid) {
627 $bid = db_fetch_array(db_query('SELECT bid FROM {book_manager} WHERE bid = %d', $node->nid));
628 if ($bid['bid']) {
629 $ispersonal = TRUE;
630 }
631 else {
632 $ispersonal = FALSE;
633 }
634 }
635 else {
636 $ispersonal = FALSE;
637 }
638
639 // prepare some jquery to hide the ispersonal box unless it makes sense
640 if ($node->nid) {
641 $jsnid = " || $('#edit-book-bid').val() == ". $node->nid;
642 }
643 else {
644 $jsnid = '';
645 }
646
647 $jscript = "if (Drupal.jsEnabled) {
648 function ispersonaljs() {
649 if ($('#edit-book-bid').val() == 'new'". $jsnid .") {
650 $('#edit-book-ispersonal-wrapper').css('display', 'inline');
651 }
652 else {
653 $('#edit-book-ispersonal-wrapper').css('display', 'none');
654 }
655 }
656
657 $(document).ready(function() {
658 ispersonaljs();
659 $('#edit-book-bid').change(ispersonaljs);
660 });
661 }";
662
663 drupal_add_js($jscript, 'inline');
664
665 $form['book']['ispersonal'] = array(
666 '#type' => 'checkbox',
667 '#default_value' => $ispersonal,
668 '#title' => t('Make Personal'),
669 '#description' => t('If checked this book will be a personal book, and will only be able to contain nodes from a single author'),
670 );
671 }
672 }
673
674 /**
675 * This function just sets whether a book is personal or not
676 */
677 function book_manager_set_personal_submit($form, &$form_state) {
678 $node = $form['#node'];
679 if ($form_state['values']['book']['ispersonal']) {
680 book_manager_make_personal($node, $user);
681 }
682 }
683
684 function book_manager_views_data() {
685 $data = array();
686
687 $data['book_manager']['table']['group'] = t('Book');
688 $data['book_manager']['table']['join'] = array(
689 'node' => array(
690 'left_field' => 'nid',
691 'field' => 'bid'),
692 );
693
694 $data['book_manager']['bid'] = array(
695 'title' => t('Personal Book'),
696 'help' => t('Thie personal book the node is in.'),
697 'relationship' => array(
698 'base' => 'node',
699 'field' => 'bid',
700 'handler' => 'views_handler_relationship',
701 'label' => t('Personal Book'),
702 ),
703 );
704 return $data;
705 }
706
707 /**
708 * Implementation of hook_book_copy_alter()
709 */
710 function book_manager_book_copy_alter(&$node, $oldbid, $newbid) {
711 $oldbook = node_load(array('nid' => $oldbid));
712 if ($oldbook->book_manager & BOOK_MANAGER_IS_IN_PERSONAL) {
713 @db_query('INSERT INTO {book_manager} (bid) VALUES (%d)', $newbid);
714 }
715 }
716
717 /**
718 * Implementation of hook_book_copy_goto_alter()
719 * change $node->bookcopydata['url'] to goto location
720 * change $node->bookcopydata['message'] to message to send via drupal_set_message()
721 */
722 function book_manager_book_copy_goto_alter(&$node) {
723 if (_book_manager_outline_access_menu_callback($node)) {
724 $node->bookcopydata['url'] = 'node/'. $node->nid .'/outline';
725 }
726 else {
727 $node->bookcopydata['url'] = 'node/'. $node->nid;
728 }
729 }
730
731 /**
732 * Since we overrode the book module's access control to /node/%/outline
733 * we need to remove the help as it displays links specific to users
734 * with 'administer book outlines'
735 */
736 function phptemplate_help() {
737 if ($help = menu_get_active_help()) {
738 if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == 'outline') {
739 if (user_access('administer book outlines')) {
740 return '<div class="help">'. $help .'</div>';
741 }
742 }
743 else {
744 return '<div class="help">'. $help .'</div>';
745 }
746 }
747 }

  ViewVC Help
Powered by ViewVC 1.1.2