From a547ae61783bfe21a94acc077c66c015a7dd7c57 Mon Sep 17 00:00:00 2001 From: Nathaniel Catchpole <catch@35733.no-reply.drupal.org> Date: Mon, 7 Mar 2016 09:21:33 +0900 Subject: [PATCH] Issue #2412569 by claudiu.cristea, amateescu, yched, jibran, epari.siva: Allow setting the auto-create bundle on entity reference fields with multiple target bundles --- core/config/schema/core.data_types.schema.yml | 3 + .../DefaultSelection.php | 41 +++++++ .../Field/FieldType/EntityReferenceItem.php | 15 ++- .../EntityReferenceAutocompleteWidget.php | 26 ++--- core/modules/field/field.install | 36 +++++++ core/modules/field/field.module | 2 +- .../EntityReferenceAdminTest.php | 82 ++++++++++++-- .../EntityReferenceAutoCreateTest.php | 102 +++++++++++++++++- .../src/Tests/Update/FieldUpdateTest.php | 20 ++++ ...views_entity_reference_plugins-2429191.php | 37 +++++-- ...e.article.field_ref_autocreate_2412569.yml | 29 +++++ ...rage.node.field_ref_autocreate_2412569.yml | 20 ++++ .../TermSelection.php | 7 -- 13 files changed, 376 insertions(+), 44 deletions(-) create mode 100644 core/modules/field/tests/fixtures/update/field.field.node.article.field_ref_autocreate_2412569.yml create mode 100644 core/modules/field/tests/fixtures/update/field.storage.node.field_ref_autocreate_2412569.yml diff --git a/core/config/schema/core.data_types.schema.yml b/core/config/schema/core.data_types.schema.yml index 4ab0fd769c3d..559362f506ac 100644 --- a/core/config/schema/core.data_types.schema.yml +++ b/core/config/schema/core.data_types.schema.yml @@ -795,6 +795,9 @@ entity_reference_selection: auto_create: type: boolean label: 'Create referenced entities if they don''t already exist' + auto_create_bundle: + type: string + label: 'Bundle assigned to the auto-created entities.' entity_reference_selection.*: type: entity_reference_selection diff --git a/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/DefaultSelection.php b/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/DefaultSelection.php index b108bb45e89b..e89596c22507 100644 --- a/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/DefaultSelection.php +++ b/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/DefaultSelection.php @@ -122,6 +122,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta 'field' => '_none', ), 'auto_create' => FALSE, + 'auto_create_bundle' => NULL, ); if ($entity_type->hasKey('bundle')) { @@ -139,7 +140,19 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta '#size' => 6, '#multiple' => TRUE, '#element_validate' => [[get_class($this), 'elementValidateFilter']], + '#ajax' => TRUE, + '#limit_validation_errors' => [], ); + + $form['target_bundles_update'] = [ + '#type' => 'submit', + '#value' => $this->t('Update form'), + '#limit_validation_errors' => [], + '#attributes' => [ + 'class' => ['js-hide'], + ], + '#submit' => [[EntityReferenceItem::class, 'settingsAjaxSubmit']], + ]; } else { $form['target_bundles'] = array( @@ -207,6 +220,30 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta } } + $form['auto_create'] = array( + '#type' => 'checkbox', + '#title' => $this->t("Create referenced entities if they don't already exist"), + '#default_value' => $selection_handler_settings['auto_create'], + '#weight' => -2, + ); + + if ($entity_type->hasKey('bundle')) { + $bundles = array_intersect_key($bundle_options, array_filter((array) $selection_handler_settings['target_bundles'])); + $form['auto_create_bundle'] = [ + '#type' => 'select', + '#title' => $this->t('Store new items in'), + '#options' => $bundles, + '#default_value' => $selection_handler_settings['auto_create_bundle'], + '#access' => count($bundles) > 1, + '#states' => [ + 'visible' => [ + ':input[name="settings[handler_settings][auto_create]"]' => ['checked' => TRUE], + ], + ], + '#weight' => -1, + ]; + } + return $form; } @@ -221,6 +258,10 @@ public function validateConfigurationForm(array &$form, FormStateInterface $form if ($form_state->getValue(['settings', 'handler_settings', 'target_bundles']) === []) { $form_state->setValue(['settings', 'handler_settings', 'target_bundles'], NULL); } + + // Don't store the 'target_bundles_update' button value into the field + // config settings. + $form_state->unsetValue(['settings', 'handler_settings', 'target_bundles_update']); } /** 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 9ad1a9d29aec..4c3235120333 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php @@ -413,7 +413,9 @@ public static function calculateDependencies(FieldDefinitionInterface $field_def } } - // Depend on target bundle configurations. + // Depend on target bundle configurations. Dependencies for 'target_bundles' + // also covers the 'auto_create_bundle' setting, if any, because its value + // is included in the 'target_bundles' list. $handler = $field_definition->getSetting('handler_settings'); if (!empty($handler['target_bundles'])) { if ($bundle_entity_type_id = $target_entity_type->getBundleEntityType()) { @@ -473,10 +475,19 @@ public static function onDependencyRemoval(FieldDefinitionInterface $field_defin foreach ($storage->loadMultiple($handler_settings['target_bundles']) as $bundle) { if (isset($dependencies[$bundle->getConfigDependencyKey()][$bundle->getConfigDependencyName()])) { unset($handler_settings['target_bundles'][$bundle->id()]); + + // If this bundle is also used in the 'auto_create_bundle' + // setting, disable the auto-creation feature completely. + $auto_create_bundle = !empty($handler_settings['auto_create_bundle']) ? $handler_settings['auto_create_bundle'] : FALSE; + if ($auto_create_bundle && $auto_create_bundle == $bundle->id()) { + $handler_settings['auto_create'] = NULL; + $handler_settings['auto_create_bundle'] = NULL; + } + $bundles_changed = TRUE; // In case we deleted the only target bundle allowed by the field - // we have to log a warning message because the field will not + // we have to log a critical message because the field will not // function correctly anymore. if ($handler_settings['target_bundles'] === []) { \Drupal::logger('entity_reference')->critical('The %target_bundle bundle (entity type: %target_entity_type) was deleted. As a result, the %field_name entity reference field (entity_type: %entity_type, bundle: %bundle) no longer has any valid bundle it can reference. The field is not working correctly anymore and has to be adjusted.', [ diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/EntityReferenceAutocompleteWidget.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/EntityReferenceAutocompleteWidget.php index 79eff67b7579..667d01309b22 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/EntityReferenceAutocompleteWidget.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/EntityReferenceAutocompleteWidget.php @@ -106,9 +106,9 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen '#placeholder' => $this->getSetting('placeholder'), ); - if ($this->getSelectionHandlerSetting('auto_create')) { + if ($this->getSelectionHandlerSetting('auto_create') && ($bundle = $this->getAutocreateBundle())) { $element['#autocreate'] = array( - 'bundle' => $this->getAutocreateBundle(), + 'bundle' => $bundle, 'uid' => ($entity instanceof EntityOwnerInterface) ? $entity->getOwnerId() : \Drupal::currentUser()->id() ); } @@ -147,18 +147,20 @@ public function massageFormValues(array $values, array $form, FormStateInterface */ protected function getAutocreateBundle() { $bundle = NULL; - if ($this->getSelectionHandlerSetting('auto_create')) { - // If the 'target_bundles' setting is restricted to a single choice, we - // can use that. - if (($target_bundles = $this->getSelectionHandlerSetting('target_bundles')) && count($target_bundles) == 1) { + if ($this->getSelectionHandlerSetting('auto_create') && $target_bundles = $this->getSelectionHandlerSetting('target_bundles')) { + // If there's only one target bundle, use it. + if (count($target_bundles) == 1) { $bundle = reset($target_bundles); } - // Otherwise use the first bundle as a fallback. - else { - // @todo Expose a proper UI for choosing the bundle for autocreated - // entities in https://www.drupal.org/node/2412569. - $bundles = entity_get_bundles($this->getFieldSetting('target_type')); - $bundle = key($bundles); + // Otherwise use the target bundle stored in selection handler settings. + elseif (!$bundle = $this->getSelectionHandlerSetting('auto_create_bundle')) { + // If no bundle has been set as auto create target means that there is + // an inconsistency in entity reference field settings. + trigger_error(sprintf( + "The 'Create referenced entities if they don't already exist' option is enabled but a specific destination bundle is not set. You should re-visit and fix the settings of the '%s' (%s) field.", + $this->fieldDefinition->getLabel(), + $this->fieldDefinition->getName() + ), E_USER_WARNING); } } diff --git a/core/modules/field/field.install b/core/modules/field/field.install index 1860ad8e6382..ecd2b3150bd0 100644 --- a/core/modules/field/field.install +++ b/core/modules/field/field.install @@ -68,3 +68,39 @@ function field_update_8002() { } } } + +/** + * Populate the new 'auto_create_bundle' setting for entity reference fields. + */ +function field_update_8003() { + $config = \Drupal::configFactory(); + /** @var \Drupal\Core\Field\FieldTypePluginManager $field_type_manager */ + $field_type_manager = \Drupal::service('plugin.manager.field.field_type'); + + // Iterate over all fields. + foreach ($config->listAll('field.field.') as $field_id) { + $field = $config->getEditable($field_id); + $class = $field_type_manager->getPluginClass($field->get('field_type')); + + // Deal only with entity reference fields and descendants. + if ($class == EntityReferenceItem::class || is_subclass_of($class, EntityReferenceItem::class)) { + $handler_settings = $field->get('settings.handler_settings'); + + if (is_array($handler_settings) && !empty($handler_settings['auto_create'])) { + // If the field can reference multiple bundles, pick the first one + // available in order to replicate the previous behavior. + if (is_array($handler_settings['target_bundles']) && count($handler_settings['target_bundles']) > 1) { + $handler_settings['auto_create_bundle'] = reset($handler_settings['target_bundles']); + } + // Otherwise, we don't know which bundle to use for auto-creation so we + // have to disable the functionality completely. + elseif (!$handler_settings['target_bundles']) { + $handler_settings['auto_create'] = FALSE; + $handler_settings['auto_create_bundle'] = NULL; + } + } + + $field->set('settings.handler_settings', $handler_settings)->save(TRUE); + } + } +} diff --git a/core/modules/field/field.module b/core/modules/field/field.module index e453c46cbb7a..51b82e906fc1 100644 --- a/core/modules/field/field.module +++ b/core/modules/field/field.module @@ -250,7 +250,7 @@ function field_entity_bundle_delete($entity_type_id, $bundle) { $field_config->save(); // In case we deleted the only target bundle allowed by the field we - // have to log a warning message because the field will not function + // have to log a critical message because the field will not function // correctly anymore. if ($handler_settings['target_bundles'] === []) { \Drupal::logger('entity_reference')->critical('The %target_bundle bundle (entity type: %target_entity_type) was deleted. As a result, the %field_name entity reference field (entity_type: %entity_type, bundle: %bundle) no longer has any valid bundle it can reference. The field is not working correctly anymore and has to be adjusted.', [ diff --git a/core/modules/field/src/Tests/EntityReference/EntityReferenceAdminTest.php b/core/modules/field/src/Tests/EntityReference/EntityReferenceAdminTest.php index 9ee63b0732b2..0d8c4b902719 100644 --- a/core/modules/field/src/Tests/EntityReference/EntityReferenceAdminTest.php +++ b/core/modules/field/src/Tests/EntityReference/EntityReferenceAdminTest.php @@ -7,6 +7,8 @@ namespace Drupal\field\Tests\EntityReference; +use Drupal\Component\Utility\Unicode; +use Drupal\field\Entity\FieldConfig; use Drupal\Core\Entity\Entity; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\field_ui\Tests\FieldUiTestTrait; @@ -315,7 +317,7 @@ public function testFieldAdminHandler() { // Tests adding default values to autocomplete widgets. Vocabulary::create(array('vid' => 'tags', 'name' => 'tags'))->save(); - $taxonomy_term_field_name = $this->createEntityReferenceField('taxonomy_term', 'tags'); + $taxonomy_term_field_name = $this->createEntityReferenceField('taxonomy_term', ['tags']); $field_path = 'node.' . $this->type . '.field_' . $taxonomy_term_field_name; $this->drupalGet($bundle_path . '/fields/' . $field_path . '/storage'); $edit = [ @@ -348,13 +350,13 @@ public function testAvailableFormatters() { Vocabulary::create(array('vid' => 'tags', 'name' => 'tags'))->save(); // Create entity reference field with taxonomy term as a target. - $taxonomy_term_field_name = $this->createEntityReferenceField('taxonomy_term', 'tags'); + $taxonomy_term_field_name = $this->createEntityReferenceField('taxonomy_term', ['tags']); // Create entity reference field with user as a target. $user_field_name = $this->createEntityReferenceField('user'); // Create entity reference field with node as a target. - $node_field_name = $this->createEntityReferenceField('node', $this->type); + $node_field_name = $this->createEntityReferenceField('node', [$this->type]); // Create entity reference field with date format as a target. $date_format_field_name = $this->createEntityReferenceField('date_format'); @@ -402,18 +404,79 @@ public function testAvailableFormatters() { )); } + /** + * Tests field settings for an entity reference field when the field has + * multiple target bundles and is set to auto-create the target entity. + */ + public function testMultipleTargetBundles() { + /** @var \Drupal\taxonomy\Entity\Vocabulary[] $vocabularies */ + $vocabularies = []; + for ($i = 0; $i < 2; $i++) { + $vid = Unicode::strtolower($this->randomMachineName()); + $vocabularies[$i] = Vocabulary::create([ + 'name' => $this->randomString(), + 'vid' => $vid, + ]); + $vocabularies[$i]->save(); + } + + // Create a new field pointing to the first vocabulary. + $field_name = $this->createEntityReferenceField('taxonomy_term', [$vocabularies[0]->id()]); + $field_name = "field_$field_name"; + $field_id = 'node.' . $this->type . '.' . $field_name; + $path = 'admin/structure/types/manage/' . $this->type . '/fields/' . $field_id; + + $this->drupalGet($path); + + // Expect that there's no 'auto_create_bundle' selected. + $this->assertNoFieldByName('settings[handler_settings][auto_create_bundle]'); + + $edit = [ + 'settings[handler_settings][target_bundles][' . $vocabularies[1]->id() . ']' => TRUE, + ]; + // Enable the second vocabulary as a target bundle. + $this->drupalPostAjaxForm($path, $edit, key($edit)); + // Expect a select element with the two vocabularies as options. + $this->assertFieldByXPath("//select[@name='settings[handler_settings][auto_create_bundle]']/option[@value='" . $vocabularies[0]->id() . "']"); + $this->assertFieldByXPath("//select[@name='settings[handler_settings][auto_create_bundle]']/option[@value='" . $vocabularies[1]->id() . "']"); + + $edit = [ + 'settings[handler_settings][auto_create]' => TRUE, + 'settings[handler_settings][auto_create_bundle]' => $vocabularies[1]->id(), + ]; + $this->drupalPostForm(NULL, $edit, t('Save settings')); + + /** @var \Drupal\field\Entity\FieldConfig $field_config */ + $field_config = FieldConfig::load($field_id); + // Expect that the target bundle has been saved in the backend. + $this->assertEqual($field_config->getSetting('handler_settings')['auto_create_bundle'], $vocabularies[1]->id()); + + // Delete the other bundle. Field config should not be affected. + $vocabularies[0]->delete(); + $field_config = FieldConfig::load($field_id); + $this->assertTrue($field_config->getSetting('handler_settings')['auto_create']); + $this->assertIdentical($field_config->getSetting('handler_settings')['auto_create_bundle'], $vocabularies[1]->id()); + + // Delete the bundle set for entity auto-creation. Auto-created settings + // should be reset (no auto-creation). + $vocabularies[1]->delete(); + $field_config = FieldConfig::load($field_id); + $this->assertFalse($field_config->getSetting('handler_settings')['auto_create']); + $this->assertFalse(isset($field_config->getSetting('handler_settings')['auto_create_bundle'])); + } + /** * Creates a new Entity Reference fields with a given target type. * - * @param $target_type + * @param string $target_type * The name of the target type - * @param $bundle - * Name of the bundle - * Default = NULL + * @param string[] $bundles + * A list of bundle IDs. Defaults to []. + * * @return string * Returns the generated field name */ - public function createEntityReferenceField($target_type, $bundle = NULL) { + protected function createEntityReferenceField($target_type, $bundles = []) { // Generates a bundle path for the newly created content type. $bundle_path = 'admin/structure/types/manage/' . $this->type; @@ -422,7 +485,7 @@ public function createEntityReferenceField($target_type, $bundle = NULL) { $storage_edit = $field_edit = array(); $storage_edit['settings[target_type]'] = $target_type; - if ($bundle) { + foreach ($bundles as $bundle) { $field_edit['settings[handler_settings][target_bundles][' . $bundle . ']'] = TRUE; } @@ -432,7 +495,6 @@ public function createEntityReferenceField($target_type, $bundle = NULL) { return $field_name; } - /** * Checks if a select element contains the specified options. * diff --git a/core/modules/field/src/Tests/EntityReference/EntityReferenceAutoCreateTest.php b/core/modules/field/src/Tests/EntityReference/EntityReferenceAutoCreateTest.php index a381b1f93ab8..acaabdbd71a5 100644 --- a/core/modules/field/src/Tests/EntityReference/EntityReferenceAutoCreateTest.php +++ b/core/modules/field/src/Tests/EntityReference/EntityReferenceAutoCreateTest.php @@ -7,9 +7,11 @@ namespace Drupal\field\Tests\EntityReference; +use Drupal\Component\Utility\Unicode; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\field\Entity\FieldConfig; use Drupal\simpletest\WebTestBase; +use Drupal\taxonomy\Entity\Vocabulary; use Drupal\node\Entity\Node; use Drupal\field\Entity\FieldStorageConfig; @@ -20,7 +22,9 @@ */ class EntityReferenceAutoCreateTest extends WebTestBase { - public static $modules = ['node']; + use EntityReferenceTestTrait; + + public static $modules = ['node', 'taxonomy']; /** * The name of a content type that will reference $referencedType. @@ -84,6 +88,9 @@ protected function setUp() { 'type' => 'entity_reference_autocomplete', )) ->save(); + + $account = $this->drupalCreateUser(['access content', "create $this->referencingType content"]); + $this->drupalLogin($account); } /** @@ -91,9 +98,6 @@ protected function setUp() { * entity. */ public function testAutoCreate() { - $user1 = $this->drupalCreateUser(array('access content', "create $this->referencingType content")); - $this->drupalLogin($user1); - $this->drupalGet('node/add/' . $this->referencingType); $this->assertFieldByXPath('//input[@id="edit-test-field-0-target-id" and contains(@class, "form-autocomplete")]', NULL, 'The autocomplete input element appears.'); @@ -136,4 +140,94 @@ public function testAutoCreate() { $this->assertText($referencing_node->label(), 'Referencing node label found.'); $this->assertText($referenced_node->label(), 'Referenced node label found.'); } + + /** + * Tests if an entity reference field having multiple target bundles is + * storing the auto-created entity in the right destination. + */ + public function testMultipleTargetBundles() { + /** @var \Drupal\taxonomy\Entity\Vocabulary[] $vocabularies */ + $vocabularies = []; + for ($i = 0; $i < 2; $i++) { + $vid = Unicode::strtolower($this->randomMachineName()); + $vocabularies[$i] = Vocabulary::create([ + 'name' => $this->randomMachineName(), + 'vid' => $vid, + ]); + $vocabularies[$i]->save(); + } + + // Create a taxonomy term entity reference field that saves the auto-created + // taxonomy terms in the second vocabulary from the two that were configured + // as targets. + $field_name = Unicode::strtolower($this->randomMachineName()); + $handler_settings = [ + 'target_bundles' => [ + $vocabularies[0]->id() => $vocabularies[0]->id(), + $vocabularies[1]->id() => $vocabularies[1]->id(), + ], + 'auto_create' => TRUE, + 'auto_create_bundle' => $vocabularies[1]->id(), + ]; + $this->createEntityReferenceField('node', $this->referencingType, $field_name, $this->randomString(), 'taxonomy_term', 'default', $handler_settings); + /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $fd */ + entity_get_form_display('node', $this->referencingType, 'default') + ->setComponent($field_name, ['type' => 'entity_reference_autocomplete']) + ->save(); + + $term_name = $this->randomString(); + $edit = [ + $field_name . '[0][target_id]' => $term_name, + 'title[0][value]' => $this->randomString(), + ]; + + $this->drupalPostForm('node/add/' . $this->referencingType, $edit, 'Save'); + /** @var \Drupal\taxonomy\Entity\Term $term */ + $term = taxonomy_term_load_multiple_by_name($term_name); + $term = reset($term); + + // The new term is expected to be stored in the second vocabulary. + $this->assertEqual($vocabularies[1]->id(), $term->bundle()); + + /** @var \Drupal\field\Entity\FieldConfig $field_config */ + $field_config = FieldConfig::loadByName('node', $this->referencingType, $field_name); + $handler_settings = $field_config->getSetting('handler_settings'); + + // Change the field setting to store the auto-created terms in the first + // vocabulary and test again. + $handler_settings['auto_create_bundle'] = $vocabularies[0]->id(); + $field_config->setSetting('handler_settings', $handler_settings); + $field_config->save(); + + $term_name = $this->randomString(); + $edit = [ + $field_name . '[0][target_id]' => $term_name, + 'title[0][value]' => $this->randomString(), + ]; + + $this->drupalPostForm('node/add/' . $this->referencingType, $edit, 'Save'); + /** @var \Drupal\taxonomy\Entity\Term $term */ + $term = taxonomy_term_load_multiple_by_name($term_name); + $term = reset($term); + + // The second term is expected to be stored in the first vocabulary. + $this->assertEqual($vocabularies[0]->id(), $term->bundle()); + + // @todo Re-enable this test when WebTestBase::curlHeaderCallback() provides + // a way to catch and assert user-triggered errors. + + // Test the case when the field config settings are inconsistent. + //unset($handler_settings['auto_create_bundle']); + //$field_config->setSetting('handler_settings', $handler_settings); + //$field_config->save(); + // + //$this->drupalGet('node/add/' . $this->referencingType); + //$error_message = sprintf( + // "Create referenced entities if they don't already exist option is enabled but a specific destination bundle is not set. You should re-visit and fix the settings of the '%s' (%s) field.", + // $field_config->getLabel(), + // $field_config->getName() + //); + //$this->assertErrorLogged($error_message); + } + } diff --git a/core/modules/field/src/Tests/Update/FieldUpdateTest.php b/core/modules/field/src/Tests/Update/FieldUpdateTest.php index 65ca7200aeb3..d555f47d2a31 100644 --- a/core/modules/field/src/Tests/Update/FieldUpdateTest.php +++ b/core/modules/field/src/Tests/Update/FieldUpdateTest.php @@ -111,6 +111,26 @@ public function testFieldUpdate8002() { $this->assertEqual(array_keys($referencable['article']), [$node_1->id()]); } + /** + * Tests field_update_8003(). + * + * @see field_update_8003() + */ + public function testFieldUpdate8003() { + // Run updates. + $this->runUpdates(); + + // Check that the new 'auto_create_bundle' setting is populated correctly. + $field = $this->configFactory->get('field.field.node.article.field_ref_autocreate_2412569'); + $handler_settings = $field->get('settings.handler_settings'); + + $expected_target_bundles = ['tags' => 'tags', 'test' => 'test']; + $this->assertEqual($handler_settings['target_bundles'], $expected_target_bundles); + + $this->assertTrue($handler_settings['auto_create']); + $this->assertEqual($handler_settings['auto_create_bundle'], 'tags'); + } + /** * Asserts that a config depends on 'entity_reference' or not * diff --git a/core/modules/field/tests/fixtures/update/drupal-8.views_entity_reference_plugins-2429191.php b/core/modules/field/tests/fixtures/update/drupal-8.views_entity_reference_plugins-2429191.php index 90f395b6419b..ca7c51a1db74 100644 --- a/core/modules/field/tests/fixtures/update/drupal-8.views_entity_reference_plugins-2429191.php +++ b/core/modules/field/tests/fixtures/update/drupal-8.views_entity_reference_plugins-2429191.php @@ -26,8 +26,14 @@ ]) ->execute(); -// Configuration for an entity_reference field storage. -$config = Yaml::decode(file_get_contents(__DIR__ . '/field.storage.node.field_ref_views_select_2429191.yml')); +// Configuration for an entity_reference field storage using the View for +// selection. +$field_ref_views_select_2429191 = Yaml::decode(file_get_contents(__DIR__ . '/field.storage.node.field_ref_views_select_2429191.yml')); + +// Configuration for an entity_reference field storage using the auto-create +// feature. +$field_ref_autocreate_2412569 = Yaml::decode(file_get_contents(__DIR__ . '/field.storage.node.field_ref_autocreate_2412569.yml')); + $connection->insert('config') ->fields([ 'collection', @@ -36,8 +42,13 @@ ]) ->values([ 'collection' => '', - 'name' => 'field.storage.' . $config['id'], - 'data' => serialize($config), + 'name' => 'field.storage.' . $field_ref_views_select_2429191['id'], + 'data' => serialize($field_ref_views_select_2429191), + ]) + ->values([ + 'collection' => '', + 'name' => 'field.storage.' . $field_ref_autocreate_2412569['id'], + 'data' => serialize($field_ref_autocreate_2412569), ]) ->execute(); // We need to Update the registry of "last installed" field definitions. @@ -48,7 +59,8 @@ ->execute() ->fetchField(); $installed = unserialize($installed); -$installed['field_ref_views_select_2429191'] = new \Drupal\field\Entity\FieldStorageConfig($config); +$installed['field_ref_views_select_2429191'] = new \Drupal\field\Entity\FieldStorageConfig($field_ref_views_select_2429191); +$installed['field_ref_autocreate_2412569'] = new \Drupal\field\Entity\FieldStorageConfig($field_ref_autocreate_2412569); $connection->update('key_value') ->condition('collection', 'entity.definitions.installed') ->condition('name', 'node.field_storage_definitions') @@ -58,7 +70,11 @@ ->execute(); // Configuration for an entity_reference field using the View for selection. -$config = Yaml::decode(file_get_contents(__DIR__ . '/field.field.node.article.field_ref_views_select_2429191.yml')); +$field_ref_views_select_2429191 = Yaml::decode(file_get_contents(__DIR__ . '/field.field.node.article.field_ref_views_select_2429191.yml')); + +// Configuration for an entity_reference field using the auto-create feature. +$field_ref_autocreate_2412569 = Yaml::decode(file_get_contents(__DIR__ . '/field.field.node.article.field_ref_autocreate_2412569.yml')); + $connection->insert('config') ->fields([ 'collection', @@ -67,7 +83,12 @@ ]) ->values([ 'collection' => '', - 'name' => 'field.field.' . $config['id'], - 'data' => serialize($config), + 'name' => 'field.field.' . $field_ref_views_select_2429191['id'], + 'data' => serialize($field_ref_views_select_2429191), + ]) + ->values([ + 'collection' => '', + 'name' => 'field.field.' . $field_ref_autocreate_2412569['id'], + 'data' => serialize($field_ref_autocreate_2412569), ]) ->execute(); diff --git a/core/modules/field/tests/fixtures/update/field.field.node.article.field_ref_autocreate_2412569.yml b/core/modules/field/tests/fixtures/update/field.field.node.article.field_ref_autocreate_2412569.yml new file mode 100644 index 000000000000..2606bf6f0aa5 --- /dev/null +++ b/core/modules/field/tests/fixtures/update/field.field.node.article.field_ref_autocreate_2412569.yml @@ -0,0 +1,29 @@ +uuid: d6deba8d-073a-4572-a000-ee2a2de94de2 +langcode: en +status: true +dependencies: + config: + - field.storage.node.field_ref_autocreate_2412569 + - node.type.article + - taxonomy.vocabulary.tags + - taxonomy.vocabulary.test +id: node.article.field_ref_autocreate_2412569 +field_name: field_ref_autocreate_2412569 +entity_type: node +bundle: article +label: 'Ref Autocreate 2412569' +description: '' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: + handler: 'default:taxonomy_term' + handler_settings: + target_bundles: + tags: tags + test: test + sort: + field: _none + auto_create: true +field_type: entity_reference diff --git a/core/modules/field/tests/fixtures/update/field.storage.node.field_ref_autocreate_2412569.yml b/core/modules/field/tests/fixtures/update/field.storage.node.field_ref_autocreate_2412569.yml new file mode 100644 index 000000000000..19e4a6abf76c --- /dev/null +++ b/core/modules/field/tests/fixtures/update/field.storage.node.field_ref_autocreate_2412569.yml @@ -0,0 +1,20 @@ +uuid: 5e4095a3-8f89-4d7a-b222-34bf5240b646 +langcode: en +status: true +dependencies: + module: + - node + - taxonomy +id: node.field_ref_autocreate_2412569 +field_name: field_ref_autocreate_2412569 +entity_type: node +type: entity_reference +settings: + target_type: taxonomy_term +module: core +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/core/modules/taxonomy/src/Plugin/EntityReferenceSelection/TermSelection.php b/core/modules/taxonomy/src/Plugin/EntityReferenceSelection/TermSelection.php index ef8a89239fb1..f9bb7374493b 100644 --- a/core/modules/taxonomy/src/Plugin/EntityReferenceSelection/TermSelection.php +++ b/core/modules/taxonomy/src/Plugin/EntityReferenceSelection/TermSelection.php @@ -40,13 +40,6 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta $form = parent::buildConfigurationForm($form, $form_state); $form['target_bundles']['#title'] = $this->t('Available Vocabularies'); - // @todo: Currently allow auto-create only on taxonomy terms. - $form['auto_create'] = array( - '#type' => 'checkbox', - '#weight' => -1, - '#title' => $this->t("Create referenced entities if they don't already exist"), - '#default_value' => isset($this->configuration['handler_settings']['auto_create']) ? $this->configuration['handler_settings']['auto_create'] : FALSE, - ); // Sorting is not possible for taxonomy terms because we use // \Drupal\taxonomy\TermStorageInterface::loadTree() to retrieve matches. -- GitLab