0010060: Timezone handling Date Filter
authorAlexander Stintzing <a.stintzing@metaways.de>
Wed, 16 Jul 2014 17:28:44 +0000 (19:28 +0200)
committerPhilipp Schüle <p.schuele@metaways.de>
Fri, 18 Jul 2014 08:30:50 +0000 (10:30 +0200)
When using the "relative" date filters like "lastWeek", the
server and not the usertimezone is used to find out the interval.

https://forge.tine20.org/mantisbt/view.php?id=10060

Change-Id: Icbe23ea957ca7dad709b9a3b6b58cde27cc90550
Reviewed-on: http://gerrit.tine20.com/customers/875
Tested-by: Jenkins CI (http://ci.tine20.com/)
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
tests/tine20/Timetracker/FilterTest.php
tests/tine20/Tinebase/Model/Filter/DateMock.php [new file with mode: 0644]
tine20/Tinebase/Model/Filter/Date.php

index 4de1392..dc23fd4 100644 (file)
@@ -133,4 +133,41 @@ class Timetracker_FilterTest extends Timetracker_AbstractTest
         $r->setFromArray($ra);
         return $r;
     }
+    
+    /**
+     * tests the corret handling of the usertimezone in the date filter
+     */
+    public function testDateIntervalFilter()
+    {
+        $taController = Timetracker_Controller_Timeaccount::getInstance();
+        $tsController = Timetracker_Controller_Timesheet::getInstance();
+        $dateString = '2014-07-14 00:15:00';
+        
+        $date = new Tinebase_DateTime($dateString, Tinebase_Core::get(Tinebase_Core::USERTIMEZONE));
+        
+        $ta = $taController->create(new Timetracker_Model_Timeaccount(array('number' => '123', 'title' => 'test')));
+        $r = new Timetracker_Model_Timesheet(array(
+            'timeaccount_id' => $ta->getId(), 
+            'account_id' => Tinebase_Core::getUser()->getId(),
+            'description' => 'lazy boring',
+            'start_date' => $date,
+        ));
+        
+        $r->setTimezone('UTC');
+        
+        $ts = $tsController->create($r);
+        
+        $filter = new Timetracker_Model_TimesheetFilter(array());
+        $dateFilter = new Tinebase_Model_Filter_DateMock(
+            array('field' => 'start_date', 'operator' => "within", "value" => "weekThis")
+        );
+        
+        $dateFilter::$testDate = $date;
+        
+        $filter->addFilter($dateFilter);
+        
+        $results = $tsController->search($filter);
+        
+        $this->assertEquals(1, $results->count());
+    }
 }
diff --git a/tests/tine20/Tinebase/Model/Filter/DateMock.php b/tests/tine20/Tinebase/Model/Filter/DateMock.php
new file mode 100644 (file)
index 0000000..3f0ed80
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+class Tinebase_Model_Filter_DateMock extends Tinebase_Model_Filter_Date {
+    
+    /**
+     * may hold a date self::now() will return
+     * 
+     * @var Tinebase_DateTime
+     */
+    public static $testDate = NULL;
+    
+    /**
+     * returns the current date if no $date string is given (needed for mocking only)
+     *
+     * @param string $date
+     * @param boolean $usertimezone
+     */
+    protected function _getDate($date = NULL, $usertimezone = FALSE)
+    {
+        if (self::$testDate == NULL) {
+            return parent::_getDate($date, $usertimezone);
+        }
+        
+        return self::$testDate;
+    }
+
+    /**
+     * Returns the actual date as new date object
+     *
+     * @return Tinebase_DateTime
+     */
+    public static function now()
+    {
+        if (self::$testDate === NULL) {
+            return new Tinebase_DateTime();
+        }
+        return self::$testDate;
+    }
+}
\ No newline at end of file
index 99fd73c..0292543 100644 (file)
@@ -105,7 +105,7 @@ class Tinebase_Model_Filter_Date extends Tinebase_Model_Filter_Abstract
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Setting "within" filter: ' . $_value);
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Timezone: ' . date_default_timezone_get());
             
-            $date = new Tinebase_DateTime();
+            $date = $this->_getDate(NULL, TRUE);
             
             // special values like this week, ...
             switch($_value) {
@@ -228,7 +228,8 @@ class Tinebase_Model_Filter_Date extends Tinebase_Model_Filter_Abstract
                 /******* try to create datetime from value string *********/
                 default:
                     try {
-                        $date = new Tinebase_DateTime($_value);
+                        $date = $this->_getDate($_value, TRUE);
+                        
                         $value = array(
                             $date->toString($this->_dateFormat),
                             $date->toString($this->_dateFormat),
@@ -240,7 +241,7 @@ class Tinebase_Model_Filter_Date extends Tinebase_Model_Filter_Abstract
                     }
             }
         } elseif ($_operator === 'inweek') {
-            $date = new Tinebase_DateTime();
+            $date = $this->_getDate(NULL, TRUE);
             
             if ($_value > 52) {
                 $_value = 52;
@@ -302,4 +303,25 @@ class Tinebase_Model_Filter_Date extends Tinebase_Model_Filter_Abstract
         
         return $result;
     }
+    
+    /**
+     * returns the current date if no $date string is given (needed for mocking only)
+     * 
+     * @param string $date
+     * @param boolean $usertimezone
+     */
+    protected function _getDate($date = NULL, $usertimezone = FALSE)
+    {
+        if (! $date) {
+            $date = Tinebase_DateTime::now();
+        } else {
+            $date = new Tinebase_DateTime($date);
+        }
+        
+        if ($usertimezone) {
+            $date->setTimezone(Tinebase_Core::get(Tinebase_Core::USERTIMEZONE));
+        }
+        
+        return $date;
+    }
 }