Entity API

 

[My other notes from DrupalCon Denver]

Which entities are there?

In core, comments, nodes, user accounts, taxonomy terms, feeds.

In addition, contrib modules can define entity types. Modules that define their own entities include Drupal Commerce, Organic groups, Profile2, Heartbeat and Message, and File entity.

With Drupal 7, there is a shift from node-centric modules to entity-centric modules. This is the future for Drupal.

What is the Entity API for?

The entity API is a unified way to access the data of Drupal. This way, modules can easily make use of it. Solution modules such as Group or Vote can use the entity API to access user information, nodes, profiles, products... any data type that is exposed as an entity.

With Drupal core, you can entity_load() and entity_get_info(); the Entity API module adds more helper functions that allow you to create, access, delete, metadata-wrap, and perform other interactions with entities. For example:

$wrapper = entity_metadata_wrapper('node', $nid);

$mail = $wrapper->author->mail->value();
$wrapper->author->mail->set('fago@example.com');

You can also use property info to fetch an array of key/value pairs.

To Provide an Entity Type:

  • Implement hook_entity_info()
  • Specify your controller class
  • implement hook_schema()

Once these are defined, the entity is active. The entity property information is generated from the database schema, but it is incomplete and you really should complement it. You can specify that each piece of data specifies a node, for example, or a date.

The views integration controller provides fully-featured views integration; once you have specified the entity information, it will automatically generate relationships to the other entities for you.

The entity token modules, when enabled, provides a ton of tokens for free; the Rules module has control for saving and using tokens. Finally, any additional contrib module will be able to use the Entity API to access your data.

Exportable entities

You may know the concept of exportables from ctools. It's a way to manage the data so that you can export the data into code, put it into your module, and use versioning (e.g. git) to manage it.

With the entity API you can easily make use of exportables. Improved upon ctools, there is a unified CRUD interface, it is synced to the DB, there are regular CRUD hooks and it integrates with views, tokens, features, and i18n.

Example

Profile2 is an entity type, and profile2 types are:

  • entity type
  • bundle of profile2
  • exportable

The job of Profile2 is to take care of permissions, access, the profile form, and the display of the data. It may be useful to have some general defaults that you can build from, but we do not have that currently.

Entity API works with database-based items, but it can also work with NoSQL controllers, Doctrine, and PHPCR. You could, if you wanted, impement remote entities to display data from one site on another Drupal site. Another example: you can use the entity API for data integration. Basically, you just need to write the storage controller.

Once you're providing non-DB based entities, everything works the same way, except instead of specifying the database schema, you'll specify the storage information. You'll still get working views, rules and tokens support, as well as all the other modules which work off the Entity API information.

What does it buy us?

You get a classed CRUD api (which allows you, for example, to use memcache to cache your entity data,) CRUD hooks, tokens, entity reference, rules (which will "just work") and rules links, and integration with all the other entity API-supported contrib modules.

It's not required for entities to have Integer IDs; it's not. It's only required when the entity is fieldable. Some content modules do assume that the ID will be an integer, however, so you may run into some bugs with contrib modules.

Room for Improvement

  • Better views support based on the Entity Field Query. There is already a module for this which is being updated. Once we have this, you could implement filter support rather easily.
  • Read-only mode. It's possible for an entity to be read-only.
  • Generated display. It would be nice if the entity could provide some way to simply display the entity based on the property information.

Drupal 8 Entity API

For Drupal 8, there's quite a bit of work that has to be done. We already have an API and a full CRUD storage controller in core. The way that the entity interface works in Drupal 8 is very similar to the way it works in Drupal 7. We have helper functions like entity_delete_multiple(), which is already in core. To do this, we have classes and a common storage controller in Drupal core, as well as an entity database storage controller.

For example, for comments, we have:

class Comment extends Entity

Questions

Q: What about a controller to generate an entity form?
A: That's still on the roadmap. It's something that we would like to see, but we don't know if we have time to get it into Drupal 8.

Q: Is there a way to preserve API calls?
A: As of now it has no support for that, because you'd need an API for that. You could do it yourself in the views integration. It's something you have to take care of manually as of now. You could implement a views handler that stores things in memory.

Q: What about revision support?
A: Yes, that's the plan. We already have revisions in nodes, and the plan is to make that general functionality that is implemented in the controller.

Did you enjoy this post? Please spread the word.