Entidades en drupal 8

Preview:

Citation preview

Entidades en Drupal 8Luis Ortiz Ramos@luisortizramos

● Somos expertos en Drupal● Somos Siddharta, Oriol, Robert, David,

Patricia, Ignacio, Javier y Luis.● Trabajamos para Estrella Damm, Dexeus,

Médicos Sin Fronteras, Infojobs, Greenpeace, Chupa Chups, Ayuntamiento de Barcelona, Torres, la CUP…

● Estamos en Barcelona● Puedes contactar con nosotros en

hola@ateneatech.com

Dos tipos de entidades

Configuration entities:● Forma parte de CMI● Views, Blocks, Image styles, Menus, Rols…

Content entities

Historia

● Drupal 3 y anteriores: solo nodos● Drupal 4: flexinode● Drupal 5: nodos con campos con Content

Construction Kit● Drupal 6: “nodificamos” todo con módulos

contrib y añadimos campos con Content Construction Kit

● Drupal 7: entidades limitadas en core● Drupal 8: ¡entidades completas en core!

¿Qué es una entidad?

“Entities, in Drupal, are objects that are used for persistent storage of content and configuration information.”

Entity API

“Loadable thingy, that can optionally be fieldable”

Frando http://dgo.to/460320

Así que… ¿qué es una entidad?

A thingy …

Una “unidad” de información estructurada:● Un artículo o entrada en un blog● Un usuario● Un término de un vocabulario● Otra estructura de datos que creemos

… loadable …

Dispone de un conjunto de funciones para gestionar la información:● Funciones comunes para crear, leer,

actualizar y borrar entidades● Propiedades comunes● Integración con Views y otros servicios

… and optionally fieldable

Cada tipo de entidad tiene un conjunto de propiedades.

Cada tipo de entidad puede tener “subtipos” llamados bundles. Podemos adjuntar un conjunto de campos diferenciados a cada uno.

En Drupal 8: ● “contenido” es un tipo de entidad● “artículo” es un tipo de contenido (un bundle) ● “Integración Continua y trabajo en equipo en

Pantheon” es una entidad

Entidades en el núcleo de Drupal 8

Contenidos:● Para contenido!● Cada entidad de este tipo:

○ tiene una página node/ID○ revisiones

Usuarios:● Gestión de cuentas● Cada entidad tiene una página user/ID

Bloques personalizados:● Para contenido secundario

Términos:● Para organizar otras entidades● Cada entidad de este tipo tiene una página

taxonomy/term/ID

Comentarios:● Para adjuntar información estructurada a

otra entidad en el tiempo

Archivos:● Guarda metainformación sobre los archivos

Trabajando con entidades

Acceso a entidades

$manager = \Drupal::entityTypeManager();$entity = $manager ->getStorage('comment') ->load($id);

$entity = Comment::load($id);

$user = User::create(array('name' => 'me'));

$entity->getEntityTypeId();$entity->label();$entity->id();

Acceso a campos

echo $entity->subject->value;$term_id = $entity ->field_tags[2] ->target_id;

$entity->hasField($field_name); $entity = $field_item->getEntity();

$entity->title->value = 'new Title';$entity->save();

if ($node->isPromoted()) { $title = $node->getTitle();} elseif ($node->isPublished()) { $node->setTitle( $node->getAuthor() ->getUsername() );}

Acceso a traducciones

echo $entity ->getTranslation('de') ->title->value;

$translation = $entity->getTranslation('de');$translation->language()->id == 'de';$translation->title->value = 'German title';

$translation = $manager ->getTranslationFromContext($entity);echo $translation->label();

$entity = $translation->getUntranslated();

Acceso a definiciones

$entity_type = $entity_manager ->getDefinition('node');

$entity_type->id() == 'node'

$entity_type ->getClass()$entity_type ->hasKey('label')$entity_type ->isSubclassOf('ContentEntityInterface')

$field_definition = $entity-> getFieldDefinition($field_name);

$field_definition->getName();$field_definition->getPropertyDefinitions();

$entity_manager ->getFieldDefinitions('node', 'article');

Tipos de entidad personalizados

Son plugins:● Deben estar en Drupal/module/Entity● Deben cumplir la anotación

@ContentEntityType● Deben implementar ContentEntityBase

/** * Defines the comment entity class. * * @ContentEntityType( * id = "comment", * label = @Translation("Comment"), * bundle_label = @Translation("Comment type"), * handlers = { * "storage" = "Drupal\comment\CommentStorage", * "storage_schema" = "Drupal\comment\CommentStorageSchema", * "access" = "Drupal\comment\CommentAccessControlHandler", * "list_builder" = "Drupal\Core\Entity\EntityListBuilder", * "view_builder" = "Drupal\comment\CommentViewBuilder", * "views_data" = "Drupal\comment\CommentViewsData", * "form" = { * "default" = "Drupal\comment\CommentForm", * "delete" = "Drupal\comment\Form\DeleteForm" * }, * "translation" = “Drupal\comment\CommentTranslationHandler" * },...

... * base_table = "comment", * data_table = "comment_field_data", * uri_callback = "comment_uri", * translatable = TRUE, * entity_keys = { * "id" = "cid", * "bundle" = "comment_type", * "label" = "subject", * "langcode" = "langcode", * "uuid" = "uuid" * }, * links = { * "canonical" = "/comment/{comment}", * "delete-form" = "/comment/{comment}/delete", * "edit-form" = "/comment/{comment}/edit", * }, * bundle_entity_type = "comment_type", * field_ui_base_route = "entity.comment_type.edit_form", * constraints = { * "CommentName" = {} * } * ) */

Definen sus campos base:● Implementan la función baseFieldDefinitions● Usan BaseFieldDefinition::create para añadir

campos:○ Tipo de campo○ Propiedades○ Formateadores

class Comment extends ContentEntityBase implements CommentInterface {

public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {

/** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */$fields = parent::baseFieldDefinitions($entity_type);

$fields['subject'] = BaseFieldDefinition::create('string')

->setLabel(t('Subject'))->setTranslatable(TRUE)->setSetting('max_length', 64)->setDisplayOptions('form', array(

'type' => 'string_textfield',// Default comment body field has weight 20.'weight' => 10,

))->setDisplayConfigurable('form', TRUE);

return $fields;}

}

$fields['title'] = FieldDefinition::create('string')->setLabel(t('Title'))...->setDisplayOptions('view', array(

'label' => 'hidden','type' => 'string','weight' => -5,

))->setDisplayOptions('form', array(

'type' => 'string','weight' => -5,

))->setDisplayConfigurable('form', TRUE);

Los handlers:● son clases independientes del tipo de

entidad● definen:

○ Storage○ Access○ List and view builder○ Views data○ Forms

... * handlers = { * "storage" = "Drupal\comment\CommentStorage", * "storage_schema" = "Drupal\comment\CommentStorageSchema", * "access" = "Drupal\comment\CommentAccessControlHandler", * "list_builder" = "Drupal\Core\Entity\EntityListBuilder", * "view_builder" = "Drupal\comment\CommentViewBuilder", * "views_data" = "Drupal\comment\CommentViewsData", * "form" = { * "default" = "Drupal\comment\CommentForm", * "delete" = "Drupal\comment\Form\DeleteForm" * }, * "translation" = “Drupal\comment\CommentTranslationHandler" * },...

Storage:● Se utiliza para gestionar la persistencia de la

entidad.● Implementa EntityStorageInterface● Implementaciones base:

○ SqlContentEntityStorage○ ContentEntityNullStorage

class CommentStorage extends SqlContentEntityStorage implements CommentStorageInterface {

... public function loadThread(...) {

...}...

}

Entity keys:● Definen las claves que se usarán para cargar

las entidades● ContentEntityBase::baseFieldDefinitions crea

campos para ellas automáticamente

... * entity_keys = { * "id" = "cid", * "bundle" = "comment_type", * "label" = "subject", * "langcode" = "langcode", * "uuid" = "uuid" * },...

Links● Define la forma de los enlaces:

○ canonical○ add-form○ edit-form○ delete-form○ ...

... * links = { * "canonical" = "/comment/{comment}", * "delete-form" = "/comment/{comment}/delete", * "edit-form" = "/comment/{comment}/edit", * },...

Routing● Es posible definir las rutas en el archivo *.

routing.yml● Es mejor usar un handler route_provider

como DefaultHtmlRouteProvider

¿Por qué?

● Cuando necesitas un tipo de entidad específico: propiedades, métodos, acceso, almacenamiento…

● Cuando no quieres usar un tipo existente: puedes clonar uno y los demás módulos no sabrán de él

● Cuando necesitas control total sobre él: los campos base no pueden modificarse usando la interfaz

● Cuando el modelo de datos es muy complicado: como pasa con Commerce o Paragraphs

¡Gracias!¿Preguntas?