Creazione di contenuto personalizzato
Pubblico di riferimento
Questa documentazione è rivolta principalmente agli sviluppatori con esperienza di programmazione in PHP orientato agli oggetti, Drupal 6 o Drupal 7, e a chi desidera imparare i principi di Drupal 8.
La documentazione sulla creazione di un tipo di entità di contenuto in Drupal 8 include un elenco completo delle opzioni disponibili.
Creazione di un tipo di contenuto senza bundle in Drupal 8
In questo caso, creiamo un’entità di contenuto in Drupal 8 che non ha bundle.
L’entità non implementa l’API dei campi, quindi rimane nel codice. Tuttavia, può essere un utile scheletro per costruire Content Entities, dato che in seguito importeremo dati più complessi.
Infine, dove ci sono alcuni concetti di OOP, farò riferimento alla documentazione pertinente.
Contesto
Il nostro modulo si chiama Advertiser.
Il nostro tipo di entità di contenuto si chiama Advertiser.
La nostra nuova Content Entity Advertiser in Drupal 8 avrà i campi:
- UUID
- ID
Definizione dell’entità di contenuto in Drupal 8
Prima di tutto, tutte le entità personalizzate ora si trovano in modules/custom invece che in sites/all/modules/custom.
All’interno della nostra entità personalizzata, la struttura finale delle cartelle sarà la seguente:
modules/custom/advertiser$
├── advertiser.info.yml
└── src
└── Entity
└── Advertiser.php
Per riferimento, puoi consultare l’entità Advertiser completa insieme a componenti aggiuntivi, come test e constraint plugin, ma per ora manterremo il tutto più semplice.
Info file
Iniziamo definendo il nostro modulo personalizzato in module_name.info.yml. È abbastanza autoesplicativo:
name: Advertiser type: module description: 'Barebones advertiser entity' package: custom core: 8.x
Scheletro dell’entità
Il codice base dell’entità Advertiser e lo schema associato sono definiti in src/Entity/Advertiser.php.
Per prima cosa, definiamo il namespace della nostra classe Advertiser. Questo ci servirà quando useremo le nostre classi.
namespace Drupal\advertiser\Entity;
Ora è il momento di definire la nostra entità, cosa che facciamo con le annotazioni.
Questa è la vera definizione del tipo di entità che Drupal leggerà e metterà in cache, quindi ricordati di svuotare la cache dopo ogni modifica.
<?php
/**
* Definisce l’entità Advertiser.
*
* @ingroup advertiser
*
* @ContentEntityType(
* id = "advertiser",
* label = @Translation("Advertiser"),
* base_table = "advertiser",
* entity_keys = {
* "id" = "id",
* "uuid" = "uuid",
* },
* )
*/
?>
Poiché è un’entità vuota, utilizziamo solo alcune proprietà, senza handler come il modulo Access.
Abbiamo un modulo funzionante che definisce la nostra entità di contenuto personalizzata, ma noteremo che la tabella “advertiser” non è stata creata nel database.
$ drush sql-cli mysql> SHOW TABLES;
Questo perché nella nostra classe non ci sono metodi che interagiscono esplicitamente con il database. Inoltre, ci serve una descrizione minima dei metodi necessari per consentire all’entità di interagire correttamente con il DB.
ContentEntityBase
In genere possiamo includere classi aggiungendo, per esempio, use Drupal\Core\Entity\ContentEntityBase; dopo la definizione del namespace. Questo rende disponibili i metodi per la nostra classe, che può estenderli o implementarli nel caso di interfacce.
Facciamo due cose: estendiamo la classe esistente ContentEntityBase, che ha già i metodi per interagire con il DB, e implementiamo ContentEntityInterface per descrivere i metodi richiesti.
I metodi definiti dall’interfaccia servono ad accedere al DB. NON definiscono come lo facciamo: questo è compito della classe che implementa. Possiamo implementare questa interfaccia in modi diversi e poi cambiare implementazione senza rompere il codice, perché l’interfaccia definisce solo il “come usarla”. – Manuale PHP sulle interfacce
Quindi otteniamo quanto segue. Ricorda di aggiungere qualsiasi nuova classe con use all’inizio del file:
class Advertiser extends ContentEntityBase implements ContentEntityInterface {
Ora però dobbiamo usare questi nuovi metodi per inserire dati nel DB, partendo dai campi base della nostra entità.
baseFieldDefinitions
Il metodo baseFieldDefinitions viene da ContentEntityBase, che stiamo estendendo.
Richiede un parametro:
La definizione del tipo di entità. Utile quando una classe viene usata per più tipi di entità, anche dinamici.
E restituisce:
Un array con le definizioni dei campi base del tipo di entità, indicizzate per nome del campo.
Quindi lo implementiamo così:
<?php
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
// Campo standard, usato come indice primario univoco.
$fields['id'] = BaseFieldDefinition::create('integer')
->setLabel(t('ID'))
->setDescription(t('The ID of the Advertiser entity.'))
->setReadOnly(TRUE);
// Campo standard, univoco a livello globale.
$fields['uuid'] = BaseFieldDefinition::create('uuid')
->setLabel(t('UUID'))
->setDescription(t('The UUID of the Advertiser entity.'))
->setReadOnly(TRUE);
return $fields;
}
?>
Da notare che:
“Fornisce le definizioni dei campi base per un tipo di entità”.
- È un metodo pubblico statico di FieldableEntityInterface.
“Classe per la definizione dei campi delle entità”.
- Contiene tutti i metodi per creare campi, aggiungere vincoli, ecc.
Entità completa
Quindi, in definitiva, avremo questo:
<?php
namespace Drupal\advertiser\Entity;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\ContentEntityInterface;
/**
* Definisce l’entità Advertiser.
*
* @ingroup advertiser
*
* @ContentEntityType(
* id = "advertiser",
* label = @Translation("advertiser"),
* base_table = "advertiser",
* entity_keys = {
* "id" = "id",
* "uuid" = "uuid",
* },
* )
*/
class Advertiser extends ContentEntityBase implements ContentEntityInterface {
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
// Campo standard, usato come indice primario univoco.
$fields['id'] = BaseFieldDefinition::create('integer')
->setLabel(t('ID'))
->setDescription(t('The ID of the Advertiser entity.'))
->setReadOnly(TRUE);
// Campo standard, univoco a livello globale.
$fields['uuid'] = BaseFieldDefinition::create('uuid')
->setLabel(t('UUID'))
->setDescription(t('The UUID of the Advertiser entity.'))
->setReadOnly(TRUE);
return $fields;
}
}
?>
Dopo aver installato il modulo, dovresti vedere che la tabella “advertiser” è stata aggiunta al database!
$ drush sql-cli mysql> SHOW TABLES;
oppure
drush sqlq "show tables like 'advertiser'" drush sqlq "describe advertiser"
Se il modulo è già installato, sarà necessario eseguire un aggiornamento delle entità.
In #2976035: Le operazioni CRUD con i tipi di entità devono usare l’ultima definizione installata, la possibilità di eseguire aggiornamenti “on demand” è stata rimossa. Consulta anche la relativa change record.
Puoi utilizzare il modulo Devel Entity Updates.