From e324171c3e189a77782cc1afdcdfc76fa581dcf1 Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Mon, 25 Oct 2021 12:27:21 +0100 Subject: [PATCH] Revert "Issue #2934995 by benjifisher, larowlan, paulocs, AaronMcHale, vikashsoni, danflanagan8, Berdir, SKAUGHT: Add a "Manage permissions" tab for each bundle that has associated permissions" This reverts commit 3dbf9972744c7e05735fd6811744832d7253a170. --- core/core.services.yml | 5 - .../Enhancer/EntityBundleRouteEnhancer.php | 57 ------ core/modules/field_ui/field_ui.services.yml | 4 +- .../src/Routing/FieldUiRouteEnhancer.php | 58 +++++- .../src/Kernel/FieldUiRouteEnhancerTest.php | 32 ---- .../src/Unit/FieldUiRouteEnhancerTest.php | 27 --- .../tests/src/Functional/NodeTypeTest.php | 7 +- .../src/Unit/Menu/ShortcutLocalTasksTest.php | 9 - .../src/Functional/Menu/LocalTasksTest.php | 15 +- .../src/Form/UserPermissionsBundleForm.php | 181 ------------------ .../src/Plugin/Derivative/UserLocalTask.php | 75 -------- .../user/src/Routing/RouteSubscriber.php | 78 -------- .../src/Functional/UserPermissionsTest.php | 48 ----- .../Form/UserPermissionsBundleFormTest.php | 109 ----------- .../src/Unit/Menu/UserLocalTasksTest.php | 9 - .../Plugin/Derivative/UserLocalTaskTest.php | 70 ------- core/modules/user/user.links.task.yml | 4 - core/modules/user/user.module | 32 ---- core/modules/user/user.services.yml | 5 - 19 files changed, 56 insertions(+), 769 deletions(-) delete mode 100644 core/lib/Drupal/Core/Entity/Enhancer/EntityBundleRouteEnhancer.php delete mode 100644 core/modules/field_ui/tests/src/Kernel/FieldUiRouteEnhancerTest.php delete mode 100644 core/modules/field_ui/tests/src/Unit/FieldUiRouteEnhancerTest.php delete mode 100644 core/modules/user/src/Form/UserPermissionsBundleForm.php delete mode 100644 core/modules/user/src/Plugin/Derivative/UserLocalTask.php delete mode 100644 core/modules/user/src/Routing/RouteSubscriber.php delete mode 100644 core/modules/user/tests/src/Unit/Form/UserPermissionsBundleFormTest.php delete mode 100644 core/modules/user/tests/src/Unit/Plugin/Derivative/UserLocalTaskTest.php diff --git a/core/core.services.yml b/core/core.services.yml index 0ddf970ed43f..0fa5ab98a3a2 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -1074,11 +1074,6 @@ services: class: Drupal\Core\Entity\Enhancer\EntityRouteEnhancer tags: - { name: route_enhancer, priority: 20 } - route_enhancer.entity_bundle: - class: Drupal\Core\Entity\Enhancer\EntityBundleRouteEnhancer - arguments: ['@entity_type.manager'] - tags: - - { name: route_enhancer } route_enhancer.entity_revision: class: Drupal\Core\Routing\Enhancer\EntityRevisionRouteEnhancer tags: diff --git a/core/lib/Drupal/Core/Entity/Enhancer/EntityBundleRouteEnhancer.php b/core/lib/Drupal/Core/Entity/Enhancer/EntityBundleRouteEnhancer.php deleted file mode 100644 index 4b8d0c07c73f..000000000000 --- a/core/lib/Drupal/Core/Entity/Enhancer/EntityBundleRouteEnhancer.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php - -namespace Drupal\Core\Entity\Enhancer; - -use Drupal\Core\Routing\EnhancerInterface; -use Drupal\Core\Routing\RouteObjectInterface; -use Drupal\Core\Entity\EntityTypeManagerInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Routing\Route; - -/** - * Sets the bundle parameter for routes with the _field_ui option. - */ -class EntityBundleRouteEnhancer implements EnhancerInterface { - - /** - * The entity type manager service. - * - * @var \Drupal\Core\Entity\EntityTypeManagerInterface - */ - protected $entityTypeManager; - - /** - * Constructs a EntityBundleRouteEnhancer object. - * - * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager - * The entity type manager service. - */ - public function __construct(EntityTypeManagerInterface $entity_type_manager) { - $this->entityTypeManager = $entity_type_manager; - } - - /** - * {@inheritdoc} - */ - public function enhance(array $defaults, Request $request) { - if (!$this->applies($defaults[RouteObjectInterface::ROUTE_OBJECT])) { - return $defaults; - } - if (($bundle = $this->entityTypeManager->getDefinition($defaults['entity_type_id'])->getBundleEntityType()) && isset($defaults[$bundle])) { - // Field UI forms only need the actual name of the bundle they're dealing - // with, not an upcasted entity object, so provide a simple way for them - // to get it. - $defaults['bundle'] = $defaults['_raw_variables']->get($bundle); - } - - return $defaults; - } - - /** - * {@inheritdoc} - */ - protected function applies(Route $route) { - return ($route->hasOption('_field_ui')); - } - -} diff --git a/core/modules/field_ui/field_ui.services.yml b/core/modules/field_ui/field_ui.services.yml index f342cb500d3d..ef93e9bdecf9 100644 --- a/core/modules/field_ui/field_ui.services.yml +++ b/core/modules/field_ui/field_ui.services.yml @@ -5,9 +5,7 @@ services: tags: - { name: event_subscriber } field_ui.route_enhancer: - alias: route_enhancer.entity_bundle - deprecated: The "%alias_id%" service is deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use the "route_enhancer.entity_bundle" service instead. See https://www.drupal.org/node/3245017 - class: Drupal\Core\Entity\Enhancer\EntityBundleRouteEnhancer + class: Drupal\field_ui\Routing\FieldUiRouteEnhancer arguments: ['@entity_type.manager'] tags: - { name: route_enhancer } diff --git a/core/modules/field_ui/src/Routing/FieldUiRouteEnhancer.php b/core/modules/field_ui/src/Routing/FieldUiRouteEnhancer.php index ac20040d3989..dac2ca0d473c 100644 --- a/core/modules/field_ui/src/Routing/FieldUiRouteEnhancer.php +++ b/core/modules/field_ui/src/Routing/FieldUiRouteEnhancer.php @@ -2,16 +2,56 @@ namespace Drupal\field_ui\Routing; -@trigger_error('The ' . __NAMESPACE__ . '\EntityBundleRouteEnhancer is deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Instead, use \Drupal\Core\Entity\Enhancer\EntityBundleRouteEnhancer. See https://www.drupal.org/node/3245017', E_USER_DEPRECATED); - -use Drupal\Core\Entity\Enhancer\EntityBundleRouteEnhancer; +use Drupal\Core\Routing\EnhancerInterface; +use Drupal\Core\Routing\RouteObjectInterface; +use Drupal\Core\Entity\EntityTypeManagerInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Routing\Route; /** * Enhances Field UI routes by adding proper information about the bundle name. - * - * @deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. - * Use \Drupal\Core\Entity\Enhancer\EntityBundleRouteEnhancer. - * - * @see https://www.drupal.org/node/3245017 */ -class FieldUiRouteEnhancer extends EntityBundleRouteEnhancer {} +class FieldUiRouteEnhancer implements EnhancerInterface { + + /** + * The entity type manager service. + * + * @var \Drupal\Core\Entity\EntityTypeManagerInterface + */ + protected $entityTypeManager; + + /** + * Constructs a FieldUiRouteEnhancer object. + * + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager + * The entity type manager service. + */ + public function __construct(EntityTypeManagerInterface $entity_type_manager) { + $this->entityTypeManager = $entity_type_manager; + } + + /** + * {@inheritdoc} + */ + public function enhance(array $defaults, Request $request) { + if (!$this->applies($defaults[RouteObjectInterface::ROUTE_OBJECT])) { + return $defaults; + } + if (($bundle = $this->entityTypeManager->getDefinition($defaults['entity_type_id'])->getBundleEntityType()) && isset($defaults[$bundle])) { + // Field UI forms only need the actual name of the bundle they're dealing + // with, not an upcasted entity object, so provide a simple way for them + // to get it. + $defaults['bundle'] = $defaults['_raw_variables']->get($bundle); + } + + return $defaults; + } + + /** + * {@inheritdoc} + */ + protected function applies(Route $route) { + return ($route->hasOption('_field_ui')); + } + +} diff --git a/core/modules/field_ui/tests/src/Kernel/FieldUiRouteEnhancerTest.php b/core/modules/field_ui/tests/src/Kernel/FieldUiRouteEnhancerTest.php deleted file mode 100644 index d6f8dc31db20..000000000000 --- a/core/modules/field_ui/tests/src/Kernel/FieldUiRouteEnhancerTest.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php - -namespace Drupal\Tests\field_ui\Kernel; - -use Drupal\KernelTests\KernelTestBase; - -/** - * Tests that the service "field_ui.route_enhancer" has been deprecated. - * - * @group field_ui - * @group legacy - */ -class FieldUiRouteEnhancerTest extends KernelTestBase { - - /** - * Modules to install. - * - * @var string[] - */ - protected static $modules = ['field_ui']; - - /** - * Tests deprecation of the "field_ui.route_enhancer" service. - */ - public function testFieldUiRouteEnhancerDeprecation() { - $this->expectDeprecation('The "field_ui.route_enhancer" service is deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use the "route_enhancer.entity_bundle" service instead. See https://www.drupal.org/node/3245017'); - $legacy_service = \Drupal::service('field_ui.route_enhancer'); - $new_service = \Drupal::service('route_enhancer.entity_bundle'); - $this->assertSame($new_service, $legacy_service); - } - -} diff --git a/core/modules/field_ui/tests/src/Unit/FieldUiRouteEnhancerTest.php b/core/modules/field_ui/tests/src/Unit/FieldUiRouteEnhancerTest.php deleted file mode 100644 index 2868a2d60819..000000000000 --- a/core/modules/field_ui/tests/src/Unit/FieldUiRouteEnhancerTest.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php - -namespace Drupal\Tests\field_ui\Unit; - -use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\field_ui\Routing\FieldUiRouteEnhancer; -use Drupal\Tests\UnitTestCase; - -/** - * @coversDefaultClass \Drupal\field_ui\Routing\FieldUiRouteEnhancer - * - * @group field_ui - * @group legacy - */ -class FieldUiRouteEnhancerTest extends UnitTestCase { - - /** - * Tests deprecation of the Drupal\field_ui\Routing\FieldUiRouteEnhancer - * class. - */ - public function testDeprecation() { - $this->expectDeprecation('The Drupal\field_ui\Routing\EntityBundleRouteEnhancer is deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Instead, use \Drupal\Core\Entity\Enhancer\EntityBundleRouteEnhancer. See https://www.drupal.org/node/3245017'); - $entity_type_manager = $this->prophesize(EntityTypeManagerInterface::class)->reveal(); - $route_enhancer = new FieldUiRouteEnhancer($entity_type_manager); - } - -} diff --git a/core/modules/node/tests/src/Functional/NodeTypeTest.php b/core/modules/node/tests/src/Functional/NodeTypeTest.php index af1195808641..1128a858c12b 100644 --- a/core/modules/node/tests/src/Functional/NodeTypeTest.php +++ b/core/modules/node/tests/src/Functional/NodeTypeTest.php @@ -225,21 +225,19 @@ public function testNodeTypeDeletion() { } /** - * Tests operations from Field UI and User modules for content types. + * Tests Field UI integration for content types. */ - public function testNodeTypeOperations() { + public function testNodeTypeFieldUiPermissions() { // Create an admin user who can only manage node fields. $admin_user_1 = $this->drupalCreateUser([ 'administer content types', 'administer node fields', - 'administer permissions', ]); $this->drupalLogin($admin_user_1); // Test that the user only sees the actions available to them. $this->drupalGet('admin/structure/types'); $this->assertSession()->linkByHrefExists('admin/structure/types/manage/article/fields'); - $this->assertSession()->linkByHrefExists('admin/structure/types/manage/article/permissions'); $this->assertSession()->linkByHrefNotExists('admin/structure/types/manage/article/display'); // Create another admin user who can manage node fields display. @@ -252,7 +250,6 @@ public function testNodeTypeOperations() { // Test that the user only sees the actions available to them. $this->drupalGet('admin/structure/types'); $this->assertSession()->linkByHrefNotExists('admin/structure/types/manage/article/fields'); - $this->assertSession()->linkByHrefNotExists('admin/structure/types/manage/article/permissions'); $this->assertSession()->linkByHrefExists('admin/structure/types/manage/article/display'); } diff --git a/core/modules/shortcut/tests/src/Unit/Menu/ShortcutLocalTasksTest.php b/core/modules/shortcut/tests/src/Unit/Menu/ShortcutLocalTasksTest.php index b400cbee3973..a77b97d66eec 100644 --- a/core/modules/shortcut/tests/src/Unit/Menu/ShortcutLocalTasksTest.php +++ b/core/modules/shortcut/tests/src/Unit/Menu/ShortcutLocalTasksTest.php @@ -2,7 +2,6 @@ namespace Drupal\Tests\shortcut\Unit\Menu; -use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Tests\Core\Menu\LocalTaskIntegrationTestBase; /** @@ -18,14 +17,6 @@ protected function setUp(): void { 'user' => 'core/modules/user', ]; parent::setUp(); - - // Add services required for user local tasks. - $entity_type_manager = $this->createMock(EntityTypeManagerInterface::class); - $entity_type_manager->expects($this->any()) - ->method('getDefinitions') - ->will($this->returnValue([])); - $this->container->set('entity_type.manager', $entity_type_manager); - $this->container->set('string_translation', $this->getStringTranslationStub()); } /** diff --git a/core/modules/system/tests/src/Functional/Menu/LocalTasksTest.php b/core/modules/system/tests/src/Functional/Menu/LocalTasksTest.php index 0c4524dfde4f..7df11671adba 100644 --- a/core/modules/system/tests/src/Functional/Menu/LocalTasksTest.php +++ b/core/modules/system/tests/src/Functional/Menu/LocalTasksTest.php @@ -62,7 +62,6 @@ protected function assertLocalTasks(array $routes, $level = 0) { $expected = Url::fromRoute($route_name, $route_parameters)->toString(); $this->assertEquals($expected, $elements[$index]->getAttribute('href'), "Task " . ($index + 1) . "number href " . $elements[$index]->getAttribute('href') . " equals $expected."); } - $this->assertEquals(count($routes), count($elements), 'Only expected local tasks are found.'); } /** @@ -225,7 +224,6 @@ public function testLocalTaskBlock() { ['menu_test.local_task_test_tasks_view', []], ['menu_test.local_task_test_tasks_edit', []], ['menu_test.local_task_test_tasks_settings', []], - ['menu_test.local_task_test_tasks_settings_dynamic', []], ]); // Verify that local tasks in the second level doesn't appear. @@ -261,26 +259,21 @@ public function testLocalTaskBlockCache() { $this->drupalLogin($this->rootUser); $this->drupalCreateContentType(['type' => 'page']); + $this->drupalGet('/admin/structure/types/manage/page'); + // Only the Edit task. The block avoids showing a single tab. - $this->drupalGet('/admin/config/people/accounts'); $this->assertNoLocalTasks(); - // Only the Edit and Manage permission tabs. - $this->drupalGet('/admin/structure/types/manage/page'); - $this->assertLocalTasks([ - ['entity.node_type.edit_form', ['node_type' => 'page']], - ['entity.node_type.permission_form', ['node_type' => 'page']], - ]); - // Field UI adds the usual Manage fields etc tabs. \Drupal::service('module_installer')->install(['field_ui']); + $this->drupalGet('/admin/structure/types/manage/page'); + $this->assertLocalTasks([ ['entity.node_type.edit_form', ['node_type' => 'page']], ['entity.node.field_ui_fields', ['node_type' => 'page']], ['entity.entity_form_display.node.default', ['node_type' => 'page']], ['entity.entity_view_display.node.default', ['node_type' => 'page']], - ['entity.node_type.permission_form', ['node_type' => 'page']], ]); } diff --git a/core/modules/user/src/Form/UserPermissionsBundleForm.php b/core/modules/user/src/Form/UserPermissionsBundleForm.php deleted file mode 100644 index d8bb8e3276ec..000000000000 --- a/core/modules/user/src/Form/UserPermissionsBundleForm.php +++ /dev/null @@ -1,181 +0,0 @@ -<?php - -namespace Drupal\user\Form; - -use Drupal\Core\Access\AccessResult; -use Drupal\Core\Access\AccessResultInterface; -use Drupal\Core\Config\ConfigManagerInterface; -use Drupal\Core\Entity\EntityInterface; -use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Extension\ModuleHandlerInterface; -use Drupal\Core\Form\FormStateInterface; -use Drupal\Core\Routing\RouteMatchInterface; -use Drupal\user\PermissionHandlerInterface; -use Drupal\user\RoleStorageInterface; -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\Routing\Route; - -/** - * Provides the permissions administration form for a bundle. - * - * This class handles bundles that are defined by configuration objects. - * - * @internal - */ -class UserPermissionsBundleForm extends UserPermissionsForm { - - /** - * The configuration entity manager. - * - * @var \Drupal\Core\Config\ConfigManagerInterface - */ - protected $configManager; - - /** - * The entity type manager service. - * - * @var \Drupal\Core\Entity\EntityTypeManagerInterface - */ - protected $entityTypeManager; - - /** - * The bundle object. - * - * @var \Drupal\Core\Entity\EntityInterface - */ - protected $bundle; - - /** - * Constructs a new UserPermissionsBundleForm. - * - * @param \Drupal\user\PermissionHandlerInterface $permission_handler - * The permission handler. - * @param \Drupal\user\RoleStorageInterface $role_storage - * The role storage. - * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler - * The module handler. - * @param Drupal\Core\Config\ConfigManagerInterface $config_manager - * The configuration entity manager. - * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager - * The entity type manager service. - */ - public function __construct(PermissionHandlerInterface $permission_handler, RoleStorageInterface $role_storage, ModuleHandlerInterface $module_handler, ConfigManagerInterface $config_manager, EntityTypeManagerInterface $entity_type_manager) { - parent::__construct($permission_handler, $role_storage, $module_handler); - $this->configManager = $config_manager; - $this->entityTypeManager = $entity_type_manager; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container) { - return new static( - $container->get('user.permissions'), - $container->get('entity_type.manager')->getStorage('user_role'), - $container->get('module_handler'), - $container->get('config.manager'), - $container->get('entity_type.manager') - ); - } - - /** - * {@inheritdoc} - */ - protected function permissionsByProvider(): array { - // Get the names of all config entities that depend on $this->bundle. - $config_name = $this->bundle->getConfigDependencyName(); - $config_entities = $this->configManager - ->getConfigEntitiesToChangeOnDependencyRemoval('config', [$config_name]); - $config_names = array_map( - function ($dependent_config) { - return $dependent_config->getConfigDependencyName(); - }, $config_entities['delete'] ?? [] - ); - $config_names[] = $config_name; - - // Find all the permissions that depend on $this->bundle. - $permissions = $this->permissionHandler->getPermissions(); - $permissions_by_provider = []; - foreach ($permissions as $permission_name => $permission) { - $required_configs = $permission['dependencies']['config'] ?? []; - if (array_intersect($required_configs, $config_names)) { - $provider = $permission['provider']; - $permissions_by_provider[$provider][$permission_name] = $permission; - } - } - - return $permissions_by_provider; - } - - /** - * Builds the user permissions administration form for a bundle. - * - * @param array $form - * An associative array containing the structure of the form. - * @param \Drupal\Core\Form\FormStateInterface $form_state - * The current state of the form. - * @param string $bundle_entity_type - * (optional) The entity type ID. - * @param string|Drupal\Core\Entity\EntityInterface $bundle - * (optional) Either the bundle name or the bundle object. - */ - public function buildForm(array $form, FormStateInterface $form_state, string $bundle_entity_type = NULL, $bundle = NULL): array { - // Set $this->bundle for use by ::permissionsByProvider(). - if ($bundle instanceof EntityInterface) { - $this->bundle = $bundle; - return parent::buildForm($form, $form_state); - } - - $this->bundle = $this->entityTypeManager - ->getStorage($bundle_entity_type) - ->load($bundle); - - return parent::buildForm($form, $form_state); - } - - /** - * Checks that there are permissions to be managed. - * - * @param \Symfony\Component\Routing\Route $route - * The route to check against. - * @param \Drupal\Core\Routing\RouteMatchInterface $route_match - * The parametrized route. - * @param string|EntityInterface $bundle - * (optional) The bundle. Different entity types can have different names - * for their bundle key, so if not specified on the route via a {bundle} - * parameter, the access checker determines the appropriate key name, and - * gets the value from the corresponding request attribute. For example, - * for nodes, the bundle key is "node_type", so the value would be - * available via the {node_type} parameter rather than a {bundle} - * parameter. - * - * @return \Drupal\Core\Access\AccessResultInterface - * The access result. - */ - public function access(Route $route, RouteMatchInterface $route_match, $bundle = NULL): AccessResultInterface { - // Set $this->bundle for use by ::permissionsByProvider(). - if ($bundle instanceof EntityInterface) { - $this->bundle = $bundle; - } - else { - $bundle_entity_type = $route->getDefault('bundle_entity_type'); - $bundle_name = is_string($bundle) ? $bundle : $route_match->getRawParameter($bundle_entity_type); - $this->bundle = $this->entityTypeManager - ->getStorage($bundle_entity_type) - ->load($bundle_name); - } - - if (empty($this->bundle)) { - // A typo in the request path can lead to this case. - return AccessResult::forbidden(); - } - - $granularity = $this->entityTypeManager - ->getDefinition($this->bundle->getEntityType()->getBundleOf()) - ->getPermissionGranularity(); - $bundle_has_permissions = $granularity === 'bundle' || (bool) $this->permissionsByProvider(); - - return AccessResult::allowedIf($bundle_has_permissions); - } - -} diff --git a/core/modules/user/src/Plugin/Derivative/UserLocalTask.php b/core/modules/user/src/Plugin/Derivative/UserLocalTask.php deleted file mode 100644 index cd67bfbe9b66..000000000000 --- a/core/modules/user/src/Plugin/Derivative/UserLocalTask.php +++ /dev/null @@ -1,75 +0,0 @@ -<?php - -namespace Drupal\user\Plugin\Derivative; - -use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Component\Plugin\Derivative\DeriverBase; -use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface; -use Drupal\Core\StringTranslation\StringTranslationTrait; -use Drupal\Core\StringTranslation\TranslationInterface; -use Symfony\Component\DependencyInjection\ContainerInterface; - -/** - * Provides local task definitions for all entity bundles. - */ -class UserLocalTask extends DeriverBase implements ContainerDeriverInterface { - use StringTranslationTrait; - - /** - * The entity type manager. - * - * @var \Drupal\Core\Entity\EntityTypeManagerInterface - */ - protected $entityTypeManager; - - /** - * Creates a UserLocalTask object. - * - * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager - * The entity type manager. - * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation - * The translation manager. - */ - public function __construct(EntityTypeManagerInterface $entity_type_manager, TranslationInterface $string_translation) { - $this->entityTypeManager = $entity_type_manager; - $this->stringTranslation = $string_translation; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container, $base_plugin_id) { - return new static( - $container->get('entity_type.manager'), - $container->get('string_translation') - ); - } - - /** - * {@inheritdoc} - */ - public function getDerivativeDefinitions($base_plugin_definition) { - $this->derivatives = []; - - foreach ($this->entityTypeManager->getDefinitions() as $entity_type) { - if (!$base_route = $entity_type->get('field_ui_base_route')) { - continue; - } - - if (!$bundle_entity_type = $entity_type->getBundleEntityType()) { - continue; - } - - $this->derivatives["permissions_$bundle_entity_type"] = [ - 'route_name' => "entity.$bundle_entity_type.permission_form", - 'weight' => 10, - 'title' => $this->t('Manage permissions'), - 'base_route' => $base_route, - ] + $base_plugin_definition; - - } - - return parent::getDerivativeDefinitions($base_plugin_definition); - } - -} diff --git a/core/modules/user/src/Routing/RouteSubscriber.php b/core/modules/user/src/Routing/RouteSubscriber.php deleted file mode 100644 index c7545ce1514f..000000000000 --- a/core/modules/user/src/Routing/RouteSubscriber.php +++ /dev/null @@ -1,78 +0,0 @@ -<?php - -namespace Drupal\user\Routing; - -use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Routing\RouteSubscriberBase; -use Symfony\Component\Routing\Route; -use Symfony\Component\Routing\RouteCollection; - -/** - * User route subscriber. - */ -class RouteSubscriber extends RouteSubscriberBase { - - /** - * The entity type manager service. - * - * @var \Drupal\Core\Entity\EntityTypeManagerInterface - */ - protected $entityTypeManager; - - /** - * Constructs a RouteSubscriber object. - * - * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager - * The entity type manager service. - */ - public function __construct(EntityTypeManagerInterface $entity_type_manager) { - $this->entityTypeManager = $entity_type_manager; - } - - /** - * {@inheritdoc} - */ - protected function alterRoutes(RouteCollection $collection) { - foreach ($this->entityTypeManager->getDefinitions() as $entity_type_id => $entity_type) { - if (!$route_name = $entity_type->get('field_ui_base_route')) { - continue; - } - - if (!$bundle_entity_type = $entity_type->getBundleEntityType()) { - continue; - } - - // Try to get the route from the current collection. - if (!$entity_route = $collection->get($route_name)) { - continue; - } - - $route = new Route( - $entity_route->getPath() . '/permissions', - [ - '_title' => 'Manage permissions', - '_form' => 'Drupal\user\Form\UserPermissionsBundleForm', - 'entity_type_id' => $entity_type_id, - 'bundle_entity_type' => $bundle_entity_type, - ], - [ - '_permission' => 'administer permissions', - '_custom_access' => '\Drupal\user\Form\UserPermissionsBundleForm::access', - ], - [ - // Indicate that Drupal\Core\Entity\EntityBundleRouteEnhancer should - // set the bundle parameter. - '_field_ui' => TRUE, - 'parameters' => [ - $bundle_entity_type => [ - 'type' => "entity:$bundle_entity_type", - 'with_config_overrides' => TRUE, - ], - ], - ] + $entity_route->getOptions() - ); - $collection->add("entity.$bundle_entity_type.permission_form", $route); - } - } - -} diff --git a/core/modules/user/tests/src/Functional/UserPermissionsTest.php b/core/modules/user/tests/src/Functional/UserPermissionsTest.php index 314a10f4066e..d2d6d336a5f7 100644 --- a/core/modules/user/tests/src/Functional/UserPermissionsTest.php +++ b/core/modules/user/tests/src/Functional/UserPermissionsTest.php @@ -247,52 +247,4 @@ public function testAccessModulePermission() { $this->assertSession()->statusCodeEquals(403); } - /** - * Verify that bundle-specific pages work properly. - */ - public function testAccessBundlePermission() { - $this->drupalLogin($this->adminUser); - - \Drupal::service('module_installer')->install(['block_content', 'taxonomy']); - $this->grantPermissions(Role::load($this->rid), ['administer blocks', 'administer taxonomy']); - $storage = $this->container->get('entity_type.manager')->getStorage('user_role'); - - // Bundles that do not have permissions have no permissions pages. - $edit = []; - $edit['label'] = 'Test block type'; - $edit['id'] = 'test_block_type'; - $this->drupalGet('admin/structure/block/block-content/types/add'); - $this->submitForm($edit, 'Save'); - $this->drupalGet('admin/structure/block/block-content/manage/test_block_type/permissions'); - $this->assertSession()->statusCodeEquals(403); - - // Permissions can be changed using the bundle-specific pages. - $edit = []; - $edit['name'] = 'Test vocabulary'; - $edit['vid'] = 'test_vocabulary'; - $this->drupalGet('admin/structure/taxonomy/add'); - $this->submitForm($edit, 'Save'); - $authenticated = $storage->load('authenticated'); - $this->assertFalse($authenticated->hasPermission('create terms in test_vocabulary')); - $edit = []; - $edit['authenticated[create terms in test_vocabulary]'] = TRUE; - $this->drupalGet('admin/structure/taxonomy/manage/test_vocabulary/overview/permissions'); - $this->submitForm($edit, 'Save permissions'); - $this->assertSession()->pageTextContains('The changes have been saved.'); - $storage->resetCache(['authenticated']); - $authenticated = $storage->load('authenticated'); - $this->assertTrue($authenticated->hasPermission('create terms in test_vocabulary')); - - // Typos produce 404 response, not server errors. - $this->drupalGet('admin/structure/taxonomy/manage/test_typo/overview/permissions'); - $this->assertSession()->statusCodeEquals(404); - - // Anonymous users cannot access any of these pages. - $this->drupalLogout(); - $this->drupalGet('admin/structure/taxonomy/manage/test_vocabulary/overview/permissions'); - $this->assertSession()->statusCodeEquals(403); - $this->drupalGet('admin/structure/block/block-content/manage/test_block_type/permissions'); - $this->assertSession()->statusCodeEquals(403); - } - } diff --git a/core/modules/user/tests/src/Unit/Form/UserPermissionsBundleFormTest.php b/core/modules/user/tests/src/Unit/Form/UserPermissionsBundleFormTest.php deleted file mode 100644 index 148788f0a709..000000000000 --- a/core/modules/user/tests/src/Unit/Form/UserPermissionsBundleFormTest.php +++ /dev/null @@ -1,109 +0,0 @@ -<?php - -namespace Drupal\Tests\user\Unit\Form; - -use Drupal\Core\Access\AccessResult; -use Drupal\Core\Config\ConfigManagerInterface; -use Drupal\Core\Config\Entity\ConfigEntityDependency; -use Drupal\Core\Entity\EntityInterface; -use Drupal\Core\Entity\EntityTypeInterface; -use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Extension\ModuleHandlerInterface; -use Drupal\Core\Routing\RouteMatchInterface; -use Drupal\Tests\UnitTestCase; -use Drupal\user\Form\UserPermissionsBundleForm; -use Drupal\user\PermissionHandlerInterface; -use Drupal\user\RoleStorageInterface; -use Symfony\Component\Routing\Route; - -/** - * Tests the permissions administration form for a bundle. - * - * @coversDefaultClass \Drupal\user\Form\UserPermissionsBundleForm - * @group user - */ -class UserPermissionsBundleFormTest extends UnitTestCase { - - /** - * Tests generating the permissions list. - * - * This is really a test of the protected method permissionsByProvider(). Call - * the public method access() with an object $bundle, so that it skips most of - * the logic in that function. - * - * @param string $dependency_name - * The test permission has a direct dependency on this. - * @param bool $found - * TRUE if there is a permission to be managed by the form. - * - * @dataProvider providerTestPermissionsByProvider - * @covers ::access() - * @covers ::permissionsByProvider() - */ - public function testPermissionsByProvider(string $dependency_name, bool $found) { - - // Mock the constructor parameters. - $prophecy = $this->prophesize(PermissionHandlerInterface::class); - $prophecy->getPermissions() - ->willReturn([ - 'permission name' => [ - 'title' => 'permission display name', - 'provider' => 'some module', - 'dependencies' => ['config' => [$dependency_name]], - ], - ]); - $permission_handler = $prophecy->reveal(); - $role_storage = $this->prophesize(RoleStorageInterface::class)->reveal(); - $module_handler = $this->prophesize(ModuleHandlerInterface::class)->reveal(); - $prophecy = $this->prophesize(ConfigManagerInterface::class); - $prophecy->getConfigEntitiesToChangeOnDependencyRemoval('config', ['node.type.article']) - ->willReturn([ - 'delete' => [ - new ConfigEntityDependency('core.entity_view_display.node.article.full'), - new ConfigEntityDependency('field.field.node.article.body'), - ], - ]); - $config_manager = $prophecy->reveal(); - $prophecy = $this->prophesize(EntityTypeInterface::class); - $prophecy->getPermissionGranularity() - ->willReturn('entity_type'); - $entity_type = $prophecy->reveal(); - $prophecy = $this->prophesize(EntityTypeManagerInterface::class); - $prophecy->getDefinition('entity_type') - ->willReturn($entity_type); - $entity_type_manager = $prophecy->reveal(); - - $bundle_form = new UserPermissionsBundleForm($permission_handler, $role_storage, $module_handler, $config_manager, $entity_type_manager); - - // Mock the method parameters. - $route = new Route('some.path'); - $route_match = $this->prophesize(RouteMatchInterface::class)->reveal(); - $prophecy = $this->prophesize(EntityTypeInterface::class); - $prophecy->getBundleOf() - ->willReturn('entity_type'); - $bundle_type = $prophecy->reveal(); - $prophecy = $this->prophesize(EntityInterface::class); - $prophecy->getEntityType() - ->willReturn($bundle_type); - $prophecy->getConfigDependencyName() - ->willReturn('node.type.article'); - $bundle = $prophecy->reveal(); - - $access_actual = $bundle_form->access($route, $route_match, $bundle); - $this->assertEquals($found ? AccessResult::allowed() : AccessResult::neutral(), $access_actual); - } - - /** - * Provides data for the testPermissionsByProvider method. - * - * @return array - */ - public function providerTestPermissionsByProvider() { - return [ - 'direct dependency' => ['node.type.article', TRUE], - 'indirect dependency' => ['core.entity_view_display.node.article.full', TRUE], - 'not a dependency' => ['node.type.page', FALSE], - ]; - } - -} diff --git a/core/modules/user/tests/src/Unit/Menu/UserLocalTasksTest.php b/core/modules/user/tests/src/Unit/Menu/UserLocalTasksTest.php index 88a167d24cef..ed08681e37cc 100644 --- a/core/modules/user/tests/src/Unit/Menu/UserLocalTasksTest.php +++ b/core/modules/user/tests/src/Unit/Menu/UserLocalTasksTest.php @@ -2,7 +2,6 @@ namespace Drupal\Tests\user\Unit\Menu; -use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Tests\Core\Menu\LocalTaskIntegrationTestBase; /** @@ -15,14 +14,6 @@ class UserLocalTasksTest extends LocalTaskIntegrationTestBase { protected function setUp(): void { $this->directoryList = ['user' => 'core/modules/user']; parent::setUp(); - - // Add services required for user local tasks. - $entity_type_manager = $this->createMock(EntityTypeManagerInterface::class); - $entity_type_manager->expects($this->any()) - ->method('getDefinitions') - ->will($this->returnValue([])); - $this->container->set('entity_type.manager', $entity_type_manager); - $this->container->set('string_translation', $this->getStringTranslationStub()); } /** diff --git a/core/modules/user/tests/src/Unit/Plugin/Derivative/UserLocalTaskTest.php b/core/modules/user/tests/src/Unit/Plugin/Derivative/UserLocalTaskTest.php deleted file mode 100644 index c90b5228ef2e..000000000000 --- a/core/modules/user/tests/src/Unit/Plugin/Derivative/UserLocalTaskTest.php +++ /dev/null @@ -1,70 +0,0 @@ -<?php - -namespace Drupal\Tests\user\Unit\Plugin\Derivative; - -use Drupal\Core\Entity\EntityTypeInterface; -use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Tests\UnitTestCase; -use Drupal\user\Plugin\Derivative\UserLocalTask; - -/** - * Tests the local tasks deriver class. - * - * @coversDefaultClass \Drupal\user\Plugin\Derivative\UserLocalTask - * @group user - */ -class UserLocalTaskTest extends UnitTestCase { - - /** - * The local tasks deriver. - * - * @var \Drupal\user\Plugin\Derivative\UserLocalTask - */ - protected $deriver; - - protected function setUp(): void { - parent::setUp(); - - $prophecy = $this->prophesize(EntityTypeInterface::class); - $prophecy->get('field_ui_base_route')->willReturn(NULL); - $entity_no_bundle_type = $prophecy->reveal(); - - $prophecy = $this->prophesize(EntityTypeInterface::class); - $prophecy->get('field_ui_base_route')->willReturn('field_ui.base_route'); - $prophecy->getBundleEntityType()->willReturn(NULL); - $entity_bundle_type = $prophecy->reveal(); - - $prophecy = $this->prophesize(EntityTypeInterface::class); - $prophecy->get('field_ui_base_route')->willReturn('field_ui.base_route'); - $prophecy->getBundleEntityType()->willReturn('field_ui_bundle_type'); - $field_ui_bundle_type = $prophecy->reveal(); - - $prophecy = $this->prophesize(EntityTypeManagerInterface::class); - $prophecy->getDefinitions()->willReturn([ - 'case_no_bundle_type' => $entity_no_bundle_type, - 'case_bundle_type' => $entity_bundle_type, - 'case_field_ui' => $field_ui_bundle_type, - ]); - $entity_type_manager = $prophecy->reveal(); - - $this->deriver = new UserLocalTask($entity_type_manager, $this->getStringTranslationStub()); - } - - /** - * Tests the derivatives generated for local tasks. - * - * @covers \Drupal\user\Plugin\Derivative\UserLocalTask::getDerivativeDefinitions() - */ - public function testGetDerivativeDefinitions() { - $expected = [ - 'permissions_field_ui_bundle_type' => [ - 'route_name' => 'entity.field_ui_bundle_type.permission_form', - 'weight' => 10, - 'title' => $this->getStringTranslationStub()->translate('Manage permissions'), - 'base_route' => 'field_ui.base_route', - ], - ]; - $this->assertEquals($expected, $this->deriver->getDerivativeDefinitions([])); - } - -} diff --git a/core/modules/user/user.links.task.yml b/core/modules/user/user.links.task.yml index 4cc03bd81df5..35892a8ffe8d 100644 --- a/core/modules/user/user.links.task.yml +++ b/core/modules/user/user.links.task.yml @@ -44,10 +44,6 @@ user.admin_permissions: route_name: user.admin_permissions base_route: entity.user.collection -entity.bundle.permission_form: - class: \Drupal\Core\Menu\LocalTaskDefault - deriver: \Drupal\user\Plugin\Derivative\UserLocalTask - entity.user_role.collection: title: 'Roles' route_name: entity.user_role.collection diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 08143dca37be..531f40a01560 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -13,7 +13,6 @@ use Drupal\Core\Asset\AttachedAssetsInterface; use Drupal\Core\Batch\BatchBuilder; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; -use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; @@ -47,8 +46,6 @@ function user_help($route_name, RouteMatchInterface $route_match) { $output .= '<dd>' . t('<em>Roles</em> are used to group and classify users; each user can be assigned one or more roles. Typically there are two pre-defined roles: <em>Anonymous user</em> (users that are not logged in), and <em>Authenticated user</em> (users that are registered and logged in). Depending on how your site was set up, an <em>Administrator</em> role may also be available: users with this role will automatically be assigned any new permissions whenever a module is enabled. You can create additional roles on the <a href=":roles">Roles administration page</a>.', [':roles' => Url::fromRoute('entity.user_role.collection')->toString()]) . '</dd>'; $output .= '<dt>' . t('Setting permissions') . '</dt>'; $output .= '<dd>' . t('After creating roles, you can set permissions for each role on the <a href=":permissions_user">Permissions page</a>. Granting a permission allows users who have been assigned a particular role to perform an action on the site, such as viewing content, editing or creating a particular type of content, administering settings for a particular module, or using a particular function of the site (such as search).', [':permissions_user' => Url::fromRoute('user.admin_permissions')->toString()]) . '</dd>'; - $output .= '<dt>' . t('Other permissions pages') . '</dt>'; - $output .= '<dd>' . t('The main Permissions page can be overwhelming, so each module that defines permissions has its own page for setting them. There are links to these pages on the <a href=":modules">Extend page</a>. When editing a content type, vocabulary, etc., there is also a Manage permissions tab for permissions related to that configuration.', [':modules' => Url::fromRoute('system.modules_list')->toString()]) . '</dd>'; $output .= '<dt>' . t('Managing account settings') . '</dt>'; $output .= '<dd>' . t('The <a href=":accounts">Account settings page</a> allows you to manage settings for the displayed name of the Anonymous user role, personal contact forms, user registration settings, and account cancellation settings. On this page you can also manage settings for account personalization, and adapt the text for the email messages that users receive when they register or request a password recovery. You may also set which role is automatically assigned new permissions whenever a module is enabled (the Administrator role).', [':accounts' => Url::fromRoute('entity.user.admin_form')->toString()]) . '</dd>'; $output .= '<dt>' . t('Managing user account fields') . '</dt>'; @@ -1326,32 +1323,3 @@ function user_filter_format_disable(FilterFormatInterface $filter_format) { } } } - -/** - * Implements hook_entity_operation(). - */ -function user_entity_operation(EntityInterface $entity) { - // Add Manage permissions link if this entity type is the bundle of another. - if (!$bundle_entity_type = $entity->bundle()) { - return []; - } - - $route = "entity.$bundle_entity_type.permission_form"; - if (empty(\Drupal::service('router.route_provider')->getRoutesByNames([$route]))) { - return []; - } - - $url = Url::fromRoute($route, [$bundle_entity_type => $entity->id()]); - if (!$url->access()) { - return []; - } - - return [ - 'manage-permissions' => [ - 'title' => t('Manage permissions'), - 'weight' => 50, - 'url' => $url, - ], - ]; - -} diff --git a/core/modules/user/user.services.yml b/core/modules/user/user.services.yml index 2f82493c44d8..f8f7d15f4e1b 100644 --- a/core/modules/user/user.services.yml +++ b/core/modules/user/user.services.yml @@ -52,11 +52,6 @@ services: user.permissions: class: Drupal\user\PermissionHandler arguments: ['@module_handler', '@string_translation', '@controller_resolver'] - user.route_subscriber: - class: Drupal\user\Routing\RouteSubscriber - arguments: ['@entity_type.manager'] - tags: - - { name: event_subscriber } user.current_user_context: class: Drupal\user\ContextProvider\CurrentUserContext arguments: ['@current_user', '@entity_type.manager'] -- GitLab