Symptoms
Currently, whenever a decision is updated through the pattern
$node = node_load(NID);
// Do something with node, such $node->promote = 1
node_save($node);
all the settings are lost. Its a problem, because this pattern is used quite a lot by both contrib and core modules. Below are some relatively contrived steps to reproduce the problem using only core and decisions:
- Enable the Trigger module
- Go to admin/build/trigger/comments (Administer -> Site building -> Triggers, and then the local task Comments)
- Add the "Save post" actions to the trigger "Trigger: After saving a new comment"
- Create a new Decisions node
- Add a comment to it
Expected result: No change to the decision node, as the only action we've assigned is the Save post one.
Actual result: The node is now marked as closed, and every settings made in the Decision settings fieldset are gone.
A more realistic scenario would be: install both the Views and Views Bulk Operations modules, go to the new administration page provided by Views Bulk Operations (located at admin/content/node2), choose a decision node and one of the available actions, such as "Promote post to frontpage", apply ... and observe that all the settings are lost.
What's going on
Currently, both decisions_inserts and decisions_updates assumes that their values come from a form submission, and thus use the values as they would appear in a form api submit callback.
The problem is that decisions_form sets '#tree' => TRUE on the settings fieldset, which means that the values in the submit callback are stored in a settings array ; decisions_load puts them straight in the node object though.
A concrete example: decisions_load puts the algorithm in $node->algorithm, but the value at the submit stage and thus used by decisions_update is $node->settings['algorithm'].
This obviously breaks if the node passed to decisions_update is just the object returned by decisions_load, and not a node object coming from the form.
Possible solution
I'm attaching a patch that makes decisions_load also put all the values in the $node->settings array, pretty much like they would be in a form api submit callback. This means that the node object becomes a bit heavier memory-wise, because some informations is stored twice: that could be avoided by unsetting the original properties of the object once they're in the settings array, but it also means changing a lot of code all around.
The patch also slightly tweaks decisions_insert / decisions_update to make them check the format of both startdate and enddate, to avoid unnecessary timestamp => array => timestamp
conversions.
Just in case: This isn't the same as #514562: Allow creating decisions programatically. That issue deals with providing default values to make it easier to create decisions node from scratch, this issue deals with preserving existing settings set on a node.
Comment | File | Size | Author |
---|---|---|---|
#3 | decisions-dont-lose-settings-919622-2.patch | 7.8 KB | DeFr |
#1 | decisions-dont-lose-settings-919622-1.patch | 4.64 KB | DeFr |
Comments
Comment #1
DeFr CreditAttribution: DeFr commentedAttaching patch mentioned above.
Comment #3
DeFr CreditAttribution: DeFr commentedI've been thinking a bit more about the problem, and thus here come a completely different approach to solving this issue, that's probably cleaner.
As stated in the original comment, the problem is that due to the '#tree' => TRUE property in decisions_form, the shape of the node values isn't the same in the form submit callback and in decisions_load. Instead of patching decisions_load to make it load the values in both place like patch in #1 does, this patch simply overhaul decisions_form a bit, to make it output the variables directly in $node.
Comment #4
DeFr CreditAttribution: DeFr commentedBumping to major, as this bug can cause some sort of dataloss.