公開日:
更新日:
  • WordPress

Advanced Custom Fieldsでカスタムバリデーションを実装する

目次

WordPressの管理画面に独自の入力欄を追加したいときに便利なのが、プラグイン「Advanced Custom Fields(ACF)」です。テキスト・日付・画像・セレクトボックスなどのカスタムフィールドを簡単に設置でき、業務に合わせた管理画面を構築できます。

ただし、自由に入力できるだけでは操作ミスや不整合が起こりやすくなります。便利なカスタムフィールドも、正しく入力されなければ意味がありません。

そこで重要になるのがバリデーション(入力チェック)です。この記事では、より柔軟な制御が可能な「カスタムバリデーション」の実装方法をコードとともに紹介します。

デフォルトのバリデーション機能でできること

ACFにはデフォルトのバリデーション機能があります。デフォルトのバリデーション機能では、各フィールドに次のようなバリデーションを設定できます。

  • 必須チェック(空欄を許可しない)
  • 文字数制限(最小・最大文字数)
  • 形式チェック(メールアドレス、URLなど)
  • 数値の範囲チェック(最小値・最大値)
  • ファイルの種類・サイズ制限(画像やPDFなど)

これらはフィールド編集画面の「検証」タブから設定できます。

形式チェックなど一部のバリデーションはフィールドタイプに応じて自動で適用されます。バリデーションに通らなければ投稿の公開や更新はできず、入力欄にエラーメッセージが表示されます。

多くの場合はデフォルトのバリデーションで十分ですが、「未来の日付しか選べないようにする」といった条件には対応できません。

acf/validate_valueで独自のバリデーションを追加する

デフォルトのバリデーションで対応できない条件をチェックするには、ACFが提供するacf/validate_valueフィルターを利用します。

ACF | acf/validate_value

Used to perform validation on the field's $value before being saved.

www.advancedcustomfields.com

基本構文は以下のとおりです。テーマのfunctions.phpに記述します。

functions.php
add_filter(
// 'acf/validate_value/name=...' の部分で対象フィールドを指定(name=の代わりにkey=やtype=も使える)
'acf/validate_value/name=フィールド名',
function ( $valid, $value, $field, $input ) {
// $valid: 現在のバリデーション結果(trueまたはエラーメッセージ)
// $value: フィールドに入力された値
// $field: 対象フィールドの設定情報(ラベル、タイプなど)
// $input: フォーム上のname属性。POSTデータの識別に使える
// バリデーションに成功した場合はtrueを、失敗した場合はfalseまたはエラーメッセージを返す
return $valid;
},
10,
4
);

add_filter()の第1引数に'acf/validate_value/name=フィールド名'を渡してバリデーション対象のフィールドを指定し、第2引数にバリデーション関数を渡します。

バリデーション関数は投稿の保存直前に実行されます。バリデーション関数がtrueを返せば保存が続行され、falseまたはエラーメッセージを返せば保存が失敗します。

エラーメッセージを返した場合、投稿画面にエラーメッセージが表示されます。

acf/validate_valueフィルターを利用すれば、次のような柔軟なチェックが可能になります。

  • 入力値が指定フォーマットに一致しているか
  • 他のフィールドとの値の比較(例:開始日 < 終了日)

次のセクションでは、「未来の日付しか選べないようにする」バリデーションの実装例を紹介します。

実装例①:締切日が現在より未来であることをチェック

カスタムフィールド締切日の入力値が未来の日付であることをカスタムバリデーションでチェックします。

カスタムフィールドの設定は以下のとおりです。

  • ラベル:締切日
  • フィールド名:deadline
  • フィールドタイプ:日時選択ツール
  • 戻り値の形式:Y-m-d H:i:s

このままだと過去の日付も選択できてしまうため、次のコードをfunctions.phpに追加します。

functions.php
add_filter(
'acf/validate_value/name=deadline', // バリデーションを適用するフィールド名を指定
function ( $valid, $value ) {
// 既にバリデーションが失敗している場合は、その結果をそのまま返す
if ( ! $valid ) {
return $valid;
}
// 入力された日付が現在より未来の日付であるかをチェック
return new DateTime() < new DateTime( $value )
? $valid
: '締切日は現在より未来の日付を選択してください。';
},
10,
4
);

このコードでは、締切日に入力された日付が現在よりも未来かどうかをDateTimeで比較しています。過去の日付であれば、エラーメッセージを返してバリデーションエラーとします。

このようにカスタムバリデーションを活用することで、ユーザーの入力ミスを防ぎ正しい情報だけが保存されるように制御できます。

実装例②:開始日と終了日の前後関係をチェック

次に、2つの日付フィールドの前後関係をチェックするケースを紹介します。ここでは開始日終了日という2つのカスタムフィールドを使用します。

カスタムフィールドの設定は以下のとおりです。

  • ラベル:開始日
  • フィールド名:start_date
  • フィールドタイプ:日付選択ツール
  • 戻り値の形式:Ymd
  • ラベル:終了日
  • フィールド名:end_date
  • フィールドタイプ:日付選択ツール
  • 戻り値の形式:Ymd

functions.phpに、次のコードを追加します。

functions.php
add_filter(
'acf/validate_value/name=end_date',
function ( $valid, $value ) {
// 既にバリデーションが失敗している場合は、その結果をそのまま返す
if ( ! $valid ) {
return $valid;
}
// POSTデータから開始日を取得
$post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0;
$start_date_field = get_field_object( 'start_date', $post_id );
$start_date_key = $start_date_field['key'] ?? null;
$start_date = isset( $_POST['acf'][ $start_date_key ] ) ? sanitize_text_field( wp_unslash( $_POST['acf'][ $start_date_key ] ) ) : null;
// 開始日が存在し、かつ終了日が開始日より後の日付であるかをチェック
return $start_date && new DateTime( $start_date ) < new DateTime( $value )
? $valid
: '終了日は開始日より後の日付を選択してください。';
},
10,
4
);

ここでは終了日がバリデーション対象のため終了日の値は$valueとして取得できますが、開始日$_POSTから取得する必要があります。get_field_object()でフィールドキーを取得し配列から開始日の値を取り出します。2つの値をDateTimeで比較し、終了日開始日より前の日付であればエラーメッセージを返すようにしています。

このように開始日と終了日のような複数フィールド間の関係も、カスタムバリデーションを使えば柔軟にチェックできます。

まとめ

  • 簡単なチェックならACFのデフォルトのバリデーション機能で対応できる
  • acf/validate_valueフィルターで独自のバリデーションを追加できる
  • 独自バリデーションでは単体の値だけでなく、複数フィールド間の関係もチェックできる

検証環境とサンプルコード

  • PHP 8.2.28
  • WordPress 6.8.1
  • Advanced Custom Fields 6.4.0.1

今回のサンプルコードはGitHubで公開しています。

松田 拓也
エンジニア

フロントエンドエンジニア。制作会社および事業会社での実務経験を経て、greenciderに参画。コーディングから保守運用まで、WEBサイト制作における実装業務を担当。趣味は読書、登山、野球観戦、美術鑑賞など。