Original issue:

I'm trying to redirect urls in the form of:

/home/?m=destinations&destid=6&resortid=152&hotelid=357

Where there is a hierarchy like:

destination > resort > hotel

When going to the above url, it redirects to the destination node where there is a separate rule like:

/home/?m=destinations&destid=6 -> node/x

So it appears there is a problem with multiple query parameters.

Adam

To explain hopefully a little more clearly...

Let's say I have two urls in an old system
http://myoldsite.com/view.php?list=fruit
That shows all fruit. AND
http://myoldsite.com/view.php?list=fruit&item=apple
That shows a specific fruit (here, an apple).

In the new Drupal site, I want my redirects to do this:
http://myoldsite.com/view.php?list=fruit goes to http://mynewsite.com/taxonomy/term/fruit
http://myoldsite.com/view.php?list=fruit&item=apple goes to http://mynewsite.com/node/apple

Currently, if you create your redirect to http://mynewsite.com/node/apple FIRST, then create the redirect to http://mynewsite.com/taxonomy/term/fruit, all attempts to hit /node/apple will take you to /taxonomy/term/fruit.

Comments

adam clarey’s picture

Nearly found the issue, its because in this function 'redirect_load_by_source' it creates an array of potential redirect urls based on the arguments and query params. In my case above, the urls destination, resort and hotel will all be potential redirect links because of the rules that state if a child page cannot be found, go to the nearest parent page.

So with this array of potential urls it then does a sort in function '_redirect_uasort', here it orders based on language and rid where rid relates to the row position of the csv import and therefore assumes that when importing that rows will be in the order

destination -> node/x
resort -> node/y
hotel -> node/z

but if the order is reversed or random then it will select which ever row comes last as the final url to redirect to.

Which in my case is the incorrect url.

What i think is needed is ordering based on specificity, the url with the most matching query parameters would be selected to redirect to.

Don't you agree?

adam clarey’s picture

Found and fixed the problem

in redirect.module at line 1419

replace:

elseif (!empty($a->source_options['query']) != !empty($b->source_options['query'])) {
// Then sort by redirects that do not have query strings over ones that do.
return empty($a->source_options['query']);
}
with:

elseif(count($a->source_options['query']) != count($b->source_options['query'])){
return count($a->source_options['query']) < count($b->source_options['query']);
}

Now everything works fine no matter what order the redirects were created.

adam clarey’s picture

Status: Active » Needs review
StatusFileSize
new740 bytes

Patch attached

mariacha1’s picture

Issue summary: View changes
mariacha1’s picture

Status: Needs review » Reviewed & tested by the community

This works great for me, and the code looks fine.

pere orga’s picture

Status: Reviewed & tested by the community » Needs work

I've seen this behaviour in the past, it would be great to have a solution for this committed.

However the code style of the patch does not follow Drupal standards. And ideally we should not delete that comment but replace it for another one.

pere orga’s picture

This is very related (if not duplicate) of #1447460: Problem with url-escaped characters

mfernea’s picture

Status: Needs work » Needs review
StatusFileSize
new834 bytes

Here is the modified patch. It's just about coding standards and comments.

mfernea’s picture

We might have problems when some of the redirect don't have query parameters. We get notices.
Here's a better version of the patch.

dave reid’s picture

dave reid’s picture

Issue tags: +Needs tests
mfernea’s picture

Here are the test only patch and the complete patch.

tomsegarra’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs tests

I manually tested the patch from #12, and reviewed the (appropriate) unit test it contains, and all seems to be working properly.

alex_optim’s picture

+1

pifagor’s picture

  • pifagor committed 0639867 on 7.x-1.x authored by mfernea
    Issue #1817764 by mfernea, Adam Clarey, mariacha1, Pere Orga, Dave Reid...

  • pifagor committed a18ce92 on 7.x-2.x
    Issue #1817764 by mfernea, Adam Clarey, mariacha1, Pere Orga, Dave Reid...
pifagor’s picture

Status: Reviewed & tested by the community » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

Natallia’s picture

Here is the update of the latest patch from #12
Changes:
As this fragment
return $a_weight > $b_weight;
isn't equivalent to
return ($a_weight > $b_weight) ? -1 : 1;
for callback in uasort function, the correct variant has been added:
return ($a_weight > $b_weight) ? 1 : -1;