| webmaster@1 | 1 <?php | 
| webmaster@1 | 2 // $Id: book.pages.inc,v 1.5 2007/12/22 23:24:24 goba Exp $ | 
| webmaster@1 | 3 | 
| webmaster@1 | 4 /** | 
| webmaster@1 | 5  * @file | 
| webmaster@1 | 6  * User page callbacks for the book module. | 
| webmaster@1 | 7  */ | 
| webmaster@1 | 8 | 
| webmaster@1 | 9 /** | 
| webmaster@1 | 10  * Menu callback; prints a listing of all books. | 
| webmaster@1 | 11  */ | 
| webmaster@1 | 12 function book_render() { | 
| webmaster@1 | 13   $book_list = array(); | 
| webmaster@1 | 14   foreach (book_get_books() as $book) { | 
| webmaster@1 | 15     $book_list[] = l($book['title'], $book['href'], $book['options']); | 
| webmaster@1 | 16   } | 
| webmaster@1 | 17 | 
| webmaster@1 | 18   return theme('item_list', $book_list); | 
| webmaster@1 | 19 } | 
| webmaster@1 | 20 | 
| webmaster@1 | 21 /** | 
| webmaster@1 | 22  * Menu callback; Generates various representation of a book page and its children. | 
| webmaster@1 | 23  * | 
| webmaster@1 | 24  * The function delegates the generation of output to helper functions. | 
| webmaster@1 | 25  * The function name is derived by prepending 'book_export_' to the | 
| webmaster@1 | 26  * given output type. So, e.g., a type of 'html' results in a call to | 
| webmaster@1 | 27  * the function book_export_html(). | 
| webmaster@1 | 28  * | 
| webmaster@1 | 29  * @param $type | 
| webmaster@1 | 30  *   A string encoding the type of output requested. The following | 
| webmaster@1 | 31  *   types are currently supported in book module: | 
| webmaster@1 | 32  * | 
| webmaster@1 | 33  *   - html: HTML (printer friendly output) | 
| webmaster@1 | 34  * | 
| webmaster@1 | 35  *   Other types may be supported in contributed modules. | 
| webmaster@1 | 36  * @param $nid | 
| webmaster@1 | 37  *   An integer representing the node id (nid) of the node to export | 
| webmaster@1 | 38  * @return | 
| webmaster@1 | 39  *   A string representing the node and its children in the book hierarchy | 
| webmaster@1 | 40  *   in a format determined by the $type parameter. | 
| webmaster@1 | 41  */ | 
| webmaster@1 | 42 function book_export($type, $nid) { | 
| webmaster@1 | 43 | 
| webmaster@1 | 44   $type = drupal_strtolower($type); | 
| webmaster@1 | 45 | 
| webmaster@1 | 46   $export_function = 'book_export_'. $type; | 
| webmaster@1 | 47 | 
| webmaster@1 | 48   if (function_exists($export_function)) { | 
| webmaster@1 | 49     print call_user_func($export_function, $nid); | 
| webmaster@1 | 50   } | 
| webmaster@1 | 51   else { | 
| webmaster@1 | 52     drupal_set_message(t('Unknown export format.')); | 
| webmaster@1 | 53     drupal_not_found(); | 
| webmaster@1 | 54   } | 
| webmaster@1 | 55 } | 
| webmaster@1 | 56 | 
| webmaster@1 | 57 /** | 
| webmaster@1 | 58  * This function is called by book_export() to generate HTML for export. | 
| webmaster@1 | 59  * | 
| webmaster@1 | 60  * The given node is /embedded to its absolute depth in a top level | 
| webmaster@1 | 61  * section/. For example, a child node with depth 2 in the hierarchy | 
| webmaster@1 | 62  * is contained in (otherwise empty) <div> elements | 
| webmaster@1 | 63  * corresponding to depth 0 and depth 1. This is intended to support | 
| webmaster@1 | 64  * WYSIWYG output - e.g., level 3 sections always look like level 3 | 
| webmaster@1 | 65  * sections, no matter their depth relative to the node selected to be | 
| webmaster@1 | 66  * exported as printer-friendly HTML. | 
| webmaster@1 | 67  * | 
| webmaster@1 | 68  * @param $nid | 
| webmaster@1 | 69  *   An integer representing the node id (nid) of the node to export. | 
| webmaster@1 | 70  * @return | 
| webmaster@1 | 71  *   A string containing HTML representing the node and its children in | 
| webmaster@1 | 72  *   the book hierarchy. | 
| webmaster@1 | 73  */ | 
| webmaster@1 | 74 function book_export_html($nid) { | 
| webmaster@1 | 75   if (user_access('access printer-friendly version')) { | 
| webmaster@1 | 76     $export_data = array(); | 
| webmaster@1 | 77     $node = node_load($nid); | 
| webmaster@1 | 78     if (isset($node->book)) { | 
| webmaster@1 | 79       $tree = book_menu_subtree_data($node->book); | 
| webmaster@1 | 80       $contents = book_export_traverse($tree, 'book_node_export'); | 
| webmaster@1 | 81     } | 
| webmaster@1 | 82     return theme('book_export_html', $node->title, $contents, $node->book['depth']); | 
| webmaster@1 | 83   } | 
| webmaster@1 | 84   else { | 
| webmaster@1 | 85     drupal_access_denied(); | 
| webmaster@1 | 86   } | 
| webmaster@1 | 87 } | 
| webmaster@1 | 88 | 
| webmaster@1 | 89 /** | 
| webmaster@1 | 90  * Menu callback; show the outline form for a single node. | 
| webmaster@1 | 91  */ | 
| webmaster@1 | 92 function book_outline($node) { | 
| webmaster@1 | 93   drupal_set_title(check_plain($node->title)); | 
| webmaster@1 | 94   return drupal_get_form('book_outline_form', $node); | 
| webmaster@1 | 95 } | 
| webmaster@1 | 96 | 
| webmaster@1 | 97 /** | 
| webmaster@1 | 98  * Build the form to handle all book outline operations via the outline tab. | 
| webmaster@1 | 99  * | 
| webmaster@1 | 100  * @see book_outline_form_submit() | 
| webmaster@1 | 101  * @see book_remove_button_submit() | 
| webmaster@1 | 102  * | 
| webmaster@1 | 103  * @ingroup forms | 
| webmaster@1 | 104  */ | 
| webmaster@1 | 105 function book_outline_form(&$form_state, $node) { | 
| webmaster@1 | 106 | 
| webmaster@1 | 107   if (!isset($node->book)) { | 
| webmaster@1 | 108     // The node is not part of any book yet - set default options. | 
| webmaster@1 | 109     $node->book = _book_link_defaults($node->nid); | 
| webmaster@1 | 110   } | 
| webmaster@1 | 111   else { | 
| webmaster@1 | 112     $node->book['original_bid'] = $node->book['bid']; | 
| webmaster@1 | 113   } | 
| webmaster@1 | 114   // Find the depth limit for the parent select. | 
| webmaster@1 | 115   if (!isset($node->book['parent_depth_limit'])) { | 
| webmaster@1 | 116     $node->book['parent_depth_limit'] = _book_parent_depth_limit($node->book); | 
| webmaster@1 | 117   } | 
| webmaster@1 | 118   $form['#node'] = $node; | 
| webmaster@1 | 119   $form['#id'] = 'book-outline'; | 
| webmaster@1 | 120   _book_add_form_elements($form, $node); | 
| webmaster@1 | 121 | 
| webmaster@1 | 122   $form['book']['#collapsible'] = FALSE; | 
| webmaster@1 | 123 | 
| webmaster@1 | 124   $form['update'] = array( | 
| webmaster@1 | 125     '#type' => 'submit', | 
| webmaster@1 | 126     '#value' => $node->book['original_bid'] ? t('Update book outline') : t('Add to book outline'), | 
| webmaster@1 | 127     '#weight' => 15, | 
| webmaster@1 | 128   ); | 
| webmaster@1 | 129 | 
| webmaster@1 | 130   $form['remove'] = array( | 
| webmaster@1 | 131     '#type' => 'submit', | 
| webmaster@1 | 132     '#value' => t('Remove from book outline'), | 
| webmaster@1 | 133     '#access' => $node->nid != $node->book['bid'] && $node->book['bid'], | 
| webmaster@1 | 134     '#weight' => 20, | 
| webmaster@1 | 135     '#submit' => array('book_remove_button_submit'), | 
| webmaster@1 | 136   ); | 
| webmaster@1 | 137 | 
| webmaster@1 | 138   return $form; | 
| webmaster@1 | 139 } | 
| webmaster@1 | 140 | 
| webmaster@1 | 141 /** | 
| webmaster@1 | 142  * Button submit function to redirect to removal confirm form. | 
| webmaster@1 | 143  * | 
| webmaster@1 | 144  * @see book_outline_form() | 
| webmaster@1 | 145  */ | 
| webmaster@1 | 146 function book_remove_button_submit($form, &$form_state) { | 
| webmaster@1 | 147   $form_state['redirect'] = 'node/'. $form['#node']->nid .'/outline/remove'; | 
| webmaster@1 | 148 } | 
| webmaster@1 | 149 | 
| webmaster@1 | 150 /** | 
| webmaster@1 | 151  * Handles book outline form submissions from the outline tab. | 
| webmaster@1 | 152  * | 
| webmaster@1 | 153  * @see book_outline_form() | 
| webmaster@1 | 154  */ | 
| webmaster@1 | 155 function book_outline_form_submit($form, &$form_state) { | 
| webmaster@1 | 156   $node = $form['#node']; | 
| webmaster@1 | 157   $form_state['redirect'] = "node/". $node->nid; | 
| webmaster@1 | 158   $book_link = $form_state['values']['book']; | 
| webmaster@1 | 159   if (!$book_link['bid']) { | 
| webmaster@1 | 160     drupal_set_message(t('No changes were made')); | 
| webmaster@1 | 161     return; | 
| webmaster@1 | 162   } | 
| webmaster@1 | 163 | 
| webmaster@1 | 164   $book_link['menu_name'] = book_menu_name($book_link['bid']); | 
| webmaster@1 | 165   $node->book = $book_link; | 
| webmaster@1 | 166   if (_book_update_outline($node)) { | 
| webmaster@1 | 167     if ($node->book['parent_mismatch']) { | 
| webmaster@1 | 168       // This will usually only happen when JS is disabled. | 
| webmaster@1 | 169       drupal_set_message(t('The post has been added to the selected book. You may now position it relative to other pages.')); | 
| webmaster@1 | 170       $form_state['redirect'] = "node/". $node->nid ."/outline"; | 
| webmaster@1 | 171     } | 
| webmaster@1 | 172     else { | 
| webmaster@1 | 173       drupal_set_message(t('The book outline has been updated.')); | 
| webmaster@1 | 174     } | 
| webmaster@1 | 175   } | 
| webmaster@1 | 176   else { | 
| webmaster@1 | 177     drupal_set_message(t('There was an error adding the post to the book.'), 'error'); | 
| webmaster@1 | 178   } | 
| webmaster@1 | 179 } | 
| webmaster@1 | 180 | 
| webmaster@1 | 181 /** | 
| webmaster@1 | 182  * Menu callback; builds a form to confirm removal of a node from the book. | 
| webmaster@1 | 183  * | 
| webmaster@1 | 184  * @see book_remove_form_submit() | 
| webmaster@1 | 185  * | 
| webmaster@1 | 186  * @ingroup forms | 
| webmaster@1 | 187  */ | 
| webmaster@1 | 188 function book_remove_form(&$form_state, $node) { | 
| webmaster@1 | 189   $form['#node'] = $node; | 
| webmaster@1 | 190   $title = array('%title' => $node->title); | 
| webmaster@1 | 191 | 
| webmaster@1 | 192   if ($node->book['has_children']) { | 
| webmaster@1 | 193     $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); | 
| webmaster@1 | 194   } | 
| webmaster@1 | 195   else { | 
| webmaster@1 | 196     $description = t('%title may be added to hierarchy again using the Outline tab.', $title); | 
| webmaster@1 | 197   } | 
| webmaster@1 | 198 | 
| webmaster@1 | 199   return confirm_form($form, t('Are you sure you want to remove %title from the book hierarchy?', $title), 'node/'. $node->nid, $description, t('Remove')); | 
| webmaster@1 | 200 } | 
| webmaster@1 | 201 | 
| webmaster@1 | 202 /** | 
| webmaster@1 | 203  * Confirm form submit function to remove a node from the book. | 
| webmaster@1 | 204  * | 
| webmaster@1 | 205  * @see book_remove_form() | 
| webmaster@1 | 206  */ | 
| webmaster@1 | 207 function book_remove_form_submit($form, &$form_state) { | 
| webmaster@1 | 208   $node = $form['#node']; | 
| webmaster@1 | 209   if ($node->nid != $node->book['bid']) { | 
| webmaster@1 | 210     // Only allowed when this is not a book (top-level page). | 
| webmaster@1 | 211     menu_link_delete($node->book['mlid']); | 
| webmaster@1 | 212     db_query('DELETE FROM {book} WHERE nid = %d', $node->nid); | 
| webmaster@1 | 213     drupal_set_message(t('The post has been removed from the book.')); | 
| webmaster@1 | 214   } | 
| webmaster@1 | 215   $form_state['redirect'] = 'node/'. $node->nid; | 
| webmaster@1 | 216 } | 
| webmaster@1 | 217 | 
| webmaster@1 | 218 /** | 
| webmaster@1 | 219  * AJAX callback to replace the book parent select options. | 
| webmaster@1 | 220  * | 
| webmaster@1 | 221  * This function is called when the selected book is changed.  It updates the | 
| webmaster@1 | 222  * cached form (either the node form or the book outline form) and returns | 
| webmaster@1 | 223  * rendered output to be used to replace the select containing the possible | 
| webmaster@1 | 224  * parent pages in the newly selected book. | 
| webmaster@1 | 225  * | 
| webmaster@1 | 226  * @param $build_id | 
| webmaster@1 | 227  *   The form's build_id. | 
| webmaster@1 | 228  * @param $bid | 
| webmaster@1 | 229  *   A bid from from among those in the form's book select. | 
| webmaster@1 | 230  * @return | 
| webmaster@1 | 231  *   Prints the replacement HTML in JSON format. | 
| webmaster@1 | 232  */ | 
| webmaster@1 | 233 function book_form_update() { | 
| webmaster@1 | 234   $cid = 'form_'. $_POST['form_build_id']; | 
| webmaster@1 | 235   $bid = $_POST['book']['bid']; | 
| webmaster@1 | 236   $cache = cache_get($cid, 'cache_form'); | 
| webmaster@1 | 237   if ($cache) { | 
| webmaster@1 | 238     $form = $cache->data; | 
| webmaster@1 | 239 | 
| webmaster@1 | 240     // Validate the bid. | 
| webmaster@1 | 241     if (isset($form['book']['bid']['#options'][$bid])) { | 
| webmaster@1 | 242       $book_link = $form['#node']->book; | 
| webmaster@1 | 243       $book_link['bid'] = $bid; | 
| webmaster@1 | 244       // Get the new options and update the cache. | 
| webmaster@1 | 245       $form['book']['plid'] = _book_parent_select($book_link); | 
| webmaster@1 | 246       cache_set($cid, $form, 'cache_form', $cache->expire); | 
| webmaster@1 | 247 | 
| webmaster@1 | 248       // Build and render the new select element, then return it in JSON format. | 
| webmaster@1 | 249       $form_state = array(); | 
| webmaster@1 | 250       $form['#post'] = array(); | 
| webmaster@1 | 251       $form = form_builder($form['form_id']['#value'] , $form, $form_state); | 
| webmaster@1 | 252       $output = drupal_render($form['book']['plid']); | 
| webmaster@1 | 253       drupal_json(array('status' => TRUE, 'data' => $output)); | 
| webmaster@1 | 254     } | 
| webmaster@1 | 255     else { | 
| webmaster@1 | 256       drupal_json(array('status' => FALSE, 'data' => '')); | 
| webmaster@1 | 257     } | 
| webmaster@1 | 258   } | 
| webmaster@1 | 259   else { | 
| webmaster@1 | 260     drupal_json(array('status' => FALSE, 'data' => '')); | 
| webmaster@1 | 261   } | 
| webmaster@1 | 262   exit(); | 
| webmaster@1 | 263 } |