【Drupal】バンドルクラスを使ってみる

【Drupal】バンドルクラスを使ってみる
sinceretechnology

 

 

 

はじめに

 

Drupal 9.3では、DrupalエンティティAPIにバンドルクラスというとてもクールな開発者向けの新機能が追加されました。そこで、これがどのように機能し、どのような変更点があるのかを簡単に説明します。

 

まず、「良い」コードとは何でしょうか?良いコードとは一般的に以下の特徴があります。

  • 宣言的(Declarative)であること。処理の意図が明確であり、細かな処理の手続きは内部に隠蔽されている。
  • テスト可能であること。テスト可能なコードは、依存関係を明示的に宣言し、入力と出力を明確にしている。

 

これを念頭に置いて、カスタムバンドルクラスとは何かを探ってみると、バンドルクラスはエンティティの周りのビジネスロジックをカプセル化するクラスらしいです。

エンティティバンドルは基本的にビジネスオブジェクトであり、必要なビジネスロジックをカプセル化した独自のクラスを宣言できるようになりました。

 

以下のサンプルコードと説明は以下のサイトを翻訳・引用させていただきました。

バンドルクラスの使い方

 

バンドル固有のエンティティクラスを定義するために必要なことは、主に2つあります。

まず、メインのエンティティクラスを継承したクラスを作成します。例えば、”EntityArticle “は “EntityNode “を継承しています。エンティティクラスから継承されていない場合、DrupalはBundleClassInheritanceExceptionをスローします。バンドルクラスは、独自のインターフェイスを実装したり、複数のバンドルで使用されるベースクラスを持ったり、必要に応じて様々なtraitを使用したりできます。

 

次に、このクラスは適用するエンティティバンドル上で定義する必要があります。私たちに属するエンティティの場合は、hook_entity_bundle_info()をこのように実装する必要があります:

 
use \Drupal\my_module\Entity\Brand;

function hook_entity_bundle_info() {
  $bundles['my_entity']['my_bundle']['class'] = Brand::class;
  return $bundles;
}

 

例えばNodeのような他のモジュールから来たエンティティには、alterフックを使います:

 
use \Drupal\my_module\Entity\Article;

function my_module_entity_bundle_info_alter(array &$bundles) {
  $bundles['node']['article']['class'] = Article::class;
}

 

注意点としては、AmbiguousBundleClassExceptionが発生しないように、同じクラスを複数のバンドルに使用しないことです。バンドル間でロジックを再利用したい場合は、個々のバンドルクラスが共有できる基底クラスか trait を考えてください。

 

そして、これが注意すべきことの大部分です。特に、エンティティストレージが複数のエンティティを一度に読み込むことができるようになり、同じバンドルクラスを使うかどうか、個別にインスタンス化する必要があるかどうかといった点です。しかし、それ以外は、エンティティの保存とロードを扱うカスタムコードへの影響を最小限に抑えながら、これまで通り動作するはずです。

 

詳細はDrupal公式サイトをご覧ください。

https://www.drupal.org/node/3191609

 

 

 

 

さいごに

これまで独自クラスを作成して呼び出していたビジネスロジックをバンドル(特定のエンティティタイプを継承したカスタムエンティティタイプ)ごとにバンドルクラスを作成することができるようになりました。

バンドルクラスを一度定義しておくと、対象のバンドルのエンティティを呼び出した際にバンドルクラスも同時に呼び出されて、バンドルクラスに定義済みのメソッドまたはファンクションが簡単に利用できます。この機能を利用するとデータベース周りの細かなビジネスロジックをバンドルごとに内包できるので、ソースコードの可読性が高まり保守性が一段と向上するでしょう!

 

 

 

 

参考

 

 

 

 


この記事に関するご質問やご意見などございましたらお問い合わせフォームからお気軽にご連絡ください。