Skip to content

Commit f2eefa5

Browse files
authored
Merge pull request #16490 from themsaid/beforeandafterorequalrules
[5.3] Add before_or_equal and after_or_equal rules
2 parents 17daa1e + 3f79df5 commit f2eefa5

File tree

2 files changed

+110
-42
lines changed

2 files changed

+110
-42
lines changed

src/Illuminate/Validation/Validator.php

Lines changed: 75 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ class Validator implements ValidatorContract
178178
protected $dependentRules = [
179179
'RequiredWith', 'RequiredWithAll', 'RequiredWithout', 'RequiredWithoutAll',
180180
'RequiredIf', 'RequiredUnless', 'Confirmed', 'Same', 'Different', 'Unique',
181-
'Before', 'After',
181+
'Before', 'After', 'BeforeOrEqual', 'AfterOrEqual',
182182
];
183183

184184
/**
@@ -1853,34 +1853,22 @@ protected function validateBefore($attribute, $value, $parameters)
18531853
{
18541854
$this->requireParameterCount(1, $parameters, 'before');
18551855

1856-
if (! is_string($value) && ! is_numeric($value) && ! $value instanceof DateTimeInterface) {
1857-
return false;
1858-
}
1859-
1860-
if ($format = $this->getDateFormat($attribute)) {
1861-
return $this->validateBeforeWithFormat($format, $value, $parameters);
1862-
}
1863-
1864-
if (! $date = $this->getDateTimestamp($parameters[0])) {
1865-
$date = $this->getDateTimestamp($this->getValue($parameters[0]));
1866-
}
1867-
1868-
return $this->getDateTimestamp($value) < $date;
1856+
return $this->compareDates($attribute, $value, $parameters, '<');
18691857
}
18701858

18711859
/**
1872-
* Validate the date is before a given date with a given format.
1860+
* Validate the date is before or equal a given date.
18731861
*
1874-
* @param string $format
1862+
* @param string $attribute
18751863
* @param mixed $value
18761864
* @param array $parameters
18771865
* @return bool
18781866
*/
1879-
protected function validateBeforeWithFormat($format, $value, $parameters)
1867+
protected function validateBeforeOrEqual($attribute, $value, $parameters)
18801868
{
1881-
$param = $this->getValue($parameters[0]) ?: $parameters[0];
1869+
$this->requireParameterCount(1, $parameters, 'before_or_equal');
18821870

1883-
return $this->checkDateTimeOrder($format, $value, $param);
1871+
return $this->compareDates($attribute, $value, $parameters, '<=');
18841872
}
18851873

18861874
/**
@@ -1895,51 +1883,68 @@ protected function validateAfter($attribute, $value, $parameters)
18951883
{
18961884
$this->requireParameterCount(1, $parameters, 'after');
18971885

1886+
return $this->compareDates($attribute, $value, $parameters, '>');
1887+
}
1888+
1889+
/**
1890+
* Validate the date is equal or after a given date.
1891+
*
1892+
* @param string $attribute
1893+
* @param mixed $value
1894+
* @param array $parameters
1895+
* @return bool
1896+
*/
1897+
protected function validateAfterOrEqual($attribute, $value, $parameters)
1898+
{
1899+
$this->requireParameterCount(1, $parameters, 'after_or_equal');
1900+
1901+
return $this->compareDates($attribute, $value, $parameters, '>=');
1902+
}
1903+
1904+
/**
1905+
* Compare a given date against another using an operator.
1906+
*
1907+
* @param string $attribute
1908+
* @param mixed $value
1909+
* @param array $parameters
1910+
* @param string $operator
1911+
* @return bool
1912+
*/
1913+
protected function compareDates($attribute, $value, $parameters, $operator)
1914+
{
18981915
if (! is_string($value) && ! is_numeric($value) && ! $value instanceof DateTimeInterface) {
18991916
return false;
19001917
}
19011918

19021919
if ($format = $this->getDateFormat($attribute)) {
1903-
return $this->validateAfterWithFormat($format, $value, $parameters);
1920+
$param = $this->getValue($parameters[0]) ?: $parameters[0];
1921+
1922+
return $this->checkDateTimeOrder($format, $value, $param, $operator);
19041923
}
19051924

19061925
if (! $date = $this->getDateTimestamp($parameters[0])) {
19071926
$date = $this->getDateTimestamp($this->getValue($parameters[0]));
19081927
}
19091928

1910-
return $this->getDateTimestamp($value) > $date;
1911-
}
1912-
1913-
/**
1914-
* Validate the date is after a given date with a given format.
1915-
*
1916-
* @param string $format
1917-
* @param mixed $value
1918-
* @param array $parameters
1919-
* @return bool
1920-
*/
1921-
protected function validateAfterWithFormat($format, $value, $parameters)
1922-
{
1923-
$param = $this->getValue($parameters[0]) ?: $parameters[0];
1924-
1925-
return $this->checkDateTimeOrder($format, $param, $value);
1929+
return $this->compare($this->getDateTimestamp($value), $date, $operator);
19261930
}
19271931

19281932
/**
19291933
* Given two date/time strings, check that one is after the other.
19301934
*
19311935
* @param string $format
1932-
* @param string $before
1933-
* @param string $after
1936+
* @param string $first
1937+
* @param string $second
1938+
* @param string $operator
19341939
* @return bool
19351940
*/
1936-
protected function checkDateTimeOrder($format, $before, $after)
1941+
protected function checkDateTimeOrder($format, $first, $second, $operator)
19371942
{
1938-
$before = $this->getDateTimeWithOptionalFormat($format, $before);
1943+
$first = $this->getDateTimeWithOptionalFormat($format, $first);
19391944

1940-
$after = $this->getDateTimeWithOptionalFormat($format, $after);
1945+
$second = $this->getDateTimeWithOptionalFormat($format, $second);
19411946

1942-
return ($before && $after) && ($after > $before);
1947+
return ($first && $second) && ($this->compare($first, $second, $operator));
19431948
}
19441949

19451950
/**
@@ -3340,6 +3345,34 @@ protected function requireParameterCount($count, $parameters, $rule)
33403345
}
33413346
}
33423347

3348+
/**
3349+
* Determine if a comparison passes between the given values.
3350+
*
3351+
* @param mixed $first
3352+
* @param mixed $second
3353+
* @param string $operator
3354+
* @return bool
3355+
*/
3356+
protected function compare($first, $second, $operator)
3357+
{
3358+
switch ($operator) {
3359+
case '<':
3360+
return $first < $second;
3361+
break;
3362+
case '>':
3363+
return $first > $second;
3364+
break;
3365+
case '<=':
3366+
return $first <= $second;
3367+
break;
3368+
case '>=':
3369+
return $first >= $second;
3370+
break;
3371+
default:
3372+
throw new \InvalidArgumentException();
3373+
}
3374+
}
3375+
33433376
/**
33443377
* Handle dynamic calls to class methods.
33453378
*

tests/Validation/ValidationValidatorTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2243,6 +2243,41 @@ public function testBeforeAndAfterWithFormat()
22432243
$this->assertTrue($v->fails());
22442244
}
22452245

2246+
public function testWeakBeforeAndAfter()
2247+
{
2248+
date_default_timezone_set('UTC');
2249+
$trans = $this->getIlluminateArrayTranslator();
2250+
$v = new Validator($trans, ['x' => '2012-01-15'], ['x' => 'before_or_equal:2012-01-15']);
2251+
$this->assertTrue($v->passes());
2252+
2253+
$v = new Validator($trans, ['x' => '2012-01-15'], ['x' => 'before_or_equal:2012-01-16']);
2254+
$this->assertTrue($v->passes());
2255+
2256+
$v = new Validator($trans, ['x' => '2012-01-15'], ['x' => 'before_or_equal:2012-01-14']);
2257+
$this->assertTrue($v->fails());
2258+
2259+
$v = new Validator($trans, ['x' => '31/12/2012'], ['x' => 'date_format:d/m/Y|before_or_equal:31/12/2012']);
2260+
$this->assertTrue($v->passes());
2261+
2262+
$v = new Validator($trans, ['x' => '31/12/2012'], ['x' => 'date_format:d/m/Y|before_or_equal:29/12/2012']);
2263+
$this->assertTrue($v->fails());
2264+
2265+
$v = new Validator($trans, ['x' => '2012-01-15'], ['x' => 'after_or_equal:2012-01-15']);
2266+
$this->assertTrue($v->passes());
2267+
2268+
$v = new Validator($trans, ['x' => '2012-01-15'], ['x' => 'after_or_equal:2012-01-14']);
2269+
$this->assertTrue($v->passes());
2270+
2271+
$v = new Validator($trans, ['x' => '2012-01-15'], ['x' => 'after_or_equal:2012-01-16']);
2272+
$this->assertTrue($v->fails());
2273+
2274+
$v = new Validator($trans, ['x' => '31/12/2012'], ['x' => 'date_format:d/m/Y|after_or_equal:31/12/2012']);
2275+
$this->assertTrue($v->passes());
2276+
2277+
$v = new Validator($trans, ['x' => '31/12/2012'], ['x' => 'date_format:d/m/Y|after_or_equal:02/01/2013']);
2278+
$this->assertTrue($v->fails());
2279+
}
2280+
22462281
public function testSometimesAddingRules()
22472282
{
22482283
$trans = $this->getIlluminateArrayTranslator();

0 commit comments

Comments
 (0)