cms/drupal/modules/book/book.admin.inc
changeset 541 e756a8c72c3d
equal deleted inserted replaced
540:07239de796bb 541:e756a8c72c3d
       
     1 <?php
       
     2 
       
     3 /**
       
     4  * @file
       
     5  * Administration page callbacks for the Book module.
       
     6  */
       
     7 
       
     8 /**
       
     9  * Returns an administrative overview of all books.
       
    10  *
       
    11  * @return string
       
    12  *   A HTML-formatted string with the administrative page content.
       
    13  *
       
    14  * @see book_menu()
       
    15  */
       
    16 function book_admin_overview() {
       
    17   $rows = array();
       
    18 
       
    19   $headers = array(t('Book'), t('Operations'));
       
    20 
       
    21   // Add any recognized books to the table list.
       
    22   foreach (book_get_books() as $book) {
       
    23     $rows[] = array(l($book['title'], $book['href'], $book['options']), l(t('edit order and titles'), 'admin/content/book/' . $book['nid']));
       
    24   }
       
    25 
       
    26   return theme('table', array('header' => $headers, 'rows' => $rows, 'empty' => t('No books available.')));
       
    27 }
       
    28 
       
    29 /**
       
    30  * Form constructor for the book settings form.
       
    31  *
       
    32  * @see book_admin_settings_validate()
       
    33  *
       
    34  * @ingroup forms
       
    35  */
       
    36 function book_admin_settings() {
       
    37   $types = node_type_get_names();
       
    38   $form['book_allowed_types'] = array(
       
    39     '#type' => 'checkboxes',
       
    40     '#title' => t('Content types allowed in book outlines'),
       
    41     '#default_value' => variable_get('book_allowed_types', array('book')),
       
    42     '#options' => $types,
       
    43     '#description' => t('Users with the %outline-perm permission can add all content types.', array('%outline-perm' => t('Administer book outlines'))),
       
    44     '#required' => TRUE,
       
    45   );
       
    46   $form['book_child_type'] = array(
       
    47     '#type' => 'radios',
       
    48     '#title' => t('Content type for child pages'),
       
    49     '#default_value' => variable_get('book_child_type', 'book'),
       
    50     '#options' => $types,
       
    51     '#required' => TRUE,
       
    52   );
       
    53   $form['array_filter'] = array('#type' => 'value', '#value' => TRUE);
       
    54   $form['#validate'][] = 'book_admin_settings_validate';
       
    55 
       
    56   return system_settings_form($form);
       
    57 }
       
    58 
       
    59 /**
       
    60  * Form validation handler for book_admin_settings().
       
    61  *
       
    62  * @see book_admin_settings_submit()
       
    63  */
       
    64 function book_admin_settings_validate($form, &$form_state) {
       
    65   $child_type = $form_state['values']['book_child_type'];
       
    66   if (empty($form_state['values']['book_allowed_types'][$child_type])) {
       
    67     form_set_error('book_child_type', t('The content type for the %add-child link must be one of those selected as an allowed book outline type.', array('%add-child' => t('Add child page'))));
       
    68   }
       
    69 }
       
    70 
       
    71 /**
       
    72  * Form constructor for administering a single book's hierarchy.
       
    73  *
       
    74  * @see book_admin_edit_submit()
       
    75  *
       
    76  * @param $node
       
    77  *   The node of the top-level page in the book.
       
    78  *
       
    79  * @see book_admin_edit_validate()
       
    80  * @see book_admin_edit_submit()
       
    81  * @ingroup forms
       
    82  */
       
    83 function book_admin_edit($form, $form_state, $node) {
       
    84   drupal_set_title($node->title);
       
    85   $form['#node'] = $node;
       
    86   _book_admin_table($node, $form);
       
    87   $form['save'] = array(
       
    88     '#type' => 'submit',
       
    89     '#value' => t('Save book pages'),
       
    90   );
       
    91 
       
    92   return $form;
       
    93 }
       
    94 
       
    95 /**
       
    96  * Form validation handler for book_admin_edit().
       
    97  *
       
    98  * Checks that the book has not been changed while using the form.
       
    99  *
       
   100  * @see book_admin_edit_submit()
       
   101  */
       
   102 function book_admin_edit_validate($form, &$form_state) {
       
   103   if ($form_state['values']['tree_hash'] != $form_state['values']['tree_current_hash']) {
       
   104     form_set_error('', t('This book has been modified by another user, the changes could not be saved.'));
       
   105   }
       
   106 }
       
   107 
       
   108 /**
       
   109  * Form submission handler for book_admin_edit().
       
   110  *
       
   111  * This function takes care to save parent menu items before their children.
       
   112  * Saving menu items in the incorrect order can break the menu tree.
       
   113  *
       
   114  * @see book_admin_edit_validate()
       
   115  * @see menu_overview_form_submit()
       
   116  */
       
   117 function book_admin_edit_submit($form, &$form_state) {
       
   118   // Save elements in the same order as defined in post rather than the form.
       
   119   // This ensures parents are updated before their children, preventing orphans.
       
   120   $order = array_flip(array_keys($form_state['input']['table']));
       
   121   $form['table'] = array_merge($order, $form['table']);
       
   122 
       
   123   foreach (element_children($form['table']) as $key) {
       
   124     if ($form['table'][$key]['#item']) {
       
   125       $row = $form['table'][$key];
       
   126       $values = $form_state['values']['table'][$key];
       
   127 
       
   128       // Update menu item if moved.
       
   129       if ($row['plid']['#default_value'] != $values['plid'] || $row['weight']['#default_value'] != $values['weight']) {
       
   130         $row['#item']['plid'] = $values['plid'];
       
   131         $row['#item']['weight'] = $values['weight'];
       
   132         menu_link_save($row['#item']);
       
   133       }
       
   134 
       
   135       // Update the title if changed.
       
   136       if ($row['title']['#default_value'] != $values['title']) {
       
   137         $node = node_load($values['nid']);
       
   138         $langcode = LANGUAGE_NONE;
       
   139         $node->title = $values['title'];
       
   140         $node->book['link_title'] = $values['title'];
       
   141         $node->revision = 1;
       
   142         $node->log = t('Title changed from %original to %current.', array('%original' => $node->title, '%current' => $values['title']));
       
   143 
       
   144         node_save($node);
       
   145         watchdog('content', 'book: updated %title.', array('%title' => $node->title), WATCHDOG_NOTICE, l(t('view'), 'node/' . $node->nid));
       
   146       }
       
   147     }
       
   148   }
       
   149 
       
   150   drupal_set_message(t('Updated book %title.', array('%title' => $form['#node']->title)));
       
   151 }
       
   152 
       
   153 /**
       
   154  * Builds the table portion of the form for the book administration page.
       
   155  *
       
   156  * @param $node
       
   157  *   The node of the top-level page in the book.
       
   158  * @param $form
       
   159  *   The form that is being modified, passed by reference.
       
   160  *
       
   161  * @see book_admin_edit()
       
   162  */
       
   163 function _book_admin_table($node, &$form) {
       
   164   $form['table'] = array(
       
   165     '#theme' => 'book_admin_table',
       
   166     '#tree' => TRUE,
       
   167   );
       
   168 
       
   169   $tree = book_menu_subtree_data($node->book);
       
   170   $tree = array_shift($tree); // Do not include the book item itself.
       
   171   if ($tree['below']) {
       
   172     $hash = drupal_hash_base64(serialize($tree['below']));
       
   173     // Store the hash value as a hidden form element so that we can detect
       
   174     // if another user changed the book hierarchy.
       
   175     $form['tree_hash'] = array(
       
   176       '#type' => 'hidden',
       
   177       '#default_value' => $hash,
       
   178     );
       
   179     $form['tree_current_hash'] = array(
       
   180       '#type' => 'value',
       
   181       '#value' => $hash,
       
   182     );
       
   183     _book_admin_table_tree($tree['below'], $form['table']);
       
   184   }
       
   185 
       
   186 }
       
   187 
       
   188 /**
       
   189  * Helps build the main table in the book administration page form.
       
   190  *
       
   191  * @param $tree
       
   192  *   A subtree of the book menu hierarchy.
       
   193  * @param $form
       
   194  *   The form that is being modified, passed by reference.
       
   195  *
       
   196  * @return
       
   197  *   The modified form array.
       
   198  *
       
   199  * @see book_admin_edit()
       
   200  */
       
   201 function _book_admin_table_tree($tree, &$form) {
       
   202   // The delta must be big enough to give each node a distinct value.
       
   203   $count = count($tree);
       
   204   $delta = ($count < 30) ? 15 : intval($count / 2) + 1;
       
   205 
       
   206   foreach ($tree as $data) {
       
   207     $form['book-admin-' . $data['link']['nid']] = array(
       
   208       '#item' => $data['link'],
       
   209       'nid' => array('#type' => 'value', '#value' => $data['link']['nid']),
       
   210       'depth' => array('#type' => 'value', '#value' => $data['link']['depth']),
       
   211       'href' => array('#type' => 'value', '#value' => $data['link']['href']),
       
   212       'title' => array(
       
   213         '#type' => 'textfield',
       
   214         '#default_value' => $data['link']['link_title'],
       
   215         '#maxlength' => 255,
       
   216         '#size' => 40,
       
   217       ),
       
   218       'weight' => array(
       
   219         '#type' => 'weight',
       
   220         '#default_value' => $data['link']['weight'],
       
   221         '#delta' => max($delta, abs($data['link']['weight'])),
       
   222         '#title' => t('Weight for @title', array('@title' => $data['link']['title'])),
       
   223         '#title_display' => 'invisible',
       
   224       ),
       
   225       'plid' => array(
       
   226         '#type' => 'hidden',
       
   227         '#default_value' => $data['link']['plid'],
       
   228       ),
       
   229       'mlid' => array(
       
   230         '#type' => 'hidden',
       
   231         '#default_value' => $data['link']['mlid'],
       
   232       ),
       
   233     );
       
   234     if ($data['below']) {
       
   235       _book_admin_table_tree($data['below'], $form);
       
   236     }
       
   237   }
       
   238 
       
   239   return $form;
       
   240 }
       
   241 
       
   242 /**
       
   243  * Returns HTML for a book administration form.
       
   244  *
       
   245  * @param $variables
       
   246  *   An associative array containing:
       
   247  *   - form: A render element representing the form.
       
   248  *
       
   249  * @see book_admin_table()
       
   250  * @ingroup themeable
       
   251  */
       
   252 function theme_book_admin_table($variables) {
       
   253   $form = $variables['form'];
       
   254 
       
   255   drupal_add_tabledrag('book-outline', 'match', 'parent', 'book-plid', 'book-plid', 'book-mlid', TRUE, MENU_MAX_DEPTH - 2);
       
   256   drupal_add_tabledrag('book-outline', 'order', 'sibling', 'book-weight');
       
   257 
       
   258   $header = array(t('Title'), t('Weight'), t('Parent'), array('data' => t('Operations'), 'colspan' => '3'));
       
   259 
       
   260   $rows = array();
       
   261   $destination = drupal_get_destination();
       
   262   $access = user_access('administer nodes');
       
   263   foreach (element_children($form) as $key) {
       
   264     $nid = $form[$key]['nid']['#value'];
       
   265     $href = $form[$key]['href']['#value'];
       
   266 
       
   267     // Add special classes to be used with tabledrag.js.
       
   268     $form[$key]['plid']['#attributes']['class'] = array('book-plid');
       
   269     $form[$key]['mlid']['#attributes']['class'] = array('book-mlid');
       
   270     $form[$key]['weight']['#attributes']['class'] = array('book-weight');
       
   271 
       
   272     $data = array(
       
   273       theme('indentation', array('size' => $form[$key]['depth']['#value'] - 2)) . drupal_render($form[$key]['title']),
       
   274       drupal_render($form[$key]['weight']),
       
   275       drupal_render($form[$key]['plid']) . drupal_render($form[$key]['mlid']),
       
   276       l(t('view'), $href),
       
   277       $access ? l(t('edit'), 'node/' . $nid . '/edit', array('query' => $destination)) : '&nbsp;',
       
   278       $access ? l(t('delete'), 'node/' . $nid . '/delete', array('query' => $destination) )  : '&nbsp;',
       
   279     );
       
   280     $row = array('data' => $data);
       
   281     if (isset($form[$key]['#attributes'])) {
       
   282       $row = array_merge($row, $form[$key]['#attributes']);
       
   283     }
       
   284     $row['class'][] = 'draggable';
       
   285     $rows[] = $row;
       
   286   }
       
   287 
       
   288   return theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'book-outline'), 'empty' => t('No book content available.')));
       
   289 }