This patch moves node_invoke_nodeapi($node, 'presave') to right before any drupal_write_record().
The rationale for this is currently module authors who want to alter the node with presave are unable to affect several properties of the node which they might want to. An example use case is $node->changed is set to REQUEST_TIME regardless of whether anything actually changed in the node. A module author implementing presave might only update $node->changed if the node body or title have actually changed.
| Comment | File | Size | Author |
|---|---|---|---|
| #32 | 322759-32.patch | 6.01 KB | chx |
| #27 | 722688-25.patch | 6.26 KB | jpmckinney |
| #23 | 322759-22.patch | 6.24 KB | jpmckinney |
| #22 | 322759-22.patch | 5.2 KB | jpmckinney |
| #17 | 322759-move-presave-later-17.patch | 4.56 KB | coltrane |
Comments
Comment #1
Anonymous (not verified) commentedThank you; yes, this would be a good thing to do.
Comment #2
dries commentedThis seems like a reasonable thing to do.
Comment #3
webchickCan we get a test case in there that does exactly what you describe to verify that it's working as intended, so the next well-meaning person doesn't come along and move it back to the top again? :)
Comment #4
coltraneTest case and mock function. Test isn't passing but neither are many others, so storing this for time being and will revisit soon. Above patch still applies with offset.
Comment #5
coltraneOriginal issue patch no longer applied, rerolled. Need to rewrite test.
Comment #6
coltraneRerolled to apply. I haven't worked on the test case for several months, at the time running into either cache or race condition problems.
Edit. I haven't worked with Fields at all but I'm going to leave field_attach_presave() where it's at.
Comment #7
coltranePatch includes feature request and test case. Are they suppose to be separate attachments or together?
Comment #8
damien tournoud commentedI feel that
hook_node_presave()is superseded byhook_query_alter(). Why not removing it completely?Comment #10
yched commentedre #8: hook_node_presave() is used for 'nodeapi' steps that are relevant on both insert and update. I don't see how hook_query_later() deprecates it ?
Comment #11
damien tournoud commentedWell, hook_query_alter() allows you to modify any query, insert or update, without having to have an explicit "presave" hook. I believe the former is broader then the later, and consequently deprecates it.
Comment #12
yched commentedWell, in lots of cases, nodeapi modules do their stuff in their own tables, so what they might want to do in hook_node_presave() has nothing to do with the base {node} or {node_revision} queries ?
Comment #13
coltraneThe exception is related to #482346: node_modules_installed() implementation not invoked (located in include file) I think, I'm looking into the fails with the book module.
Comment #14
damien tournoud commentedIn that case, they do not need hook_node_presave(), but hook_node_update() and hook_node_insert()... The presave hook was designed for one thing only: to give modules the opportunity to alter the node object before part of it is saved to the node and node_revision tables. That looks a lot like hook_query_alter() to me.
Comment #15
coltraneIt seems to me that removing hook_node_presave() should be in it's own issue. If I can accomplish the specific use case mentioned in the issue with hook_query_alter() that's fine but right now hook_node_presave() works (kinda) and makes more sense (conceptually) since I'm modifying the node object, not the query.
Comment #16
yched commentedre #14:
"give modules the opportunity to alter the node object before part of it is saved to the node and node_revision tables. That looks a lot like hook_query_alter() to me."
And depending on whether I want to modify a core element or a contrib addition, I need to find the right query and alter it ? Yuck.
Also: that works only if the node property is stored locally and saved by a db query.
I don't see why we'd want to prevent acting on the $node level while we can.
Comment #17
coltraneAh, book_node_presave() sets $node->revision and node_save() checks if revision is set before saving the old vid. Previous patch broke book because node->vid wasn't unset.
This patch moves the created, changed, and timestamp fields above the module_invoke_all() and above the filters.
Comment #18
moshe weitzman commentedpre_save is not at all the same as query_alter. sometimes modules need to fiddle with node elements such as $node->og_groups in in helper modules. they might want to set the groups of a post according to own logic, and then all the saving happen as normal.
Comment #20
coltraneI need to review node_save() now to see if there are any other fields that presave can't edit. #722688: Allow programmatic setting of node->changed was committed which handles $node->changed
If there aren't this issue isn't needed anymore.
Comment #21
drewish commentedSounds like #722688-21: Allow programmatic setting of node->changed's patch has some issues, there's talk of backing it out and resurrecting this issue.
Comment #22
jpmckinney commentedIndeed, I have written a patch in that issue to back it out, and I am resurrecting this issue with a patch. Btw, I think this should be critical if the other is critical.
Comment #23
jpmckinney commentedForgot two new files. Tests will fail in the last patch. Re-roll.
Comment #24
catchComment doesn't wrap at 80 characters, otherwise looks RTBC. Should we mark the other issue as duplicate of this?
114 critical left. Go review some!
Comment #27
jpmckinney commentedI've marked #722688: Allow programmatic setting of node->changed duplicate. Here is a re-roll.
Comment #28
jpmckinney commentedComment #29
catchSince this is the correct fix for #722688: Allow programmatic setting of node->changed I'm closing that other issue and reclassifying this as a bug.
Comment #30
catchWhoopsie on the crosspost.
Comment #31
webchickLet's move the test into node_test.module instead of its own module. We're already testing other hooks there such as view.
Comment #32
chx commentedThere we go.
Comment #33
webchickThanks! Committed to HEAD.