m_shige1979のときどきITブログ

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

cakephp3でカスタムバリデーションプロバイダを作成

バリデーションのルールはチェックはいろいろありますが

多少細かいチェックなどがあった場合は対応できません。
各テーブルだけの機能ならともかくいろいろなテーブルクラスで使用する場合はバリデーションを使いまわしたい

環境

CentOS 7.x
php7.0.3
cakephp3.2.3

日本語のマニュアルがあると調査も捗る…少し放置していた隙に3.2行っていたのか…

対応

ディレクトリを作成
mkdir -p src/Model/Validation
バリデーションインターフェースを実装

src/Model/Validation/CustomValidationInterface.php

<?php
namespace App\Model\Validation;


interface CustomValidationInterface
{
    // チェックメソッドを定義する
    public static function sampleCheck1($string);

    // チェックメソッドを定義する
    public static function sampleCheck2($string, $len);
}
チェック処理を実装

src/Model/Validation/CustomValidation.php

<?php
namespace App\Model\Validation;

use Cake\Validation;

class CustomValidation implements CustomValidationInterface
{
    // チェックメソッドを実装する
    public static function sampleCheck1($check)
    {
        $result = null;
        if ($check == "check1") {
            $result = true;
        } else {
            $result = false;
        }
        return $result;
    }

    // チェックメソッドを実装する
    public static function sampleCheck2($check, $len)
    {
        $result = null;
        if ($check == "1234567890" && strlen($check) == $len) {
            $result = true;
        } else {
            $result = false;
        }
        return $result;
    }
}

※サンプルって手抜きの方がわかりやすいと思います

テーブルのバリデーションに実装
<?php
namespace App\Model\Table;

use App\Model\Entity\Post;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use App\Model\Validation;

/**
 * Posts Model
 *
 */
class PostsTable extends Table
{

    /**
     * Initialize method
     *
     * @param array $config The configuration for the Table.
     * @return void
     */
    public function initialize(array $config)
    {
        parent::initialize($config);

        $this->table('posts');
        $this->displayField('title');
        $this->primaryKey('id');

        $this->addBehavior('Timestamp');
    }

    /**
     * Default validation rules.
     *
     * @param \Cake\Validation\Validator $validator Validator instance.
     * @return \Cake\Validation\Validator
     */
    public function validationDefault(Validator $validator)
    {

        // プロバイダを追加
        $validator->provider('custom', Validation\CustomValidation::class);

        $validator
            ->integer('id')
            ->allowEmpty('id', 'create');

        $validator
            ->requirePresence('title', 'create')
            ->notEmpty('title')
            ->add("title", [
                "check1" => [
                    "rule" => ["sampleCheck2", 10],
                    "message" => "カスタムプロバイダーエラー1",
                    "provider" => "custom",  // 使用するプロバイダ名を設定
                ]
            ]);

        $validator
            ->requirePresence('body', 'create')
            ->notEmpty('body');

        return $validator;
    }

}

こんな感じ

所感

cakephp2の場合はビヘイビアに組み込むという方法で共通化していたので別の場所に配置できるようになるとメンテナンスもやりやすくなるかも…
データだけのチェックの場合とデータベースが絡む場合で難易度が変わるかもしれないので注意する必要があるかもしれないけど…