Создание пользовательского контента
Зрительская аудитория
Эта документация предназначена в первую очередь для разработчиков, имеющих опыт программирования на объектно-ориентированной PHP, Drupal 6 или Drupal 7, а также для тех, кто хочет изучить принципы Drupal 8.
Документация по созданию типа сущности контента в Drupal 8 включает полный список доступных опций.
Построение типа содержимого без связки в Drupal 8.
В этом случае мы создаем объект контента Drupal 8, который не имеет никаких пакетов.
Сущность не реализует API поля, поэтому она остается в коде. Тем не менее, это может быть полезным каркасом для построения Content Entities, поскольку мы импортируем более сложные данные позже.
Наконец, где есть некоторые концепции ООП, я буду ссылаться на соответствующие документы.
Фон.
Наш модуль называется рекламодателем.
Наш тип сущности контента называется рекламодателем.
Наш новый контент-контент рекламодателя Drupal 8 будет иметь поля:
- UUID
- ID
Определение содержимого объекта в Drupal 8.
Во-первых, все пользовательские объекты теперь живут в modules/custom вместо того, чтобы находиться в sites/all/modules/custom.
Внутри нашего пользовательского объекта файловая структура, с которой мы в итоге получим, выглядит следующим образом:
modules/custom/advertiser$ ├── advertiser.info.yml └── src └── Entity └── Advertiser.php
Для справки вы можете просмотреть готовую сущность Advertiser вместе с дополнительными дополнениями, такими как тесты и плагины ограничений, но пока что все будет проще.
Info file
Мы начнем с определения нашего пользовательского модуля в module_name.info.yml. Это говорит само за себя:
name: Advertiser type: module description: 'Barebones advertiser entity' package: custom core: 8.x
Скелет сущности
Между тем базовый класс сущности Advertiser и связанная с ним схема определены в src/Entity/Advertiser.php.
Первое, что мы делаем, это определяем namespace для нашего Advertiser Entity Class. Это пригодится, когда мы захотим использовать наши классы.
namespace Drupal\advertiser\Entity;
Теперь пришло время определить нашу сущность, что мы делаем в аннотации.
Это фактическое определение типа объекта, который он читает и кэширует, поэтому обязательно очищайте кеш после любых изменений.
<? PHP / ** * Определяет сущность рекламодателя. * * @ingroup рекламодатель * * @ContentEntityType ( * id = "рекламодатель", * label = @Translation ("Рекламодатель"), * base_table = "рекламодатель", * entity_keys = { * "id" = "id", * "uuid" = "uuid", *}, *) * / ?>
Поскольку это пустая сущность, мы используем только несколько свойств, а не обработчики, такие как модуль Access.
У нас есть функциональный модуль, который определяет нашу пользовательскую сущность контента, но мы увидим, что таблица «рекламодатель» не была создана в базе данных.
$ drush sql-cli mysql> SHOW TABLES;
Это потому, что в нашем классе нет методов, которые явно взаимодействуют с базой данных. Кроме того, нам необходимо описание самого необходимого минимума методов, необходимых для удовлетворительного взаимодействия сущности с базой данных.
ContentEntityBase
Обычно мы можем добавлять классы, добавляя что-то вроде use Drupal\Core\Entity\ContentEntityBase; после нашего определения пространства имен в верхней части нашего скрипта. Это делает эти методы доступными для нашего собственного класса, который может расширять их или, в случае интерфейсов, реализовывать их.
Мы делаем две вещи, расширяем существующий класс ContentEntityBase, который уже имеет необходимые методы для взаимодействия с БД, и реализуем ContentEntityInterface для описания ...
методы, которые нам нужны для доступа к нашей базе данных. Это НЕ описывает, каким образом мы этого добиваемся. Вот что делает класс IMPLEMENTing. Мы можем РЕАЛИЗОВАТЬ этот интерфейс столько раз, сколько нам нужно, так много разных способов, как нам нужно. Затем мы можем переключаться между реализациями интерфейса без ущерба для нашего кода, потому что интерфейс определяет, как мы будем его использовать, независимо от того, как он на самом деле работает. - https://secure.php.net/manual/en/language.oop5.interfaces.php
Все это означает, что мы получаем следующее: Совет Не забудьте добавить любые новые классы с помощью оператора use в верхней части нашего скрипта:
class Advertiser extends ContentEntityBase implements ContentEntityInterface {
Но нам все еще нужно использовать эти новые полезные методы, чтобы поместить что-то в базу данных, мы начнем с основных полей для нашей сущности.
baseFieldDefinitions
Метод baseFieldDefinitions происходит из класса ContentEntityBase, который мы расширяем.
Требуется один параметр:
Определение типа объекта. Полезно, когда один класс используется для нескольких, возможно, динамических типов объектов.
И это возвращается
Массив базовых определений полей для типа объекта, основанный на имени поля.
Итак, мы реализуем это так:
<?php public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { // Standard field, used as unique if primary index. $fields['id'] = BaseFieldDefinition::create('integer') ->setLabel(t('ID')) ->setDescription(t('The ID of the Advertiser entity.')) ->setReadOnly(TRUE); // Standard field, unique outside of the scope of the current project. $fields['uuid'] = BaseFieldDefinition::create('uuid') ->setLabel(t('UUID')) ->setDescription(t('The UUID of the Advertiser entity.')) ->setReadOnly(TRUE); return $fields; } ?>
Стоит отметить, что:
«Предоставляет определения базового поля для типа объекта».
- Это открытый статический метод из FieldableEntityInterface.
«Класс для определения полей сущностей».
- Все методы, которые нам нужны для создания полей, добавления ограничений и т. д.
Полная сущность
Итак, в целом у нас есть это:
<?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; /** * Defines the 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) { // Standard field, used as unique if primary index. $fields['id'] = BaseFieldDefinition::create('integer') ->setLabel(t('ID')) ->setDescription(t('The ID of the Advertiser entity.')) ->setReadOnly(TRUE); // Standard field, unique outside of the scope of the current project. $fields['uuid'] = BaseFieldDefinition::create('uuid') ->setLabel(t('UUID')) ->setDescription(t('The UUID of the Advertiser entity.')) ->setReadOnly(TRUE); return $fields; } } ?>
После установки вашего модуля вы должны увидеть, что таблица «рекламодатель» была добавлена в базу данных!
$ drush sql-cli mysql> SHOW TABLES;
или
drush sqlq "show tables like 'advertiser'" drush sqlq "describe advertiser"
Если ваш модуль уже установлен, вам нужно будет выполнить обновление сущностей.
В # 2976035: Операции CRUD с типом объекта должны использовать последний установленный тип объекта и определения хранилища полей, возможность удаленного запуска по запросу была удалена, см. Дополнительную информацию в соответствующей записи об изменениях.
Пожалуйста, смотрите модуль Devel Entity Updates.
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.