Entity API реализует API Typed Data
Значительное улучшение
- Entity API теперь реализует API Typed Data
В этой новой реализации Entity API все представляет собой поле, основанное на одном и том же API, поэтому сущности являются предсказуемыми и согласованными.
Понимание модели данных Drupal
Во-первых, прежде чем мы углубимся в сам API Typed Data, мы должны понять, как раньше воспринималась модель данных Drupal (Entity API). Это важно, потому что именно отсюда исходит API типизированных данных, а Entity API - одна из систем, для которых он был разработан.
Сущность - это сложная часть данных, состоящая из других частей данных, таких как поля со списком элементов. Элемент поля также сложен - состоит из большего количества фрагментов данных, таких как текстовое значение и формат ввода. Однако сложность заходит так далеко, что что-то можно описать как некий примитивный тип данных, такой как строка или целое число.
Упрощенный пример из Drupal 7 (пример без языкового ключа, потому что Drupal 8 обрабатывает это по-разному):
Пример 1
// Entities are complex, they contain other pieces of data. $entity; // Fields are not complex, they only contain a list of items. $entity->image; // Items are complex, they contain other pieces of data. They’re also translatable and accessible (has permissions). $entity->image[0]; // The file ID is a primitive integer. $entity->image[0][‘fid’]; // The alternative text is a primitive string. $entity->image[0][‘alt’];
Собираем все вместе
Ниже приведен упрощенный пример того, как Entity API реализует интерфейсы, отличные от API Typed Data. В действительности Entity API расширяет эти интерфейсы, добавляя дополнительные методы, которые необходимы Entity API. Тем не менее, все приведенные ниже утверждения оцениваются как истинные:
Пример 2
// Entities are complex. $entity instanceof ComplexDataInterface; // Properties are not complex, they’re only a list of items. $entity->get('image') instanceof ListInterface; // Items are complex. $entity->get('image')->offsetGet(0) instanceof ComplexDataInterface; // The typed data object representing the alt value. $entity->get('image')->offsetGet(0)->get('alt') instanceof TypedDataInterface; // The alt value is a primitive string. is_string($entity->get('image')->offsetGet(0)->get('alt')->getValue());
Ниже приведен краткий обзор того, как Entity API расширяет API Typed Data для удовлетворения некоторых дополнительных потребностей:
Пример 3
interface EntityInterface extends ComplexDataInterface, TranslatableInterface, AccessibleInterface { // ... } interface FielditemListInterface extends ListInterface { // ... } // Note that this extends two interfaces. Explanation below. interface FieldItemInterface extends ComplexDataInterface, TypedDataInterface { // ... } // Below follows some actual implementations. // Extends an abstract class with some common logic. class ImageItem extends FieldItemBase { // ... } // Extends an abstract class with some common logic. class String extends TypedData { // ... }
[Следующие два абзаца требуют дополнительной работы]
Две наиболее заметные вещи выше:
1. EntityInterface расширяет некоторые служебные интерфейсы для таких вещей, как перевод и возможности доступа. Это должно быть довольно очевидно.
2. FieldItemInterface расширяет как ComplexDataInterface, так и TypedDataInterface. Как объяснялось ранее, элементы являются сложными в том смысле, что они содержат больше фрагментов данных (например, текстовое значение и формат для текстовых элементов). Но в то же время элемент сам является частью типизированных данных, поэтому имеет свое собственное определение и тип данных.
Таким образом, чтобы подвести итог, в дополнение к примеру 2, все приведенные ниже утверждения также имеют значение true:
Пример 4
$entity instanceof EntityInterface; $entity->get('image') instanceof FieldItemListInterface; $entity->get('image')->offsetGet(0) instanceof FieldItemInterface; $entity->get('image')->offsetGet(0)->get('alt') instanceof String; is_string($entity->get('image')->offsetGet(0)->get('alt')->getValue());
Использование API
[В этом разделе нужно еще несколько примеров]
Entity API определяет некоторые магические методы, такие как __get(), чтобы обеспечить быстрый и легкий доступ к значениям полей. Таким образом, использование API очень просто, а синтаксис напоминает эпоху до Drupal 8.
Извлечение действительного значения альтернативного текста изображения будет сделано, как показано ниже:
Пример 5
// The most verbose way. $string = $entity->get('image')->offsetGet(0)->get('alt')->getValue(); // With magic added by the Entity API. $string = $entity->image[0]->alt; // With more magic added by Entity API, to fetch the first item // in the list by default. $string = $entity->image->alt;
Приведенный выше пример только добавляет хороший синтаксис к старому API. Приведенные ниже примеры демонстрируют, где проявляется реальная ценность этого API - проверка данных:
Пример 6
// Returns an array with named keys for all fields and their // definitions. For example the ‘image’ field. $property_definitions = $entity->getFieldDefinitions(); // Returns an array with name keys for all properties and their // definitions. For example the ‘file_id’ and ‘alt’ properties. $property_definitions = $entity->image ->getFieldDefinition() ->getFieldStorageDefinition() ->getPropertyDefinitions(); // Returns only definition for the ‘alt’ property. $string_definition = $entity->image ->getFieldDefinition() ->getFieldStorageDefinition() ->getPropertyDefinition('alt');
На основании приведенных выше определений мы можем теперь делать умные вещи, такие как сериализация или другой массив данных. Мы также можем предоставлять эти данные через семантически богатые API, такие как конечная точка JSON-LD, чтобы другие системы могли понять основы наших данных.
См. Https://drupal.org/node/2078241 для получения дополнительной информации о том, как определять и использовать определения полей типа сущности.
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.