From 97072d8670efd9841fa9725137c82d563570d9a6 Mon Sep 17 00:00:00 2001
From: webchick <webchick@24967.no-reply.drupal.org>
Date: Fri, 24 Jan 2014 00:32:45 -0800
Subject: [PATCH] Issue #2150179 by swentel, larowlan: Delete confirm form for
 locked fields is hotlinkable.

---
 .../field/lib/Drupal/field/Entity/Field.php   |  7 ++++
 .../field/lib/Drupal/field/FieldInterface.php |  8 +++++
 core/modules/field_ui/field_ui.services.yml   |  4 +++
 .../Access/FieldDeleteAccessCheck.php         | 33 +++++++++++++++++++
 .../field_ui/Routing/RouteSubscriber.php      |  2 +-
 .../field_ui/Tests/ManageFieldsTest.php       |  2 ++
 6 files changed, 55 insertions(+), 1 deletion(-)
 create mode 100644 core/modules/field_ui/lib/Drupal/field_ui/Access/FieldDeleteAccessCheck.php

diff --git a/core/modules/field/lib/Drupal/field/Entity/Field.php b/core/modules/field/lib/Drupal/field/Entity/Field.php
index b87ee9b0a7ff..3e5a63f30689 100644
--- a/core/modules/field/lib/Drupal/field/Entity/Field.php
+++ b/core/modules/field/lib/Drupal/field/Entity/Field.php
@@ -607,6 +607,13 @@ public function isMultiple() {
     return ($cardinality == static::CARDINALITY_UNLIMITED) || ($cardinality > 1);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function isLocked() {
+    return $this->locked;
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/field/lib/Drupal/field/FieldInterface.php b/core/modules/field/lib/Drupal/field/FieldInterface.php
index ed2658c8e7e0..afa0ebae179e 100644
--- a/core/modules/field/lib/Drupal/field/FieldInterface.php
+++ b/core/modules/field/lib/Drupal/field/FieldInterface.php
@@ -23,4 +23,12 @@ interface FieldInterface extends ConfigEntityInterface, FieldDefinitionInterface
    */
   public function getBundles();
 
+  /**
+   * Returns whether the field is locked or not.
+   *
+   * @return bool
+   *   TRUE if the field is locked.
+   */
+  public function isLocked();
+
 }
diff --git a/core/modules/field_ui/field_ui.services.yml b/core/modules/field_ui/field_ui.services.yml
index 4f5ef7a2c7f1..e643e543ff94 100644
--- a/core/modules/field_ui/field_ui.services.yml
+++ b/core/modules/field_ui/field_ui.services.yml
@@ -4,6 +4,10 @@ services:
     arguments: ['@entity.manager']
     tags:
      - { name: event_subscriber }
+  access_check.field_ui.field_delete:
+    class: Drupal\field_ui\Access\FieldDeleteAccessCheck
+    tags:
+     - { name: access_check, applies_to: _field_ui_field_delete_access }
   access_check.field_ui.view_mode:
     class: Drupal\field_ui\Access\ViewModeAccessCheck
     arguments: ['@entity.manager']
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Access/FieldDeleteAccessCheck.php b/core/modules/field_ui/lib/Drupal/field_ui/Access/FieldDeleteAccessCheck.php
new file mode 100644
index 000000000000..c8f931b7eb4f
--- /dev/null
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Access/FieldDeleteAccessCheck.php
@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field_ui\Access\FieldDeleteAccessCheck.
+ */
+
+namespace Drupal\field_ui\Access;
+
+use Drupal\Core\Routing\Access\AccessInterface;
+use Drupal\Core\Session\AccountInterface;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Allows access to routes to be controlled by an '_access' boolean parameter.
+ */
+class FieldDeleteAccessCheck implements AccessInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function access(Route $route, Request $request, AccountInterface $account) {
+    $field_instance = $request->attributes->get('field_instance');
+    if (!$field_instance->getField()->isLocked()) {
+      $permission = $route->getRequirement('_field_ui_field_delete_access');
+      return $account->hasPermission($permission) ? static::ALLOW : static::DENY;
+    }
+
+    return static::DENY;
+  }
+
+}
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Routing/RouteSubscriber.php b/core/modules/field_ui/lib/Drupal/field_ui/Routing/RouteSubscriber.php
index 3bebd66add71..2ec74381c295 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Routing/RouteSubscriber.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Routing/RouteSubscriber.php
@@ -68,7 +68,7 @@ protected function alterRoutes(RouteCollection $collection, $provider) {
         $route = new Route(
           "$path/fields/{field_instance}/delete",
           array('_entity_form' => 'field_instance.delete'),
-          array('_permission' => 'administer ' . $entity_type . ' fields')
+          array('_field_ui_field_delete_access' => 'administer ' . $entity_type . ' fields')
         );
         $collection->add("field_ui.delete_$entity_type", $route);
 
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
index 27197581a4c4..a8e6508ec743 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
@@ -415,6 +415,8 @@ function testLockedField() {
     $this->assertFalse(in_array('edit', $edit_link), 'Edit option for locked field is not present the UI');
     $delete_link = $this->xpath('//tr[@id=:field_name]/td[4]', array(':field_name' => $field->name));
     $this->assertFalse(in_array('delete', $delete_link), 'Delete option for locked field is not present the UI');
+    $this->drupalGet('admin/structure/types/manage/' . $this->type . '/fields/node.' . $this->type . '.' . $field->name . '/delete');
+    $this->assertResponse(403);
   }
 
   /**
-- 
GitLab