logo

パレット - カラフルに🎨

Palette — ビジュアルページビルダー、デザインの専門知識は不要です。

ライブデモ パレットをダウンロード

Scroll

Entity API は Typed Data API を実装する

17/05/2020, by maria

重要な改善

  • 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 を参照してください。