23

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->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?

  • This may add a deeper understanding to the entity api and wrappers. It is a talk by Fago, the Entity guy. wolfgangziegler.net/drupalcon-denver – Ken Jun 11 '12 at 21:46
  • Thanks, that sounds really useful from the opening gambit. I'll give it a look over when I've got some time – Clive Jun 11 '12 at 21:55
  • That "video has been removed from blip" but the slides still download. – artfulrobot Mar 6 '15 at 9:29
23
+50

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->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)->field_subnode->value();
    $default = $subnode->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.

  • Brilliant, I knew I'd just missed something with this. I think it was the description of the EntityDrupalWrapper that caused the confusion; when it mentioned 'properties' I didn't realise fields were involved at all, I just thought it literally meant the class took care of properties (nid, status, etc). Thanks for the clearing that up, knowing that the Rules module uses it for the data selector makes it make a lot more sense – Clive Jun 7 '12 at 19:41
  • @Berdir "I'm not necessarly fond of the actual API of the wrapper..." I have the same feelings as you. Do you do anything to combat this? Do you use field_view_value() to view values? How would you recommend setting values in custom callbacks for a custom workflow or dashboard? – Charlie Schliesser Aug 7 '12 at 17:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.