Entity API は Typed Data API を実装する
重要な改善
- Entity API は現在、Typed Data API を実装しています
この新しい Entity API の実装では、すべてが同じ API に基づくフィールドであるため、エンティティは予測可能で一貫性があります。
Drupal データモデルの理解
まず、Typed Data API 自体に踏み込む前に、Drupal のデータモデル(Entity API)が以前どのように認識されていたかを理解する必要があります。型付きデータ API はここから来ており、Entity API はそれが設計されたシステムの1つであるため、これは重要です。
エンティティは、アイテムのリストを持つフィールドなど、他のデータの断片で構成される複雑なデータです。フィールドアイテムもまた複雑で、テキスト値と入力形式などのより多くのデータの断片で構成されています。ただし、複雑さは、何かを文字列や整数などのプリミティブデータ型として記述できるところまで達します。
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 が Typed Data API のインターフェイスを実装する方法の簡略化した例です。実際には、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 がいくつかの追加ニーズに対応するために Typed Data API をどのように拡張するかについての簡単な概要です:
例 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 {
// ...
}
[次の2つの段落はさらなる作業が必要です]
上記の最も顕著な2つの点:
1. EntityInterface は、翻訳やアクセス権などのためのいくつかのユーティリティインターフェイスを拡張します。これはかなり明白なはずです。
2. FieldItemInterface は、ComplexDataInterface と TypedDataInterface の両方を拡張します。前述のように、アイテムはより多くのデータの断片(たとえば、テキストアイテムのテキスト値と形式)を含むという意味で複雑です。しかし同時に、アイテム自体が型付きデータの一部であるため、独自の定義とデータ型を持っています。
要約すると、例 2 に加えて、以下のステートメントもすべて真です:
例 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');
上記の定義に基づいて、シリアル化やその他のデータ配列などのスマートなことを行うことができます。また、JSON-LD エンドポイントなどの意味的にリッチな API を介してこのデータを提供できるため、他のシステムがデータの基礎を理解できます。
エンティティタイプのフィールド定義の定義と使用の詳細については、Https://drupal.org/node/2078241 を参照してください。