From 609d4f44835a6d4b839f32fb8d4e5906d99c46d3 Mon Sep 17 00:00:00 2001 From: Mohamed Said Date: Mon, 21 Nov 2016 18:00:07 +0200 Subject: [PATCH] Add before_or_equal and after_or_equal rules --- src/Illuminate/Validation/Validator.php | 117 ++++++++++++------- tests/Validation/ValidationValidatorTest.php | 35 ++++++ 2 files changed, 110 insertions(+), 42 deletions(-) diff --git a/src/Illuminate/Validation/Validator.php b/src/Illuminate/Validation/Validator.php index ac07ebb8203b..edc9598af72d 100755 --- a/src/Illuminate/Validation/Validator.php +++ b/src/Illuminate/Validation/Validator.php @@ -178,7 +178,7 @@ class Validator implements ValidatorContract protected $dependentRules = [ 'RequiredWith', 'RequiredWithAll', 'RequiredWithout', 'RequiredWithoutAll', 'RequiredIf', 'RequiredUnless', 'Confirmed', 'Same', 'Different', 'Unique', - 'Before', 'After', + 'Before', 'After', 'BeforeOrEqual', 'AfterOrEqual' ]; /** @@ -1853,34 +1853,22 @@ protected function validateBefore($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'before'); - if (! is_string($value) && ! is_numeric($value) && ! $value instanceof DateTimeInterface) { - return false; - } - - if ($format = $this->getDateFormat($attribute)) { - return $this->validateBeforeWithFormat($format, $value, $parameters); - } - - if (! $date = $this->getDateTimestamp($parameters[0])) { - $date = $this->getDateTimestamp($this->getValue($parameters[0])); - } - - return $this->getDateTimestamp($value) < $date; + return $this->compareDates($attribute, $value, $parameters, '<'); } /** - * Validate the date is before a given date with a given format. + * Validate the date is before or equal a given date. * - * @param string $format + * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ - protected function validateBeforeWithFormat($format, $value, $parameters) + protected function validateBeforeOrEqual($attribute, $value, $parameters) { - $param = $this->getValue($parameters[0]) ?: $parameters[0]; + $this->requireParameterCount(1, $parameters, 'before_or_equal'); - return $this->checkDateTimeOrder($format, $value, $param); + return $this->compareDates($attribute, $value, $parameters, '<='); } /** @@ -1895,51 +1883,68 @@ protected function validateAfter($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'after'); + return $this->compareDates($attribute, $value, $parameters, '>'); + } + + /** + * Validate the date is equal or after a given date. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validateAfterOrEqual($attribute, $value, $parameters) + { + $this->requireParameterCount(1, $parameters, 'after_or_equal'); + + return $this->compareDates($attribute, $value, $parameters, '>='); + } + + /** + * Compare a given date against another using an operator. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @param string $operator + * @return bool + */ + protected function compareDates($attribute, $value, $parameters, $operator) + { if (! is_string($value) && ! is_numeric($value) && ! $value instanceof DateTimeInterface) { return false; } if ($format = $this->getDateFormat($attribute)) { - return $this->validateAfterWithFormat($format, $value, $parameters); + $param = $this->getValue($parameters[0]) ?: $parameters[0]; + + return $this->checkDateTimeOrder($format, $value, $param, $operator); } if (! $date = $this->getDateTimestamp($parameters[0])) { $date = $this->getDateTimestamp($this->getValue($parameters[0])); } - return $this->getDateTimestamp($value) > $date; - } - - /** - * Validate the date is after a given date with a given format. - * - * @param string $format - * @param mixed $value - * @param array $parameters - * @return bool - */ - protected function validateAfterWithFormat($format, $value, $parameters) - { - $param = $this->getValue($parameters[0]) ?: $parameters[0]; - - return $this->checkDateTimeOrder($format, $param, $value); + return $this->compare($this->getDateTimestamp($value), $date, $operator); } /** * Given two date/time strings, check that one is after the other. * * @param string $format - * @param string $before - * @param string $after + * @param string $first + * @param string $second + * @param string $operator * @return bool */ - protected function checkDateTimeOrder($format, $before, $after) + protected function checkDateTimeOrder($format, $first, $second, $operator) { - $before = $this->getDateTimeWithOptionalFormat($format, $before); + $first = $this->getDateTimeWithOptionalFormat($format, $first); - $after = $this->getDateTimeWithOptionalFormat($format, $after); + $second = $this->getDateTimeWithOptionalFormat($format, $second); - return ($before && $after) && ($after > $before); + return ($first && $second) && ($this->compare($first, $second, $operator)); } /** @@ -3340,6 +3345,34 @@ protected function requireParameterCount($count, $parameters, $rule) } } + /** + * Determine if a comparison passes between the given values. + * + * @param mixed $first + * @param mixed $second + * @param string $operator + * @return bool + */ + protected function compare($first, $second, $operator) + { + switch ($operator) { + case '<': + return $first < $second; + break; + case '>': + return $first > $second; + break; + case '<=': + return $first <= $second; + break; + case '>=': + return $first >= $second; + break; + default: + throw new \InvalidArgumentException(); + } + } + /** * Handle dynamic calls to class methods. * diff --git a/tests/Validation/ValidationValidatorTest.php b/tests/Validation/ValidationValidatorTest.php index 2bec30bbc86f..5171ad7226ab 100755 --- a/tests/Validation/ValidationValidatorTest.php +++ b/tests/Validation/ValidationValidatorTest.php @@ -2243,6 +2243,41 @@ public function testBeforeAndAfterWithFormat() $this->assertTrue($v->fails()); } + public function testWeakBeforeAndAfter() + { + date_default_timezone_set('UTC'); + $trans = $this->getIlluminateArrayTranslator(); + $v = new Validator($trans, ['x' => '2012-01-15'], ['x' => 'before_or_equal:2012-01-15']); + $this->assertTrue($v->passes()); + + $v = new Validator($trans, ['x' => '2012-01-15'], ['x' => 'before_or_equal:2012-01-16']); + $this->assertTrue($v->passes()); + + $v = new Validator($trans, ['x' => '2012-01-15'], ['x' => 'before_or_equal:2012-01-14']); + $this->assertTrue($v->fails()); + + $v = new Validator($trans, ['x' => '31/12/2012'], ['x' => 'date_format:d/m/Y|before_or_equal:31/12/2012']); + $this->assertTrue($v->passes()); + + $v = new Validator($trans, ['x' => '31/12/2012'], ['x' => 'date_format:d/m/Y|before_or_equal:29/12/2012']); + $this->assertTrue($v->fails()); + + $v = new Validator($trans, ['x' => '2012-01-15'], ['x' => 'after_or_equal:2012-01-15']); + $this->assertTrue($v->passes()); + + $v = new Validator($trans, ['x' => '2012-01-15'], ['x' => 'after_or_equal:2012-01-14']); + $this->assertTrue($v->passes()); + + $v = new Validator($trans, ['x' => '2012-01-15'], ['x' => 'after_or_equal:2012-01-16']); + $this->assertTrue($v->fails()); + + $v = new Validator($trans, ['x' => '31/12/2012'], ['x' => 'date_format:d/m/Y|after_or_equal:31/12/2012']); + $this->assertTrue($v->passes()); + + $v = new Validator($trans, ['x' => '31/12/2012'], ['x' => 'date_format:d/m/Y|after_or_equal:02/01/2013']); + $this->assertTrue($v->fails()); + } + public function testSometimesAddingRules() { $trans = $this->getIlluminateArrayTranslator();