En Drupal 8 puede cargar una entidad con:
$node = \Drupal::entityManager()->getStorage('node')->load(123);
Esto busca las definiciones de entidad y encuentra que ese nodo está definido por Drupal \ node \ Entity \ Node , por lo que (supongo) Drupal \ node \ NodeStorage creará una nueva instancia de Drupal \ node \ Entity \ Node .
Lo que me gustaría lograr es subclasificar Drupal \ node \ Entity \ Node y poder instanciar esta subclase cuando sea apropiado. Por ejemplo, si tengo un artículo de paquete de nodos, habría una clase:
namespace Drupal\my_module\Entity\Article;
class Article extends Drupal\node\Entity\Node {
}
Y yo llamaría:
$node = \Drupal::entityManager()->getStorage('node_article')->load(123);
Y el regreso sería mi Article
subclase.
Puedo lograr esto creando un nuevo tipo de entidad y conectándolo de nuevo a otras definiciones de entidad existentes, por ejemplo, el ejemplo de artículo de nodo sería esta clase:
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);
Esto funciona bien (tanto como puedo ver); Sin embargo, huele. Agrega un nuevo tipo de entidad, que no es cierto, y podría causar otros problemas en el futuro.
¿Cómo defino una subclase para un paquete de entidades para que cargar la entidad devuelva un objeto de esa clase?
hook_entity_type_alter()
para hacer el cambio de manera más limpia, pero no sé cómo limitaría eso a un paquete específicoRespuestas:
Cree una nueva clase en su módulo que se extienda
\Drupal\node\Entity\Node
.Poner en práctica
hook_entity_type_build()
.Recuerde reconstruir el caché.
Funciona bien al cargar nodos a través del servicio de administrador de tipo de entidad y el almacenamiento de nodos. Incluso funciona cuando solo lo usa
Drupal\node\Entity\Node::load($nid)
gracias al hecho de que estaload()
función es solo un contenedor estático para la llamada de servicio del administrador de tipo de entidad proporcionada por laEntity
clase que se extiende desde laNode
clase.Esto también funciona bien con la
entity_load_multiple()
función que se eliminará pronto , por lo que supongo que cubre todos los casos de uso estándar para cargar nodos.Por supuesto, si su módulo hace esto y otro módulo hace lo mismo, tendrá un problema, pero supongo que no es un escenario común, y tiene sentido solo para casos de uso muy específicos.
fuente
Experimenté el mismo problema y decidí crear un módulo que altere la clase de tipo de entidad de las entidades de Drupal a través del sistema de complementos. Actualmente es compatible con la alteración de las clases
Node
,User
yFile
entidad. Al modificar laNode
entidad, puede modificar la clase de tipo por paquete de nodos.Consulte la descripción del módulo para ver un ejemplo:
https://www.drupal.org/project/entity_type_class
El módulo usa hook_entity_type_alter () para establecer una clase de controlador en las entidades que proporcione en su anotación de complemento.
fuente
Este módulo también le ofrece clases de paquetes reales: https://github.com/amcgowanca/discoverable_entity_bundle_classes
fuente
Esta es una vieja pregunta, pero la respuesta real debería ser:
Si necesita un comportamiento diferente entre los paquetes, debería usar diferentes tipos de entidad, no paquetes diferentes.
Las entidades de contenido personalizado son ciudadanos de primera clase en D8. De hecho, estimamos que se tarda unos 30 minutos en obtener una nueva entidad de contenido personalizada al nivel de ese nodo (que realmente se reduce a agregar la interfaz de usuario del formulario para obtener el panel lateral agradable y los campos de alias / revisión). no incluye agregar las páginas de traducción, pero eso no es mucho más.
Si no lo ha visto, eche un vistazo a las características de la entidad generate: custom: de Drupal Console.
fuente