What is the purpose of the entity_metadata_wrapper() function, and why should I use it? I seem to be developing add-ons to a lot of modules that use Entity API at the moment, and the entity_metadata_wrapper() function keeps on popping up.

The docs page says this about it:


  Returns a property wrapper for the given data.
  
  If an entity is wrapped, the wrapper can be used to retrieve further wrappers for the entitity properties.


Ignoring the wonderfully Freudian spelling of the word 'entity' in there, I don't really understand what the purpose of these wrappers is.

I understand that the function essentially returns a EntityDrupalWrapper class:


  The wrapper eases applying getter and setter callbacks of entity properties


But what I can't understand is how it makes things easier.

For example, to update the status property of a node I could use this code:

$node = node_load($nid);
$node-&gt;status = 1;
node_save($node);


That's pretty clean. As I understand it (but may be wrong) the equivalent code using entity_metadata_wrapper() would be more verbose than that.

I'm not sure if it's simply the use of the term 'wrapper' that's tripping me up here, but I've looked through the code in the Entity module too and I'm not really any closer to understanding it.

Is anyone able to explain what the benefits of using this function are, and perhaps provide a simple code example for a common use-case?
Yes, changing the status of a node is trivial, as that is a hardcoded property.

Fields on the other hand, are much more complicated. They are nested three levels deep, while there is field_get_items() to get them in the correct language, there is no such function for setting field values. So, you always need to check whether a field is translatable or not and you need know which property exactly contains the values you're looking for/want to set.

Two examples, that show what the entity wrapper can do:


The following line adds the commerce line item to the order, taking care of the language and the actual property that holds the reference id, taken from the following answer https://drupal.stackexchange.com/a/23513/31

$order_wrapper-&gt;commerce_line_items[] = $line_item;

In a similar way, being able to directly access a value of a field, without having to check the language, or the delta, even being able to directly access referenced entities, taken from https://drupal.stackexchange.com/a/33010/31

$subnode = entity_metadata_wrapper('node', $node)-&gt;field_subnode-&gt;value();
$default = $subnode-&gt;title;



The entity wrapper is the driving force behind flexible, powerful modules like Search API and Rules as it allows them to work their way through multiple levels of references, so that you can e.g. access a field of the product a user bought in an order with something like [commerce-order:commerce-line-items:0:commerce-product:some-field] (might not actually be correct, but something like that), or add the body summary of a referenced node to your search index.

That said, I'm not necessarly fond of the actual API of the wrapper, it's huge internal arrays and that even simple properties are again wrapper classes. I hope that the improved entity (and hopefully field) system in Drupal 8 will remove the need for such a wrapper thanks to having classed entities.