From d75377535a4288b10a4dfbd38a201e032d0872a2 Mon Sep 17 00:00:00 2001 From: Lee Rowlands Date: Wed, 31 Jan 2024 15:20:50 +1000 Subject: [PATCH] Issue #3383131 by WalkingDexter, xjm, allisonherodevs, ashley_herodev, pradhumanjain2311, smustgrave, marcoliver, lauriii: Entity autocomplete form element ignores entities with label "0" --- .../Core/Entity/Element/EntityAutocomplete.php | 3 ++- .../Controller/EntityAutocompleteController.php | 6 +++++- .../Element/EntityAutocompleteElementFormTest.php | 15 +++++++++++++++ .../Core/Entity/EntityAutocompleteTest.php | 14 +++++++++++--- 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php b/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php index 2cb823aaed3..bd63eeb0b61 100644 --- a/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php +++ b/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php @@ -203,7 +203,8 @@ class EntityAutocomplete extends Textfield { public static function validateEntityAutocomplete(array &$element, FormStateInterface $form_state, array &$complete_form) { $value = NULL; - if (!empty($element['#value'])) { + // Check the value for emptiness, but allow the use of (string) "0". + if (!empty($element['#value']) || (is_string($element['#value']) && strlen($element['#value']))) { $options = $element['#selection_settings'] + [ 'target_type' => $element['#target_type'], 'handler' => $element['#selection_handler'], diff --git a/core/modules/system/src/Controller/EntityAutocompleteController.php b/core/modules/system/src/Controller/EntityAutocompleteController.php index a49da373406..860ab7f846e 100644 --- a/core/modules/system/src/Controller/EntityAutocompleteController.php +++ b/core/modules/system/src/Controller/EntityAutocompleteController.php @@ -77,8 +77,12 @@ class EntityAutocompleteController extends ControllerBase { */ public function handleAutocomplete(Request $request, $target_type, $selection_handler, $selection_settings_key) { $matches = []; + // Get the typed string from the URL, if it exists. - if ($input = $request->query->get('q')) { + $input = $request->query->get('q'); + + // Check this string for emptiness, but allow any non-empty string. + if (is_string($input) && strlen($input)) { $tag_list = Tags::explode($input); $typed_string = !empty($tag_list) ? mb_strtolower(array_pop($tag_list)) : ''; diff --git a/core/tests/Drupal/KernelTests/Core/Entity/Element/EntityAutocompleteElementFormTest.php b/core/tests/Drupal/KernelTests/Core/Entity/Element/EntityAutocompleteElementFormTest.php index e2f7780e95c..2141a613c71 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/Element/EntityAutocompleteElementFormTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/Element/EntityAutocompleteElementFormTest.php @@ -92,6 +92,12 @@ class EntityAutocompleteElementFormTest extends EntityKernelTestBase implements $entity->save(); $this->referencedEntities[] = $entity; } + + $entity = EntityTest::create([ + 'name' => '0', + ]); + $entity->save(); + $this->referencedEntities[] = $entity; } /** @@ -184,6 +190,11 @@ class EntityAutocompleteElementFormTest extends EntityKernelTestBase implements '#tags' => TRUE, ]; + $form['single_name_0'] = [ + '#type' => 'entity_autocomplete', + '#target_type' => 'entity_test', + ]; + return $form; } @@ -211,6 +222,7 @@ class EntityAutocompleteElementFormTest extends EntityKernelTestBase implements 'tags_autocreate_specific_uid' => $this->getAutocompleteInput($this->referencedEntities[0]) . ', tags - autocreated entity label with specific uid, ' . $this->getAutocompleteInput($this->referencedEntities[1]), 'single_string_id' => $this->getAutocompleteInput($this->referencedEntities[2]), 'tags_string_id' => $this->getAutocompleteInput($this->referencedEntities[2]) . ', ' . $this->getAutocompleteInput($this->referencedEntities[3]), + 'single_name_0' => $this->referencedEntities[4]->label(), ]); $form_builder = $this->container->get('form_builder'); $form_builder->submitForm($this, $form_state); @@ -271,6 +283,9 @@ class EntityAutocompleteElementFormTest extends EntityKernelTestBase implements ['target_id' => $this->referencedEntities[3]->id()], ]; $this->assertEquals($expected, $form_state->getValue('tags_string_id')); + + // Test the 'single_name_0' element. + $this->assertEquals($this->referencedEntities[4]->id(), $form_state->getValue('single_name_0')); } /** diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityAutocompleteTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityAutocompleteTest.php index 2b8058a45a5..5b41f448bf3 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityAutocompleteTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityAutocompleteTest.php @@ -106,9 +106,11 @@ class EntityAutocompleteTest extends EntityKernelTestBase { ]; $this->assertSame($target, reset($data), 'Autocomplete returns an entity label containing a comma and a slash.'); - $input = ''; - $data = $this->getAutocompleteResult($input); - $this->assertSame([], $data, 'Autocomplete of empty string returns empty result'); + // Test empty input. + foreach (['', NULL, FALSE, 0, 0.0] as $input) { + $data = $this->getAutocompleteResult($input); + $this->assertSame([], $data, 'Autocomplete of empty input returns empty result'); + } $input = ','; $data = $this->getAutocompleteResult($input); @@ -130,6 +132,12 @@ class EntityAutocompleteTest extends EntityKernelTestBase { $this->assertSame(Html::escape($entity_1->name->value), $data[0]['label'], 'Autocomplete returned the first matching entity'); $this->assertSame(Html::escape($entity_2->name->value), $data[1]['label'], 'Autocomplete returned the second matching entity'); $this->assertSame(Html::escape($entity_3->name->value), $data[2]['label'], 'Autocomplete returned the third matching entity'); + + // Try to autocomplete an entity label with the '0' character. + $input = '0'; + $data = $this->getAutocompleteResult($input); + $this->assertSame(Html::escape($entity_1->name->value), $data[0]['label'], 'Autocomplete returned the first matching entity'); + $this->assertSame(Html::escape($entity_2->name->value), $data[1]['label'], 'Autocomplete returned the second matching entity'); } /**