Введение в Entity API в Drupal 8
Система сущностей Drupal 8
Сущности - это типизированные классы с методами
Generic methods |
$entity->id() |
Entity type specific methods | $node->getTitle() |
Background
Entity System была введена в конце цикла разработки Drupal 7 с базовыми стандартами загрузки Entity. Внесенный entity.module еще больше расширил API, добавив поддержку для сохранения и удаления Entity и многих других улучшений.
Большинство из этих улучшений теперь включены в Drupal 8. Проверка Entity теперь осуществляется в своем собственном API (который может проверять сущность, сохраненную с помощью REST, а не формы, например).
Два варианта
Типы Entity в ядре бывают двух вариантов.
Конфигурационный объект
Используется Configuration System. Поддерживает переводы и может предоставить пользовательские настройки по умолчанию для установок. Объекты конфигурации хранятся в общей таблице базы данных конфигурации в виде строк.
Содержание сущности
Состоит из настраиваемых и базовых полей, может иметь ревизии и поддерживать переводы. Содержимые объекты хранятся в пользовательской таблице базы данных в виде строк. Имя таблицы совпадает с именем объекта «id», а столбцы определяются методом «baseFieldDefinitions» объекта.
Связки
Связки - это разные варианты типа сущности. Например, с типом сущности узла комплектами являются разные типы узлов, такие как «статья» и «страница».
Как правило, пакет представлен объектом конфигурации, хотя в модулях contrib есть и другие модели. Таким образом, в примере узла тип узла «article» сам является объектом конфигурации. Конфигурация хранит различия между типами объектов содержимого, такими как настройки и поля. При создании нового типа сущности с пакетными Entity вы создадите как сущность контента, которая будет управлять деталями и операциями контента, так и объект конфигурации, который будет обрабатывать различия между типами Entity контента.
Аннотации
При создании нового типа сущности вам нужно будет использовать систему аннотаций, встроенную в ядро. Аннотации выглядят как комментарии docblock над классом, но анализируются и кэшируются ядром Drupal. Во многих отношениях аннотации заменяют некоторые из более старых стилей, используемых в Drupal 7.
Анализатор аннотаций
Аннотации читаются и анализируются во время выполнения механизмом аннотаций. Drupal 8 использует анализатор аннотаций Doctrine, который превращает его в объект, который может использовать PHP.
Синтаксис. Синтаксис аннотации окружен @ClassName(), состоит в основном из пар key/value pairs и может содержать массивы, использующие фигурные скобки. Ключи верхнего уровня не должны быть заключены в кавычки, а ключи массива должны быть. Каждая пара key/value pairs должна находиться на отдельной строке, и эта строка должна заканчиваться запятой. Определенные функции могут быть выполнены со значениями, особенно функция @Translation().
Неработающий пример синтаксиса аннотации:
/** * @ContentEntityType( * id = "my_entity_type_id", * label = @Translation("My entity type label"), * example_pair = "this_examples_value", * example_array = { * "array_key" = "array_value", * "some_other_key" = "some_other_value", * }, * ) */
Общие аннотации верхнего уровня
Key = "Example Value" | Описание | Entity Variant |
id = "node", |
Имя машины для типа объекта. |
Content & Config |
label = @Translation("Node"), |
Удобочитаемое имя для типа объекта. |
Content & Config |
admin_permission = "administer nodes", |
Разрешение, которое позволяет административному доступу настраивать и управлять типом объекта. Это необходимо, если ваша сущность не определяет обработчик «доступа». |
Content & Config |
bundle_label = @Translation("Content type"), |
Необязательное удобочитаемое имя для типа объекта пакета. |
Content |
bundle_entity_type = "node_type", |
При создании объекта содержимого с пакетами это значение должно быть «идентификатором» объекта конфигурации. В этом случае «node_type» является объектом конфигурации. |
Content |
base_table = "node", |
Имя таблицы базы данных для типа объекта. |
Content |
fieldable = TRUE, |
(boolean) Может ли этот тип сущности быть расширен с помощью пользовательского интерфейса поля. |
Content |
field_ui_base_route = "entity.node_type.edit_form", | Имя маршрута, к которому привязан пользовательский интерфейс поля для объекта, доступного для entity. | Content |
Handlers
Обработчики определяются в аннотации объекта как массив. Они поддерживают сущность, отображая определенные части ее выполнения в другие классы PHP. Эти классы будут «обрабатывать» назначенные части выполнения сущности.
Хранение - обрабатывает загрузку, сохранение и удаление объекта. По умолчанию объекты содержимого используют Drupal\Core\Entity\Sql\SqlContentEntityStorage, в то время как объекты конфигурации используют Drupal\Core\Config\Entity\ConfigEntityStorage. Вы можете определить обработчик хранилища, чтобы расширить стандартные методы хранения вашей сущности. Возможно, вы захотите сделать это, чтобы предоставить дополнительные методы для сбора идентификаторов редакции сущности или определения количества переводов, которые имеет сущность.
Пример: "storage" = "Drupal\node\NodeStorage",
Форма - в аннотации обработчиков любой сущности есть несколько обработчиков форм, которые отображают формы добавления, редактирования и удаления сущности в другие классы PHP.
Пример:
"form" = { "add" = "Drupal\block\BlockForm", "edit" = "Drupal\block\BlockForm", "delete" = "Drupal\block\Form\BlockDeleteForm", }
Кроме того, вы можете определить форму «по умолчанию», чтобы обрабатывать формы «добавить» и «редактировать», а не определять их отдельно. Стоит отметить, что форма «удалить» почти всегда будет обрабатываться отдельным классом от других форм. Это потому, что форма удаления, как правило, является «формой подтверждения», которая просто спрашивает, уверен ли пользователь, что хочет удалить объект.
View builder - этот обработчик предоставляет класс, который будет обрабатывать вывод сущности при просмотре конечным пользователем. Например, при посещении узла на сайте Drupal 8 вывод сущности обрабатывается классом NodeViewBuilder.
Пример: "view_builder" = "Drupal\node\NodeViewBuilder",
List builder - класс построителя списков будет обрабатывать список объектов для административных целей. Этот класс будет определять содержимое заголовков, строк и операций при посещении страницы управления сущностями для сущности. Например, при посещении URI/admin/content вашего сайта Drupal содержимое таблицы предоставляется классом построителя списка сущности Node.
Пример: "list_builder" = "Drupal\node\NodeListBuilder",
Route provider - необязательный обработчик, который, если он реализован, генерирует маршруты для управления вашим объектом. Реализация этого обработчика может заменить необходимость в путях entity, определенных в файле routing.yml вашего модуля. Обратите внимание, что route_provider работает в сочетании со ссылками, определенными для вашей сущности (см. Пример ниже раздела «Ссылки»). Аннотация route_provider представляет собой массив.
Пример:
"route_provider" = { "html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider", }
Access - Обработчик доступа может использоваться для динамической проверки разрешений вашей сущности. Это отображение на класс, который реализует EntityAccessControlHandlerInterface. Core предоставляет реализацию этого интерфейса в виде EntityAccessControlHandler, но для надежного контроля над вашей сущностью вы захотите расширить этот класс своим собственным.
Пример: "access" = "NodeAccessControlHandler",
Views data - Обработчик views_data позволяет объекту расширять модуль Views пользовательскими данными, предоставленными вашей сущностью. Это может быть для добавления baseFieldDefinitions вашей сущности в качестве полей представлений, объединения таблиц на взаимосвязях сущностей или других изменений данных, связанных с представлениями.
Пример: "views_data" = "Drupal\node\NodeViewsData",
Storage schema - Обработчик storage_schema может быть реализован для дальнейшего изменения настроек хранения базы данных объекта. Например, добавление дополнительных табличных индексов.
Пример: "storage_schema" = "Drupal\node\NodeStorageSchema",
Translation. Обработчик перевода можно использовать для изменения способа взаимодействия форм вашей сущности с переводами.
Пример: "translation" = "Drupal\node\NodeTranslationHandler",
Пример полного handlers:
Ядро Drupal предоставляет обработчики, которые вы можете использовать "из коробки", но во многих случаях вы захотите расширить эти классы своими собственными для большего контроля и настройки вашей сущности. В этом примере показана более полная аннотация обработчиков с использованием основных классов, которые вы можете расширить.
handlers = { "view_builder" = "Drupal\Core\Entity\EntityViewBuilder", "list_builder" = "Drupal\Core\Entity\EntityListBuilder", "access" = "Drupal\Core\Entity\EntityAccessControlHandler", "views_data" = "Drupal\views\EntityViewsData", "storage" = "Drupal\Core\Entity\Sql\SqlContentEntityStorage", "storage_schema" = "Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema", "translation" = "Drupal\content_translation\ContentTranslationHandler", "form" = { "default" = "Drupal\Core\Entity\ContentEntityForm", "add" = "Drupal\Core\Entity\ContentEntityForm", "edit" = "Drupal\Core\Entity\ContentEntityForm", "delete" = "Drupal\Core\Entity\ContentEntityDeleteForm", }, "route_provider" = { "html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider", }, },
Ссылки
Ссылки определяются в аннотации объекта с синтаксисом массива. Ссылки имеют определенный набор ключей, значения которых являются URI, где можно управлять типом объекта или отдельными объектами этого типа. Эти объекты могут быть определены как для контента, так и для объектов конфигурации.
Пример:
id = "node", handlers = { "route_provider" = { "html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider" } }, links = { "canonical" = "/node/{node}", "add-page" = "/node/add", "add-form" = "/node/add/{node_type}", "edit-form" = "/node/{node}/edit", "delete-form" = "/node/{node}/delete", "collection" = "/admin/content", },
Обратите внимание, что это не взято дословно из модуля Node, это только пример.
Создание этих ссылок не создает автоматически маршруты для этих URI. Чтобы сделать эти ссылки доступными, вашему модулю потребуется реализовать собственный файл routing.yml или использовать обработчик route_provider в аннотации объекта.
Ссылки и поставщик маршрутов
Приведенные выше ссылки, работающие вместе с «route_provider», сделают следующие именованные маршруты доступными для Drupal.
Ключ ссылки | Имя маршрута | Пример маршрута URI | Описание |
canonical | entity.node.canonical | /node/1 | Просмотр определенного узла |
add-page | entity.node.add_page | /node/add | Выберите узел, который будет добавлен |
add-form | entity.node.add_form | /node/add/article | Добавить узел (определенного пакета) |
edit-form | entity.node.edit_form | /node/1/edit | Редактировать форму для определенного узла |
delete-form | entity.node.delete_form | /node/1/delete | Удалить форму для определенного узла |
collection | entity.node.collection | /admin/content | Просмотр всех узлов в виде списка |
Использование ссылок
Эти ссылки могут быть доступны с помощью метода toUrl() объекта:
$view_url_object = $entity->toUrl(); // Default is 'canonical' $edit_url_string = $entity->toUrl('edit-form')->toString();
Ссылки:
- Entity API - Сгенерированная документация.
- Создание пользовательского объекта контента - Очень простой пользовательский объект.
- Создание типа entity контента в Drupal 8 - расширенный пример с обработчиками, разрешениями, маршрутизацией и ссылками.
- Создание типа объекта конфигурации в Drupal 8 - расширенный пример с обработчиками, маршрутизацией и схемой.
- [External] Entity Type Walkthrough - документация для общего типа сущности на практике
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.