4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

cakephp3における日付のバリデーション

Posted at

今回やりたいこと

postされてくる日付を、現在の日付(今日)より、前であればvalidationを有効にしたい

基本

app/src/Model/Table/HogeTable.php

POST入力値等の入力値チェックは validationDefault に記述する
saveの入力値チェック(Entityチェック)は buildRules に記述する

cakephp3のバリデーションは2パターン存在

思考の流れ

自分で考えたbadコードを、プレビューしていただき、
より良いコードになった流れです。

public function validationDefault(Validator $validator)

bakeにより、デフォで設定されているのが、
下記の初期段階です。
※hoge_date は、postされてくるinputのラベル名になります。

◯◯Table1.php
$validator
  ->date('hoge_date', ['ymd', 'mdy'])
  ->requirePresence('hoge_date', 'create')
  ->notEmpty('hoge_date');

次に
手動でadd部分を加えようとしてました。(他はデフォで記載済み)

◯◯Table2.php
$validator
  ->date('hoge_date', ['ymd', 'mdy'])
  ->requirePresence('hoge_date', 'create')
  ->add('hoge_date',[
       'date' => [
         'rule' => ['boolean'],
         'message' => '今日より前の日付はダメ',
       ],
   ])
  ->notEmpty('hoge_date');

ruleのところを、いったんbooleanにしていますが、
完成系は、ここにfunction名を記載し、

'rule' => dateCheck

などと記載し、別ファンクションを作るつもりでした。

public function dateCheck($hoge_date) {
      if( $now  === $hoge_date){
            echo "その日付は今日です";
        }else if( $now > $hoge_date){
            echo "その日付は過去です。予約できません";
        }else{
            echo "その日付は未来です";
}

このようなファンクションを作成し、戻り値に、falseを返すようにする。
そうすることで、'rule' => ['false'] という記述により、エラーメッセージが出るというロジックにしようと考えてました。

ここまでが、いわゆる記述量が多いbadコードでした。

参考に、、、
http://book.cakephp.org/3.0/ja/core-libraries/validation.html#id8

現在時間という日付の取得方法 (横道にそれます)

比較するのは、postされた日付と、現在の時間。
どのようにしようか、、、、、

phpの関数で、今日の日付が取れる

$today = date("Y/m/d”);//2016/12/15

postされたdataの日付の形式を変える
(postされてる日付は12/2)

$hoge = date('Y/m/d', strtotime($date[‘hoge’]);//2016/12/02

cakeのオブジェクトを使用して、こんなのもできる

use Cake\I18n\Time; (宣言)
$now = new Time();
$now = date('Y/m/d', strtotime($now));

ただこれだと、オブジェクトを出しているだけなようです。

dubug($now);の結果

object(Cake\I18n\Time) {
    'time' => '2016-12-15T06:59:42+00:00',
    'timezone' => 'UTC',
    'fixedNowTime' => false
}

やるならこんな感じの方が無難

echo $now->format('Ymd’);//20161215

betterなcodeに変身

cakephp3.2から出ているオブジェクトを使ったスマートな方法です。
Cake\I18n\FrozenDate

$validator
    ->date('checkin_date', ['ymd', 'mdy'])
    ->requirePresence('checkin_date', 'create')
    ->add('checkin_date', [
        'date' => [
            'rule' => function($value){
                return (new FrozenDate($value))->isFuture();
            },
            'message' => '今日より前の日付はダメ',
        ],
    ])
    ->notEmpty('checkin_date');

FrozenDate
というオブジェクトを使うことで、(cake3.2から使える??)
自前でphpで判定をすることなく、
->isFuture()こうゆうメソッドを使うだけで、現在より過去か未来かとかの判定ができるようです。

ちなみに、引数の$valueは、特にどこかで宣言されてる変数ではなく、予約語??的な扱いかと思われます。
中身としては、今回postされてくる、
$this->request->data['checkout_date']の中身ですが、
各、$validatorごとに、$valueで対象のデータを取得できると思います。

4
4
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
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?