Issue #1914180 by amateescu: Unbreak and cleanup the autocomplete widgets.
parent
f66ac34331
commit
4d4facb2db
|
@ -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)";
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue