Entity Types
- Drupal 7 - Entity waren algemene stdClass-objecten.
- Drupal 8 - Entity zijn nu objecten met specifieke typisering, waarbij elk entity type een klasse definieert die zal worden gebruikt voor instanties van die entity.
Vereisten
Entity-klassen moeten worden geplaatst in de namespace Entity van de module die het entity type aanbiedt, bijvoorbeeld \Drupal\[module_name]\Entity. Dit betekent dat de PHP-bestanden van de Entity-klasse te vinden zijn in de map src/Entity van de module.
De docblock voor de klasse moet een EntityType-annotatie bevatten die metadata definieert voor dit entity type. Dit omvat zaken zoals het label van het entity type, handlers, tabellen, enz. Voor een gedocumenteerde lijst van alle beschikbare metadata-eigenschappen, zie de klasse \Drupal\Core\Entity\Annotation\EntityType.
Naming
Entity type-namen moeten het moduleprefix hebben als het entity type en de modulenaam niet identiek zijn. De prefix voor de entity type-klasse zelf is niet nodig, omdat deze zich bevindt in de namespace van de definiërende module, zolang de naam op zichzelf maar duidelijk genoeg is. Bijvoorbeeld, het entity type voor taxonomie-termen heet taxonomy_term, en de klassennaam is Drupal\taxonomy\Entity\Term.
Interfaces
Drupal 8 raadt aan om type hints en methoden met interfaces te gebruiken in plaats van met klassen. Bijvoorbeeld, de opslag voor algemene entities gebruikt een type hint met EntityInterface, zoals in hook_entity_insert(EntityInterface $entity), terwijl de specifieke opslag voor nodes een type hint gebruikt met NodeInterface, zoals in hook_node_insert(NodeInterface $node).
Entity-velden / eigenschappen zijn vaak erg kort, puur opslaggericht en niet heel beschrijvend. Bovendien gebruiken content entities bepaalde eigenschappen helemaal niet voor hun velden (inclusief basisvelden zoals de node-titel).
Daarom is de aanbevolen aanpak om een interface te voorzien met gedocumenteerde methodenamen. Hierbij moeten enkele regels worden gevolgd:
- Methoden hebben meestal een prefix zoals get/set/is of iets vergelijkbaars:
getSomething(),setSomething($value),isSomething(). - Voeg alleen methoden toe voor zaken die door andere code moeten kunnen worden aangepast. De datum van de laatste wijziging van nodes (
$node->updated) mag niet handmatig worden aangepast, dus bestaat er een methode$node->getChangedTime(), maar geen$node->setChangedTime(). - Gebruik zelfverklarende methodenamen, bijvoorbeeld, de methode om toegang te krijgen tot
$node->statusheet$node->isPublished().
Begrijpelijkheid
Om te weten welke entity types een module aanbiedt, kijk je naar de klassen in de Entity-namespace van die module die een @EntityType-annotatie hebben. Deze bevat ook de naam in de sleutel id van de annotatie.
Bij het zoeken waar een bepaald entity type is gedefinieerd, kijk je eerst naar het prefix van het entity type. Als een module dit naamgevingsconventie niet volgt, kun je zoeken naar id = "$type". Als in plaats van het entity type een klasse of interface bekend is, wijst de namespace naar de module van herkomst.
Voorbeeld
core/modules/node/src/Entity/Node.php:
namespace Drupal\node\Entity;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityChangedTrait;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Session\AccountInterface;
use Drupal\node\NodeInterface;
use Drupal\user\UserInterface;
/**
* Defines the node entity class.
*
* @ContentEntityType(
* id = "node",
* label = @Translation("Content"),
* bundle_label = @Translation("Content type"),
* handlers = {
* "storage" = "Drupal\node\NodeStorage",
* "storage_schema" = "Drupal\node\NodeStorageSchema",
* "view_builder" = "Drupal\node\NodeViewBuilder",
* "access" = "Drupal\node\NodeAccessControlHandler",
* "views_data" = "Drupal\node\NodeViewsData",
* "form" = {
* "default" = "Drupal\node\NodeForm",
* "delete" = "Drupal\node\Form\NodeDeleteForm",
* "edit" = "Drupal\node\NodeForm"
* },
* "route_provider" = {
* "html" = "Drupal\node\Entity\NodeRouteProvider",
* },
* "list_builder" = "Drupal\node\NodeListBuilder",
* "translation" = "Drupal\node\NodeTranslationHandler"
* },
* base_table = "node",
* data_table = "node_field_data",
* revision_table = "node_revision",
* revision_data_table = "node_field_revision",
* translatable = TRUE,
* list_cache_contexts = { "user.node_grants:view" },
* entity_keys = {
* "id" = "nid",
* "revision" = "vid",
* "bundle" = "type",
* "label" = "title",
* "langcode" = "langcode",
* "uuid" = "uuid",
* "status" = "status",
* "uid" = "uid",
* },
* bundle_entity_type = "node_type",
* field_ui_base_route = "entity.node_type.edit_form",
* common_reference_target = TRUE,
* permission_granularity = "bundle",
* links = {
* "canonical" = "/node/{node}",
* "delete-form" = "/node/{node}/delete",
* "edit-form" = "/node/{node}/edit",
* "version-history" = "/node/{node}/revisions",
* "revision" = "/node/{node}/revisions/{node_revision}/view",
* }
* )
*/
class Node extends ContentEntityBase implements NodeInterface {
// ...
}
Om het volledige plaatje van entities in Drupal 8 te begrijpen, kunnen we het volgende diagram bekijken. Dit geeft de entity-klassen weer. Om in detail te zien, open het in een nieuw tabblad:
