Enhancement for DateValidator (#7177, #10165)

Added parameter to define if checking for 'date' or 'dateTime'
and updated parseDateValueIntl($value, $format) to facilitate
this validation based on defined type.

Added unit tests to for validating dateTime values when using short format validation.

close #10778
This commit is contained in:
Robbert Jan
2016-02-07 17:22:44 +01:00
committed by Carsten Brandt
parent 2ac17ddae6
commit bb0ef88860
3 changed files with 66 additions and 2 deletions

View File

@ -41,6 +41,7 @@ Yii Framework 2 Change Log
- Bug #11280: Descendants of `yii\console\controllers\BaseMigrateController`, like the one for MongoDB, unable to create new migration (klimov-paul) - Bug #11280: Descendants of `yii\console\controllers\BaseMigrateController`, like the one for MongoDB, unable to create new migration (klimov-paul)
- Bug: SQlite querybuilder did not create primary key with bigint for `TYPE_BIGPK` (cebe) - Bug: SQlite querybuilder did not create primary key with bigint for `TYPE_BIGPK` (cebe)
- Enh #5469: Add mimetype validation by mask in FileValidator (kirsenn, samdark, silverfire) - Enh #5469: Add mimetype validation by mask in FileValidator (kirsenn, samdark, silverfire)
- Enh #7177, #10165: Added support for validating datetime values using intl short format to `DateValidator` (VirtualRJ)
- Enh #8145, #8139, #10234 #11153: `yii\validators\Validator::$attributes` property now supports `!attribute` notation to validate attribute, but do not mark it as safe (mdmunir) - Enh #8145, #8139, #10234 #11153: `yii\validators\Validator::$attributes` property now supports `!attribute` notation to validate attribute, but do not mark it as safe (mdmunir)
- Enh #8148: Implemented ability to add comment on table and column in migration (vaseninm, silverfire) - Enh #8148: Implemented ability to add comment on table and column in migration (vaseninm, silverfire)
- Enh #8505: `yii\db\Query` now contains a andFilterCompare() method that allows filtering using operators in the query value (lennartvdd) - Enh #8505: `yii\db\Query` now contains a andFilterCompare() method that allows filtering using operators in the query value (lennartvdd)

View File

@ -30,6 +30,19 @@ use yii\helpers\FormatConverter;
*/ */
class DateValidator extends Validator class DateValidator extends Validator
{ {
/**
* Constant for specifying the validation [[type]] as a date value, used for validation with intl short format.
* @since 2.0.8
* @see type
*/
const TYPE_DATE = 'date';
/**
* Constant for specifying the validation [[type]] as a datetime value, used for validation with intl short format.
* @since 2.0.8
* @see type
*/
const TYPE_DATETIME = 'datetime';
/** /**
* @var string the date format that the value being validated should follow. * @var string the date format that the value being validated should follow.
* This can be a date time pattern as described in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax). * This can be a date time pattern as described in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax).
@ -143,7 +156,22 @@ class DateValidator extends Validator
* @since 2.0.4 * @since 2.0.4
*/ */
public $minString; public $minString;
/**
* @var string the type of the date or time format to validate, when [[format]] is one of the intl
* short formats, `short`, `medium`, `long`, or `full`.
*
* This is only effective when the [PHP intl extension](http://php.net/manual/en/book.intl.php) is installed.
*
* This property can be set to the following values:
*
* - [[TYPE_DATE]] - for validating date values only, that means only values that do not include a time range are valid.
* - [[TYPE_DATETIME]] - for validating datetime values, that contain a date part as well as a time part.
*
* Defaults to [[TYPE_DATE]].
* @since 2.0.8
*/
public $type = self::TYPE_DATE;
/** /**
* @var array map of short format names to IntlDateFormatter constant values. * @var array map of short format names to IntlDateFormatter constant values.
*/ */
@ -297,7 +325,13 @@ class DateValidator extends Validator
private function parseDateValueIntl($value, $format) private function parseDateValueIntl($value, $format)
{ {
if (isset($this->_dateFormats[$format])) { if (isset($this->_dateFormats[$format])) {
$formatter = new IntlDateFormatter($this->locale, $this->_dateFormats[$format], IntlDateFormatter::NONE, 'UTC'); if ($this->type === self::TYPE_DATE) {
$formatter = new IntlDateFormatter($this->locale, $this->_dateFormats[$format], IntlDateFormatter::NONE, 'UTC');
} elseif ($this->type === self::TYPE_DATETIME) {
$formatter = new IntlDateFormatter($this->locale, $this->_dateFormats[$format], $this->_dateFormats[$format], $this->timeZone);
} else {
throw new InvalidConfigException('Unknown validation type set for DateValidator::$type: ' . $this->type);
}
} else { } else {
// if no time was provided in the format string set time to 0 to get a simple date timestamp // if no time was provided in the format string set time to 0 to get a simple date timestamp
$hasTimeInfo = (strpbrk($format, 'ahHkKmsSA') !== false); $hasTimeInfo = (strpbrk($format, 'ahHkKmsSA') !== false);

View File

@ -280,6 +280,35 @@ class DateValidatorTest extends TestCase
public function testIntlValidationWithTime($timezone) public function testIntlValidationWithTime($timezone)
{ {
$this->testValidationWithTime($timezone); $this->testValidationWithTime($timezone);
$this->mockApplication([
'language' => 'en-GB',
'components' => [
'formatter' => [
'dateFormat' => 'short',
]
]
]);
$val = new DateValidator(['type' => 'dateTime']);
$this->assertTrue($val->validate('31/5/2017 12:30'));
$this->assertFalse($val->validate('5/31/2017 12:30'));
$val = new DateValidator(['format' => 'short', 'locale' => 'en-GB', 'type' => DateValidator::TYPE_DATETIME]);
$this->assertTrue($val->validate('31/5/2017 12:30'));
$this->assertFalse($val->validate('5/31/2017 12:30'));
$this->mockApplication([
'language' => 'de-DE',
'components' => [
'formatter' => [
'dateFormat' => 'short',
]
]
]);
$val = new DateValidator(['type' => 'dateTime']);
$this->assertTrue($val->validate('31.5.2017 12:30'));
$this->assertFalse($val->validate('5.31.2017 12:30'));
$val = new DateValidator(['format' => 'short', 'locale' => 'de-DE', 'type' => DateValidator::TYPE_DATETIME]);
$this->assertTrue($val->validate('31.5.2017 12:30'));
$this->assertFalse($val->validate('5.31.2017 12:30'));
} }
/** /**