Jump to:
| Project: | Rules |
| Version: | 6.x-1.x-dev |
| Component: | Rules Engine |
| Category: | bug report |
| Priority: | major |
| Assigned: | Unassigned |
| Status: | closed (fixed) |
Issue Summary
This one is odd. I have working rules that check if a field has been updated. They work fine. On any new content types I create, rules always returns FALSE for "field has been updated". Even odder, If I negate the rule, it still returns FALSE. I can use a field from an older content type and the rule works fine, but if I use a field from a content type created within the last week it fails.
I am racking my brain trying to figure out if some setting has been changed but aside from perms I can't figure out what would do this. Besides, I am running as user #1, perms should not matter.
I would LOVE to solve this problem, I am just not sure how to begin. I just created a new content type and the rule, "After existing content has been updated" Condition "Field has changed" I have triple checked that I have the correct field. arguments are : Content containing changes (updated content) content not containing changes (unchanged content) When I edit the content type, then save, I get this.
*
o 0 ms "After updating existing content" has been invoked.
o 0.118 ms Executing the rule "testing field change detect rule." on rule set "After updating existing content"
o 0.4 ms Loaded variable "unchanged content"
o 0.514 ms Condition "Updated content's field 'field_test_content_test' has been changed" evaluated to FALSE.
o 0.588 ms Evaluation of "After updating existing content" has been finished.
* Test Content type Test item has been updated.
field_test_content_test WAS changed.
If I go back to the rule and NEGATE it.. I get the same thing..
*
o 0 ms "After updating existing content" has been invoked.
o 0.117 ms Executing the rule "testing field change detect rule." on rule set "After updating existing content"
o 0.398 ms Loaded variable "unchanged content"
o 0.509 ms Condition "Updated content's field 'field_test_content_test' has been changed" evaluated to FALSE.
o 0.583 ms Evaluation of "After updating existing content" has been finished.
* Test Content type Test item has been updated.
Now.. If I use a field from an old content type.. This is what I get..
*
o 0 ms "After updating existing content" has been invoked.
o 0.141 ms Executing the rule "testing field change detect rule." on rule set "After updating existing content"
o 0.485 ms Loaded variable "unchanged content"
o 0.622 ms Condition "Updated content's field 'field_nurse_first_name' has been changed" evaluated to TRUE.
o 0.712 ms Evaluation of "After updating existing content" has been finished.
* Nursing Profile Mclifter, Jim, RN has been updated.
It works perfectly. So, new content fields are not working, old ones are.
Comments
#1
More data.
if I change the condition to "content is going to be saved" it works.
#
* 0 ms "Content is going to be saved" has been invoked.
* 0.12 ms Executing the rule "test field rule" on rule set "Content is going to be saved"
* 0.375 ms Loaded variable "unchanged content"
* 0.485 ms Condition "Saved content's field 'field_test_content_test' has been changed" evaluated to TRUE.
* 0.562 ms Evaluation of "Content is going to be saved" has been finished.
If I activate the "content has been updated and both rules execute this follows..
# 0.445 ms Executing the rule "content has been updated test" on rule set "After updating existing content"
# 0.771 ms Loaded variable "unchanged content"
# 0.935 ms Condition "Updated content's field 'field_test_content_test' has been changed" evaluated to FALSE.
# 1.013 ms Evaluation of "After updating existing content" has been finished.
#2
Seems like you fixed it.
#3
Automatically closed -- issue fixed for 2 weeks with no activity.
#4
I encountered exactly the same problem in Rules 6.x-1.4 and 6.x-1.x-dev with FileField 6.x-3.10 and CCK 6.x-2.9.
Only in my case changing to "content is going to be saved" does not fix the problem.
#5
I did a bit of code digging, and it seems like rules module hands off a screwed up argument $exec_args to cck. In function rules_execute_condition(), $exec_args is set by function rules_get_execution_arguments() and it has the same new value for both elements [0] and [1] (which are passed to cck for comparison). From what I can gather, one of these elements is supposed to have old field value. Since both are set to new value, cck will compare and rightfully respond that there is no change of field value.
#6
More code digging, and I have a hack that fixes it.
in rules.variables.inc file after this code:
function rules_get_element_arguments($element, &$state) {
$element_info = rules_get_element_info($element);
$map = rules_get_mapped_argument_names($element);
$args = array();
foreach (array_keys($element_info['arguments']) as $key => $name) {
if (($var = rules_get_element_variable($element, $name)) !== NULL) {
$args[$key] = $var;
}
I've inserted this case (using unmapped $name before trying $map[$name] since $map[$name] for both node and node_unchanged contains 'node'):
elseif (isset($name) && isset($state['variables'][$name])) {$args[$key] = &$state['variables'][$name]->get();
}
And the original function continues:
elseif (isset($map[$name]) && isset($state['variables'][$map[$name]])) {$args[$key] = &$state['variables'][$map[$name]]->get();
}
elseif (array_key_exists('default value', $element_info['arguments'][$name])) {
$args[$key] = $element_info['arguments'][$name]['default value'];
}
else {
rules_log(t('Warning: Unable to get argument "@name".', array('@name' => $key)));
return FALSE;
}
}
return $args;
}
I am not sure this hack is meaningful, but it fixes the problem. Looks like the element data is not set up correctly: map for both 'node' and 'node_unchanged' contains the same value 'node', which causes the comparison down the road to always return 'TRUE', thus 'change condition' is always 'FALSE'.
Can someone from maintainers look into this and chime back in - is that the right place for a fix? My sense is that the map should be set up properly in the first place, but I don't know where that happens.
Rules is a cornerstone module for many CCK related things, and this issue breaks significant functionality. Raising to 'major'.
UPDATE:
Does this block in node.rules.inc look right?
function rules_events_node_arguments($node_label, $author_label, $update = FALSE) {$args = array(
'node' => array(
'type' => 'node',
'label' => $node_label,
),
'author' => array(
'type' => 'user',
'label' => $author_label,
'handler' => 'rules_events_argument_node_author',
),
);
if ($update) {
$args += array(
'node_unchanged' => array(
'type' => 'node', //<<<<<<<<<<<<<<WRONG??
'label' => t('unchanged content'),
'handler' => 'rules_events_argument_node_unchanged',
),
'author_unchanged' => array(
'type' => 'user',
'label' => t("unchanged content's author"),
'handler' => 'rules_events_argument_unchanged_node_author',
),
);
}
return $args + rules_events_global_user_argument();
}
I suspect that 'type' for 'node_unchanged' (line 68) is incorrect.
#7
I tested some more, and none of the changes I tried are completely good - the rule's condition is now always true, even when the field has not been changed.
Interestingly, I rolled back the changes, and now this rule is always true. What I noticed is that on the rule admin page the drop-down lists for changed and unchanged arguments now have two items as expected - 'saved content' and 'unchanged content', but they both had only 'saved' content' item when I started. I missed that first - maybe that was the initial problem. I should mention that I cleared caches couple of times, deleted the whole rule and started from scratch. Now I can't make this rule to be FALSE when field is not changed. Spooky. Any thoughts?
#8
Close due to long inactivity. Please don't hesitate to re-open if the issue is still relevant.
#9
It's there any progress in this issue?
I've rule which print a message after node is created -> works corectly.
Than I've another rules which print message after the node is changed -> works corectly too.
The problem
After creation of the node, one of its fields is filled up wia another rules -> thats work corectly. But at this point the newly created node is changed and fires the second rule. So instead of one message I got two of them.
I've tryed the negation of Field has changed, but with every combination posible I can't get it working as I need.
If needed I can provide aditional info.
Thank you in advance for your help.