Working with the Entity API

Last updated on
19 March 2017

Covers

  • generic entity API
  • configuration entity
  • content entity

More specific API's will be covered in specific chapters. TODO: Link once created.

Check

// Make sure that an object is an entity.
if ($object instanceof \Drupal\Core\Entity\EntityInterface) {
}

// Make sure it's a content entity.
if ($entity instanceof \Drupal\Core\Entity\ContentEntityInterface) {
}

// Get the entity type.
$entity->getEntityTypeId();

// Make sure it's a node.
if ($entity instanceof \Drupal\node\NodeInterface) {
}

// Using entityType() works better when the needed entity type is dynamic.
$needed_type = 'node';
if ($entity->getEntityTypeId() == $needed_type) {
}

Get information from an entity/ Entity methods

A number of generic methods are available to get information from an entity, like the ID, bundle, revision ID and so on. See the documentation on the EntityInterface for details.

// Get the ID.
$entity->id();

// Get the bundle.
$entity->bundle();

// Check if the entity is new.
$entity->isNew();

// Get the label of an entity. Replacement for entity_label().
$entity->label().

// Get the URI for an entity.
// @todo: This might still change with the new URI template API.
$entity->uri();

// Create a duplicate that can be saved as a new entity.
$duplicate = $entity->createDuplicate();

Create

// Use the procedural wrapper.
$node = entity_create('node', array(
  'title' => 'My node',
  'body' => 'The body content. This just works like this due to the new Entity Field
          API. It will be assigned as the value of the first field item in the
          default language.',
));

// Or you can use the static create() method if you know
// the entity class::
$node = Node::create(array('title' => 'The node title'));

// Use the entity manager.
$node = \Drupal::entityTypeManager()->getStorage('node')->create(array('type' => 'article', 'title' => 'Another node'));

Settings defaults from the field type annotation are only added for missing top level keys, no deep merge is performed.

Load

// Use the static method
$node = Node::load(1);

// Dynamic entity type, entity_load() now loads a single entity, the 7.x entity_load() has been renamed to entity_load_multiple().
$entity = entity_load($entity_type, $id);

// Using the storage controller.
$entity = \Drupal::entityTypeManager()->getStorage($entity_type)->load(1);

// Load multiple entities, also exists as entity_load_multiple().
$entities = \Drupal::entityTypeManager()->getStorage($entity_type)->loadMultiple(array(1, 2, 3));

// Load entities by their property values.
$entities = \Drupal::entityTypeManager()->getStorage('node')->loadByProperties(array('type' => 'article'));

To update an entity, load it and then save it with your changes.

Save

// To save an entity.
$entity->save();

That works for both new and existing entities, the entity itself keeps track whether it's new or not. By default, for content entities, that depends on whether it has an ID or not. To save an entity that has an entity as a new entity (e.g, when importing something), the isNew flag can be enforced.

// The following will attempt to insert a new node with the ID 5, this will fail if that node already exists.
$node->nid->value = 5;
$node->enforceIsNew(TRUE);
$node->save()

Delete

// Delete a single entity.
$entity = \Drupal::entityTypeManager()->getStorage('node')->load(1);
$entity->delete();

// Delete multiple entities at once.
\Drupal::entityTypeManager()->getStorage($entity_type)->delete(array($id1 => $entity1, $id2 => $entity2));

Access control

The access() method can be used to check who can do what with an entity. The method supports different operations, the standard operations are view, update, delete and create, create is a somewhat special, see below.

Access checks are forwarded to the access controller. (TODO: Add link)

// Check view access of an entity.
// This defaults to check access for the currently logged in user.
if ($entity->access('view')) {

}

// Check if a given user can delete an entity.
if ($entity->access('delete', $account)) {

}

When checking create access, there is usually no entity yet. Creating one just to check if someone would be able to create it, is a costly operation. Therefore, create access for those should be checked directly on the access controller.

\Drupal::entityTypeManager()->getAccessController('node')->createAccess('article');

If there is already an entity, $entity->access('create') works too, which just forwards to the createAccess() method, the same way other operations forward to the access() method on the access controller.

NOTE: Some online guides use \Drupal::entityManager(), but it is deprecated in 8.x it will be removed in 9.x. So you can use \Drupal::entityTypeManager() instead of \Drupal::entityManager().