I have a field collection on a custom content type and I'd like to add up the values of all the instances of one field within the field collection. The normal way to reference fields doesn't seem to work when they're in a collection.

For instance, say I had a "widget" field collection (field_widget) with two fields - widget name (field_wname) and widget quantity (field_wquantity).

How would I reference the widget quantity field in my computed field php in order to add up all the quantities of widgets to get a total number of all types of widgets?

Comments

Murz’s picture

Expiring same problem, subscribe to this issue.

RobW’s picture

Since a computed field uses php just like a theme, I believe you should be able to use entity_load() or an entity API wrapper.

Thomas_M’s picture

Having the same problem and am stuck here.
Trying to use values from field_collection fields in presave. How can I access them?

Can you give an example?

Thomas_M’s picture

ok, got it

Here I have a custom content type ($node) with a field collection "field_field_collection_item".
The field collection has two fields: "foo" and "bar".
To keep it easy, foo and bar don't have multiple entries.


<?php

		/*
		 *  Get field_collection_item ids saved in the "field_field_collection_item" field of custom content type ($node).
		 */
		
		$field_collection_items = field_get_items('node', $node, 'field_field_collection_item');
		$field_collection_item_ids = array();
		$i = 0;
		foreach ($field_collection_items as $field_collection_item){
			$field_collection_item_ids[$i] = $field_collection_item['value'];
			$i++;
		}
		
		
		/*
		 *  load the content of field_collection_items fields "foo" and "bar"
		 */
		
		
		$field_collection_item_fields = entity_load('field_collection_item', $field_collection_item_ids);
		$foo_fields = array();
		$bar_fields = array();
		$i = 0;
		foreach ($field_collection_item_fields as $field_collection_item_field){
			$foo_fields[$i] = field_get_items('field_collection_item', $field_collection_item_field, 'field_foo');
			$bar_fields[$i] = field_get_items('field_collection_item', $field_collection_item_field, 'field_bar');
			$i++;
		}
		
		
		/*
		 *  getting the the values for each foo and bar (delta = 0)
		 */
		
		$foos= array();
		$i = 0;
		foreach ($foo_fields as $foo_field){
			$foos[$i] = $foo_field[0]['value'];
			$i++;
		}
		
		$bars= array();
		$i = 0;
		foreach ($bar_fields as $bar_field){
			$bars[$i] = $bar_field[0]['value'];
			$i++;
		}

?>
Yuri’s picture

I am just wondering if other people than the #4 poster succeeded in getting a working 'total' field for the field collection's price field items. I tried the code in $4 but the calculated field shows me nothing.

Also, maybe there are some other D7 functions that make the the #4 code shorter.

stevebab’s picture

This also works for fields with single values:

$wrapper = entity_metadata_wrapper($entity_type, $entity);
$foo = $wrapper->field_collection->field_item_foo->value();
tvphong’s picture

How to reference field collection fields in a computed field without any code. Please help

dmouse’s picture

for multiple value

$wrapper = entity_metadata_wrapper($entity_type, $entity);
foreach($wrapper->field_collections as $collection)
   $sum += $collection->field_integer->value();
danon1981’s picture

#8 works great, nice and short code and exactly the code snippet I was looking for. Only problem is that it throws and error for every field I use it on.

Notice: Undefined variable: sum in eval() (line 4 of /Applications/MAMP/htdocs/sitename/sites/all/modules/computed_field/computed_field.module(466) : eval()'d code).

Jonny_Orange’s picture

This worked for me

<?php

	$wrapper = entity_metadata_wrapper($entity_type, $entity);
	foreach($wrapper->YOUR_FC_COLLECTION as $collection) {
			$time = $collection->YOUR_FC_FIELD->value();
			$sum += hoursToMinutes($time);			
	}
	$entity_field[0]['value'] =  minutesToHours(($sum));

?>
danon1981’s picture

I solved the error by using
i Thought i solved this error by using:

$sum += $collection->YOUR_FC_FIELD->['value'];

instead of

$sum += $collection->YOUR_FC_FIELD->value();

The complete code now looks like this

$wrapper = entity_metadata_wrapper($entity_type, $entity);
foreach($wrapper->YOUR_FC_COLLECTION as $collection) {
   $sum += $collection->YOUR_FC_FIELD->['value'];
}

But it does not:)

dannygoh’s picture

<?php

// have you forgot to declare this var first?
$sum = 0;

$wrapper = entity_metadata_wrapper($entity_type, $entity);
foreach($wrapper->YOUR_FC_COLLECTION as $collection) {
   $sum += $collection->YOUR_FC_FIELD->value();
}

// see the result
dsm( $sum );

?>
W01F’s picture

How could I pull just the first value in a multiple value field?

My case is the user can input multiple pricings and I just need to pull out the first one they use as an example.

jmuzz’s picture

Issue summary: View changes
Status: Active » Fixed

@W0LF you should be able to use the array dereference operator. So in the above example replace the loop with $collection = $wrapper->YOUR_FC_COLLECTION[0] or the inner part with sum += $collection->YOUR_FC_FIELD[0]->value();

More details about how to use metadata wrappers can be found here:

https://drupal.org/node/1021556

It looks like people have found their solutions. I will set it to fixed.

Status: Fixed » Closed (fixed)

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

kaizerking’s picture

I have profile2 profile,
which has the filed collection field field_resume_xp, unlimted values,this field collection field has a field called field_duration this value is populated with computed field
This field collection aalso jas a term reference field with two terms term 1 and term 2

Now I have 2 fields in profile2 profile "field_total_duration_term1" and "field_total_duration_term2" I want the sum of all the "field_duration" values for term 1 in "field_total_duration_term1" field and sum of all the "field_duration" values for term 2 in "field_total_duration_term2" field
Simplyfy I want sum of term1 durations and sum of term2 durations separately computed and stored
how to get this?

kaizerking’s picture

Please ignore this it was a cache problem and hast to edit this post to update

daniel-san’s picture

@dannygoh your code in #12 was incredibly helpful and it helped me solve this issue on my site. Thank you for adding that to the conversation.

sachav’s picture

I have also been using the solution of posts #8/10 successfully for one "field collection".
Having created a second one with it's own computed field, although having added values for the FC when saving the user, it seems like it is looping an empty array.

I have two requirements on users:

  1. Membership periods
  2. Parents or guardian information

Both can have an unlimited number of instances, and are similar in setup. The first is a " Field Collection " (FC) with a " string list " and a " date ". The second is an FC with a " string list " and two other " text fields ".

I am making status fields for both fields using a computed field and entity wrapper.

$wrapper = entity_metadata_wrapper($entity_type, $entity);
foreach($wrapper->field_membership_type_periodical as $period) {
...
This one is working as expected and it loops over every "field_membership_type_periodical" FC added to the user, and I can use all other properties of this FC as expected.

When I do the same for the "field_parents_guardian" FC, although I have added items to the list, it doesn't iterate over it and if I dump the "field_parents_guardian->value() ", it says it is an empty array.

If I dump the whole wrapper object, I find it strange that the "field_membership_type_periodical" is dumped as:

[field_membership_type_periodical] => Array
                (
                    [und] => Array
                        (
                            [0] => Array
                                (
                                    [value] => 1
                                    [revision_id] => 1
                                )

                        )

                )

While the guardian field is dumped as:

[field_parents_guardian] => Array
                (
                    [und] => Array
                        (
                            [0] => Array
                                (
                                    [field_parents_guardian_type] => Array
                                        (
                                            [und] => Array
                                                (
                                                    [0] => Array
                                                        (
                                                            [value] => Vader
                                                        )

                                                )

                                        )

                                    [entity] => FieldCollectionItemEntity Object
                                        (
                                            [fieldInfo:protected] => 
                                            [hostEntity:protected] => 
                                            [hostEntityId:protected] => 
...

So the first one it seems, is merely a reference to the FC item, which it lazy loaded, while the second one seems to be having no reference information, but the object itself already loaded.

Both FC's have been setup in the same way and I can't find any major differences in their settings. What might cause this strange behaviour in structure and could it be the source of the "empty list issue"?

ebenfarnworth’s picture

Using @dannygoh's code in #12 I now get a green status message at the top of the saved content showing the sum of the fields I'm calculating with computed fields module (the value shown in the message is correct. However the computed field its self is always empty. I have the display for the computed field set to 'raw value, no display code'.

My computed field php looks like this:

$sum = 0;

$wrapper = entity_metadata_wrapper($entity_type, $entity);
foreach($wrapper->field_route_book as $collection) {
   $sum += $collection->field_points->value();
}

dsm( $sum );

My field collection is called: field_route_book
The field in the field collection is called: field_points

What am I doing wrong?

I have also tried setting the display for the computed field to 'plain text' and the display code as default:

$display_output = $entity_field_item['value'];
and then I tried this:
$display_output = $entity_metadata_wrapper_item['value'];
Still I get the sum showing up in the status message but the computed field its self stays empty.

ebenfarnworth’s picture

OK, I worked it out!

dsm( $sum ); sets the out put to be a status message. I changed it to:

$entity_field[0]['value'] = ($sum);

Now the field works correctly and the full code in my case looks like this:

$sum = 0;

$wrapper = entity_metadata_wrapper($entity_type, $entity);
foreach($wrapper->field_route_book as $collection) {
   $sum += $collection->field_points->value();
}

$entity_field[0]['value'] =  ($sum);
Yuri’s picture

Well done @ebenfarnworth, Thanks!