diff --git a/src/Plugin/Field/FieldType/DynamicEntityReferenceItem.php b/src/Plugin/Field/FieldType/DynamicEntityReferenceItem.php index 945cb039c9addaf6f317217f7df26dad3a6a226c..93cfd1779f8b8bc8439edc2fb041ced96a20047a 100644 --- a/src/Plugin/Field/FieldType/DynamicEntityReferenceItem.php +++ b/src/Plugin/Field/FieldType/DynamicEntityReferenceItem.php @@ -2,6 +2,7 @@ namespace Drupal\dynamic_entity_reference\Plugin\Field\FieldType; +use Drupal\Component\Utility\DeprecationHelper; use Drupal\Component\Utility\Html; use Drupal\Core\Entity\ContentEntityTypeInterface; use Drupal\Core\Entity\EntityInterface; @@ -11,6 +12,7 @@ use Drupal\Core\Field\FieldItemBase; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Form\SubformState; use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\Core\TypedData\DataReferenceTargetDefinition; @@ -232,11 +234,21 @@ class DynamicEntityReferenceItem extends EntityReferenceItem { */ public static function storageSettingsFormValidate(array &$element, FormStateInterface $form_state, array $form) { $labels = \Drupal::service('entity_type.repository')->getEntityTypeLabels(TRUE); - $exclude_entity_types = $form_state->getValue([ + // 10.2 combined the field storage form into the field config form. To get + // the field values we want, we need to either use the passed form state + // for 10.1 and below, or create a subform state for 10.2 and above. + // @see \Drupal\field_ui\Form\FieldConfigEditForm::validateForm + $subform_state = DeprecationHelper::backwardsCompatibleCall( + \Drupal::VERSION, + 10.2, + fn() => SubformState::createForSubform($form['field_storage']['subform'], $form, $form_state), + fn() => $form_state + ); + $exclude_entity_types = $subform_state->getValue([ 'settings', 'exclude_entity_types', ], 0); - $entity_type_ids = $form_state->getValue([ + $entity_type_ids = $subform_state->getValue([ 'settings', 'entity_type_ids', ], []); diff --git a/src/Plugin/Field/FieldWidget/DynamicEntityReferenceWidget.php b/src/Plugin/Field/FieldWidget/DynamicEntityReferenceWidget.php index 9ff14575ab7ec5ce4d1205d74455c5683b6dd996..e5564293f52be7e05748e772ebbdc3a9f651ab81 100644 --- a/src/Plugin/Field/FieldWidget/DynamicEntityReferenceWidget.php +++ b/src/Plugin/Field/FieldWidget/DynamicEntityReferenceWidget.php @@ -337,12 +337,13 @@ class DynamicEntityReferenceWidget extends EntityReferenceAutocompleteWidget { foreach ($target_types as $target_type) { // Store the selection settings in the key/value store and pass a hashed // key in the route parameters. - $selection_settings = $settings[$target_type]['handler_settings'] ?: []; + $selection_settings = $settings[$target_type]['handler_settings'] ?? []; $selection_settings += [ 'match_operator' => $this->getSetting('match_operator'), 'match_limit' => $this->getSetting('match_limit'), ]; - $data = serialize($selection_settings) . $target_type . $settings[$target_type]['handler']; + $handler = $settings[$target_type]['handler'] ?? 'default:' . $target_type; + $data = serialize($selection_settings) . $target_type . $handler; $selection_settings_key = Crypt::hmacBase64($data, Settings::getHashSalt()); $key_value_storage = $this->keyValue->get('entity_autocomplete'); if (!$key_value_storage->has($selection_settings_key)) { @@ -350,7 +351,7 @@ class DynamicEntityReferenceWidget extends EntityReferenceAutocompleteWidget { } $auto_complete_paths[$target_type] = Url::fromRoute('system.entity_autocomplete', [ 'target_type' => $target_type, - 'selection_handler' => $settings[$target_type]['handler'], + 'selection_handler' => $handler, 'selection_settings_key' => $selection_settings_key, ])->toString(); } diff --git a/tests/src/Functional/DynamicEntityReferenceFieldDefaultValueTest.php b/tests/src/Functional/DynamicEntityReferenceFieldDefaultValueTest.php index 06a7850ef8d6f58361bce17774e6dfd5602c1983..46ebc7819d1830031f81f5dfa1b64ca57ae6d1d9 100644 --- a/tests/src/Functional/DynamicEntityReferenceFieldDefaultValueTest.php +++ b/tests/src/Functional/DynamicEntityReferenceFieldDefaultValueTest.php @@ -89,7 +89,7 @@ class DynamicEntityReferenceFieldDefaultValueTest extends BrowserTestBase { ], ]); $field_storage->save(); - FieldConfig::create([ + $field_config = FieldConfig::create([ 'field_storage' => $field_storage, 'bundle' => 'reference_content', 'settings' => [ @@ -107,7 +107,9 @@ class DynamicEntityReferenceFieldDefaultValueTest extends BrowserTestBase { ], ], ], - ])->save(); + ]); + $field_config->save(); + $this->assertEmpty($field_config->getDefaultValueLiteral()); // Set created node as default_value. $field_edit = [ @@ -117,11 +119,17 @@ class DynamicEntityReferenceFieldDefaultValueTest extends BrowserTestBase { ]; $this->drupalGet('admin/structure/types/manage/reference_content/fields/node.reference_content.' . $field_name); $this->submitForm($field_edit, t('Save settings')); + $field_config = \Drupal::entityTypeManager()->getStorage('field_config')->loadUnchanged($field_config->id()); + $default_value = $field_config->getDefaultValueLiteral(); + $this->assertNotEmpty($default_value); + $this->assertEquals('node', $default_value[0]['target_type']); + $this->assertEquals($referenced_node->uuid(), $default_value[0]['target_uuid']); // Check that default value is selected in default value form. $this->drupalGet('admin/structure/types/manage/reference_content/fields/node.reference_content.' . $field_name); $assert_session->optionExists("default_value_input[$field_name][0][target_type]", $referenced_node->getEntityTypeId()); - $assert_session->responseContains('name="default_value_input[' . $field_name . '][0][target_id]" value="' . $referenced_node->getTitle() . ' (' . $referenced_node->id() . ')'); + $input = $assert_session->fieldExists('default_value_input[' . $field_name . '][0][target_id]'); + $this->assertEquals($referenced_node->getTitle() . ' (' . $referenced_node->id() . ')', $input->getValue()); // Check if the ID has been converted to UUID in config entity. $config_entity = $this->config('field.field.node.reference_content.' . $field_name)->get(); diff --git a/tests/src/Functional/DynamicEntityReferenceTest.php b/tests/src/Functional/DynamicEntityReferenceTest.php index 2c3e5e1ceb3816c02681396c42d1fc5ede9c1009..1aef227cab52b48808037079d760674913e1a81b 100644 --- a/tests/src/Functional/DynamicEntityReferenceTest.php +++ b/tests/src/Functional/DynamicEntityReferenceTest.php @@ -121,83 +121,87 @@ class DynamicEntityReferenceTest extends BrowserTestBase { $this->drupalLogin($this->adminUser); // Add a new dynamic entity reference field. $this->drupalGet('entity_test/structure/entity_test/fields/add-field'); + $edit = []; + $excluded_entity_type_ids = $this->excludedEntities; + $bundled_entities_type_ids = $this->bundleAbleEntities; + $labels = $this->container->get('entity_type.repository')->getEntityTypeLabels(TRUE); + foreach ($labels[(string) t('Content', [], ['context' => 'Entity type group'])] as $entity_type_id => $entity_type_label) { + if (!in_array($entity_type_id, $excluded_entity_type_ids, TRUE)) { + if (!in_array($entity_type_id, array_keys($bundled_entities_type_ids, TRUE))) { + $edit["settings[$entity_type_id][handler_settings][target_bundles][$entity_type_id]"] = TRUE; + } + else { + $edit["settings[$entity_type_id][handler_settings][target_bundles][{$bundled_entities_type_ids[$entity_type_id]}]"] = TRUE; + } + } + } + $additions = []; if (version_compare(\Drupal::VERSION, '10.2-dev', '>=')) { - $test = [ + $this->submitForm([ 'new_storage_type' => 'reference', - ]; - $this->submitForm($test, 'Change field group'); - $edit = [ + ], 'Continue'); + $this->submitForm([ 'group_field_options_wrapper' => 'dynamic_entity_reference', 'label' => 'Foobar', 'field_name' => 'foobar', - ]; + ], t('Continue')); + $field_name = 'field_storage[subform][settings][entity_type_ids][]'; + $button_label = t('Save settings'); + $cardinality_field = 'field_storage[subform][cardinality]'; + $additions += $edit; + $edit_path = 'entity_test/structure/entity_test/fields/entity_test.entity_test.field_foobar'; + $exclude_field_name = 'field_storage[subform][settings][exclude_entity_types]'; } else { - $edit = [ + $edit_path = 'entity_test/structure/entity_test/fields/entity_test.entity_test.field_foobar/storage'; + $this->submitForm([ 'label' => 'Foobar', 'field_name' => 'foobar', 'new_storage_type' => 'dynamic_entity_reference', - ]; + ], t('Save and continue')); + $field_name = 'settings[entity_type_ids][]'; + $button_label = t('Save field settings'); + $cardinality_field = 'cardinality'; + $exclude_field_name = 'settings[exclude_entity_types]'; } - $this->submitForm($edit, t('Save and continue')); - $this->submitForm([ - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings[entity_type_ids][]' => ['user', 'entity_test_label'], - ], t('Save field settings')); - $this->assertTrue(\Drupal::database()->schema()->tableExists('entity_test__field_foobar')); - $this->assertTrue(\Drupal::database()->schema()->fieldExists('entity_test__field_foobar', 'field_foobar_target_id_int')); + $assert_session->fieldExists($cardinality_field)->setValue(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); + $assert_session->fieldExists($field_name)->setValue(['user', 'entity_test_label']); + $assert_session->buttonExists(t('Update settings'))->click(); $assert_session->fieldExists('default_value_input[field_foobar][0][target_type]'); $assert_session->optionExists('default_value_input[field_foobar][0][target_type]', 'entity_test'); $assert_session->optionNotExists('default_value_input[field_foobar][0][target_type]', 'user'); + $this->submitForm($additions, $button_label); - // Ensure no configuration entities are exposed to the UI. - $labels = $this->container->get('entity_type.repository')->getEntityTypeLabels(TRUE); - foreach (array_keys($labels[(string) t('Configuration')]) as $entity_type) { - $assert_session->fieldNotExists('settings[' . $entity_type . '][handler]'); - } - $edit = []; - $excluded_entity_type_ids = $this->excludedEntities; - $bundled_entities_type_ids = $this->bundleAbleEntities; - foreach ($labels[(string) t('Content', [], ['context' => 'Entity type group'])] as $entity_type_id => $entity_type_label) { - if (!in_array($entity_type_id, $excluded_entity_type_ids, TRUE)) { - if (!in_array($entity_type_id, array_keys($bundled_entities_type_ids, TRUE))) { - $edit["settings[$entity_type_id][handler_settings][target_bundles][$entity_type_id]"] = TRUE; - } - else { - $edit["settings[$entity_type_id][handler_settings][target_bundles][{$bundled_entities_type_ids[$entity_type_id]}]"] = TRUE; - } - } - } - $this->submitForm($edit, t('Save settings')); - $this->assertTrue(\Drupal::database()->schema()->tableExists('entity_test__field_foobar')); - $this->assertTrue(\Drupal::database()->schema()->fieldExists('entity_test__field_foobar', 'field_foobar_target_id_int')); $assert_session->responseContains(t('Saved %name configuration', ['%name' => 'Foobar'])); $excluded_entity_type_ids = FieldStorageConfig::loadByName('entity_test', 'field_foobar') ->getSetting('entity_type_ids'); $this->assertNotNull($excluded_entity_type_ids); - $this->assertSame(array_keys($excluded_entity_type_ids), [ - 'user', + $excluded = array_keys($excluded_entity_type_ids); + sort($excluded); + $this->assertEquals($excluded, [ 'entity_test_label', + 'user', ]); // Check the include entity settings. - $this->drupalGet('entity_test/structure/entity_test/fields/entity_test.entity_test.field_foobar/storage'); + $this->drupalGet($edit_path); $this->submitForm([ - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings[exclude_entity_types]' => FALSE, - 'settings[entity_type_ids][]' => [], - ], t('Save field settings')); + $cardinality_field => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, + $exclude_field_name => FALSE, + $field_name => [], + ], $button_label); $assert_session->pageTextContains('Select at least one entity type ID.'); + $options = array_keys($labels[(string) t('Content', [], ['context' => 'Entity type group'])]); $this->submitForm([ - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings[exclude_entity_types]' => TRUE, - 'settings[entity_type_ids][]' => array_keys($labels[(string) t('Content', [], ['context' => 'Entity type group'])]), - ], t('Save field settings')); + $cardinality_field => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, + $exclude_field_name => TRUE, + $field_name => $options, + ], $button_label); $assert_session->pageTextContains('Select at least one entity type ID.'); $this->submitForm([ - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings[exclude_entity_types]' => FALSE, - 'settings[entity_type_ids][]' => ['user', 'entity_test_label'], - ], t('Save field settings')); + $cardinality_field => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, + $exclude_field_name => FALSE, + $field_name => ['user', 'entity_test_label'], + ], $button_label); $this->drupalGet('entity_test/structure/entity_test/fields/entity_test.entity_test.field_foobar'); $assert_session->fieldExists('default_value_input[field_foobar][0][target_type]'); $assert_session->optionNotExists('default_value_input[field_foobar][0][target_type]', 'entity_test'); @@ -212,9 +216,11 @@ class DynamicEntityReferenceTest extends BrowserTestBase { $excluded_entity_type_ids = FieldStorageConfig::loadByName('entity_test', 'field_foobar') ->getSetting('entity_type_ids'); $this->assertNotNull($excluded_entity_type_ids); - $this->assertSame(array_keys($excluded_entity_type_ids), [ - 'user', + $excluded = array_keys($excluded_entity_type_ids); + sort($excluded); + $this->assertSame($excluded, [ 'entity_test_label', + 'user', ]); // Check the default settings. $this->drupalGet('entity_test/structure/entity_test/fields/entity_test.entity_test.field_foobar'); @@ -240,27 +246,33 @@ class DynamicEntityReferenceTest extends BrowserTestBase { // Add a new dynamic entity reference field. $this->drupalGet('entity_test/structure/entity_test/fields/add-field'); if (version_compare(\Drupal::VERSION, '10.2-dev', '>=')) { - $test = [ + $this->submitForm([ 'new_storage_type' => 'reference', - ]; - $this->submitForm($test, 'Change field group'); - $edit = [ + ], 'Continue'); + $this->submitForm([ 'group_field_options_wrapper' => 'dynamic_entity_reference', 'label' => 'Foobar', 'field_name' => 'foobar', - ]; + ], t('Continue')); + $field_name = 'field_storage[subform][settings][entity_type_ids][]'; + $button_label = t('Save settings'); + $cardinality_field = 'field_storage[subform][cardinality]'; } else { - $edit = [ + $this->submitForm([ 'label' => 'Foobar', 'field_name' => 'foobar', 'new_storage_type' => 'dynamic_entity_reference', - ]; + ], t('Save and continue')); + $field_name = 'settings[entity_type_ids][]'; + $button_label = t('Save field settings'); + $cardinality_field = 'cardinality'; } - $this->submitForm($edit, t('Save and continue')); + $assert_session->optionNotExists($field_name, 'settings[entity_test_no_id][handler_settings][target_bundles][entity_test_no_id]'); + $assert_session->optionNotExists($field_name, 'settings[entity_test_no_id][handler_settings][target_bundles][entity_test_string_id]'); $this->submitForm([ - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - ], t('Save field settings')); + $cardinality_field => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, + ], $button_label); $labels = $this->container->get('entity_type.repository')->getEntityTypeLabels(TRUE); $edit = []; $excluded_entity_type_ids = array_combine($this->excludedEntities, $this->excludedEntities); @@ -293,21 +305,22 @@ class DynamicEntityReferenceTest extends BrowserTestBase { // Test the new entity commenting inherits default. $this->drupalGet('entity_test/add'); $assert_session->fieldExists('field_foobar[0][target_id]'); - $assert_session->fieldExists('field_foobar[0][target_type]'); + $target_type = $assert_session->fieldExists('field_foobar[0][target_type]'); // Ensure that the autocomplete path is correct. $input = $assert_session->fieldExists('field_foobar[0][target_id]'); + $selected = $target_type->getValue(); $settings = FieldConfig::loadByName('entity_test', 'entity_test', 'field_foobar')->getSettings(); - $selection_settings = $settings['entity_test_computed_field']['handler_settings'] ?: []; + $selection_settings = $settings[$selected]['handler_settings'] ?: []; $selection_settings += [ 'match_operator' => 'CONTAINS', 'match_limit' => 10, ]; - $data = serialize($selection_settings) . 'entity_test_computed_field' . $settings['entity_test_computed_field']['handler']; + $data = serialize($selection_settings) . $selected . $settings[$selected]['handler']; $selection_settings_key = Crypt::hmacBase64($data, Settings::getHashSalt()); $expected_autocomplete_path = Url::fromRoute('system.entity_autocomplete', [ - 'target_type' => 'entity_test_computed_field', - 'selection_handler' => $settings['entity_test_computed_field']['handler'], + 'target_type' => $selected, + 'selection_handler' => $settings[$selected]['handler'], 'selection_settings_key' => $selection_settings_key, ])->toString(); $this->assertStringContainsString($input->getAttribute('data-autocomplete-path'), $expected_autocomplete_path); @@ -479,35 +492,45 @@ class DynamicEntityReferenceTest extends BrowserTestBase { $this->drupalLogin($this->adminUser); // Add a new dynamic entity reference field. $this->drupalGet('entity_test/structure/entity_test/fields/add-field'); + $edit = [ + 'settings[taxonomy_term][handler_settings][target_bundles][' . $vocabulary->id() . ']' => $vocabulary->id(), + 'settings[taxonomy_term][handler_settings][auto_create]' => TRUE, + ]; + $additional = []; if (version_compare(\Drupal::VERSION, '10.2-dev', '>=')) { - $test = [ + $additional = $edit; + $this->submitForm([ 'new_storage_type' => 'reference', - ]; - $this->submitForm($test, 'Change field group'); - $edit = [ + ], 'Continue'); + $this->submitForm([ 'group_field_options_wrapper' => 'dynamic_entity_reference', 'label' => 'Foobar', 'field_name' => 'foobar', - ]; + ], t('Continue')); + $field_name = 'field_storage[subform][settings][entity_type_ids][]'; + $button_label = t('Save settings'); + $cardinality_field = 'field_storage[subform][cardinality]'; + $exclude_field_name = 'field_storage[subform][settings][exclude_entity_types]'; } else { - $edit = [ + $this->submitForm([ 'label' => 'Foobar', 'field_name' => 'foobar', 'new_storage_type' => 'dynamic_entity_reference', - ]; + ], t('Save and continue')); + $field_name = 'settings[entity_type_ids][]'; + $button_label = t('Save field settings'); + $cardinality_field = 'cardinality'; + $exclude_field_name = 'settings[exclude_entity_types]'; } - $this->submitForm($edit, t('Save and continue')); + $assert_session->fieldExists($field_name)->setValue(['taxonomy_term', 'user']); + $assert_session->fieldExists($exclude_field_name)->uncheck(); + $assert_session->buttonExists('Update settings')->click(); $this->submitForm([ - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings[exclude_entity_types]' => FALSE, - 'settings[entity_type_ids][]' => ['taxonomy_term', 'user'], - ], t('Save field settings')); - $edit = [ - 'settings[taxonomy_term][handler_settings][target_bundles][' . $vocabulary->id() . ']' => $vocabulary->id(), - 'settings[taxonomy_term][handler_settings][auto_create]' => TRUE, - ]; - $this->submitForm($edit, t('Save settings')); + $cardinality_field => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, + ] + $additional, $button_label); + $this->drupalGet('entity_test/structure/entity_test/fields/entity_test.entity_test.field_foobar'); + $this->submitForm($edit, $button_label); \Drupal::service('entity_field.manager')->clearCachedFieldDefinitions(); $this->drupalGet('entity_test/add'); @@ -578,37 +601,46 @@ class DynamicEntityReferenceTest extends BrowserTestBase { $this->drupalLogin($this->adminUser); // Add a new dynamic entity reference field. + $edit = [ + 'settings[taxonomy_term][handler_settings][target_bundles][' . $vocabulary->id() . ']' => $vocabulary->id(), + 'settings[taxonomy_term][handler_settings][auto_create]' => TRUE, + ]; + $additional = []; $this->drupalGet('admin/structure/types/manage/article/fields/add-field'); if (version_compare(\Drupal::VERSION, '10.2-dev', '>=')) { - $test = [ + $this->submitForm([ 'new_storage_type' => 'reference', - ]; - $this->submitForm($test, 'Change field group'); - $edit = [ + ], 'Continue'); + $this->submitForm([ 'group_field_options_wrapper' => 'dynamic_entity_reference', - 'label' => 'DER', + 'label' => 'Foobar', 'field_name' => 'der', - ]; + ], t('Continue')); + $field_name = 'field_storage[subform][settings][entity_type_ids][]'; + $button_label = t('Save settings'); + $cardinality_field = 'field_storage[subform][cardinality]'; + $exclude_field_name = 'field_storage[subform][settings][exclude_entity_types]'; + $additional = $edit; } else { - $edit = [ - 'label' => 'DER', + $this->submitForm([ + 'label' => 'Foobar', 'field_name' => 'der', 'new_storage_type' => 'dynamic_entity_reference', - ]; - }; - $this->submitForm($edit, t('Save and continue')); + ], t('Save and continue')); + $field_name = 'settings[entity_type_ids][]'; + $button_label = t('Save field settings'); + $cardinality_field = 'cardinality'; + $exclude_field_name = 'settings[exclude_entity_types]'; + } + $assert_session->fieldExists($field_name)->setValue(['taxonomy_term', 'user']); + $assert_session->fieldExists($exclude_field_name)->uncheck(); + $assert_session->buttonExists('Update settings')->click(); $this->submitForm([ - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings[exclude_entity_types]' => FALSE, - 'settings[entity_type_ids][]' => ['taxonomy_term', 'entity_test_label'], - ], t('Save field settings')); - $edit = [ - 'settings[entity_test_label][handler_settings][target_bundles][entity_test_label]' => 'entity_test_label', - 'settings[taxonomy_term][handler_settings][target_bundles][' . $vocabulary->id() . ']' => $vocabulary->id(), - 'settings[taxonomy_term][handler_settings][auto_create]' => TRUE, - ]; - $this->submitForm($edit, t('Save settings')); + $cardinality_field => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, + ] + $additional, $button_label); + $this->drupalGet('/admin/structure/types/manage/article/fields/node.article.field_der'); + $this->submitForm($edit, $button_label); \Drupal::service('entity_field.manager')->clearCachedFieldDefinitions(); // Test the node preview for existing term. diff --git a/tests/src/FunctionalJavascript/DynamicEntityReferenceTest.php b/tests/src/FunctionalJavascript/DynamicEntityReferenceTest.php index c295aa1320e6fc8e5170821aadab89c7773c49c3..cefe4550d9f464fe5d085ba8d0f0444a49bf4213 100644 --- a/tests/src/FunctionalJavascript/DynamicEntityReferenceTest.php +++ b/tests/src/FunctionalJavascript/DynamicEntityReferenceTest.php @@ -88,6 +88,52 @@ class DynamicEntityReferenceTest extends WebDriverTestBase { $this->anotherUser = $this->drupalCreateUser(); } + /** + * Sets up field for testing. + */ + protected function setupField(string $field_name, string $entity_type_id, string $bundle, array $storage_settings, array $field_settings, string $label): void { + // Add a new dynamic entity reference field. + $storage = FieldStorageConfig::create([ + 'entity_type' => $entity_type_id, + 'field_name' => $field_name, + 'id' => "$entity_type_id.$field_name", + 'type' => 'dynamic_entity_reference', + 'settings' => $storage_settings, + 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, + ]); + $storage->save(); + $config = FieldConfig::create([ + 'field_name' => $field_name, + 'entity_type' => $entity_type_id, + 'bundle' => $bundle, + 'id' => "$entity_type_id.$bundle.$field_name", + 'label' => $label, + 'settings' => $field_settings, + ]); + $config->save(); + $display_repository = \Drupal::service('entity_display.repository'); + $display_repository + ->getViewDisplay($entity_type_id, $bundle, 'default') + ->setComponent($field_name, [ + 'region' => 'content', + 'type' => 'dynamic_entity_reference_label', + ]) + ->save(); + $display_repository + ->getFormDisplay($entity_type_id, $bundle, 'default') + ->setComponent($field_name, [ + 'region' => 'content', + 'type' => 'dynamic_entity_reference_default', + 'settings' => [ + 'match_operator' => 'CONTAINS', + 'match_limit' => 10, + 'size' => 40, + 'placeholder' => '', + ], + ]) + ->save(); + } + /** * Tests field settings of dynamic entity reference field. */ @@ -109,31 +155,35 @@ class DynamicEntityReferenceTest extends WebDriverTestBase { $this->testEntity->save(); $this->drupalLogin($this->adminUser); - // Add a new dynamic entity reference field. - $this->drupalGet('entity_test/structure/entity_test/fields/add-field'); - if (version_compare(\Drupal::VERSION, '10.2-dev', '>=')) { - $page = $this->getSession()->getPage(); - $page->find('css', "[name='new_storage_type'][value='reference']")->click(); - $assert_session->waitForText('Choose an option below'); - $assert_session->elementExists('css', "[name='group_field_options_wrapper'][value='dynamic_entity_reference']")->click(); - } - else { - $select = $assert_session->selectExists('new_storage_type'); - $select->selectOption('dynamic_entity_reference'); - } - $label = $assert_session->fieldExists('label'); - $label->setValue('Foobar'); - // Wait for the machine name. - $assert_session->waitForElementVisible('css', '[name="label"] + * .machine-name-value'); - $this->submitForm([], t('Save and continue'), 'field-ui-field-storage-add-form'); - $page = $this->getSession()->getPage(); - $entity_type_ids_select = $assert_session->selectExists('settings[entity_type_ids][]', $page); - $entity_type_ids_select->selectOption('user'); - $entity_type_ids_select->selectOption('entity_test', TRUE); - $assert_session->selectExists('cardinality', $page) - ->selectOption(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); - $page->uncheckField('settings[exclude_entity_types]'); - $this->submitForm([], t('Save field settings'), 'field-storage-config-edit-form'); + $this->setupField( + 'field_foobar', + 'entity_test', + 'entity_test', + [ + 'entity_type_ids' => ['user', 'entity_test'], + 'exclude_entity_types' => FALSE, + ], + [ + 'entity_test' => [ + 'handler' => 'default:entity_test', + 'handler_settings' => [ + 'target_bundles' => [ + 'entity_test' => 'entity_test', + ], + ], + ], + 'user' => [ + 'handler' => 'default:user', + 'handler_settings' => [ + 'target_bundles' => [ + 'user' => 'user', + ], + ], + ], + ], + 'Foobar' + ); + $this->drupalGet('entity_test/structure/entity_test/fields/entity_test.entity_test.field_foobar'); $page = $this->getSession()->getPage(); $page->checkField('set_default_value'); $assert_session->fieldExists('default_value_input[field_foobar][0][target_id]'); @@ -144,42 +194,32 @@ class DynamicEntityReferenceTest extends WebDriverTestBase { $autocomplete_field = $page->findField('default_value_input[field_foobar][0][target_id]'); $autocomplete_field_1 = $page->findField('default_value_input[field_foobar][1][target_id]'); $target_type_select = $assert_session->selectExists('default_value_input[field_foobar][0][target_type]'); - $this->assertSame($autocomplete_field->getAttribute('data-autocomplete-path'), $this->createAutoCompletePath('entity_test')); - $this->assertSame($autocomplete_field_1->getAttribute('data-autocomplete-path'), $this->createAutoCompletePath('entity_test')); + $entity_test_path = $this->createAutoCompletePath('entity_test'); + $this->assertSame($autocomplete_field->getAttribute('data-autocomplete-path'), $entity_test_path); + $this->assertSame($autocomplete_field_1->getAttribute('data-autocomplete-path'), $entity_test_path); $target_type_select->selectOption('user'); // Changing the selected value changes the autocomplete path for the // corresponding autocomplete field. - $this->assertSame($autocomplete_field->getAttribute('data-autocomplete-path'), $this->createAutoCompletePath('user')); + $this->assertSession()->assertNoElementAfterWait('css', sprintf('[name="default_value_input[field_foobar][0][target_id]"][data-autocomplete-path="%s"]', $entity_test_path)); + $user_path = $this->createAutoCompletePath('user'); + $this->assertSame($autocomplete_field->getAttribute('data-autocomplete-path'), $user_path); // Changing the selected value of delta 0 doesn't change the autocomplete // path for delta 1 autocomplete field. - $this->assertSame($autocomplete_field_1->getAttribute('data-autocomplete-path'), $this->createAutoCompletePath('entity_test')); + $this->assertSame($autocomplete_field_1->getAttribute('data-autocomplete-path'), $entity_test_path); $target_type_select->selectOption('entity_test'); // Changing the selected value changes the autocomplete path for the // corresponding autocomplete field. - $this->assertSame($autocomplete_field->getAttribute('data-autocomplete-path'), $this->createAutoCompletePath('entity_test')); + $this->assertSession()->assertNoElementAfterWait('css', sprintf('[name="default_value_input[field_foobar][0][target_id]"][data-autocomplete-path="%s"]', $user_path)); + $this->assertSame($autocomplete_field->getAttribute('data-autocomplete-path'), $entity_test_path); // Changing the selected value of delta 0 doesn't change the autocomplete // path for delta 1 autocomplete field. - $this->assertSame($autocomplete_field_1->getAttribute('data-autocomplete-path'), $this->createAutoCompletePath('entity_test')); + $this->assertSame($autocomplete_field_1->getAttribute('data-autocomplete-path'), $entity_test_path); $page = $this->getSession()->getPage(); - $page->checkField('settings[entity_test][handler_settings][target_bundles][entity_test]'); $assert_session->assertWaitOnAjaxRequest(20000); $page->checkField('settings[entity_test][handler_settings][auto_create]'); - $this->submitForm([], t('Save settings'), 'field-config-edit-form'); + $this->submitForm([], t('Save settings')); $assert_session->pageTextContains('Saved Foobar configuration'); \Drupal::service('entity_field.manager')->clearCachedFieldDefinitions(); - $field_storage = FieldStorageConfig::loadByName('entity_test', 'field_foobar'); - $this->assertEmpty($field_storage->getSetting('exclude_entity_types')); - $this->assertEquals($field_storage->getSetting('entity_type_ids'), [ - 'entity_test' => 'entity_test', - 'user' => 'user', - ]); - $field_config = FieldConfig::loadByName('entity_test', 'entity_test', 'field_foobar'); - $settings = $field_config->getSettings(); - $this->assertEquals($settings['entity_test']['handler'], 'default:entity_test'); - $this->assertNotEmpty($settings['entity_test']['handler_settings']); - $this->assertEquals($settings['entity_test']['handler_settings']['target_bundles'], ['entity_test' => 'entity_test']); - $this->assertTrue($settings['entity_test']['handler_settings']['auto_create']); - $this->assertEmpty($settings['entity_test']['handler_settings']['auto_create_bundle']); $this->drupalGet('entity_test/add'); $autocomplete_field = $page->findField('field_foobar[0][target_id]'); $entity_type_field = $page->findField('field_foobar[0][target_type]'); @@ -204,29 +244,26 @@ class DynamicEntityReferenceTest extends WebDriverTestBase { $assert_session = $this->assertSession(); $this->drupalLogin($this->adminUser); $this->drupalCreateContentType(['type' => 'test_content']); - $this->drupalGet('/admin/structure/types/manage/test_content/fields/add-field'); - if (version_compare(\Drupal::VERSION, '10.2-dev', '>=')) { - $page = $this->getSession()->getPage(); - $page->find('css', "[name='new_storage_type'][value='reference']")->click(); - $assert_session->waitForText('Choose an option below'); - $assert_session->elementExists('css', "[name='group_field_options_wrapper'][value='dynamic_entity_reference']")->click(); - } - else { - $select = $assert_session->selectExists('new_storage_type'); - $select->selectOption('dynamic_entity_reference'); - } - $label = $assert_session->fieldExists('label'); - $label->setValue('Foobar'); - // Wait for the machine name. - $assert_session->waitForElementVisible('css', '[name="label"] + * .machine-name-value'); - $this->submitForm([], t('Save and continue'), 'field-ui-field-storage-add-form'); - $page = $this->getSession()->getPage(); - $entity_type_ids_select = $assert_session->selectExists('settings[entity_type_ids][]', $page); - $entity_type_ids_select->selectOption('user'); - $assert_session->selectExists('cardinality', $page) - ->selectOption(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); - $page->uncheckField('settings[exclude_entity_types]'); - $this->submitForm([], t('Save field settings'), 'field-storage-config-edit-form'); + $this->setupField( + 'field_foobar', + 'node', + 'test_content', + [ + 'entity_type_ids' => ['user'], + 'exclude_entity_types' => FALSE, + ], + [ + 'user' => [ + 'handler' => 'default:user', + 'handler_settings' => [ + 'target_bundles' => [ + 'user' => 'user', + ], + ], + ], + ], + 'Foobar' + ); $this->drupalGet('admin/structure/types/manage/test_content/display'); $page = $this->getSession()->getPage(); $formats = $assert_session->selectExists('fields[field_foobar][type]', $page); @@ -239,9 +276,8 @@ class DynamicEntityReferenceTest extends WebDriverTestBase { $assert_session->optionExists('fields[field_foobar][settings_edit_form][settings][user][view_mode]', 'compact', $page); $assert_session->optionExists('fields[field_foobar][settings_edit_form][settings][user][view_mode]', 'full', $page); // Edit field, turn on exclude entity types and check display again. - $this->drupalGet('admin/structure/types/manage/test_content/fields/node.test_content.field_foobar/storage'); - $page->checkField('settings[exclude_entity_types]'); - $this->submitForm([], t('Save field settings'), 'field-storage-config-edit-form'); + $storage = FieldStorageConfig::loadByName('node', 'field_foobar'); + $storage->setSetting('exclude_entity_types', TRUE)->save(); $this->drupalGet('admin/structure/types/manage/test_content/display'); $page = $this->getSession()->getPage(); $formats = $assert_session->selectExists('fields[field_foobar][type]', $page); @@ -287,6 +323,7 @@ class DynamicEntityReferenceTest extends WebDriverTestBase { */ protected function createAutoCompletePath($target_type) { $selection_settings = [ + 'target_bundles' => [$target_type => $target_type], 'match_operator' => 'CONTAINS', 'match_limit' => 10, ];