diff --git a/core/modules/book/book.module b/core/modules/book/book.module index cdc87b6..9de8912 100644 --- a/core/modules/book/book.module +++ b/core/modules/book/book.module @@ -417,102 +417,6 @@ function book_form_update($form, $form_state) { } /** - * Handles additions and updates to the book outline. - * - * This common helper function performs all additions and updates to the book - * outline through node addition, node editing, node deletion, or the outline - * tab. - * - * @param \Drupal\Core\Entity\EntityInterface $node - * The node that is being saved, added, deleted, or moved. - * - * @return - * TRUE if the menu link was saved; FALSE otherwise. - */ -function _book_update_outline(EntityInterface $node) { - if (empty($node->book['bid'])) { - return FALSE; - } - $new = empty($node->book['mlid']); - - $node->book['link_path'] = 'node/' . $node->id(); - $node->book['link_title'] = $node->label(); - $node->book['parent_mismatch'] = FALSE; // The normal case. - - if ($node->book['bid'] == $node->id()) { - $node->book['plid'] = 0; - $node->book['menu_name'] = book_menu_name($node->id()); - } - else { - // Check in case the parent is not is this book; the book takes precedence. - if (!empty($node->book['plid'])) { - $parent = db_query("SELECT * FROM {book} WHERE mlid = :mlid", array( - ':mlid' => $node->book['plid'], - ))->fetchAssoc(); - } - if (empty($node->book['plid']) || !$parent || $parent['bid'] != $node->book['bid']) { - $node->book['plid'] = db_query("SELECT mlid FROM {book} WHERE nid = :nid", array( - ':nid' => $node->book['bid'], - ))->fetchField(); - $node->book['parent_mismatch'] = TRUE; // Likely when JS is disabled. - } - } - - $node->book = entity_create('menu_link', $node->book); - if ($node->book->save()) { - if ($new) { - // Insert new. - db_insert('book') - ->fields(array( - 'nid' => $node->id(), - 'mlid' => $node->book['mlid'], - 'bid' => $node->book['bid'], - )) - ->execute(); - // Reset the cache of stored books. - drupal_static_reset('book_get_books'); - } - else { - if ($node->book['bid'] != db_query("SELECT bid FROM {book} WHERE nid = :nid", array( - ':nid' => $node->id(), - ))->fetchField()) { - // Update the bid for this page and all children. - book_update_bid($node->book); - // Reset the cache of stored books. - drupal_static_reset('book_get_books'); - } - } - - return TRUE; - } - - // Failed to save the menu link. - return FALSE; -} - -/** - * Updates the book ID of a page and its children when it moves to a new book. - * - * @param $book_link - * A fully loaded menu link that is part of the book hierarchy. - */ -function book_update_bid($book_link) { - $query = db_select('menu_links'); - $query->addField('menu_links', 'mlid'); - for ($i = 1; $i <= MENU_MAX_DEPTH && $book_link["p$i"]; $i++) { - $query->condition("p$i", $book_link["p$i"]); - } - $mlids = $query->execute()->fetchCol(); - - if ($mlids) { - db_update('book') - ->fields(array('bid' => $book_link['bid'])) - ->condition('mlid', $mlids, 'IN') - ->execute(); - } -} - -/** * Gets the book menu tree for a page and returns it as a linear array. * * @param $book_link @@ -660,19 +564,6 @@ function book_children($book_link) { } /** - * Generates the corresponding menu name from a book ID. - * - * @param $bid - * The book ID for which to make a menu name. - * - * @return - * The menu name. - */ -function book_menu_name($bid) { - return 'book-toc-' . $bid; -} - -/** * Implements hook_node_load(). */ function book_node_load($nodes, $types) { @@ -741,14 +632,15 @@ function book_node_presave(EntityInterface $node) { * Implements hook_node_insert(). */ function book_node_insert(EntityInterface $node) { + $book_manager = Drupal::service('book.manager'); if (!empty($node->book['bid'])) { if ($node->book['bid'] == 'new') { // New nodes that are their own book. $node->book['bid'] = $node->id(); } $node->book['nid'] = $node->id(); - $node->book['menu_name'] = book_menu_name($node->book['bid']); - _book_update_outline($node); + $node->book['menu_name'] = $book_manager->createMenuName($node->book['bid']); + $book_manager->updateOutline($node); } } @@ -756,14 +648,15 @@ function book_node_insert(EntityInterface $node) { * Implements hook_node_update(). */ function book_node_update(EntityInterface $node) { + $book_manager = Drupal::service('book.manager'); if (!empty($node->book['bid'])) { if ($node->book['bid'] == 'new') { // New nodes that are their own book. $node->book['bid'] = $node->id(); } $node->book['nid'] = $node->id(); - $node->book['menu_name'] = book_menu_name($node->book['bid']); - _book_update_outline($node); + $node->book['menu_name'] = $book_manager->createMenuName($node->book['bid']); + $book->manager->updateOutline($node); } } @@ -780,7 +673,7 @@ function book_node_predelete(EntityInterface $node) { foreach ($result as $child) { $child_node = node_load($child->id()); $child_node->book['bid'] = $child_node->id(); - _book_update_outline($child_node); + Drupal::service('book.manager')->updateOutline($child_node); } } menu_link_delete($node->book['mlid']); @@ -993,7 +886,7 @@ function _book_toc_recurse($tree, $indent, &$toc, $exclude, $depth_limit) { * book page. */ function book_toc($bid, $depth_limit, $exclude = array()) { - $tree = menu_tree_all_data(book_menu_name($bid)); + $tree = menu_tree_all_data(Drupal::service('book.manager')->createMenuName($bid)); $toc = array(); _book_toc_recurse($tree, '', $toc, $exclude, $depth_limit); diff --git a/core/modules/book/lib/Drupal/book/BookManager.php b/core/modules/book/lib/Drupal/book/BookManager.php index 32b5916..6840a08 100644 --- a/core/modules/book/lib/Drupal/book/BookManager.php +++ b/core/modules/book/lib/Drupal/book/BookManager.php @@ -267,8 +267,66 @@ public function nodeIsRemovable(NodeInterface $node) { * @return bool * TRUE if the menu link was saved; FALSE otherwise. */ - public function updateBookOutline(NodeInterface $node) { - return _book_update_outline($node); + public function updateOutline(NodeInterface $node) { + if (empty($node->book['bid'])) { + return FALSE; + } + $new = empty($node->book['mlid']); + + $node->book['link_path'] = 'node/' . $node->id(); + $node->book['link_title'] = $node->label(); + $node->book['parent_mismatch'] = FALSE; // The normal case. + + if ($node->book['bid'] == $node->id()) { + $node->book['plid'] = 0; + $node->book['menu_name'] = $this->createMenuName($node->id()); + } + else { + // Check in case the parent is not is this book; the book takes precedence. + if (!empty($node->book['plid'])) { + $parent = $database->query("SELECT * FROM {book} WHERE mlid = :mlid", array( + ':mlid' => $node->book['plid'], + ))->fetchAssoc(); + } + if (empty($node->book['plid']) || !$parent || $parent['bid'] != $node->book['bid']) { + $node->book['plid'] = $database->query("SELECT mlid FROM {book} WHERE nid = :nid", array( + ':nid' => $node->book['bid'], + ))->fetchField(); + $node->book['parent_mismatch'] = TRUE; // Likely when JS is disabled. + } + } + + $node->book = $this->entityManager + ->getStorageController('menu_link')->create($node->book); + if ($node->book->save()) { + if ($new) { + // Insert new. + $database->insert('book') + ->fields(array( + 'nid' => $node->id(), + 'mlid' => $node->book['mlid'], + 'bid' => $node->book['bid'], + )) + ->execute(); + // Reset the cache of stored books. + drupal_static_reset('book_get_books'); + } + else { + if ($node->book['bid'] != $database->query("SELECT bid FROM {book} WHERE nid = :nid", array( + ':nid' => $node->id(), + ))->fetchField()) { + // Update the bid for this page and all children. + $this->updateID($node->book); + // Reset the cache of stored books. + drupal_static_reset('book_get_books'); + } + } + + return TRUE; + } + + // Failed to save the menu link. + return FALSE; } /** @@ -293,4 +351,40 @@ protected function t($string, array $args = array(), array $options = array()) { return $this->translation->translate($string, $args, $options); } + + /** + * Generates the corresponding menu name from a book ID. + * + * @param $id + * The book ID for which to make a menu name. + * + * @return + * The menu name. + */ + public function createMenuName($id) { + return 'book-toc-' . $id; + } + + /** + * Updates the book ID of a page and its children when it moves to a new book. + * + * @param $book_link + * A fully loaded menu link that is part of the book hierarchy. + */ + function updateID($book_link) { + $query = $database->select('menu_links'); + $query->addField('menu_links', 'mlid'); + for ($i = 1; $i <= MENU_MAX_DEPTH && $book_link["p$i"]; $i++) { + $query->condition("p$i", $book_link["p$i"]); + } + $mlids = $query->execute()->fetchCol(); + + if ($mlids) { + $database->update('book') + ->fields(array('bid' => $book_link['bid'])) + ->condition('mlid', $mlids, 'IN') + ->execute(); + } + } + } diff --git a/core/modules/book/lib/Drupal/book/Form/BookOutlineForm.php b/core/modules/book/lib/Drupal/book/Form/BookOutlineForm.php index a1092db..b60ef0f 100644 --- a/core/modules/book/lib/Drupal/book/Form/BookOutlineForm.php +++ b/core/modules/book/lib/Drupal/book/Form/BookOutlineForm.php @@ -101,9 +101,9 @@ public function submit(array $form, array &$form_state) { return; } - $book_link['menu_name'] = book_menu_name($book_link['bid']); + $book_link['menu_name'] = $this->bookManager->createMenuName($book_link['bid']); $this->entity->book = $book_link; - if ($this->bookManager->updateBookOutline($this->entity)) { + if ($this->bookManager->updateOutline($this->entity)) { if ($this->entity->book['parent_mismatch']) { // This will usually only happen when JS is disabled. drupal_set_message($this->t('The post has been added to the selected book. You may now position it relative to other pages.'));