Entity Reference Integrity
エンティティ参照フィールドのターゲットとなっているエンティティを削除から保護するモジュール。
entity_reference_integrity
インストール
composer require 'drupal/entity_reference_integrity:^2.0'
composer require 'drupal/entity_reference_integrity:8.x-1.3'
概要
Entity Reference Integrityは、Drupalサイトにおけるエンティティ参照の整合性を維持するためのモジュールです。エンティティ参照フィールドによって他のエンティティから参照されているエンティティが削除されることを防ぎ、データベースの参照整合性を保護します。
このモジュールは2つの部分で構成されています。メインモジュール(entity_reference_integrity)は、エンティティが他のエンティティから参照されているかどうかをプログラムで検出するためのAPIを提供します。サブモジュール(entity_reference_integrity_enforce)は、実際に削除を阻止する強制機能を提供し、管理画面から保護するエンティティタイプを設定できます。
保護が有効化されたエンティティタイプは、削除フォームでの削除ボタンが無効化され、どのエンティティが参照しているかの一覧が表示されます。また、JSON:APIなどのAPI経由での削除も403エラーで拒否されます。プログラムからの直接削除を試みた場合は、ProtectedEntityException例外がスローされます。
Features
- エンティティが他のエンティティ参照フィールドから参照されているかどうかを検出するAPI
- 参照元エンティティの一覧を取得するメソッド(ID一覧または読み込み済みエンティティ一覧)
- エンティティタイプ単位での削除保護の有効化/無効化設定
- 削除フォームでの削除ボタン無効化と参照元エンティティの表示
- JSON:API経由での削除リクエストに対する403アクセス拒否
- 一括削除アクション(Views Bulk Operations等)での保護対応
- プログラムからの削除試行時のProtectedEntityException例外スロー
- 大規模サイトでのパフォーマンス向上のため、参照元エンティティ表示数を最大10件に制限
Use Cases
タクソノミーターム(カテゴリ)の保護
コンテンツで使用されているタクソノミータームが誤って削除されることを防ぎます。例えば、記事に付けられたカテゴリータームは、その記事が存在する限り削除できなくなります。設定画面で taxonomy_term を有効にすることで保護されます。
ユーザーアカウントの保護
コンテンツの作成者として参照されているユーザーアカウントの削除を防ぎます。ノードのuid(作成者)フィールドはentity_referenceフィールドなので、ユーザーを保護対象にすると、そのユーザーが作成したコンテンツがある限り削除できません。
メディアアセットの保護
コンテンツで参照されているメディアエンティティ(画像、ドキュメント等)が削除されることを防ぎます。Media Libraryと組み合わせて使用することで、使用中のメディアの誤削除を防止できます。
ブロックコンテンツの保護
Layout Builderなどで配置されているカスタムブロックが削除されることを防ぎます。ブロックがレイアウトで参照されている場合、削除を阻止できます。
カスタムAPIでの参照チェック
独自のモジュールでエンティティ削除前に参照をチェックしたい場合、APIを直接使用できます。$handler = $entityTypeManager->getHandler('node', 'entity_reference_integrity'); if ($handler->hasDependents($entity)) { /* 処理 */ } といった形で使用します。
Tips
- メインモジュールはAPIのみを提供し、実際の保護機能はサブモジュール(Entity Reference Integrity Enforce)で提供されます。両方を有効にする必要があります。
- 保護するエンティティタイプは慎重に選択してください。すべてのエンティティタイプを保護すると、運用上の問題が発生する可能性があります。
- カスタムモジュールでは、エンティティハンドラーを取得して hasDependents() メソッドで事前にチェックすることで、より良いユーザー体験を提供できます。
- 削除フォームでは参照元エンティティへのリンクが表示されるため、ユーザーは参照を解除してから削除することができます。
- hook_entity_predeleteの実行順序が調整されており、このモジュールのフックが最初に実行されます。これにより、他のモジュールが参照を自動的にクリーンアップする前に保護が適用されます。
- APIのみを使用したい場合(強制なし)は、メインモジュールのみを有効化し、独自のロジックで参照チェックを実装できます。
Technical Details
Admin Pages 1
/admin/config/content/entity-reference-integrity
参照整合性を維持するエンティティタイプを設定する画面です。ここで選択されたエンティティタイプは、他のエンティティから参照されている場合に削除が阻止されます。
権限 1
Hooks 1
hook_entity_type_alter
全エンティティタイプに対して 'entity_reference_integrity' ハンドラーを自動的に登録します。これにより、任意のエンティティに対して参照チェックAPIを使用できるようになります。
Troubleshooting 5
キャッシュをクリアしてください(drush cr)。また、削除フォームに表示される参照元エンティティ一覧を確認してください。アクセス権限がない参照元エンティティは「Access to some entities is restricted」と表示されます。
「administer entity reference integrity enforce」パーミッションが必要です。このパーミッションはアクセス制限付きなので、通常のロール設定画面で見つけやすい位置にない場合があります。
設定画面(/admin/config/content/entity-reference-integrity)で該当エンティティタイプにチェックが入っているか確認してください。また、そのエンティティタイプを参照するフィールドがentity_referenceタイプであることを確認してください。
ProtectedEntityExceptionがスローされるのは正常な動作です。削除前に参照を解除するか、try-catchで例外を処理してください。
最新バージョンでは参照元エンティティの表示が最大10件に制限されています。また、参照チェック自体はデータベースのCOUNTクエリで効率的に行われます。
Security Notes 2
- 「administer entity reference integrity enforce」パーミッションは「restrict access」が設定されており、信頼できる管理者にのみ付与してください。この設定により、悪意あるユーザーが保護を無効化することを防げます。
- JSON:API経由での削除は hook_entity_access で制御されており、APIエンドポイントでも一貫した保護が適用されます。