book.pages.inc 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <?php
  2. /**
  3. * @file
  4. * User page callbacks for the book module.
  5. */
  6. /**
  7. * Menu callback: Prints a listing of all books.
  8. */
  9. function book_render() {
  10. $book_list = array();
  11. foreach (book_get_books() as $book) {
  12. $book_list[] = l($book['title'], $book['href'], $book['options']);
  13. }
  14. return theme('item_list', array('items' => $book_list));
  15. }
  16. /**
  17. * Menu callback; Generates representations of a book page and its children.
  18. *
  19. * The function delegates the generation of output to helper functions. The
  20. * function name is derived by prepending 'book_export_' to the given output
  21. * type. So, e.g., a type of 'html' results in a call to the function
  22. * book_export_html().
  23. *
  24. * @param $type
  25. * A string encoding the type of output requested. The following types are
  26. * currently supported in book module:
  27. * - html: Printer-friendly HTML.
  28. * Other types may be supported in contributed modules.
  29. * @param $nid
  30. * An integer representing the node id (nid) of the node to export
  31. *
  32. * @return
  33. * A string representing the node and its children in the book hierarchy in a
  34. * format determined by the $type parameter.
  35. */
  36. function book_export($type, $nid) {
  37. $type = drupal_strtolower($type);
  38. $export_function = 'book_export_' . $type;
  39. if (function_exists($export_function)) {
  40. print call_user_func($export_function, $nid);
  41. }
  42. else {
  43. drupal_set_message(t('Unknown export format.'));
  44. drupal_not_found();
  45. }
  46. }
  47. /**
  48. * Generates HTML for export when invoked by book_export().
  49. *
  50. * The given node is embedded to its absolute depth in a top level section. For
  51. * example, a child node with depth 2 in the hierarchy is contained in
  52. * (otherwise empty) <div> elements corresponding to depth 0 and depth 1.
  53. * This is intended to support WYSIWYG output - e.g., level 3 sections always
  54. * look like level 3 sections, no matter their depth relative to the node
  55. * selected to be exported as printer-friendly HTML.
  56. *
  57. * @param $nid
  58. * An integer representing the node id (nid) of the node to export.
  59. *
  60. * @return
  61. * A string containing HTML representing the node and its children in
  62. * the book hierarchy.
  63. */
  64. function book_export_html($nid) {
  65. if (user_access('access printer-friendly version')) {
  66. $export_data = array();
  67. $node = node_load($nid);
  68. if (isset($node->book)) {
  69. $tree = book_menu_subtree_data($node->book);
  70. $contents = book_export_traverse($tree, 'book_node_export');
  71. return theme('book_export_html', array('title' => $node->title, 'contents' => $contents, 'depth' => $node->book['depth']));
  72. }
  73. else {
  74. drupal_not_found();
  75. }
  76. }
  77. else {
  78. drupal_access_denied();
  79. }
  80. }
  81. /**
  82. * Menu callback: Shows the outline form for a single node.
  83. *
  84. * @param $node
  85. * The book node for which to show the outline.
  86. */
  87. function book_outline($node) {
  88. drupal_set_title($node->title);
  89. return drupal_get_form('book_outline_form', $node);
  90. }
  91. /**
  92. * Form constructor for the book outline form.
  93. *
  94. * Allows handling of all book outline operations via the outline tab.
  95. *
  96. * @param $node
  97. * The book node for which to show the outline.
  98. *
  99. * @see book_outline_form_submit()
  100. * @see book_remove_button_submit()
  101. * @ingroup forms
  102. */
  103. function book_outline_form($form, &$form_state, $node) {
  104. if (!isset($node->book)) {
  105. // The node is not part of any book yet - set default options.
  106. $node->book = _book_link_defaults($node->nid);
  107. }
  108. else {
  109. $node->book['original_bid'] = $node->book['bid'];
  110. }
  111. // Find the depth limit for the parent select.
  112. if (!isset($node->book['parent_depth_limit'])) {
  113. $node->book['parent_depth_limit'] = _book_parent_depth_limit($node->book);
  114. }
  115. $form['#node'] = $node;
  116. $form['#id'] = 'book-outline';
  117. _book_add_form_elements($form, $form_state, $node);
  118. $form['book']['#collapsible'] = FALSE;
  119. $form['update'] = array(
  120. '#type' => 'submit',
  121. '#value' => $node->book['original_bid'] ? t('Update book outline') : t('Add to book outline'),
  122. '#weight' => 15,
  123. );
  124. $form['remove'] = array(
  125. '#type' => 'submit',
  126. '#value' => t('Remove from book outline'),
  127. '#access' => _book_node_is_removable($node),
  128. '#weight' => 20,
  129. '#submit' => array('book_remove_button_submit'),
  130. );
  131. return $form;
  132. }
  133. /**
  134. * Form submission handler for book_outline_form().
  135. *
  136. * Redirects to removal confirmation form.
  137. *
  138. * @see book_outline_form_submit()
  139. */
  140. function book_remove_button_submit($form, &$form_state) {
  141. $form_state['redirect'] = 'node/' . $form['#node']->nid . '/outline/remove';
  142. }
  143. /**
  144. * Form submission handler for book_outline_form().
  145. *
  146. * @see book_remove_button_submit()
  147. */
  148. function book_outline_form_submit($form, &$form_state) {
  149. $node = $form['#node'];
  150. $form_state['redirect'] = "node/" . $node->nid;
  151. $book_link = $form_state['values']['book'];
  152. if (!$book_link['bid']) {
  153. drupal_set_message(t('No changes were made'));
  154. return;
  155. }
  156. $book_link['menu_name'] = book_menu_name($book_link['bid']);
  157. $node->book = $book_link;
  158. if (_book_update_outline($node)) {
  159. if ($node->book['parent_mismatch']) {
  160. // This will usually only happen when JS is disabled.
  161. drupal_set_message(t('The post has been added to the selected book. You may now position it relative to other pages.'));
  162. $form_state['redirect'] = "node/" . $node->nid . "/outline";
  163. }
  164. else {
  165. drupal_set_message(t('The book outline has been updated.'));
  166. }
  167. }
  168. else {
  169. drupal_set_message(t('There was an error adding the post to the book.'), 'error');
  170. }
  171. }
  172. /**
  173. * Form constructor to confirm removal of a node from a book.
  174. *
  175. * @param $node
  176. * The node to delete.
  177. *
  178. * @see book_remove_form_submit()
  179. * @ingroup forms
  180. */
  181. function book_remove_form($form, &$form_state, $node) {
  182. $form['#node'] = $node;
  183. $title = array('%title' => $node->title);
  184. if ($node->book['has_children']) {
  185. $description = t('%title has associated child pages, which will be relocated automatically to maintain their connection to the book. To recreate the hierarchy (as it was before removing this page), %title may be added again using the Outline tab, and each of its former child pages will need to be relocated manually.', $title);
  186. }
  187. else {
  188. $description = t('%title may be added to hierarchy again using the Outline tab.', $title);
  189. }
  190. return confirm_form($form, t('Are you sure you want to remove %title from the book hierarchy?', $title), 'node/' . $node->nid, $description, t('Remove'));
  191. }
  192. /**
  193. * Form submission handler for book_remove_form().
  194. */
  195. function book_remove_form_submit($form, &$form_state) {
  196. $node = $form['#node'];
  197. if (_book_node_is_removable($node)) {
  198. menu_link_delete($node->book['mlid']);
  199. db_delete('book')
  200. ->condition('nid', $node->nid)
  201. ->execute();
  202. drupal_set_message(t('The post has been removed from the book.'));
  203. }
  204. $form_state['redirect'] = 'node/' . $node->nid;
  205. }