Commit 29f50ae3 authored by webchick's avatar webchick

Issue #1945390 by Alan Evans, disasm, tim.plunkett, dawehner: Convert...

Issue #1945390 by Alan Evans, disasm, tim.plunkett, dawehner: Convert book_admin_edit() to a new-style FormInterface implementation.
parent b3ef2ab3
......@@ -9,188 +9,6 @@
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Language\Language;
/**
* Form constructor for administering a single book's hierarchy.
*
* @param \Drupal\Core\Entity\EntityInterface $node
* The node of the top-level page in the book.
*
* @see book_menu()
* @see book_admin_edit_validate()
* @see book_admin_edit_submit()
* @ingroup forms
*/
function book_admin_edit($form, $form_state, EntityInterface $node) {
drupal_set_title($node->label());
$form['#node'] = $node;
_book_admin_table($node, $form);
$form['save'] = array(
'#type' => 'submit',
'#value' => t('Save book pages'),
);
return $form;
}
/**
* Form validation handler for book_admin_edit().
*
* Checks that the book has not been changed while using the form.
*
* @see book_admin_edit_submit()
*/
function book_admin_edit_validate($form, &$form_state) {
if ($form_state['values']['tree_hash'] != $form_state['values']['tree_current_hash']) {
form_set_error('', t('This book has been modified by another user, the changes could not be saved.'));
}
}
/**
* Form submission handler for book_admin_edit().
*
* This function takes care to save parent menu items before their children.
* Saving menu items in the incorrect order can break the menu tree.
*
* @see book_admin_edit_validate()
* @see menu_overview_form_submit()
*/
function book_admin_edit_submit($form, &$form_state) {
// Save elements in the same order as defined in post rather than the form.
// This ensures parents are updated before their children, preventing orphans.
$order = array_flip(array_keys($form_state['input']['table']));
$form['table'] = array_merge($order, $form['table']);
// Track updates.
$updated = FALSE;
foreach (element_children($form['table']) as $key) {
if ($form['table'][$key]['#item']) {
$row = $form['table'][$key];
$values = $form_state['values']['table'][$key];
// Update menu item if moved.
if ($row['plid']['#default_value'] != $values['plid'] || $row['weight']['#default_value'] != $values['weight']) {
$menu_link = entity_load('menu_link', $values['mlid']);
$menu_link->weight = $values['weight'];
$menu_link->plid = $values['plid'];
$menu_link->save();
$updated = TRUE;
}
// Update the title if changed.
if ($row['title']['#default_value'] != $values['title']) {
$node = node_load($values['nid']);
$langcode = Language::LANGCODE_NOT_SPECIFIED;
$node->title = $values['title'];
$node->book['link_title'] = $values['title'];
$node->setNewRevision();
$node->log = t('Title changed from %original to %current.', array('%original' => $node->title, '%current' => $values['title']));
$node->save();
watchdog('content', 'book: updated %title.', array('%title' => $node->label()), WATCHDOG_NOTICE, l(t('view'), 'node/' . $node->id()));
}
}
}
if ($updated) {
// Flush static and cache.
drupal_static_reset('book_menu_subtree_data');
$cid = 'links:' . $form['#node']->book['menu_name'] . ':subtree-cid:' . $form['#node']->book['mlid'];
cache('menu')->delete($cid);
}
drupal_set_message(t('Updated book %title.', array('%title' => $form['#node']->label())));
}
/**
* Builds the table portion of the form for the book administration page.
*
* @param \Drupal\Core\Entity\EntityInterface $node
* The node of the top-level page in the book.
* @param $form
* The form that is being modified, passed by reference.
*
* @see book_admin_edit()
*/
function _book_admin_table(EntityInterface $node, &$form) {
$form['table'] = array(
'#theme' => 'book_admin_table',
'#tree' => TRUE,
);
$tree = book_menu_subtree_data($node->book);
$tree = array_shift($tree); // Do not include the book item itself.
if ($tree['below']) {
$hash = Crypt::hashBase64(serialize($tree['below']));
// Store the hash value as a hidden form element so that we can detect
// if another user changed the book hierarchy.
$form['tree_hash'] = array(
'#type' => 'hidden',
'#default_value' => $hash,
);
$form['tree_current_hash'] = array(
'#type' => 'value',
'#value' => $hash,
);
_book_admin_table_tree($tree['below'], $form['table']);
}
}
/**
* Helps build the main table in the book administration page form.
*
* @param $tree
* A subtree of the book menu hierarchy.
* @param $form
* The form that is being modified, passed by reference.
*
* @return
* The modified form array.
*
* @see book_admin_edit()
*/
function _book_admin_table_tree($tree, &$form) {
// The delta must be big enough to give each node a distinct value.
$count = count($tree);
$delta = ($count < 30) ? 15 : intval($count / 2) + 1;
foreach ($tree as $data) {
$form['book-admin-' . $data['link']['nid']] = array(
'#item' => $data['link'],
'nid' => array('#type' => 'value', '#value' => $data['link']['nid']),
'depth' => array('#type' => 'value', '#value' => $data['link']['depth']),
'href' => array('#type' => 'value', '#value' => $data['link']['href']),
'title' => array(
'#title' => t('Title'),
'#title_display' => 'invisible',
'#type' => 'textfield',
'#default_value' => $data['link']['link_title'],
'#maxlength' => 255,
'#size' => 40,
),
'weight' => array(
'#type' => 'weight',
'#default_value' => $data['link']['weight'],
'#delta' => max($delta, abs($data['link']['weight'])),
'#title' => t('Weight for @title', array('@title' => $data['link']['title'])),
'#title_display' => 'invisible',
),
'plid' => array(
'#type' => 'hidden',
'#default_value' => $data['link']['plid'],
),
'mlid' => array(
'#type' => 'hidden',
'#default_value' => $data['link']['mlid'],
),
);
if ($data['below']) {
_book_admin_table_tree($data['below'], $form);
}
}
return $form;
}
/**
* Returns HTML for a book administration form.
*
......@@ -198,7 +16,7 @@ function _book_admin_table_tree($tree, &$form) {
* An associative array containing:
* - form: A render element representing the form.
*
* @see book_admin_table()
* @see \Drupal\book\Form\BookAdminEditForm::bookAdminTable()
* @ingroup themeable
*/
function theme_book_admin_table($variables) {
......
......@@ -79,6 +79,7 @@ function book_theme() {
),
'book_admin_table' => array(
'render element' => 'form',
'file' => 'book.admin.inc',
),
'book_all_books_block' => array(
'render element' => 'book_menus',
......@@ -181,15 +182,6 @@ function book_menu() {
'type' => MENU_LOCAL_TASK,
'weight' => 100,
);
$items['admin/structure/book/%node'] = array(
'title' => 'Re-order book pages and change titles',
'page callback' => 'drupal_get_form',
'page arguments' => array('book_admin_edit', 3),
'access callback' => '_book_outline_access',
'access arguments' => array(3),
'type' => MENU_CALLBACK,
'file' => 'book.admin.inc',
);
$items['book'] = array(
'title' => 'Books',
'route_name' => 'book_render',
......
......@@ -38,3 +38,15 @@ book_outline:
requirements:
_permission: 'administer book outlines'
_entity_access: 'node.view'
book_admin_edit:
pattern: '/admin/structure/book/{node}'
defaults:
_form: 'Drupal\book\Form\BookAdminEditForm'
_title: 'Re-order book pages and change titles'
options:
_access_mode: 'ALL'
requirements:
_permission: 'administer book outlines'
_entity_access: 'node.view'
node: \d+
......@@ -196,7 +196,8 @@ public function addFormElements(array $form, array &$form_state, NodeInterface $
$form['book']['plid'] = $this->addParentSelectFormElements($node->book);
// @see _book_admin_table_tree(). The weight may be larger than 15.
// @see \Drupal\book\Form\BookAdminEditForm::bookAdminTableTree(). The
// weight may be larger than 15.
$form['book']['weight'] = array(
'#type' => 'weight',
'#title' => $this->t('Weight'),
......
<?php
/**
* @file
* Contains \Drupal\book\Form\BookAdminEditForm.
*/
namespace Drupal\book\Form;
use Drupal\Component\Utility\Crypt;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Entity\EntityStorageControllerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\menu_link\MenuLinkStorageControllerInterface;
use Drupal\node\NodeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a form for administering a single book's hierarchy.
*/
class BookAdminEditForm extends FormBase {
/**
* The menu cache object for this controller.
*
* @var \Drupal\Core\Cache\CacheBackendInterface
*/
protected $cache;
/**
* The node storage controller.
*
* @var \Drupal\Core\Entity\EntityStorageControllerInterface
*/
protected $nodeStorage;
/**
* The menu link storage controller.
*
* @var \Drupal\menu_link\MenuLinkStorageControllerInterface
*/
protected $menuLinkStorage;
/**
* Constructs a new BookAdminEditForm.
*
* @param \Drupal\Core\Cache\CacheBackendInterface $cache
* The menu cache object to be used by this controller.
* @param \Drupal\Core\Entity\EntityStorageControllerInterface $node_storage
* The custom block storage controller.
* @param \Drupal\menu_link\MenuLinkStorageControllerInterface $menu_link_storage
* The custom block type storage controller.
*/
public function __construct(CacheBackendInterface $cache, EntityStorageControllerInterface $node_storage, MenuLinkStorageControllerInterface $menu_link_storage) {
$this->cache = $cache;
$this->nodeStorage = $node_storage;
$this->menuLinkStorage = $menu_link_storage;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
$entity_manager = $container->get('entity.manager');
return new static(
$container->get('cache.menu'),
$entity_manager->getStorageController('node'),
$entity_manager->getStorageController('menu_link')
);
}
/**
* {@inheritdoc}
*/
public function getFormID() {
return 'book_admin_edit';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, array &$form_state, NodeInterface $node = NULL) {
$form['#title'] = $node->label();
$form['#node'] = $node;
$this->bookAdminTable($node, $form);
$form['save'] = array(
'#type' => 'submit',
'#value' => $this->t('Save book pages'),
);
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, array &$form_state) {
if ($form_state['values']['tree_hash'] != $form_state['values']['tree_current_hash']) {
form_set_error('', $this->t('This book has been modified by another user, the changes could not be saved.'));
}
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, array &$form_state) {
// Save elements in the same order as defined in post rather than the form.
// This ensures parents are updated before their children, preventing orphans.
$order = array_flip(array_keys($form_state['input']['table']));
$form['table'] = array_merge($order, $form['table']);
// Track updates.
$updated = FALSE;
foreach (element_children($form['table']) as $key) {
if ($form['table'][$key]['#item']) {
$row = $form['table'][$key];
$values = $form_state['values']['table'][$key];
// Update menu item if moved.
if ($row['plid']['#default_value'] != $values['plid'] || $row['weight']['#default_value'] != $values['weight']) {
$menu_link = $this->menuLinkStorage->load($values['mlid']);
$menu_link->weight = $values['weight'];
$menu_link->plid = $values['plid'];
$menu_link->save();
$updated = TRUE;
}
// Update the title if changed.
if ($row['title']['#default_value'] != $values['title']) {
$node = $this->nodeStorage->load($values['nid']);
$node->log = $this->t('Title changed from %original to %current.', array('%original' => $node->label(), '%current' => $values['title']));
$node->title = $values['title'];
$node->book['link_title'] = $values['title'];
$node->setNewRevision();
$node->save();
watchdog('content', 'book: updated %title.', array('%title' => $node->label()), WATCHDOG_NOTICE, l($this->t('view'), 'node/' . $node->id()));
}
}
}
if ($updated) {
// Flush static and cache.
drupal_static_reset('book_menu_subtree_data');
$cid = 'links:' . $form['#node']->book['menu_name'] . ':subtree-cid:' . $form['#node']->book['mlid'];
$this->cache->delete($cid);
}
drupal_set_message($this->t('Updated book %title.', array('%title' => $form['#node']->label())));
}
/**
* Builds the table portion of the form for the book administration page.
*
* @param \Drupal\node\NodeInterface $node
* The node of the top-level page in the book.
* @param array $form
* The form that is being modified, passed by reference.
*
* @see self::buildForm()
*/
protected function bookAdminTable(NodeInterface $node, array &$form) {
$form['table'] = array(
'#theme' => 'book_admin_table',
'#tree' => TRUE,
);
$tree = book_menu_subtree_data($node->book);
// Do not include the book item itself.
$tree = array_shift($tree);
if ($tree['below']) {
$hash = Crypt::hashBase64(serialize($tree['below']));
// Store the hash value as a hidden form element so that we can detect
// if another user changed the book hierarchy.
$form['tree_hash'] = array(
'#type' => 'hidden',
'#default_value' => $hash,
);
$form['tree_current_hash'] = array(
'#type' => 'value',
'#value' => $hash,
);
$this->bookAdminTableTree($tree['below'], $form['table']);
}
}
/**
* Helps build the main table in the book administration page form.
*
* @param array $tree
* A subtree of the book menu hierarchy.
* @param array $form
* The form that is being modified, passed by reference.
*
* @see self::buildForm()
*/
protected function bookAdminTableTree(array $tree, array &$form) {
// The delta must be big enough to give each node a distinct value.
$count = count($tree);
$delta = ($count < 30) ? 15 : intval($count / 2) + 1;
foreach ($tree as $data) {
$form['book-admin-' . $data['link']['nid']] = array(
'#item' => $data['link'],
'nid' => array('#type' => 'value', '#value' => $data['link']['nid']),
'depth' => array('#type' => 'value', '#value' => $data['link']['depth']),
'href' => array('#type' => 'value', '#value' => $data['link']['href']),
'title' => array(
'#type' => 'textfield',
'#default_value' => $data['link']['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',
),
'plid' => array(
'#type' => 'hidden',
'#default_value' => $data['link']['plid'],
),
'mlid' => array(
'#type' => 'hidden',
'#default_value' => $data['link']['mlid'],
),
);
if ($data['below']) {
$this->bookAdminTableTree($data['below'], $form);
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment