Enable the contact.module, setup a form, and visit the contact page. Notice that the breadcrumb is only set for "Home". Thus, there's no reason for the two lines of code this patch deletes in contact_mail_page(), which attempt to set the breadcrumb. As a side-effect of setting the breadcrumb, our arg()'s get futzed around with, which makes it impossible for anyone to ever use, for example, contact/3, to automatically set the category ID.
This example code, which should work in (the fictional) contact_category.module, with a URL of contact/3
function contact_category_form_alter($form_id, &$form) {
if ($form_id == 'contact_mail_page') {
if (arg(1) && is_numeric(arg(1))) {
$form['cid']['#default_value'] = arg(1);
}
}
has to be written as the following instead, with a URL of contact&cid=3:
function contact_category_form_alter($form_id, &$form) {
if ($form_id == 'contact_mail_page') {
if (isset($_GET['cid']) && is_numeric($_GET['cid'])) {
$form['cid']['#default_value'] = $_GET['cid'];
}
}
}
Comments
Comment #1
morbus iffI thought I attached this. Hrms.
Comment #2
seanrChanged title and component from comment to contact. ;-)
The patch works perfectly for me, with no apparent side-effects. I say commit it.
Comment #3
Zen commenteda) Said breadcrumb vanishes on my local install when I comment out the menu_set_location line. Stock bluemarine.
b) From a quick look, this is happening because $_GET['q'] is reset (in menu_set_active) to the "fallback" menu which is /contact because there is no explicit declaration of /contact/cid.
Setting status to "code needs work" as I lose my breadcrumb due to the attached patch. Third party mediator required :)
My 10p.
-K
P.S Mangling a $_GET variable directly like this seems like a bad idea.
Comment #4
morbus iffIn testing with Zen, there seems to be two problems:
* $_GET is being mangled, as he's already mentioned.
* The breadcrumb is disappearing under weird circumstances. Under PHP 5, I can see the breadcrumb as user 1, and as an anonymous user. On PHP 4.4.1, I can see it as user 1, but not as anonymous or unprivileged user. Under 4.3, Zen can't seen it as anyone.
Comment #5
Zen commentedI can confirm that this also breaks other pages like the comment_reply form which also uses a menu_set_location. The reason why we aren't already seeing breakage is because the functions in question access these arguments via initialised variables in the function parameter list. Any arguments not explicity stated in hook_menu will be lost after the menu_set_location; i.e. hooks along the lines of hook_form_alter etc. will possibly fail.
Grep output:
Setting this to critical for the 4.7 release.
-K
Comment #6
Zen commentedThe attached patch fixes the symptoms by avoiding menu_set_location altogether.
Fixes:
This is it I think. I've not removed menu_set_location (which is not used anywhere in core now) with this patch mainly due to the following comment in menu.inc:
I'd prefer to get an opinion on this before doing anything destructive.
-K
Comment #7
Zen commented.
Comment #8
jonbob commentedI disagree with moving from menu_set_location() to drupal_set_breadcrumb(). The two are not equivalent. Setting the user's location affects the rendering of the menu tree, and the breadcrumb call does not. In fact, I don't think we should be ever using drupal_set_breadcrumb().
Here's a use case to demonstrate:
Suppose we have the menu structure
- Foo
- Bar
- Baz
- Xyzzy
- Plugh
Now suppose we are on a node view page for a node that is not in the menu structure, "Fnord." Suppose some code in a hook_nodeapi() wants to react to this node view and position the user in the menu, as if they were at Foo -> Bar -> Fnord.
Regardless of whether menu_set_location() or drupal_set_breadcrumb() is used, we get the correct breadcrumb trail. But in the former case the menu is expanded properly, whereas in the latter case we end up with
- Foo
- Xyzzy
- Plugh
which is not what we want.
Comment #9
jonbob commentedThe example structures were mangled, sorry. The first one should be
- Foo
- - Bar
- - Baz
- Xyzzy
- Plugh
and the second one should be
- Foo
- Xyzzy
- Plugh
Comment #10
jonbob commentedI don't think menu_set_location ever needs to change the current path; it should be affecting the menu tree only. The attached is worth a shot.
Comment #11
chx commentedAs long as callbacks rely on $_GET['q'] and arg, menu_set_location needs to update the location IMNSHO.
Comment #12
Steven commentedThe way I interpret the menu_set_active_location() doxygen, I disagree with chx. It should only be used to make the current page appear somewhere else in the menu, not to invoke pages from another actual page. That would be a bad idea anyway IMO because it violates the good practice that a piece of content has only one unique URL.
If you want to make another page appear as the content of your current page, it is not that much effort to set $_GET['q'] yourself. It is not very elegant, but then this is IMO not a supported feature of the menu system.
Comment #13
jonbob commentedI agree with Steven on this one. I don't think changing the function of the page is part of what menu_set_location is supposed to do. One should probably do a drupal_goto() for this.
Comment #14
killes@www.drop.org commentedapplied
Comment #15
(not verified) commented