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

Commit

Permalink
Merge branch 'hotfix/159'
Browse files Browse the repository at this point in the history
Close #159
Fixes #158
  • Loading branch information
weierophinney committed May 18, 2017
2 parents ff96c89 + 4cc04fa commit 95beb4d
Show file tree
Hide file tree
Showing 12 changed files with 227 additions and 17 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ All notable changes to this project will be documented in this file, in reverse
and thus seeding it with configured form/form element services. This means
that the `form_elements` configuration will now be honored in non-zend-mvc
contexts.
- [#159](https://github.com/zendframework/zend-form/pull/159) fixes the behavior
of the `min` and `max` attributes of the various `DateTime` elements, ensuring
that the elements raise an exception during instantiation if the values
provided are in a format that `DateTime` does not recognize for the element
type in question.

## 2.10.1 - 2017-04-26

Expand Down
3 changes: 3 additions & 0 deletions src/Element/Date.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

class Date extends DateTimeElement
{

const DATETIME_FORMAT = 'Y-m-d';

/**
* Seed attributes
*
Expand Down
51 changes: 45 additions & 6 deletions src/Element/DateTime.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@

use DateInterval;
use DateTime as PhpDateTime;
use DateTimeInterface;
use Zend\Form\Element;
use Zend\Form\Exception\InvalidArgumentException;
use Zend\InputFilter\InputProviderInterface;
use Zend\Validator\Date as DateValidator;
use Zend\Validator\DateStep as DateStepValidator;
Expand Down Expand Up @@ -120,17 +122,40 @@ protected function getValidators()
$validators = [];
$validators[] = $this->getDateValidator();

if (isset($this->attributes['min'])) {
if (isset($this->attributes['min'])
&& $this->valueIsValidDateTimeFormat($this->attributes['min'])
) {
$validators[] = new GreaterThanValidator([
'min' => $this->attributes['min'],
'min' => $this->attributes['min'],
'inclusive' => true,
]);
} elseif (isset($this->attributes['min'])
&& ! $this->valueIsValidDateTimeFormat($this->attributes['min'])
) {
throw new InvalidArgumentException(sprintf(
'%1$s expects "min" to conform to %2$s; received "%3$s"',
__METHOD__,
static::DATETIME_FORMAT,
$this->attributes['min']
));
}
if (isset($this->attributes['max'])) {

if (isset($this->attributes['max'])
&& $this->valueIsValidDateTimeFormat($this->attributes['max'])
) {
$validators[] = new LessThanValidator([
'max' => $this->attributes['max'],
'max' => $this->attributes['max'],
'inclusive' => true,
]);
} elseif (isset($this->attributes['max'])
&& ! $this->valueIsValidDateTimeFormat($this->attributes['max'])
) {
throw new InvalidArgumentException(sprintf(
'%1$s expects "max" to conform to %2$s; received "%3$s"',
__METHOD__,
static::DATETIME_FORMAT,
$this->attributes['max']
));
}
if (! isset($this->attributes['step'])
|| 'any' !== $this->attributes['step']
Expand All @@ -145,7 +170,7 @@ protected function getValidators()
/**
* Retrieves a Date Validator configured for a DateTime Input type
*
* @return DateTime
* @return DateValidator
*/
protected function getDateValidator()
{
Expand All @@ -155,7 +180,7 @@ protected function getDateValidator()
/**
* Retrieves a DateStep Validator configured for a DateTime Input type
*
* @return DateTime
* @return DateStepValidator
*/
protected function getStepValidator()
{
Expand Down Expand Up @@ -191,4 +216,18 @@ public function getInputSpecification()
'validators' => $this->getValidators(),
];
}

/**
* Indicate whether or not a value represents a valid DateTime format.
*
* @param string $value
* @return bool
*/
private function valueIsValidDateTimeFormat($value)
{
return PhpDateTime::createFromFormat(
static::DATETIME_FORMAT,
$value
) instanceof DateTimeInterface;
}
}
3 changes: 3 additions & 0 deletions src/Element/DateTimeLocal.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@

class DateTimeLocal extends DateTime
{

const DATETIME_LOCAL_FORMAT = 'Y-m-d\TH:i';

const DATETIME_FORMAT = self::DATETIME_LOCAL_FORMAT;

/**
* Seed attributes
*
Expand Down
3 changes: 3 additions & 0 deletions src/Element/Month.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@

class Month extends DateTime
{

const DATETIME_FORMAT = 'Y-m';

/**
* Seed attributes
*
Expand Down
3 changes: 3 additions & 0 deletions src/Element/Time.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

class Time extends DateTime
{

const DATETIME_FORMAT = 'H:i:s';

/**
* Seed attributes
*
Expand Down
34 changes: 34 additions & 0 deletions src/Element/Week.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

use Zend\Validator\DateStep as DateStepValidator;
use Zend\Validator\Regex as RegexValidator;
use Zend\Validator\GreaterThan as GreaterThanValidator;
use Zend\Validator\LessThan as LessThanValidator;

class Week extends DateTime
{
Expand Down Expand Up @@ -52,4 +54,36 @@ protected function getStepValidator()
'step' => new \DateInterval("P{$stepValue}W"),
]);
}

/**
* @see https://bugs.php.net/bug.php?id=74511
* @return array
*/
protected function getValidators()
{
if ($this->validators) {
return $this->validators;
}
$validators = [];
$validators[] = $this->getDateValidator();
if (isset($this->attributes['min'])) {
$validators[] = new GreaterThanValidator([
'min' => $this->attributes['min'],
'inclusive' => true,
]);
}
if (isset($this->attributes['max'])) {
$validators[] = new LessThanValidator([
'max' => $this->attributes['max'],
'inclusive' => true,
]);
}
if (! isset($this->attributes['step'])
|| 'any' !== $this->attributes['step']
) {
$validators[] = $this->getStepValidator();
}
$this->validators = $validators;
return $this->validators;
}
}
30 changes: 30 additions & 0 deletions test/Element/DateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use DateTime;
use PHPUnit\Framework\TestCase;
use Zend\Form\Element\Date as DateElement;
use Zend\Form\Exception\InvalidArgumentException;

/**
* @covers \Zend\Form\Element\Date
Expand Down Expand Up @@ -158,4 +159,33 @@ public function testStepValidatorIgnoresDaylightSavings()
}
}
}

public function testFailsWithInvalidMinSpecification()
{
$element = new DateElement('foo');
$element->setAttributes(
[
'inclusive' => true,
'min' => '2000-01-01T00',
'step' => '1',
]
);

$this->expectException(InvalidArgumentException::class);
$element->getInputSpecification();
}

public function testFailsWithInvalidMaxSpecification()
{
$element = new DateElement('foo');
$element->setAttributes(
[
'inclusive' => true,
'max' => '2001-01-01T00',
'step' => '1',
]
);
$this->expectException(InvalidArgumentException::class);
$element->getInputSpecification();
}
}
38 changes: 34 additions & 4 deletions test/Element/DateTimeLocalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

use PHPUnit\Framework\TestCase;
use Zend\Form\Element\DateTimeLocal as DateTimeLocalElement;
use Zend\Form\Exception\InvalidArgumentException;

class DateTimeLocalTest extends TestCase
{
Expand All @@ -19,8 +20,8 @@ public function testProvidesInputSpecificationThatIncludesValidatorsBasedOnAttri
$element = new DateTimeLocalElement('foo');
$element->setAttributes([
'inclusive' => true,
'min' => '2000-01-01T00:00Z',
'max' => '2001-01-01T00:00Z',
'min' => '2000-01-01T00:00',
'max' => '2001-01-01T00:00',
'step' => '1',
]);

Expand All @@ -40,11 +41,11 @@ public function testProvidesInputSpecificationThatIncludesValidatorsBasedOnAttri
switch ($class) {
case 'Zend\Validator\GreaterThan':
$this->assertTrue($validator->getInclusive());
$this->assertEquals('2000-01-01T00:00Z', $validator->getMin());
$this->assertEquals('2000-01-01T00:00', $validator->getMin());
break;
case 'Zend\Validator\LessThan':
$this->assertTrue($validator->getInclusive());
$this->assertEquals('2001-01-01T00:00Z', $validator->getMax());
$this->assertEquals('2001-01-01T00:00', $validator->getMax());
break;
case 'Zend\Validator\DateStep':
$dateInterval = new \DateInterval('PT1M');
Expand All @@ -55,4 +56,33 @@ public function testProvidesInputSpecificationThatIncludesValidatorsBasedOnAttri
}
}
}

public function testFailsWithInvalidMinSpecification()
{
$element = new DateTimeLocalElement('foo');
$element->setAttributes(
[
'inclusive' => true,
'min' => '2001-01-01T00:00Z',
'step' => '1',
]
);

$this->expectException(InvalidArgumentException::class);
$element->getInputSpecification();
}

public function testFailsWithInvalidMaxSpecification()
{
$element = new DateTimeLocalElement('foo');
$element->setAttributes(
[
'inclusive' => true,
'max' => '2001-01-01T00:00Z',
'step' => '1',
]
);
$this->expectException(InvalidArgumentException::class);
$element->getInputSpecification();
}
}
30 changes: 30 additions & 0 deletions test/Element/DateTimeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use DateTime;
use PHPUnit\Framework\TestCase;
use Zend\Form\Element\DateTime as DateTimeElement;
use Zend\Form\Exception\InvalidArgumentException;

class DateTimeTest extends TestCase
{
Expand Down Expand Up @@ -119,4 +120,33 @@ public function testSetFormatWithOptions()

$this->assertSame($format, $element->getFormat());
}

public function testFailsWithInvalidMinSpecification()
{
$element = new DateTimeElement('foo');
$element->setAttributes(
[
'inclusive' => true,
'min' => '2000-01-01T00',
'step' => '1',
]
);

$this->expectException(InvalidArgumentException::class);
$element->getInputSpecification();
}

public function testFailsWithInvalidMaxSpecification()
{
$element = new DateTimeElement('foo');
$element->setAttributes(
[
'inclusive' => true,
'max' => '2001-01-01T00',
'step' => '1',
]
);
$this->expectException(InvalidArgumentException::class);
$element->getInputSpecification();
}
}
30 changes: 30 additions & 0 deletions test/Element/TimeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

use PHPUnit\Framework\TestCase;
use Zend\Form\Element\Time as TimeElement;
use Zend\Form\Exception\InvalidArgumentException;

class TimeTest extends TestCase
{
Expand Down Expand Up @@ -58,4 +59,33 @@ public function testProvidesInputSpecificationThatIncludesValidatorsBasedOnAttri
}
}
}

public function testFailsWithInvalidMinSpecification()
{
$element = new TimeElement('foo');
$element->setAttributes(
[
'inclusive' => true,
'min' => '00:00',
'step' => '1',
]
);

$this->expectException(InvalidArgumentException::class);
$element->getInputSpecification();
}

public function testFailsWithInvalidMaxSpecification()
{
$element = new TimeElement('foo');
$element->setAttributes(
[
'inclusive' => true,
'max' => '00:00',
'step' => '1',
]
);
$this->expectException(InvalidArgumentException::class);
$element->getInputSpecification();
}
}
Loading

0 comments on commit 95beb4d

Please sign in to comment.