Introduction à l’Entity API dans Drupal 8
Le système d’entités de Drupal 8
Les entités sont des classes typées avec des méthodes :
Méthodes génériques | $entity->id() |
Méthodes spécifiques au type d’entité | $node->getTitle() |
Contexte
Le système d’entités a été introduit vers la fin du cycle de développement de Drupal 7 avec des standards de base pour le chargement des entités. Le module entity a ensuite étendu l’API avec la prise en charge de la sauvegarde, suppression et autres améliorations.
La majorité de ces améliorations sont maintenant intégrées dans Drupal 8. La validation d’entité se fait via une API dédiée (permettant par exemple la validation d’entité sauvegardée via REST, pas seulement via formulaire).
Deux variantes
Les types d’entité du noyau Drupal existent en deux variantes :
Objet de configuration
Utilise le système de configuration. Supporte les traductions et peut fournir des réglages par défaut. Les objets de configuration sont stockés sous forme de chaînes dans une table de configuration commune.
Entité de contenu
Composée de champs personnalisables et de base, pouvant avoir des révisions et des traductions. Les données sont stockées dans des tables dédiées selon le nom d’« id » de l’entité, avec des colonnes définies dans la méthode « baseFieldDefinitions ».
Bundles (paquets)
Les bundles sont des variantes d’un type d’entité. Par exemple, pour l’entité node, les bundles sont les types de contenu comme « article » et « page ».
Typiquement, un bundle est une entité de configuration. Par exemple, le type de nœud « article » est un objet de configuration. La configuration stocke les différences entre types d’entité, comme les réglages et champs. Lors de la création d’un nouveau type d’entité avec bundles, vous créez à la fois une entité de contenu (gestion des données) et un objet de configuration (gestion des différences entre bundles).
Annotations
Pour créer un nouveau type d’entité, vous devez utiliser le système d’annotations intégré au noyau. Les annotations ressemblent à des commentaires docblock au-dessus de la classe, mais sont analysées et mises en cache par Drupal. Elles remplacent de nombreux anciens styles Drupal 7.
Analyseur d’annotations
Les annotations sont lues à l’exécution par le mécanisme d’annotations. Drupal 8 utilise l’analyseur d’annotations Doctrine, qui convertit les annotations en objets PHP exploitables.
Syntaxe : Les annotations sont entourées de @ClassName(), avec des paires clé/valeur, et peuvent contenir des tableaux avec accolades. Les clés du premier niveau ne sont pas entre guillemets, celles des tableaux le sont. Chaque paire clé/valeur est sur une ligne et se termine par une virgule. Certaines fonctions, comme @Translation(), peuvent être utilisées dans les valeurs.
Exemple d’annotation :
/** * @ContentEntityType( * id = "my_entity_type_id", * label = @Translation("Mon type d’entité"), * example_pair = "valeur_exemple", * example_array = { * "cle_tableau" = "valeur_tableau", * "autre_cle" = "autre_valeur", * }, * ) */
Annotations courantes
Clé = "Valeur exemple" | Description | Variante d’entité |
---|---|---|
id = "node" | Nom machine du type d’entité. | Contenu & Configuration |
label = @Translation("Node") | Nom lisible du type d’entité. | Contenu & Configuration |
admin_permission = "administer nodes" | Droit requis pour administrer ce type d’entité (si aucun handler d’accès n’est défini). | Contenu & Configuration |
bundle_label = @Translation("Content type") | Nom lisible optionnel du bundle (type de contenu). | Contenu |
bundle_entity_type = "node_type" | Identifiant de l’objet de configuration du bundle (par ex. « node_type »). | Contenu |
base_table = "node" | Nom de la table en base pour ce type d’entité. | Contenu |
fieldable = TRUE | (bool) Ce type d’entité peut être étendu avec des champs via l’interface utilisateur. | Contenu |
field_ui_base_route = "entity.node_type.edit_form" | Nom de la route du formulaire d’édition du bundle dans l’UI des champs. | Contenu |
Handlers (gestionnaires)
Les handlers sont définis dans l’annotation comme un tableau. Ils permettent de déléguer certaines parties de la gestion d’une entité à des classes PHP spécifiques.
Storage — Gère le chargement, la sauvegarde et la suppression. Par défaut, les entités de contenu utilisent Drupal\Core\Entity\Sql\SqlContentEntityStorage
et les objets de configuration Drupal\Core\Config\Entity\ConfigEntityStorage
. Vous pouvez définir un handler personnalisé pour ajouter des fonctionnalités, comme obtenir les identifiants de révision ou le nombre de traductions.
Exemple : "storage" = "Drupal\node\NodeStorage"
Form — Handlers pour les formulaires d’ajout, édition et suppression, mappés à des classes.
Exemple :
"form" = { "add" = "Drupal\block\BlockForm", "edit" = "Drupal\block\BlockForm", "delete" = "Drupal\block\Form\BlockDeleteForm", }
Il est possible de définir une forme « default » commune à l’ajout et édition. Le formulaire de suppression est généralement distinct car il s’agit d’un formulaire de confirmation.
View builder — Classe gérant l’affichage de l’entité pour l’utilisateur final.
Exemple : "view_builder" = "Drupal\node\NodeViewBuilder"
List builder — Classe gérant la liste des entités (ex. page d’administration).
Exemple : "list_builder" = "Drupal\node\NodeListBuilder"
Route provider — (optionnel) Génère les routes pour gérer l’entité, remplaçant le fichier routing.yml.
Exemple :
"route_provider" = { "html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider", }
Access — Gestionnaire d’accès dynamique implémentant EntityAccessControlHandlerInterface
. Vous pouvez étendre EntityAccessControlHandler
pour un contrôle avancé.
Exemple : "access" = "NodeAccessControlHandler"
Views data — Permet d’ajouter les données de l’entité au module Views.
Exemple : "views_data" = "Drupal\node\NodeViewsData"
Storage schema — Pour personnaliser le schéma de stockage en base (index, etc.).
Exemple : "storage_schema" = "Drupal\node\NodeStorageSchema"
Translation — Gestion des traductions.
Exemple : "translation" = "Drupal\node\NodeTranslationHandler"
Exemple complet de handlers :
handlers = { "view_builder" = "Drupal\Core\Entity\EntityViewBuilder", "list_builder" = "Drupal\Core\Entity\EntityListBuilder", "access" = "Drupal\Core\Entity\EntityAccessControlHandler", "views_data" = "Drupal\views\EntityViewsData", "storage" = "Drupal\Core\Entity\Sql\SqlContentEntityStorage", "storage_schema" = "Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema", "translation" = "Drupal\content_translation\ContentTranslationHandler", "form" = { "default" = "Drupal\Core\Entity\ContentEntityForm", "add" = "Drupal\Core\Entity\ContentEntityForm", "edit" = "Drupal\Core\Entity\ContentEntityForm", "delete" = "Drupal\Core\Entity\ContentEntityDeleteForm", }, "route_provider" = { "html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider", }, },
Liens
Les liens sont définis dans l’annotation sous forme de tableau. Ils contiennent les URI pour gérer le type d’entité ou des entités spécifiques. Ces liens concernent aussi bien les entités de contenu que de configuration.
Exemple :
id = "node", handlers = { "route_provider" = { "html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider" } }, links = { "canonical" = "/node/{node}", "add-page" = "/node/add", "add-form" = "/node/add/{node_type}", "edit-form" = "/node/{node}/edit", "delete-form" = "/node/{node}/delete", "collection" = "/admin/content", },
Notez que ces liens ne créent pas automatiquement les routes correspondantes. Vous devez définir un fichier routing.yml ou utiliser un route_provider.
Liens et route provider
Associés au route_provider, ces liens activent les routes suivantes dans Drupal :
Clé du lien | Nom de la route | Exemple d’URI | Description |
---|---|---|---|
canonical | entity.node.canonical | /node/1 | Afficher un nœud spécifique |
add-page | entity.node.add_page | /node/add | Page de sélection du type de nœud à ajouter |
add-form | entity.node.add_form | /node/add/article | Formulaire d’ajout d’un nœud de type spécifique |
edit-form | entity.node.edit_form | /node/1/edit | Formulaire d’édition d’un nœud |
delete-form | entity.node.delete_form | /node/1/delete | Formulaire de suppression d’un nœud |
collection | entity.node.collection | /admin/content | Liste de tous les nœuds |
Utilisation des liens
Ces liens sont accessibles via la méthode toUrl() de l’objet :
$view_url_object = $entity->toUrl(); // Par défaut 'canonical' $edit_url_string = $entity->toUrl('edit-form')->toString();
Liens utiles :
- Entity API — Documentation générée
- Créer une entité de contenu personnalisée — Exemple simple
- Créer un type d’entité de contenu dans Drupal 8 — Exemple avancé avec handlers, permissions, routage et liens
- Créer un type d’objet de configuration dans Drupal 8 — Exemple avancé avec handlers, routage et schéma
- Entity Type Walkthrough — Documentation d’un type d’entité général