[BUGFIX] Allow range options to work for date/time fields 20/56020/7
authorJigal van Hemert <jigal.van.hemert@typo3.org>
Tue, 6 Mar 2018 10:22:35 +0000 (11:22 +0100)
committerOliver Hader <oliver.hader@typo3.org>
Thu, 8 Mar 2018 14:08:40 +0000 (15:08 +0100)
Date and time fields can contain ISO-8601 values. To apply lower and
upper limits the value must first be converted to a UNIX timestamp.

Resolves: #83240
Releases: master, 8.7
Change-Id: Ic15e9486cf7a4bcdf557c8a197d957ad88302b61
Reviewed-on: https://review.typo3.org/56020
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Susanne Moog <susanne.moog@typo3.org>
Tested-by: Susanne Moog <susanne.moog@typo3.org>
Reviewed-by: Jigal van Hemert <jigal.van.hemert@typo3.org>
Tested-by: Jigal van Hemert <jigal.van.hemert@typo3.org>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Mathias Schreiber <mathias.schreiber@typo3.com>
Tested-by: Mathias Schreiber <mathias.schreiber@typo3.com>
Reviewed-by: Oliver Hader <oliver.hader@typo3.org>
Tested-by: Oliver Hader <oliver.hader@typo3.org>
typo3/sysext/backend/Classes/Form/Element/InputDateTimeElement.php
typo3/sysext/core/Classes/DataHandling/DataHandler.php
typo3/sysext/core/Tests/Unit/DataHandling/DataHandlerTest.php

index 2574884..ad654c0 100644 (file)
@@ -148,10 +148,10 @@ class InputDateTimeElement extends AbstractFormElement
                 $itemValue = gmdate('c', $adjustedValue);
             }
             if (isset($config['range']['lower'])) {
-                $attributes['data-date-minDate'] = (int)$config['range']['lower'];
+                $attributes['data-date-min-date'] = (int)$config['range']['lower'] * 1000;
             }
             if (isset($config['range']['upper'])) {
-                $attributes['data-date-maxDate'] = (int)$config['range']['upper'];
+                $attributes['data-date-max-date'] = (int)$config['range']['upper'] * 1000;
             }
         }
         if (($format === 'time' || $format === 'timesec') && MathUtility::canBeInterpretedAsInteger($itemValue) && $itemValue != 0) {
index b7b5bb4..ddd8640 100644 (file)
@@ -1855,16 +1855,6 @@ class DataHandler implements LoggerAwareInterface
         if ((int)$tcaFieldConf['max'] > 0) {
             $value = mb_substr((string)$value, 0, (int)$tcaFieldConf['max'], 'utf-8');
         }
-        // Checking range of value:
-        // @todo: The "checkbox" option was removed for type=input, this check could be probably relaxed?
-        if ($tcaFieldConf['range'] && $value != $tcaFieldConf['checkbox'] && (int)$value !== (int)$tcaFieldConf['default']) {
-            if (isset($tcaFieldConf['range']['upper']) && (int)$value > (int)$tcaFieldConf['range']['upper']) {
-                $value = $tcaFieldConf['range']['upper'];
-            }
-            if (isset($tcaFieldConf['range']['lower']) && (int)$value < (int)$tcaFieldConf['range']['lower']) {
-                $value = $tcaFieldConf['range']['lower'];
-            }
-        }
 
         if (empty($tcaFieldConf['eval'])) {
             $res = ['value' => $value];
@@ -1895,6 +1885,17 @@ class DataHandler implements LoggerAwareInterface
             }
         }
 
+        // Checking range of value:
+        // @todo: The "checkbox" option was removed for type=input, this check could be probably relaxed?
+        if ($tcaFieldConf['range'] && $res['value'] != $tcaFieldConf['checkbox'] && (int)$res['value'] !== (int)$tcaFieldConf['default']) {
+            if (isset($tcaFieldConf['range']['upper']) && (int)$res['value'] > (int)$tcaFieldConf['range']['upper']) {
+                $res['value'] = (int)$tcaFieldConf['range']['upper'];
+            }
+            if (isset($tcaFieldConf['range']['lower']) && (int)$res['value'] < (int)$tcaFieldConf['range']['lower']) {
+                $res['value'] = (int)$tcaFieldConf['range']['lower'];
+            }
+        }
+
         // Handle native date/time fields
         if ($isDateOrDateTimeField) {
             // Convert the timestamp back to a date/time
index 110fddc..3349da2 100644 (file)
@@ -214,12 +214,20 @@ class DataHandlerTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
                 '0',
                 0
             ],
-            '"-1999999" is interpreted correctly as -1999999 and is lot lower than -200000' => [
-                '-1999999',
-                -1999999
+            '"-2000001" is interpreted correctly as -2000001 but is lower than -2000000 and set to -2000000' => [
+                '-2000001',
+                -2000000
             ],
-            '"3000000" is interpreted correctly as 3000000 but is higher then 200000 and set to 200000' => [
-                '3000000',
+            '"-2000000" is interpreted correctly as -2000000 and is equal to -2000000' => [
+                '-2000000',
+                -2000000
+            ],
+            '"2000000" is interpreted correctly as 2000000 and is equal to 2000000' => [
+                '2000000',
+                2000000
+            ],
+            '"2000001" is interpreted correctly as 2000001 but is greater then 2000000 and set to 2000000' => [
+                '2000001',
                 2000000
             ],
         ];
@@ -248,6 +256,62 @@ class DataHandlerTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
     /**
      * @return array
      */
+    public function inputValuesDataTimeDataProvider()
+    {
+        return [
+            'undershot date adjusted' => [
+                '2018-02-28T00:00:00Z',
+                1519862400,
+            ],
+            'exact lower date accepted' => [
+                '2018-03-01T00:00:00Z',
+                1519862400,
+            ],
+            'exact upper date accepted' => [
+                '2018-03-31T23:59:59Z',
+                1522540799,
+            ],
+            'exceeded date adjusted' => [
+                '2018-04-01T00:00:00Z',
+                1522540799,
+            ],
+        ];
+    }
+
+    /**
+     * @param string $value
+     * @param int $expected
+     *
+     * @test
+     * @dataProvider inputValuesDataTimeDataProvider
+     */
+    public function inputValueCheckRecognizesDateTimeValuesAsIntegerValuesCorrectly($value, int $expected)
+    {
+        $tcaFieldConf = [
+            'input' => [],
+            'eval' => 'datetime',
+            'range' => [
+                // unix timestamp: 1519862400
+                'lower' => gmmktime(0, 0, 0, 3, 1, 2018),
+                // unix timestamp: 1522540799
+                'upper' => gmmktime(23, 59, 59, 3, 31, 2018),
+            ]
+        ];
+
+        // @todo Switch to UTC since otherwise DataHandler removes timezone offset
+        $previousTimezone = date_default_timezone_get();
+        date_default_timezone_set('UTC');
+
+        $returnValue = $this->subject->_call('checkValueForInput', $value, $tcaFieldConf, '', 0, 0, '');
+
+        date_default_timezone_set($previousTimezone);
+
+        $this->assertSame($returnValue['value'], $expected);
+    }
+
+    /**
+     * @return array
+     */
     public function inputValueCheckDoesNotCallGetDateTimeFormatsForNonDatetimeFieldsDataProvider()
     {
         return [