Skip to content

Entity Metadata Wrappers usage

Alejandro Cremaschi edited this page Mar 2, 2024 · 4 revisions
  • This module introduces a unique place for metadata about entity properties: hook_entity_property_info(), whereas hook_entity_property_info() may be placed in your module's {YOUR_MODULE}.info.inc include file. For details have a look at the API documentation, i.e. hook_entity_property_info() and at http://drupal.org/node/878876.

  • The information about entity properties contains the data type and callbacks for how to get and set the data of the property. That way the data of an entity can be easily re-used, e.g. to export it into other data formats like XML.

  • For making use of this information (metadata) the module provides some wrapper classes which ease getting and setting values. The wrapper supports chained usage for retrieving wrappers of entity properties, e.g. to get a node author's mail address one could use:

  $wrapper = entity_metadata_wrapper('node', $node);
  $wrapper->author->mail->value();

To update the user's mail address one could use

$wrapper->author->mail->set('sepp@example.com');

or

$wrapper->author->mail = 'sepp@example.com';

The wrappers always return the data as described in the property information, which may be retrieved directly via entity_plus_get_property_info() or from the wrapper:

$mail_info = $wrapper->author->mail->info();

In order to force getting a textual value sanitized for output one can use, e.g.

 `$wrapper->title->value(array('sanitize' => TRUE));`

to get the sanitized node title. When a property is already returned sanitized by default, like the node body, one possibly wants to get the not-sanitized data as it would appear in a browser for other use-cases. To do so one can enable the 'decode' option, which ensures for any sanitized data the tags are stripped and HTML entities are decoded before the property is returned:

 `$wrapper->body->value->value(array('decode' => TRUE));`

That way one always gets the data as shown to the user. However if you really want to get the raw, unprocessed value, even for sanitized textual data, you can do so via:

`$wrapper->body->value->raw();`

Additional examples of usage

This is a copy-paste of a forum question and answer.

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;