f1d1f5ae1cd0bdbf22f033dd68d1924b4cd422c4
[Packages/TYPO3.CMS.git] / typo3 / sysext / fluid / Classes / ViewHelpers / Format / DateViewHelper.php
1 <?php
2 namespace TYPO3\CMS\Fluid\ViewHelpers\Format;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Utility\MathUtility;
18 use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
19 use TYPO3\CMS\Fluid\Core\ViewHelper\Exception;
20 use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
21 use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithContentArgumentAndRenderStatic;
22
23 /**
24 * Formats an object implementing \DateTimeInterface.
25 *
26 * = Examples =
27 *
28 * <code title="Defaults">
29 * <f:format.date>{dateObject}</f:format.date>
30 * </code>
31 * <output>
32 * 1980-12-13
33 * (depending on the current date)
34 * </output>
35 *
36 * <code title="Custom date format">
37 * <f:format.date format="H:i">{dateObject}</f:format.date>
38 * </code>
39 * <output>
40 * 01:23
41 * (depending on the current time)
42 * </output>
43 *
44 * <code title="Relative date with given time">
45 * <f:format.date format="Y" base="{dateObject}">-1 year</f:format.date>
46 * </code>
47 * <output>
48 * 2016
49 * (assuming dateObject is in 2017)
50 * </output>
51 *
52 * <code title="strtotime string">
53 * <f:format.date format="d.m.Y - H:i:s">+1 week 2 days 4 hours 2 seconds</f:format.date>
54 * </code>
55 * <output>
56 * 13.12.1980 - 21:03:42
57 * (depending on the current time, see http://www.php.net/manual/en/function.strtotime.php)
58 * </output>
59 *
60 * <code title="Localized dates using strftime date format">
61 * <f:format.date format="%d. %B %Y">{dateObject}</f:format.date>
62 * </code>
63 * <output>
64 * 13. Dezember 1980
65 * (depending on the current date and defined locale. In the example you see the 1980-12-13 in a german locale)
66 * </output>
67 *
68 * <code title="Inline notation">
69 * {f:format.date(date: dateObject)}
70 * </code>
71 * <output>
72 * 1980-12-13
73 * (depending on the value of {dateObject})
74 * </output>
75 *
76 * <code title="Inline notation (2nd variant)">
77 * {dateObject -> f:format.date()}
78 * </code>
79 * <output>
80 * 1980-12-13
81 * (depending on the value of {dateObject})
82 * </output>
83 */
84 class DateViewHelper extends AbstractViewHelper
85 {
86 use CompileWithContentArgumentAndRenderStatic;
87
88 /**
89 * Needed as child node's output can return a DateTime object which can't be escaped
90 *
91 * @var bool
92 */
93 protected $escapeChildren = false;
94
95 /**
96 * Initialize arguments
97 */
98 public function initializeArguments()
99 {
100 parent::initializeArguments();
101 $this->registerArgument('date', 'mixed', 'Either an object implementing DateTimeInterface or a string that is accepted by DateTime constructor');
102 $this->registerArgument('format', 'string', 'Format String which is taken to format the Date/Time', false, '');
103 $this->registerArgument('base', 'mixed', 'A base time (an object implementing DateTimeInterface or a string) used if $date is a relative date specification. Defaults to current time.');
104 }
105
106 /**
107 * @param array $arguments
108 * @param \Closure $renderChildrenClosure
109 * @param RenderingContextInterface $renderingContext
110 *
111 * @return string
112 * @throws Exception
113 */
114 public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
115 {
116 $format = $arguments['format'];
117 $base = $arguments['base'] === null ? time() : $arguments['base'];
118 if (is_string($base)) {
119 $base = trim($base);
120 }
121
122 if ($format === '') {
123 $format = $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'] ?: 'Y-m-d';
124 }
125
126 $date = $renderChildrenClosure();
127 if ($date === null) {
128 return '';
129 }
130
131 if (is_string($date)) {
132 $date = trim($date);
133 }
134
135 if ($date === '') {
136 $date = 'now';
137 }
138
139 if (!$date instanceof \DateTimeInterface) {
140 try {
141 $base = $base instanceof \DateTimeInterface ? $base->format('U') : strtotime((MathUtility::canBeInterpretedAsInteger($base) ? '@' : '') . $base);
142 $dateTimestamp = strtotime((MathUtility::canBeInterpretedAsInteger($date) ? '@' : '') . $date, $base);
143 $date = new \DateTime('@' . $dateTimestamp);
144 $date->setTimezone(new \DateTimeZone(date_default_timezone_get()));
145 } catch (\Exception $exception) {
146 throw new Exception('"' . $date . '" could not be parsed by \DateTime constructor: ' . $exception->getMessage(), 1241722579);
147 }
148 }
149
150 if (strpos($format, '%') !== false) {
151 return strftime($format, $date->format('U'));
152 } else {
153 return $date->format($format);
154 }
155 }
156 }