diff --git a/core/core.services.yml b/core/core.services.yml index 0ea69d4..ae52b34 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -172,7 +172,7 @@ services: - { name: persist } entity.manager: class: Drupal\Core\Entity\EntityManager - arguments: ['@container.namespaces', '@service_container', '@module_handler', '@cache.cache', '@language_manager', '@string_translation'] + arguments: ['@container.namespaces', '@service_container', '@module_handler', '@cache.cache', '@language_manager', '@string_translation', '@url_generator'] plugin.manager.entity: alias: entity.manager plugin.manager.field.field_type: diff --git a/core/lib/Drupal/Core/Entity/Annotation/EntityType.php b/core/lib/Drupal/Core/Entity/Annotation/EntityType.php index 604bf5d..60748c8 100644 --- a/core/lib/Drupal/Core/Entity/Annotation/EntityType.php +++ b/core/lib/Drupal/Core/Entity/Annotation/EntityType.php @@ -225,16 +225,11 @@ class EntityType extends Plugin { public $bundle_keys; /** - * The base router path for the entity type's field administration page. - * - * If the entity type has a bundle, include {bundle} in the path. - * - * For example, the node entity type specifies - * "admin/structure/types/manage/{bundle}" as its base field admin path. + * The name of the entity type which provides bundles. * * @var string (optional) */ - public $route_base_path; + public $bundle_entity_type; /** * Link templates using the URI template syntax. diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php index 5fc2d16..cdcd667 100644 --- a/core/lib/Drupal/Core/Entity/EntityManager.php +++ b/core/lib/Drupal/Core/Entity/EntityManager.php @@ -18,6 +18,7 @@ use Drupal\Core\Plugin\Discovery\CacheDecorator; use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery; use Drupal\Core\Plugin\Discovery\InfoHookDecorator; +use Drupal\Core\Routing\UrlGeneratorInterface; use Drupal\Core\StringTranslation\TranslationInterface; use Drupal\Core\TypedData\TranslatableInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -106,6 +107,13 @@ class EntityManager extends PluginManagerBase implements EntityManagerInterface protected $translationManager; /** + * The url generator. + * + * @var \Drupal\Core\Routing\UrlGeneratorInterface + */ + protected $urlGenerator; + + /** * Static cache of bundle information. * * @var array @@ -128,8 +136,11 @@ class EntityManager extends PluginManagerBase implements EntityManagerInterface * The language manager. * @param \Drupal\Core\StringTranslation\TranslationInterface $translation_manager * The string translationManager. + * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator + * The url generator. + */ - public function __construct(\Traversable $namespaces, ContainerInterface $container, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache, LanguageManager $language_manager, TranslationInterface $translation_manager) { + public function __construct(\Traversable $namespaces, ContainerInterface $container, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache, LanguageManager $language_manager, TranslationInterface $translation_manager, UrlGeneratorInterface $url_generator) { // Allow the plugin definition to be altered by hook_entity_info_alter(). $this->moduleHandler = $module_handler; @@ -137,6 +148,7 @@ public function __construct(\Traversable $namespaces, ContainerInterface $contai $this->languageManager = $language_manager; $this->namespaces = $namespaces; $this->translationManager = $translation_manager; + $this->urlGenerator = $url_generator; $this->discovery = new AnnotatedClassDiscovery('Entity', $namespaces, 'Drupal\Core\Entity\Annotation\EntityType'); $this->discovery = new InfoHookDecorator($this->discovery, 'entity_info'); @@ -301,9 +313,12 @@ public function getAdminPath($entity_type, $bundle) { $admin_path = ''; $entity_info = $this->getDefinition($entity_type); // Check for an entity type's admin base path. - if (isset($entity_info['route_base_path'])) { - // Replace any dynamic 'bundle' portion of the path with the actual bundle. - $admin_path = str_replace('{bundle}', $bundle, $entity_info['route_base_path']); + if (isset($entity_info['links']['admin-form'])) { + $route_parameters = array('bundle' => $bundle); + if (isset($entity_info['bundle_entity_type'])) { + $route_parameters[$entity_info['bundle_entity_type']] = $bundle; + } + $admin_path = $this->urlGenerator->getPathFromRoute($entity_info['links']['admin-form'], $route_parameters); } return $admin_path; diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php index a83352b..055bfea 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php @@ -36,10 +36,10 @@ * admin_permission = "administer blocks", * base_table = "custom_block", * revision_table = "custom_block_revision", - * route_base_path = "admin/structure/block/custom-blocks/manage/{bundle}", * links = { * "canonical" = "custom_block.edit", - * "edit-form" = "custom_block.edit" + * "edit-form" = "custom_block.edit", + * "admin-form" = "custom_block.type_edit" * }, * fieldable = TRUE, * translatable = TRUE, @@ -52,7 +52,8 @@ * }, * bundle_keys = { * "bundle" = "type" - * } + * }, + * bundle_entity_type = "custom_block_type" * ) */ class CustomBlock extends ContentEntityBase implements CustomBlockInterface { diff --git a/core/modules/comment/lib/Drupal/comment/Entity/Comment.php b/core/modules/comment/lib/Drupal/comment/Entity/Comment.php index 4d22fbf..8c5b999 100644 --- a/core/modules/comment/lib/Drupal/comment/Entity/Comment.php +++ b/core/modules/comment/lib/Drupal/comment/Entity/Comment.php @@ -36,7 +36,6 @@ * fieldable = TRUE, * translatable = TRUE, * render_cache = FALSE, - * route_base_path = "admin/structure/comments/manage/{bundle}", * entity_keys = { * "id" = "cid", * "bundle" = "field_id", @@ -48,7 +47,8 @@ * }, * links = { * "canonical" = "comment.permalink", - * "edit-form" = "comment.edit_page" + * "edit-form" = "comment.edit_page", + * "admin-form" = "comment.bundle" * } * ) */ diff --git a/core/modules/contact/lib/Drupal/contact/Entity/Message.php b/core/modules/contact/lib/Drupal/contact/Entity/Message.php index 9e424fa..aaaa64e 100644 --- a/core/modules/contact/lib/Drupal/contact/Entity/Message.php +++ b/core/modules/contact/lib/Drupal/contact/Entity/Message.php @@ -26,10 +26,13 @@ * entity_keys = { * "bundle" = "category" * }, - * route_base_path = "admin/structure/contact/manage/{bundle}", + * bundle_entity_type = "contact_category", * fieldable = TRUE, * bundle_keys = { * "bundle" = "id" + * }, + * links = { + * "admin-form" = "contact.category_edit" * } * ) */ diff --git a/core/modules/field_ui/field_ui.local_tasks.yml b/core/modules/field_ui/field_ui.local_tasks.yml index e690491..1330c2d 100644 --- a/core/modules/field_ui/field_ui.local_tasks.yml +++ b/core/modules/field_ui/field_ui.local_tasks.yml @@ -2,3 +2,6 @@ field_ui.list: title: Entities route_name: field_ui.list tab_root_id: field_ui.list +field_ui.fields: + class: \Drupal\Core\Menu\LocalTaskDefault + derivative: \Drupal\field_ui\Plugin\Derivative\FieldUiLocalTask diff --git a/core/modules/field_ui/field_ui.module b/core/modules/field_ui/field_ui.module index f9d90c6..340ecad 100644 --- a/core/modules/field_ui/field_ui.module +++ b/core/modules/field_ui/field_ui.module @@ -7,6 +7,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\entity\EntityViewModeInterface; +use Drupal\field_ui\Plugin\Derivative\FieldUiLocalTask; /** * Implements hook_help(). @@ -61,94 +62,6 @@ function field_ui_menu() { 'type' => MENU_NORMAL_ITEM, ); - // Create tabs for all possible bundles. - foreach (entity_get_info() as $entity_type => $entity_info) { - if ($entity_info['fieldable'] && isset($entity_info['route_base_path'])) { - // Extract path information from the entity type. - $path = $entity_info['route_base_path']; - $default_path = preg_replace('/{' . DRUPAL_PHP_FUNCTION_PATTERN . '}/', '%', $path); - // This is the position of the %field_ui_instance placeholder in the - // items below. - $field_position = count(explode('/', $path)) + 1; - - $items["$path/fields"] = array( - 'title' => 'Manage fields', - 'type' => MENU_LOCAL_TASK, - 'route_name' => "field_ui.overview_$entity_type", - 'weight' => 1, - ); - $items["$path/fields/%"] = array( - 'title callback' => 'entity_page_label', - 'title arguments' => array($field_position), - 'route_name' => "field_ui.instance_edit_$entity_type", - ); - $items["$default_path/fields/%/edit"] = array( - 'title' => 'Edit', - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); - $items["$path/fields/%/field"] = array( - 'title' => 'Field settings', - 'type' => MENU_LOCAL_TASK, - 'route_name' => "field_ui.field_edit_$entity_type", - ); - $items["$path/fields/%/delete"] = array( - 'title' => 'Delete', - 'type' => MENU_VISIBLE_IN_BREADCRUMB, - 'route_name' => "field_ui.delete_$entity_type", - 'weight' => 10, - ); - - // 'Manage form display' tab. - $items["$path/form-display"] = array( - 'title' => 'Manage form display', - 'type' => MENU_LOCAL_TASK, - 'route_name' => "field_ui.form_display_overview_$entity_type", - 'weight' => 2, - ); - - // 'Manage display' tab. - $items["$path/display"] = array( - 'title' => 'Manage display', - 'type' => MENU_LOCAL_TASK, - 'route_name' => "field_ui.display_overview_$entity_type", - 'weight' => 3, - ); - - // View and form modes secondary tabs. - // The same base $path for the menu item (with a placeholder) can be - // used for all bundles of a given entity type; but depending on - // administrator settings, each bundle has a different set of view - // modes available for customisation. So we define menu items for all - // view modes, and use a route requirement to determine which ones are - // actually visible for a given bundle. - $items["$default_path/form-display/default"] = array( - 'title' => t('Default'), - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); - $items["$default_path/display/default"] = array( - 'title' => t('Default'), - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); - $weight = 0; - foreach (entity_get_form_modes($entity_type) as $form_mode => $form_mode_info) { - $items["$path/form-display/$form_mode"] = array( - 'title' => $form_mode_info['label'], - 'type' => MENU_LOCAL_TASK, - 'weight' => $weight++, - 'route_name' => "field_ui.form_display_overview_$entity_type" . '_' . $form_mode, - ); - } - $weight = 0; - foreach (entity_get_view_modes($entity_type) as $view_mode => $view_mode_info) { - $items["$path/display/$view_mode"] = array( - 'title' => $view_mode_info['label'], - 'type' => MENU_LOCAL_TASK, - 'weight' => $weight++, - 'route_name' => "field_ui.display_overview_$entity_type" . '_' . $view_mode, - ); - } - } - } return $items; } @@ -462,3 +375,11 @@ function theme_field_ui_table($variables) { return drupal_render($table); } +/** + * Implements hook_local_tasks_alter(). + */ +function field_ui_local_tasks_alter(&$local_tasks) { + $container = \Drupal::getContainer(); + $local_task = FieldUiLocalTask::create($container, 'field_ui.fields'); + $local_task->alterLocalTasks($local_tasks); +} diff --git a/core/modules/field_ui/field_ui.services.yml b/core/modules/field_ui/field_ui.services.yml index 2ab3051..10752b0 100644 --- a/core/modules/field_ui/field_ui.services.yml +++ b/core/modules/field_ui/field_ui.services.yml @@ -1,14 +1,16 @@ services: field_ui.subscriber: class: Drupal\field_ui\Routing\RouteSubscriber - arguments: ['@entity.manager'] + arguments: ['@entity.manager', '@router.route_provider'] tags: - { name: event_subscriber } access_check.field_ui.view_mode: class: Drupal\field_ui\Access\ViewModeAccessCheck + arguments: ['@entity.manager'] tags: - { name: access_check } access_check.field_ui.form_mode: class: Drupal\field_ui\Access\FormModeAccessCheck + arguments: ['@entity.manager'] tags: - { name: access_check } diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Access/FormModeAccessCheck.php b/core/modules/field_ui/lib/Drupal/field_ui/Access/FormModeAccessCheck.php index 92e3790..fb78f36 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Access/FormModeAccessCheck.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Access/FormModeAccessCheck.php @@ -8,6 +8,7 @@ namespace Drupal\field_ui\Access; use Drupal\Core\Access\StaticAccessCheckInterface; +use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Session\AccountInterface; use Symfony\Component\Routing\Route; use Symfony\Component\HttpFoundation\Request; @@ -18,6 +19,23 @@ class FormModeAccessCheck implements StaticAccessCheckInterface { /** + * The entity manager. + * + * @var \Drupal\Core\Entity\EntityManagerInterface + */ + protected $entityManager; + + /** + * Creates a new FormModeAccessCheck. + * + * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager + * The entity manager. + */ + public function __construct(EntityManagerInterface $entity_manager) { + $this->entityManager = $entity_manager; + } + + /** * {@inheritdoc} */ public function appliesTo() { @@ -29,17 +47,19 @@ public function appliesTo() { */ public function access(Route $route, Request $request, AccountInterface $account) { if ($entity_type = $request->attributes->get('entity_type')) { - $bundle = $request->attributes->get('bundle'); $form_mode = $request->attributes->get('mode'); - if ($form_mode == 'default') { - $visibility = TRUE; + if (!($bundle = $request->attributes->get('bundle'))) { + $entity_info = $this->entityManager->getDefinition($entity_type); + $bundle = $request->attributes->get('_raw_variables')->get($entity_info['bundle_entity_type']); } - elseif ($entity_form_display = entity_load('entity_form_display', $entity_type . '.' . $bundle . '.' . $form_mode)) { - $visibility = $entity_form_display->status(); + + $visibility = FALSE; + if (!$form_mode || $form_mode == 'default') { + $visibility = TRUE; } - else { - $visibility = FALSE; + elseif ($entity_display = $this->entityManager->getStorageController('entity_form_display')->load($entity_type . '.' . $bundle . '.' . $form_mode)) { + $visibility = $entity_display->status(); } if ($visibility) { diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Access/ViewModeAccessCheck.php b/core/modules/field_ui/lib/Drupal/field_ui/Access/ViewModeAccessCheck.php index 2fe350b..71ef1da 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Access/ViewModeAccessCheck.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Access/ViewModeAccessCheck.php @@ -8,6 +8,7 @@ namespace Drupal\field_ui\Access; use Drupal\Core\Access\StaticAccessCheckInterface; +use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Session\AccountInterface; use Symfony\Component\Routing\Route; use Symfony\Component\HttpFoundation\Request; @@ -18,6 +19,23 @@ class ViewModeAccessCheck implements StaticAccessCheckInterface { /** + * The entity manager. + * + * @var \Drupal\Core\Entity\EntityManagerInterface + */ + protected $entityManager; + + /** + * Creates a new ViewModeAccessCheck. + * + * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager + * The entity manager. + */ + public function __construct(EntityManagerInterface $entity_manager) { + $this->entityManager = $entity_manager; + } + + /** * {@inheritdoc} */ public function appliesTo() { @@ -29,18 +47,20 @@ public function appliesTo() { */ public function access(Route $route, Request $request, AccountInterface $account) { if ($entity_type = $request->attributes->get('entity_type')) { - $bundle = $request->attributes->get('bundle'); $view_mode = $request->attributes->get('mode'); - if ($view_mode == 'default') { + if (!($bundle = $request->attributes->get('bundle'))) { + $entity_info = $this->entityManager->getDefinition($entity_type); + $bundle = $request->attributes->get('_raw_variables')->get($entity_info['bundle_entity_type']); + } + + $visibility = FALSE; + if (!$view_mode || $view_mode == 'default') { $visibility = TRUE; } - elseif ($entity_display = entity_load('entity_display', $entity_type . '.' . $bundle . '.' . $view_mode)) { + elseif ($entity_display = $this->entityManager->getStorageController('entity_display')->load($entity_type . '.' . $bundle . '.' . $view_mode)) { $visibility = $entity_display->status(); } - else { - $visibility = FALSE; - } if ($visibility) { $permission = $route->getRequirement('_field_ui_view_mode_access'); diff --git a/core/modules/field_ui/lib/Drupal/field_ui/OverviewBase.php b/core/modules/field_ui/lib/Drupal/field_ui/OverviewBase.php index c7db86e..8114efd 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/OverviewBase.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/OverviewBase.php @@ -77,6 +77,9 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL, $entity_info = $this->entityManager->getDefinition($entity_type); $this->entity_type = $entity_type; + if (!$bundle) { + $bundle = $this->getRequest()->attributes->get('_raw_variables')->get($entity_info['bundle_entity_type']); + } $this->bundle = $bundle; $this->adminPath = $this->entityManager->getAdminPath($this->entity_type, $this->bundle); diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Plugin/Derivative/FieldUiLocalTask.php b/core/modules/field_ui/lib/Drupal/field_ui/Plugin/Derivative/FieldUiLocalTask.php new file mode 100644 index 0000000..eb77b7e --- /dev/null +++ b/core/modules/field_ui/lib/Drupal/field_ui/Plugin/Derivative/FieldUiLocalTask.php @@ -0,0 +1,231 @@ +routeProvider = $route_provider; + $this->entityManager = $entity_manager; + $this->translationManager = $translation_manager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, $base_plugin_id) { + return new static( + $container->get('router.route_provider'), + $container->get('entity.manager'), + $container->get('string_translation') + ); + } + + /** + * {@inheritdoc} + */ + public function getDerivativeDefinitions(array $base_plugin_definition) { + $this->derivatives = array(); + + foreach ($this->entityManager->getDefinitions() as $entity_type => $entity_info) { + if ($entity_info['fieldable'] && isset($entity_info['links']['admin-form'])) { + $this->derivatives["overview_$entity_type"] = array( + 'route_name' => "field_ui.overview_$entity_type", + 'weight' => 1, + 'title' => $this->t('Manage fields'), + 'tab_root_id' => "field_ui.fields:overview_$entity_type", + ); + + // 'Manage form display' tab. + $this->derivatives["form_display_overview_$entity_type"] = array( + 'route_name' => "field_ui.form_display_overview_$entity_type", + 'weight' => 2, + 'title' => $this->t('Manage form display'), + 'tab_root_id' => "field_ui.fields:overview_$entity_type", + ); + + // 'Manage display' tab. + $this->derivatives["display_overview_$entity_type"] = array( + 'route_name' => "field_ui.display_overview_$entity_type", + 'weight' => 3, + 'title' => $this->t('Manage display'), + 'tab_root_id' => "field_ui.fields:overview_$entity_type", + ); + + // Field instance edit tab. + $this->derivatives["instance_edit_$entity_type"] = array( + 'route_name' => "field_ui.instance_edit_$entity_type", + 'title' => $this->t('Edit'), + 'tab_root_id' => "field_ui.fields:instance_edit_$entity_type", + ); + + // Field settings tab. + $this->derivatives["field_edit_$entity_type"] = array( + 'route_name' => "field_ui.field_edit_$entity_type", + 'title' => $this->t('Field settings'), + 'tab_root_id' => "field_ui.fields:instance_edit_$entity_type", + ); + + // View and form modes secondary tabs. + // The same base $path for the menu item (with a placeholder) can be + // used for all bundles of a given entity type; but depending on + // administrator settings, each bundle has a different set of view + // modes available for customisation. So we define menu items for all + // view modes, and use a route requirement to determine which ones are + // actually visible for a given bundle. + $this->derivatives['field_form_display_default_' . $entity_type] = array( + 'title' => 'Default', + 'route_name' => "field_ui.form_display_overview_$entity_type", + 'tab_root_id' => "field_ui.fields:overview_$entity_type", + 'tab_parent_id' => "field_ui.fields:form_display_overview_$entity_type", + ); + $this->derivatives['field_display_default_' . $entity_type] = array( + 'title' => 'Default', + 'route_name' => "field_ui.display_overview_$entity_type", + 'tab_root_id' => "field_ui.fields:overview_$entity_type", + 'tab_parent_id' => "field_ui.fields:display_overview_$entity_type", + ); + + // One local task for each form mode. + $weight = 0; + foreach (entity_get_form_modes($entity_type) as $form_mode => $form_mode_info) { + $this->derivatives['field_form_display_' . $form_mode . '_' . $entity_type] = array( + 'title' => $form_mode_info['label'], + 'route_name' => "field_ui.form_display_overview_$entity_type", + 'route_parameters' => array( + 'mode' => $form_mode, + ), + 'tab_root_id' => "field_ui.fields:overview_$entity_type", + 'tab_parent_id' => "field_ui.fields:form_display_overview_$entity_type", + 'weight' => $weight++, + ); + } + + // One local task for each view mode. + $weight = 0; + foreach (entity_get_view_modes($entity_type) as $view_mode => $form_mode_info) { + $this->derivatives['field_display_' . $view_mode . '_' . $entity_type] = array( + 'title' => $form_mode_info['label'], + 'route_name' => "field_ui.display_overview_$entity_type", + 'route_parameters' => array( + 'mode' => $view_mode, + ), + 'tab_root_id' => "field_ui.fields:overview_$entity_type", + 'tab_parent_id' => "field_ui.fields:display_overview_$entity_type", + 'weight' => $weight++, + ); + } + } + } + + foreach ($this->derivatives as &$entry) { + $entry += $base_plugin_definition; + } + + return $this->derivatives; + } + + /** + * Alters the tab_root_id definition for field_ui local tasks. + */ + public function alterLocalTasks(&$local_tasks) { + foreach ($this->entityManager->getDefinitions() as $entity_type => $entity_info) { + if ($entity_info['fieldable'] && isset($entity_info['links']['admin-form'])) { + if ($parent_task = $this->getPluginIdFromRoute($entity_info['links']['admin-form'], $local_tasks)) { + $local_tasks["field_ui.fields:overview_$entity_type"]['tab_root_id'] = $parent_task; + $local_tasks["field_ui.fields:form_display_overview_$entity_type"]['tab_root_id'] = $parent_task; + $local_tasks["field_ui.fields:display_overview_$entity_type"]['tab_root_id'] = $parent_task; + $local_tasks["field_ui.fields:field_form_display_default_$entity_type"]['tab_root_id'] = $parent_task; + $local_tasks["field_ui.fields:field_display_default_$entity_type"]['tab_root_id'] = $parent_task; + + foreach (entity_get_form_modes($entity_type) as $form_mode => $form_mode_info) { + $local_tasks['field_ui.fields:field_form_display_' . $form_mode . '_' . $entity_type]['tab_root_id'] = $parent_task; + } + + foreach (entity_get_view_modes($entity_type) as $view_mode => $form_mode_info) { + $local_tasks['field_ui.fields:field_display_' . $view_mode . '_' . $entity_type]['tab_root_id'] = $parent_task; + } + } + } + } + } + + /** + * Finds the local task ID of a route given the route name. + * + * @param string $route_name + * The route name. + * @param array $local_tasks + * An array of all local task definitions. + * + * @return string|null + * Returns the local task ID of the given route or NULL if none is found. + */ + protected function getPluginIdFromRoute($route_name, &$local_tasks) { + $local_task_id = NULL; + foreach ($local_tasks as $plugin_id => $local_task) { + if ($local_task['route_name'] == $route_name) { + $local_task_id = $plugin_id; + break; + } + } + + return $local_task_id; + } + + /** + * Translates a string to the current language or to a given language. + * + * See the t() documentation for details. + */ + protected function t($string, array $args = array(), array $options = array()) { + return $this->translationManager->translate($string, $args, $options); + } + +} 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 ff49c18..67de1ca 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 @@ -8,6 +8,7 @@ namespace Drupal\field_ui\Routing; use Drupal\Core\Entity\EntityManagerInterface; +use Drupal\Core\Routing\RouteProviderInterface; use Drupal\Core\Routing\RouteSubscriberBase; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; @@ -25,13 +26,23 @@ class RouteSubscriber extends RouteSubscriberBase { protected $manager; /** + * The route provider. + * + * @var \Drupal\Core\Routing\RouteProviderInterface + */ + protected $routeProvider; + + /** * Constructs a RouteSubscriber object. * * @param \Drupal\Core\Entity\EntityManagerInterface $manager * The entity type manager. + * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider + * The route provider. */ - public function __construct(EntityManagerInterface $manager) { + public function __construct(EntityManagerInterface $manager, RouteProviderInterface $route_provider) { $this->manager = $manager; + $this->routeProvider = $route_provider; } /** @@ -40,8 +51,8 @@ public function __construct(EntityManagerInterface $manager) { protected function routes(RouteCollection $collection) { foreach ($this->manager->getDefinitions() as $entity_type => $entity_info) { $defaults = array(); - if ($entity_info['fieldable'] && isset($entity_info['route_base_path'])) { - $path = $entity_info['route_base_path']; + if ($entity_info['fieldable'] && isset($entity_info['links']['admin-form'])) { + $path = $this->routeProvider->getRouteByName($entity_info['links']['admin-form'])->getPath(); $route = new Route( "$path/fields/{field_instance}", @@ -80,46 +91,26 @@ protected function routes(RouteCollection $collection) { $collection->add("field_ui.overview_$entity_type", $route); $route = new Route( - "$path/form-display", + "$path/form-display/{mode}", array( '_form' => '\Drupal\field_ui\FormDisplayOverview', '_title' => 'Manage form display', + 'mode' => NULL, ) + $defaults, - array('_permission' => 'administer ' . $entity_type . ' form display') + array('_field_ui_form_mode_access' => 'administer ' . $entity_type . ' form display') ); $collection->add("field_ui.form_display_overview_$entity_type", $route); - foreach (entity_get_form_modes($entity_type) as $form_mode => $form_mode_info) { - $route = new Route( - "$path/form-display/$form_mode", - array( - '_form' => '\Drupal\field_ui\FormDisplayOverview', - 'mode' => $form_mode, - ) + $defaults, - array('_field_ui_form_mode_access' => 'administer ' . $entity_type . ' form display')); - $collection->add("field_ui.form_display_overview_$entity_type" . '_'. $form_mode, $route); - } - $route = new Route( - "$path/display", + "$path/display/{mode}", array( '_form' => '\Drupal\field_ui\DisplayOverview', '_title' => 'Manage display', + 'mode' => NULL, ) + $defaults, - array('_permission' => 'administer ' . $entity_type . ' display') + array('_field_ui_view_mode_access' => 'administer ' . $entity_type . ' display') ); $collection->add("field_ui.display_overview_$entity_type", $route); - - foreach (entity_get_view_modes($entity_type) as $view_mode => $view_mode_info) { - $route = new Route( - "$path/display/$view_mode", - array( - '_form' => '\Drupal\field_ui\DisplayOverview', - 'mode' => $view_mode, - ) + $defaults, - array('_field_ui_view_mode_access' => 'administer ' . $entity_type . ' display')); - $collection->add("field_ui.display_overview_$entity_type" . '_' . $view_mode, $route); - } } } } diff --git a/core/modules/field_ui/tests/modules/field_ui_test/lib/Drupal/field_ui_test/Entity/FieldUITestNoBundle.php b/core/modules/field_ui/tests/modules/field_ui_test/lib/Drupal/field_ui_test/Entity/FieldUITestNoBundle.php index e6841c5..ede7799 100644 --- a/core/modules/field_ui/tests/modules/field_ui_test/lib/Drupal/field_ui_test/Entity/FieldUITestNoBundle.php +++ b/core/modules/field_ui/tests/modules/field_ui_test/lib/Drupal/field_ui_test/Entity/FieldUITestNoBundle.php @@ -20,8 +20,7 @@ * controllers = { * "storage" = "Drupal\Core\Entity\DatabaseStorageController" * }, - * fieldable = TRUE, - * route_base_path = "field-ui-test-no-bundle/manage" + * fieldable = TRUE * ) */ class FieldUITestNoBundle extends Entity { diff --git a/core/modules/node/lib/Drupal/node/Entity/Node.php b/core/modules/node/lib/Drupal/node/Entity/Node.php index f67d15b..dddecb3 100644 --- a/core/modules/node/lib/Drupal/node/Entity/Node.php +++ b/core/modules/node/lib/Drupal/node/Entity/Node.php @@ -49,12 +49,13 @@ * bundle_keys = { * "bundle" = "type" * }, - * route_base_path = "admin/structure/types/manage/{bundle}", + * bundle_entity_type = "node_type", * permission_granularity = "bundle", * links = { * "canonical" = "node.view", * "edit-form" = "node.page_edit", - * "version-history" = "node.revision_overview" + * "version-history" = "node.revision_overview", + * "admin-form" = "node.type_edit" * } * ) */ diff --git a/core/modules/node/node.local_tasks.yml b/core/modules/node/node.local_tasks.yml index 24d9ef2..ecf6298 100644 --- a/core/modules/node/node.local_tasks.yml +++ b/core/modules/node/node.local_tasks.yml @@ -16,3 +16,7 @@ node.revision_overview: tab_root_id: node.view title: 'Revisions' weight: 20 +node.type_edit: + title: 'Edit' + route_name: node.type_edit + tab_root_id: node.type_edit diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 438104d..6fcc21e 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -949,16 +949,6 @@ function node_menu() { 'title' => 'List', 'type' => MENU_DEFAULT_LOCAL_TASK, ); - $items['admin/structure/types/manage/%node_type'] = array( - 'title' => 'Edit content type', - 'title callback' => 'entity_page_label', - 'title arguments' => array(4), - 'route_name' => 'node.type_edit', - ); - $items['admin/structure/types/manage/%node_type/edit'] = array( - 'title' => 'Edit', - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); $items['node/add'] = array( 'title' => 'Add content', 'route_name' => 'node.add_page', diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTest.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTest.php index 5ba7091..f1dd221 100644 --- a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTest.php +++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTest.php @@ -37,7 +37,6 @@ * "bundle" = "type", * "label" = "name" * }, - * route_base_path = "admin/structure/entity-test/manage/{bundle}", * links = { * "canonical" = "entity_test.render", * "edit-form" = "entity_test.edit_entity_test" diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestMul.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestMul.php index c3f9212..7580934 100644 --- a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestMul.php +++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestMul.php @@ -36,7 +36,6 @@ * "bundle" = "type", * "label" = "name" * }, - * route_base_path = "entity_test_mul/structure/{bundle}", * links = { * "canonical" = "entity_test.edit_entity_test_mul", * "edit-form" = "entity_test.edit_entity_test_mul" diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Term.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Term.php index 0b7c3d6..a091d1a 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Term.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Term.php @@ -44,11 +44,12 @@ * bundle_keys = { * "bundle" = "vid" * }, + * bundle_entity_type = "taxonomy_vocabulary", * links = { * "canonical" = "taxonomy.term_page", - * "edit-form" = "taxonomy.term_edit" + * "edit-form" = "taxonomy.term_edit", + * "admin-form" = "taxonomy.overview_terms" * }, - * route_base_path = "admin/structure/taxonomy/manage/{bundle}", * permission_granularity = "bundle" * ) */ diff --git a/core/modules/user/lib/Drupal/user/Entity/User.php b/core/modules/user/lib/Drupal/user/Entity/User.php index fe90bfc..c667d20 100644 --- a/core/modules/user/lib/Drupal/user/Entity/User.php +++ b/core/modules/user/lib/Drupal/user/Entity/User.php @@ -32,7 +32,6 @@ * admin_permission = "administer user", * base_table = "users", * uri_callback = "user_uri", - * route_base_path = "admin/config/people/accounts", * label_callback = "user_label", * fieldable = TRUE, * translatable = TRUE, @@ -42,7 +41,8 @@ * }, * links = { * "canonical" = "user.view", - * "edit-form" = "user.edit" + * "edit-form" = "user.edit", + * "admin-form" = "user.account_settings" * } * ) */