diff --git a/core/config/schema/core.data_types.schema.yml b/core/config/schema/core.data_types.schema.yml index 41332e3..404818a 100644 --- a/core/config/schema/core.data_types.schema.yml +++ b/core/config/schema/core.data_types.schema.yml @@ -552,7 +552,7 @@ field.value.changed: field.storage_settings.entity_reference: type: mapping - label: 'Entity reference settings' + label: 'Entity reference storage settings' mapping: target_type: type: string @@ -560,14 +560,14 @@ field.storage_settings.entity_reference: field.field_settings.entity_reference: type: mapping - label: 'Entity reference settings' + label: 'Entity reference field settings' mapping: handler: type: string label: 'Reference method' handler_settings: - type: entity_reference.[%parent.handler].handler_settings - label: 'Reference method settings' + type: entity_reference_selection.[plugin_id] + label: 'Entity reference selection settings' field.value.entity_reference: type: mapping @@ -754,3 +754,35 @@ text_format: label: 'Text format' # The text format should not be translated as part of the string # translation system, so this is not marked as translatable. + +# Schema for the configuration of the Entity reference selection plugins. + +entity_reference_selection: + type: mapping + label: 'Entity reference selection plugin configuration' + mapping: + plugin_id: + type: string + label: 'Entity reference selection plugin ID' + target_bundles: + type: sequence + label: 'types' + sequence: + - type: string + label: 'Type' + sort: + type: mapping + label: 'Sort settings' + mapping: + field: + type: string + label: 'Sort by' + direction: + type: string + label: 'Sort direction' + auto_create: + type: boolean + label: 'Create referenced entities if they don''t already exist' + +entity_reference_selection.*: + type: entity_reference_selection diff --git a/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginManager.php b/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginManager.php index 089dee8..5aadd3d 100644 --- a/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginManager.php +++ b/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginManager.php @@ -49,15 +49,22 @@ public function getInstance(array $options) { 'handler_settings' => array(), ); + return $this->createInstance($this->getPluginId($options['target_type'], $options['handler']), $options); + } + + /** + * {@inheritdoc} + */ + public function getPluginId($target_type, $base_plugin_id) { // Get all available selection plugins for this entity type. - $selection_handler_groups = $this->getSelectionGroups($options['target_type']); + $selection_handler_groups = $this->getSelectionGroups($target_type); // Sort the selection plugins by weight and select the best match. - uasort($selection_handler_groups[$options['handler']], array('Drupal\Component\Utility\SortArray', 'sortByWeightElement')); - end($selection_handler_groups[$options['handler']]); - $plugin_id = key($selection_handler_groups[$options['handler']]); + uasort($selection_handler_groups[$base_plugin_id], array('Drupal\Component\Utility\SortArray', 'sortByWeightElement')); + end($selection_handler_groups[$base_plugin_id]); + $plugin_id = key($selection_handler_groups[$base_plugin_id]); - return $this->createInstance($plugin_id, $options); + return $plugin_id; } /** diff --git a/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginManagerInterface.php b/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginManagerInterface.php index 81d555d..278e3c4 100644 --- a/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginManagerInterface.php +++ b/core/lib/Drupal/Core/Entity/EntityReferenceSelection/SelectionPluginManagerInterface.php @@ -17,6 +17,19 @@ interface SelectionPluginManagerInterface extends PluginManagerInterface { /** + * Gets the plugin ID for a given target entity type and base plugin ID. + * + * @param string $target_type + * The target entity type. + * @param string $base_plugin_id + * The base plugin ID (e.g. 'default' or 'views'). + * + * @return string + * The plugin ID. + */ + public function getPluginId($target_type, $base_plugin_id); + + /** * Returns selection plugins that can reference a specific entity type. * * @param string $entity_type_id diff --git a/core/lib/Drupal/Core/Field/FieldConfigStorageBase.php b/core/lib/Drupal/Core/Field/FieldConfigStorageBase.php index 9fb25b4..67652e5 100644 --- a/core/lib/Drupal/Core/Field/FieldConfigStorageBase.php +++ b/core/lib/Drupal/Core/Field/FieldConfigStorageBase.php @@ -39,7 +39,7 @@ protected function mapFromStorageRecords(array $records) { protected function mapToStorageRecord(EntityInterface $entity) { $record = parent::mapToStorageRecord($entity); $class = $this->fieldTypeManager->getPluginClass($record['field_type']); - $record['settings'] = $class::fieldSettingsToConfigData($record['settings']); + $record['settings'] = $class::fieldSettingsToConfigData($record['settings'], $entity); return $record; } diff --git a/core/lib/Drupal/Core/Field/FieldItemBase.php b/core/lib/Drupal/Core/Field/FieldItemBase.php index 1bb5486..1857b15 100644 --- a/core/lib/Drupal/Core/Field/FieldItemBase.php +++ b/core/lib/Drupal/Core/Field/FieldItemBase.php @@ -255,7 +255,7 @@ public static function storageSettingsFromConfigData(array $settings) { /** * {@inheritdoc} */ - public static function fieldSettingsToConfigData(array $settings) { + public static function fieldSettingsToConfigData(array $settings, FieldConfigInterface $field_config) { return $settings; } diff --git a/core/lib/Drupal/Core/Field/FieldItemInterface.php b/core/lib/Drupal/Core/Field/FieldItemInterface.php index f74b3f7..4fdab39 100644 --- a/core/lib/Drupal/Core/Field/FieldItemInterface.php +++ b/core/lib/Drupal/Core/Field/FieldItemInterface.php @@ -309,6 +309,8 @@ public static function storageSettingsFromConfigData(array $settings); * * @param array $settings * The field's settings in the field type's canonical representation. + * @param \Drupal\Core\Field\FieldConfigInterface $field_config + * The field config entity that is about to be saved in configuration. * * @return array * An array (either the unmodified $settings or a modified representation) @@ -316,7 +318,7 @@ public static function storageSettingsFromConfigData(array $settings); * * @see \Drupal\Core\Field\FieldItemInterface::storageSettingsToConfigData() */ - public static function fieldSettingsToConfigData(array $settings); + public static function fieldSettingsToConfigData(array $settings, FieldConfigInterface $field_config); /** * Returns a settings array in the field type's canonical representation. diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php index 5844cf9..a1068ba 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php @@ -59,6 +59,7 @@ public static function defaultStorageSettings() { public static function defaultFieldSettings() { return array( 'handler' => 'default', + 'handler_settings' => array(), ) + parent::defaultFieldSettings(); } diff --git a/core/modules/entity_reference/config/schema/entity_reference.schema.yml b/core/modules/entity_reference/config/schema/entity_reference.schema.yml deleted file mode 100644 index ec291fa..0000000 --- a/core/modules/entity_reference/config/schema/entity_reference.schema.yml +++ /dev/null @@ -1,38 +0,0 @@ -# Schema for the configuration files of the Entity Reference module. - -entity_reference.default.handler_settings: - type: mapping - label: 'View handler settings' - mapping: - target_bundles: - type: sequence - label: 'types' - sequence: - - type: string - label: 'Type' - sort: - type: mapping - label: 'Sort settings' - mapping: - field: - type: string - label: 'Sort by' - direction: - type: string - label: 'Sort direction' - filter: - type: mapping - label: 'Filter settings' - mapping: - type: - type: string - label: 'Filter by' - role: - type: sequence - label: 'Restrict to the selected roles' - sequence: - - type: string - label: 'Role' - auto_create: - type: boolean - label: 'Create referenced entities if they don''t already exist' diff --git a/core/modules/entity_reference/entity_reference.module b/core/modules/entity_reference/entity_reference.module index 526c60c..b4c95c2 100644 --- a/core/modules/entity_reference/entity_reference.module +++ b/core/modules/entity_reference/entity_reference.module @@ -84,19 +84,10 @@ function entity_reference_field_storage_config_update(FieldStorageConfigInterfac return; } - if (empty($field_storage->bundles)) { - // Field storage has no fields. - return; - } - - $field_name = $field_storage->getName(); - - foreach ($field_storage->bundles() as $entity_type => $bundles) { - foreach ($bundles as $bundle) { - $field = FieldConfig::loadByName($entity_type, $bundle, $field_name); - $field->settings['handler_settings'] = array(); - $field->save(); - } + foreach ($field_storage->getBundles() as $bundle) { + $field = FieldConfig::loadByName($field_storage->getTargetEntityTypeId(), $bundle, $field_storage->getName()); + $field->settings['handler_settings'] = array(); + $field->save(); } } diff --git a/core/modules/entity_reference/src/ConfigurableEntityReferenceItem.php b/core/modules/entity_reference/src/ConfigurableEntityReferenceItem.php index 5f0f75d..fb9898c 100644 --- a/core/modules/entity_reference/src/ConfigurableEntityReferenceItem.php +++ b/core/modules/entity_reference/src/ConfigurableEntityReferenceItem.php @@ -8,6 +8,7 @@ namespace Drupal\entity_reference; use Drupal\Component\Utility\String; +use Drupal\Core\Field\FieldConfigInterface; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem; use Drupal\Core\Form\FormStateInterface; @@ -45,15 +46,6 @@ public static function defaultStorageSettings() { /** * {@inheritdoc} */ - public static function defaultFieldSettings() { - return array( - 'handler_settings' => array(), - ) + parent::defaultFieldSettings(); - } - - /** - * {@inheritdoc} - */ public function getPossibleValues(AccountInterface $account = NULL) { return $this->getSettableValues($account); } @@ -216,4 +208,28 @@ public static function fieldSettingsFormValidate(array $form, FormStateInterface } } + /** + * {@inheritdoc} + */ + public static function fieldSettingsToConfigData(array $settings, FieldConfigInterface $field_config) { + $settings = parent::fieldSettingsToConfigData($settings, $field_config); + + $target_type = $field_config->getFieldStorageDefinition()->getSetting('target_type'); + $selection_manager = \Drupal::service('plugin.manager.entity_reference_selection'); + $settings['handler_settings']['plugin_id'] = $selection_manager->getPluginId($target_type, $settings['handler']); + + return $settings; + } + + /** + * {@inheritdoc} + */ + public static function fieldSettingsFromConfigData(array $settings) { + // The 'plugin_id' handler setting is saved to config only to satisfy + // config schema and it is not used on runtime. + unset($settings['handler_settings']['plugin_id']); + + return $settings; + } + } diff --git a/core/modules/file/config/schema/file.schema.yml b/core/modules/file/config/schema/file.schema.yml index 70bf21f..b6195d2 100644 --- a/core/modules/file/config/schema/file.schema.yml +++ b/core/modules/file/config/schema/file.schema.yml @@ -46,6 +46,9 @@ base_file_field_field_settings: handler: type: string label: 'Reference method' + handler_settings: + type: entity_reference_selection.[plugin_id] + label: 'Entity reference selection settings' file_directory: type: string label: 'File directory' diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateFieldInstanceTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateFieldInstanceTest.php index 05cc467..daac5b2 100644 --- a/core/modules/migrate_drupal/src/Tests/d6/MigrateFieldInstanceTest.php +++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateFieldInstanceTest.php @@ -135,11 +135,14 @@ public function testFieldInstanceSettings() { 'display_default' => FALSE, 'uri_scheme' => 'public', 'handler' => 'default', + 'handler_settings' => array(), 'target_bundle' => NULL, ); + $field_settings = $field->getSettings(); + ksort($expected); + ksort($field_settings); // This is the only way to compare arrays. - $this->assertFalse(array_diff_assoc($field->getSettings(), $expected)); - $this->assertFalse(array_diff_assoc($expected, $field->getSettings())); + $this->assertIdentical($expected, $field_settings); // Test a link field. $field = FieldConfig::load('node.story.field_test_link'); diff --git a/core/modules/taxonomy/config/schema/taxonomy.schema.yml b/core/modules/taxonomy/config/schema/taxonomy.schema.yml index c79fa5f..f7439de 100644 --- a/core/modules/taxonomy/config/schema/taxonomy.schema.yml +++ b/core/modules/taxonomy/config/schema/taxonomy.schema.yml @@ -62,6 +62,9 @@ field.field_settings.taxonomy_term_reference: handler: type: string label: 'Reference method' + handler_settings: + type: entity_reference_selection.[plugin_id] + label: 'Entity reference selection settings' field.value.taxonomy_term_reference: type: mapping diff --git a/core/modules/user/config/schema/user.schema.yml b/core/modules/user/config/schema/user.schema.yml index 772deea..96101c5 100644 --- a/core/modules/user/config/schema/user.schema.yml +++ b/core/modules/user/config/schema/user.schema.yml @@ -174,3 +174,20 @@ condition.plugin.user_role: type: sequence sequence: - type: string + +entity_reference_selection.default:user: + type: entity_reference_selection + mapping: + filter: + type: mapping + label: 'Filter settings' + mapping: + type: + type: string + label: 'Filter by' + role: + type: sequence + label: 'Restrict to the selected roles' + sequence: + - type: string + label: 'Role' diff --git a/core/modules/views/config/schema/views.entity_reference.schema.yml b/core/modules/views/config/schema/views.entity_reference.schema.yml index 3067041..83b9dc8 100644 --- a/core/modules/views/config/schema/views.entity_reference.schema.yml +++ b/core/modules/views/config/schema/views.entity_reference.schema.yml @@ -1,9 +1,12 @@ # Schema for the views entity reference selection plugins. -entity_reference.views.handler_settings: +entity_reference_selection.views: type: mapping label: 'View handler settings' mapping: + plugin_id: + type: string + label: 'Entity reference selection plugin ID' view: type: mapping label: 'View used to select the entities'