I have some logic that generates calls to drupal_goto() for the purpose of going to a Views page showing taxonomy categorized nodes.

The urls I'm generating look like: "hdr_terms/42+45+47" or "hdr_terms/42,45" where the use of the plus or comma signifies inclusion or exclusion in the term ids for what is to be displayed by the View.

However, I am seeing the pluses and comma characters get encoded - but I'd like them to remain unencoded so the url is not so ugly. Is there anyway to stop the encoding?

Also, why is it encoding those characters? I can see pluses, maybe, but why commas?

Comments

Ludo.R’s picture

Im experiencing the exact same problem, working with views and taxonomy.

Has anyone a workaround here?

bsenftner, did you find a solution to this issue?

bsenftner’s picture

no solution yet. I've love one, so please post here if you find a solution.

Ludo.R’s picture

Ok, thank you.

I'll post here if i find one.

bsenftner’s picture

I don't have the time right now, but it may be worthwhile for you to make a copy of the routine (source is here: http://api.drupal.org/api/function/drupal_goto/6 ) and add debugging and or whatnot to figure out where it's happening and then remove that encoding. I took a look at the code, and it will require (for me at least) more time than I have today to figure it out.

If you do this, I'd appreciate seeing your result.

Keep in mind that any modified drupal_goto() you create should only be used in your code locations where the logic you removed or modified from the original drupal_goto() is not needed.

Ludo.R’s picture

The problem is not (directly) drupal_goto().

drupal_goto() calls url(), which itself calls drupal_urlencode() : http://api.drupal.org/api/function/drupal_urlencode/6

drupal_urlencode() calls the php function rawurlencode(), which returns "%2C" in place of "," (which is normal i think).
But inside the drupal_urlencode() there is a str_replace() where the "%2C" could be replaced by ",".

Do you think this should be reported as an issue?

Ludo.R’s picture

So the drupal_urlencode() would end up like this :

function drupal_urlencode($text) {
  if (variable_get('clean_url', '0')) {
    return str_replace(array('%2F', '%26', '%23', '//', '%2C', '%2B'),
                       array('/', '%2526', '%2523', '/%252F', ',', '+'),
                       rawurlencode($text));
  }
  else {
    return str_replace('%2F', '/', rawurlencode($text));
  }
}

I also added the '+' (is it '%2B' ?)

bsenftner’s picture

Test it, use for a bit and report back. I'm buried with a client's project and can't check...

Ludo.R’s picture

I've tested this update, and all seems ok (commas and pluses).

I've posted a patch here : http://drupal.org/node/113035#comment-3497466

bsenftner’s picture

This is great. I really appreciate your taking this and finding a solution. Thank you very much!

Ludo.R’s picture

You're welcome.

Unfortunately, as you may have seen where i have commited this patch, this feature request wont be integrated in D6 nor D7, but maybe in D8.

(I dont know if this issue is still there in D7).

indigoblue’s picture

I'm working with this same issue and this patch does not appear to be in D7 beta2, so I guess that it is unlikely to make it into D7. The code appears to be quite different... anyone any ideas on how to work this patch into D7?

Using an autopath pattern, the '+' does appear in the url ( when running cursor over link or viewing the link) - but when the url is clicked - at some point the '+' is encoded and appears as '%2B' in the url as displayed as the address bar of the browser. My understanding is that '+' is a "reserved" character, however... it is legal within an url path and therefore should not be encoded in that position.

OK, Ive done some research and delved into the D7 code to see how this can be done and I have come up with a hack that works.

Step 1: modify drupal_http_build_query in common.inc. This removes the encoding for the + character in the url.

<?php
function drupal_http_build_query(array $query, $parent = '') {
  $params = array();

  foreach ($query as $key => $value) {
    $key = ($parent ? $parent . '[' . rawurlencode($key) . ']' : rawurlencode($key));

    // Recurse into children.
    if (is_array($value)) {
      $params[] = drupal_http_build_query($value, $key);
    }
    // If a query parameter value is NULL, only append its key.
    elseif (!isset($value)) {
      $params[] = $key;
    }
    else {
      // For better readability of paths in query strings, we decode slashes.
      //$params[] = $key . '=' . str_replace('%2F','/', rawurlencode($value)); // ORIGINAL
      $params[] = $key . '=' . str_replace(array('%2F','%2B'),array('/','+'), rawurlencode($value)); // MODIFIED
	  
    }
  }
  	
  return implode('&', $params);
}
?>

This however exposes one of the difficulties! This fix will probably work without further work if clean urls are enabled ( I can't test because I'm developing on a windows machine ). But without clean urls the path becomes part of the query string. The plus character is a 'reserved' character in query strings representing a space. PHP automatically converts the + to a space and drupal is therefore unable to route the page. My understanding is that a space is not a valid character within a path. The next part of the solution relies on this.

Step 2: Modify drupal_lookup_path in path.inc

<?php
function drupal_lookup_path($action, $path = '', $path_language = NULL) {
  $path=str_replace(' ','+', $path); //ADD THIS
  ...
?>

I simply replace any spaces with + in the path.

This is a very specific fix but I hope this helps someone to a final more general patch!

As of D7-RC2 with clean urls the following is also required for the above solution (common.inc line 610 )

function drupal_encode_path($path) {
  return str_replace(array('%2F','%2B'),array('/','+'), rawurlencode($path));
}
Anonymous’s picture

In my project I needed commas in url. The only modification I made was:

<?php
function drupal_encode_path($path) {
  return str_replace(array('%2F','%2C'),array('/',','), rawurlencode($path));
}
?>

And it works :)

arsal_u1’s picture

Sometimes we may focus PHP coding instead of brain **** so you may use following code in your custom module
if (your_condition)
{
header("Location: /url/to/the/other/page");
exit;
}

Marc DeLay’s picture

Please do not use header location in your module code.
This makes it impossible for other modules, or core, to react to the normal flow of code.
Please read more about using drupal_goto at https://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_...

darrenwh’s picture

I've been having issues with search facets, the url I had was with this parameter:

sort_bef_combine=created+DESC

My resolution was to just replace the plus sign with a space:

sort_bef_combine=created DESC and then the search worked correctly, hope this is of help to some.