Open5

【Drupal】カスタムのエンティティバリデーションの作成

ピン留めされたアイテム
WoodstockWoodstock

エンティティバリデーションとは

  • 以下のコードで実行されるバリデーションを指す。
$entity->validate();
$entity->field_name->validate();
  • フォームのバリデーションとは違い、エンティティに紐づいているため以下の特徴を持つ。
    • タイミングを問わずに実行できる。
      • フォームやフックなど好きなタイミングで上記コードを追加するだけで実行できる。
      • エンティティフォームを保存するときはデフォルトで自動的に実行される。
    • バリデーションの処理が分散しにくいので、コードの管理がしやすくなる。
WoodstockWoodstock

1. Constraint(制約)を作る

  • example/src/Plugin/Validation/Constraintの下にSymfony\Component\Validator\Constraintを継承したクラスを作成する。
  • このクラスでは、IDとエラーメッセージだけを定義する。
ExampleConstraint.php
<?php

namespace Drupal\example\Plugin\Validation\Constraint;

use Symfony\Component\Validator\Constraint;

/**
 * Example1とExample2のどちらか一方の入力が必要
 * 
 * @Constraint(
 *   id = "ExampleConstraint",
 *   label = @Translation("Example1かExample2の入力", context = "Validation"),
 *   type = "string"
 * )
 */
class ExampleConstraint extends Constraint {

  public $message = 'Example1とExample2のどちらか一方を入力してください。'

}
WoodstockWoodstock

2. Validatorを作成する

  • 上記のConstraintに対応するValidatorを作成する。
  • 場所はConstraintと同じディレクトリ。
  • Symfony\Component\Validator\ConstraintValidatorを継承する。
  • クラス名は必ず[Constraint名]Validatorにする必要がある。
  • このクラスでは、$entity->validate()メソッドが動いたときに実際に行うバリデーションを定義する。
ExampleConstraintValidator
<?php

namespace Drupal\example\Plugin\Validation\Constraint;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

/**
 * Example1とExample2の入力のバリデーションを行う。
 */
class ExampleConstraintValidator extends ConstraintValidator {

  /**
   * {@inheritdoc}
   */
  public function validate($entity, Constraint $constraint) {
    $example1 = $entity->get('example1')->getSting();
    $example2 = $entity->get('example2')->getSting();

    // Example1とExample2のどちらも空の場合、エラー
    if (empty($example1) && empty($example2)) {
      $this->context->addViolation($constraint->message);
    }
  }

}
WoodstockWoodstock

3. Constraintをエンティティに適用する

  • Constraintをエンティティタイプやフィールドに適用する。
  • 上記により、エンティティやフィールドのvalidate()実行時にConstraintに対応するValidatorのvalidate()メソッドが実行されるようになる。
/**
 * Implements hook_entity_type_alter().
 */
function example_entity_type_alter(array &$entity_types) {
  // エンティティにExample1とExample2の制約を適用する。
  $entity->addConstraint('Example');
}