Dans Drupal 8, vous pouvez charger une entité avec:
$node = \Drupal::entityManager()->getStorage('node')->load(123);
Cela recherche les définitions d'entité et constate que le nœud est défini par Drupal \ node \ Entity \ Node - donc (je suppose) Drupal \ node \ NodeStorage instanciera une nouvelle instance Drupal \ node \ Entity \ Node .
Ce que j'aimerais réaliser, c'est sous- classer Drupal \ node \ Entity \ Node et pouvoir instancier cette sous-classe quand c'est approprié. Par exemple, si j'ai un article sur un ensemble de nœuds, il y aurait une classe:
namespace Drupal\my_module\Entity\Article;
class Article extends Drupal\node\Entity\Node {
}
Et j'appellerais:
$node = \Drupal::entityManager()->getStorage('node_article')->load(123);
Et le retour serait ma Article
sous - classe.
Je peux y parvenir en créant un nouveau type d'entité et en le reliant à une autre définition d'entité existante, par exemple l'exemple d'article de nœud serait cette classe:
namespace Drupal\my_module\Entity;
use Drupal\node\Entity\Node;
/**
* @ContentEntityType(
* id = "node_article",
* 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 Article extends Node { }
// Results my Article sub type.
$node = \Drupal::entityManager()->getStorage('node_article')->load(123);
Cela fonctionne bien (autant que je peux voir); cependant, ça sent. Il ajoute un nouveau type d'entité, ce qui n'est pas vrai et pourrait entraîner d'autres problèmes à l'avenir.
Comment définir une sous-classe pour un ensemble d'entités afin que le chargement de l'entité renvoie un objet de cette classe?
hook_entity_type_alter()
pour effectuer le changement plus proprement, mais je ne sais pas comment vous limiteriez cela à un ensemble spécifiqueRéponses:
Créez une nouvelle classe dans votre module qui s'étend
\Drupal\node\Entity\Node
.Mettre en œuvre
hook_entity_type_build()
.N'oubliez pas de reconstruire le cache.
Cela fonctionne très bien lors du chargement des nœuds via le service de gestionnaire de type d'entité et le stockage des nœuds. Cela fonctionne même lorsque vous utilisez simplement
Drupal\node\Entity\Node::load($nid)
grâce au fait que cetteload()
fonction est juste un wrapper statique pour l'appel de service du gestionnaire de type d'entité fourni par laEntity
classe qui est étendue à partir de laNode
classe.Cela fonctionne également très bien avec la fonction qui sera bientôt supprimée
entity_load_multiple()
, donc je suppose que cela couvre tous les cas d'utilisation standard pour le chargement de nœuds.Bien sûr, si votre module fait cela et qu'un autre module fait de même, vous aurez un problème, mais je suppose que ce n'est pas un scénario courant, et cela n'a de sens que pour des cas d'utilisation très spécifiques.
la source
J'ai rencontré le même problème et j'ai décidé de créer un module qui modifie la classe de type d'entité des entités Drupal via le système de plugin. Il supporte actuellement la modification de la
Node
,User
et lesFile
classes d'entités. LorsqueNode
vous modifiez le droit, vous pouvez modifier la classe de type par groupe de nœuds.Consultez la description du module pour un exemple:
https://www.drupal.org/project/entity_type_class
Le module utilise hook_entity_type_alter () pour définir une classe de gestionnaire sur les entités que vous fournissez dans votre annotation de plug-in.
la source
Ce module vous donne également de vraies classes de bundle - https://github.com/amcgowanca/discoverable_entity_bundle_classes
la source
C'est une vieille question, mais la vraie réponse devrait être:
Si vous avez besoin d'un comportement différent entre les bundles, vous devez utiliser différents types d'entités, pas différents bundles.
Les entités de contenu personnalisé sont des citoyens de première classe en D8. En fait, nous estimons qu'il faut environ 30 minutes pour obtenir une nouvelle entité de contenu personnalisé au niveau de ce nœud (ce qui revient vraiment à ajouter l'interface utilisateur du formulaire pour obtenir le joli panneau latéral et les champs d'alias / révision.) n'inclut pas l'ajout des pages de traduction, mais ce n'est pas beaucoup plus.
Si vous ne l'avez pas vu, jetez un œil aux fonctionnalités d'entité generate: custom: de la console Drupal.
la source