node_load() during signup's node_save() breaks node data cached by CCK
| Project: | Signup |
| Version: | 6.x-1.0-rc6 |
| Component: | Code |
| Category: | bug report |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | needs review |
Jump to:
Here's an issue that has been bugging for a while.
I'm using filefiels_paths for an imagefield where the filepath uses a custom token. This means that filefield_paths will move the file to the final location and update the record in the {file} table to reflect the new filepath.
On the other hand, during node_load(), CCK caches the data of the fields, and it happens that filefield loads the record of the {file} table here, which is then cached by CCK.
When a node is updated, CCK clears the cache entry, but when a node is created, if something in your system causes a node load after the node has been saved by node module, but before filefield_paths updates the record in the {file} table, it will happen that this node_load() will make CCK cache an incorrect version of the file data, because it has not been updated yet by fieldfield_paths.
The solution to this is pretty simple. Just make sure the CCK cached version of the node is cleared if filefield_paths_file_move() succeeds.
I'm not 100% sure this is the best way to fix, but a quick one is:
<?php
if (filefield_paths_file_move($file)) {
+ cache_clear_all('content:'. $node->nid .':'. $node->vid, content_cache_tablename());
?>I don't know what causes a node_load() between the node has been created and this step in filefield_paths, but it seems to me it was signup module in my case, in signup_save_node(). I guess it could also happen from other modules, so this is why I'm reporting this here. If the CCK cache is cleared here, then no matter if other modules do a node_load() for whatever reason.

#1
Actually, the fix above does not work because signup executes after filefield_paths module, so the node_load() performed by signup module causes the node data to be cached by CCK after the fix above happens.
I'm moving this issue to the signup queue, as I have finally found a method to fix this in that module. I'm using 6.x-1.0-rc6 of signup module, and the following change to signup/includes/node_form.inc, function signup_save_node() fixed the issue here:
<?php$node = node_load($node->nid);
+ if (module_exists('content')) {
+ cache_clear_all('content:'. $node->nid .':'. $node->vid, content_cache_tablename());
+ }
if (_signup_node_completed($node) && !empty($node->signup_status)) {
?>
In the meantime, I'm using a custom module that I use for hacks, that has a weight higher than other modules, and here I'm implementing the following hook_nodeapi(), that also works:
<?php/**
* Implementation of hook_nodeapi().
*/
function MODULE_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
switch ($op) {
case 'insert':
case 'update':
// Ensure content cache is cleared to account for changes in {file}
// records when these have been updated by filefield_paths module
// using tokens, broken by signup module doing a node_load() during
// a node_save() operation.
// See http ://drupal.org/node/605594
cache_clear_all('content:'. $node->nid .':'. $node->vid, content_cache_tablename());
break;
}
}
?>
#2
Adjusting issue title.
#3
Wow, this is nasty... I have several different content types with various types of CCK fields, and whenever trying to create a new node for any of those types (regardless of whether they were signup enabled) the CCK fields wouldn't save (but would when editing them).
The first patch in #1 seems to have fixed the problem, thanks!