Erstellung benutzerdefinierter Inhalte
Zielpublikum
Diese Dokumentation richtet sich in erster Linie an Entwickler mit Erfahrung in objektorientiertem PHP, Drupal 6 oder Drupal 7 sowie an diejenigen, die die Prinzipien von Drupal 8 erlernen möchten.
Dokumentation zur Erstellung eines Content Entity Typs in Drupal 8 enthält eine vollständige Liste der verfügbaren Optionen.
Erstellung eines Content Types ohne Bundle in Drupal 8.
In diesem Fall erstellen wir ein Drupal 8 Content Entity Objekt ohne Bundles.
Das Entity implementiert nicht das Field API, daher verbleibt es im Code. Dennoch kann es als nützliches Gerüst für den Aufbau von Content Entities dienen, da wir später komplexere Daten importieren.
Schließlich werde ich bei einigen OOP-Konzepten auf entsprechende Dokumentationen verweisen.
Hintergrund.
Unser Modul heißt advertiser.
Unser Content Entity Typ heißt ebenfalls advertiser.
Unser neues Drupal 8 Content Entity advertiser wird die Felder haben:
- UUID
- ID
Definition des Content Objekts in Drupal 8.
Erstens leben nun alle benutzerdefinierten Entities in modules/custom anstelle von sites/all/modules/custom.
Innerhalb unseres Custom Entity sieht die Dateistruktur am Ende folgendermaßen aus:
modules/custom/advertiser$ ├── advertiser.info.yml └── src └── Entity └── Advertiser.php
Zur Referenz können Sie sich die fertige Advertiser Entity mit zusätzlichen Ergänzungen wie Tests und Constraint Plugins anschauen, aber vorerst bleibt alles einfach.
Info-Datei
Wir beginnen mit der Definition unseres Custom Modules in module_name.info.yml. Das erklärt sich von selbst:
name: Advertiser type: module description: 'Barebones advertiser entity' package: custom core: 8.x
Entity-Skelett
Der Basis-Klassenentwurf der Advertiser Entity und das zugehörige Schema befinden sich in src/Entity/Advertiser.php.
Als Erstes definieren wir den Namespace für unsere Advertiser Entity Klasse. Das ist wichtig, damit wir später unsere Klassen verwenden können.
namespace Drupal\advertiser\Entity;
Nun definieren wir unsere Entity in der Annotation.
Dies ist die tatsächliche Definition des Entity Typs, den Drupal einliest und cached, also unbedingt nach Änderungen den Cache leeren.
<?php /** * Definiert die Advertiser Entity. * * @ingroup advertiser * * @ContentEntityType( * id = "advertiser", * label = @Translation("Advertiser"), * base_table = "advertiser", * entity_keys = { * "id" = "id", * "uuid" = "uuid", * }, * ) */ ?>
Da dies eine minimalistische Entity ist, verwenden wir nur wenige Properties und keine Handler wie etwa Access.
Wir haben nun ein funktionierendes Modul, das unsere benutzerdefinierte Content Entity definiert, jedoch wird die Tabelle „advertiser“ noch nicht in der Datenbank angelegt.
$ drush sql-cli mysql> SHOW TABLES;
Das liegt daran, dass unsere Klasse noch keine Methoden implementiert, die explizit mit der Datenbank interagieren. Außerdem brauchen wir eine Beschreibung der minimal notwendigen Methoden, um ein zufriedenstellendes DB-Handling zu gewährleisten.
ContentEntityBase
Üblicherweise fügen wir Klassen hinzu, indem wir use Drupal\Core\Entity\ContentEntityBase; nach dem Namespace in unserem Skript einfügen. Dadurch stehen diese Methoden in unserer eigenen Klasse zur Verfügung, die wir erweitern oder implementieren können.
Wir machen zwei Dinge: Wir erweitern die bestehende Klasse ContentEntityBase, die bereits die nötigen Methoden für DB-Interaktion besitzt, und implementieren das Interface ContentEntityInterface, das ...
die Methoden beschreibt, die wir für DB-Zugriffe benötigen. Es beschreibt NICHT, wie wir das erreichen. Genau das macht die Klasse, die das Interface IMPLEMENTIERT. Wir können dieses Interface beliebig oft auf verschiedene Arten implementieren. So können wir zwischen den Implementierungen wechseln, ohne den Code zu ändern, denn das Interface definiert, wie wir es nutzen, unabhängig von der tatsächlichen Funktionsweise. – https://secure.php.net/manual/en/language.oop5.interfaces.php
Das heißt, wir erhalten Folgendes. Tipp: Vergessen Sie nicht, alle neuen Klassen mit use ganz oben im Skript einzubinden:
class Advertiser extends ContentEntityBase implements ContentEntityInterface {
Aber wir müssen noch diese nützlichen Methoden nutzen, um tatsächlich etwas in die Datenbank zu speichern. Wir starten mit den Basisfeldern unserer Entity.
baseFieldDefinitions
Die Methode baseFieldDefinitions stammt aus der Klasse ContentEntityBase, die wir erweitern.
Sie erhält einen Parameter:
Die Definition des Entity Typs. Nützlich, wenn eine Klasse für mehrere dynamische Entity Typen verwendet wird.
Und sie gibt zurück:
Ein Array von Basisfeld-Definitionen für den Entity Typ, nach Feldnamen geordnet.
So implementieren wir sie:
<?php public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { // Standardfeld, verwendet als eindeutiger Primärschlüssel. $fields['id'] = BaseFieldDefinition::create('integer') ->setLabel(t('ID')) ->setDescription(t('Die ID der Advertiser Entity.')) ->setReadOnly(TRUE); // Standardfeld, eindeutig außerhalb des aktuellen Projekts. $fields['uuid'] = BaseFieldDefinition::create('uuid') ->setLabel(t('UUID')) ->setDescription(t('Die UUID der Advertiser Entity.')) ->setReadOnly(TRUE); return $fields; } ?>
Es ist wichtig zu wissen, dass:
„Stellt Basisfelddefinitionen für einen Entity Typ bereit“.
– Es ist eine public static Methode des FieldableEntityInterface.
„Klasse zur Definition von Entity-Feldern“.
– Alle nötigen Methoden zum Erstellen, Hinzufügen von Constraints etc. sind hier verfügbar.
Vollständige Entity Klasse
Also haben wir insgesamt:
<?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; /** * Definiert die Advertiser Entity. * * @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) { // Standardfeld, verwendet als eindeutiger Primärschlüssel. $fields['id'] = BaseFieldDefinition::create('integer') ->setLabel(t('ID')) ->setDescription(t('Die ID der Advertiser Entity.')) ->setReadOnly(TRUE); // Standardfeld, eindeutig außerhalb des aktuellen Projekts. $fields['uuid'] = BaseFieldDefinition::create('uuid') ->setLabel(t('UUID')) ->setDescription(t('Die UUID der Advertiser Entity.')) ->setReadOnly(TRUE); return $fields; } } ?>
Nach der Installation Ihres Moduls sollten Sie sehen, dass die Tabelle „advertiser“ in der Datenbank angelegt wurde!
$ drush sql-cli mysql> SHOW TABLES;
oder
drush sqlq "show tables like 'advertiser'" drush sqlq "describe advertiser"
Falls Ihr Modul bereits installiert ist, müssen Sie ein Entity-Update durchführen.
Im Issue #2976035: CRUD Operationen mit Entity Types sollten die zuletzt installierten Entity- und Feld-Storage-Definitionen nutzen wurde die Möglichkeit für remote-requested Runs entfernt, siehe detaillierte Informationen im entsprechenden Change Record.
Bitte sehen Sie sich das Modul Devel Entity Updates an.
Drupal’s online documentation is © 2000-2020 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.