Skip to content
This repository was archived by the owner on Jan 31, 2020. It is now read-only.

Commit eb9a7e7

Browse files
michalbundyraweierophinney
authored andcommitted
Strict mode for Date validator
Input must be always in the defined format and must be the same as output of format method of DateTime. Strict mode is set to `false` by default to keep BC. Resolve #33 Fix zendframework/zendframework#6407
1 parent d3355e9 commit eb9a7e7

File tree

2 files changed

+92
-35
lines changed

2 files changed

+92
-35
lines changed

src/Date.php

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ class Date extends AbstractValidator
5656
*/
5757
protected $format = self::FORMAT_DEFAULT;
5858

59+
/**
60+
* @var bool
61+
*/
62+
protected $strict = false;
63+
5964
/**
6065
* Sets validator options
6166
*
@@ -100,6 +105,32 @@ public function setFormat($format = self::FORMAT_DEFAULT)
100105
return $this;
101106
}
102107

108+
/**
109+
* @param bool $strict
110+
* @return $this
111+
*/
112+
public function setStrict($strict)
113+
{
114+
if (! is_bool($strict)) {
115+
throw new Exception\InvalidArgumentException(sprintf(
116+
'Expected boolean value; %s received',
117+
is_object($strict) ? get_class($strict) : gettype($strict)
118+
));
119+
}
120+
121+
$this->strict = $strict;
122+
123+
return $this;
124+
}
125+
126+
/**
127+
* @return bool
128+
*/
129+
public function isStrict()
130+
{
131+
return $this->strict;
132+
}
133+
103134
/**
104135
* Returns true if $value is a DateTime instance or can be converted into one.
105136
*
@@ -110,11 +141,17 @@ public function isValid($value)
110141
{
111142
$this->setValue($value);
112143

113-
if (! $this->convertToDateTime($value)) {
144+
$date = $this->convertToDateTime($value);
145+
if (! $date) {
114146
$this->error(self::INVALID_DATE);
115147
return false;
116148
}
117149

150+
if ($this->isStrict() && $date->format($this->getFormat()) !== $value) {
151+
$this->error(self::FALSEFORMAT);
152+
return false;
153+
}
154+
118155
return true;
119156
}
120157

test/DateTest.php

Lines changed: 54 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -44,48 +44,53 @@ public function testSetFormatIgnoresNull()
4444
public function datesDataProvider()
4545
{
4646
return [
47-
// date format isValid
48-
['2007-01-01', null, true],
49-
['2007-02-28', null, true],
50-
['2007-02-29', null, false],
51-
['2008-02-29', null, true],
52-
['2007-02-30', null, false],
53-
['2007-02-99', null, false],
54-
['2007-02-99', 'Y-m-d', false],
55-
['9999-99-99', null, false],
56-
['9999-99-99', 'Y-m-d', false],
57-
['Jan 1 2007', null, false],
58-
['Jan 1 2007', 'M j Y', true],
59-
['asdasda', null, false],
60-
['sdgsdg', null, false],
61-
['2007-01-01something', null, false],
62-
['something2007-01-01', null, false],
63-
['10.01.2008', 'd.m.Y', true],
64-
['01 2010', 'm Y', true],
65-
['2008/10/22', 'd/m/Y', false],
66-
['22/10/08', 'd/m/y', true],
67-
['22/10', 'd/m/Y', false],
47+
// date format isValid isValid Strict
48+
['2007-01-01', null, true, true],
49+
['2007-02-28', null, true, true],
50+
['2007-02-29', null, false, false],
51+
['2008-02-29', null, true, true],
52+
['2007-02-30', null, false, false],
53+
['2007-02-99', null, false, false],
54+
['2007-02-99', 'Y-m-d', false, false],
55+
['9999-99-99', null, false, false],
56+
['9999-99-99', 'Y-m-d', false, false],
57+
['Jan 1 2007', null, false, false],
58+
['Jan 1 2007', 'M j Y', true, true],
59+
['asdasda', null, false, false],
60+
['sdgsdg', null, false, false],
61+
['2007-01-01something', null, false, false],
62+
['something2007-01-01', null, false, false],
63+
['10.01.2008', 'd.m.Y', true, true],
64+
['01 2010', 'm Y', true, true],
65+
['2008/10/22', 'd/m/Y', false, false],
66+
['22/10/08', 'd/m/y', true, true],
67+
['22/10', 'd/m/Y', false, false],
6868
// time
69-
['2007-01-01T12:02:55Z', DateTime::ISO8601, true],
70-
['12:02:55', 'H:i:s', true],
71-
['25:02:55', 'H:i:s', false],
69+
['2007-01-01T12:02:55Z', DateTime::ISO8601, true, false],
70+
['2007-01-01T12:02:55+0000', DateTime::ISO8601, true, true],
71+
['12:02:55', 'H:i:s', true, true],
72+
['25:02:55', 'H:i:s', false, false],
7273
// int
73-
[0, null, true],
74-
[1340677235, null, true],
74+
[0, null, true, false],
75+
[6, 'd', true, false],
76+
['6', 'd', true, false],
77+
['06', 'd', true, true],
78+
[123, null, true, false],
79+
[1340677235, null, true, false],
7580
// 32bit version of php will convert this to double
76-
[999999999999, null, true],
81+
[999999999999, null, true, false],
7782
// double
78-
[12.12, null, false],
83+
[12.12, null, false, false],
7984
// array
80-
[['2012', '06', '25'], null, true],
85+
[['2012', '06', '25'], null, true, false],
8186
// 0012-06-25 is a valid date, if you want 2012, use 'y' instead of 'Y'
82-
[['12', '06', '25'], null, true],
83-
[['2012', '06', '33'], null, false],
84-
[[1 => 1], null, false],
87+
[['12', '06', '25'], null, true, false],
88+
[['2012', '06', '33'], null, false, false],
89+
[[1 => 1], null, false, false],
8590
// DateTime
86-
[new DateTime(), null, true],
91+
[new DateTime(), null, true, false],
8792
// invalid obj
88-
[new stdClass(), null, false],
93+
[new stdClass(), null, false, false],
8994
];
9095
}
9196

@@ -100,6 +105,21 @@ public function testBasic($input, $format, $result)
100105
$this->assertEquals($result, $this->validator->isValid($input));
101106
}
102107

108+
/**
109+
* @dataProvider datesDataProvider
110+
*
111+
* @param mixed $input
112+
* @param string|null $format
113+
* @param bool $result
114+
* @param bool $resultStrict
115+
*/
116+
public function testBasicStrictMode($input, $format, $result, $resultStrict)
117+
{
118+
$this->validator->setStrict(true);
119+
$this->validator->setFormat($format);
120+
$this->assertSame($resultStrict, $this->validator->isValid($input));
121+
}
122+
103123
public function testDateTimeImmutable()
104124
{
105125
$this->assertTrue($this->validator->isValid(new DateTimeImmutable()));

0 commit comments

Comments
 (0)