From be44d265e20d3434f3f2774fc4a77249c4ddb6f4 Mon Sep 17 00:00:00 2001 From: MaximAL Date: Fri, 26 Feb 2016 15:06:24 +0300 Subject: [PATCH 1/2] Fix accidental `getResponseHeader()` fails --- framework/assets/yii.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/assets/yii.js b/framework/assets/yii.js index cf9168bada..0859b0ecf4 100644 --- a/framework/assets/yii.js +++ b/framework/assets/yii.js @@ -324,7 +324,7 @@ yii = (function ($) { function initRedirectHandler() { // handle AJAX redirection $(document).ajaxComplete(function (event, xhr, settings) { - var url = xhr.getResponseHeader('X-Redirect'); + var url = xhr && xhr.getResponseHeader('X-Redirect'); if (url) { window.location = url; } From 779b1e90cea13ca3a05768a8e82b96b022d1f710 Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Fri, 26 Feb 2016 15:02:22 +0200 Subject: [PATCH 2/2] `yii\validators\DateValidator` skip validation for `timestampAttribute`, if it is already in correct format --- framework/CHANGELOG.md | 1 + framework/validators/DateValidator.php | 27 ++++++++++++++-- .../validators/DateValidatorTest.php | 32 +++++++++++++++++++ 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index c11e7e346d..e26611223b 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -10,6 +10,7 @@ Yii Framework 2 Change Log - Bug #10946: Fixed parameters binding to the SQL query in `yii\db\mysqlSchema::findConstraints()` (silverfire) - 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 #8602: `yii\validators\DateValidator` skip validation for `timestampAttribute`, if it is already in correct format (klimov-paul) - Enh #9893: `yii.js` handleAction enhanced to support for data-form attribute, so links can trigger specific forms (SamMousa) - Enh #10487: `yii\helpers\BaseArrayHelper::index()` got a third parameter `$groupBy` to group the input array by the key in one or more dimensions (quantum13, silverfire, samdark) - Enh #8639: Improve ActiveRecord to not create new instances of classes when objects are available (cebe) diff --git a/framework/validators/DateValidator.php b/framework/validators/DateValidator.php index 118ce98264..ecfab4e38c 100644 --- a/framework/validators/DateValidator.php +++ b/framework/validators/DateValidator.php @@ -209,6 +209,17 @@ class DateValidator extends Validator $value = $model->$attribute; $timestamp = $this->parseDateValue($value); if ($timestamp === false) { + if ($this->timestampAttribute === $attribute) { + if ($this->timestampAttributeFormat === null) { + if (ctype_digit($value)) { + return; + } + } else { + if ($this->parseDateValueFormat($value, $this->timestampAttributeFormat) !== false) { + return; + } + } + } $this->addError($model, $attribute, $this->message, []); } elseif ($this->min !== null && $timestamp < $this->min) { $this->addError($model, $attribute, $this->tooSmall, ['min' => $this->minString]); @@ -247,12 +258,24 @@ class DateValidator extends Validator * @return integer|false a UNIX timestamp or `false` on failure. */ protected function parseDateValue($value) + { + // TODO consider merging these methods into single one at 2.1 + return $this->parseDateValueFormat($value, $this->format); + } + + /** + * Parses date string into UNIX timestamp + * + * @param string $value string representing date + * @param string $format expected date format + * @return integer|false a UNIX timestamp or `false` on failure. + */ + private function parseDateValueFormat($value, $format) { if (is_array($value)) { return false; } - $format = $this->format; - if (strncmp($this->format, 'php:', 4) === 0) { + if (strncmp($format, 'php:', 4) === 0) { $format = substr($format, 4); } else { if (extension_loaded('intl')) { diff --git a/tests/framework/validators/DateValidatorTest.php b/tests/framework/validators/DateValidatorTest.php index c3e1d00674..19d58db077 100644 --- a/tests/framework/validators/DateValidatorTest.php +++ b/tests/framework/validators/DateValidatorTest.php @@ -539,4 +539,36 @@ class DateValidatorTest extends TestCase return false; } + + /** + * @depends testValidateAttributePHPFormat + */ + public function testTimestampAttributeSkipValidation() + { + // timestamp as integer + $val = new DateValidator(['format' => 'php:Y/m/d', 'timestampAttribute' => 'attr_date']); + $model = new FakedValidationModel(); + $model->attr_date = 1379030400; + $val->validateAttribute($model, 'attr_date'); + $this->assertFalse($model->hasErrors('attr_date')); + + $val = new DateValidator(['format' => 'php:Y/m/d', 'timestampAttribute' => 'attr_date']); + $model = new FakedValidationModel(); + $model->attr_date = 'invalid'; + $val->validateAttribute($model, 'attr_date'); + $this->assertTrue($model->hasErrors('attr_date')); + + // timestamp as formatted date + $val = new DateValidator(['format' => 'php:Y/m/d', 'timestampAttribute' => 'attr_date', 'timestampAttributeFormat' => 'php:Y-m-d']); + $model = new FakedValidationModel(); + $model->attr_date = '2013-09-13'; + $val->validateAttribute($model, 'attr_date'); + $this->assertFalse($model->hasErrors('attr_date')); + + $val = new DateValidator(['format' => 'php:Y/m/d', 'timestampAttribute' => 'attr_date', 'timestampAttributeFormat' => 'php:Y-m-d']); + $model = new FakedValidationModel(); + $model->attr_date = '2013-09-2013'; + $val->validateAttribute($model, 'attr_date'); + $this->assertTrue($model->hasErrors('attr_date')); + } }