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 = '') {
 | 
					function entity_reference_autocomplete_callback($type, $field_name, $entity_type, $bundle_name, $entity_id = '') {
 | 
				
			||||||
  $field = field_info_field($field_name);
 | 
					  $field = field_info_field($field_name);
 | 
				
			||||||
  $instance = field_info_instance($entity_type, $field_name, $bundle_name);
 | 
					  $instance = field_info_instance($entity_type, $field_name, $bundle_name);
 | 
				
			||||||
 | 
					  $prefix = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Get the typed string, if exists from the URL.
 | 
					  // Get the typed string, if exists from the URL.
 | 
				
			||||||
  $tags_typed = drupal_container()->get('request')->query->get('q');
 | 
					  $tags_typed = drupal_container()->get('request')->query->get('q');
 | 
				
			||||||
  $tags_typed = drupal_explode_tags($tags_typed);
 | 
					  $tags_typed = drupal_explode_tags($tags_typed);
 | 
				
			||||||
  $string = drupal_strtolower(array_pop($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.
 | 
					 * 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
 | 
					 * 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
 | 
					 * @param array $field
 | 
				
			||||||
 *   The field array definition.
 | 
					 *   The field array definition.
 | 
				
			||||||
 * @param array $instance
 | 
					 * @param array $instance
 | 
				
			||||||
| 
						 | 
					@ -495,14 +500,16 @@ function entity_reference_autocomplete_callback($type, $field_name, $entity_type
 | 
				
			||||||
 * @param string $entity_id
 | 
					 * @param string $entity_id
 | 
				
			||||||
 *   (optional) The entity ID the entity reference field is attached to.
 | 
					 *   (optional) The entity ID the entity reference field is attached to.
 | 
				
			||||||
 *   Defaults to ''.
 | 
					 *   Defaults to ''.
 | 
				
			||||||
 | 
					 * @param string $prefix
 | 
				
			||||||
 | 
					 *   (optional) A prefix for all the keys returned by this function.
 | 
				
			||||||
 * @param string $string
 | 
					 * @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
 | 
					 * @return \Symfony\Component\HttpFoundation\JsonResponse
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @see entity_reference_autocomplete_callback()
 | 
					 * @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'];
 | 
					  $target_type = $field['settings']['target_type'];
 | 
				
			||||||
  $matches = array();
 | 
					  $matches = array();
 | 
				
			||||||
  $entity = NULL;
 | 
					  $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);
 | 
					  $handler = entity_reference_get_selection_handler($field, $instance, $entity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ($type == 'tags') {
 | 
					  if (isset($string)) {
 | 
				
			||||||
    // 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)) {
 | 
					 | 
				
			||||||
    // Get an array of matching entities.
 | 
					    // Get an array of matching entities.
 | 
				
			||||||
    $match_operator = !empty($instance['widget']['settings']['match_operator']) ? $instance['widget']['settings']['match_operator'] : 'CONTAINS';
 | 
					    $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 ($entity_labels as $values) {
 | 
				
			||||||
      foreach ($values as $entity_id => $label) {
 | 
					      foreach ($values as $entity_id => $label) {
 | 
				
			||||||
        $key = "$label ($entity_id)";
 | 
					        $key = "$label ($entity_id)";
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,7 @@ use Drupal\entity_reference\Plugin\field\widget\AutocompleteWidgetBase;
 | 
				
			||||||
 *     "autocomplete_path" = "entity_reference/autocomplete/tags",
 | 
					 *     "autocomplete_path" = "entity_reference/autocomplete/tags",
 | 
				
			||||||
 *     "placeholder" = ""
 | 
					 *     "placeholder" = ""
 | 
				
			||||||
 *   },
 | 
					 *   },
 | 
				
			||||||
 *   multiple_values = FIELD_BEHAVIOR_CUSTOM
 | 
					 *   multiple_values = TRUE
 | 
				
			||||||
 * )
 | 
					 * )
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class AutocompleteTagsWidget extends AutocompleteWidgetBase {
 | 
					class AutocompleteTagsWidget extends AutocompleteWidgetBase {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,26 +83,32 @@ class EntityReferenceAutocompleteTest extends TaxonomyTestBase {
 | 
				
			||||||
    taxonomy_term_save($third_term);
 | 
					    taxonomy_term_save($third_term);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Set the path prefix to point to entity reference's autocomplete path.
 | 
					    // 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.
 | 
					    // Try to autocomplete a term name that matches both terms.
 | 
				
			||||||
    // We should get both terms in a JSON encoded string.
 | 
					    // We should get both terms in a JSON encoded string.
 | 
				
			||||||
    $input = '10/';
 | 
					    $input = '10/';
 | 
				
			||||||
    $result = $this->drupalGet($path_prefix, array('query' => array('q' => $input)));
 | 
					    $data = $this->drupalGetAJAX($path_prefix_single, array('query' => array('q' => $input)));
 | 
				
			||||||
    $data = drupal_json_decode($result);
 | 
					 | 
				
			||||||
    $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[$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');
 | 
					    $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.
 | 
					    // Try to autocomplete a term name that matches the first term.
 | 
				
			||||||
    // We should only get the first term in a JSON encoded string.
 | 
					    // We should only get the first term in a JSON encoded string.
 | 
				
			||||||
    $input = '10/16';
 | 
					    $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>');
 | 
					    $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.');
 | 
					    $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.
 | 
					    // Try to autocomplete a term name with both a comma and a slash.
 | 
				
			||||||
    $input = '"term with, comma and / a';
 | 
					    $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;
 | 
					    $n = $third_term->name;
 | 
				
			||||||
    // Term names containing commas or quotes must be wrapped in quotes.
 | 
					    // Term names containing commas or quotes must be wrapped in quotes.
 | 
				
			||||||
    if (strpos($third_term->name, ',') !== FALSE || strpos($third_term->name, '"') !== FALSE) {
 | 
					    if (strpos($third_term->name, ',') !== FALSE || strpos($third_term->name, '"') !== FALSE) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue