Conditional result for hook_content_is_empty()
markus_petrux - December 20, 2008 - 20:11
| Project: | Computed Field |
| Version: | 6.x-1.0-beta3 |
| Component: | Code |
| Category: | bug report |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | active |
Description
Hi,
I've been testing Computed fields with the multigroup module and it caused a problem because how the way Computed Fields implements hook_content_is_empty(). It always returns FALSE, and that within the context of a multigroup is problematic. Please, see the following comments for details:
http://drupal.org/node/119102#comment-1164604
In my working copy of Computed Fields I tried the following code that seems to work nicely:
<?php
/**
* Implementation of cck hook_content_is_empty().
*/
function computed_field_content_is_empty($item, $field) {
if ($field['data_type'] == 'int' || $field['data_type'] == 'float') {
return !is_numeric($item['value']);
}
return empty($item['value']);
}
?>
#1
#2
I setup a new Drupal installation to test Computed Field with Multigroup (need it for a site I'm working on). I installed the cck and computed_fields modules, patched both, then tried adding a computed field to a multigroup, only to see this familiar error message:
This change is not allowed. The field Total handles multiple values differently than the Content module. Making this change could result in the loss of data.As I was trying this, I realised that you set the version as 1.0-beta2 (I had downloaded the latest .dev). So I disabled the computed_field module, uninstalled it, deleted the folder from the server, then installed the beat2 version and patched it - same error.
I'd mark this as 'Patch (code needs work)', but I'm not convinced I'm not doing something wrong...
Any ideas?
#3
BWPanda #2: You're right. There's something else that needs to be added to computed fields module in order to support content multigroup. The reason is that widgets that are coded to support their own multiple values need to implement a couple of multigroup exposed hooks.
Please, try adding the following to the end of
computed_fields.module/**
* Implementation of hook_content_multigroup_allowed_widgets().
*/
function computed_field_content_multigroup_allowed_widgets() {
return array('computed');
}
/**
* Implementation of hook_content_multigroup_no_remove_widgets().
*/
function computed_field_content_multigroup_no_remove_widgets() {
return array('computed');
}
In summary: there are 2 different issues here.
1) Function computed_field_content_is_empty() needs to fixed to return conditional result.
2) Computed fields module needs to implement a couple of content multigroup hooks.
#4
I'm attaching to patches.
1) computed_field-is_empty-349548-4.patch: modifies hook_content_is_empty() implementation to return conditional result.
2) computed_field-multigroup-349548-4.patch: Implements hook_content_multigroup_allowed_widgets() and hook_content_multigroup_no_remove_widgets() to add support for the multigroup module. This is necessary to tell the multigroup module that widgets that deal with multiple values themselves are compatible with the multigroup module, which is true for this module.
The second patch works with the latest version of multigroup module posted here #119102: Combo field - group different fields into one ...but it could be changed. I would not commit this to CVS until the multigroup module is commited to CCK repository.
#5
Ok, that at least lets me add the computed field to the multigroup.
However, I've noticed that if the computed field is set to 'required', when creating a node it gives the error: [computed field] field is required in group [multigroup]...
#6
It seems computed_field_content_is_empty() is returning TRUE in your case for some reason. That may depend on the data type of the computed field and the code used to compute the value.
#7
Computed Code:
$node_field[0]['value'] = $node->field_value1[0]['value'] + $node->field_value2[0]['value'];Data Type: Was the default 'varchar', but I changed it to 'float', then to 'int', all with the same error...
#8
I also just tried:
$node_field[0]['value'] = $node->value1[0]['value'] + $node->value2[0]['value'];Same result.
#9
If you expect to hold a number, you may wish to set the computed field type to int or float.
Then try something like the following to compute the value of the field:
<?phpif (isset($node->field_value1[0]['value']) || isset($node->field_value2[0]['value'])) {
$node_field[0]['value'] = $node->field_value1[0]['value'] + $node->field_value2[0]['value'];
}
else {
$node_field[0]['value'] = NULL;
}
?>
When the source fields are not set, then the computed field value would be set to NULL, and that will result in computed_field_content_is_empty() to work as expected.
#10
In fact, we would have to compute the values for all the items in the subgroup, so we would need something like the following instead:
<?phpforeach (array_keys($node->field_value1) as $delta) {
if (isset($node->field_value1[$delta]['value']) || isset($node->field_value2[$delta]['value'])) {
$node_field[$delta]['value'] = $node->field_value1[$delta]['value'] + $node->field_value2[$delta]['value'];
}
else {
$node_field[$delta]['value'] = NULL;
}
}
?>
There's an additional problem, and it is that the computed field code is not executed when the node edit form is being validated. I beleive there's something else that needs to be done here in order to have the correct values when the multigroup checks if the fields are empty or not. I'll try to investigate this further. Meanwhile, try unsetting the required flag of the computed field.
#11
Correction to patch for content_is_empty() in #4 above. Function arguments are missing. My bad. The code I posted when opening the issue was correct, but the patch in #4 was not. This should be fixed in the patch attached here. The other patch, the one that implements the multigroup hooks in #4 is also necessary.
@BWPanda: aside from the patches here, I have not been able to solve the error "[computed field] field is required in group [multigroup]" when the computed field is required. I believe this is because there is no real widget and the check for required fields has this dependence here. Anyway, computed fields should work with the patches here. Just do not set them as required. The other fields in the multigroup can, though.
The method to compute values for all items in the multigroup should use a foreach loop similar to the one I posted in #10 above. Note the code to compute a particular field is invokes just once for all items in a group. So the code should process all items.
#12
I don't know why a hidden/computed field would have a 'required' option... How would it not be set anyway?
Thanks Markus, I'll just not set 'required'. Will test more when I get home after work.
#13
That all seems to work fine, though I didn't seem to have to surround the 'Display Format' in a foreach loop...
Just wondering if it's possible (and practical) to put the foreach loop in the module code, rather than making users do it. Something like this:?
function _computed_field_compute_value(&$node, $field, &$node_field) {
foreach (array_keys($node->field_value1) as $delta) {
if (isset($field['code'])) {
eval($field['code']);
}
}
}
I didn't make it into a patch as I have no idea whether it'd work or not, and it's a bit hard to see what's happening when you can't see the field in question :)
#14
Having said that, there is an issue when only creating 1 instance of the multigroup (i.e. fill in the multigroup but don't click 'add more values').
Nothing shows up...
#15
Sorry to get back to this so late, but it looks like multigroup is stalled ATM. So I'll mark this as postponed for now, at least until the deletion issue is resolved:
#196421: Deleting unwanted multiple values / multiple values delta issues
and the multigroup discussion resumes:
#119102: Combo field - group different fields into one
#16
I've tried adding both patches to beta2 but the computed field inside the multivalue is always 0. What am I missing?
this is the code for my computed field:
$node_field[0]['value'] =
$node->multigroupfield[0]['value'] +
$node->multigroupfield2[0]['value'];
#17
@Moonshine #15: Hi, I'm setting this back to active. The multigroup can be found on the CCK repository, branch 6.x-3.x. :)
As per the patches that may allow to use Computed fields with multigroups, I would say these are:
#18
@ballerjones: With multiple value fields, you should perform a loop, something like in comment #10 above, or something like the example posted in your rules related issue:
#495610: printing multigroup fields
#19
I have patched as you suggested successfully. However, I got the following error.
After adding a computed field to a multigroup: (content type screen)
user warning: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') SELECT vid, nid, 0, FROM content_type_mgtest' at line 1 query: INSERT INTO content_field_computedfieldtest (vid, nid, delta, ) SELECT vid, nid, 0, FROM content_type_mgtest in /srv/www/internal/modules/cck/includes/content.admin.inc on line 1523.This was how I added your loop code from #10:
$node_field[0]['value'] = "<?phpforeach (array_keys($node->field_value1) as $delta) {
if (isset($node->field_value1[$delta]['value']) || isset($node->field_value2[$delta]['value'])) {
$node_field[$delta]['value'] = $node->field_value1[$delta]['value'] + $node->field_value2[$delta]['value'];
}
else {
$node_field[$delta]['value'] = NULL;
}
}
?>";
Upon testing node submission, the computed field's title is shown, but there is no value. FYI, this was tested on a blank content type, with 1 multigroup (named mgtest) and two textfield-integer fields (value1 and value2) and the computed field.
Perhaps someone could post the export code for a content type with a working computed field + multigroup combination?
#20
Can anyone shed some light on this issue?
#21
Subscribing. Computed Field is very important for advanced use of multigroups.
#22
&ballerjones
Maybe you should remove the first and last lines in your code at #19
#23
I tested the patch at #17. It works for me. Thank you markus_petrux.
#24
I have tried the patch at # 17 but i still get this error on page load:
: array_keys() []: The first argument should be an array in on line
and i get this error when i try to "add more values" to the multigroup in node edit:
Warningfunction.array-keys/home2/break9/public_html/sites/all/modules/cck/modules/content_multigroup/content_multigroup.node_form.inc143
using: cck3 multigroups and computed field
#25
subscribing
#26
Subscribing and testing...
#27
Tested the patches at #17 and working excellently. Thanks @markus_petrux
#28
subscribing...
I hope that these patches will be added to the dev version soon.
#29
if patched with #17 it works now, without any warning, if adding the computed field to the multigroup.
the following is my computed code:
foreach (array_keys($node->field_category) as $delta) {$result1 = db_result(db_query("SELECT field_default1_value FROM content_type_categories WHERE nid=%d",$node->field_category[$delta][nid]));
$result2 = db_result(db_query("SELECT field_default2_value FROM content_type_categories WHERE nid=%d",$node->field_category[$delta][nid]));
if (!isset($node->field_value1[$delta]['value'])) {
$node_field_value1[$delta]['value']=$result1;
} elseif (!isset($node->field_value2[$delta]['value'])) {
$node_field_value2[$delta]['value']=$result2;
}
}
anyhow, it makes no sense to put this code into the multigroup - or does it ?
also, it doesnt fill any field, but thats maybe another issue..
->edit: ok, it works now, should have been $node->field_value1[.. instead of $node_field_value1[..
(field_category is a nodereference)
#30
I just applied both patches from #17. I have two decimal fields and a computed field in each multigroup. The computed field is setup to simply multiply the two other fields. The computed field shows up in the first instance of the multigroup, but if I add another, the computed field is a no show.
So it works ... kinda. Any help appreciated!