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.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Anonymous’s picture

Status: Needs review » Reviewed & tested by the community

Thank you; yes, this would be a good thing to do.

Dries’s picture

This seems like a reasonable thing to do.

webchick’s picture

Status: Reviewed & tested by the community » Needs work

Can 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? :)

coltrane’s picture

Test 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.

coltrane’s picture

Original issue patch no longer applied, rerolled. Need to rewrite test.

coltrane’s picture

Rerolled 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.

coltrane’s picture

Status: Needs work » Needs review
FileSize
3.84 KB

Patch includes feature request and test case. Are they suppose to be separate attachments or together?

Damien Tournoud’s picture

I feel that hook_node_presave() is superseded by hook_query_alter(). Why not removing it completely?

Status: Needs review » Needs work

The last submitted patch failed testing.

yched’s picture

re #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 ?

Damien Tournoud’s picture

Well, 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.

yched’s picture

Well, 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 ?

coltrane’s picture

The 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.

Damien Tournoud’s picture

Well, 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 ?

In 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.

coltrane’s picture

It 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.

yched’s picture

re #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.

coltrane’s picture

Title: Move node invoke presave to right before drupal_write_record » Allow hook_node_presave() to alter other node fields
Status: Needs work » Needs review
FileSize
4.56 KB

Ah, 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.

moshe weitzman’s picture

pre_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.

Status: Needs review » Needs work

The last submitted patch failed testing.

coltrane’s picture

I 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.

drewish’s picture

Sounds 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.

jpmckinney’s picture

Priority: Normal » Critical
Status: Needs work » Needs review
FileSize
5.2 KB

Indeed, 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.

jpmckinney’s picture

FileSize
6.24 KB

Forgot two new files. Tests will fail in the last patch. Re-roll.

catch’s picture

Category: feature » task
Status: Needs review » Needs work
+++ modules/node/node.module
@@ -994,6 +992,19 @@ function node_save($node) {
+    // The changed timestamp is always updated for bookkeeping purposes (revisions, searching, ...)
+    $node->changed = REQUEST_TIME;

Comment 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!

jpmckinney’s picture

FileSize
6.26 KB

I've marked #722688: Allow programmatic setting of node->changed duplicate. Here is a re-roll.

jpmckinney’s picture

Status: Needs work » Needs review
catch’s picture

Category: task » bug
Status: Needs review » Needs work

Since 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.

catch’s picture

Status: Needs work » Reviewed & tested by the community

Whoopsie on the crosspost.

webchick’s picture

Status: Reviewed & tested by the community » Needs work

Let's move the test into node_test.module instead of its own module. We're already testing other hooks there such as view.

chx’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
6.01 KB

There we go.

webchick’s picture

Status: Reviewed & tested by the community » Fixed

Thanks! Committed to HEAD.

Status: Fixed » Closed (fixed)

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