I'm trying to add a URL to a link field with a query string of
page?content_type=foo&content_type=bar
but when the link renders I just get page?content_type=bar
I lose my foo, I've tried all the settings on the link field and I also tried the dev version, but can't seem to get this working, am I missing something or is this a bug?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dave.erwin’s picture

Issue summary: View changes
DamienMcKenna’s picture

Version: 7.x-1.3 » 7.x-1.x-dev

This also affects using ISField to output a youtube video, the "v=j54d-9_gsCQ" part in "http://youtube.com/watch?v=j54d-9_gsCQ" gets removed.

DamienMcKenna’s picture

FYI I ended up replacing the Link-based field with one using the URL module.

DamienMcKenna’s picture

I suspect that the query string should go in a 'query' element in the record's 'attributes' field, but it currently isn't happening.

dave.erwin’s picture

thanks Damien, I'm going to try the URL module now.

cbrasfield’s picture

For what it's worth, the 'display_url' key of the array shows the entire url, as does the title.

saurabh.dhariwal’s picture

Hello,

Here's the solution:

I've tried using [ ] array format of controller (i.e. content_type) to the input name, later the url appears like: ?content_type[]=foo&content_type[]=bar

This will allow you to add multiple variables with same parameter name.

When the form is submitted, the destination URL looks different in different browsers.

Hope this helps!

Anonymous’s picture

Status: Active » Needs review
FileSize
1.22 KB

The problem stems from the function _link_parse_str($query), called by _link_parse_url($url).

function _link_parse_str($query) {
  $query_array = array();

  $pairs = explode('&', $query);
  foreach ($pairs as $pair) {
    $name_value = explode('=', $pair, 2);
    $name = urldecode($name_value[0]);
    $value = isset($name_value[1]) ? urldecode($name_value[1]) : NULL;
    $query_array[$name] = $value;
  
  return $query_array;
}

It's splitting the query string up into components & storing it in an array for use by _link_parse_url, which creates URL parts (path, query string, fragment) for use in _link_sanitize(), which runs those parts through the Drupal function url() to create & display the URL.

The problem arises from the fact that _link_parse_str is creating an array whose keys are the query parameter names. In the case here, the query parameter names are identical, so the array keys are identical. In that case PHP only keeps the last array key, hence the cut off query string when it's all done.

Since Drupal's url() (https://api.drupal.org/api/drupal/includes!common.inc/function/url/7) can accept a query string as part of the 'path' parameter, why not just run the whole input URL into the 'path' parameter rather than splitting off the query string, making it an array, & passing it in as the 'query' parameter? What are the advantages of using _link_parse_str($query) & _link_parse_url($url) to get the query part as an array & passing it into url() as such rather than just plugging the whole URL into the 'path' parameter of url()?

I'm attaching a patch which solves this problem by taking the approach outlined above. Not sure if it has some liability since I'm not clear on why it's being done the way it is currently--I could be missing something here.

By the way, it is possible to cause _link_parse_str to create a multidimensional array which will create a URL which preserves both identical query parameters, but then those parameters are suffixed with the integer key/index of the query string values, e.g.: page?content_type[0]=foo&content_type[1]=bar. Simply change $query_array[$name] = $value; to $query_array[$name][] = $value; (or a more complicated version of that with if/then checks a la https://php.net/manual/en/reserved.variables.get.php#92439 ).

PS: The URL module has this same problem; while it will display a URL such as page?content_type=foo&content_type=bar correctly, the HTML link it creates (href) actually is truncated exactly as discribed in this problem. It's using drupal_parse_url() to split up the URL parts & passing them into url just like this module.

DamienMcKenna’s picture

FYI if the URL module has a similar problem then it's possibly also a bug in D8 core too.

Peter Törnstrand’s picture

Reroll of patch against 7.x-1.3 ... sorry, it got a bit messy.

Sorry, that patch was completely broken.

Status: Needs review » Needs work

The last submitted patch, 10: link_query_string_being_removed-2433057-10.patch, failed testing.

The last submitted patch, 10: link_query_string_being_removed-2433057-10.patch, failed testing.

jessehs’s picture

Status: Needs work » Needs review
FileSize
1.58 KB

This is a reroll of #8 for version 1.3. I ran into this problem with a modal edit of a link field using the Boxes module. The problem did not occur using the standard box edit form (non-modal).

Status: Needs review » Needs work

The last submitted patch, 13: link_query_string_being_removed-2433057-13.patch, failed testing.

jessehs’s picture

Haha, I realized that the 1.4 release of the module fixes the problem I was having. I don't know if the original issue reported has been fixed.

dgtlmoon’s picture

Status: Needs work » Closed (duplicate)
Jason Dean’s picture

Status: Closed (duplicate) » Active

Reopening this issue, as it isn't a duplicate of https://www.drupal.org/node/1914072 and the patch in that issue doesn't fix this.

I populate my link field with this URL: buy-artwork/artworks?artist=All&subject[]=28&subject[]=47&subject[]=27&subject[]=29&sort_by=created

It is rendered as: buy-artwork/artworks?artist=All&subject[]=29&sort_by=created

So where there are multiple values for a query string ('subject' in this example), Link module only applies the last value.

chrlvclaudiu’s picture

agree with @Jason Dean . Same issue for core menu, see https://www.drupal.org/node/1220410

Anonymous’s picture

The patch I uploaded has been working for me for two years. Maybe somebody can test it or one of the re-rolls & mark it RTBC, & perhaps it can get into the module eventually?

cilefen’s picture

By the way, I checked and Drupal 8's link module is not affected by this bug.

cilefen’s picture

Title: Query string being removed » Duplicate query strings such as array parameters are removed
pwolanin’s picture

Status: Active » Needs work

The bug seems to be that _link_parse_url() is a buggy function http://cgit.drupalcode.org/link/tree/link.module#n752

The patch should instead work to replace with direct use (or wrap) the core function drupal_parse_url($url)

https://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_...

cilefen’s picture

Thank you for that suggestion, Peter.

drumm’s picture

cilefen’s picture

Yes, they seem identical. I'm going to close this one and upload my patch on the other. Thanks.

cilefen’s picture

Status: Needs review » Closed (duplicate)