diff --git a/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php b/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php index 51adf91b7bb32522ef24cbba21cff2ad3e38fb86..9c3e705bd3744755faab7b2cefa540c9994cb2d6 100644 --- a/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php +++ b/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php @@ -348,13 +348,10 @@ public static function getEntityLabels(array $entities) { public static function extractEntityIdFromAutocompleteInput($input) { $match = NULL; - // Take "label (entity id)', match the ID from parenthesis when it's a - // number. - if (preg_match("/.+\s\((\d+)\)/", $input, $matches)) { - $match = $matches[1]; - } - // Match the ID when it's a string (e.g. for config entity types). - elseif (preg_match("/.+\s\(([\w.]+)\)/", $input, $matches)) { + // Take "label (entity id)', match the ID from inside the parentheses. + // @todo Add support for entities containing parentheses in their ID. + // @see https://www.drupal.org/node/2520416 + if (preg_match("/.+\s\(([^\)]+)\)/", $input, $matches)) { $match = $matches[1]; } diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestStringId.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestStringId.php index a63abada07daccddea9c3c935d4b086ef80ee87f..342cbb9b1662e340fa16a61e1f86470a2935f50c 100644 --- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestStringId.php +++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestStringId.php @@ -25,7 +25,8 @@ * entity_keys = { * "id" = "id", * "uuid" = "uuid", - * "bundle" = "type" + * "bundle" = "type", + * "label" = "name", * }, * links = { * "canonical" = "/entity_test_string_id/manage/{entity_test_string_id}", diff --git a/core/tests/Drupal/KernelTests/Core/Entity/Element/EntityAutocompleteElementFormTest.php b/core/tests/Drupal/KernelTests/Core/Entity/Element/EntityAutocompleteElementFormTest.php index ec81f7b38f8ec4f8a786145475539c7ca2c99fe4..c2d737bfb8d840e9577fc8ce1db6732dd4c3b7d2 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/Element/EntityAutocompleteElementFormTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/Element/EntityAutocompleteElementFormTest.php @@ -8,6 +8,7 @@ use Drupal\Core\Form\FormState; use Drupal\Core\Form\FormStateInterface; use Drupal\entity_test\Entity\EntityTest; +use Drupal\entity_test\Entity\EntityTestStringId; use Drupal\KernelTests\Core\Entity\EntityKernelTestBase; use Drupal\user\Entity\User; @@ -46,6 +47,7 @@ protected function setUp() { parent::setUp(); $this->installSchema('system', ['key_value_expire']); + $this->installEntitySchema('entity_test_string_id'); \Drupal::service('router.builder')->rebuild(); $this->testUser = User::create(array( @@ -68,6 +70,17 @@ protected function setUp() { $entity->save(); $this->referencedEntities[] = $entity; } + + // Use special characters in the ID of some of the test entities so we can + // test if these are handled correctly. + for ($i = 0; $i < 2; $i++) { + $entity = EntityTestStringId::create([ + 'name' => $this->randomMachineName(), + 'id' => $this->randomMachineName() . '&</\\:?', + ]); + $entity->save(); + $this->referencedEntities[] = $entity; + } } /** @@ -150,6 +163,16 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#default_value' => array($this->referencedEntities[0], $this->referencedEntities[1]), ); + $form['single_string_id'] = array( + '#type' => 'entity_autocomplete', + '#target_type' => 'entity_test_string_id', + ); + $form['tags_string_id'] = array( + '#type' => 'entity_autocomplete', + '#target_type' => 'entity_test_string_id', + '#tags' => TRUE, + ); + return $form; } @@ -181,6 +204,8 @@ public function testValidEntityAutocompleteElement() { $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]), ]); $form_builder = $this->container->get('form_builder'); $form_builder->submitForm($this, $form_state); @@ -231,6 +256,16 @@ public function testValidEntityAutocompleteElement() { $this->assertEqual($value[1]['entity']->getOwnerId(), $this->testAutocreateUser->id()); // Third value is an existing entity. $this->assertEqual($value[2]['target_id'], $this->referencedEntities[1]->id()); + + // Test the 'single_string_id' element. + $this->assertEquals($this->referencedEntities[2]->id(), $form_state->getValue('single_string_id')); + + // Test the 'tags_string_id' element. + $expected = [ + ['target_id' => $this->referencedEntities[2]->id()], + ['target_id' => $this->referencedEntities[3]->id()], + ]; + $this->assertEquals($expected, $form_state->getValue('tags_string_id')); } /**