Drupal entities - part2

May 31, 2013

Finally had a chance last week to complete some research on Entities. Drupalize.me had put up the last of there screencasts, so sat down, and got to work. Initially, there was nothing particular new or crazy, it discussed 'view modes' which are very useful, but used everywhere else in Drupal, so not a new concept. But then we jumped into some more interesting areas, some of which are very useful outside of custom entities (metadata wrappers).

Entity UI Controller

Main point to make here is brief, but as with all things entity, the online documentation is a little weak, but the comments in the code are excellent, so long as you know where to look. This next piece of docs are found in /entity/includes/entity.ui.inc. The main purpose of this controller is for editing labels, and some functionality. Simply extend the class you want, then copy the functions out, replacing what you need in the copy.

For example, on the UI admin page, you have a table, this would be how you go about editing column one to say 'name' rather than 'label'.

Entity Property Info.

This next piece will giv you the ability to edit how Drupal uses the entities property data. For example, when we add our item, we may insert a date timestamp, by default this is saved into the DB as an int, and so Drupal will treat it as such. The hook_entity_property_info() functionality will allow us to tell Drupal that this data is a timestamp, which will be used by display modes, and Views fields.

For more information on this, as usual, we look in the code (entity.api.php line:372). But also, if you are after an example, take a look in entity/modules/xxxx

Metadata Wrappers

This is the fun part, since early Drupal, we always traversed arrays to get out field variables out, and in Drupal 7, we had a habit of continuing this method, even in the messier looking objects. This is not required it would seem, as it's an object, there are some quite sexy functions you can use to pull things out, meaning you don't have to know the language (usually 'und' or undefined). There is a page online called Entity Metadata Wrappers which is useful, as well as the README.txt in entity module or /includes/entity.wrapper.inc.

But the general jist of things is that instead of:

$node->field_name['und'][0]['value']

You can use something like:

$node_wrapper = entity_metadata_wrapper('node', $node);$node_wrapper->field_name->value();

Whilst this appears longer, it is cleaner, and much more reliable, especially when working on a multilingual site. Also, it's just a lot easier to read by new developers, or if you are returning to a project. It has a lot more capabilities than this though, these are all documented in the readme.txt file, but they are things like:

  • value() = get data
  • author->mail->value() = gets the author of this entities email address
  • author->mail->set('xxxxx')
  • value(array('sanitized' => TRUE))
  • value->raw()
  • $node_wrapper->getPropertyInfo() = shows a list of all the information you can pull out of the item easily
  • Another handy little point is that you can use this in foreach loops nicely, for example:
    foreach($node_wrapper->field_tags->setIterator() as $tag){  print $tag->name->value();}
  • $entity->label = gets the items label, this should work even if the label variable name has been changed

Entity Revisions

Adding the revision capabilities was an important addition in my opinion. They are so very useful, and less optional once you start to understand why people like CMS'. To add this ability to your custom entity though, you have to make a few tweaks, as it's not something which comes for free:

  • Alter the .install file to add in a revision table
    • Add revisionID to both tables
    • Add ID to new revision table (set from serial to int)
    • set revisionID as a primary key on the new table
  • Add 'revision table' => 'entity_revision' to hook_entity_info
  • If you modified extend EntityAPIController then you will need to add the line $entity->is_new_revision=TRUE

Sadly, whilst this should get revisions working for you, you wont really be able to use them. For that to happen you will need to build your own UI, listing all the revisions, and allowing you the opportunity to 'revert to' one of them.