]> git.immae.eu Git - github/wallabag/wallabag.git/blame - vendor/symfony/form/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php
gitignore vendor
[github/wallabag/wallabag.git] / vendor / symfony / form / Symfony / Component / Form / Extension / Core / DataTransformer / DateTimeToArrayTransformer.php
CommitLineData
4f5b44bd
NL
1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Component\Form\Extension\Core\DataTransformer;
13
14use Symfony\Component\Form\Exception\TransformationFailedException;
15use Symfony\Component\Form\Exception\UnexpectedTypeException;
16
17/**
18 * Transforms between a normalized time and a localized time string/array.
19 *
20 * @author Bernhard Schussek <bschussek@gmail.com>
21 * @author Florian Eckerstorfer <florian@eckerstorfer.org>
22 */
23class DateTimeToArrayTransformer extends BaseDateTimeTransformer
24{
25 private $pad;
26
27 private $fields;
28
29 /**
30 * Constructor.
31 *
32 * @param string $inputTimezone The input timezone
33 * @param string $outputTimezone The output timezone
34 * @param array $fields The date fields
35 * @param Boolean $pad Whether to use padding
36 *
37 * @throws UnexpectedTypeException if a timezone is not a string
38 */
39 public function __construct($inputTimezone = null, $outputTimezone = null, array $fields = null, $pad = false)
40 {
41 parent::__construct($inputTimezone, $outputTimezone);
42
43 if (null === $fields) {
44 $fields = array('year', 'month', 'day', 'hour', 'minute', 'second');
45 }
46
47 $this->fields = $fields;
48 $this->pad = (Boolean) $pad;
49 }
50
51 /**
52 * Transforms a normalized date into a localized date.
53 *
54 * @param \DateTime $dateTime Normalized date.
55 *
56 * @return array Localized date.
57 *
58 * @throws TransformationFailedException If the given value is not an
59 * instance of \DateTime or if the
60 * output timezone is not supported.
61 */
62 public function transform($dateTime)
63 {
64 if (null === $dateTime) {
65 return array_intersect_key(array(
66 'year' => '',
67 'month' => '',
68 'day' => '',
69 'hour' => '',
70 'minute' => '',
71 'second' => '',
72 ), array_flip($this->fields));
73 }
74
75 if (!$dateTime instanceof \DateTime) {
76 throw new TransformationFailedException('Expected a \DateTime.');
77 }
78
79 $dateTime = clone $dateTime;
80 if ($this->inputTimezone !== $this->outputTimezone) {
81 try {
82 $dateTime->setTimezone(new \DateTimeZone($this->outputTimezone));
83 } catch (\Exception $e) {
84 throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
85 }
86 }
87
88 $result = array_intersect_key(array(
89 'year' => $dateTime->format('Y'),
90 'month' => $dateTime->format('m'),
91 'day' => $dateTime->format('d'),
92 'hour' => $dateTime->format('H'),
93 'minute' => $dateTime->format('i'),
94 'second' => $dateTime->format('s'),
95 ), array_flip($this->fields));
96
97 if (!$this->pad) {
98 foreach ($result as &$entry) {
99 // remove leading zeros
100 $entry = (string) (int) $entry;
101 }
102 }
103
104 return $result;
105 }
106
107 /**
108 * Transforms a localized date into a normalized date.
109 *
110 * @param array $value Localized date
111 *
112 * @return \DateTime Normalized date
113 *
114 * @throws TransformationFailedException If the given value is not an array,
115 * if the value could not be transformed
116 * or if the input timezone is not
117 * supported.
118 */
119 public function reverseTransform($value)
120 {
121 if (null === $value) {
122 return null;
123 }
124
125 if (!is_array($value)) {
126 throw new TransformationFailedException('Expected an array.');
127 }
128
129 if ('' === implode('', $value)) {
130 return null;
131 }
132
133 $emptyFields = array();
134
135 foreach ($this->fields as $field) {
136 if (!isset($value[$field])) {
137 $emptyFields[] = $field;
138 }
139 }
140
141 if (count($emptyFields) > 0) {
142 throw new TransformationFailedException(
143 sprintf('The fields "%s" should not be empty', implode('", "', $emptyFields)
144 ));
145 }
146
147 if (isset($value['month']) && !ctype_digit($value['month']) && !is_int($value['month'])) {
148 throw new TransformationFailedException('This month is invalid');
149 }
150
151 if (isset($value['day']) && !ctype_digit($value['day']) && !is_int($value['day'])) {
152 throw new TransformationFailedException('This day is invalid');
153 }
154
155 if (isset($value['year']) && !ctype_digit($value['year']) && !is_int($value['year'])) {
156 throw new TransformationFailedException('This year is invalid');
157 }
158
159 if (!empty($value['month']) && !empty($value['day']) && !empty($value['year']) && false === checkdate($value['month'], $value['day'], $value['year'])) {
160 throw new TransformationFailedException('This is an invalid date');
161 }
162
163 try {
164 $dateTime = new \DateTime(sprintf(
165 '%s-%s-%s %s:%s:%s %s',
166 empty($value['year']) ? '1970' : $value['year'],
167 empty($value['month']) ? '1' : $value['month'],
168 empty($value['day']) ? '1' : $value['day'],
169 empty($value['hour']) ? '0' : $value['hour'],
170 empty($value['minute']) ? '0' : $value['minute'],
171 empty($value['second']) ? '0' : $value['second'],
172 $this->outputTimezone
173 ));
174
175 if ($this->inputTimezone !== $this->outputTimezone) {
176 $dateTime->setTimezone(new \DateTimeZone($this->inputTimezone));
177 }
178 } catch (\Exception $e) {
179 throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
180 }
181
182 return $dateTime;
183 }
184}