example:
say: variable site_frontpage = 'welcome' //for example the name of a views.module page view

print url('welcome', null, null, true);

output:

http://example.com/welcome

but it should be

http://example.com/

where can I see this problem in real life?
- if you are using views.module and set one view as the frontpage.
and then have a look at the pager generated... it has welcome in its url, which shouldn't.
- let some node be the frontpage and the look what the view-tab url is. It is 'welcome' but should be ''

I introduced a check which compares the $path with the frontpage url

Comments

beginner’s picture

Version: 4.7.1 » x.y.z
Status: Needs review » Needs work

This issue seems very close to the following which has been committed recently:
http://drupal.org/node/70177 : is_front incorrectly set to FALSE when viewing the front page node directly.

Can you
1) confirm that your issue is slightly different, and not fixed by the above issue.
2) if the bug exists in cvs, provide a patch for head first.

I think your patch may need updating in any case because of the above commit.

Tobias Maier’s picture

the bug is not fixed with the issue mentioned.

Tobias Maier’s picture

Version: x.y.z » 4.7.3
Assigned: Unassigned » Tobias Maier
Status: Needs work » Needs review
StatusFileSize
new2.3 KB

this time I fixed the root of the evil.

it is drupal_lookup_path().
* first of all I commented every step which is important.
* it returns '' as the alias of the frontpage path
* fixed small bug which was a result of $map[$path] = FALSE;.

the patch applies to drupal 4.7 and 5

Tobias Maier’s picture

tested it at drupal 5
works great!

killes@www.drop.org’s picture

Version: 4.7.3 » x.y.z

Moving to HEAD to get more reviews.

dries’s picture

drupal_lookup_path is a super-expensive function (#1 bottleneck). The proposed changes need serious benchmarking before they can be considered.

Tobias Maier’s picture

StatusFileSize
new2.29 KB

i had an idea

have no time, yet --> untested!!!

Tobias Maier’s picture

Status: Needs review » Needs work
Tobias Maier’s picture

Status: Needs work » Needs review
StatusFileSize
new2.26 KB

here is a new version of the patch

I removed some new dead code and fixed an error of the last patch

I benchmarked the code per http://drupal.org/node/79237
but i was not able to "disable mysql query cache"

it seems that there is a performance loss of 3 percent
i compared "Time per request" in the output of the benchmark - i hope this was the right one

Arto’s picture

I think the original idea of this patch is a good one, as it increases consistency and prevents search engines from seeing duplicate content (same page at two URLs). In fact, on building Drupal sites I've often wished that it would work like this with regards to the front page.

A minor point from a quick review of the latest patch: maybe you should memoize the result of drupal_get_normal_path(variable_get('site_frontpage', 'node')) in a static variable to avoid performing that normalization each time an alias is looked up?

Tobias Maier’s picture

StatusFileSize
new2.64 KB

here comes a new patch with artos suggestion of using static.

i benchmarked this 10 times and I got every time the same result:
the new patch seems to be 6% faster then the current version of this function in head.

I did not change anything on the test system.
It would be nice if someone else coud benchmark this again
Because it might be a wonder if this would be so much faster...

RayZ’s picture

I confirm that this patch fixes the related issue http://drupal.org/node/89947

RayZ’s picture

Status: Needs review » Needs work

Unfortunately, it looks like this patch breaks block visibility for blocks that are set to show up only on the <front> page.

Tobias Maier’s picture

Status: Needs work » Needs review
StatusFileSize
new3.78 KB

the error only occours if the frontpage variable is set to any url alias (not to the real src).

I dont understand any word about regexp... so i fixed it by pressing del on my keyboard ;)

Tobias Maier’s picture

btw. I dont think that
variable_get('site_frontpage', 'node')
was used properly in block_list() (block.module)

think about this use case:
your url_alias looks like this:

###############################
#   src  #          dst       #
###############################
# node/5 # my-first-frontpage #
# node/5 # my-great-frontpage #
###############################

* site_frontpage variable has the value my-great-frontpage
* some block gets only shown on the <front>-page

what is block_list() doing if you are on the frontpage?

the snippet of interest:

          $path = drupal_get_path_alias($_GET['q']);
          $regexp = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1'. preg_quote(variable_get('site_frontpage', 'node'), '/') .'\2'), preg_quote($block->pages, '/')) .')$/';
          // Compare with the internal and path alias (if any).
          $page_match = preg_match($regexp, $path);
          if ($path != $_GET['q']) {
            $page_match = $page_match || preg_match($regexp, $_GET['q']);
          }
          // When $block->visibility has a value of 0, the block is displayed on
          // all pages except those listed in $block->pages. When set to 1, it
          // is displayed only on those pages listed in $block->pages.
          $page_match = !($block->visibility xor $page_match); 

$_GET['q'] is node/5
first of all it looks for the alias of "q" with drupal_get_path_alias() the alias is my-first-frontpage (first matching row in table)
now it replaces <front> in the allowed paths with variable_get('site_frontpage', 'node') this means with my-great-frontpage
it looks if my-first-frontpage is in the list. but it will never find this path. Now it searches again for node/5... with no result.

this means a solution for this problem without the patch above is to replace variable_get('site_frontpage', 'node') with drupal_get_path_alias(variable_get('site_frontpage', 'node'))

RayZ’s picture

I'm on 4.7, so I had to apply part of the patch in #14 by hand. But I confirm that it does fix the issue I was seeing with missing <front> page blocks.

@Tobias, your comment seems to indicate your results were different, but with the earlier patch I had missing <front> page blocks with the frontpage variable set to both 'node/312' and 'frontpage' (which was aliased to 'node/312'). In any case, the patch in #14 seems to fix both cases.

Tobias Maier’s picture

another issue which will be fixed by this: drupal_lookup_path does not cache negative results

Tobias Maier’s picture

one question to higher skilled developers:
is it allowed in SQL to use LIMIT?

eg. change
SELECT dst FROM {url_alias} WHERE src = '%s'
to
SELECT dst FROM {url_alias} WHERE src = '%s' LIMIT 1

does this give us a performance gain?

Wesley Tanaka’s picture

http://drupal.org/node/47545 was marked a duplicate of this, even though the issues are different, because that fix is included in the particular patch that's being discussed right now, it seems. subscribing as a reminder for myself to check on 47545 after this patch gets committed.

nicholasthompson’s picture

RE: The limit question...

I'd imagine it would give an advantage - i cant see it slowing it down. My concern would be what to do if a src has multiple dst's... Eg:
node/123 = mysite.html
node/123 = mysite2.html

You should never need to do that AFAIK but you might need to at some point...

Tobias Maier’s picture

nicholasThompson, what you are describing happens for example if you are using pathauto configured to add a new alias after an update of a node.
what we are doing in this case is to take the first entry we find in the database.

I could imagine that we add a new "active" or "weight" row to the url_alias-table but I think this is another issue and could mean a loss of speed...

Tobias Maier’s picture

* could someone run a benchmark, because I got weird results on my last test (see #11)
* look over the code again
* and set it asap to "ready to be commited" to see what happens and what the big guys say about that...

Arto’s picture

In the case of LIMIT 1, you probably want to order by the 'pid' column, in ascending order - this ensures you'll correctly (and consistently) get the first (oldest) path alias that was defined for that internal Drupal path.

Tobias Maier’s picture

i think order by costs speed
so this will never come

Arto’s picture

Normally, yes, but it shouldn't cost speed in the case of the 'pid' column - that's the primary key, and sorting by it in ascending order should conform to the order the rows were created in, in the first place.

Tobias Maier’s picture

Status: Needs review » Reviewed & tested by the community

well i did another benchmark - this time without mysql query cache.

the patch is on my test environment around 5% slower than without the patch.
but it works and fixes a few issues

so I set it to rtbc and look what happens....

Tobias Maier’s picture

btw. how to disable mysql query cache

at /etc/mysql/my.cnf:
change
query_cache_type = 1
to
query_cache_type = 0

don't forget to restart your mysql server
(this could be a good addition to http://drupal.org/node/79237)

webchick’s picture

LIMIT doesn't work in pgsql, afaik. It's not ANSI SQL standard, at any rate...

@ "this would be a good addition to the docs..." Please add it!! edit the page directly if you can, else post as a comment and it can get integrated at some point. no one will ever think to look at issue #65493 for benchmarking tips. ;)

Tobias Maier’s picture

I dont have access to edit the handbook

Tobias Maier’s picture

Tobias Maier’s picture

rtbc still remains for #14

but i tried to optimize it more and more.
here you can see my current stage.
I tried for hours and hours a lot of things
I can't really say if the new patch is faster
so i would be really happy if someone could test it on his machine

Thanks

what did I change?

  • replace count()-query - why do we look for count which does us not really interest? let us get any alias so this MAY save us a query later on
  • replace drupal_get_normal_path() with drupal_lookup_path('source', ...) - dont call a function you dont really need in this case. stay inside drupal_lookup_path()
  • shifted around the queries - no speed gain. to get the alias in some special case (i nver saw this one but i could think that this may happen)
  • added ORDER BY pid DESC LIMIT 1 - only to one of the two queries, because the other one has UNIQUE in the db - i added order by because pgsql-doc suggests it
  • path.module can use drupal_lookup_path('alias', $path) instead of its own query
Tobias Maier’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new6.43 KB

here comes a new patch.
this time it is 0.44 % slower than the current query (as alway please benchmark it too i want to hear about your results)
it is the best result currently

please test it
and tell me if there are any negative side effects

sime’s picture

StatusFileSize
new3.05 KB

I wasn't able to do more than a benchmark, being the first benchmark I've done it took a bit of mucking around (webchick, thanks for the HOWTO, I added a few notes to the the query_cache part).

I get a 3.1% performance loss on patch at #32. I've attached the results (side-by-side) and I'm willing to give it another go if requested.

sime’s picture

Oh, and the above benchmark data will generally look slow. This is just my dinky local test server in action.

Tobias Maier’s picture

Version: x.y.z » 5.x-dev
dkruglyak’s picture

I am a little confused. Are these patches for 4.7 or 5.x ???

Will this get commited to 4.7 branch? There is a module needing this fix: http://drupal.org/node/89600

TheWhippinpost’s picture

There's patches flying around everywhere here - Which one is best to apply?

Tobias Maier’s picture

the one at #32 is the most current one.
it was developed for 5.0 but there was a commit so this will not anymore apply cleanly.
but it should be easy for you to solve this

it should be possible to apply this to drupal 4.7, too but then with a little bit hand work
it the patch file you can read modules/path/path.module this file was in drupal 4.7 at modules/path.module
modules/block/block.module was at modules/block.module

I want to inform you that there is another issue which hacks around in drupal_lookup_path()
http://drupal.org/node/97317
but with another purpose..
this is the reason why this issue does not apply anymore

drumm’s picture

Status: Needs review » Needs work

Doesn't apply cleanly for 5?

m3avrck’s picture

Subscribing, this is one of the most annoying issues I face constantly.

Which patch are we looking at folks? Update for HEAD?

Christoph C. Cemper’s picture

subscribing

and can ANYONE please post the full module for drupal 4.7.4 ?

thanks!

RayZ’s picture

@Tobias, any chance you could re-roll the latest patch?

I assume this is still an open bug in 5.x, I know it is still affecting me in 4.7.5.

Tobias Maier’s picture

Status: Needs work » Needs review
StatusFileSize
new4.27 KB

here comes a new patch

I didnt test it much, because of lack of time.

I had to clear my cache to get this running...

Tobias Maier’s picture

StatusFileSize
new3.98 KB

something veeery old slipped in...

Tobias Maier’s picture

it runs since a few days on my test page and works as expected

Tobias Maier’s picture

StatusFileSize
new4.05 KB

and here comes a new, better one patch.

joshk’s picture

Status: Needs review » Needs work

Patch applied cleanly. However, while I may be missing the intent, the patch doesn't appear to provide desired functionality.

I set to = node/5 and url('node/5', null, null, true) = http://mysite.org/~joshk/node/5

I set to = taxonomy/term/3 and url('taxonomy/term/3', null, null, true) = http://mysite.org/~joshk/taxonomy/term/3

I set to = frontpage (from views) and url('frontpage', null, null, true = http://mysite.org/~joshk/frontpage

If I'm reading the thread correctly, all the above cases url() should be returning http://mysite.org/~joshk

Tobias Maier’s picture

Status: Needs work » Needs review
StatusFileSize
new4.16 KB

thank you for trying the patch.
I appreciate every feedback I get.

here comes a fixed patch.
I hope it works for you, too

You can see my test case below
I use it inside the devel.module's execute block

$url['taxonomy/term/16']      = TRUE;
$url['blog/tags/countries']   = TRUE;
$url['taxonomy/term/1']       = FALSE;
$url['blog']                  = FALSE;
foreach ($url as $address => $flag) {
  if ($flag) {
    print 'should be frontpage url = ';
  }
  print url($address, NULL, NULL, TRUE);
  print "<br />\n";
}

I set taxonomy/term/16 and blog/tags/countries to my frontpage path

Pushkar Gaikwad’s picture

Version: 5.x-dev » 4.7.4

I hope I am posting this in right section as this is the first time I am posting anything ourside Drupal forum.

I spent about an hour understanding everything for my 4.7.4 installation as globalredirect was not working on it. So I applied the patch of post#14 by removing the - lines and adding + lines in my include/path.inc file. Now it seems it is working but I think now it looks that on the front page, some blocks have got messed up. Sometime they get invisible(when normal user is logged in)

What should I do ? upgrading to 5.0 is not a option right now as I don't have so much time.

webchick’s picture

Version: 4.7.4 » 6.x-dev

bug needs to be fixed in HEAD first.

forngren’s picture

Up on radar

catch’s picture

Status: Needs review » Needs work

needs a re-roll.

mot’s picture

Status: Needs work » Closed (fixed)

Well by design there is a path of the ideally "Frontpage" (this is an Alias) and there is a path of anything.

If you need to get the Path of the frontpage you therefore should use '' as the first parameter or try with ''.

But I can not see any bug here. The problem maybe is that you try to use the URL function for something that it has not been coded for
. Even the parameter count does not fit with the API:

http://api.drupal.org/api/function/url/6

Since this Issue is very orphaned and does not match the API, I closed it.

Wesley Tanaka’s picture

Status: Closed (fixed) » Needs work

The function parameter signature wouldn't need to be changed. If you think of the front page "/welcome" => "/" conceptually as an alias, then url() should be normalizing that just like it normalizes "real" aliases.

mot’s picture

Well then please tell me where actually the BUG is that is reported here. That the URL() function does its job properly? The job of the URL function is not to handle any mappings that might be related by the frontpage option, it is to Generate a URL from a Drupal menu path. Will also pass-through existing URLs. And that's it.

mot’s picture

Status: Needs work » Closed (works as designed)

Tobias Maier, you take care of it. What do you think about changing the status to "by design" as I did with this post?