Drupal 8: Entities Drupal 8: Entities Working with entities in Drupal 8 modules Working with entities in Drupal 8 modules Drupal Meetup Stuttgart Drupal Meetup Stuttgart 06/11/2015
Drupal 8: EntitiesDrupal 8: EntitiesWorking with entities in Drupal 8 modulesWorking with entities in Drupal 8 modules
Drupal Meetup StuttgartDrupal Meetup Stuttgart
06/11/2015
1. What are Entities?1. What are Entities?
“ loadable thingies, thatloadable thingies, thatcan optionally be fieldablecan optionally be fieldable
https://www.drupal.org/node/460320
Entities areEntities are
Entity types - node, user, ...-> Base fields, like nid, title, author
Bundles - article, story, ...-> Bundle fields, like an image
All entities aren't equal, they may haveAll entities aren't equal, they may havedifferentdifferent
Entities in Drupal 7 (Core)Entities in Drupal 7 (Core)
NodesUsersTaxonomy vocabulariesTaxonomy termsFilesComments
Entities in Drupal 8Entities in Drupal 8
Entities in Drupal 8 are classesCan be content entities or config entitiesExtend corresponding base classes
class Contact extends ContentEntityBase implements ContactInterface {
...
}
Entity examples in Drupal 8 (Core)Entity examples in Drupal 8 (Core)
Content Entities Configuration entities
Aggregator feed / item
Block content
Comment
Message
File
Menu link
Content (aka node)
Shortcut
Taxonomy term
User
Action
Block
Breakpoint
Comment type
Content type
Date format
Field
Image Style
Language
Menu
Role
View
...
2. Working with entities:2. Working with entities:CRUDCRUD
CRUD =CRUD =CreateReadUpdateDelete
entities, implemented by something calledEntity API
The problem with D7:The problem with D7:
Entity API is incomplete, only the R exists (entity_load)Most missing parts implemented by contrib (entity module)But many developers keep using proprietary D6 functions,still not removed from core:- node_load(), node_save()- user_load(), user_save()- taxonomy_get_term_by_name()- taxonomy_vocabulary_delete()- ...
Drupal 8: Entity API in core!Drupal 8: Entity API in core!
Streamlines the way of working with entitiesEasy extendable / testable (OOP)No need for proprietary stuff
3. Read entities (C3. Read entities (CRRUD)UD)
Drupal 7: proprietary functionsDrupal 7: proprietary functions// Load a single node$customer = node_load(526);
// Load multiple users$users = user_load_multiple(array(77, 83, 121));
// Load a single term$category = taxonomy_term_load(19);
Drupal 8: entity managerDrupal 8: entity manager// Load a single node$storage = \Drupal::entityManager()->getStorage('node');$customer = $storage->load(526);
// Load multiple users$storage = \Drupal::entityManager()->getStorage('user');$users = $storage->loadMultiple(array(77, 83, 121));
// Load a single term$storage = \Drupal::entityManager()->getStorage('taxonomy_term');$category = $storage->load(19);
Better: use Dependency Injection, not static calls!
Drupal 8: static callsDrupal 8: static calls// Load a single node$customer = Node::load(526);
// Load multiple users$users = User::loadMultiple(array(77, 83, 121));
// Load a single term$category = Term::load(19);
Drupal 8: procedural wrappersDrupal 8: procedural wrappers// Load a single node$customer = entity_load('node', 526);
// Load multiple users$users = entity_load_multiple('user', array(77, 83, 121));
// Load a single term$category = entity_load('taxonomy_term', 19);
4. Create entities (4. Create entities (CCRUD)RUD)
Drupal 7: generic classesDrupal 7: generic classes$node = new stdClass();$node->type = 'article';node_object_prepare($node);$node->title = 'Breaking News';node_save($node);
$storage = \Drupal::entityManager()->getStorage('node');$node = $storage->create(array('type' => 'article', 'title' => 'Breaking News'));$node->save();
Drupal 8: entity managerDrupal 8: entity manager
$node = Node::create(array('type' => 'article', 'title' => 'Breaking News'));$node->save();
Drupal 8: static callDrupal 8: static call
5. Update entities (CR5. Update entities (CRUUD)D)
Drupal 7: proprietary functionsDrupal 7: proprietary functions$node = node_load(331);$node->title = 'Changed title';node_save($node);
Drupal 8: entity managerDrupal 8: entity manager$storage = \Drupal::entityManager()->getStorage('node');$node = $storage->load(526);$node->setTitle('Changed title');$node->save();
Drupal 8: procedural wrapperDrupal 8: procedural wrapper$node = entity_load('node', 526);$node->setTitle('Changed title');$node->save();
6. Delete entities (CRU6. Delete entities (CRUDD))
Drupal 7: proprietary functionsDrupal 7: proprietary functionsnode_delete(529);node_delete_multiple(array(22,56,77));
Drupal 8: procedural wrapperDrupal 8: procedural wrapperentity_delete_multiple('node', array(529));entity_delete_multiple('node', array(22,56,77));
$storage = \Drupal::entityManager()->getStorage('node');$node = $storage->loadMultiple(array(529));$storage->delete($node);
$storage = \Drupal::entityManager()->getStorage('node');$nodes = $storage->loadMultiple(array(22,56,77));$storage->delete($nodes);
Drupal 8: entity managerDrupal 8: entity manager
7. Accessing entities7. Accessing entities
Accessing entities in D7Accessing entities in D7
$car = node_load(23);
$title = $car->title;$color = $car->field_color['und'][0]['value']$manufacturer = $car->field_manufacturer['und'][0]['target_id']
...
Or, thanks to Entity Metadata Wrapper (contrib):$car = entity_metadata_wrapper('node', 23);
$title = $car->title;$color = $car->field_color->value();$manufacturer = $car->field_manufacturer->raw();
...
No getter / setter methods, but some lovely arrays:
Accessing entities in D8Accessing entities in D8
$nid = $car->id();$nid = $car->get('nid')->value;$nid = $car->nid->value;
$title = $car->label();$title = $car->getTitle();$title = $car->get('title')->value;$title = $car->title->value;
$created = $car->getCreatedTime();$created = $car->get('created')->value;$created = $car->created->value;
$color = $car->field_color->value;$color = $car->get('field_color')->value;
$uid = $car->getOwnerId();$uid = $car->get('uid')->target_id;$uid = $car->uid->value;
$user = $car->getOwner();$user = $car->get('uid')->entity;
Getter / setter methods in core, but ambivalent:
Reasonable, or just bad DX ?
Drupal\node\Entity\Node Object( [values:protected] => Array( [vid] => Array([x-default] => 1) [langcode] => Array ([x-default] => en) [revision_timestamp] => Array([x-default] => 1433958690) [revision_uid] => Array([x-default] => 1) [revision_log] => Array([x-default] => ) [nid] => Array([x-default] => 1) [type] => Array([x-default] => test) [uuid] => Array([x-default] => 46b4af73-616a-494a-8a16-22be8dfe592e) [isDefaultRevision] => Array([x-default] => 1) [title] => Array([x-default] => Breaking News) [uid] => Array([x-default] => 1) [status] => Array([x-default] => 1) [created] => Array([x-default] => 1433958679) [changed] => Array([x-default] => 1433958679) [promote] => Array([x-default] => 1) [sticky] => Array([x-default] => 0) [default_langcode] => Array([x-default] => 1) ) [fields:protected] => Array() [fieldDefinitions:protected] => [languages:protected] => [langcodeKey:protected] => langcode [defaultLangcodeKey:protected] => default_langcode [activeLangcode:protected] => x-default [defaultLangcode:protected] => en [translations:protected] => Array( [x-default] => Array([status] => 1) ) [translationInitialize:protected] => [newRevision:protected] => [isDefaultRevision:protected] => 1 [entityKeys:protected] => Array( [bundle] => test [id] => 1 [revision] => 1 [label] => Breaking News [langcode] => en [uuid] => 46b4af73-616a-494a-8a16-22be8dfe592e [default_langcode] => 1 ) [entityTypeId:protected] => node [enforceIsNew:protected] => [typedData:protected] => [_serviceIds:protected] => Array())
By the way...By the way...$node->values['title']['x-default'] ?$node->entityKeys['label'] ?
Don't even think of it!
8. Entity Queries8. Entity Queries
Drupal 7: Entity Field QueryDrupal 7: Entity Field Query$query = new EntityFieldQuery();
$query ->entityCondition('entity_type', 'node') ->entityCondition('bundle', array('product', 'movies')) ->propertyCondition('status', 1) ->fieldCondition('body', 'value', 'discount', 'CONTAINS') ->propertyOrderBy('created', 'DESC');
$result = $query->execute();
if (!empty($result['node'])) { $nodes = node_load_multiple(array_keys($result['node']))}
Useful, but
why is this called Entity Field Query?why are there three condition types?what's the result structure?
Drupal 8: Entity QueryDrupal 8: Entity Query
$storage = \Drupal::entityManager()->getStorage('node');
$query = $storage->getQuery();
$query ->Condition('type', array('product', 'movies')) ->Condition('status', 1) ->Condition('body', 'value', 'discount', 'CONTAINS') ->OrderBy('created', 'DESC');
$result = $query->execute();
$nodes = $storage->loadMultiple($result);
9. There's even more...9. There's even more...
Create your own customCreate your own customEntity typesBundlesEntity formsAccess handlersStorage controllers...
Thank You!Thank You!
http://slides.com/drubbhttp://slideshare.net/drubb