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