Previously, @argiepiano told me about entity metadata wrappers being a great way to get at node data / fields. I am now wanting to use them to do some (hopefully) automatic updates to some saved nodes and have a couple more questions. I did read the info at the Entity Plus module Wiki but didn't see the answers there.

1. What does it return if a field value isn't set?

2. How to set values for multivalued fields? Looking at the return value for such a field (as an array) I am wondering if I can just assign the array value to it, like this:

$wrapper->field_name = $my_array;

3. How about for entity reference (taxonomy) fields? In this case, would I be assigning to something like this:

$wrapper->field_name->tid = $my_value;

ETA:

4. And what if the entity reference field in #3 can have multiple values? Plus, do I need to check that the new value is not a duplicate?

Thanks!

Accepted answer

Hi @leeksoup. Glad to hear you find EMW useful. I use them all the time.

1. What does it return if a field value isn't set?

Running $wrapper->field_my_field->value() returns empty if the field has cardinality == 1, or an empty array if the cardinality > 1 or unlimited. 

If you try to run $wrapper->field_my_field->value() and the field doesn't exist in the node or entity, then you get a fatal error. So, if you are not sure if the field exists, it's a good idea to do if(isset($wrapper->field_my_field)) {} isset will check if the field exists in the entity.

2. How to set values for multivalued fields? Looking at the return value for such a field (as an array) I am wondering if I can just assign the array value to it, like this: $wrapper->field_name = $my_array;

Yes, you can do that. The array contains the values for each item of a multivalue field. Or you can do this:

$wrapper->field_name[$delta] = $my_value;

Where $delta is the delta of the multivalue field. BTW, to get the value you can also do $wrapper->field_name[$delta]->value() and you'll get the value stored in that delta.

3. How about for entity reference (taxonomy) fields? In this case, would I be assigning to something like this: $wrapper->field_name->tid = $my_value;

No. The beauty of EMW is that you don't need to worry about the column name (tid), so the right way is:

$wrapper->field_term_reference = $my_value;

Where $my_value is the TID (numerical). But you can also assign a fully loaded term! So this would work too:

$term = taxonomy_term_load(2);
$wrapper->field_term_reference = $term;

Same thing for entity reference fields.

4. And what if the entity reference field in #3 can have multiple values?

If it's a multivalue entity reference, you can do, for example:

$target_ids = array(2, 4, 8);
$wrapper->field_entity_references = $target_ids;

OR

$wrapper->field_entity_references[0] = 2;
$wrapper->field_entity_references[1] = 4;
$wrapper->field_entity_references[2] = 8;

Or even assign a fully loaded array of entities instead of the entity IDs.

Plus, do I need to check that the new value is not a duplicate?

Yes, you do. I often do this

$target_ids = $wrapper->field_entity_references->raw(); // the method "raw()" will give me an array of target IDs, rather than an array of fully loaded entities
$target_ids[] = $my_new_value;
$target_ids = array_unique($target_ids); // This will assure there are no duplicate ids.
$wrapper->field_entity_references = $target_ids;

 

Comments

Hi @leeksoup. Glad to hear you find EMW useful. I use them all the time.

1. What does it return if a field value isn't set?

Running $wrapper->field_my_field->value() returns empty if the field has cardinality == 1, or an empty array if the cardinality > 1 or unlimited. 

If you try to run $wrapper->field_my_field->value() and the field doesn't exist in the node or entity, then you get a fatal error. So, if you are not sure if the field exists, it's a good idea to do if(isset($wrapper->field_my_field)) {} isset will check if the field exists in the entity.

2. How to set values for multivalued fields? Looking at the return value for such a field (as an array) I am wondering if I can just assign the array value to it, like this: $wrapper->field_name = $my_array;

Yes, you can do that. The array contains the values for each item of a multivalue field. Or you can do this:

$wrapper->field_name[$delta] = $my_value;

Where $delta is the delta of the multivalue field. BTW, to get the value you can also do $wrapper->field_name[$delta]->value() and you'll get the value stored in that delta.

3. How about for entity reference (taxonomy) fields? In this case, would I be assigning to something like this: $wrapper->field_name->tid = $my_value;

No. The beauty of EMW is that you don't need to worry about the column name (tid), so the right way is:

$wrapper->field_term_reference = $my_value;

Where $my_value is the TID (numerical). But you can also assign a fully loaded term! So this would work too:

$term = taxonomy_term_load(2);
$wrapper->field_term_reference = $term;

Same thing for entity reference fields.

4. And what if the entity reference field in #3 can have multiple values?

If it's a multivalue entity reference, you can do, for example:

$target_ids = array(2, 4, 8);
$wrapper->field_entity_references = $target_ids;

OR

$wrapper->field_entity_references[0] = 2;
$wrapper->field_entity_references[1] = 4;
$wrapper->field_entity_references[2] = 8;

Or even assign a fully loaded array of entities instead of the entity IDs.

Plus, do I need to check that the new value is not a duplicate?

Yes, you do. I often do this

$target_ids = $wrapper->field_entity_references->raw(); // the method "raw()" will give me an array of target IDs, rather than an array of fully loaded entities
$target_ids[] = $my_new_value;
$target_ids = array_unique($target_ids); // This will assure there are no duplicate ids.
$wrapper->field_entity_references = $target_ids;

 

Wonderful! Thank you so much, @argiepiano!

It would be great to add your answers to the module docs, too. :)