[FEATURE] Add base date for DateTimeViewHelper 43/40843/5
authorMarkus Klein <markus.klein@typo3.org>
Wed, 1 Jul 2015 21:17:52 +0000 (23:17 +0200)
committerAnja Leichsenring <aleichsenring@ab-softlab.de>
Thu, 9 Jul 2015 21:12:23 +0000 (23:12 +0200)
This allows to use the full set of relative date formats
on a given base time:
http://www.php.net/manual/en/datetime.formats.relative.php

Resolves: #68022
Releases: master
Change-Id: Icf7c204b9c1d280805679b6edba7c03f575d936e
Reviewed-on: http://review.typo3.org/40843
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
typo3/sysext/core/Documentation/Changelog/master/Feature-68022-AddedBaseDateAttributeToDateViewHelper.rst [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Format/DateViewHelper.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/DateViewHelperTest.php

diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-68022-AddedBaseDateAttributeToDateViewHelper.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-68022-AddedBaseDateAttributeToDateViewHelper.rst
new file mode 100644 (file)
index 0000000..9cdc923
--- /dev/null
@@ -0,0 +1,19 @@
+=============================================================
+Feature: #68022 - Added base date attribute to DateViewHelper
+=============================================================
+
+Description
+===========
+
+The DateViewHelper has been improved with an optional attribute named ``base``.
+The attribute can be used to define a base-date when using a relative time specification for ``date``.
+If ``date`` is a ``DateTime`` object, ``base`` is ignored.
+
+The possible relative date format specification can be found in:
+http://www.php.net/manual/en/datetime.formats.relative.php
+
+.. code-block:: html
+
+       <f:format.date format="Y" base="{dateObject}">-1 year</f:format.date>
+
+This will result in the output ``2016`` assuming the ``dateObject`` is some date in 2017.
index e0817c8..8a35ee3 100644 (file)
@@ -38,6 +38,14 @@ use TYPO3\CMS\Fluid\Core\ViewHelper\Facets\CompilableInterface;
  * (depending on the current time)
  * </output>
  *
+ * <code title="Relative date with given time">
+ * <f:format.date format="Y" base="{dateObject}">-1 year</f:format.date>
+ * </code>
+ * <output>
+ * 2016
+ * (assuming dateObject is in 2017)
+ * </output>
+ *
  * <code title="strtotime string">
  * <f:format.date format="d.m.Y - H:i:s">+1 week 2 days 4 hours 2 seconds</f:format.date>
  * </code>
@@ -84,16 +92,18 @@ class DateViewHelper extends AbstractViewHelper implements CompilableInterface {
         *
         * @param mixed $date either a DateTime object or a string that is accepted by DateTime constructor
         * @param string $format Format String which is taken to format the Date/Time
+        * @param mixed $base A base time (a DateTime object or a string) used if $date is a relative date specification. Defaults to current time.
         *
         * @return string Formatted date
         * @throws Exception
         * @api
         */
-       public function render($date = NULL, $format = '') {
+       public function render($date = NULL, $format = '', $base = NULL) {
                return static::renderStatic(
                        array(
                                'date' => $date,
-                               'format' => $format
+                               'format' => $format,
+                               'base' => $base
                        ),
                        $this->buildRenderChildrenClosure(),
                        $this->renderingContext
@@ -102,7 +112,7 @@ class DateViewHelper extends AbstractViewHelper implements CompilableInterface {
 
        /**
         * @param array $arguments
-        * @param callable $renderChildrenClosure
+        * @param \Closure $renderChildrenClosure
         * @param RenderingContextInterface $renderingContext
         *
         * @return string
@@ -111,6 +121,7 @@ class DateViewHelper extends AbstractViewHelper implements CompilableInterface {
        static public function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext) {
                $date = $arguments['date'];
                $format = $arguments['format'];
+               $base = $arguments['base'] === NULL ? time() : $arguments['base'];
                if ($format === '') {
                        $format = $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'] ?: 'Y-m-d';
                }
@@ -123,11 +134,9 @@ class DateViewHelper extends AbstractViewHelper implements CompilableInterface {
                }
                if (!$date instanceof \DateTime) {
                        try {
-                               if (MathUtility::canBeInterpretedAsInteger($date)) {
-                                       $date = new \DateTime('@' . $date);
-                               } else {
-                                       $date = new \DateTime($date);
-                               }
+                               $base = $base instanceof \DateTime ? $base->format('U') : strtotime((MathUtility::canBeInterpretedAsInteger($date) ? '@' : '') . $base);
+                               $dateTimestamp = strtotime((MathUtility::canBeInterpretedAsInteger($date) ? '@' : '') . $date, $base);
+                               $date = new \DateTime('@' . $dateTimestamp);
                                $date->setTimezone(new \DateTimeZone(date_default_timezone_get()));
                        } catch (\Exception $exception) {
                                throw new Exception('"' . $date . '" could not be parsed by \DateTime constructor.', 1241722579);
index f8b4550..c686bf3 100644 (file)
@@ -25,7 +25,7 @@ class DateViewHelperTest extends UnitTestCase {
        protected $backupLocales = array();
 
        /**
-        * @var DateViewHelper
+        * @var DateViewHelper|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface
         */
        protected $subject;
 
@@ -146,6 +146,33 @@ class DateViewHelperTest extends UnitTestCase {
        }
 
        /**
+        * @test
+        */
+       public function baseArgumentIsConsideredForRelativeDate() {
+               $this->subject->expects($this->never())->method('renderChildren');
+               $actualResult = $this->subject->render('-1 year', 'Y', '2017-01-01');
+               $this->assertEquals('2016', $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function baseArgumentAsDateTimeIsConsideredForRelativeDate() {
+               $this->subject->expects($this->never())->method('renderChildren');
+               $actualResult = $this->subject->render('-1 year', 'Y', new \DateTime('2017-01-01'));
+               $this->assertEquals('2016', $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function baseArgumentDoesNotAffectAbsoluteTime() {
+               $this->subject->expects($this->never())->method('renderChildren');
+               $actualResult = $this->subject->render('@1435784732', 'Y', 1485907200); // somewhere in 2017
+               $this->assertEquals('2015', $actualResult);
+       }
+
+       /**
         * Data provider for viewHelperRespectsDefaultTimezoneForIntegerTimestamp
         *
         * @return array