Considering this code:

  $items['admin/structure/block/manage/%block/%'] = array(
    'title' => 'Configure block',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('block_admin_configure', 4),
    'load arguments' => array(5),
    'access arguments' => array('administer blocks'),
    'file' => 'block.admin.inc',
  );
  $items['admin/structure/block/manage/%block/%/configure'] = array(
    'title' => 'Configure block',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'tab_type' => 'context',
  );
  $items['admin/structure/block/manage/%block/%/delete'] = array(
    'title' => 'Delete block',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('block_custom_block_delete', 4),
    'load arguments' => array(5),
    'access arguments' => array('administer blocks'),
    'type' => MENU_CALLBACK,
    'file' => 'block.admin.inc',
  );

Expected behavior: When requesting the path admin/structure/block/manage/foo/bar, block_load() gets two arguments: 'foo' and 'bar'.

Actual behavior: When requesting the path admin/structure/block/manage/foo/bar, block_load() gets one argument: 'foo'.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

chx’s picture

When requesting the path admin/structure/block/manage/foo/bar, block_load() gets two arguments: 'foo' and 'bar'.

That's curious. Why do you expect that? The "rest of the path as arguments" is only applicable for page. Or are you saying that

$items['foo/%bar'] = array('load arguments' => 2);
return $items;

then bar_load on foo/b/c wont get b and c as arguments??

sun’s picture

Issue tags: +Contextual links

In this case, block_load() requires two arguments: $module and $delta. These are expected to be passed to the menu argument loader, and hence, block_load() can't be invoked with %block only.

For the path admin/structure/block/manage/%block/% - which defines load arguments - the load function arguments are properly stored in the database.

For the path admin/structure/block/manage/%block/%/configure - which does not define load arguments on its own - only %block is stored as argument in load_functions.

Since admin/structure/block/manage/%block/%/configure is a MENU_DEFAULT_LOCAL_TASK, I expected that

  $router_item = menu_get_item('admin/structure/block/manage/foor/bar/configure');

would take over the defined load arguments from the parent, because I equally don't need to specify any other arguments defined by the parent to make the MENU_DEFAULT_LOCAL_TASK work as it should:

  $items['admin/structure/block/manage/%block/%'] = array(
    'load arguments' => array(5),
  );
  $items['admin/structure/block/manage/%block/%/configure'] = array(
    'title' => 'Configure',
    'type' => MENU_DEFAULT_LOCAL_TASK,
  );

I expected this behavior, because I can't see how any path of

admin/structure/block/manage/%block/%/configure

can work at all when the "parent path" defines load arguments to allow the menu argument loader %block, i.e. block_load(), to load the right thing, as in:

admin/structure/block/manage/%block/%

(yes, you ranted there's no concept of parents, but you didn't explain why, so I'm not sure how I can grok that.)

I would expect this behavior as long as an item does not define load arguments on its own:

  $items['admin/structure/block/manage/%block/%'] = array(
    'load arguments' => array(5),
  );
  $items['admin/structure/block/manage/%block/%/send-to-mars/%'] = array(
    'load arguments' => array(5, 7),
  );
chx’s picture

So the bug is this:

While most page callback +page arguments, file + file path, delivery callback and theme callback inherits, load argument was left out. However, access callback only inherits for default tasks. So we need to make a decision what and how to inherit with load arguments. Given that load arguments were a last minute ugly bolt on in D6 which noone bother to fix in D7 we have three ways to go:

  1. Leave this alone.
  2. Hack up menu.inc so it inherits load arguments. My head hurts.
  3. Get permission from Dries to add another column to menu_router for the arguments.
chx’s picture

Title: MENU_DEFAULT_LOCAL_TASK doesn't work without explicitly defining 'load arguments' » 'load arguments' does not inherit at all
sun’s picture

Priority: Normal » Critical
Issue tags: +D7 API clean-up

With the new usage of local tasks/contextual links, I'm pretty sure that I'll not be the only one who runs into this bug + has no clue at all why it's not working, so I recommend doing #3.

It took 3 experienced Drupal developers to find out that "load arguments" are not inherited at all (which sounds quite simple, but it's totally not what you expect).

chx’s picture

Priority: Critical » Normal
Status: Active » Needs review
Issue tags: -D7 API clean-up
FileSize
0 bytes

this is 2. Not that horribly complicated now that i thought it though.

chx’s picture

FileSize
1.34 KB

That was too simple.

sun’s picture

Priority: Normal » Critical
Status: Needs review » Active

Thanks! This seems to pass the bot and looks correct. However, we also want 1) a bit more docs and 2) tests. Not sure whether I'll get to do that.

sun’s picture

Status: Active » Needs review

oopsie

chx’s picture

Title: 'load arguments' does not inherit at all » Now easy task: write tests and docs

Given the rate people are helping with criticals we will release in 2011.

Edit: I deliberately deleted the title so people are not running screaming.

mr.baileys’s picture

So if I understand correctly, all that is needed to move this forward are tests (verify that 'load arguments' is inherited when not explicitly specified) and documentation?

Here's a stab at adding tests for it...

Status: Needs review » Needs work
Issue tags: -Needs tests, -Needs documentation, -Contextual links

The last submitted patch, menu-load-arguments-inheritance.patch, failed testing.

Status: Needs work » Needs review

Re-test of menu-load-arguments-inheritance.patch from comment #11 was requested by mikey_p.

Status: Needs review » Needs work
Issue tags: +Needs tests, +Needs documentation, +Contextual links

The last submitted patch, menu-load-arguments-inheritance.patch, failed testing.

sun.core’s picture

Title: Now easy task: write tests and docs » 'load arguments' does not inherit at all
Priority: Critical » Normal

Not critical. Please read and understand Priority levels of Issues, thanks.

sun’s picture

Issue tags: -Needs documentation

Broken tags.

sun’s picture

Title: 'load arguments' does not inherit at all » 'load arguments' of parent path are not inherited
Assigned: Unassigned » sun
Status: Needs work » Needs review
Issue tags: -Needs tests
FileSize
5.48 KB

Reworked those tests. Also had to rework that foreach loop in menu_router_build(), as it did not properly work and led to bogus load functions data.

Lastly, during debugging I recognized that we're needlessly unserializing a lot of menu item load functions, and serialize()/unserialize() is very slow, so this patch additionally fixes that.

chx’s picture

Status: Needs review » Reviewed & tested by the community

This is sheer awesome: bugfix, test and performance boost.

sun’s picture

Issue tags: +Performance

Just to be precise: adding Performance tag. unserialize() is known to be slow. And the current usage is just useless.

sun’s picture

Although my local box is totally not suitable for doing benchmarks, I've mass-applied the following range of current performance patches and am getting a nice boost:

#910190: Entire schema cache needlessly loaded on all pages
#910156: Remove 'description' keys from schema cache
#606966: 'load arguments' of parent path are not inherited
#910124: Clean up menu_contextual_links()

BEFORE patches:
Executed 36 queries in 25.18 ms.
Page execution time was 481.48 ms.
Memory used at: devel_boot()=2.5 MB, devel_shutdown()=16.23 MB, PHP peak=16.75 MB.

AFTER patches:
Executed 35 queries in 15.99 ms.
Page execution time was 471.18 ms.
Memory used at: devel_boot()=1.95 MB, devel_shutdown()=15.85 MB, PHP peak=16.5 MB.

Test page: admin/config/development/devel; Garland; enabled Navigation menu block containing 1 taxonomy term link and 1 node link.

sun’s picture

sun’s picture

sun’s picture

Status: Reviewed & tested by the community » Closed (won't fix)
Dave Reid’s picture

Assigned: sun » Unassigned
Status: Closed (won't fix) » Reviewed & tested by the community

Just because someone is upset doesn't mean we have to mark something as won't fix. Someone else is more than welcome to pick up work on a ticket.

sun’s picture

Version: 7.x-dev » 8.x-dev

Although badly needed, this is D8 material according to the rules (I had to learn today). It may be backported at a later point in time (though that's unlikely).

chx’s picture

Version: 8.x-dev » 7.x-dev

This is a performance boost, no reason to postpone just yet. If it does not get into 7.0 that's fine, it's not a critical.

sun’s picture

Assigned: Unassigned » sun
sun’s picture

webchick’s picture

Status: Reviewed & tested by the community » Fixed

Committed to HEAD. Thanks!

das-peter’s picture

Status: Fixed » Closed (fixed)
Issue tags: -Performance, -Contextual links

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