今回やりたいこと
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のラベル名になります。
$validator
->date('hoge_date', ['ymd', 'mdy'])
->requirePresence('hoge_date', 'create')
->notEmpty('hoge_date');
次に
手動でadd部分を加えようとしてました。(他はデフォで記載済み)
$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
で対象のデータを取得できると思います。