summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDries2013-07-12 02:04:19 (GMT)
committer Dries2013-07-12 02:04:19 (GMT)
commite85f89c3ccc8c521b0d9889bbb45e6d47c22adc3 (patch)
treef560fbc062d43efe5cbf932e4732f19ed12e99b2
parentd5b67717528c3dd30995236374b97dcd96c0547e (diff)
Issue #1946434 by tim.plunkett: Convert all of confirm_form() in node.admin.inc and node.pages.inc to the new form interface.
-rw-r--r--core/modules/node/lib/Drupal/node/Access/NodeRevisionAccessCheck.php158
-rw-r--r--core/modules/node/lib/Drupal/node/Form/NodeDeleteForm.php106
-rw-r--r--core/modules/node/lib/Drupal/node/Form/NodeRevisionDeleteForm.php130
-rw-r--r--core/modules/node/lib/Drupal/node/Form/NodeRevisionRevertForm.php119
-rw-r--r--core/modules/node/lib/Drupal/node/Form/RebuildPermissionsForm.php57
-rw-r--r--core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php1
-rw-r--r--core/modules/node/node.admin.inc23
-rw-r--r--core/modules/node/node.module88
-rw-r--r--core/modules/node/node.pages.inc115
-rw-r--r--core/modules/node/node.routing.yml28
-rw-r--r--core/modules/node/node.services.yml5
11 files changed, 608 insertions, 222 deletions
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 0000000..aca491d
--- /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 0000000..5a3fdb0
--- /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 0000000..8c06d49
--- /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 0000000..d4c69ec
--- /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 0000000..d104fab
--- /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 8202319..01a3535 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 @@ use Drupal\node\NodeBCDecorator;
* "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 eeec22b..3a30faf 100644
--- a/core/modules/node/node.admin.inc
+++ b/core/modules/node/node.admin.inc
@@ -9,29 +9,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.
*
* IMPORTANT NOTE: This function is intended to work when called from a form
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index e836700..293c64e 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 0532aa2..7dff75d 100644
--- a/core/modules/node/node.pages.inc
+++ b/core/modules/node/node.pages.inc
@@ -181,44 +181,6 @@ function theme_node_preview($variables) {
}
/**
- * 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.
*
* @param object $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 9204a2b..dfdc0a6 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 6f486f7..ab49617 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 }