From f1a52222a7b55cf3ce61fa2f6d8825abe9a06458 Mon Sep 17 00:00:00 2001 From: Dave Long <dave@longwaveconsulting.com> Date: Fri, 21 Jul 2023 10:54:16 +0200 Subject: [PATCH] Issue #3372097 by srishtiiee, lauriii, larowlan, longwave, tedbow: Consider replacing hook_field_type_category_info with YML based plugin discovery --- core/core.field_type_categories.yml | 18 ++++ core/core.services.yml | 6 +- .../Core/Field/FallbackFieldTypeCategory.php | 22 +++++ .../Drupal/Core/Field/FieldTypeCategory.php | 36 ++++++++ .../Core/Field/FieldTypeCategoryInterface.php | 36 ++++++++ .../Core/Field/FieldTypeCategoryManager.php | 85 +++++++++++++++++++ .../FieldTypeCategoryManagerInterface.php | 11 +++ .../Core/Field/FieldTypePluginManager.php | 12 ++- core/modules/field/field.api.php | 25 ++++++ core/modules/field/field.module | 28 ------ ...eld_plugins_test.field_type_categories.yml | 4 + .../Kernel/FieldTypeCategoryDiscoveryTest.php | 41 +++++++++ core/modules/field_ui/field_ui.api.php | 26 ------ .../field_ui/src/Form/FieldStorageAddForm.php | 48 +++++------ .../file/file.field_type_categories.yml | 4 + core/modules/file/file.module | 13 --- .../options/options.field_type_categories.yml | 4 + core/modules/options/options.module | 13 --- .../text/text.field_type_categories.yml | 4 + core/modules/text/text.module | 13 --- .../Field/BaseFieldDefinitionTestBase.php | 5 +- 21 files changed, 332 insertions(+), 122 deletions(-) create mode 100644 core/core.field_type_categories.yml create mode 100644 core/lib/Drupal/Core/Field/FallbackFieldTypeCategory.php create mode 100644 core/lib/Drupal/Core/Field/FieldTypeCategory.php create mode 100644 core/lib/Drupal/Core/Field/FieldTypeCategoryInterface.php create mode 100644 core/lib/Drupal/Core/Field/FieldTypeCategoryManager.php create mode 100644 core/lib/Drupal/Core/Field/FieldTypeCategoryManagerInterface.php create mode 100644 core/modules/field/tests/modules/field_plugins_test/field_plugins_test.field_type_categories.yml create mode 100644 core/modules/field/tests/src/Kernel/FieldTypeCategoryDiscoveryTest.php create mode 100644 core/modules/file/file.field_type_categories.yml create mode 100644 core/modules/options/options.field_type_categories.yml create mode 100644 core/modules/text/text.field_type_categories.yml diff --git a/core/core.field_type_categories.yml b/core/core.field_type_categories.yml new file mode 100644 index 000000000000..c71b43d4b54a --- /dev/null +++ b/core/core.field_type_categories.yml @@ -0,0 +1,18 @@ +plain_text: + label: 'Plain text' + description: 'Text field that does not support markup.' + weight: -50 +number: + label: 'Number' + description: 'Field to store number. I.e. id, price, or quantity.' + weight: -40 +reference: + label: 'Reference' + description: 'Field to reference other content.' + weight: -30 +date_time: + label: 'Date and time' + description: 'Field to store date and time values.' + weight: -10 +general: + class: \Drupal\Core\Field\FallbackFieldTypeCategory diff --git a/core/core.services.yml b/core/core.services.yml index cce73e7794e1..e84dfbb29eac 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -744,8 +744,12 @@ services: Drupal\Core\Block\BlockManagerInterface: '@plugin.manager.block' plugin.manager.field.field_type: class: Drupal\Core\Field\FieldTypePluginManager - arguments: ['@container.namespaces', '@cache.discovery', '@module_handler', '@typed_data_manager'] + arguments: ['@container.namespaces', '@cache.discovery', '@module_handler', '@typed_data_manager', '@plugin.manager.field.field_type_category'] Drupal\Core\Field\FieldTypePluginManagerInterface: '@plugin.manager.field.field_type' + plugin.manager.field.field_type_category: + class: \Drupal\Core\Field\FieldTypeCategoryManager + arguments: [ '%app.root%', '@module_handler', '@cache.discovery' ] + Drupal\Core\Field\FieldTypeCategoryManagerInterface: '@plugin.manager.field.field_type_category' plugin.manager.field.widget: class: Drupal\Core\Field\WidgetPluginManager arguments: ['@container.namespaces', '@cache.discovery', '@module_handler', '@plugin.manager.field.field_type'] diff --git a/core/lib/Drupal/Core/Field/FallbackFieldTypeCategory.php b/core/lib/Drupal/Core/Field/FallbackFieldTypeCategory.php new file mode 100644 index 000000000000..1a83aa073740 --- /dev/null +++ b/core/lib/Drupal/Core/Field/FallbackFieldTypeCategory.php @@ -0,0 +1,22 @@ +<?php + +namespace Drupal\Core\Field; + +/** + * Fallback plugin class for FieldTypeCategoryManager. + */ +class FallbackFieldTypeCategory extends FieldTypeCategory { + + /** + * {@inheritdoc} + */ + public function __construct(array $configuration) { + $plugin_definition = [ + 'label' => $configuration['label'] ?? '', + 'description' => $configuration['description'] ?? '', + 'weight' => $configuration['weight'] ?? 0, + ]; + parent::__construct($configuration, $configuration['unique_identifier'], $plugin_definition); + } + +} diff --git a/core/lib/Drupal/Core/Field/FieldTypeCategory.php b/core/lib/Drupal/Core/Field/FieldTypeCategory.php new file mode 100644 index 000000000000..ac04b5124947 --- /dev/null +++ b/core/lib/Drupal/Core/Field/FieldTypeCategory.php @@ -0,0 +1,36 @@ +<?php + +namespace Drupal\Core\Field; + +use Drupal\Core\Plugin\PluginBase; +use Drupal\Core\StringTranslation\TranslatableMarkup; + +/** + * Default object used for field_type_categories plugins. + * + * @see \Drupal\Core\Field\FieldTypeCategoryManager + */ +class FieldTypeCategory extends PluginBase implements FieldTypeCategoryInterface { + + /** + * {@inheritdoc} + */ + public function getLabel(): TranslatableMarkup { + return $this->pluginDefinition['label']; + } + + /** + * {@inheritdoc} + */ + public function getDescription(): TranslatableMarkup { + return $this->pluginDefinition['description']; + } + + /** + * {@inheritdoc} + */ + public function getWeight(): int { + return $this->pluginDefinition['weight']; + } + +} diff --git a/core/lib/Drupal/Core/Field/FieldTypeCategoryInterface.php b/core/lib/Drupal/Core/Field/FieldTypeCategoryInterface.php new file mode 100644 index 000000000000..e9a1a0d21a85 --- /dev/null +++ b/core/lib/Drupal/Core/Field/FieldTypeCategoryInterface.php @@ -0,0 +1,36 @@ +<?php + +namespace Drupal\Core\Field; + +use Drupal\Core\StringTranslation\TranslatableMarkup; + +/** + * Provides an object that returns the category info about the field type. + */ +interface FieldTypeCategoryInterface { + + /** + * Returns the field group label. + * + * @return \Drupal\Core\StringTranslation\TranslatableMarkup + * The category label. + */ + public function getLabel(): TranslatableMarkup; + + /** + * Returns the field group description. + * + * @return \Drupal\Core\StringTranslation\TranslatableMarkup + * The category description. + */ + public function getDescription(): TranslatableMarkup; + + /** + * Returns the field group weight. + * + * @return int + * The weight. + */ + public function getWeight(): int; + +} diff --git a/core/lib/Drupal/Core/Field/FieldTypeCategoryManager.php b/core/lib/Drupal/Core/Field/FieldTypeCategoryManager.php new file mode 100644 index 000000000000..81a246751ebc --- /dev/null +++ b/core/lib/Drupal/Core/Field/FieldTypeCategoryManager.php @@ -0,0 +1,85 @@ +<?php + +namespace Drupal\Core\Field; + +use Drupal\Component\Plugin\FallbackPluginManagerInterface; +use Drupal\Core\Cache\CacheBackendInterface; +use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Plugin\Discovery\YamlDiscovery; +use Drupal\Core\Plugin\DefaultPluginManager; + +/** + * Defines a field type category info plugin manager. + * + * A module can define field type categories in a + * MODULE_NAME.field_type_categories.yml file contained in the module's + * base directory. Each plugin has the following structure: + * @code + * CATEGORY_NAME: + * label: STRING + * description: STRING + * weight: INTEGER + * @endcode + * For example: + * @code + * text: + * label: Text + * description: Text fields. + * weight: 2 + * @endcode + * + * @see \Drupal\Core\Field\FieldTypeCategoryInterface + * @see \Drupal\Core\Field\FieldTypeCategory + * @see \hook_field_type_category_info_alter + */ +class FieldTypeCategoryManager extends DefaultPluginManager implements FieldTypeCategoryManagerInterface, FallbackPluginManagerInterface { + + /** + * {@inheritdoc} + */ + protected $defaults = [ + 'label' => '', + 'description' => '', + 'weight' => 0, + 'class' => FieldTypeCategory::class, + ]; + + /** + * Constructs a new FieldTypeCategoryManager. + * + * @param string $root + * The app root. + * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler + * The module handler. + * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend + * The cache backend. + */ + public function __construct(protected readonly string $root, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend) { + $this->moduleHandler = $module_handler; + $this->alterInfo('field_type_category_info'); + $this->setCacheBackend($cache_backend, 'field_type_category_info_plugins'); + } + + /** + * {@inheritdoc} + */ + protected function getDiscovery(): YamlDiscovery { + if (!isset($this->discovery)) { + $directories = ['core' => $this->root . '/core']; + $directories += $this->moduleHandler->getModuleDirectories(); + $this->discovery = new YamlDiscovery('field_type_categories', $directories); + $this->discovery + ->addTranslatableProperty('label') + ->addTranslatableProperty('description'); + } + return $this->discovery; + } + + /** + * {@inheritdoc} + */ + public function getFallbackPluginId($plugin_id, array $configuration = []): string { + return 'general'; + } + +} diff --git a/core/lib/Drupal/Core/Field/FieldTypeCategoryManagerInterface.php b/core/lib/Drupal/Core/Field/FieldTypeCategoryManagerInterface.php new file mode 100644 index 000000000000..dc8dae960d33 --- /dev/null +++ b/core/lib/Drupal/Core/Field/FieldTypeCategoryManagerInterface.php @@ -0,0 +1,11 @@ +<?php + +namespace Drupal\Core\Field; + +use Drupal\Component\Plugin\PluginManagerInterface; + +/** + * Defines an interface for field type category managers. + */ +interface FieldTypeCategoryManagerInterface extends PluginManagerInterface { +} diff --git a/core/lib/Drupal/Core/Field/FieldTypePluginManager.php b/core/lib/Drupal/Core/Field/FieldTypePluginManager.php index ee68da04e430..81160c701cb2 100644 --- a/core/lib/Drupal/Core/Field/FieldTypePluginManager.php +++ b/core/lib/Drupal/Core/Field/FieldTypePluginManager.php @@ -46,12 +46,18 @@ class FieldTypePluginManager extends DefaultPluginManager implements FieldTypePl * The module handler. * @param \Drupal\Core\TypedData\TypedDataManagerInterface $typed_data_manager * The typed data manager. + * @param \Drupal\Core\Field\FieldTypeCategoryManagerInterface|null $fieldTypeCategoryManager + * The field type category plugin manager. */ - public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, TypedDataManagerInterface $typed_data_manager) { + public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, TypedDataManagerInterface $typed_data_manager, protected ?FieldTypeCategoryManagerInterface $fieldTypeCategoryManager = NULL) { parent::__construct('Plugin/Field/FieldType', $namespaces, $module_handler, 'Drupal\Core\Field\FieldItemInterface', 'Drupal\Core\Field\Annotation\FieldType'); $this->alterInfo('field_info'); $this->setCacheBackend($cache_backend, 'field_types_plugins'); $this->typedDataManager = $typed_data_manager; + if ($this->fieldTypeCategoryManager === NULL) { + @trigger_error('Calling FieldTypePluginManager::__construct() without the $fieldTypeCategoryManager argument is deprecated in drupal:10.2.0 and will be required in drupal:11.0.0. See https://www.drupal.org/node/3375737', E_USER_DEPRECATED); + $this->fieldTypeCategoryManager = \Drupal::service('plugin.manager.field.field_type_category'); + } } /** @@ -162,10 +168,10 @@ public function getFieldSettingsSummary(FieldDefinitionInterface $field_definiti */ public function getGroupedDefinitions(array $definitions = NULL, $label_key = 'label') { $grouped_categories = $this->getGroupedDefinitionsTrait($definitions, $label_key); - $category_info = \Drupal::moduleHandler()->invokeAll('field_type_category_info'); + $category_info = $this->fieldTypeCategoryManager->getDefinitions(); foreach ($grouped_categories as $group => $definitions) { if (!isset($category_info[$group]) && $group !== static::DEFAULT_CATEGORY) { - assert(FALSE, "\"$group\" must be defined in hook_field_type_category_info()."); + assert(FALSE, "\"$group\" must be defined in MODULE_NAME.field_type_categories.yml"); $grouped_categories[static::DEFAULT_CATEGORY] += $definitions; unset($grouped_categories[$group]); } diff --git a/core/modules/field/field.api.php b/core/modules/field/field.api.php index e8b07637b304..ed9b86a8afff 100644 --- a/core/modules/field/field.api.php +++ b/core/modules/field/field.api.php @@ -410,6 +410,31 @@ function hook_field_purge_field(\Drupal\field\Entity\FieldConfig $field) { ->execute(); } +/** + * Allows modules to alter the field type category information. + * + * This hook provides a way for modules to modify or add to the existing + * category information. Modules can use this hook to modify the properties of + * existing categories. It can also be used to define custom field type + * categories although the use of YAML-based plugins should be preferred over + * the hook. + * + * @param array &$categories + * An associative array of field type categories, keyed by category machine + * name. + * + * @see \Drupal\Core\Field\FieldTypeCategoryManager + */ +function hook_field_type_category_info_alter(array &$categories) { + // Modify or add field type categories. + $categories['my_custom_category'] = [ + 'label' => 'My Custom Category', + 'description' => 'This is a custom category for my field types.', + ]; + // Modify the properties of an existing category. + $categories['text']['description'] = 'Modified Text'; +} + /** * @} End of "addtogroup field_purge". */ diff --git a/core/modules/field/field.module b/core/modules/field/field.module index 3b637910a88f..d5a8182048a6 100644 --- a/core/modules/field/field.module +++ b/core/modules/field/field.module @@ -426,31 +426,3 @@ function field_field_config_presave(FieldConfigInterface $field) { ]); } } - -/** - * Returns field category properties. - */ -function field_field_type_category_info() { - return [ - 'plain_text' => [ - 'label' => t('Plain text'), - 'description' => t('Text field that does not support markup.'), - 'weight' => -50, - ], - 'number' => [ - 'label' => t('Number'), - 'description' => t('Field to store number. I.e. id, price, or quantity.'), - 'weight' => -40, - ], - 'reference' => [ - 'label' => t('Reference'), - 'description' => t('Field to reference other content.'), - 'weight' => -30, - ], - 'date_time' => [ - 'label' => t('Date and time'), - 'description' => t('Field to store date and time values.'), - 'weight' => -10, - ], - ]; -} diff --git a/core/modules/field/tests/modules/field_plugins_test/field_plugins_test.field_type_categories.yml b/core/modules/field/tests/modules/field_plugins_test/field_plugins_test.field_type_categories.yml new file mode 100644 index 000000000000..35b725c68630 --- /dev/null +++ b/core/modules/field/tests/modules/field_plugins_test/field_plugins_test.field_type_categories.yml @@ -0,0 +1,4 @@ +test_category: + label: 'Test category' + description: 'This is a test field type category.' + weight: -10 diff --git a/core/modules/field/tests/src/Kernel/FieldTypeCategoryDiscoveryTest.php b/core/modules/field/tests/src/Kernel/FieldTypeCategoryDiscoveryTest.php new file mode 100644 index 000000000000..0dbf670fdcbe --- /dev/null +++ b/core/modules/field/tests/src/Kernel/FieldTypeCategoryDiscoveryTest.php @@ -0,0 +1,41 @@ +<?php + +namespace Drupal\Tests\field\Kernel; + +use Drupal\KernelTests\KernelTestBase; + +/** + * Tests discovery of field type categories provided by modules. + * + * @group field + */ +class FieldTypeCategoryDiscoveryTest extends KernelTestBase { + + /** + * Modules to install. + * + * @var array + */ + protected static $modules = [ + 'field_plugins_test', + ]; + + /** + * Tests custom field type categories created by modules. + */ + public function testFieldTypeCategories() { + $category = \Drupal::service('plugin.manager.field.field_type_category')->createInstance('test_category'); + $expected = [ + 'Test category', + 'This is a test field type category.', + -10, + ]; + + $this->assertSame($expected, [ + (string) $category->getLabel(), + (string) $category->getDescription(), + $category->getWeight(), + ]); + } + +} diff --git a/core/modules/field_ui/field_ui.api.php b/core/modules/field_ui/field_ui.api.php index 9437339a85f6..87f55ae6e1a5 100644 --- a/core/modules/field_ui/field_ui.api.php +++ b/core/modules/field_ui/field_ui.api.php @@ -122,32 +122,6 @@ function hook_field_widget_settings_summary_alter(array &$summary, array $contex } } -/** - * Provides information about field categories used for the UI. - * - * @return array - * Returns an array with the field category information. - */ -function hook_field_type_category_info() { - return [ - 'selection_list' => [ - 'label' => t('Selection list'), - 'description' => t('Field to select from predefined options.'), - 'weight' => -30, - ], - 'number' => [ - 'label' => t('Number'), - 'description' => t('Field to store number. I.e. id, price, or quantity.'), - 'weight' => -20, - ], - 'date_time' => [ - 'label' => t('Date and time'), - 'description' => t('Field to store date and time values.'), - 'weight' => -12, - ], - ]; -} - /** * @} End of "addtogroup field_types". */ diff --git a/core/modules/field_ui/src/Form/FieldStorageAddForm.php b/core/modules/field_ui/src/Form/FieldStorageAddForm.php index 52d633a01d5a..2134c00c35da 100644 --- a/core/modules/field_ui/src/Form/FieldStorageAddForm.php +++ b/core/modules/field_ui/src/Form/FieldStorageAddForm.php @@ -8,7 +8,8 @@ use Drupal\Core\Entity\EntityDisplayRepositoryInterface; use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Field\FieldTypePluginManager; +use Drupal\Core\Field\FallbackFieldTypeCategory; +use Drupal\Core\Field\FieldTypeCategoryManagerInterface; use Drupal\Core\Field\FieldTypePluginManagerInterface; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; @@ -83,17 +84,23 @@ class FieldStorageAddForm extends FormBase { * The field type plugin manager. * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * The configuration factory. - * @param \Drupal\Core\Entity\EntityFieldManagerInterface|null $entity_field_manager + * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager * (optional) The entity field manager. * @param \Drupal\Core\Entity\EntityDisplayRepositoryInterface $entity_display_repository * (optional) The entity display repository. + * @param \Drupal\Core\Field\FieldTypeCategoryManagerInterface|null $fieldTypeCategoryManager + * The field type category plugin manager. */ - public function __construct(EntityTypeManagerInterface $entity_type_manager, FieldTypePluginManagerInterface $field_type_plugin_manager, ConfigFactoryInterface $config_factory, EntityFieldManagerInterface $entity_field_manager = NULL, EntityDisplayRepositoryInterface $entity_display_repository = NULL) { + public function __construct(EntityTypeManagerInterface $entity_type_manager, FieldTypePluginManagerInterface $field_type_plugin_manager, ConfigFactoryInterface $config_factory, EntityFieldManagerInterface $entity_field_manager, EntityDisplayRepositoryInterface $entity_display_repository, protected ?FieldTypeCategoryManagerInterface $fieldTypeCategoryManager = NULL) { $this->entityTypeManager = $entity_type_manager; $this->fieldTypePluginManager = $field_type_plugin_manager; $this->configFactory = $config_factory; $this->entityFieldManager = $entity_field_manager; $this->entityDisplayRepository = $entity_display_repository; + if ($this->fieldTypeCategoryManager === NULL) { + @trigger_error('Calling FieldStorageAddForm::__construct() without the $fieldTypeCategoryManager argument is deprecated in drupal:10.2.0 and will be required in drupal:11.0.0. See https://www.drupal.org/node/3375740', E_USER_DEPRECATED); + $this->fieldTypeCategoryManager = \Drupal::service('plugin.manager.field.field_type_category'); + } } /** @@ -112,7 +119,8 @@ public static function create(ContainerInterface $container) { $container->get('plugin.manager.field.field_type'), $container->get('config.factory'), $container->get('entity_field.manager'), - $container->get('entity_display.repository') + $container->get('entity_display.repository'), + $container->get('plugin.manager.field.field_type_category'), ); } @@ -150,16 +158,12 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t $field_type_options = $unique_definitions = []; $grouped_definitions = $this->fieldTypePluginManager->getGroupedDefinitions($this->fieldTypePluginManager->getUiDefinitions()); // Invoke a hook to get category properties. - $category_info = \Drupal::moduleHandler()->invokeAll('field_type_category_info'); foreach ($grouped_definitions as $category => $field_types) { foreach ($field_types as $name => $field_type) { $unique_definitions[$category][$name] = ['unique_identifier' => $name] + $field_type; - if (isset($category_info[$category])) { - // Get the category label from the hook if it is defined in the hook. - $field_type_options[$category_info[$category]['label']->render()] = ['unique_identifier' => $name] + $field_type; - } - else { - $field_type_options[$field_type['label']->render()] = ['unique_identifier' => $name] + $field_type; + if ($this->fieldTypeCategoryManager->hasDefinition($category)) { + $category_plugin = $this->fieldTypeCategoryManager->createInstance($category, $unique_definitions[$category][$name]); + $field_type_options[$category_plugin->getPluginId()] = ['unique_identifier' => $name] + $field_type; } } } @@ -177,12 +181,9 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t ]; $field_type_options_radios = []; foreach ($field_type_options as $field_option => $val) { - // Boolean flag for whether a field option is to be displayed as a group. - // When an option should be displayed as a group, its category value - // is a string id instead of TranslatableMarkup. The string id maps - // to the values returned by the field_type_category_info hook. - $display_as_group = is_string($val['category']) && $val['category'] !== FieldTypePluginManager::DEFAULT_CATEGORY; - $option_info = $display_as_group ? $category_info[$val['category']] : $val; + /** @var \Drupal\Core\Field\FieldTypeCategoryInterface $category_info */ + $category_info = $this->fieldTypeCategoryManager->createInstance($val['category'], $val); + $display_as_group = !($category_info instanceof FallbackFieldTypeCategory); $cleaned_class_name = Html::getClass($val['unique_identifier']); $field_type_options_radios[$field_option] = [ '#type' => 'container', @@ -190,7 +191,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t 'class' => ['field-option', 'js-click-to-select'], 'checked' => $this->getRequest()->request->get('new_storage_type') !== NULL && $this->getRequest()->request->get('new_storage_type') == ($display_as_group ? $val['category'] : $val['unique_identifier']), ], - '#weight' => $option_info['weight'] ?? 1, + '#weight' => $category_info->getWeight(), 'thumb' => [ '#type' => 'container', '#attributes' => [ @@ -211,7 +212,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t ], 'radio' => [ '#type' => 'radio', - '#title' => $field_option, + '#title' => $category_info->getLabel(), '#parents' => ['new_storage_type'], '#title_display' => 'before', '#description_display' => 'before', @@ -234,7 +235,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t '#attributes' => [ 'class' => ['field-option__description'], ], - '#markup' => $option_info['description'] ?? NULL, + '#markup' => $category_info->getDescription(), ], '#variant' => 'field-option', ], @@ -261,14 +262,13 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t $selected_field_type = NULL; foreach ($field_type_options_radios as $field_type_options_radio) { if ($field_type_options_radio['#attributes']['checked']) { - $selected_field_label = $field_type_options_radio['radio']['#title']; $selected_field_type = $field_type_options_radio['radio']['#return_value']; $form_state->setValue('selected_field_type', $selected_field_type); break; } } - if (isset($selected_field_label)) { - $group_display = $field_type_options_radios[$selected_field_label]['#data']['#group_display']; + if (isset($selected_field_type)) { + $group_display = $field_type_options_radios[$selected_field_type]['#data']['#group_display']; if ($group_display) { $form['group_field_options_wrapper']['label'] = [ '#type' => 'label', @@ -286,7 +286,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t $radio_element = [ '#type' => 'radio', '#theme_wrappers' => ['form_element__new_storage_type'], - '#title' => $option['label']->render(), + '#title' => $option['label'], '#description' => [ '#theme' => 'item_list', '#items' => $unique_definitions[$selected_field_type][$option_key]['description'], diff --git a/core/modules/file/file.field_type_categories.yml b/core/modules/file/file.field_type_categories.yml new file mode 100644 index 000000000000..efb40e7eeb03 --- /dev/null +++ b/core/modules/file/file.field_type_categories.yml @@ -0,0 +1,4 @@ +file_upload: + label: 'File upload' + description: 'Field to upload any type of files.' + weight: -15 diff --git a/core/modules/file/file.module b/core/modules/file/file.module index 1fa00345e651..fa17d9c8de81 100644 --- a/core/modules/file/file.module +++ b/core/modules/file/file.module @@ -1553,19 +1553,6 @@ function file_field_find_file_reference_column(FieldDefinitionInterface $field) return FALSE; } -/** - * Implements hook_field_type_category_info(). - */ -function file_field_type_category_info() { - return [ - 'file_upload' => [ - 'label' => t('File upload'), - 'description' => t('Field to upload any type of files.'), - 'weight' => -15, - ], - ]; -} - /** * Implements hook_preprocess_form_element__new_storage_type(). */ diff --git a/core/modules/options/options.field_type_categories.yml b/core/modules/options/options.field_type_categories.yml new file mode 100644 index 000000000000..9c23ff067057 --- /dev/null +++ b/core/modules/options/options.field_type_categories.yml @@ -0,0 +1,4 @@ +selection_list: + label: 'Selection list' + description: 'Field to select from predefined options.' + weight: -15 diff --git a/core/modules/options/options.module b/core/modules/options/options.module index 244a766acd61..2feed0daf806 100644 --- a/core/modules/options/options.module +++ b/core/modules/options/options.module @@ -139,19 +139,6 @@ function _options_values_in_use($entity_type, $field_name, $values) { return FALSE; } -/** - * Implements hook_field_type_category_info(). - */ -function options_field_type_category_info() { - return [ - 'selection_list' => [ - 'label' => t('Selection list'), - 'description' => t('Field to select from predefined options.'), - 'weight' => -15, - ], - ]; -} - /** * Implements hook_form_FORM_ID_alter(). * diff --git a/core/modules/text/text.field_type_categories.yml b/core/modules/text/text.field_type_categories.yml new file mode 100644 index 000000000000..787cfc979572 --- /dev/null +++ b/core/modules/text/text.field_type_categories.yml @@ -0,0 +1,4 @@ +formatted_text: + label: 'Formatted text' + description: 'Text field with markup support and optional editor.' + weight: -45 diff --git a/core/modules/text/text.module b/core/modules/text/text.module index eb74636478ac..54f513281d4f 100644 --- a/core/modules/text/text.module +++ b/core/modules/text/text.module @@ -165,19 +165,6 @@ function text_summary($text, $format = NULL, $size = NULL) { return $summary; } -/** - * Implements hook_field_type_category_info(). - */ -function text_field_type_category_info() { - return [ - 'formatted_text' => [ - 'label' => t('Formatted text'), - 'description' => t('Text field with markup support and optional editor.'), - 'weight' => -45, - ], - ]; -} - /** * Implements hook_preprocess_form_element__new_storage_type(). */ diff --git a/core/tests/Drupal/Tests/Core/Field/BaseFieldDefinitionTestBase.php b/core/tests/Drupal/Tests/Core/Field/BaseFieldDefinitionTestBase.php index c2f45ae31180..3398baf9f866 100644 --- a/core/tests/Drupal/Tests/Core/Field/BaseFieldDefinitionTestBase.php +++ b/core/tests/Drupal/Tests/Core/Field/BaseFieldDefinitionTestBase.php @@ -4,6 +4,7 @@ use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\Field\BaseFieldDefinition; +use Drupal\Core\Field\FieldTypeCategoryManagerInterface; use Drupal\Core\Field\FieldTypePluginManager; use Drupal\Core\TypedData\TypedDataManagerInterface; use Drupal\Tests\UnitTestCase; @@ -38,11 +39,13 @@ protected function setUp(): void { ->with($module_name) ->willReturn(TRUE); $typed_data_manager = $this->createMock(TypedDataManagerInterface::class); + $field_type_category_manager = $this->createMock(FieldTypeCategoryManagerInterface::class); $plugin_manager = new FieldTypePluginManager( $namespaces, $this->createMock('Drupal\Core\Cache\CacheBackendInterface'), $module_handler, - $typed_data_manager + $typed_data_manager, + $field_type_category_manager, ); $container = new ContainerBuilder(); -- GitLab