logo

パレット - カラフルに🎨

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

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

Scroll

カスタムコンテンツの作成

17/05/2020, by maria

対象読者

このドキュメントは、主にオブジェクト指向PHP、Drupal 6、またはDrupal 7でのプログラミング経験を持つ開発者を対象としており、Drupal 8の原則を学びたい方も対象です。

Drupal 8でコンテンツエンティティタイプを作成するドキュメントには、利用可能な全オプションのリストが含まれています。

Drupal 8でバンドルなしのコンテンツタイプを構築する

この例では、バンドルを持たないDrupal 8のコンテンツエンティティを作成します。

このエンティティはフィールドAPIを実装しないため、コード内に留まります。とはいえ、後でより複雑なデータをインポートすることになるため、Content Entitiesを構築するための有用な骨組みとなるでしょう。

最後に、OOPの概念が関係する部分では、対応するドキュメントを参照します。

背景

私たちのモジュールはadvertiser(広告主)と呼ばれます。
私たちのコンテンツエンティティタイプはadvertiserと呼ばれます。

新しいDrupal 8のadvertiserコンテンツエンティティには、次のフィールドがあります:
- UUID
- ID

Drupal 8でのエンティティの定義

まず、すべてのカスタムエンティティはsites/all/modules/customではなくmodules/customに配置されるようになりました。

カスタムエンティティの内部の最終的なファイル構造は次のようになります:

modules/custom/advertiser$
├── advertiser.info.yml
└── src
    └── Entity
         └── Advertiser.php

参考として、完成済みのAdvertiserエンティティを、テストや制約プラグインなどの追加要素とともに確認できますが、今のところはよりシンプルに進めます。

Infoファイル

まず、module_name.info.ymlでカスタムモジュールを定義します。これは一目瞭然です:

name: Advertiser
type: module
description: 'Barebones advertiser entity'
package: custom
core: 8.x

エンティティのスケルトン

一方、Advertiserエンティティの基本クラスと関連するスキーマはsrc/Entity/Advertiser.phpで定義されています。

最初に行うのは、Advertiserエンティティクラスのnamespaceを定義することです。これは、後でクラスを使用するときに役立ちます。

namespace Drupal\advertiser\Entity;

次に、アノテーションでエンティティを定義します。

これはエンティティが読み取り、キャッシュする実際の型定義です。変更後は必ずキャッシュをクリアしてください。
<? PHP
/**
  * advertiserエンティティを定義します。
  *
  * @ingroup advertiser
  *
  * @ContentEntityType (
  * id = "advertiser",
  * label = @Translation ("Advertiser"),
  * base_table = "advertiser",
  * entity_keys = {
  * "id" = "id",
  * "uuid" = "uuid",
  *},
  *)
  */
?>

これは空のエンティティなので、Accessモジュールなどのハンドラではなく、いくつかのプロパティのみを使用します。

カスタムコンテンツエンティティを定義する機能的なモジュールがありますが、データベースに「advertiser」テーブルが作成されていないことがわかります。

$ drush sql-cli
mysql> SHOW TABLES;

これは、クラスにデータベースと明示的にやり取りするメソッドがないためです。さらに、エンティティがデータベースと満足のいく形でやり取りするために必要な最小限のメソッドの定義が必要です。

ContentEntityBase

通常、スクリプトの先頭にある名前空間定義の後にuse Drupal\Core\Entity\ContentEntityBase;のように追加することでクラスを利用できます。これにより、これらのメソッドが独自のクラスで利用可能になり、クラスはそれらを拡張したり、インターフェースの場合は実装したりできます。

私たちは2つのことを行います。データベースとのやり取りに必要なメソッドを既に持つ既存のContentEntityBaseクラスを拡張し、ContentEntityInterfaceを実装して、…を説明します。

データベースにアクセスするために必要なメソッド。これは、どのようにしてそれを達成するかを説明するものではありません。それを実現するのが実装クラスの役割です。このインターフェースは、必要なだけ何度でも、必要なだけ多くの異なる方法で実装できます。その後、インターフェースは、実際の動作方法に関係なく使用方法を定義するため、コードに影響を与えずに実装を切り替えることができます。 - https://secure.php.net/manual/en/language.oop5.interfaces.php

つまり、次のようになります:ヒント スクリプトの先頭でuse演算子を使用して新しいクラスを追加するのを忘れないでください:

class Advertiser extends ContentEntityBase implements ContentEntityInterface {

しかし、データベースに何かを保存するには、まだこれらの新しい便利なメソッドを使用する必要があります。まず、エンティティの基本フィールドから始めます。

baseFieldDefinitions

baseFieldDefinitionsメソッドは、拡張しているContentEntityBaseクラスから継承されます。
必要なパラメータは1つです:

エンティティタイプの定義。1つのクラスが複数の(おそらく動的な)エンティティタイプに使用される場合に役立ちます。

そして、これは返されます

フィールド名に基づく、エンティティタイプの基本フィールド定義の配列。

では、次のように実装します:

<?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;
  }
?>

注目すべき点:

BaseFieldDefinitions

「エンティティタイプの基本フィールド定義を表します。」

- これはFieldableEntityInterfaceの公開静的メソッドです。

BaseFieldDefinition

「エンティティのフィールドを定義するためのクラス。」

- これは、フィールドの作成制約の追加などに必要なすべてのメソッドです。

完全なエンティティ

全体として、次のようになります:

<?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;
  }
}
?>

モジュールをインストールすると、データベースに「advertiser」テーブルが追加されているはずです!

$ drush sql-cli
mysql> SHOW TABLES;

または

drush sqlq "show tables like 'advertiser'"
drush sqlq "describe advertiser"

モジュールが既にインストールされている場合は、エンティティの更新を実行する必要があります。

# 2976035: エンティティタイプのCRUD操作では、最新のインストール済みエンティティタイプとフィールドストレージ定義を使用する必要がありますで、オンデマンドでのリモート実行機能が削除されました。詳細は対応する変更記録を参照してください。

モジュールDevel Entity Updatesを参照してください。