Cakephp PHP WEB開発

【Cakephp4】標準バリデートdate()は2999年までしか対応していない件

※本サイトはPR表記を含みます。

Cakephp4標準の date() バリデートは2999年までしか対応してないようです。なので、例えば 3000-01-01 などのような日付が渡ってくる場合、問答無用で検証エラーとなります。あまりないケースかもですが、もし 2999年 移行の日付フォーマットチェックをしたい場合、以下のようにするのが良いかと思います。

Cake4: 対応策としてカスタムバリデートで別途日付チェック定義をする

- CustomValidation.php

<?php
declare(strict_types=1);

namespace App\Model\Validation;

use Cake\Validation\Validation;

class CustomValidation extends Validation
{
    /**
     * 日付フォーマット検証
     *
     * @param string $data 当該カラム値
     * @param array $context コンテキスト リクエストデータ群など
     * @return bool
     */
    public static function validateDate($data, $context): bool
    {
        if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/", $data)) {
            [$y, $m, $d] = explode('-', $data);
            if (checkdate((int)$m, (int)$d, (int)$y)) {
                return true;
            }
        }

        return false;
    }
}

シンプルに preg_match() 関数で日付フォーマット(ここでは yyyy-mm-dd という形)を判定し、それを explode() で抽出しつつ、checkdate()  で日付が正しいかを判定して、真偽を返すようにしています。ちなみに、カスタムバリデートメソッドはルールとして public static なメソッドとして定義する必要があります。

あとは、defaultValidation() などで呼び出す形です。

Cake4: 任意のモデルテーブルのバリデートで呼び出す

// 任意のモデルテーブル内で
/**
 * デフォルトバリデーション
 *
 * @param \Cake\Validation\Validator $validator A Validator instance
 * @return \Cake\Validation\Validator
 */
public function validationDefault(Validator $validator): Validator
{
    $validator->setProvider('customValidation', 'App\Model\Validation\CustomValidation');

    $validator
        ->notEmptyString('start', '開始日を入力してください')
        ->add('start', 'date', [
            'rule' => 'validateDate',
            'provider' => 'customValidation',
            'message' => '開始日を正しく入力してください',
    ])
}

setProvider() でカスタムバリデーション定義を読み込んで、$validator->add()  内の provider プロパティで setProvider でセットした名前を呼び出せば、rule でカスタムバリデートメソッドを呼び出すことが可能になります。

-Cakephp, PHP, WEB開発
-