diff --git a/core/core.services.yml b/core/core.services.yml index 0ddf970ed43f3497657e066f7b03b255cdc4cb3f..0fa5ab98a3a28dfb5438db501d568fdb967cd3ca 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 4b8d0c07c73f0868815e6aeebe0ed28d5ea43252..0000000000000000000000000000000000000000 --- 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 f342cb500d3d810dc18b98d045ba32d4da1eb692..ef93e9bdecf924c48d45b780696e83c5b2a5493f 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 ac20040d3989a81de5afe8f5820e2367362a8f72..dac2ca0d473c46861c5fdaed468fa214dffe65a6 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 d6f8dc31db207a96a711f9a87154d0cce6984575..0000000000000000000000000000000000000000 --- 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 2868a2d60819847140416c422d46a2323de600fe..0000000000000000000000000000000000000000 --- 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 af119580864135e19034ef7e9e81cbe0608ff65f..1128a858c12bebd1b7ddcc4922b2efb2989604bb 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 b400cbee39734360d31811970965230cff18f0ab..a77b97d66eec3f2c8a94f25e1dd6e36db7efa717 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 0c4524dfde4f7876618e1a4c71b066333d8bf580..7df11671adba266a4c15fb353ded900c131034dd 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 d8bb8e3276ecb89ce3e808c7ae24608f092858d0..0000000000000000000000000000000000000000 --- 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 cd67bfbe9b6693c8f5b21c0c8561ac39f69b5481..0000000000000000000000000000000000000000 --- 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 c7545ce1514f87ecb49a480bc6ec13bd2ad6a2e0..0000000000000000000000000000000000000000 --- 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 314a10f4066e756fa861950fe94880217bb47505..d2d6d336a5f7325b69d5449c7e3703e7bd123b95 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 148788f0a7099870f3ab0f819491879afbb98e52..0000000000000000000000000000000000000000 --- 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 88a167d24cefae1d3a2c5c2513be8483f4d08412..ed08681e37cc7308c0b32101fbe8917d32833b84 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 c90b5228ef2ea54e68c204501f3a26c6898228a2..0000000000000000000000000000000000000000 --- 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 4cc03bd81df5cd7f63afda4b0c92368657b73be4..35892a8ffe8d70261a60f1b976dbb5fa1f9b4a73 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 08143dca37be450c8188f4ba406360a6c66d4eaf..531f40a0156076565848641fd4a23e3b5c65b71b 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 2f82493c44d8480520b4755b04e23046aec7b2da..f8f7d15f4e1b3f31b71d49527c58ab3ddb50617b 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']