Transcript
Page 1: Entities in Drupal 7 & the Entity API

Entities in Drupal 7& the Entity API

#sfdug

March 11, 2013

JD Leonard (@drupal_jd)

ModernBizConsulting.com

Page 2: Entities in Drupal 7 & the Entity API

About Me

Computer science background Working with Drupal since 2006 Developer, architect, project manager Freelance through my business:

Modern Biz Consulting Focus on complex web application development

Page 3: Entities in Drupal 7 & the Entity API

Agenda

Ways we represent data in D6 vs D7 Entities, entity types, & bundles Fields (formerly CCK) The Entity API contrib module How (and why) to define a custom entity Using EntityFieldQuery Defining entity property info Leveraging the Entity Metadata Wrapper

Page 4: Entities in Drupal 7 & the Entity API

Poll

Who here is...

– Brand new to Drupal?

– A site builder?

– A module developer?

– On the business side of things? Who here has...

– Created a custom D7 entity?

– Not created a custom D7 entity?

Page 5: Entities in Drupal 7 & the Entity API

D6 Data

(Custom database table) User Comment File Taxonomy vocabulary Taxonomy term Node

– Page, Blog post, (custom content type)

Page 6: Entities in Drupal 7 & the Entity API

D7 Data

(Custom database table) Entity

– User

– Comment

– File

– Taxonomy vocabulary

– Taxonomy term

– Node• Page, Blog post, (custom content type)

(Custom entity type)

Page 7: Entities in Drupal 7 & the Entity API

Entity Types

Elemental building block for most important data in Drupal 7

Represents a concept or noun Different types store different data

– Generally in a single DB table

– Eg: Node• Title, body, created timestamp, etc.

– Eg: User• Username, created timestamp, last visit timestamp, etc.

Defined using hook_entity_info()

Page 8: Entities in Drupal 7 & the Entity API

Entity

Instance of an entity type Examples of entities from core:

– The user jdleonard with uid 80902

– The page “Drupal Rocks” with nid 44 Any entity can be loaded with entity_load()

– Eg: entity_load(‘node’, array(44, 65))• Returns an array with two nodes with nids 44 and 65

– Core provides some convenience wrappers• Eg: node_load() and user_load()

Page 9: Entities in Drupal 7 & the Entity API

Entity Bundles

Subtype of an entity Eg: Page and Blog post

– Two content types (bundles) of node entity type Not all entity types have more than one bundle

– Eg: User• No subtypes; concept stands on its own

Page 10: Entities in Drupal 7 & the Entity API

Why We Need Entity Bundles

Each entity type stores some data in a table

– We call these pieces of data “properties”

– Eg: node• Title, body, author (uid), created timestamp

• But not all nodes are created equal– Page may have data beyond that captured by node– Blog posts get tagged– We need fields!

Page 11: Entities in Drupal 7 & the Entity API

CCK: Content Construction Kit (D6)

Contrib module Store additional data per content (node) content type Eg: Fivestar

– Contrib module leveraging contrib CCK API

– Allows nodes to be rated (think 1-5 stars)

– Eg: let users rate pages or blog posts

Page 12: Entities in Drupal 7 & the Entity API

Fields (D7)

Core concept Store additional data per entity type Applies power of CCK to all entity types

– Not just nodes! Eg: Fivestar

– Contrib module leveraging core Field API

– Allows entities to be rated

– Eg: let users rate pages, blog posts, users, comments, custom entities

Page 13: Entities in Drupal 7 & the Entity API

Entities in Core vs Contrib

Entities are a Drupal 7 core concept Core provides the “Entity API”

– Functions and hooks to define and interact with entities, entity types, and entity bundles

Everything we've discussed so far is part of Drupal 7 core (no contrib modules necessary)

Not everything “made it into” core

– Thankfully there's the “Entity API” contrib module• (confusingly named)

Page 14: Entities in Drupal 7 & the Entity API

Entity API Contrib Module

Makes dealing with entities easier Provides full CRUD functionality

– CReate, Update, and Delete Allows definition of metadata about entities Optionally makes entity data

– Exportable (for configuration)

– Revisionable (eg: node revisions) Optional administrative UI for managing entities Object-oriented representation of entity types

Page 15: Entities in Drupal 7 & the Entity API

A Note on Documentation

Documentation for core's Entity API is separate from that for the Entity API contrib module

In practice, you'll probably always use the Entity API contrib module

– It provides so much awesome functionality! Don't get confused

– Always install the Entity API contrib module when defining an entity

– Make sure to read the module's documentation

Page 16: Entities in Drupal 7 & the Entity API

Contrib Modules Defining Entities

Commerce

– Commerce Product, Commerce Payment Transaction Organic Groups

– OG Membership, OG Membership Type Rules

– Rules Configuration Message (think activity stream)

– Message, Message Type, Message Type Category … and many more!

Page 17: Entities in Drupal 7 & the Entity API

Example Custom Entity Type

TextbookMadness.com

– Classified listings for textbooks at schools

– Online price comparison shopping (prices from Amazon, Textbooks.com, etc.)

Online prices are

– Fetched from a third-party API and stored by Drupal

– Hereafter known as Offers

Page 18: Entities in Drupal 7 & the Entity API

How Shall we Define an Offer?

We could use the UI to define an offer node with a bunch of fields to store pricing information

But there's a lot of overhead!

– Don't need/want a page (path) per offer

– Don't need/want revisions

– Don't need/want node base table information• Language (and translation info), Title, Author,

Published status, Created date, Commenting, Promoting, etc.

We want an entity!

Page 19: Entities in Drupal 7 & the Entity API

Implement hook_schema()

$schema['tbm_offer'] = array( // SIMPLIFIED FOR SLIDE

'fields' => array(

'offer_id' => array('type' => 'serial'),

'isbn' => array('type' => 'int'),

'retailer_id' => array('type' => 'int'),

'price' => array('type' => 'int'),

'last_updated' => array('type' => 'int'),

),

'primary key' => array('offer_id')

);

Page 20: Entities in Drupal 7 & the Entity API

Implement hook_entity_info()$entities['tbm_offer'] = array(

'label' => t('Offer'),

'plural label' => t('Offers'),

'entity class' => 'Entity',

'controller class' => 'EntityAPIController',

'module' => 'tbm',

'base table' => 'tbm_offer',

'fieldable' => FALSE,

'entity keys' => array(

'id' => 'offer_id',

));

Page 21: Entities in Drupal 7 & the Entity API

Make an Entity Type Exportable$entities['tbm_offer'] = array(

'label' => t('Offer'),

'plural label' => t('Offers'),

'entity class' => 'Entity',

'controller class' => 'EntityAPIControllerExportable',

'module' => 'tbm',

'base table' => 'tbm_offer',

'fieldable' => FALSE, 'exportable' => TRUE,

'entity keys' => array(

'id' => 'offer_id', 'name' => 'my_machine_name'

));

Page 22: Entities in Drupal 7 & the Entity API

Make an Entity Type Revisionable$entities['tbm_offer'] = array(

'label' => t('Offer'),

'plural label' => t('Offers'),

'entity class' => 'Entity',

'controller class' => 'EntityAPIController',

'module' => 'tbm',

'base table' => 'tbm_offer', 'revision_table' => 'tbm_o_revision',

'fieldable' => FALSE,

'entity keys' => array(

'id' => 'offer_id', 'revision' => 'revision_id',

));

Page 23: Entities in Drupal 7 & the Entity API

Other hook_entity_info() configuration$entities['tbm_offer'] = array( …

'entity class' => 'TbmOfferEntity', // Extends Entity class

'controller class' => 'TbmOfferEntityController',

'access callback' => 'tbm_offer_access',

'admin ui' => array(

'path' => 'admin/structure/offers',

'file' => 'tbm.admin.inc',

),

'label callback' => 'entity_class_label',

'uri callback' => 'entity_class_uri',

); // TbmOfferEntity->defaultLabel(), defaultUri()

Page 24: Entities in Drupal 7 & the Entity API

Entity Property Info

hook_entity_property_info()

– Defines entity metadata

– Provided for core entities Automatically generated from hook_schema()

– Doesn't understand foreign key relationships (references)

– Doesn't know when an integer is actually a date (eg: unix timestamps)

Fill in the gaps with hook_entity_property_info_alter()

Page 25: Entities in Drupal 7 & the Entity API

hook_entity_property_info_alter()

$offer = &$info['tbm_offer']['properties'];

$offer['url']['type'] = 'uri'; // was a varchar in hook_schema

$offer['url']['label'] = 'URL';

$offer['last_updated']['type'] = 'date'; // integer in hook_schema

$offer['last_updated']['label'] = t('Last updated');

// Other types: text, token (machine name), integer, decimal, duration, boolean, entity, struct, list<TYPE>

Page 26: Entities in Drupal 7 & the Entity API

hook_entity_property_info_alter()

// Define a new property to reference an offer's retailer (eg: Amazon.com)

$offer['retailer'] = array(

'label' => t('Retailer'),

'type' => 'tbm_retailer', // The tbm_retailer entity type

'description' => t('The retailer making the offer.'),

'required' => TRUE,

'schema field' => 'retailer_id', // as defined in hook_schema

);

Page 27: Entities in Drupal 7 & the Entity API

Entity API Integrations

Views

– Eg: in a view of offers, we can add a retailer relationship and include details about each offer's retailer

Rules Search API Features I18n Token system - Eg: [tbm_offer:retailer:name]

Page 28: Entities in Drupal 7 & the Entity API

EntityFieldQuery

Tool for querying entities Can query entity properties and field data Can query field data across entity types

– Eg: “return all pages and users tagged with taxonomy term 456”

Returns entity IDs

– Usually you’ll then load with entity_load()

Page 29: Entities in Drupal 7 & the Entity API

EntityFieldQuery Example

$query = new EntityFieldQuery();

$query

->entityCondition('entity_type', 'node')

->entityCondition('bundle', 'page')

->propertyCondition('status', 1)

->fieldCondition('field_awesome_factor', 'value', 3.2, '<')

->fieldOrderBy('field_awesome_factor', 'value', 'DESC')

->range(0, 10);

// Top 10 Published page nodes with an awesome factor < 3.2

Page 30: Entities in Drupal 7 & the Entity API

EntityFieldQuery Example

$result = $query->execute(); // Keyed by entity type

if (isset($result['node'])) {

$nids = array_keys($result['node']);

$pages = node_load_multiple($nids);

$same_as_pages = entity_load('node', $nids);

}

Page 31: Entities in Drupal 7 & the Entity API

Entity Metadata Wrapper Examples

// Get node author's email address (given $nid)

// BEFORE

$node = node_load($nid);

$author = user_load($node->uid);

$email = check_plain($author->mail);

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

$email = $wrapper->author->mail->value();

Page 32: Entities in Drupal 7 & the Entity API

Entity Metadata Wrapper Examples

// Set node author's email address

$wrapper->author->mail = '[email protected]';

$wrapper->save();

// Iterate over a list of node's taxonomy terms

foreach ($wrapper->field_taxonomy_terms->getIterator() as $term_wrapper) {

$label = $term_wrapper->label->value();

}

Page 33: Entities in Drupal 7 & the Entity API

More Modules!

Entity Construction Kit (ECK)

– CCK for entities

– Create entity types in a UI Entity Cache

– Integrates entities with Drupal's Cache API Entity Reference

– Like node reference field, but for any type of entity Automatic Entity Label

– Generic successor to Automatic Node Titles

Page 34: Entities in Drupal 7 & the Entity API

More information

Entity API documentation

– Lots of information in many subpages EntityFieldQuery documentation Entity API contrib module page Deck is on Slideshare Email me: jd at ModernBizConsulting.com Follow me: @drupal_jd


Top Related