In this case the actual message is this:
The requested page "/node/5/edit/maestro/edit/4" could not be found.

This came from clicking on the link "Test Article" shown in the attached image.

The user has all privileges from all enabled modules set on the permissions page but is not actually user 1.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Reg’s picture

FileSize
127.45 KB
_randy’s picture

Status: Active » Postponed (maintainer needs more info)

Any other modules installed that cause the path for nodes to be intercepted before Maestro can intercept them? I've seen this happen before and the only way around it was to disable the offending module or alter the weights of the modules to have maestro's menu router run before any other contrib modules.

Reg’s picture

There's pathauto but that shouldn't be causing any rerouting as far as I know. Still I'l poke around a little and see if I can find some module that's doing that... or do know of any issues with pathauto and maestro?

Reg’s picture

Okay, I set the module to be first with a weight of -100. That made no difference.

I looked in your hook_menu() and there is no definition that I can see that would pick up "node/*/edit/maestro/edit/*".

I did see it defined in admin_paths() but that doesn't do anything but return an array so at this point I don't see how you are responding the URL.

If you can tell me how you are picking up the URL (when it is) I'll track down what's going on and of course supply a patch if it helps.

Reg’s picture

Status: Postponed (maintainer needs more info) » Active
Reg’s picture

I've made a little bit of headway. I loaded one of your samples and the Add Node part worked.

So, looking at the image here's what's happening. Clicking on:

  • "Create New Article" looks like: node/add/article/maestro/28 but uses JS to send the URL maestro/taskconsole/ajax/starttask to Drupal. This works as expected and goes to an add node page.
  • "SME Drafts/Reviews Content" looks like: maestro/taskconsole# but uses JS to send the URL maestro/taskconsole/ajax/starttask to Drupal. This works as expected and opens up the yellow area below it.
  • "t5" (in the yellow area) looks like: node/46/edit/maestro/edit/22 and that is what Drupal sees.

Clearly this link (t5) isn't getting JS attached to it like "Task Name" links are - not sure if this is something not working or just an oversight. Because of this it's sending a URL to Drupal that has no menu item for it and the menu system is giving the "Page not found" error since it can't find a handler for the path. I verified all this by watching both firebug and tracing through Drupal as it happened with my PHP debugger.

There are no JS errors on my page breaking the JS, at least according to FireBug.

I'm not sure where the JS is in your code that should be governing that link. If you want to point to the file(s) to look in then I'll try to debug it. My JS however isn't nearly as strong as my PHP so I'm hoping you could have a look at this now that there's more information. I don't see how another module could be causing this unless it was cause your JS not to attach to the link but in that case we should see some sort of JS error and there are none.

Reg’s picture

FileSize
46.25 KB

The image I forgot to attach to #6

_randy’s picture

We alter the form through maestro_form_alter where we try to determine once a form is loaded if there's any Maestro to-dos on the page independent of forcing it through a menu hook. This way any other module can do what it wants to do (theoretically) and we can simply detect the /maestro in the form's URL.

Reg’s picture

Status: Active » Postponed (maintainer needs more info)

Okay, but without the JS which uses a completely different URL to what's hard coded into the HTML "A" tag it will never get to your hook because the menu system only sees a URL that there is no handler for and immediately rejects the page -- nothing has a chance to get called. About the only hooks you will get are boot, init and drupal_alter in this scenario which is what's happening.

I don't know if there's even code in the system to attach JS to the URL in that yellow area (it's created from it's own template file from what I can see) or if it was something that was missed.

BTW, this is a little different to the philosophy of Drupal. Drupal is meant to "degrade gracefully" meaning that if you turn off JS your application should still work albeit perhaps a little clunky so even the hard coded URL's should be setup to work which some won't (e.g.: there is no pattern setup in the menu system for node/*/edit/maestro/edit/* or node/%/edit/maestro/edit/% so any URL with that pattern gets rejected outright with just the few hooks I mentioned getting called).

Clearly degrading gracefully is not going to be possible with you admin interface for designing the workflows but a simple link in a table cell (or div or whatever) where users are just clicking on tasks should work with or without JS. Probably the best example I know of this is the views interface. Turn off JS in your browser and it will still all work... but clearly not fun to work with.

Reg’s picture

I am pretty sure that I have pin pointed the issue. By not defining the menu item you rely on menu_get_ancestors() to return the correct path. In the case of node/add that's fine.

However, in the case of node/%/edit there is a definition by another module closer to your full path of node/46/edit/maestro/edit/22 which in this case is node/%/edit/% . This path goes to entity_translation_edit_title() and eventually that leads to a "Not Found" error.

The solution is to define your menu router item in the menu system rather than relying on the one you want to be picked up by menu_get_ancestors() since that can't be guaranteed, albeit usually likely. Or, there may be some menu router hook you can use to make sure you get the result you want but definition in the hook_menu would be easiest for others to understand.

_randy’s picture

Yup - good pinpointing Reg -- however this is generally why we customize the node alteration/editing tasks and the out of the box provided content type tasks are simply there to get one started. We usually have a customized node editing task that surfaces portions of the node in the task console when expanding the interactive task. Then on-click, we're able to surface the node, with modifications, as we see fit.

I wouldn't mind getting a menu router in place, but then that negates the simple form_alter that we've got for that task type or anything else for that matter that uses the URI for passing in editing parameters in that fashion.

I wonder if a simple tweak would be to have the uri changed to a ?maestro_op=edit&maestro_id=xxx ... food for thought...

Reg’s picture

Yep, I figured that was it which is why I'm looking at hook_menu_get_item_alter() . However, your form_alter() will probably still work if you just copy the whole node_edit menu item and then just change to your more specific path. It's kind of a way to have two paths go to the same handler... might be an easy solution?

E.g.:
Original:

  $items['node/%node/edit'] = array(
    'title' => 'Edit',
    'page callback' => 'node_page_edit',
    'page arguments' => array(1),
    'access callback' => 'node_access',
    'access arguments' => array('update', 1),
    'weight' => 0,
    'type' => MENU_LOCAL_TASK,
    'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
    'file' => 'node.pages.inc',
  );

Possibly yours?:

  $items['node/%node/edit/maestro/edit/%'] = array(   # <- Only line different
    'title' => 'Edit',
    'page callback' => 'node_page_edit',
    'page arguments' => array(1),
    'access callback' => 'node_access',
    'access arguments' => array('update', 1),
    'weight' => 0,
    'type' => MENU_LOCAL_TASK,  # <- Probably change this to a hidden menu item and that should be all you need
    'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
    'file' => 'node.pages.inc',
  );

Reg’s picture

Adding these seems to work:

  $items['node/add/*/maestro/%'] = array(
    'title' => 'Add content',
    'page callback' => 'node_add_page',
    'access callback' => '_node_add_access',
    'file' => 'node.pages.inc',
    'file path' => drupal_get_path('module', 'node'),
  );

  $items['node/%node/edit/maestro/edit/%'] = array(
    'title' => 'Edit',
    'page callback' => 'node_page_edit',
    'page arguments' => array(1),
    'access callback' => 'node_access',
    'access arguments' => array('update', 1),
    'weight' => 0,
    'type' => MENU_CALLBACK,
    'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
    'file' => 'node.pages.inc',
    'file path' => drupal_get_path('module', 'node'),
  );

Patch next. Also in the patch is some commented out code for hook_menu_get_item_alter() (just below hook_menu) which I feel is a more elegant solution but it wasn't playing nice so I gave up. Perhaps you will have better luck with fresh eyes on it.

Reg’s picture

Reg’s picture

Status: Postponed (maintainer needs more info) » Needs review