diff --git a/CHANGELOG.md b/CHANGELOG.md index 3121473f..0e5601f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,8 @@ All notable changes to this project will be documented in this file, in reverse ### Fixed -- Nothing. +- An invalid date string input caused an exception to be thrown by filter(). Added an option to return unfiltered input in the event that the input cannot be formatted. + ## 2.9.1 - 2018-12-17 diff --git a/docs/book/standard-filters.md b/docs/book/standard-filters.md index 1ecca8e4..caa6cbb0 100644 --- a/docs/book/standard-filters.md +++ b/docs/book/standard-filters.md @@ -710,6 +710,35 @@ All options can be set at instantiation or by using a related method. For exampl methods for `target` are `getTarget()` and `setTarget()`. You can also use the `setOptions()` method which accepts an array of all options. +## DateTimeFormatter + +Returns parsable date input string formatted according to format. + +### Supported Options + +The following options are supported for `Zend\Filter\DateTimeFormatter`: + +- `format`: A format string compatible with [DateTime::format](http://php.net/manual/en/datetime.format.php). Defaults to `DateTime::ISO8601` which [is not compliant with ISO-8601](http://php.net/manual/en/class.datetimeinterface.php#datetime.constants.iso8601). +- `throwInvalidDateException`: Defaults to `true`. Set to `false` to return the input value unfiltered in the event that DateTime is unable to parse the input. + +### Basic Usage + +```php +$filter = new Zend\Filter\DateTimeFormatter(); + +print $filter->filter('1/2/03'); +``` + +Returns "2003-01-02T00:00:00+0000". + +```php +$filter = new Zend\Filter\DateTimeFormatter(); + +print $filter->filter('03-1-2'); +``` + +Returns "2003-01-02T00:00:00+0000". + ## Digits Returns the string `$value`, removing all but digits. diff --git a/src/DateTimeFormatter.php b/src/DateTimeFormatter.php index 03f6699f..9851e8b0 100644 --- a/src/DateTimeFormatter.php +++ b/src/DateTimeFormatter.php @@ -16,10 +16,22 @@ class DateTimeFormatter extends AbstractFilter /** * A valid format string accepted by date() * + * @todo This default should be changed to DateTime::ATOM or perhaps DateTime::RFC3339 + * @see http://php.net/manual/en/class.datetimeinterface.php#datetime.constants.iso8601 + * @see https://github.com/zendframework/zend-filter/issues/58 + * * @var string */ protected $format = DateTime::ISO8601; + /** + * Whether or not to throw an exception in the event that DateTime + * is unable to parse the input + * + * @var bool + */ + protected $throwInvalidDateException = true; + /** * Sets filter options * @@ -45,6 +57,20 @@ public function setFormat($format) return $this; } + /** + * Set whether or not to throw an exception in the event that DateTime + * cannot parse the input value + * + * @param bool $throwException + * @return self + */ + public function setThrowInvalidDateException(bool $throwException): self + { + $this->throwInvalidDateException = $throwInvalidDateException; + + return $this; + } + /** * Filter a datetime string by normalizing it to the filters specified format * @@ -57,6 +83,9 @@ public function filter($value) try { $result = $this->normalizeDateTime($value); } catch (\Exception $e) { + if (!$this->throwInvalidDateException) { + return $value; + } // DateTime threw an exception, an invalid date string was provided throw new Exception\InvalidArgumentException('Invalid date string provided', $e->getCode(), $e); } diff --git a/test/DateTimeFormatterTest.php b/test/DateTimeFormatterTest.php index 8c1ca884..a28e29b5 100644 --- a/test/DateTimeFormatterTest.php +++ b/test/DateTimeFormatterTest.php @@ -123,4 +123,19 @@ public function testInvalidArgumentExceptionThrownOnInvalidInput() $filter = new DateTimeFormatter(); $result = $filter->filter('2013-31-31'); } + + public function testInvalidInputUnfilteredWhenExceptionsOptionIsDisabled() + { + $filter = new DateTimeFormatter(); + $filter->setThrowInvalidDateException(false); + $invalidValue = '2013-31-31'; + $this->assertSame($invalidValue, $filter->filter($invalidValue)); + } + + public function testInvalidInputUnfilteredWhenExceptionsOptionIsDisabledViaConstructor() + { + $filter = new DateTimeFormatter(['throwInvalidDateException' => false]); + $invalidValue = '2013-31-31'; + $this->assertSame($invalidValue, $filter->filter($invalidValue)); + } }