3c7ddee09cd7a5fe76b6a1f1d1555d2c83f45fe4
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Property / TypeConverter / DateTimeConverter.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Property\TypeConverter;
3
4 /* *
5 * This script belongs to the Extbase framework *
6 * *
7 * It is free software; you can redistribute it and/or modify it under *
8 * the terms of the GNU Lesser General Public License as published by the *
9 * Free Software Foundation, either version 3 of the License, or (at your *
10 * option) any later version. *
11 * *
12 * This script is distributed in the hope that it will be useful, but *
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
14 * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser *
15 * General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU Lesser General Public *
18 * License along with the script. *
19 * If not, see http://www.gnu.org/licenses/lgpl.html *
20 * *
21 * The TYPO3 project - inspiring people to share! *
22 * */
23 /**
24 * Converter which transforms from different input formats into DateTime objects.
25 *
26 * Source can be either a string or an array.
27 * The date string is expected to be formatted according to DEFAULT_DATE_FORMAT
28 * But the default date format can be overridden in the initialize*Action() method like this:
29 * $this->arguments['<argumentName>']
30 * ->getPropertyMappingConfiguration()
31 * ->forProperty('<propertyName>') // this line can be skipped in order to specify the format for all properties
32 * ->setTypeConverterOption('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\DateTimeConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::CONFIGURATION_DATE_FORMAT, '<dateFormat>');
33 *
34 * If the source is of type array, it is possible to override the format in the source:
35 * array(
36 * 'date' => '<dateString>',
37 * 'dateFormat' => '<dateFormat>'
38 * );
39 *
40 * By using an array as source you can also override time and timezone of the created DateTime object:
41 * array(
42 * 'date' => '<dateString>',
43 * 'hour' => '<hour>', // integer
44 * 'minute' => '<minute>', // integer
45 * 'seconds' => '<seconds>', // integer
46 * 'timezone' => '<timezone>', // string, see http://www.php.net/manual/timezones.php
47 * );
48 *
49 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
50 * @api
51 */
52 class DateTimeConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\AbstractTypeConverter implements \TYPO3\CMS\Core\SingletonInterface {
53
54 /**
55 * @var string
56 */
57 const CONFIGURATION_DATE_FORMAT = 'dateFormat';
58
59 /**
60 * The default date format is "YYYY-MM-DDT##:##:##+##:##", for example "2005-08-15T15:52:01+00:00"
61 * according to the W3C standard @see http://www.w3.org/TR/NOTE-datetime.html
62 *
63 * @var string
64 */
65 const DEFAULT_DATE_FORMAT = \DateTime::W3C;
66
67 /**
68 * @var array<string>
69 */
70 protected $sourceTypes = array('string', 'array');
71
72 /**
73 * @var string
74 */
75 protected $targetType = 'DateTime';
76
77 /**
78 * @var integer
79 */
80 protected $priority = 1;
81
82 /**
83 * Empty strings can't be converted
84 *
85 * @param string $source
86 * @param string $targetType
87 * @return boolean
88 * @author Bastian Waidelich <bastian@typo3.org>
89 */
90 public function canConvertFrom($source, $targetType) {
91 if ($targetType !== 'DateTime') {
92 return FALSE;
93 }
94 if (is_array($source)) {
95 return TRUE;
96 }
97 return is_string($source);
98 }
99
100 /**
101 * Converts $source to a DateTime using the configured dateFormat
102 *
103 * @param string $source the string to be converted to a DateTime object
104 * @param string $targetType must be "DateTime
105 * @param array $convertedChildProperties not used currently
106 * @param \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration
107 * @throws \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException
108 * @return \DateTime
109 * @author Bastian Waidelich <bastian@typo3.org>
110 */
111 public function convertFrom($source, $targetType, array $convertedChildProperties = array(), \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration = NULL) {
112 $dateFormat = $this->getDefaultDateFormat($configuration);
113 if (is_string($source)) {
114 $dateAsString = $source;
115 } else {
116 if (!isset($source['date']) || !is_string($source['date'])) {
117 throw new \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException('Could not convert the given source into a DateTime object because it was not an array with a valid date as a string', 1308003914);
118 }
119 $dateAsString = $source['date'];
120 if (isset($source['dateFormat']) && strlen($source['dateFormat']) > 0) {
121 $dateFormat = $source['dateFormat'];
122 }
123 }
124 if ($dateAsString === '') {
125 return NULL;
126 }
127 $date = \DateTime::createFromFormat($dateFormat, $dateAsString);
128 if ($date === FALSE) {
129 return new \TYPO3\CMS\Extbase\Error\Error('The string"' . $dateAsString . '" could not be converted to DateTime with format "' . $dateFormat . '"', 1307719788);
130 }
131 if (is_array($source)) {
132 $this->overrideTimeIfSpecified($date, $source);
133 $this->overrideTimezoneIfSpecified($date, $source);
134 }
135 return $date;
136 }
137
138 /**
139 * Determines the default date format to use for the conversion.
140 * If no format is specified in the mapping configuration DEFAULT_DATE_FORMAT is used.
141 *
142 * @param \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration
143 * @throws \TYPO3\CMS\Extbase\Property\Exception\InvalidPropertyMappingConfigurationException
144 * @return string
145 * @author Bastian Waidelich <bastian@typo3.org>
146 */
147 protected function getDefaultDateFormat(\TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration = NULL) {
148 if ($configuration === NULL) {
149 return self::DEFAULT_DATE_FORMAT;
150 }
151 $dateFormat = $configuration->getConfigurationValue('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\DateTimeConverter', self::CONFIGURATION_DATE_FORMAT);
152 if ($dateFormat === NULL) {
153 return self::DEFAULT_DATE_FORMAT;
154 } elseif ($dateFormat !== NULL && !is_string($dateFormat)) {
155 throw new \TYPO3\CMS\Extbase\Property\Exception\InvalidPropertyMappingConfigurationException('CONFIGURATION_DATE_FORMAT must be of type string, "' . (is_object($dateFormat) ? get_class($dateFormat) : gettype($dateFormat)) . '" given', 1307719569);
156 }
157 return $dateFormat;
158 }
159
160 /**
161 * Overrides hour, minute & second of the given date with the values in the $source array
162 *
163 * @param \DateTime $date
164 * @param array $source
165 * @return void
166 */
167 protected function overrideTimeIfSpecified(\DateTime $date, array $source) {
168 if (!isset($source['hour']) && !isset($source['minute']) && !isset($source['second'])) {
169 return;
170 }
171 $hour = isset($source['hour']) ? (integer) $source['hour'] : 0;
172 $minute = isset($source['minute']) ? (integer) $source['minute'] : 0;
173 $second = isset($source['second']) ? (integer) $source['second'] : 0;
174 $date->setTime($hour, $minute, $second);
175 }
176
177 /**
178 * Overrides timezone of the given date with $source['timezone']
179 *
180 * @param \DateTime $date
181 * @param array $source
182 * @throws \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException
183 * @return void
184 */
185 protected function overrideTimezoneIfSpecified(\DateTime $date, array $source) {
186 if (!isset($source['timezone']) || strlen($source['timezone']) === 0) {
187 return;
188 }
189 try {
190 $timezone = new \DateTimeZone($source['timezone']);
191 } catch (\Exception $e) {
192 throw new \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException('The specified timezone "' . $source['timezone'] . '" is invalid', 1308240974);
193 }
194 $date->setTimezone($timezone);
195 }
196 }
197
198 ?>