PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.20
Booking for Appointments and Events Calendar – Amelia v1.2.20
2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / vendor / sabre / vobject / lib / Property / VCard / DateAndOrTime.php
ameliabooking / vendor / sabre / vobject / lib / Property / VCard Last commit date
Date.php 1 year ago DateAndOrTime.php 1 year ago DateTime.php 1 year ago LanguageTag.php 1 year ago PhoneNumber.php 1 year ago TimeStamp.php 1 year ago
DateAndOrTime.php
368 lines
1 <?php
2
3 namespace Sabre\VObject\Property\VCard;
4
5 use DateTime;
6 use DateTimeImmutable;
7 use DateTimeInterface;
8 use Sabre\VObject\DateTimeParser;
9 use Sabre\VObject\InvalidDataException;
10 use Sabre\VObject\Property;
11 use Sabre\Xml;
12
13 /**
14 * DateAndOrTime property.
15 *
16 * This object encodes DATE-AND-OR-TIME values.
17 *
18 * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
19 * @author Evert Pot (http://evertpot.com/)
20 * @license http://sabre.io/license/ Modified BSD License
21 */
22 class DateAndOrTime extends Property
23 {
24 /**
25 * Field separator.
26 *
27 * @var string
28 */
29 public $delimiter = '';
30
31 /**
32 * Returns the type of value.
33 *
34 * This corresponds to the VALUE= parameter. Every property also has a
35 * 'default' valueType.
36 *
37 * @return string
38 */
39 public function getValueType()
40 {
41 return 'DATE-AND-OR-TIME';
42 }
43
44 /**
45 * Sets a multi-valued property.
46 *
47 * You may also specify DateTimeInterface objects here.
48 */
49 public function setParts(array $parts)
50 {
51 if (count($parts) > 1) {
52 throw new \InvalidArgumentException('Only one value allowed');
53 }
54 if (isset($parts[0]) && $parts[0] instanceof DateTimeInterface) {
55 $this->setDateTime($parts[0]);
56 } else {
57 parent::setParts($parts);
58 }
59 }
60
61 /**
62 * Updates the current value.
63 *
64 * This may be either a single, or multiple strings in an array.
65 *
66 * Instead of strings, you may also use DateTimeInterface here.
67 *
68 * @param string|array|DateTimeInterface $value
69 */
70 public function setValue($value)
71 {
72 if ($value instanceof DateTimeInterface) {
73 $this->setDateTime($value);
74 } else {
75 parent::setValue($value);
76 }
77 }
78
79 /**
80 * Sets the property as a DateTime object.
81 */
82 public function setDateTime(DateTimeInterface $dt)
83 {
84 $tz = $dt->getTimeZone();
85 $isUtc = in_array($tz->getName(), ['UTC', 'GMT', 'Z']);
86
87 if ($isUtc) {
88 $value = $dt->format('Ymd\\THis\\Z');
89 } else {
90 // Calculating the offset.
91 $value = $dt->format('Ymd\\THisO');
92 }
93
94 $this->value = $value;
95 }
96
97 /**
98 * Returns a date-time value.
99 *
100 * Note that if this property contained more than 1 date-time, only the
101 * first will be returned. To get an array with multiple values, call
102 * getDateTimes.
103 *
104 * If no time was specified, we will always use midnight (in the default
105 * timezone) as the time.
106 *
107 * If parts of the date were omitted, such as the year, we will grab the
108 * current values for those. So at the time of writing, if the year was
109 * omitted, we would have filled in 2014.
110 *
111 * @return DateTimeImmutable
112 */
113 public function getDateTime()
114 {
115 $now = new DateTime();
116
117 $tzFormat = 0 === $now->getTimezone()->getOffset($now) ? '\\Z' : 'O';
118 $nowParts = DateTimeParser::parseVCardDateTime($now->format('Ymd\\This'.$tzFormat));
119
120 $dateParts = DateTimeParser::parseVCardDateTime($this->getValue());
121
122 // This sets all the missing parts to the current date/time.
123 // So if the year was missing for a birthday, we're making it 'this
124 // year'.
125 foreach ($dateParts as $k => $v) {
126 if (is_null($v)) {
127 $dateParts[$k] = $nowParts[$k];
128 }
129 }
130
131 return new DateTimeImmutable("$dateParts[year]-$dateParts[month]-$dateParts[date] $dateParts[hour]:$dateParts[minute]:$dateParts[second] $dateParts[timezone]");
132 }
133
134 /**
135 * Returns the value, in the format it should be encoded for json.
136 *
137 * This method must always return an array.
138 *
139 * @return array
140 */
141 public function getJsonValue()
142 {
143 $parts = DateTimeParser::parseVCardDateTime($this->getValue());
144
145 $dateStr = '';
146
147 // Year
148 if (!is_null($parts['year'])) {
149 $dateStr .= $parts['year'];
150
151 if (!is_null($parts['month'])) {
152 // If a year and a month is set, we need to insert a separator
153 // dash.
154 $dateStr .= '-';
155 }
156 } else {
157 if (!is_null($parts['month']) || !is_null($parts['date'])) {
158 // Inserting two dashes
159 $dateStr .= '--';
160 }
161 }
162
163 // Month
164 if (!is_null($parts['month'])) {
165 $dateStr .= $parts['month'];
166
167 if (isset($parts['date'])) {
168 // If month and date are set, we need the separator dash.
169 $dateStr .= '-';
170 }
171 } elseif (isset($parts['date'])) {
172 // If the month is empty, and a date is set, we need a 'empty
173 // dash'
174 $dateStr .= '-';
175 }
176
177 // Date
178 if (!is_null($parts['date'])) {
179 $dateStr .= $parts['date'];
180 }
181
182 // Early exit if we don't have a time string.
183 if (is_null($parts['hour']) && is_null($parts['minute']) && is_null($parts['second'])) {
184 return [$dateStr];
185 }
186
187 $dateStr .= 'T';
188
189 // Hour
190 if (!is_null($parts['hour'])) {
191 $dateStr .= $parts['hour'];
192
193 if (!is_null($parts['minute'])) {
194 $dateStr .= ':';
195 }
196 } else {
197 // We know either minute or second _must_ be set, so we insert a
198 // dash for an empty value.
199 $dateStr .= '-';
200 }
201
202 // Minute
203 if (!is_null($parts['minute'])) {
204 $dateStr .= $parts['minute'];
205
206 if (!is_null($parts['second'])) {
207 $dateStr .= ':';
208 }
209 } elseif (isset($parts['second'])) {
210 // Dash for empty minute
211 $dateStr .= '-';
212 }
213
214 // Second
215 if (!is_null($parts['second'])) {
216 $dateStr .= $parts['second'];
217 }
218
219 // Timezone
220 if (!is_null($parts['timezone'])) {
221 $dateStr .= $parts['timezone'];
222 }
223
224 return [$dateStr];
225 }
226
227 /**
228 * This method serializes only the value of a property. This is used to
229 * create xCard or xCal documents.
230 *
231 * @param Xml\Writer $writer XML writer
232 */
233 protected function xmlSerializeValue(Xml\Writer $writer)
234 {
235 $valueType = strtolower($this->getValueType());
236 $parts = DateTimeParser::parseVCardDateAndOrTime($this->getValue());
237 $value = '';
238
239 // $d = defined
240 $d = function ($part) use ($parts) {
241 return !is_null($parts[$part]);
242 };
243
244 // $r = read
245 $r = function ($part) use ($parts) {
246 return $parts[$part];
247 };
248
249 // From the Relax NG Schema.
250 //
251 // # 4.3.1
252 // value-date = element date {
253 // xsd:string { pattern = "\d{8}|\d{4}-\d\d|--\d\d(\d\d)?|---\d\d" }
254 // }
255 if (($d('year') || $d('month') || $d('date'))
256 && (!$d('hour') && !$d('minute') && !$d('second') && !$d('timezone'))) {
257 if ($d('year') && $d('month') && $d('date')) {
258 $value .= $r('year').$r('month').$r('date');
259 } elseif ($d('year') && $d('month') && !$d('date')) {
260 $value .= $r('year').'-'.$r('month');
261 } elseif (!$d('year') && $d('month')) {
262 $value .= '--'.$r('month').$r('date');
263 } elseif (!$d('year') && !$d('month') && $d('date')) {
264 $value .= '---'.$r('date');
265 }
266
267 // # 4.3.2
268 // value-time = element time {
269 // xsd:string { pattern = "(\d\d(\d\d(\d\d)?)?|-\d\d(\d\d?)|--\d\d)"
270 // ~ "(Z|[+\-]\d\d(\d\d)?)?" }
271 // }
272 } elseif ((!$d('year') && !$d('month') && !$d('date'))
273 && ($d('hour') || $d('minute') || $d('second'))) {
274 if ($d('hour')) {
275 $value .= $r('hour').$r('minute').$r('second');
276 } elseif ($d('minute')) {
277 $value .= '-'.$r('minute').$r('second');
278 } elseif ($d('second')) {
279 $value .= '--'.$r('second');
280 }
281
282 $value .= $r('timezone');
283
284 // # 4.3.3
285 // value-date-time = element date-time {
286 // xsd:string { pattern = "(\d{8}|--\d{4}|---\d\d)T\d\d(\d\d(\d\d)?)?"
287 // ~ "(Z|[+\-]\d\d(\d\d)?)?" }
288 // }
289 } elseif ($d('date') && $d('hour')) {
290 if ($d('year') && $d('month') && $d('date')) {
291 $value .= $r('year').$r('month').$r('date');
292 } elseif (!$d('year') && $d('month') && $d('date')) {
293 $value .= '--'.$r('month').$r('date');
294 } elseif (!$d('year') && !$d('month') && $d('date')) {
295 $value .= '---'.$r('date');
296 }
297
298 $value .= 'T'.$r('hour').$r('minute').$r('second').
299 $r('timezone');
300 }
301
302 $writer->writeElement($valueType, $value);
303 }
304
305 /**
306 * Sets a raw value coming from a mimedir (iCalendar/vCard) file.
307 *
308 * This has been 'unfolded', so only 1 line will be passed. Unescaping is
309 * not yet done, but parameters are not included.
310 *
311 * @param string $val
312 */
313 public function setRawMimeDirValue($val)
314 {
315 $this->setValue($val);
316 }
317
318 /**
319 * Returns a raw mime-dir representation of the value.
320 *
321 * @return string
322 */
323 public function getRawMimeDirValue()
324 {
325 return implode($this->delimiter, $this->getParts());
326 }
327
328 /**
329 * Validates the node for correctness.
330 *
331 * The following options are supported:
332 * Node::REPAIR - May attempt to automatically repair the problem.
333 *
334 * This method returns an array with detected problems.
335 * Every element has the following properties:
336 *
337 * * level - problem level.
338 * * message - A human-readable string describing the issue.
339 * * node - A reference to the problematic node.
340 *
341 * The level means:
342 * 1 - The issue was repaired (only happens if REPAIR was turned on)
343 * 2 - An inconsequential issue
344 * 3 - A severe issue.
345 *
346 * @param int $options
347 *
348 * @return array
349 */
350 public function validate($options = 0)
351 {
352 $messages = parent::validate($options);
353 $value = $this->getValue();
354
355 try {
356 DateTimeParser::parseVCardDateTime($value);
357 } catch (InvalidDataException $e) {
358 $messages[] = [
359 'level' => 3,
360 'message' => 'The supplied value ('.$value.') is not a correct DATE-AND-OR-TIME property',
361 'node' => $this,
362 ];
363 }
364
365 return $messages;
366 }
367 }
368