Hi,

I came across a problem with the use of , escaped with quotes in the ajax autocomplete functionality.

An example would be the use of author names in the taxonomy in the form of Lastname, Firstname. Which means we have to escape the comma with quotes "Lastname, Firstname"
If we just bind one name to a node with the help of the autocomplete function everything works fine (the tag field has the string value "Lastname1, Firstname1") and the comma escaping quotes are generated correctly.

However, after we a second name. The tag form field gets updated in the following form Lastname1, Firstname1, "Lastname2, Firstname2". Thus the escaping quotes for the first name disappeared. Adding a third name would remove the second author names escaping quotes (Lastname1, Firstname1, Lastname2, Firstname2, "Lastname3, Firstname3") and so on.

I belive that it is due to the fact that drupal_explode_tags in taxonomy_autocomplete returns the tags without the enclosing quotes, and that the important escaping is getting lost this way.

function taxonomy_autocomplete($vid, $string = '') {
  // The user enters a comma-separated list of tags. We only autocomplete the last tag.
  $array = drupal_explode_tags($string);

  // Fetch last tag
  $last_string = trim(array_pop($array));
  $matches = array();
  if ($last_string != '') {
    $result = db_query_range(db_rewrite_sql("SELECT t.tid, t.name FROM {term_data} t WHERE t.vid = %d AND LOWER(t.name) LIKE LOWER('%%%s%%')", 't', 'tid'), $vid, $last_string, 0, 10);

    $prefix = count($array) ? implode(', ', $array) .', ' : '';

    while ($tag = db_fetch_object($result)) {
      $n = $tag->name;
      // Commas and quotes in terms are special cases, so encode 'em.
      if (strpos($tag->name, ',') !== FALSE || strpos($tag->name, '"') !== FALSE) {
        $n = '"'. str_replace('"', '""', $tag->name) .'"';
      }
      $matches[$prefix . $n] = check_plain($tag->name);
    }
  }
  drupal_json($matches);
}

thanks!

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Heine’s picture

Project: Taxonomy Defaults » Drupal core
Version: 6.x-1.x-dev » 6.x-dev
Component: Code » taxonomy.module
soghad’s picture

Version: 6.x-dev » 7.x-dev
Status: Active » Needs review
FileSize
2.55 KB

I'm submitting a patch that makes the following improvements to the taxonomy_autocomplete function:

- Closes opening quotes before drupal_explode_tags so that the last entry is not chopped off in the event the user types an opening quote
- Omits duplicate tags in match results.
- Uses drupal_implode_tags to create replacement strings so they are properly quoted.

Status: Needs review » Needs work

The last submitted patch failed testing.

soghad’s picture

Status: Needs work » Needs review
FileSize
2.56 KB

Resubmitting failed patch for #321080-1257977

Status: Needs review » Needs work

The last submitted patch failed testing.

soghad’s picture

Status: Needs work » Needs review
FileSize
2.11 KB

Resubmitting failed patch for #321080-1257977

Status: Needs review » Needs work

The last submitted patch failed testing.

soghad’s picture

Status: Needs work » Needs review
FileSize
2.3 KB

One more try using different CVS diff method.

Status: Needs review » Needs work

The last submitted patch failed testing.

soghad’s picture

FileSize
2.35 KB

Resubmitting same patch as above as diff exported relative to project root

soghad’s picture

Status: Needs work » Needs review
FileSize
2.35 KB

This is a patch that provides the following fixes and enhancements to taxonomy_autocomplete:

  • Necessary quotes are now maintained across multiple tags.
  • Suggestions that would result in duplicate tags are suppressed
  • Open quotes in the string passed to taxonomy_autocomplete are close before the string gets passed to drupal_explode_tags

For the following examples, assume that we have a vocabulary named "Celebrity Tags" that contains the following terms:

  • Adele
  • David "The Hoff" Hasselhoff
  • Sammy Davis, Jr.

Issue with quotes being discarded with multiple tags

Current Behavior

Currently, if one enters Sammy in a taxonomy tag field, taxonomy_autocomplete will suggest Sammy Davis, Jr. and set the taxonomy field value to "Sammy Davis Jr.", which is correct.

<?php
// Note: $string = 'Sammy';

// Result is...
array('"Sammy Davis, Jr."' => 'Sammy Davis, Jr.');
?>

However, if the user then successfully appends Adele to the tag list, the result is Sammy Davis, Jr., Adele. Notice that the quotes around Sammy Davis, Jr. have been dropped.

<?php
// Note: $string = '"Sammy Davis, Jr.", Ad';

// Result is...
array('Sammy Davis, Jr., Adele' => 'Adele');
?>

Behavior After Patch

This patch changes this behavior by using drupal_implode_tags to ensure that every tag is properly quoted.

<?php
while ($tag = db_fetch_object($result)) {
    ...
    $replacement = drupal_implode_tags(array_merge($array, array($tag->name)));
    $matches[$replacement] = check_plain($tag->name);
    ...
}
?>

This ensures that, if the string "Sammy Davis, Jr.", Ad is passed to taxonomy_autocomplete, the result will be:

<?php
// Note: $string = '"Sammy Davis, Jr.", Ad';

// Result is...
array('"Sammy Davis, Jr.", Adele' => 'Adele');
?>

Filtering Out Duplicate Tags

Current Behavior

Currently, if a node is tagged with Sammy Davis, Jr. and the user appends Dav to the tag list, suggestions for Sammy Davis, Jr. and David "The Hoff" Hasselhoff will be returned.

<?php
// Note: $string = '"Sammy Davis, Jr.", Dav';

// Result is...
array (
  '"Sammy Davis, Jr.", "Sammy Davis, Jr."' => 'Sammy Davis, Jr.',
  ,'"Sammy Davis, Jr.", "David ""The Hoff"" Hasselhoff"' => 'David "The Hoff" Hasselhoff'
);
?>

Behavior After Patch

This patch filters out Sammy Davis, Jr., so that only David "The Hoff" Hasselhoff" will be suggested if the node has already been tagged Sammy Davis, Jr.

<?php
while ($tag = db_fetch_object($result)) {
  // Skip tags that would create a duplicate
  if (array_search($tag->name, $array) === FALSE) {
    ...
  }
}
?>

This results in:

<?php
// Note: $string = '"Sammy Davis, Jr.", Dav';

// Result is...
array ("Sammy Davis, Jr.", '"David ""The Hoff"" Hasselhoff"' => 'David "The Hoff" Hasselhoff');
?>

Patched Source Code

Closing open quotes

Current Behavior

Currently, if the value Adele, "Samm is passed to taxonomy_autocomplete, the result will be every term matching Adele because the last tag "Samm is discarded.

<?php
// Note: $string = 'Adele, "Samm';

// Result is...
array('Adele, Adele' => 'Adele');
?>

Behavior After Patch

This patch checks to see if $string contains an odd number of double quotes and if this is the case, an extra double quote is added to the end of $string before it is passed to drupal_explode_tags. So, in this case the value Adele, "Samm would be changed to Adele, "Samm" before being sent to drupal_explode_tags.

<?php
function taxonomy_autocomplete($vid, $string='') {
  // Add closing double quote if there are an odd number of double quotes in $string.
  if (preg_match_all('/(\")/', $string, $quotes)) {
    if ((count($quotes[1]) % 2) != 0) {
      $string .= '"';
    }
  }
  ...
}
?>

This results in:

<?php
// Note: $string = 'Adele, "Samm';

// Result is...
array('Adele, "Sammy Davis, Jr"' => 'Sammy Davis, Jr.');
?>

Status: Needs review » Needs work

The last submitted patch failed testing.

mr.baileys’s picture

worldlinemine’s picture

After attempting to patch the diff into taxonomy.pages.inc, I failed. I then took a closer look at the code and it appears to me that the patch may be for some substantially older code unless the patch intentionally changes the variables. [My coding skills are limited].

Note this compares the start of the Helper function in both HEAD and the diff:

[from Sunday April, 4th 7.x-dev snapshot]
function taxonomy_autocomplete($field_name, $tags_typed = '') {

[from 321080.diff for the taxonomy.pages.inc file]
function taxonomy_autocomplete($vid, $string = '') {

I suspect that the patch may have to be updated to the newer HEAD code. Please excuse me if my analysis is incorrect. I'd be happy to try and apply the patch again once it is ready (assuming I am correct and it needs to be updated).

Thanks.

worldlinemine’s picture

Status: Needs work » Closed (duplicate)