0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

EntityForm って何? — フォームが表示される仕組みから差し替えまで

0
Last updated at Posted at 2026-04-29

AI による要約

本記事は、Drupal の EntityForm とは何かという疑問を起点に、フォームが表示される仕組みをコアのソースコードから解説した記事です。エンティティのアノテーションによるフォームクラスの宣言、Entity Form Display を通じたフィールドの自動挿入、そして hook_entity_type_alter() を使った独自フォームへの差し替えまでを、実際に動作するサンプルモジュールを通じて確認しています。

EntityForm とは

エンティティ(ノード、ユーザ、タクソノミー等)の CRUD フォームを担当する基底クラスのことです。

User エンティティ等に設定されている初期フォーム

User エンティティ等には、初期フォームが設定されています。

image.png

初期フォームの表示される仕組み

この初期フォームが表示される仕組みとしては、ソースコード側のエンティティのクラスのアノテーションにおいて使用するフォームを宣言しているというものです。

ユーザクラスであれば下記のように、 @ContentEntityType アノテーションで指定しています。

// core/modules/user/src/Entity/User.php

/**
 * @ContentEntityType(
 *   id = "user",
 *   ...
 *   handlers = {
 *     "form" = {
 *       "default" = "Drupal\user\ProfileForm",
 *       "register" = "Drupal\user\RegisterForm",
 *       "cancel" = "Drupal\user\Form\UserCancelForm",
 *     },
 *   },
 *   ...
 * )
 */
class User extends ContentEntityBase implements UserInterface {

別のフォームを使用する方法

フォームクラスの定義

例) User エンティティに適用するエンティティを書き換える場合

ProfileForm を拡張して、別のフォームクラスを作成します。

class MyUserForm extends ProfileForm {

  public function buildForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildForm($form, $form_state);

    // 不要な項目を全部消す
    unset($form['account']['mail']);
    unset($form['account']['pass']);

    // 独自フィールドを追加
    $form['bio'] = [
      '#type'  => 'textarea',
      '#title' => t('自己紹介'),
    ];

    return $form;
  }
}

適用するクラスの変更(上書き)

その後、 hook_entity_type_build(), hook_entity_type_alter() 等の hook 関数の中で setFormClass() 関数を呼び出し、アノテーションを書き換えるのと同等の処理を行います。

function my_module_entity_type_alter(array &$entity_types) {
  $entity_types['user']->setFormClass('default', MyUserForm::class);
}

Tips: hook_entity_type_buildhook_entity_type_alter の違い

既存のフォームを上書きする場合は hook_entity_type_alter() 、フォームを新規に追加する場合は hook_entity_type_build() みたいです。

より正確に述べると下記のようになるとのこと by Claude

// 曖昧
「フォームを新規に追加する場合は hook_entity_type_build()」

// 正確
「既存エンティティに新しい FormMode キーを追加する場合は hook_entity_type_build()」
「既存の FormMode キーに登録されたクラスを差し替える場合は hook_entity_type_alter()」

なので、今回のユースケースで使うのは、 alter() の方がメインです。

Tips: FormMode とは。 EntityForm と何が違うのか。

EntityForm は PHP クラスです。これと "FormMode" キーとの対応を定義しているのが、アノテーションやこの hook 関数です。

FormMode キーと EntityForm の新しい対応を Entity に追加する場合は hook_entity_type_build() で、上書きする場合は hook_entity_type_alter() です。

サンプルを使った動作検証

目的

hook_entity_type_alter()default フォームを差し替えることで、 /user/{user}/edit の表示が変わることを確認することです。

検証手順

1. モジュールの雛形を用意する

drush generate module
# Module name: form_test
# Machine name: form_test

2. フォームクラスを作成する

// modules/custom/form_test/src/Form/MyUserForm.php

namespace Drupal\form_test\Form;

use Drupal\user\ProfileForm;
use Drupal\Core\Form\FormStateInterface;

class MyUserForm extends ProfileForm {

  public function buildForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildForm($form, $form_state);

    // 動作確認用のメッセージを追加
    \Drupal::messenger()->addMessage('MyUserForm が適用されています');

    // メールとパスワードを非表示
    unset($form['account']['mail']);
    unset($form['account']['pass']);

    return $form;
  }
}

3. hook を実装する

// modules/custom/form_test/form_test.module

use Drupal\form_test\Form\MyUserForm;

function form_test_entity_type_alter(array &$entity_types) {
  if (isset($entity_types['user'])) {
    $entity_types['user']->setFormClass('default', MyUserForm::class);
  }
}

4. キャッシュをクリアして確認

drush cr

5. 確認ポイント

/user/1/edit にアクセスします。

image.png

比較すると、下記が変更されていることがわかります。

  • 画面上部にメッセージが出る
  • メールフィールドが消えている
  • パスワードフィールドが消えている

image.png

6. 元に戻す確認(念のため)

モジュールを無効化すると標準の ProfileForm に戻ることも確認しておくと、hook が正しく機能していることの裏付けになります。

drush pmu form_test
drush cr
# /user/1/edit でメールとパスワードが復活していることを確認

あとがき

ということで、 EntityForm を拡張し、 Entity に設定することで、フォームを変更できることが確認できました。

終わり。

image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?