An Intro to Entity API

Blake Hall

a bit of history

  • Flexinode
  • CCK
  • Field API & Entities

terminology

  • Entity Type
  • Bundle
  • Property
  • Field
  • Entity

Entity Type

  • Node
  • User
  • Taxonomy

Bundle

  • Page
  • Article
  • Event

Property

  • id
  • vid
  • title
  • status
  • author

Field

  • Body
  • Image
  • Start Time
  • Room

Entity

Node

Article
id, vid, created
title, author

body
image
tags

Here comes the code

DrupalDefaultEntityController

class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
  /**
   * Constructor: sets basic variables.
   */
  public function __construct($entityType) {
    $this->entityType = $entityType;
    $this->entityInfo = entity_get_info($entityType);
    $this->entityCache = array();
    $this->hookLoadArguments = array();
    $this->idKey = $this->entityInfo['entity keys']['id'];

    // Check if the entity type supports revisions.
    if (!empty($this->entityInfo['entity keys']['revision'])) {
      $this->revisionKey = $this->entityInfo['entity keys']['revision'];
      $this->revisionTable = $this->entityInfo['revision table'];
    }
    else {
      $this->revisionKey = FALSE;
    }

    // Check if the entity type supports static caching of loaded entities.
    $this->cache = !empty($this->entityInfo['static cache']);
  }
}
          

interface DrupalEntityControllerInterface {

  public function __construct($entityType);

  public function resetCache(array $ids = NULL);

  public function load($ids = array(), $conditions = array());
}

          

Where's the rest?

Entity class

class Entity {
  /**
   * Creates a new entity.
   *
   * @see entity_create()
   */
  public function __construct(array $values = array(), $entityType = NULL) {
    if (empty($entityType)) {
      throw new Exception('Cannot create an instance of Entity without a specified entity type.');
    }
    $this->entityType = $entityType;
    $this->setUp();
    // Set initial values.
    foreach ($values as $key => $value) {
      $this->$key = $value;
    }
  }
}
          
Entity controller class

interface EntityAPIControllerInterface extends DrupalEntityControllerInterface {

  public function delete($ids);

  public function invoke($hook, $entity);

  public function save($entity);

  public function create(array $values = array());

  public function export($entity, $prefix = '');

  public function import($export);

  public function buildContent($entity, $view_mode = 'full', $langcode = NULL);

  public function view($entities, $view_mode = 'full', $langcode = NULL, $page = NULL);
}
          

Coder Basics

https://github.com/Lullabot/entity-api-demos

hook_entity_info()


function videoentity_entity_info() {
  $info = array();
  // Our custom video entity needs to be defined here.
  // See http://drupal.org/node/1026420 and http://drupal.org/node/878804
  // for more documentation.
  $info['video'] = array(
    // Human readable label.
    'label' => t('Video'),
    // Table for storing entity data, defined in hook_schema().
    'base table' => 'videoentity_video',
    // This helps Entity API know how to query your custom table.
    'entity keys' => array(
      'id' => 'id',
      'label' => 'name',
    ),
   'bundles' => array(
      'video' => array(
        'label' => t('Video'),
        'admin' => array(
          'path' => 'admin/videoentity',
          'access arguments' => array('administer video'),
        ),
      ),
    ),
    // This is a uri function provided by the Entity contrib module.
    // It's a simple wrapper around the uri method in the controller class.
    'uri callback' => 'entity_class_uri',
    // These are the default controllers.
    // 'entity class' => 'Entity',
    'entity class' => 'VideoEntity',
    // 'controller class' => 'DrupalDefaultEntityController',
    // Other options provided by the EntityAPI contrib module:
    // 'controller class' => 'EntityAPIController ',
    // 'controller class' => 'EntityAPIControllerExportable',
    'controller class' => 'VideoEntityController',
     // The information below is used to extend the EntityDefaultUIController
     'admin ui' => array(
       'path' => 'admin/videoentity',
       'controller class' => 'VideoEntityUIController',
       'menu wildcard' => '%videoentity',
       'file' => 'videoentity.admin.inc',
     ),
     'module' => 'videoentity',
     // Access callback to determine permisisons.
     'access callback' => 'videoentity_access_callback',
 );

  return $info;
}
          

hook_entity_property_info()


function file_entity_entity_property_info() {
  $info['file']['properties']['type'] = array(
    'label' => t('File type'),
    'type' => 'token',
    'description' => t('The type of the file.'),
    'setter callback' => 'entity_property_verbatim_set',
    'setter permission' => 'administer files',
    'options list' => 'file_entity_type_get_names',
    'required' => TRUE,
    'schema field' => 'type',
  );

  return $info;
}
          

Fieldable


function videoentity_entity_info() {
  $info = array();
  // Our custom video entity needs to be defined here.
  // See http://drupal.org/node/1026420 and http://drupal.org/node/878804
  // for more documentation.
  $info['video'] = array(
    // Tell FieldAPI that fields can be attached to our video entity
     'fieldable' => TRUE,
    'views controller class' => 'EntityDefaultViewsController',
  );

  return $info;
}
          

Views Support


function videoentity_entity_info() {
  $info = array();
  // Our custom video entity needs to be defined here.
  // See http://drupal.org/node/1026420 and http://drupal.org/node/878804
  // for more documentation.
  $info['video'] = array(
    'views controller class' => 'EntityDefaultViewsController',
  );

  return $info;
}
          

Exportability

https://drupal.org/node/1021526


function videoentity_entity_info() {
  $info = array();
    'exportable' => TRUE,
  );
  return $info;
}
          

Revisions


$entity->is_new_revision = TRUE;
          

Entity Metadata Wrappers

https://drupal.org/node/1021556


$node->field_number[LANGUAGE_NONE][0]['value'];

$wrapper = entity_metadata_wrapper('node', $node);
$wrapper->field_number->value();

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

Entities in Contrib

File Entity
Media
Commerce
Organic Groups
Examples
Entity Operations
Entity Construction Kit

Q&A