Your Entity
Your Code
Marco Vito Moscaritolo
@mavimo@gmail.com
me.yml
users:
mavimo:
name: Marco Vito Moscaritolo
email: mavimo-at-gmail.com
twitter: @mavimo
technologies: [ php, drupal, symfony ]
role: [ developer, teacher, architect ]
work: freelance
founder: @sparkfabrik
Why	entities	?
We can	create	custom
node type…
…right?
• D6 & 5 $node = new stdClass();
// Sad L
• D7 $node = new stdClass();
// DrupalEntityControllerInterface
// EntityFieldQuery, …
• D8 $node = new DrupalnodeEntityNode();
// Yah yahhhh!!! J
A	bit	of	history
• Entity (Node,	User,	Comment,	Taxonomy,	…)
• Bundle (Node	type,	Vocabularies,	…)
• Property (Node	id,	node	title,	vocabulary	name,	…)
• Field (Body,	Image	field,	Term	references,	…)
Core	elements
D7 - hook_entity_info()
return array(
’entity_name' => array(
'label' => t(’Custom entity'),
'controller class' => ’CustomEntityController',
'base table' => ’custom_entity',
'uri callback' => ’custom_entity_uri',
'fieldable' => TRUE,
'entity keys' => array( /* ... */ )
'bundle keys' => array(
'bundle' => 'machine_name',
),
'bundles' => array( /* ... */ ),
'view modes' => array( /* ... */ ),
),
);
D7 - Entity API
D7 - Entity
Bla bla…
class CustomEntity extends Entity {
public function __construct(array $values = [], $entity_type = NULL) {}
public function identifier() {}
public function bundle() {}
public function uri() {}
public function hasStatus($status) {}
public function save() {}
public function delete() {}
public function view($view_mode = 'full', $lang = NULL, $page = NULL) {}
public function buildContent($view_mode = 'full', $langcode = NULL) {}
// ...
}
D7 - hook_entity_info()
extended by Entity API
return array(
’entity_name' => array(
// ...
’entity class' => ’CustomEntity',
// ...
'views controller class' => ’CustomEntityViewsController',
// ...
'exportable’ => TRUE,
// ...
'admin ui' => array(
// ...
'controller class' => ’CustomEntityUIController',
),
),
);
D7 - EntityAPIController
class CustomEntityController extends EntityAPIController {
public function __construct($entityType) {}
public function query($ids, $conditions, $revision_id = FALSE) {}
public function load($ids = array(), $conditions = array()) {}
public function invoke($hook, $entity) {}
public function delete($ids, DatabaseTransaction $trans = NULL) {}
public function save($entity, DatabaseTransaction $trans = NULL) {}
public function create(array $values = array()) {}
public function buildContent($entity, $view_mode = 'full’,
$lang = NULL, $content = []) {}
public function view($entities, $view_mode = 'full’,
$langcode = NULL, $page = NULL) {}
// ...
}
D7 - EntityDefaultUIController
Bla bla…class CustomEntityUIController extends EntityDefaultUIController {
public function __construct($entity_type, $entity_info) {}
public function hook_menu() {}
public function hook_forms() {}
public function overviewTable($conditions = array()) {}
public function overviewForm($form, &$form_state) {}
public function operationForm($form, &$form_state, $entity, $op) {}
// and also [overview|operation]Form[Submit|Validate] methods.
public function applyOperation($op, $entity) {}
// ...
}
D7 – Entity	(Admin	UI)
D7 - Entity	UI	(admin)
D7 - Entity	UI	(edit)
Too	much	work…	why???
Integration
view, rules, features
Code testability
easy to isolate
Reusability
code once, use more
Remote entity
social network, webservices
Drupal 8 ;-)
Integration	(eg:	views)
EntityFieldQuery
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'custom_entity')
->entityCondition('bundle', 'my_bundle')
->propertyCondition('uid', $user->uid, '=')
->fieldCondition('field_faculty_tag', 'tid', 10)
->fieldOrderBy('field_faculty_tag', 'tid', 'DESC')
->range(0, 10);
$result = $query->execute();
if (isset($result['custom_entity'])) {
$items = entity_load('custom_entity’, array_keys($result['custom_entity']));
}
EntityMetadataWrapper
$wrapper = entity_metadata_wrapper('custom_entity', $entity);
$wrapper->author->mail->set('demo@drupalday.it');
$wrapper->description->value('This is a demo!');
$labels = array();
foreach ($wrapper->field_faculty_tag->getIterator()
as $delta => $term_wrapper) {
$labels[] = $term_wrapper->label->value();
}
$wrapper->save();
D7 - Create	Custom	Entity…	Fast!(1)
drush entity-scaffold entity_name dday
File dday/entity_name/includes/entity_name.admin.inc created. [ok]
File dday/entity_name/includes/entity_name.class.inc created. [ok]
File dday/entity_name/includes/entity_name.controller.inc created. [ok]
File dday/entity_name/includes/entity_name.type.controller.inc created. [ok]
File dday/entity_name/includes/entity_name_type.admin.inc created. [ok]
File dday/entity_name/entity_name.info created. [ok]
File dday/entity_name/entity_name.install created. [ok]
File dday/entity_name/entity_name.tpl.php created. [ok]
File dday/entity_name/entity_name.module created. [ok]
https://www.drupal.org/project/entity_scaffold
D7 - Create	Custom	Entity…	Fast!(2)
https://www.drupal.org/project/eck
…Drupal	8	?
Thanks!
ContentEntityTypeInterface
(Node,	User,	Comment,	Taxonomy,	…)
ConfigEntityTypeInterface
(Configuration	information)
…
(eg:	Bundle)
D8 - Entity	type
D8 - Entity Type
Module namespaced
Drupalmy_moduleEntityMyCustomeEntity()
Defined folder in module
src/Entity/MyCustomEntity.php
INFORMATION MANAGED BY
ANNOTATION
/**
* @XyzEntityType( … )
*/
Can be “code only”
config/install/my_custom_entity.sample_1.yml
Unit testable
class MyCustomEntityTest extends DrupalTestsUnitTestCase {}
D8 - ContentEntityType
Require database definition
hook_schema()
Can be fildable/REVISIONABLE
baseFieldDefinition()
CAN HAVE CUSTOM BEHAVIOR
redefine [pre|post][Save|Load|Delete] methods
CAN PROVIDE CUSTOM ACCESS RULES
checkAccess() and checkCreateAccess()
CAN PROVIDE CUSTOM HANDLERS
strorage, view_builder, route_provider, form, translation, config_export...
D8 - ContentEntityType
/**
* @ContentEntityType(
* id = "my_content",
* label = @Translation("My Content"),
* bundle_label = @Translation("My Content type"),
* handlers = { ... },
* base_table = "my_entity",
* data_table = "my_entity_field_data",
* revision_table = "my_entity_revision",
* revision_data_table = "my_entity_field_revision",
* translatable = TRUE,
* entity_keys = { ... },
* bundle_entity_type = "my_entity_type",
* field_ui_base_route = "entity.my_entity_type.edit_form",
* common_reference_target = TRUE,
* permission_granularity = "bundle",
* links = { ... }
* )
*/
class MyContentEntity extends ContentEntityBase implements
MyContentEntityInterface { }
D8 - ConfigEntityType
Difference	compared	to	ContentEntityType:
• Schema file definition
Instead	of	database	schema	definition,	using:
config/schema/my_entity.schema.yml
• INTEGRATED with CMI API
for exportability
See	dedicated	talk.
• No field
D8 - ConfigEntityType
/**
* @ConfigEntityType(
* id = "my_config",
* label = @Translation("My config"),
* handlers = {
* "list_builder" = "Drupalmy_moduleControllerMyConfigListBuilder",
* "form" = { ... }
* },
* config_prefix = "my_config",
* admin_permission = "administer site configuration",
* entity_keys = { ... },
* links = { ... }
* )
*/
class MyConfigEntity extends ConfigEntityBase implements
MyConfigEntityInterface { ... }
my_module/config/schema/my_config.schema.yml
my_module.my_config.*:
type: config_entity
label: My config’
mapping:
id:
type: string
label: 'ID’
label:
type: label
label: 'Label'
D8 - Create	Custom	Entity…	Fast!
drupal generate:entity:content 
--module=dday 
--entity-name=my_content_entity 
--entity-class=MyContentEntity 
--label="My Content Entity”
Generated or updated files Site path: ~/dday
1 - modules/custom/dday/dday.routing.yml
2 - modules/custom/dday/dday.permissions.yml
3 - modules/custom/dday/dday.links.menu.yml
4 - modules/custom/dday/dday.links.task.yml
. . .
13 - modules/custom/dday/src/Entity/Form/MyContentEntityDeleteForm.php
14 - modules/custom/dday/my_content_entity.page.inc
15 - modules/custom/dday/templates/My Content Entity.html.twig
https://www.drupal.org/project/console
Question?
Thank you!
milan2016.drupaldays.org
References
http://joshaust.in/wp-content/uploads/2012/06/Entities-and-Bundles-in-Drupal-7.pdf
https://www.drupal.org/project/entity
https://www.drupal.org/project/eck
https://www.drupal.org/project/entity_scaffold
http://www.bluespark.com/blog/drupal-entities-part-1-moving-beyond-nodes
http://www.sitepoint.com/build-custom-entities-drupal-setup/
https://www.drupal.org/developing/api/entity
https://hechoendrupal.gitbooks.io/drupal-console/content/en/index.html
http://www.wunderkraut.com/blog/configuration-entities-in-drupal-8/2014-07-14
http://nuvole.org/blog/drupal-8
http://blog.oskoui-oskoui.com/?p=8218
https://codedrop.com.au/blog/creating-custom-config-entities-drupal-8
Your Entity, Your Code

Your Entity, Your Code