日付の最大最小 after, before では、引数に値(日付)を与えるだけでなく、比較対象の属性の名前を与えることができます。
むしろ具体的な日付を引数にすることのほうがまれでしょう。

'date_start' => 'date|before:today',
'date_end'   => 'date|after:date_start',

このような使い方は、数値型の最大最小 min, max でも使用したいこともありますよね?

例えば、次のような関係です。

unit_cost

'unit_price' => 'required|integer|min:0',
'unit_cost'  => 'required|integer|min:0|max:unit_price',

標準バリデーションの minmax を拡張して、比較対象の属性名を引数に持てるようにしてみましょう。

 

getValue()

バリデーションクラスにルールを登録するときの雛形は次のようなものでした。
一見すると引数には、ルールを定義した属性に関する情報しか与えられません。

/**
 * 追加バリデーション
 * @param  string  $attribute  検査する属性名
 * @param  string  $value      入力された値
 * @param  array   $parameters 引数の配列
 * @return boolean
 */
public function validateHoge($attribute, $value, $parameters)
{
  //
}

しかし、バリデーションクラスにはリクエストされたすべての属性に関する情報が与えれていて、他の属性に入力された値も getValue() で得ることができます。getValue() の引数は属性名です。

よって、次のバリデーションは必ず TRUE を返します。

public function validateHoge($attribute, $value, $parameters)
{
   return ($value == $this->getValue($attribute));
}

 

min と max の拡張

min, max の引数は、属性の型が何であろうと必ず数値を取ります。

そこで、引数が数値(is_numeric)でないときを限定し、引数を属性名とした値が存在するならそれを新たなしきい値としました。

/**
 * 最小値 min
 * @param string $attribute
 * @param string $value
 * @param array $parameters	0 => 比較する属性名
 * @return true
 */
protected function validateMin($attribute, $value, $parameters)
{
    if (!is_numeric($parameters[0]) && 
        !is_null($val = $this->getValue($parameters[0])))
    {
        $parameters[0] = $val;
    }
 
    return parent::validateMin($attribute, $value, $parameters);
}

/**
 * 最大値 max
 * @param string $attribute
 * @param string $value
 * @param array $parameters	0 => 比較する属性名
 * @return true
 */
protected function validateMax($attribute, $value, $parameters)
{
    if (!is_numeric($parameters[0]) &&
        !is_null($val = $this->getValue($parameters[0])))
    {
        $parameters[0] = $val;
    }
 
    return parent::validateMax($attribute, $value, $parameters);
}

 
* * * *

さて、拡張した最大最小バリデーションですが、このままではエラーメッセージが与えられた引数の属性名のままとなり、言語ファイルによる置き換えが行われません。

unit_cost2

本来の最大最小が与えられた引数そのものを、メッセージのプレースホルダー :max と置き換えることしか想定していないからです。
この部分の解決については次回にまとめる予定です。

By ymikome