Community Documentation

Entity metadata wrappers

Last updated April 16, 2013. Created by fago on January 10, 2011.
Edited by a.milkovsky, eojthebrave, alesr, tripper54. Log in to edit this page.

The Entity API provides wrapper classes you may use to make dealing with the values of an entities properties and fields easier. Wrappers make it easier to get and set the values of fields and properties as well as to programmatically retrieve additional information about these elements and iterate over lists of values in a consistent manner.

For example consider the following method of accessing the value of a field attached to a node. This is a pattern that we see used often when working with entities in Drupal. However there are a couple of things that make this less than ideal. For example what if the user had requested the page in a different language? Or what about the case where the ['value'] key just doesn't exist like with image and file fields?

<?php
$node
->field_number[LANGUAGE_NONE][0]['value']
?>

Using metadata wrappers from the entity module we can access this information like so:

<?php
$node_wrapper
->field_number->value();
?>

How about an example of making things consistent? All Drupal entities have a label of some sort. A string that can be treated as the canonical human readable name of an entity. Nodes all have a title property and user accounts all have a name property. Given a standard Drupal entity it can be hard to know which property should be treated as the label. Metadata wrappers provide us with a consistent way of getting at this kind of information for any entity.

<?php
$wrapper
->id->value();
$wrapper->label->value();
$wrapper->type->value();
?>

Examples taken from the README

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_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();

Many more examples can be found in the tests.

Working with lists

A list value that contains wrappers, such as a multi-valued reference field, can be iterated over thus:

<?php
  $wrapper
= entity_metadata_wrapper('node', $node);
  foreach (
$wrapper->field_taxonomy_terms->getIterator() as $delta => $term_wrapper) {
   
// $term_wrapper may now be accessed as a taxonomy term wrapper.
   
$label = $term_wrapper->label->value();
  }
?>

Deleting values

To delete values, there is no ->delete() method on the fields. You have to use this way to correctly delete a value:

<?php
// Using an empty ->set() removes the value
$wrapper->field_data->set();

// And handles correctly the deltas when using multiple values fields
$wrapper->field_data[$delta]->set();
?>

Introspecting wrappers

To get a list of all available properties of a(n) (entity)wrapper, you can use the following snippet (requires the devel module to be installed and enabled):

<?php
dpm
($wrapper->getPropertyInfo());
?>

Example of using value(), set() and save()

<?php
$node_wrapper
= entity_metadata_wrapper('node', $node);
$var = $node_wrapper->field_number->value() + 1;
$node_wrapper->field_number->set($var);
$node_wrapper->save();
?>

Get first value of multifield (multiple-value field)

Just set value index directly after field name:

<?php
$first_name
= $wrapper->field_tags[0]->name->value();
?>

Comments

Example for list<node>

I would love to see an example of saving a list of nodes (list).

Is it something like this?

<?php
$wrapper
= entity_metadata_wrapper('myEntity', $myEntity);

$node1 = new StdClass;
node_object_prepare($node1);
$node1->title = 'Node 1';
// ...

$node2 = new StdClass;
node_object_prepare($node2);
$node2->title = 'Node 2';
// ...

$wrapper->myProperty->value(array($node1, $node2));
?>

Here's a list of example uses

Here's a list of example uses from entity.test

$wrapper->author = 0;
$wrapper->url = 'dummy';
$wrapper->author->mail = 'foo';
$wrapper->author = NULL;
$wrapper->author->set($GLOBALS['user']->uid);
$wrapper->author->set($GLOBALS['user']);
$wrapper->body->set(array('value' => "<b>The second body.</b>"));
$wrapper->language('de');
$wrapper->body->set(array('value' => "<b>Der zweite Text.</b>"));
$wrapper->language(LANGUAGE_NONE);
$wrapper->set($node);
$wrapper->reference->name->set('foo');
$wrapper->reference->set($wrapper);
$wrapper->save();
$wrapper->delete();
$wrapper->type->set('article');
$wrapper->author = $user->uid;
$wrapper->{$property}[0] = '2009-10-05';
$wrapper->field_image = array('fid' => $file->fid);
$wrapper->$name->value();
$wrapper->parent[] = $term_parent2;
$wrapper->field_tags[1] = $term_parent;
$wrapper->field_tags->set(array(2));
$wrapper->field_tags = NULL;
$wrapper->$field_name->set(NULL);
$wrapper->field_text[0] = 'the text';
$wrapper->field_text[0]->set(array('value' => "<b>The second body.</b>"));
$wrapper->field_text2->summary = 'the summary';
$wrapper->field_text2->value = 'the text';
$wrapper->field_file[0] = array('fid' => $file->fid, 'display' => FALSE);
$wrapper->field_file[0]->description = 'foo';
$wrapper->field_file[0]->display = TRUE;
$wrapper->field_file[1]->file = $file;
$wrapper->field_file[] = array('description' => 'test');
$wrapper->field_file = NULL;
$wrapper->field_image = array('fid' => $file->fid);
$wrapper->field_image->alt = 'foo';
$wrapper->field_image->file = $file;
$wrapper->field_image = array();

^^ Generated via:
# grep "^\W*\$wrapper->" entity/entity.test | tr -s " "

For taxonomy terms

If you need to use the wrapper on taxonomy terms you should use:

$wrapper = entity_metadata_wrapper('taxonomy_term', $term);

I couldn't find a list of valid values for the $type property.

Look for hook_entity_info()

Look for hook_entity_info() implementations to find out the name.

For example, about the taxonomy module, this command shows the entity type:

$ cat taxonomy.module | awk '/function taxonomy_entity_info()/{getline; getline; print}'
   'taxonomy_term' => array(
$

Since the type is always two lines after the function declaration, getline is used twice.

Using this way, you can see all the entity types availables in core with the right regex:

$ cd modules/
$ find . -name '*.module' -print | xargs cat | awk '/_entity_info\(\) {$/ {getline; getline; print}'
    'user' => array(
    'comment' => array(
    'node' => array(
    'file' => array(
    'entity_cache_test' => array(
    'taxonomy_term' => array(
$

Now, what's entity_cache_test? I have no idea :-)

while accessing entity reference fields..

hi...

just a small suggestion : I have observed that value() is supported only in case of simple properties like integer, text etc.. But if u have Taxonomy or Node Reference or User Entity Reference field and typically if u want to compare IDs then you can use raw(). Use label() if u want readable code than using IDs..

I used it like this :

$thenode = entity_metadata_wrapper('user', 3);
if ( $thenode->field_rank->label() == 'Active Distributor')
    {/*lights camera action..*/}

**Lot of useful functions available in entity.wrapper.inc

Ananya MultiTech Private Limited.

Taxonomies

Hey,

Does somebody have more documentation about how to work with taxonomies? I use several term reference fields in the user profile / account settings. Some allow multiple values. I am trying to programmatically adjust these terms. I use the wrapper to load the user entity:
$data = entity_metadata_wrapper('user', $user);

If it is a single-value field, I assume
$data->field_term_reference_field = 23;
would overwrite any existing tag with the tid 23.

How does it work if is is a multi-value field?

Can I just add multiple tags like this?
$data->field_term_reference_field = 23;
$data->field_term_reference_field = 43;
$data->field_term_reference_field = 51;

Is there a way to clear all terms in a given vocabulary for the given user, e.g. get rid of all existing tags and set a new one like this:
$data->field_term_reference_field->clear();
$data->field_term_reference_field = 23;
Or do I have to iterate through all tags for the user and clear the all individually?

Thanks.

I just figured out: $tag

I just figured out:

$tag contains the tid.

<?php
$wrapper
= entity_metadata_wrapper('node', $entity);
foreach (
$random_tags as $i => $tag) {
 
$wrapper->field_tags[$i] = $tag;
}
$wrapper->save();
?>

Entity Metadata Wrappers and AJAX

Just a general question about using entity metadata wrappers with ajax:

When setting and saving fields of an entity through the entity metadata wrapper, does the value get updated between ajax calls or is it being done when the entire page gets reloaded?

The reason I'm asking is that I have a situation where if I set the values of fields directly on the entity it's being stored between my calls. If I do it via the wrapper ( $wrapper->field->set('value'); $wrapper->save(); ) it reverts back to the original value.

Am I posing a relevant question or am I doing something wrong in my code?

Thanks