Commit cd764752 authored by Markus Klein's avatar Markus Klein Committed by Anja Leichsenring
Browse files

[FEATURE] Add base date for DateTimeViewHelper

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's avatarChristian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Anja Leichsenring's avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring's avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
parent 0eeb13a0
=============================================================
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.
......@@ -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);
......
......@@ -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;
......@@ -145,6 +145,33 @@ class DateViewHelperTest extends UnitTestCase {
$this->assertEquals('1980-12-12', $actualResult);
}
/**
* @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
*
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment