Problem/Motivation
menu_tokens function changes the node object with menu_node_prepare() if it has not a menu variable.
if (!isset($node->menu)) {
// Nodes do not have their menu links loaded via menu_node_load().
menu_node_prepare($node);
}
A loaded node object (with node_load()) has not menu variable, even if the node has a menu item. menu_node_save() does nothing, if the node object has no menu variable, but if it has, it will create, change or delete a menu item. In this case it will delete the menu item, if it exists.
So if a module loads a node, prepare it, generate node tokens then save it, menu_tokens will remove the node's menu item. Like in this case: #1230034: Menu link disappears when publishing a node by the moderation dropdown or by the moderation view link
Proposed resolution
The menu_tokens() function needs an 'mlid', and I think, the best way to get it in this case is still the menu_node_prepare() function, so my patch just using a new variable for the mlid, and then unset the menu variable, so node object will be unchanged.
I attach also a patch just for the tests, this patch should fail.
Remaining tasks
Review needed.
User interface changes
none
API changes
none
| Comment | File | Size | Author |
|---|---|---|---|
| #5 | menu_tokens-1317926-5.patch | 1.16 KB | pp |
| #4 | menu_tokens-test_only-1317926-4.patch | 721 bytes | Désiré |
| #4 | menu_tokens-1317926-4.patch | 1.65 KB | Désiré |
| #3 | menu_tokens-1317926-3.patch | 1.57 KB | Désiré |
| #2 | menu_tokens-test_only-1317926-1.patch | 723 bytes | Désiré |
Comments
Comment #1
Désiré commentedComment #2
Désiré commented(reupload patches for testing)
Comment #3
Désiré commentedbetter tests
Comment #4
Désiré commentedAfter some consultation and code review I've made a new solution and better tests.
(test only patch should fail on tests)
Comment #5
pp commentedI think it's enough to cloning the $node.
How reproduce this bug?
Comment #6
Désiré commentedOK, you're patch is cleaner. :)
It not so simple, because it occurs only if the node object will saved with node_save() after token generation (token_generate()), like in my test:
There is how was I reproduce it:
1 - create a node, check the 'Provide a menu link' option
2 - then run the following PHP code:
3 - reload the page -> the menu item was deleted
(sorry I don't fount simpler reproduction method, but you can see, it's not impossible that a module need implements the steps above)
Comment #7
pp commentedok, I think it is good enough to understand the problem.
Comment #8
dave reidI added a couple comments and committed this to 7.x-1.x. Thanks Désiré and pp! http://drupalcode.org/project/token.git/commit/12eb465
Comment #10
Frederic wbase commentedSuper! I was waiting for this fix for a long time.
Thanks for your hard word :-)
Comment #11
Ciraxis commentedhm can't find the patch in token.tokens.inc or it is just out of date?
E: version 7.x-1.0-rc1 or 7.x-1.x-dev
Comment #11.0
Ciraxis commentedjust some correction