From e85f89c3ccc8c521b0d9889bbb45e6d47c22adc3 Mon Sep 17 00:00:00 2001 From: Dries <dries@buytaert.net> Date: Thu, 11 Jul 2013 22:04:19 -0400 Subject: [PATCH] Issue #1946434 by tim.plunkett: Convert all of confirm_form() in node.admin.inc and node.pages.inc to the new form interface. --- .../node/Access/NodeRevisionAccessCheck.php | 158 ++++++++++++++++++ .../lib/Drupal/node/Form/NodeDeleteForm.php | 106 ++++++++++++ .../node/Form/NodeRevisionDeleteForm.php | 130 ++++++++++++++ .../node/Form/NodeRevisionRevertForm.php | 119 +++++++++++++ .../node/Form/RebuildPermissionsForm.php | 57 +++++++ .../Drupal/node/Plugin/Core/Entity/Node.php | 1 + core/modules/node/node.admin.inc | 23 --- core/modules/node/node.module | 88 +--------- core/modules/node/node.pages.inc | 115 ------------- core/modules/node/node.routing.yml | 28 ++++ core/modules/node/node.services.yml | 5 + 11 files changed, 608 insertions(+), 222 deletions(-) create mode 100644 core/modules/node/lib/Drupal/node/Access/NodeRevisionAccessCheck.php create mode 100644 core/modules/node/lib/Drupal/node/Form/NodeDeleteForm.php create mode 100644 core/modules/node/lib/Drupal/node/Form/NodeRevisionDeleteForm.php create mode 100644 core/modules/node/lib/Drupal/node/Form/NodeRevisionRevertForm.php create mode 100644 core/modules/node/lib/Drupal/node/Form/RebuildPermissionsForm.php diff --git a/core/modules/node/lib/Drupal/node/Access/NodeRevisionAccessCheck.php b/core/modules/node/lib/Drupal/node/Access/NodeRevisionAccessCheck.php new file mode 100644 index 000000000000..aca491d7bdbe --- /dev/null +++ b/core/modules/node/lib/Drupal/node/Access/NodeRevisionAccessCheck.php @@ -0,0 +1,158 @@ +<?php + +/** + * @file + * Contains \Drupal\node\Access\NodeRevisionAccessCheck. + */ + +namespace Drupal\node\Access; + +use Drupal\Core\Access\AccessCheckInterface; +use Drupal\Core\Database\Connection; +use Drupal\Core\Entity\EntityManager; +use Drupal\Core\Session\AccountInterface; +use Drupal\node\NodeInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Routing\Route; + +/** + * Provides an access checker for node revisions. + */ +class NodeRevisionAccessCheck implements AccessCheckInterface { + + /** + * The node storage. + * + * @var \Drupal\Core\Entity\EntityStorageControllerInterface + */ + protected $nodeStorage; + + /** + * The node access controller. + * + * @var \Drupal\Core\Entity\EntityAccessControllerInterface + */ + protected $nodeAccess; + + /** + * The database connection. + * + * @var \Drupal\Core\Database\Connection + */ + protected $connection; + + /** + * A static cache of access checks. + * + * @var array + */ + protected $access = array(); + + /** + * Constructs a new NodeRevisionAccessCheck. + * + * @param \Drupal\Core\Entity\EntityManager $entity_manager + * The entity manager. + * @param \Drupal\Core\Database\Connection $connection + * The database connection. + */ + public function __construct(EntityManager $entity_manager, Connection $connection) { + $this->nodeStorage = $entity_manager->getStorageController('node'); + $this->nodeAccess = $entity_manager->getAccessController('node'); + $this->connection = $connection; + } + + /** + * {@inheritdoc} + */ + public function applies(Route $route) { + return array_key_exists('_access_node_revision', $route->getRequirements()); + } + + /** + * {@inheritdoc} + */ + public function access(Route $route, Request $request) { + $revision = $this->nodeStorage->loadRevision($request->attributes->get('node_revision')); + return $this->checkAccess($revision, $route->getRequirement('_access_node_revision')) ? static::ALLOW : static::DENY; + } + + /** + * Checks node revision access. + * + * @param \Drupal\node\NodeInterface $node + * The node to check. + * @param string $op + * (optional) The specific operation being checked. Defaults to 'view.' + * @param \Drupal\Core\Session\AccountInterface|null $account + * (optional) A user object representing the user for whom the operation is + * to be performed. Determines access for a user other than the current user. + * Defaults to NULL. + * @param string|null $langcode + * (optional) Language code for the variant of the node. Different language + * variants might have different permissions associated. If NULL, the + * original langcode of the node is used. Defaults to NULL. + * + * @return bool + * TRUE if the operation may be performed, FALSE otherwise. + */ + public function checkAccess(NodeInterface $node, $op = 'view', AccountInterface $account = NULL, $langcode = NULL) { + $map = array( + 'view' => 'view all revisions', + 'update' => 'revert all revisions', + 'delete' => 'delete all revisions', + ); + $bundle = $node->bundle(); + $type_map = array( + 'view' => "view $bundle revisions", + 'update' => "revert $bundle revisions", + 'delete' => "delete $bundle revisions", + ); + + if (!$node || !isset($map[$op]) || !isset($type_map[$op])) { + // If there was no node to check against, or the $op was not one of the + // supported ones, we return access denied. + return FALSE; + } + + if (!isset($account)) { + $account = $GLOBALS['user']; + } + + // If no language code was provided, default to the node revision's langcode. + if (empty($langcode)) { + $langcode = $node->language()->id; + } + + // Statically cache access by revision ID, language code, user account ID, + // and operation. + $cid = $node->getRevisionId() . ':' . $langcode . ':' . $account->id() . ':' . $op; + + if (!isset($this->access[$cid])) { + // Perform basic permission checks first. + if (!user_access($map[$op], $account) && !user_access($type_map[$op], $account) && !user_access('administer nodes', $account)) { + return $this->access[$cid] = FALSE; + } + + // There should be at least two revisions. If the vid of the given node + // and the vid of the default revision differ, then we already have two + // different revisions so there is no need for a separate database check. + // Also, if you try to revert to or delete the default revision, that's + // not good. + if ($node->isDefaultRevision() && ($this->connection->query('SELECT COUNT(*) FROM {node_field_revision} WHERE nid = :nid AND default_langcode = 1', array(':nid' => $node->id()))->fetchField() == 1 || $op == 'update' || $op == 'delete')) { + $this->access[$cid] = FALSE; + } + elseif (user_access('administer nodes', $account)) { + $this->access[$cid] = TRUE; + } + else { + // First check the access to the default revision and finally, if the + // node passed in is not the default revision then access to that, too. + $this->access[$cid] = $this->nodeAccess->access($this->nodeStorage->load($node->id()), $op, $langcode, $account) && ($node->isDefaultRevision() || $this->nodeAccess->access($node, $op, $langcode, $account)); + } + } + + return $this->access[$cid]; + } + +} diff --git a/core/modules/node/lib/Drupal/node/Form/NodeDeleteForm.php b/core/modules/node/lib/Drupal/node/Form/NodeDeleteForm.php new file mode 100644 index 000000000000..5a3fdb040400 --- /dev/null +++ b/core/modules/node/lib/Drupal/node/Form/NodeDeleteForm.php @@ -0,0 +1,106 @@ +<?php + +/** + * @file + * Contains \Drupal\node\Form\NodeDeleteForm. + */ + +namespace Drupal\node\Form; + +use Drupal\Core\Entity\EntityControllerInterface; +use Drupal\Core\Entity\EntityNGConfirmFormBase; +use Drupal\Core\Entity\EntityStorageControllerInterface; +use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Routing\PathBasedGeneratorInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; + +/** + * Provides a form for deleting a node. + */ +class NodeDeleteForm extends EntityNGConfirmFormBase implements EntityControllerInterface { + + /** + * The URL generator. + * + * @var \Drupal\Core\Routing\PathBasedGeneratorInterface + */ + protected $urlGenerator; + + /** + * The node type storage. + * + * @var \Drupal\Core\Entity\EntityStorageControllerInterface + */ + protected $nodeTypeStorage; + + /** + * Constructs a NodeDeleteForm object. + * + * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler + * The module handler service. + * @param \Drupal\Core\Routing\PathBasedGeneratorInterface $url_generator + * The URL generator. + * @param \Drupal\Core\Entity\EntityStorageControllerInterface $node_type_storage + * The node type storage. + */ + public function __construct(ModuleHandlerInterface $module_handler, PathBasedGeneratorInterface $url_generator, EntityStorageControllerInterface $node_type_storage) { + parent::__construct($module_handler); + + $this->urlGenerator = $url_generator; + $this->nodeTypeStorage = $node_type_storage; + } + + /** + * {@inheritdoc} + */ + public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info) { + return new static( + $container->get('module_handler'), + $container->get('url_generator'), + $container->get('plugin.manager.entity')->getStorageController('node_type') + ); + } + + /** + * {@inheritdoc} + */ + public function getQuestion() { + return t('Are you sure you want to delete %title?', array('%title' => $this->entity->label())); + } + + /** + * {@inheritdoc} + */ + public function getCancelPath() { + $uri = $this->entity->uri(); + return $this->urlGenerator->generateFromPath($uri['path'], $uri['options']); + } + + /** + * {@inheritdoc} + */ + public function getConfirmText() { + return t('Delete'); + } + + /** + * {@inheritdoc} + */ + public function form(array $form, array &$form_state) { + // Do not attach fields to the delete form. + return $form; + } + + /** + * {@inheritdoc} + */ + public function submit(array $form, array &$form_state) { + $this->entity->delete(); + watchdog('content', '@type: deleted %title.', array('@type' => $this->entity->bundle(), '%title' => $this->entity->label())); + $node_type = $this->nodeTypeStorage->load($this->entity->bundle())->label(); + drupal_set_message(t('@type %title has been deleted.', array('@type' => $node_type, '%title' => $this->entity->label()))); + $form_state['redirect'] = '<front>'; + } + +} diff --git a/core/modules/node/lib/Drupal/node/Form/NodeRevisionDeleteForm.php b/core/modules/node/lib/Drupal/node/Form/NodeRevisionDeleteForm.php new file mode 100644 index 000000000000..8c06d4995d6b --- /dev/null +++ b/core/modules/node/lib/Drupal/node/Form/NodeRevisionDeleteForm.php @@ -0,0 +1,130 @@ +<?php + +/** + * @file + * Contains \Drupal\node\Form\NodeRevisionDeleteForm. + */ + +namespace Drupal\node\Form; + +use Drupal\Core\Controller\ControllerInterface; +use Drupal\Core\Database\Connection; +use Drupal\Core\Entity\EntityStorageControllerInterface; +use Drupal\Core\Form\ConfirmFormBase; +use Drupal\node\NodeInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpFoundation\Request; + +/** + * Provides a form for reverting a node revision. + */ +class NodeRevisionDeleteForm extends ConfirmFormBase implements ControllerInterface { + + /** + * The node revision. + * + * @var \Drupal\node\NodeInterface + */ + protected $revision; + + /** + * The node storage. + * + * @var \Drupal\Core\Entity\EntityStorageControllerInterface + */ + protected $nodeStorage; + + /** + * The node type storage. + * + * @var \Drupal\Core\Entity\EntityStorageControllerInterface + */ + protected $nodeTypeStorage; + + /** + * The database connection. + * + * @var \Drupal\Core\Database\Connection + */ + protected $connection; + + /** + * Constructs a new NodeRevisionDeleteForm. + * + * @param \Drupal\Core\Entity\EntityStorageControllerInterface $node_storage + * The node storage. + * @param \Drupal\Core\Entity\EntityStorageControllerInterface $node_type_storage + * The node type storage. + * @param \Drupal\Core\Database\Connection $connection + * The database connection. + */ + public function __construct(EntityStorageControllerInterface $node_storage, EntityStorageControllerInterface $node_type_storage, Connection $connection) { + $this->nodeStorage = $node_storage; + $this->nodeTypeStorage = $node_type_storage; + $this->connection = $connection; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + $entity_manager = $container->get('plugin.manager.entity'); + return new static( + $entity_manager->getStorageController('node'), + $entity_manager->getStorageController('node_type'), + $container->get('database') + ); + } + + /** + * {@inheritdoc} + */ + public function getFormID() { + return 'node_revision_delete_confirm'; + } + + /** + * {@inheritdoc} + */ + public function getQuestion() { + return t('Are you sure you want to delete the revision from %revision-date?', array('%revision-date' => format_date($this->revision->getRevisionCreationTime()))); + } + + /** + * {@inheritdoc} + */ + public function getCancelPath() { + return 'node/' . $this->revision->id() . '/revisions'; + } + + /** + * {@inheritdoc} + */ + public function getConfirmText() { + return t('Delete'); + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, array &$form_state, Request $request = NULL, $node_revision = NULL) { + $this->revision = $this->nodeStorage->loadRevision($node_revision); + return parent::buildForm($form, $form_state, $request); + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, array &$form_state) { + $this->nodeStorage->deleteRevision($this->revision->getRevisionId()); + + watchdog('content', '@type: deleted %title revision %revision.', array('@type' => $this->revision->bundle(), '%title' => $this->revision->label(), '%revision' => $this->revision->getRevisionId())); + $node_type = $this->nodeTypeStorage->load($this->revision->bundle())->label(); + drupal_set_message(t('Revision from %revision-date of @type %title has been deleted.', array('%revision-date' => format_date($this->revision->getRevisionCreationTime()), '@type' => $node_type, '%title' => $this->revision->label()))); + $form_state['redirect'] = 'node/' . $this->revision->id(); + if ($this->connection->query('SELECT COUNT(DISTINCT vid) FROM {node_field_revision} WHERE nid = :nid', array(':nid' => $this->revision->id()))->fetchField() > 1) { + $form_state['redirect'] .= '/revisions'; + } + } + +} diff --git a/core/modules/node/lib/Drupal/node/Form/NodeRevisionRevertForm.php b/core/modules/node/lib/Drupal/node/Form/NodeRevisionRevertForm.php new file mode 100644 index 000000000000..d4c69ec9e276 --- /dev/null +++ b/core/modules/node/lib/Drupal/node/Form/NodeRevisionRevertForm.php @@ -0,0 +1,119 @@ +<?php + +/** + * @file + * Contains \Drupal\node\Form\NodeRevisionDeleteForm. + */ + +namespace Drupal\node\Form; + +use Drupal\Core\Controller\ControllerInterface; +use Drupal\Core\Entity\EntityStorageControllerInterface; +use Drupal\Core\Form\ConfirmFormBase; +use Drupal\node\NodeInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpFoundation\Request; + +/** + * Provides a form for reverting a node revision. + */ +class NodeRevisionRevertForm extends ConfirmFormBase implements ControllerInterface { + + /** + * The node revision. + * + * @var \Drupal\node\NodeInterface + */ + protected $revision; + + /** + * The node storage. + * + * @var \Drupal\Core\Entity\EntityStorageControllerInterface + */ + protected $nodeStorage; + + /** + * Constructs a new NodeRevisionRevertForm. + * + * @param \Drupal\Core\Entity\EntityStorageControllerInterface $node_storage + * The node storage. + */ + public function __construct(EntityStorageControllerInterface $node_storage) { + $this->nodeStorage = $node_storage; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('plugin.manager.entity')->getStorageController('node') + ); + } + + /** + * {@inheritdoc} + */ + public function getFormID() { + return 'node_revision_revert_confirm'; + } + + /** + * {@inheritdoc} + */ + public function getQuestion() { + return t('Are you sure you want to revert to the revision from %revision-date?', array('%revision-date' => format_date($this->revision->getRevisionCreationTime()))); + } + + /** + * {@inheritdoc} + */ + public function getCancelPath() { + return 'node/' . $this->revision->id() . '/revisions'; + } + + /** + * {@inheritdoc} + */ + public function getConfirmText() { + return t('Revert'); + } + + /** + * {@inheritdoc} + */ + public function getDescription() { + return ''; + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, array &$form_state, Request $request = NULL, $node_revision = NULL) { + $this->revision = $this->nodeStorage->loadRevision($node_revision); + return parent::buildForm($form, $form_state, $request); + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, array &$form_state) { + $this->revision->setNewRevision(); + // Make this the new default revision for the node. + $this->revision->isDefaultRevision(TRUE); + + // The revision timestamp will be updated when the revision is saved. Keep the + // original one for the confirmation message. + $original_revision_timestamp = $this->revision->getRevisionCreationTime(); + + $this->revision->log = t('Copy of the revision from %date.', array('%date' => format_date($original_revision_timestamp))); + + $this->revision->save(); + + watchdog('content', '@type: reverted %title revision %revision.', array('@type' => $this->revision->bundle(), '%title' => $this->revision->label(), '%revision' => $this->revision->getRevisionId())); + drupal_set_message(t('@type %title has been reverted back to the revision from %revision-date.', array('@type' => node_get_type_label($this->revision), '%title' => $this->revision->label(), '%revision-date' => format_date($original_revision_timestamp)))); + $form_state['redirect'] = 'node/' . $this->revision->id() . '/revisions'; + } + +} diff --git a/core/modules/node/lib/Drupal/node/Form/RebuildPermissionsForm.php b/core/modules/node/lib/Drupal/node/Form/RebuildPermissionsForm.php new file mode 100644 index 000000000000..d104fab287eb --- /dev/null +++ b/core/modules/node/lib/Drupal/node/Form/RebuildPermissionsForm.php @@ -0,0 +1,57 @@ +<?php + +/** + * @file + * Contains \Drupal\node\Form\RebuildPermissionsForm. + */ + +namespace Drupal\node\Form; + +use Drupal\Core\Form\ConfirmFormBase; + +class RebuildPermissionsForm extends ConfirmFormBase { + + /** + * {@inheritdoc} + */ + public function getFormID() { + return 'node_configure_rebuild_confirm'; + } + + /** + * {@inheritdoc} + */ + public function getQuestion() { + return t('Are you sure you want to rebuild the permissions on site content?'); + } + + /** + * {@inheritdoc} + */ + public function getCancelPath() { + return 'admin/reports/status'; + } + + /** + * {@inheritdoc} + */ + public function getConfirmText() { + return t('Rebuild permissions'); + } + + /** + * {@inheritdoc} + */ + public function getDescription() { + return t('This action rebuilds all permissions on site content, and may be a lengthy process. This action cannot be undone.'); + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, array &$form_state) { + node_access_rebuild(TRUE); + $form_state['redirect'] = 'admin/reports/status'; + } + +} diff --git a/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php b/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php index 82023196512d..01a35350b1e1 100644 --- a/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php +++ b/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php @@ -28,6 +28,7 @@ * "access" = "Drupal\node\NodeAccessController", * "form" = { * "default" = "Drupal\node\NodeFormController", + * "delete" = "Drupal\node\Form\NodeDeleteForm", * "edit" = "Drupal\node\NodeFormController" * }, * "translation" = "Drupal\node\NodeTranslationController" diff --git a/core/modules/node/node.admin.inc b/core/modules/node/node.admin.inc index eeec22becc68..3a30fafcb62f 100644 --- a/core/modules/node/node.admin.inc +++ b/core/modules/node/node.admin.inc @@ -8,29 +8,6 @@ use Drupal\Core\Language\Language; use Drupal\node\NodeInterface; -/** - * Page callback: Form constructor for the permission rebuild confirmation form. - * - * @return array - * An array as expected by drupal_render(). - * - * @see node_configure_rebuild_confirm_submit() - * @see node_menu() - * @ingroup forms - */ -function node_configure_rebuild_confirm() { - return confirm_form(array(), t('Are you sure you want to rebuild the permissions on site content?'), - 'admin/reports/status', t('This action rebuilds all permissions on site content, and may be a lengthy process. This action cannot be undone.'), t('Rebuild permissions'), t('Cancel')); -} - -/** - * Form submission handler for node_configure_rebuild_confirm(). - */ -function node_configure_rebuild_confirm_submit($form, &$form_state) { - node_access_rebuild(TRUE); - $form_state['redirect'] = 'admin/reports/status'; -} - /** * Updates all nodes in the passed-in array with the passed-in field values. * diff --git a/core/modules/node/node.module b/core/modules/node/node.module index e83670076273..293c64e4af2a 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -1116,64 +1116,7 @@ function theme_node_search_admin($variables) { * @see node_menu() */ function _node_revision_access(EntityInterface $node, $op = 'view', $account = NULL, $langcode = NULL) { - $access = &drupal_static(__FUNCTION__, array()); - - $map = array( - 'view' => 'view all revisions', - 'update' => 'revert all revisions', - 'delete' => 'delete all revisions', - ); - $bundle = $node->bundle(); - $type_map = array( - 'view' => "view $bundle revisions", - 'update' => "revert $bundle revisions", - 'delete' => "delete $bundle revisions", - ); - - if (!$node || !isset($map[$op]) || !isset($type_map[$op])) { - // If there was no node to check against, or the $op was not one of the - // supported ones, we return access denied. - return FALSE; - } - - if (!isset($account)) { - $account = $GLOBALS['user']; - } - - // If no language code was provided, default to the node revision's langcode. - if (empty($langcode)) { - $langcode = $node->language()->id; - } - - // Statically cache access by revision ID, language code, user account ID, - // and operation. - $cid = $node->getRevisionId() . ':' . $langcode . ':' . $account->id() . ':' . $op; - - if (!isset($access[$cid])) { - // Perform basic permission checks first. - if (!user_access($map[$op], $account) && !user_access($type_map[$op], $account) && !user_access('administer nodes', $account)) { - return $access[$cid] = FALSE; - } - - // There should be at least two revisions. If the vid of the given node - // and the vid of the default revision differ, then we already have two - // different revisions so there is no need for a separate database check. - // Also, if you try to revert to or delete the default revision, that's - // not good. - if ($node->isDefaultRevision() && (db_query('SELECT COUNT(*) FROM {node_field_revision} WHERE nid = :nid AND default_langcode = 1', array(':nid' => $node->id()))->fetchField() == 1 || $op == 'update' || $op == 'delete')) { - $access[$cid] = FALSE; - } - elseif (user_access('administer nodes', $account)) { - $access[$cid] = TRUE; - } - else { - // First check the access to the default revision and finally, if the - // node passed in is not the default revision then access to that, too. - $access[$cid] = node_access($op, node_load($node->id()), $account, $langcode) && ($node->isDefaultRevision() || node_access($op, $node, $account, $langcode)); - } - } - - return $access[$cid]; + return Drupal::service('access_check.node.revision')->checkAccess($node, $op, $account, $langcode); } /** @@ -1217,17 +1160,6 @@ function node_menu() { 'type' => MENU_DEFAULT_LOCAL_TASK, ); - $items['admin/reports/status/rebuild'] = array( - 'title' => 'Rebuild permissions', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('node_configure_rebuild_confirm'), - // Any user than can potentially trigger a node_access_needs_rebuild(TRUE) - // has to be allowed access to the 'node access rebuild' confirm form. - 'access arguments' => array('access administration pages'), - 'type' => MENU_CALLBACK, - 'file' => 'node.admin.inc', - ); - $items['admin/structure/types'] = array( 'title' => 'Content types', 'description' => 'Manage content types, including default status, front page promotion, comment settings, etc.', @@ -1295,14 +1227,10 @@ function node_menu() { ); $items['node/%node/delete'] = array( 'title' => 'Delete', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('node_delete_confirm', 1), - 'access callback' => 'node_access', - 'access arguments' => array('delete', 1), + 'route_name' => 'node_delete_confirm', 'weight' => 10, 'type' => MENU_LOCAL_TASK, 'context' => MENU_CONTEXT_INLINE, - 'file' => 'node.pages.inc', ); $items['node/%node/revisions'] = array( 'title' => 'Revisions', @@ -1323,19 +1251,11 @@ function node_menu() { ); $items['node/%node/revisions/%node_revision/revert'] = array( 'title' => 'Revert to earlier revision', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('node_revision_revert_confirm', 3), - 'access callback' => '_node_revision_access', - 'access arguments' => array(3, 'update'), - 'file' => 'node.pages.inc', + 'route_name' => 'node_revision_revert_confirm', ); $items['node/%node/revisions/%node_revision/delete'] = array( 'title' => 'Delete earlier revision', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('node_revision_delete_confirm', 3), - 'access callback' => '_node_revision_access', - 'access arguments' => array(3, 'delete'), - 'file' => 'node.pages.inc', + 'route_name' => 'node_revision_delete_confirm', ); return $items; } diff --git a/core/modules/node/node.pages.inc b/core/modules/node/node.pages.inc index 0532aa2592c0..7dff75d1e518 100644 --- a/core/modules/node/node.pages.inc +++ b/core/modules/node/node.pages.inc @@ -180,44 +180,6 @@ function theme_node_preview($variables) { return $output; } -/** - * Page callback: Form constructor for node deletion confirmation form. - * - * @param object $node - * A node object. - * - * @return array - * A form array. - * - * @see node_delete_confirm_submit() - * @see node_menu() - */ -function node_delete_confirm($form, &$form_state, $node) { - // Always provide entity id in the same form key as in the entity edit form. - $form['nid'] = array('#type' => 'value', '#value' => $node->nid); - return confirm_form($form, - t('Are you sure you want to delete %title?', array('%title' => $node->label())), - 'node/' . $node->nid, - t('This action cannot be undone.'), - t('Delete'), - t('Cancel') - ); -} - -/** - * Form submission handler for node_delete_confirm(). - */ -function node_delete_confirm_submit($form, &$form_state) { - if ($form_state['values']['confirm']) { - $node = node_load($form_state['values']['nid']); - $node->delete(); - watchdog('content', '@type: deleted %title.', array('@type' => $node->type, '%title' => $node->label())); - drupal_set_message(t('@type %title has been deleted.', array('@type' => node_get_type_label($node), '%title' => $node->label()))); - } - - $form_state['redirect'] = '<front>'; -} - /** * Page callback: Generates an overview table of older revisions of a node. * @@ -300,80 +262,3 @@ function node_revision_overview($node) { return $build; } - -/** - * Page callback: Form constructor for the reversion confirmation form. - * - * This form prevents against CSRF attacks. - * - * @param int $node_revision - * The node revision ID. - * - * @return array - * An array as expected by drupal_render(). - * - * @see node_menu() - * @see node_revision_revert_confirm_submit() - * @ingroup forms - */ -function node_revision_revert_confirm($form, $form_state, $node_revision) { - $form['#node_revision'] = $node_revision; - return confirm_form($form, t('Are you sure you want to revert to the revision from %revision-date?', array('%revision-date' => format_date($node_revision->revision_timestamp))), 'node/' . $node_revision->nid . '/revisions', '', t('Revert'), t('Cancel')); -} - -/** - * Form submission handler for node_revision_revert_confirm(). - */ -function node_revision_revert_confirm_submit($form, &$form_state) { - $node_revision = $form['#node_revision']; - $node_revision->setNewRevision(); - // Make this the new default revision for the node. - $node_revision->isDefaultRevision(TRUE); - - // The revision timestamp will be updated when the revision is saved. Keep the - // original one for the confirmation message. - $original_revision_timestamp = $node_revision->revision_timestamp; - - $node_revision->log = t('Copy of the revision from %date.', array('%date' => format_date($original_revision_timestamp))); - - $node_revision->save(); - - watchdog('content', '@type: reverted %title revision %revision.', array('@type' => $node_revision->type, '%title' => $node_revision->label(), '%revision' => $node_revision->vid)); - drupal_set_message(t('@type %title has been reverted back to the revision from %revision-date.', array('@type' => node_get_type_label($node_revision), '%title' => $node_revision->label(), '%revision-date' => format_date($original_revision_timestamp)))); - $form_state['redirect'] = 'node/' . $node_revision->nid . '/revisions'; -} - -/** - * Page callback: Form constructor for the revision deletion confirmation form. - * - * This form prevents against CSRF attacks. - * - * @param $node_revision - * The node revision ID. - * - * @return - * An array as expected by drupal_render(). - * - * @see node_menu() - * @see node_revision_delete_confirm_submit() - * @ingroup forms - */ -function node_revision_delete_confirm($form, $form_state, $node_revision) { - $form['#node_revision'] = $node_revision; - return confirm_form($form, t('Are you sure you want to delete the revision from %revision-date?', array('%revision-date' => format_date($node_revision->revision_timestamp))), 'node/' . $node_revision->nid . '/revisions', t('This action cannot be undone.'), t('Delete'), t('Cancel')); -} - -/** - * Form submission handler for node_revision_delete_confirm(). - */ -function node_revision_delete_confirm_submit($form, &$form_state) { - $node_revision = $form['#node_revision']; - node_revision_delete($node_revision->vid); - - watchdog('content', '@type: deleted %title revision %revision.', array('@type' => $node_revision->type, '%title' => $node_revision->label(), '%revision' => $node_revision->vid)); - drupal_set_message(t('Revision from %revision-date of @type %title has been deleted.', array('%revision-date' => format_date($node_revision->revision_timestamp), '@type' => node_get_type_label($node_revision), '%title' => $node_revision->label()))); - $form_state['redirect'] = 'node/' . $node_revision->nid; - if (db_query('SELECT COUNT(DISTINCT vid) FROM {node_field_revision} WHERE nid = :nid', array(':nid' => $node_revision->nid))->fetchField() > 1) { - $form_state['redirect'] .= '/revisions'; - } -} diff --git a/core/modules/node/node.routing.yml b/core/modules/node/node.routing.yml index 9204a2b90678..dfdc0a6037fd 100644 --- a/core/modules/node/node.routing.yml +++ b/core/modules/node/node.routing.yml @@ -12,6 +12,27 @@ node_page_edit: requirements: _entity_access: 'node.update' +node_delete_confirm: + pattern: '/node/{node}/delete' + defaults: + _entity_form: 'node.delete' + requirements: + _entity_access: 'node.delete' + +node_revision_revert_confirm: + pattern: '/node/{node}/revisions/{node_revision}/revert' + defaults: + _form: '\Drupal\node\Form\NodeRevisionRevertForm' + requirements: + _access_node_revision: 'update' + +node_revision_delete_confirm: + pattern: '/node/{node}/revisions/{node_revision}/delete' + defaults: + _form: '\Drupal\node\Form\NodeRevisionDeleteForm' + requirements: + _access_node_revision: 'delete' + node_overview_types: pattern: '/admin/structure/types' defaults: @@ -47,3 +68,10 @@ node_type_delete_confirm: _entity_form: 'node_type.delete' requirements: _entity_access: 'node_type.delete' + +node_configure_rebuild_confirm: + pattern: '/admin/reports/status/rebuild' + defaults: + _form: 'Drupal\node\Form\RebuildPermissionsForm' + requirements: + _permission: 'access administration pages' diff --git a/core/modules/node/node.services.yml b/core/modules/node/node.services.yml index 6f486f77c92e..ab496171b463 100644 --- a/core/modules/node/node.services.yml +++ b/core/modules/node/node.services.yml @@ -2,3 +2,8 @@ services: node.grant_storage: class: Drupal\node\NodeGrantDatabaseStorage arguments: ['@database', '@module_handler'] + access_check.node.revision: + class: Drupal\node\Access\NodeRevisionAccessCheck + arguments: ['@plugin.manager.entity', '@database'] + tags: + - { name: access_check } -- GitLab