Issue #1914180 by amateescu: Unbreak and cleanup the autocomplete widgets.

8.0.x
catch 2013-02-12 12:39:08 +00:00
parent f66ac34331
commit 4d4facb2db
3 changed files with 28 additions and 30 deletions

View File

@ -469,23 +469,28 @@ function entity_reference_autocomplete_access_callback($type, $field_name, $enti
function entity_reference_autocomplete_callback($type, $field_name, $entity_type, $bundle_name, $entity_id = '') {
$field = field_info_field($field_name);
$instance = field_info_instance($entity_type, $field_name, $bundle_name);
$prefix = '';
// Get the typed string, if exists from the URL.
$tags_typed = drupal_container()->get('request')->query->get('q');
$tags_typed = drupal_explode_tags($tags_typed);
$string = drupal_strtolower(array_pop($tags_typed));
return entity_reference_autocomplete_callback_get_matches($type, $field, $instance, $entity_type, $entity_id, $string);
// The user entered a comma-separated list of entity labels, so we generate a
// prefix.
if ($type == 'tags' && !empty($string)) {
$prefix = count($tags_typed) ? drupal_implode_tags($tags_typed) . ', ' : '';
}
return entity_reference_autocomplete_callback_get_matches($field, $instance, $entity_type, $entity_id, $prefix, $string);
}
/**
* Returns JSON data based on a given field, instance and search string.
*
* This function can be used by other modules that wish to pass a mocked
* definition of the field on instance.
* definition of the field or instance.
*
* @param string $type
* The widget type (i.e. 'single' or 'tags').
* @param array $field
* The field array definition.
* @param array $instance
@ -495,14 +500,16 @@ function entity_reference_autocomplete_callback($type, $field_name, $entity_type
* @param string $entity_id
* (optional) The entity ID the entity reference field is attached to.
* Defaults to ''.
* @param string $prefix
* (optional) A prefix for all the keys returned by this function.
* @param string $string
* The label of the entity to query by.
* (optional) The label of the entity to query by.
*
* @return \Symfony\Component\HttpFoundation\JsonResponse
*
* @see entity_reference_autocomplete_callback()
*/
function entity_reference_autocomplete_callback_get_matches($type, $field, $instance, $entity_type, $entity_id = '', $string = '') {
function entity_reference_autocomplete_callback_get_matches($field, $instance, $entity_type, $entity_id = '', $prefix = '', $string = '') {
$target_type = $field['settings']['target_type'];
$matches = array();
$entity = NULL;
@ -517,27 +524,12 @@ function entity_reference_autocomplete_callback_get_matches($type, $field, $inst
}
$handler = entity_reference_get_selection_handler($field, $instance, $entity);
if ($type == 'tags') {
// The user enters a comma-separated list of tags. We only autocomplete the
// last tag.
$tags_typed = drupal_explode_tags($string);
$tag_last = drupal_strtolower(array_pop($tags_typed));
if (!empty($tag_last)) {
$prefix = count($tags_typed) ? implode(', ', $tags_typed) . ', ' : '';
}
}
else {
// The user enters a single tag.
$prefix = '';
$tag_last = $string;
}
if (isset($tag_last)) {
if (isset($string)) {
// Get an array of matching entities.
$match_operator = !empty($instance['widget']['settings']['match_operator']) ? $instance['widget']['settings']['match_operator'] : 'CONTAINS';
$entity_labels = $handler->getReferencableEntities($tag_last, $match_operator, 10);
$entity_labels = $handler->getReferencableEntities($string, $match_operator, 10);
// Loop through the products and convert them into autocomplete output.
// Loop through the entities and convert them into autocomplete output.
foreach ($entity_labels as $values) {
foreach ($values as $entity_id => $label) {
$key = "$label ($entity_id)";

View File

@ -28,7 +28,7 @@ use Drupal\entity_reference\Plugin\field\widget\AutocompleteWidgetBase;
* "autocomplete_path" = "entity_reference/autocomplete/tags",
* "placeholder" = ""
* },
* multiple_values = FIELD_BEHAVIOR_CUSTOM
* multiple_values = TRUE
* )
*/
class AutocompleteTagsWidget extends AutocompleteWidgetBase {

View File

@ -83,26 +83,32 @@ class EntityReferenceAutocompleteTest extends TaxonomyTestBase {
taxonomy_term_save($third_term);
// Set the path prefix to point to entity reference's autocomplete path.
$path_prefix = 'entity_reference/autocomplete/single/' . $this->field_name . '/node/article/NULL';
$path_prefix_single = 'entity_reference/autocomplete/single/' . $this->field_name . '/node/article/NULL';
$path_prefix_tags = 'entity_reference/autocomplete/tags/' . $this->field_name . '/node/article/NULL';
// Try to autocomplete a term name that matches both terms.
// We should get both terms in a JSON encoded string.
$input = '10/';
$result = $this->drupalGet($path_prefix, array('query' => array('q' => $input)));
$data = drupal_json_decode($result);
$data = $this->drupalGetAJAX($path_prefix_single, array('query' => array('q' => $input)));
$this->assertEqual(strip_tags($data[$first_term->name. ' (1)']), check_plain($first_term->name), 'Autocomplete returned the first matching term');
$this->assertEqual(strip_tags($data[$second_term->name. ' (2)']), check_plain($second_term->name), 'Autocomplete returned the second matching term');
// Try to autocomplete a term name that matches the first term.
// We should only get the first term in a JSON encoded string.
$input = '10/16';
$this->drupalGet($path_prefix, array('query' => array('q' => $input)));
$this->drupalGet($path_prefix_single, array('query' => array('q' => $input)));
$target = array($first_term->name . ' (1)' => '<div class="reference-autocomplete">' . check_plain($first_term->name) . '</div>');
$this->assertRaw(drupal_json_encode($target), 'Autocomplete returns only the expected matching term.');
// Try to autocomplete a term name that matches the second term, and the
// first term is already typed in the autocomplete (tags) widget.
$input = $first_term->name . ' (1), 10/17';
$data = $this->drupalGetAJAX($path_prefix_tags, array('query' => array('q' => $input)));
$this->assertEqual(strip_tags($data[$first_term->name . ' (1), ' . $second_term->name . ' (2)']), check_plain($second_term->name), 'Autocomplete returned the second matching term');
// Try to autocomplete a term name with both a comma and a slash.
$input = '"term with, comma and / a';
$this->drupalGet($path_prefix, array('query' => array('q' => $input)));
$this->drupalGet($path_prefix_single, array('query' => array('q' => $input)));
$n = $third_term->name;
// Term names containing commas or quotes must be wrapped in quotes.
if (strpos($third_term->name, ',') !== FALSE || strpos($third_term->name, '"') !== FALSE) {