diff --git a/core/lib/Drupal/Component/Plugin/Derivative/DeriverBase.php b/core/lib/Drupal/Component/Plugin/Derivative/DeriverBase.php index d4d7cb2..b2273d0 100644 --- a/core/lib/Drupal/Component/Plugin/Derivative/DeriverBase.php +++ b/core/lib/Drupal/Component/Plugin/Derivative/DeriverBase.php @@ -15,7 +15,9 @@ /** * List of derivative definitions. * - * @var array + * @var array[] + * Keys are base plugin IDs and values are arrays of which keys are plugin + * IDs and values are derivative definitions. */ protected $derivatives = array(); @@ -31,6 +33,6 @@ public function getDerivativeDefinition($derivative_id, $base_plugin_definition) * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { - return $this->derivatives; + return isset($this->derivatives[$base_plugin_definition['id']]) ? $this->derivatives[$base_plugin_definition['id']] : []; } } diff --git a/core/lib/Drupal/Core/Entity/Plugin/Derivative/SelectionBase.php b/core/lib/Drupal/Core/Entity/Plugin/Derivative/SelectionBase.php index 0752494..cf61d12 100644 --- a/core/lib/Drupal/Core/Entity/Plugin/Derivative/SelectionBase.php +++ b/core/lib/Drupal/Core/Entity/Plugin/Derivative/SelectionBase.php @@ -53,11 +53,16 @@ public static function create(ContainerInterface $container, $base_plugin_id) { * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { - foreach ($this->entityManager->getDefinitions() as $entity_type_id => $entity_type) { - $this->derivatives[$entity_type_id] = $base_plugin_definition; - $this->derivatives[$entity_type_id]['entity_types'] = array($entity_type_id); - $this->derivatives[$entity_type_id]['label'] = t('@entity_type selection', array('@entity_type' => $entity_type->getLabel())); - $this->derivatives[$entity_type_id]['base_plugin_label'] = (string) $base_plugin_definition['label']; + if (!array_key_exists($base_plugin_definition['id'], $this->derivatives)) { + $derivative_definitions = []; + foreach ($this->entityManager->getDefinitions() as $entity_type_id => $entity_type) { + $derivative_definitions[$entity_type_id] = $base_plugin_definition; + $derivative_definitions[$entity_type_id]['entity_types'] = array($entity_type_id); + $derivative_definitions[$entity_type_id]['label'] = t('@entity_type selection', + array('@entity_type' => $entity_type->getLabel())); + $derivative_definitions[$entity_type_id]['base_plugin_label'] = (string) $base_plugin_definition['label']; + } + $this->derivatives[$base_plugin_definition['id']] = $derivative_definitions; } return parent::getDerivativeDefinitions($base_plugin_definition); } diff --git a/core/modules/block_content/src/Plugin/Derivative/BlockContent.php b/core/modules/block_content/src/Plugin/Derivative/BlockContent.php index 115f2a4..2a84dfc 100644 --- a/core/modules/block_content/src/Plugin/Derivative/BlockContent.php +++ b/core/modules/block_content/src/Plugin/Derivative/BlockContent.php @@ -48,14 +48,18 @@ public static function create(ContainerInterface $container, $base_plugin_id) { * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { - $block_contents = $this->blockContentStorage->loadMultiple(); - /** @var $block_content \Drupal\block_content\Entity\BlockContent */ - foreach ($block_contents as $block_content) { - $this->derivatives[$block_content->uuid()] = $base_plugin_definition; - $this->derivatives[$block_content->uuid()]['admin_label'] = $block_content->label(); - $this->derivatives[$block_content->uuid()]['config_dependencies']['content'] = array( - $block_content->getConfigDependencyName() - ); + if (!array_key_exists($base_plugin_definition['id'], $this->derivatives)) { + $derivative_definitions = []; + $block_contents = $this->blockContentStorage->loadMultiple(); + /** @var $block_content \Drupal\block_content\Entity\BlockContent */ + foreach ($block_contents as $block_content) { + $derivative_definitions[$block_content->uuid()] = $base_plugin_definition; + $derivative_definitions[$block_content->uuid()]['admin_label'] = $block_content->label(); + $derivative_definitions[$block_content->uuid()]['config_dependencies']['content'] = array( + $block_content->getConfigDependencyName() + ); + } + $this->derivatives[$base_plugin_definition['id']] = $derivative_definitions; } return parent::getDerivativeDefinitions($base_plugin_definition); } diff --git a/core/modules/config_translation/src/Plugin/Derivative/ConfigTranslationContextualLinks.php b/core/modules/config_translation/src/Plugin/Derivative/ConfigTranslationContextualLinks.php index 5050b0d..1dcc82e 100644 --- a/core/modules/config_translation/src/Plugin/Derivative/ConfigTranslationContextualLinks.php +++ b/core/modules/config_translation/src/Plugin/Derivative/ConfigTranslationContextualLinks.php @@ -48,23 +48,27 @@ public static function create(ContainerInterface $container, $base_plugin_id) { * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { - // Create contextual links for all mappers. - $mappers = $this->mapperManager->getMappers(); - foreach ($mappers as $plugin_id => $mapper) { - // @todo Contextual groups do not map to entity types in a predictable - // way. See https://drupal.org/node/2134841 to make them predictable. - $group_name = $mapper->getContextualLinkGroup(); - if (empty($group_name)) { - continue; - } + if (!array_key_exists($base_plugin_definition['id'], $this->derivatives)) { + $derivative_definitions = []; + // Create contextual links for all mappers. + $mappers = $this->mapperManager->getMappers(); + foreach ($mappers as $plugin_id => $mapper) { + // @todo Contextual groups do not map to entity types in a predictable + // way. See https://drupal.org/node/2134841 to make them predictable. + $group_name = $mapper->getContextualLinkGroup(); + if (empty($group_name)) { + continue; + } - /** @var \Drupal\config_translation\ConfigMapperInterface $mapper */ - $route_name = $mapper->getOverviewRouteName(); - $this->derivatives[$route_name] = $base_plugin_definition; - $this->derivatives[$route_name]['config_translation_plugin_id'] = $plugin_id; - $this->derivatives[$route_name]['class'] = '\Drupal\config_translation\Plugin\Menu\ContextualLink\ConfigTranslationContextualLink'; - $this->derivatives[$route_name]['route_name'] = $route_name; - $this->derivatives[$route_name]['group'] = $group_name; + /** @var \Drupal\config_translation\ConfigMapperInterface $mapper */ + $route_name = $mapper->getOverviewRouteName(); + $derivative_definitions[$route_name] = $base_plugin_definition; + $derivative_definitions[$route_name]['config_translation_plugin_id'] = $plugin_id; + $derivative_definitions[$route_name]['class'] = '\Drupal\config_translation\Plugin\Menu\ContextualLink\ConfigTranslationContextualLink'; + $derivative_definitions[$route_name]['route_name'] = $route_name; + $derivative_definitions[$route_name]['group'] = $group_name; + } + $this->derivatives[$base_plugin_definition['id']] = $derivative_definitions; } return parent::getDerivativeDefinitions($base_plugin_definition); } diff --git a/core/modules/config_translation/src/Plugin/Derivative/ConfigTranslationLocalTasks.php b/core/modules/config_translation/src/Plugin/Derivative/ConfigTranslationLocalTasks.php index c36f72d..76d0e3a 100644 --- a/core/modules/config_translation/src/Plugin/Derivative/ConfigTranslationLocalTasks.php +++ b/core/modules/config_translation/src/Plugin/Derivative/ConfigTranslationLocalTasks.php @@ -58,18 +58,22 @@ public static function create(ContainerInterface $container, $base_plugin_id) { * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { - $mappers = $this->mapperManager->getMappers(); - foreach ($mappers as $plugin_id => $mapper) { - /** @var \Drupal\config_translation\ConfigMapperInterface $mapper */ - $route_name = $mapper->getOverviewRouteName(); - $base_route = $mapper->getBaseRouteName(); - if (!empty($base_route)) { - $this->derivatives[$route_name] = $base_plugin_definition; - $this->derivatives[$route_name]['config_translation_plugin_id'] = $plugin_id; - $this->derivatives[$route_name]['class'] = '\Drupal\config_translation\Plugin\Menu\LocalTask\ConfigTranslationLocalTask'; - $this->derivatives[$route_name]['route_name'] = $route_name; - $this->derivatives[$route_name]['base_route'] = $base_route; + if (!array_key_exists($base_plugin_definition['id'], $this->derivatives)) { + $derivative_definitions = []; + $mappers = $this->mapperManager->getMappers(); + foreach ($mappers as $plugin_id => $mapper) { + /** @var \Drupal\config_translation\ConfigMapperInterface $mapper */ + $route_name = $mapper->getOverviewRouteName(); + $base_route = $mapper->getBaseRouteName(); + if (!empty($base_route)) { + $derivative_definitions[$route_name] = $base_plugin_definition; + $derivative_definitions[$route_name]['config_translation_plugin_id'] = $plugin_id; + $derivative_definitions[$route_name]['class'] = '\Drupal\config_translation\Plugin\Menu\LocalTask\ConfigTranslationLocalTask'; + $derivative_definitions[$route_name]['route_name'] = $route_name; + $derivative_definitions[$route_name]['base_route'] = $base_route; + } } + $this->derivatives[$base_plugin_definition['id']] = $derivative_definitions; } return parent::getDerivativeDefinitions($base_plugin_definition); } diff --git a/core/modules/content_translation/src/Plugin/Derivative/ContentTranslationContextualLinks.php b/core/modules/content_translation/src/Plugin/Derivative/ContentTranslationContextualLinks.php index 9acf394..d16536e 100644 --- a/core/modules/content_translation/src/Plugin/Derivative/ContentTranslationContextualLinks.php +++ b/core/modules/content_translation/src/Plugin/Derivative/ContentTranslationContextualLinks.php @@ -50,11 +50,15 @@ public static function create(ContainerInterface $container, $base_plugin_id) { * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { - // Create contextual links for translatable entity types. - foreach ($this->contentTranslationManager->getSupportedEntityTypes() as $entity_type_id => $entity_type) { - $this->derivatives[$entity_type_id]['title'] = t('Translate'); - $this->derivatives[$entity_type_id]['route_name'] = "entity.$entity_type_id.content_translation_overview"; - $this->derivatives[$entity_type_id]['group'] = $entity_type_id; + if (!array_key_exists($base_plugin_definition['id'], $this->derivatives)) { + $derivative_definitions = []; + // Create contextual links for translatable entity types. + foreach ($this->contentTranslationManager->getSupportedEntityTypes() as $entity_type_id => $entity_type) { + $derivative_definitions[$entity_type_id]['title'] = t('Translate'); + $derivative_definitions[$entity_type_id]['route_name'] = "entity.$entity_type_id.content_translation_overview"; + $derivative_definitions[$entity_type_id]['group'] = $entity_type_id; + } + $this->derivatives[$base_plugin_definition['id']] = $derivative_definitions; } return parent::getDerivativeDefinitions($base_plugin_definition); } diff --git a/core/modules/content_translation/src/Plugin/Derivative/ContentTranslationLocalTasks.php b/core/modules/content_translation/src/Plugin/Derivative/ContentTranslationLocalTasks.php index 995de59..661a10c 100644 --- a/core/modules/content_translation/src/Plugin/Derivative/ContentTranslationLocalTasks.php +++ b/core/modules/content_translation/src/Plugin/Derivative/ContentTranslationLocalTasks.php @@ -58,18 +58,22 @@ public static function create(ContainerInterface $container, $base_plugin_id) { * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { - // Create tabs for all possible entity types. - foreach ($this->contentTranslationManager->getSupportedEntityTypes() as $entity_type_id => $entity_type) { - // Find the route name for the translation overview. - $translation_route_name = "entity.$entity_type_id.content_translation_overview"; + if (!array_key_exists($base_plugin_definition['id'], $this->derivatives)) { + $derivative_definitions = []; + // Create tabs for all possible entity types. + foreach ($this->contentTranslationManager->getSupportedEntityTypes() as $entity_type_id => $entity_type) { + // Find the route name for the translation overview. + $translation_route_name = "entity.$entity_type_id.content_translation_overview"; - $base_route_name = "entity.$entity_type_id.canonical"; - $this->derivatives[$translation_route_name] = array( - 'entity_type' => $entity_type_id, - 'title' => 'Translate', - 'route_name' => $translation_route_name, - 'base_route' => $base_route_name, - ) + $base_plugin_definition; + $base_route_name = "entity.$entity_type_id.canonical"; + $derivative_definitions[$translation_route_name] = array( + 'entity_type' => $entity_type_id, + 'title' => 'Translate', + 'route_name' => $translation_route_name, + 'base_route' => $base_route_name, + ) + $base_plugin_definition; + } + $this->derivatives[$base_plugin_definition['id']] = $derivative_definitions; } return parent::getDerivativeDefinitions($base_plugin_definition); } diff --git a/core/modules/language/src/Plugin/Derivative/LanguageBlock.php b/core/modules/language/src/Plugin/Derivative/LanguageBlock.php index 3c54c25..7c6e9a5 100644 --- a/core/modules/language/src/Plugin/Derivative/LanguageBlock.php +++ b/core/modules/language/src/Plugin/Derivative/LanguageBlock.php @@ -19,20 +19,25 @@ class LanguageBlock extends DeriverBase { * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { - $language_manager = \Drupal::languageManager(); - - if ($language_manager instanceof ConfigurableLanguageManagerInterface) { - $info = $language_manager->getDefinedLanguageTypesInfo(); - $configurable_types = $language_manager->getLanguageTypes(); - foreach ($configurable_types as $type) { - $this->derivatives[$type] = $base_plugin_definition; - $this->derivatives[$type]['admin_label'] = t('Language switcher (!type)', array('!type' => $info[$type]['name'])); - } - // If there is just one configurable type then change the title of the - // block. - if (count($configurable_types) == 1) { - $this->derivatives[reset($configurable_types)]['admin_label'] = t('Language switcher'); + if (!array_key_exists($base_plugin_definition['id'], $this->derivatives)) { + $derivative_definitions = []; + $language_manager = \Drupal::languageManager(); + + if ($language_manager instanceof ConfigurableLanguageManagerInterface) { + $info = $language_manager->getDefinedLanguageTypesInfo(); + $configurable_types = $language_manager->getLanguageTypes(); + foreach ($configurable_types as $type) { + $derivative_definitions[$type] = $base_plugin_definition; + $derivative_definitions[$type]['admin_label'] = t('Language switcher (!type)', + array('!type' => $info[$type]['name'])); + } + // If there is just one configurable type then change the title of the + // block. + if (count($configurable_types) == 1) { + $derivative_definitions[reset($configurable_types)]['admin_label'] = t('Language switcher'); + } } + $this->derivatives[$base_plugin_definition['id']] = $derivative_definitions; } return parent::getDerivativeDefinitions($base_plugin_definition); diff --git a/core/modules/system/tests/modules/entity_test/src/Plugin/Derivative/EntityTestLocalTasks.php b/core/modules/system/tests/modules/entity_test/src/Plugin/Derivative/EntityTestLocalTasks.php index e4f8e49..5c46686 100644 --- a/core/modules/system/tests/modules/entity_test/src/Plugin/Derivative/EntityTestLocalTasks.php +++ b/core/modules/system/tests/modules/entity_test/src/Plugin/Derivative/EntityTestLocalTasks.php @@ -18,19 +18,22 @@ class EntityTestLocalTasks extends DeriverBase { * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { - $this->derivatives = array(); - $types = entity_test_entity_types(ENTITY_TEST_TYPES_ROUTING); - - foreach($types as $entity_type) { - $this->derivatives[$entity_type . '.canonical'] = array(); - $this->derivatives[$entity_type . '.canonical']['base_route'] = "entity.$entity_type.canonical"; - $this->derivatives[$entity_type . '.canonical']['route_name'] = "entity.$entity_type.canonical"; - $this->derivatives[$entity_type . '.canonical']['title'] = 'View'; - - $this->derivatives[$entity_type . '.edit'] = array(); - $this->derivatives[$entity_type . '.edit']['base_route'] = "entity.$entity_type.canonical"; - $this->derivatives[$entity_type . '.edit']['route_name'] = "entity.$entity_type.edit_form"; - $this->derivatives[$entity_type . '.edit']['title'] = 'Edit'; + if (!array_key_exists($base_plugin_definition['id'], $this->derivatives)) { + $derivative_definitions = []; + $types = entity_test_entity_types(ENTITY_TEST_TYPES_ROUTING); + + foreach ($types as $entity_type) { + $derivative_definitions[$entity_type . '.canonical'] = array(); + $derivative_definitions[$entity_type . '.canonical']['base_route'] = "entity.$entity_type.canonical"; + $derivative_definitions[$entity_type . '.canonical']['route_name'] = "entity.$entity_type.canonical"; + $derivative_definitions[$entity_type . '.canonical']['title'] = 'View'; + + $derivative_definitions[$entity_type . '.edit'] = array(); + $derivative_definitions[$entity_type . '.edit']['base_route'] = "entity.$entity_type.canonical"; + $derivative_definitions[$entity_type . '.edit']['route_name'] = "entity.$entity_type.edit_form"; + $derivative_definitions[$entity_type . '.edit']['title'] = 'Edit'; + } + $this->derivatives[$base_plugin_definition['id']] = $derivative_definitions; } return parent::getDerivativeDefinitions($base_plugin_definition); diff --git a/core/modules/views/src/Plugin/Derivative/DefaultWizardDeriver.php b/core/modules/views/src/Plugin/Derivative/DefaultWizardDeriver.php index f7610f2..005b9bf 100644 --- a/core/modules/views/src/Plugin/Derivative/DefaultWizardDeriver.php +++ b/core/modules/views/src/Plugin/Derivative/DefaultWizardDeriver.php @@ -20,19 +20,22 @@ class DefaultWizardDeriver extends DeriverBase { * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { - $views_data = Views::viewsData(); - $base_tables = array_keys($views_data->fetchBaseTables()); - $this->derivatives = array(); - foreach ($base_tables as $table) { - $views_info = $views_data->get($table); - if (empty($views_info['table']['wizard_id'])) { - $this->derivatives[$table] = array( - 'id' => 'standard', - 'base_table' => $table, - 'title' => $views_info['table']['base']['title'], - 'class' => 'Drupal\views\Plugin\views\wizard\Standard' - ); + if (!array_key_exists($base_plugin_definition['id'], $this->derivatives)) { + $derivative_definitions = []; + $views_data = Views::viewsData(); + $base_tables = array_keys($views_data->fetchBaseTables()); + foreach ($base_tables as $table) { + $views_info = $views_data->get($table); + if (empty($views_info['table']['wizard_id'])) { + $derivative_definitions[$table] = array( + 'id' => 'standard', + 'base_table' => $table, + 'title' => $views_info['table']['base']['title'], + 'class' => 'Drupal\views\Plugin\views\wizard\Standard' + ); + } } + $this->derivatives[$base_plugin_definition['id']] = $derivative_definitions; } return parent::getDerivativeDefinitions($base_plugin_definition); } diff --git a/core/tests/Drupal/Tests/Component/Plugin/Derivative/DeriverBaseTest.php b/core/tests/Drupal/Tests/Component/Plugin/Derivative/DeriverBaseTest.php index 63b4c2b..5e51fa6 100644 --- a/core/tests/Drupal/Tests/Component/Plugin/Derivative/DeriverBaseTest.php +++ b/core/tests/Drupal/Tests/Component/Plugin/Derivative/DeriverBaseTest.php @@ -25,16 +25,23 @@ class DeriverBaseTest extends UnitTestCase { */ public function providerGetDerivativeDefinition() { $derivative_id = $this->randomMachineName(); + $base_id = $this->randomMachineName(); $derivative_definitions = [ - $derivative_id => [ - 'id' => $this->randomMachineName() . ':' . $derivative_id, + $base_id => [ + $derivative_id => [ + 'id' => $this->randomMachineName() . ':' . $derivative_id, + ], ], ]; + $base_definition = [ + 'id' => $base_id, + ]; + return [ - [$derivative_definitions[$derivative_id], $derivative_definitions, $derivative_id], - [NULL, $derivative_definitions, $this->randomMachineName()], + [$derivative_definitions[$base_id][$derivative_id], $derivative_definitions, $derivative_id, $base_definition], + [NULL, $derivative_definitions, $this->randomMachineName(), $base_definition], ]; } @@ -42,10 +49,10 @@ public function providerGetDerivativeDefinition() { * @covers ::getDerivativeDefinition * @dataProvider providerGetDerivativeDefinition */ - public function testGetDerivativeDefinition($expected_derivative_definition, $derivative_definitions, $derivative_id) { + public function testGetDerivativeDefinition($expected_derivative_definition, $derivative_definitions, $derivative_id, $base_definition) { $deriver = new DeriverBaseTestDeriverBaseDummy($derivative_definitions); - $derivative_definition = $deriver->getDerivativeDefinition($derivative_id, []); + $derivative_definition = $deriver->getDerivativeDefinition($derivative_id, $base_definition); $this->assertSame($expected_derivative_definition, $derivative_definition); }