diff --git a/core/modules/field_ui/src/Form/FieldStorageAddForm.php b/core/modules/field_ui/src/Form/FieldStorageAddForm.php index 452a934428..59f2e76c37 100644 --- a/core/modules/field_ui/src/Form/FieldStorageAddForm.php +++ b/core/modules/field_ui/src/Form/FieldStorageAddForm.php @@ -314,18 +314,12 @@ protected function validateAddExisting(array $form, FormStateInterface $form_sta public function submitForm(array &$form, FormStateInterface $form_state) { $values = $form_state->getValues(); $entity_type = $this->entityTypeManager->getDefinition($this->entityTypeId); - $default_options = [ - 'entity_form_display' => ['default' => []], - 'entity_view_display' => ['default' => []], - ]; $field_values = [ 'entity_type' => $this->entityTypeId, 'bundle' => $this->bundle, ]; - // There are a few differences depending on whether we create a new field or - // re-use an existing one. - if (empty($values['new_storage_type'])) { + if ($values['existing_storage_name']) { $is_new_field = FALSE; $field_name = $values['existing_storage_name']; @@ -333,6 +327,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $default_options = $this->getExistingFieldDefaults($field_name); $field_values += [ + ...$default_options['field_config'] ?? [], 'field_name' => $field_name, 'label' => $values['existing_storage_label'], ]; @@ -590,7 +585,7 @@ protected function getExistingFieldLabels(array $field_names) { * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException */ - protected function getExistingFieldDefaults($field_name, $existing_bundle = '') { + protected function getExistingFieldDefaults(string $field_name, string $existing_bundle = ''): array { $default_options = []; $field_map = $this->entityFieldManager->getFieldMap(); if ($existing_bundle) { @@ -605,11 +600,13 @@ protected function getExistingFieldDefaults($field_name, $existing_bundle = '') } else { // If $existing_bundle is not supplied, then find a suitable candidate. - // @todo Consistently choose the bundle. Oldest? Newest? if (empty($field_map[$this->entityTypeId][$field_name]['bundles'])) { return []; } $bundles = $field_map[$this->entityTypeId][$field_name]['bundles']; + + // Sort bundles to ensure deterministic behavior. + sort($bundles); $existing_bundle = reset($bundles); } @@ -666,7 +663,7 @@ protected function getExistingFieldDefaults($field_name, $existing_bundle = '') * * @see \Drupal\Core\Field\PreconfiguredFieldUiOptionsInterface::getPreconfiguredOptions() */ - protected function getNewFieldDefaults($field_name, $preset_key) { + protected function getNewFieldDefaults(string $field_name, string $preset_key): array { $field_type_definition = $this->fieldTypePluginManager ->getDefinition($field_name); $options = $this->fieldTypePluginManager->getPreconfiguredOptions($field_type_definition['id']); diff --git a/core/modules/field_ui/tests/src/Functional/ManageFieldsFunctionalTest.php b/core/modules/field_ui/tests/src/Functional/ManageFieldsFunctionalTest.php index b3edefa926..66a1d65c4b 100644 --- a/core/modules/field_ui/tests/src/Functional/ManageFieldsFunctionalTest.php +++ b/core/modules/field_ui/tests/src/Functional/ManageFieldsFunctionalTest.php @@ -869,4 +869,38 @@ public function testNonExistentFieldUrls() { $this->assertSession()->statusCodeEquals(404); } + /** + * Tests that options are copied over when reusing a field. + */ + public function testReuseField() { + $field_name = 'test_reuse'; + $label = $this->randomMachineName(); + + // Create field with pre-configured options. + $this->fieldUIAddNewField('admin/structure/types/manage/article', $field_name, $label, 'field_ui:test_field_with_preconfigured_options:custom_options'); + + $new_label = $this->randomMachineName(); + $initial_edit = [ + 'existing_storage_name' => "field_{$field_name}", + 'existing_storage_label' => $new_label + ]; + + $this->drupalGet('admin/structure/types/manage/page/fields/add-field'); + $this->submitForm($initial_edit, 'Save and continue'); + + $field = FieldConfig::loadByName('node', 'page', "field_{$field_name}"); + $this->assertTrue($field->isRequired()); + $this->assertEquals($new_label, $field->label()); + $this->assertEquals('preconfigured_field_setting', $field->getSetting('test_field_setting')); + + /** @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface $display_repository */ + $display_repository = \Drupal::service('entity_display.repository'); + + $form_display = $display_repository->getFormDisplay('node', 'page'); + $this->assertEquals('test_field_widget_multiple', $form_display->getComponent("field_{$field_name}")['type']); + $view_display = $display_repository->getViewDisplay('node', 'page'); + $this->assertEquals('field_test_multiple', $view_display->getComponent("field_{$field_name}")['type']); + $this->assertEquals('altered dummy test string', $view_display->getComponent("field_{$field_name}")['settings']['test_formatter_setting_multiple']); + } + }