eb13c2f24b0185f079331df1e6658e8358958cfa
[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\Rendering\RenderingContextInterface;
19 use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
20 use TYPO3\CMS\Fluid\Core\ViewHelper\Exception;
21
22 /**
23 * Formats an object implementing \DateTimeInterface.
24 *
25 * = Examples =
26 *
27 * <code title="Defaults">
28 * <f:format.date>{dateObject}</f:format.date>
29 * </code>
30 * <output>
31 * 1980-12-13
32 * (depending on the current date)
33 * </output>
34 *
35 * <code title="Custom date format">
36 * <f:format.date format="H:i">{dateObject}</f:format.date>
37 * </code>
38 * <output>
39 * 01:23
40 * (depending on the current time)
41 * </output>
42 *
43 * <code title="Relative date with given time">
44 * <f:format.date format="Y" base="{dateObject}">-1 year</f:format.date>
45 * </code>
46 * <output>
47 * 2016
48 * (assuming dateObject is in 2017)
49 * </output>
50 *
51 * <code title="strtotime string">
52 * <f:format.date format="d.m.Y - H:i:s">+1 week 2 days 4 hours 2 seconds</f:format.date>
53 * </code>
54 * <output>
55 * 13.12.1980 - 21:03:42
56 * (depending on the current time, see http://www.php.net/manual/en/function.strtotime.php)
57 * </output>
58 *
59 * <code title="Localized dates using strftime date format">
60 * <f:format.date format="%d. %B %Y">{dateObject}</f:format.date>
61 * </code>
62 * <output>
63 * 13. Dezember 1980
64 * (depending on the current date and defined locale. In the example you see the 1980-12-13 in a german locale)
65 * </output>
66 *
67 * <code title="Inline notation">
68 * {f:format.date(date: dateObject)}
69 * </code>
70 * <output>
71 * 1980-12-13
72 * (depending on the value of {dateObject})
73 * </output>
74 *
75 * <code title="Inline notation (2nd variant)">
76 * {dateObject -> f:format.date()}
77 * </code>
78 * <output>
79 * 1980-12-13
80 * (depending on the value of {dateObject})
81 * </output>
82 *
83 * @api
84 */
85 class DateViewHelper extends AbstractViewHelper
86 {
87 /**
88 * @var bool
89 */
90 protected $escapeOutput = false;
91
92 /**
93 * @var bool
94 */
95 protected $escapeChildren = false;
96
97 /**
98 * Render the supplied DateTime object as a formatted date.
99 *
100 * @param mixed $date either an object implementing DateTimeInterface or a string that is accepted by DateTime constructor
101 * @param string $format Format String which is taken to format the Date/Time
102 * @param mixed $base A base time (an object implementing DateTimeInterface or a string) used if $date is a relative date specification. Defaults to current time.
103 *
104 * @return string Formatted date
105 * @throws Exception
106 * @api
107 */
108 public function render($date = null, $format = '', $base = null)
109 {
110 return static::renderStatic(
111 array(
112 'date' => $date,
113 'format' => $format,
114 'base' => $base
115 ),
116 $this->buildRenderChildrenClosure(),
117 $this->renderingContext
118 );
119 }
120
121 /**
122 * @param array $arguments
123 * @param \Closure $renderChildrenClosure
124 * @param RenderingContextInterface $renderingContext
125 *
126 * @return string
127 * @throws Exception
128 */
129 public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
130 {
131 $date = $arguments['date'];
132 $format = $arguments['format'];
133 $base = $arguments['base'] === null ? time() : $arguments['base'];
134 if (is_string($base)) {
135 $base = trim($base);
136 }
137
138 if ($format === '') {
139 $format = $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'] ?: 'Y-m-d';
140 }
141
142 if ($date === null) {
143 $date = $renderChildrenClosure();
144 if ($date === null) {
145 return '';
146 }
147 }
148
149 if (is_string($date)) {
150 $date = trim($date);
151 }
152
153 if ($date === '') {
154 $date = 'now';
155 }
156
157 if (!$date instanceof \DateTimeInterface) {
158 try {
159 $base = $base instanceof \DateTimeInterface ? $base->format('U') : strtotime((MathUtility::canBeInterpretedAsInteger($base) ? '@' : '') . $base);
160 $dateTimestamp = strtotime((MathUtility::canBeInterpretedAsInteger($date) ? '@' : '') . $date, $base);
161 $date = new \DateTime('@' . $dateTimestamp);
162 $date->setTimezone(new \DateTimeZone(date_default_timezone_get()));
163 } catch (\Exception $exception) {
164 throw new Exception('"' . $date . '" could not be parsed by \DateTime constructor: ' . $exception->getMessage(), 1241722579);
165 }
166 }
167
168 if (strpos($format, '%') !== false) {
169 return strftime($format, $date->format('U'));
170 } else {
171 return $date->format($format);
172 }
173 }
174 }