diff --git a/core/modules/book/book.admin.inc b/core/modules/book/book.admin.inc deleted file mode 100644 index ced19d920ca09a3f20417786ea1ab8745e5401d6..0000000000000000000000000000000000000000 --- a/core/modules/book/book.admin.inc +++ /dev/null @@ -1,100 +0,0 @@ -hasPermission('administer nodes'); - foreach (Element::children($form) as $key) { - $nid = $form[$key]['nid']['#value']; - $href = \Drupal::url('entity.node.canonical', array('node' => $nid)); - - // Add special classes to be used with tabledrag.js. - $form[$key]['pid']['#attributes']['class'] = array('book-pid'); - $form[$key]['nid']['#attributes']['class'] = array('book-nid'); - $form[$key]['weight']['#attributes']['class'] = array('book-weight'); - - $indentation = array('#theme' => 'indentation', '#size' => $form[$key]['depth']['#value'] - 2); - $data = array( - SafeMarkup::set(drupal_render($indentation) . drupal_render($form[$key]['title'])), - drupal_render($form[$key]['weight']), - SafeMarkup::set(drupal_render($form[$key]['pid']) . drupal_render($form[$key]['nid'])), - ); - $links = array(); - $links['view'] = array( - 'title' => t('View'), - 'url' => Url::fromRoute('entity.node.canonical', ['node' => $nid]), - ); - if ($access) { - $links['edit'] = array( - 'title' => t('Edit'), - 'url' => Url::fromRoute('entity.node.edit_form', ['node' => $nid]), - 'query' => $destination, - ); - $links['delete'] = array( - 'title' => t('Delete'), - 'url' => Url::fromRoute('entity.node.delete_form', ['node' => $nid]), - 'query' => $destination, - ); - } - $data[] = array( - 'data' => array( - '#type' => 'operations', - '#links' => $links, - ), - ); - $row = array('data' => $data); - if (isset($form[$key]['#attributes'])) { - $row = array_merge($row, $form[$key]['#attributes']); - } - $row['class'][] = 'draggable'; - $rows[] = $row; - } - $table = array( - '#type' => 'table', - '#header' => $header, - '#rows' => $rows, - '#attributes' => array('id' => 'book-outline'), - '#empty' => t('No book content available.'), - '#tabledrag' => array( - array( - 'action' => 'match', - 'relationship' => 'parent', - 'group' => 'book-pid', - 'subgroup' => 'book-pid', - 'source' => 'book-nid', - 'hidden' => TRUE, - 'limit' => BookManager::BOOK_MAX_DEPTH - 2, - ), - array( - 'action' => 'order', - 'relationship' => 'sibling', - 'group' => 'book-weight', - ), - ), - ); - return drupal_render($table); -} diff --git a/core/modules/book/book.module b/core/modules/book/book.module index a11f74d4928dcabe4b115375f9f3d1e92bb33830..5497a0ae5712c67084c1b3a5124e081c9f0ec4fb 100644 --- a/core/modules/book/book.module +++ b/core/modules/book/book.module @@ -68,11 +68,6 @@ function book_theme() { 'book_export_html' => array( 'variables' => array('title' => NULL, 'contents' => NULL, 'depth' => NULL), ), - 'book_admin_table' => array( - 'render element' => 'form', - 'file' => 'book.admin.inc', - 'function' => 'theme_book_admin_table', - ), 'book_all_books_block' => array( 'render element' => 'book_menus', ), diff --git a/core/modules/book/src/Form/BookAdminEditForm.php b/core/modules/book/src/Form/BookAdminEditForm.php index 2cf7a18fb9eb2ec6c458d9efa9da1ed1591884da..29fad4261403719300421650ebddd5137875500b 100644 --- a/core/modules/book/src/Form/BookAdminEditForm.php +++ b/core/modules/book/src/Form/BookAdminEditForm.php @@ -7,12 +7,14 @@ namespace Drupal\book\Form; +use Drupal\book\BookManager; use Drupal\book\BookManagerInterface; use Drupal\Component\Utility\Crypt; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; +use Drupal\Core\Url; use Drupal\node\NodeInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -107,7 +109,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $values = $form_state->getValue(array('table', $key)); // Update menu item if moved. - if ($row['pid']['#default_value'] != $values['pid'] || $row['weight']['#default_value'] != $values['weight']) { + if ($row['parent']['pid']['#default_value'] != $values['pid'] || $row['weight']['#default_value'] != $values['weight']) { $link = $this->bookManager->loadBookLink($values['nid'], FALSE); $link['weight'] = $values['weight']; $link['pid'] = $values['pid']; @@ -143,8 +145,30 @@ public function submitForm(array &$form, FormStateInterface $form_state) { */ protected function bookAdminTable(NodeInterface $node, array &$form) { $form['table'] = array( - '#theme' => 'book_admin_table', - '#tree' => TRUE, + '#type' => 'table', + '#header' => [ + $this->t('Title'), + $this->t('Weight'), + $this->t('Parent'), + $this->t('Operations'), + ], + '#empty' => $this->t('No book content available.'), + '#tabledrag' => [ + [ + 'action' => 'match', + 'relationship' => 'parent', + 'group' => 'book-pid', + 'subgroup' => 'book-pid', + 'source' => 'book-nid', + 'hidden' => TRUE, + 'limit' => BookManager::BOOK_MAX_DEPTH - 2, + ], + [ + 'action' => 'order', + 'relationship' => 'sibling', + 'group' => 'book-weight', + ], + ], ); $tree = $this->bookManager->bookSubtreeData($node->book); @@ -181,32 +205,92 @@ protected function bookAdminTableTree(array $tree, array &$form) { $count = count($tree); $delta = ($count < 30) ? 15 : intval($count / 2) + 1; + $access = \Drupal::currentUser()->hasPermission('administer nodes'); + $destination = drupal_get_destination(); + foreach ($tree as $data) { - $form['book-admin-' . $data['link']['nid']] = array( - '#item' => $data['link'], - 'depth' => array('#type' => 'value', '#value' => $data['link']['depth']), - 'title' => array( - '#type' => 'textfield', - '#default_value' => $data['link']['title'], - '#maxlength' => 255, - '#size' => 40, - ), - 'weight' => array( - '#type' => 'weight', - '#default_value' => $data['link']['weight'], - '#delta' => max($delta, abs($data['link']['weight'])), - '#title' => $this->t('Weight for @title', array('@title' => $data['link']['title'])), - '#title_display' => 'invisible', - ), - 'pid' => array( - '#type' => 'hidden', - '#default_value' => $data['link']['pid'], - ), - 'nid' => array( - '#type' => 'hidden', - '#default_value' => $data['link']['nid'], - ), - ); + $nid = $data['link']['nid']; + $id = 'book-admin-' . $nid; + + $form[$id]['#item'] = $data['link']; + $form[$id]['#nid'] = $nid; + $form[$id]['#attributes']['class'][] = 'draggable'; + $form[$id]['#weight'] = $data['link']['weight']; + + if (isset($data['link']['depth']) && $data['link']['depth'] > 2) { + $indentation = [ + '#theme' => 'indentation', + '#size' => $data['link']['depth'] - 2, + ]; + } + + $form[$id]['title'] = [ + '#prefix' => !empty($indentation) ? drupal_render($indentation) : '', + '#type' => 'textfield', + '#default_value' => $data['link']['title'], + '#maxlength' => 255, + '#size' => 40, + ]; + + $form[$id]['weight'] = [ + '#type' => 'weight', + '#default_value' => $data['link']['weight'], + '#delta' => max($delta, abs($data['link']['weight'])), + '#title' => $this->t('Weight for @title', ['@title' => $data['link']['title']]), + '#title_display' => 'invisible', + '#attributes' => [ + 'class' => ['book-weight'], + ], + ]; + + $form[$id]['parent']['nid'] = [ + '#parents' => ['table', $id, 'nid'], + '#type' => 'hidden', + '#value' => $nid, + '#attributes' => [ + 'class' => ['book-nid'], + ], + ]; + + $form[$id]['parent']['pid'] = [ + '#parents' => ['table', $id, 'pid'], + '#type' => 'hidden', + '#default_value' => $data['link']['pid'], + '#attributes' => [ + 'class' => ['book-pid'], + ], + ]; + + $form[$id]['parent']['bid'] = [ + '#parents' => ['table', $id, 'bid'], + '#type' => 'hidden', + '#default_value' => $data['link']['bid'], + '#attributes' => [ + 'class' => ['book-bid'], + ], + ]; + + $form[$id]['operations'] = [ + '#type' => 'operations', + ]; + $form[$id]['operations']['#links']['view'] = [ + 'title' => $this->t('View'), + 'url' => new Url('entity.node.canonical', ['node' => $nid]), + ]; + + if ($access) { + $form[$id]['operations']['#links']['edit'] = [ + 'title' => $this->t('Edit'), + 'url' => new Url('entity.node.edit_form', ['node' => $nid]), + 'query' => $destination, + ]; + $form[$id]['operations']['#links']['delete'] = [ + 'title' => $this->t('Delete'), + 'url' => new Url('entity.node.delete_form', ['node' => $nid]), + 'query' => $destination, + ]; + } + if ($data['below']) { $this->bookAdminTableTree($data['below'], $form); } diff --git a/core/modules/book/src/Tests/BookTest.php b/core/modules/book/src/Tests/BookTest.php index 2e0d95cc489ee89fd50644e8c4400d1046a1f570..330687d4c30eff0be8c2518fc83f2cbd4a146c3e 100644 --- a/core/modules/book/src/Tests/BookTest.php +++ b/core/modules/book/src/Tests/BookTest.php @@ -672,6 +672,23 @@ public function testAdminBookListing() { $this->assertText($this->book->label(), 'The book title is displayed on the administrative book listing page.'); } + /** + * Tests the administrative listing of all book pages in a book. + */ + public function testAdminBookNodeListing() { + // Create a new book. + $this->createBook(); + $this->drupalLogin($this->adminUser); + + // Load the book page list and assert the created book title is displayed + // and action links are shown on list items. + $this->drupalGet('admin/structure/book/' . $this->book->id()); + $this->assertText($this->book->label(), 'The book title is displayed on the administrative book listing page.'); + + $elements = $this->xpath('//table//ul[@class="dropbutton"]/li/a'); + $this->assertEqual((string) $elements[0], 'View', 'View link is found from the list.'); + } + /** * Ensure the loaded book in hook_node_load() does not depend on the user. */