Completed
Branch develop (804b52)
by
unknown
20:54
created
htdocs/includes/sabre/sabre/vobject/lib/Property/VCard/Date.php 1 patch
Indentation   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -13,24 +13,24 @@
 block discarded – undo
13 13
  */
14 14
 class Date extends DateAndOrTime
15 15
 {
16
-    /**
17
-     * Returns the type of value.
18
-     *
19
-     * This corresponds to the VALUE= parameter. Every property also has a
20
-     * 'default' valueType.
21
-     *
22
-     * @return string
23
-     */
24
-    public function getValueType()
25
-    {
26
-        return 'DATE';
27
-    }
16
+	/**
17
+	 * Returns the type of value.
18
+	 *
19
+	 * This corresponds to the VALUE= parameter. Every property also has a
20
+	 * 'default' valueType.
21
+	 *
22
+	 * @return string
23
+	 */
24
+	public function getValueType()
25
+	{
26
+		return 'DATE';
27
+	}
28 28
 
29
-    /**
30
-     * Sets the property as a DateTime object.
31
-     */
32
-    public function setDateTime(\DateTimeInterface $dt)
33
-    {
34
-        $this->value = $dt->format('Ymd');
35
-    }
29
+	/**
30
+	 * Sets the property as a DateTime object.
31
+	 */
32
+	public function setDateTime(\DateTimeInterface $dt)
33
+	{
34
+		$this->value = $dt->format('Ymd');
35
+	}
36 36
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/vobject/lib/Property/VCard/DateAndOrTime.php 1 patch
Indentation   +343 added lines, -343 removed lines patch added patch discarded remove patch
@@ -21,347 +21,347 @@
 block discarded – undo
21 21
  */
22 22
 class DateAndOrTime extends Property
23 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
-    }
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 367
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/vobject/lib/Property/VCard/PhoneNumber.php 1 patch
Indentation   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -13,18 +13,18 @@
 block discarded – undo
13 13
  */
14 14
 class PhoneNumber extends Property\Text
15 15
 {
16
-    protected $structuredValues = [];
16
+	protected $structuredValues = [];
17 17
 
18
-    /**
19
-     * Returns the type of value.
20
-     *
21
-     * This corresponds to the VALUE= parameter. Every property also has a
22
-     * 'default' valueType.
23
-     *
24
-     * @return string
25
-     */
26
-    public function getValueType()
27
-    {
28
-        return 'PHONE-NUMBER';
29
-    }
18
+	/**
19
+	 * Returns the type of value.
20
+	 *
21
+	 * This corresponds to the VALUE= parameter. Every property also has a
22
+	 * 'default' valueType.
23
+	 *
24
+	 * @return string
25
+	 */
26
+	public function getValueType()
27
+	{
28
+		return 'PHONE-NUMBER';
29
+	}
30 30
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/vobject/lib/Property/VCard/LanguageTag.php 1 patch
Indentation   +33 added lines, -33 removed lines patch added patch discarded remove patch
@@ -15,39 +15,39 @@
 block discarded – undo
15 15
  */
16 16
 class LanguageTag extends Property
17 17
 {
18
-    /**
19
-     * Sets a raw value coming from a mimedir (iCalendar/vCard) file.
20
-     *
21
-     * This has been 'unfolded', so only 1 line will be passed. Unescaping is
22
-     * not yet done, but parameters are not included.
23
-     *
24
-     * @param string $val
25
-     */
26
-    public function setRawMimeDirValue($val)
27
-    {
28
-        $this->setValue($val);
29
-    }
18
+	/**
19
+	 * Sets a raw value coming from a mimedir (iCalendar/vCard) file.
20
+	 *
21
+	 * This has been 'unfolded', so only 1 line will be passed. Unescaping is
22
+	 * not yet done, but parameters are not included.
23
+	 *
24
+	 * @param string $val
25
+	 */
26
+	public function setRawMimeDirValue($val)
27
+	{
28
+		$this->setValue($val);
29
+	}
30 30
 
31
-    /**
32
-     * Returns a raw mime-dir representation of the value.
33
-     *
34
-     * @return string
35
-     */
36
-    public function getRawMimeDirValue()
37
-    {
38
-        return $this->getValue();
39
-    }
31
+	/**
32
+	 * Returns a raw mime-dir representation of the value.
33
+	 *
34
+	 * @return string
35
+	 */
36
+	public function getRawMimeDirValue()
37
+	{
38
+		return $this->getValue();
39
+	}
40 40
 
41
-    /**
42
-     * Returns the type of value.
43
-     *
44
-     * This corresponds to the VALUE= parameter. Every property also has a
45
-     * 'default' valueType.
46
-     *
47
-     * @return string
48
-     */
49
-    public function getValueType()
50
-    {
51
-        return 'LANGUAGE-TAG';
52
-    }
41
+	/**
42
+	 * Returns the type of value.
43
+	 *
44
+	 * This corresponds to the VALUE= parameter. Every property also has a
45
+	 * 'default' valueType.
46
+	 *
47
+	 * @return string
48
+	 */
49
+	public function getValueType()
50
+	{
51
+		return 'LANGUAGE-TAG';
52
+	}
53 53
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/vobject/lib/Property/VCard/DateTime.php 1 patch
Indentation   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -13,16 +13,16 @@
 block discarded – undo
13 13
  */
14 14
 class DateTime extends DateAndOrTime
15 15
 {
16
-    /**
17
-     * Returns the type of value.
18
-     *
19
-     * This corresponds to the VALUE= parameter. Every property also has a
20
-     * 'default' valueType.
21
-     *
22
-     * @return string
23
-     */
24
-    public function getValueType()
25
-    {
26
-        return 'DATE-TIME';
27
-    }
16
+	/**
17
+	 * Returns the type of value.
18
+	 *
19
+	 * This corresponds to the VALUE= parameter. Every property also has a
20
+	 * 'default' valueType.
21
+	 *
22
+	 * @return string
23
+	 */
24
+	public function getValueType()
25
+	{
26
+		return 'DATE-TIME';
27
+	}
28 28
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/vobject/lib/Property/FlatText.php 1 patch
Indentation   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -24,23 +24,23 @@
 block discarded – undo
24 24
  */
25 25
 class FlatText extends Text
26 26
 {
27
-    /**
28
-     * Field separator.
29
-     *
30
-     * @var string
31
-     */
32
-    public $delimiter = ',';
27
+	/**
28
+	 * Field separator.
29
+	 *
30
+	 * @var string
31
+	 */
32
+	public $delimiter = ',';
33 33
 
34
-    /**
35
-     * Sets the value as a quoted-printable encoded string.
36
-     *
37
-     * Overriding this so we're not splitting on a ; delimiter.
38
-     *
39
-     * @param string $val
40
-     */
41
-    public function setQuotedPrintableValue($val)
42
-    {
43
-        $val = quoted_printable_decode($val);
44
-        $this->setValue($val);
45
-    }
34
+	/**
35
+	 * Sets the value as a quoted-printable encoded string.
36
+	 *
37
+	 * Overriding this so we're not splitting on a ; delimiter.
38
+	 *
39
+	 * @param string $val
40
+	 */
41
+	public function setQuotedPrintableValue($val)
42
+	{
43
+		$val = quoted_printable_decode($val);
44
+		$this->setValue($val);
45
+	}
46 46
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/vobject/lib/Property/FloatValue.php 1 patch
Indentation   +95 added lines, -95 removed lines patch added patch discarded remove patch
@@ -17,108 +17,108 @@
 block discarded – undo
17 17
  */
18 18
 class FloatValue extends Property
19 19
 {
20
-    /**
21
-     * In case this is a multi-value property. This string will be used as a
22
-     * delimiter.
23
-     *
24
-     * @var string
25
-     */
26
-    public $delimiter = ';';
20
+	/**
21
+	 * In case this is a multi-value property. This string will be used as a
22
+	 * delimiter.
23
+	 *
24
+	 * @var string
25
+	 */
26
+	public $delimiter = ';';
27 27
 
28
-    /**
29
-     * Sets a raw value coming from a mimedir (iCalendar/vCard) file.
30
-     *
31
-     * This has been 'unfolded', so only 1 line will be passed. Unescaping is
32
-     * not yet done, but parameters are not included.
33
-     *
34
-     * @param string $val
35
-     */
36
-    public function setRawMimeDirValue($val)
37
-    {
38
-        $val = explode($this->delimiter, $val);
39
-        foreach ($val as &$item) {
40
-            $item = (float) $item;
41
-        }
42
-        $this->setParts($val);
43
-    }
28
+	/**
29
+	 * Sets a raw value coming from a mimedir (iCalendar/vCard) file.
30
+	 *
31
+	 * This has been 'unfolded', so only 1 line will be passed. Unescaping is
32
+	 * not yet done, but parameters are not included.
33
+	 *
34
+	 * @param string $val
35
+	 */
36
+	public function setRawMimeDirValue($val)
37
+	{
38
+		$val = explode($this->delimiter, $val);
39
+		foreach ($val as &$item) {
40
+			$item = (float) $item;
41
+		}
42
+		$this->setParts($val);
43
+	}
44 44
 
45
-    /**
46
-     * Returns a raw mime-dir representation of the value.
47
-     *
48
-     * @return string
49
-     */
50
-    public function getRawMimeDirValue()
51
-    {
52
-        return implode(
53
-            $this->delimiter,
54
-            $this->getParts()
55
-        );
56
-    }
45
+	/**
46
+	 * Returns a raw mime-dir representation of the value.
47
+	 *
48
+	 * @return string
49
+	 */
50
+	public function getRawMimeDirValue()
51
+	{
52
+		return implode(
53
+			$this->delimiter,
54
+			$this->getParts()
55
+		);
56
+	}
57 57
 
58
-    /**
59
-     * Returns the type of value.
60
-     *
61
-     * This corresponds to the VALUE= parameter. Every property also has a
62
-     * 'default' valueType.
63
-     *
64
-     * @return string
65
-     */
66
-    public function getValueType()
67
-    {
68
-        return 'FLOAT';
69
-    }
58
+	/**
59
+	 * Returns the type of value.
60
+	 *
61
+	 * This corresponds to the VALUE= parameter. Every property also has a
62
+	 * 'default' valueType.
63
+	 *
64
+	 * @return string
65
+	 */
66
+	public function getValueType()
67
+	{
68
+		return 'FLOAT';
69
+	}
70 70
 
71
-    /**
72
-     * Returns the value, in the format it should be encoded for JSON.
73
-     *
74
-     * This method must always return an array.
75
-     *
76
-     * @return array
77
-     */
78
-    public function getJsonValue()
79
-    {
80
-        $val = array_map('floatval', $this->getParts());
71
+	/**
72
+	 * Returns the value, in the format it should be encoded for JSON.
73
+	 *
74
+	 * This method must always return an array.
75
+	 *
76
+	 * @return array
77
+	 */
78
+	public function getJsonValue()
79
+	{
80
+		$val = array_map('floatval', $this->getParts());
81 81
 
82
-        // Special-casing the GEO property.
83
-        //
84
-        // See:
85
-        // http://tools.ietf.org/html/draft-ietf-jcardcal-jcal-04#section-3.4.1.2
86
-        if ('GEO' === $this->name) {
87
-            return [$val];
88
-        }
82
+		// Special-casing the GEO property.
83
+		//
84
+		// See:
85
+		// http://tools.ietf.org/html/draft-ietf-jcardcal-jcal-04#section-3.4.1.2
86
+		if ('GEO' === $this->name) {
87
+			return [$val];
88
+		}
89 89
 
90
-        return $val;
91
-    }
90
+		return $val;
91
+	}
92 92
 
93
-    /**
94
-     * Hydrate data from a XML subtree, as it would appear in a xCard or xCal
95
-     * object.
96
-     */
97
-    public function setXmlValue(array $value)
98
-    {
99
-        $value = array_map('floatval', $value);
100
-        parent::setXmlValue($value);
101
-    }
93
+	/**
94
+	 * Hydrate data from a XML subtree, as it would appear in a xCard or xCal
95
+	 * object.
96
+	 */
97
+	public function setXmlValue(array $value)
98
+	{
99
+		$value = array_map('floatval', $value);
100
+		parent::setXmlValue($value);
101
+	}
102 102
 
103
-    /**
104
-     * This method serializes only the value of a property. This is used to
105
-     * create xCard or xCal documents.
106
-     *
107
-     * @param Xml\Writer $writer XML writer
108
-     */
109
-    protected function xmlSerializeValue(Xml\Writer $writer)
110
-    {
111
-        // Special-casing the GEO property.
112
-        //
113
-        // See:
114
-        // http://tools.ietf.org/html/rfc6321#section-3.4.1.2
115
-        if ('GEO' === $this->name) {
116
-            $value = array_map('floatval', $this->getParts());
103
+	/**
104
+	 * This method serializes only the value of a property. This is used to
105
+	 * create xCard or xCal documents.
106
+	 *
107
+	 * @param Xml\Writer $writer XML writer
108
+	 */
109
+	protected function xmlSerializeValue(Xml\Writer $writer)
110
+	{
111
+		// Special-casing the GEO property.
112
+		//
113
+		// See:
114
+		// http://tools.ietf.org/html/rfc6321#section-3.4.1.2
115
+		if ('GEO' === $this->name) {
116
+			$value = array_map('floatval', $this->getParts());
117 117
 
118
-            $writer->writeElement('latitude', $value[0]);
119
-            $writer->writeElement('longitude', $value[1]);
120
-        } else {
121
-            parent::xmlSerializeValue($writer);
122
-        }
123
-    }
118
+			$writer->writeElement('latitude', $value[0]);
119
+			$writer->writeElement('longitude', $value[1]);
120
+		} else {
121
+			parent::xmlSerializeValue($writer);
122
+		}
123
+	}
124 124
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/vobject/lib/Parser/XML.php 1 patch
Indentation   +354 added lines, -354 removed lines patch added patch discarded remove patch
@@ -20,358 +20,358 @@
 block discarded – undo
20 20
  */
21 21
 class XML extends Parser
22 22
 {
23
-    const XCAL_NAMESPACE = 'urn:ietf:params:xml:ns:icalendar-2.0';
24
-    const XCARD_NAMESPACE = 'urn:ietf:params:xml:ns:vcard-4.0';
25
-
26
-    /**
27
-     * The input data.
28
-     *
29
-     * @var array
30
-     */
31
-    protected $input;
32
-
33
-    /**
34
-     * A pointer/reference to the input.
35
-     *
36
-     * @var array
37
-     */
38
-    private $pointer;
39
-
40
-    /**
41
-     * Document, root component.
42
-     *
43
-     * @var \Sabre\VObject\Document
44
-     */
45
-    protected $root;
46
-
47
-    /**
48
-     * Creates the parser.
49
-     *
50
-     * Optionally, it's possible to parse the input stream here.
51
-     *
52
-     * @param mixed $input
53
-     * @param int   $options any parser options (OPTION constants)
54
-     */
55
-    public function __construct($input = null, $options = 0)
56
-    {
57
-        if (0 === $options) {
58
-            $options = parent::OPTION_FORGIVING;
59
-        }
60
-
61
-        parent::__construct($input, $options);
62
-    }
63
-
64
-    /**
65
-     * Parse xCal or xCard.
66
-     *
67
-     * @param resource|string $input
68
-     * @param int             $options
69
-     *
70
-     * @throws \Exception
71
-     *
72
-     * @return \Sabre\VObject\Document
73
-     */
74
-    public function parse($input = null, $options = 0)
75
-    {
76
-        if (!is_null($input)) {
77
-            $this->setInput($input);
78
-        }
79
-
80
-        if (0 !== $options) {
81
-            $this->options = $options;
82
-        }
83
-
84
-        if (is_null($this->input)) {
85
-            throw new EofException('End of input stream, or no input supplied');
86
-        }
87
-
88
-        switch ($this->input['name']) {
89
-            case '{'.self::XCAL_NAMESPACE.'}icalendar':
90
-                $this->root = new VCalendar([], false);
91
-                $this->pointer = &$this->input['value'][0];
92
-                $this->parseVCalendarComponents($this->root);
93
-                break;
94
-
95
-            case '{'.self::XCARD_NAMESPACE.'}vcards':
96
-                foreach ($this->input['value'] as &$vCard) {
97
-                    $this->root = new VCard(['version' => '4.0'], false);
98
-                    $this->pointer = &$vCard;
99
-                    $this->parseVCardComponents($this->root);
100
-
101
-                    // We just parse the first <vcard /> element.
102
-                    break;
103
-                }
104
-                break;
105
-
106
-            default:
107
-                throw new ParseException('Unsupported XML standard');
108
-        }
109
-
110
-        return $this->root;
111
-    }
112
-
113
-    /**
114
-     * Parse a xCalendar component.
115
-     */
116
-    protected function parseVCalendarComponents(Component $parentComponent)
117
-    {
118
-        foreach ($this->pointer['value'] ?: [] as $children) {
119
-            switch (static::getTagName($children['name'])) {
120
-                case 'properties':
121
-                    $this->pointer = &$children['value'];
122
-                    $this->parseProperties($parentComponent);
123
-                    break;
124
-
125
-                case 'components':
126
-                    $this->pointer = &$children;
127
-                    $this->parseComponent($parentComponent);
128
-                    break;
129
-            }
130
-        }
131
-    }
132
-
133
-    /**
134
-     * Parse a xCard component.
135
-     */
136
-    protected function parseVCardComponents(Component $parentComponent)
137
-    {
138
-        $this->pointer = &$this->pointer['value'];
139
-        $this->parseProperties($parentComponent);
140
-    }
141
-
142
-    /**
143
-     * Parse xCalendar and xCard properties.
144
-     *
145
-     * @param string $propertyNamePrefix
146
-     */
147
-    protected function parseProperties(Component $parentComponent, $propertyNamePrefix = '')
148
-    {
149
-        foreach ($this->pointer ?: [] as $xmlProperty) {
150
-            list($namespace, $tagName) = SabreXml\Service::parseClarkNotation($xmlProperty['name']);
151
-
152
-            $propertyName = $tagName;
153
-            $propertyValue = [];
154
-            $propertyParameters = [];
155
-            $propertyType = 'text';
156
-
157
-            // A property which is not part of the standard.
158
-            if (self::XCAL_NAMESPACE !== $namespace
159
-                && self::XCARD_NAMESPACE !== $namespace) {
160
-                $propertyName = 'xml';
161
-                $value = '<'.$tagName.' xmlns="'.$namespace.'"';
162
-
163
-                foreach ($xmlProperty['attributes'] as $attributeName => $attributeValue) {
164
-                    $value .= ' '.$attributeName.'="'.str_replace('"', '\"', $attributeValue).'"';
165
-                }
166
-
167
-                $value .= '>'.$xmlProperty['value'].'</'.$tagName.'>';
168
-
169
-                $propertyValue = [$value];
170
-
171
-                $this->createProperty(
172
-                    $parentComponent,
173
-                    $propertyName,
174
-                    $propertyParameters,
175
-                    $propertyType,
176
-                    $propertyValue
177
-                );
178
-
179
-                continue;
180
-            }
181
-
182
-            // xCard group.
183
-            if ('group' === $propertyName) {
184
-                if (!isset($xmlProperty['attributes']['name'])) {
185
-                    continue;
186
-                }
187
-
188
-                $this->pointer = &$xmlProperty['value'];
189
-                $this->parseProperties(
190
-                    $parentComponent,
191
-                    strtoupper($xmlProperty['attributes']['name']).'.'
192
-                );
193
-
194
-                continue;
195
-            }
196
-
197
-            // Collect parameters.
198
-            foreach ($xmlProperty['value'] as $i => $xmlPropertyChild) {
199
-                if (!is_array($xmlPropertyChild)
200
-                    || 'parameters' !== static::getTagName($xmlPropertyChild['name'])) {
201
-                    continue;
202
-                }
203
-
204
-                $xmlParameters = $xmlPropertyChild['value'];
205
-
206
-                foreach ($xmlParameters as $xmlParameter) {
207
-                    $propertyParameterValues = [];
208
-
209
-                    foreach ($xmlParameter['value'] as $xmlParameterValues) {
210
-                        $propertyParameterValues[] = $xmlParameterValues['value'];
211
-                    }
212
-
213
-                    $propertyParameters[static::getTagName($xmlParameter['name'])]
214
-                        = implode(',', $propertyParameterValues);
215
-                }
216
-
217
-                array_splice($xmlProperty['value'], $i, 1);
218
-            }
219
-
220
-            $propertyNameExtended = ($this->root instanceof VCalendar
221
-                                      ? 'xcal'
222
-                                      : 'xcard').':'.$propertyName;
223
-
224
-            switch ($propertyNameExtended) {
225
-                case 'xcal:geo':
226
-                    $propertyType = 'float';
227
-                    $propertyValue['latitude'] = 0;
228
-                    $propertyValue['longitude'] = 0;
229
-
230
-                    foreach ($xmlProperty['value'] as $xmlRequestChild) {
231
-                        $propertyValue[static::getTagName($xmlRequestChild['name'])]
232
-                            = $xmlRequestChild['value'];
233
-                    }
234
-                    break;
235
-
236
-                case 'xcal:request-status':
237
-                    $propertyType = 'text';
238
-
239
-                    foreach ($xmlProperty['value'] as $xmlRequestChild) {
240
-                        $propertyValue[static::getTagName($xmlRequestChild['name'])]
241
-                            = $xmlRequestChild['value'];
242
-                    }
243
-                    break;
244
-
245
-                case 'xcal:freebusy':
246
-                    $propertyType = 'freebusy';
247
-                    // We don't break because we only want to set
248
-                    // another property type.
249
-
250
-                    // no break
251
-                case 'xcal:categories':
252
-                case 'xcal:resources':
253
-                case 'xcal:exdate':
254
-                    foreach ($xmlProperty['value'] as $specialChild) {
255
-                        $propertyValue[static::getTagName($specialChild['name'])]
256
-                            = $specialChild['value'];
257
-                    }
258
-                    break;
259
-
260
-                case 'xcal:rdate':
261
-                    $propertyType = 'date-time';
262
-
263
-                    foreach ($xmlProperty['value'] as $specialChild) {
264
-                        $tagName = static::getTagName($specialChild['name']);
265
-
266
-                        if ('period' === $tagName) {
267
-                            $propertyParameters['value'] = 'PERIOD';
268
-                            $propertyValue[] = implode('/', $specialChild['value']);
269
-                        } else {
270
-                            $propertyValue[] = $specialChild['value'];
271
-                        }
272
-                    }
273
-                    break;
274
-
275
-                default:
276
-                    $propertyType = static::getTagName($xmlProperty['value'][0]['name']);
277
-
278
-                    foreach ($xmlProperty['value'] as $value) {
279
-                        $propertyValue[] = $value['value'];
280
-                    }
281
-
282
-                    if ('date' === $propertyType) {
283
-                        $propertyParameters['value'] = 'DATE';
284
-                    }
285
-                    break;
286
-            }
287
-
288
-            $this->createProperty(
289
-                $parentComponent,
290
-                $propertyNamePrefix.$propertyName,
291
-                $propertyParameters,
292
-                $propertyType,
293
-                $propertyValue
294
-            );
295
-        }
296
-    }
297
-
298
-    /**
299
-     * Parse a component.
300
-     */
301
-    protected function parseComponent(Component $parentComponent)
302
-    {
303
-        $components = $this->pointer['value'] ?: [];
304
-
305
-        foreach ($components as $component) {
306
-            $componentName = static::getTagName($component['name']);
307
-            $currentComponent = $this->root->createComponent(
308
-                $componentName,
309
-                null,
310
-                false
311
-            );
312
-
313
-            $this->pointer = &$component;
314
-            $this->parseVCalendarComponents($currentComponent);
315
-
316
-            $parentComponent->add($currentComponent);
317
-        }
318
-    }
319
-
320
-    /**
321
-     * Create a property.
322
-     *
323
-     * @param string $name
324
-     * @param array  $parameters
325
-     * @param string $type
326
-     * @param mixed  $value
327
-     */
328
-    protected function createProperty(Component $parentComponent, $name, $parameters, $type, $value)
329
-    {
330
-        $property = $this->root->createProperty(
331
-            $name,
332
-            null,
333
-            $parameters,
334
-            $type
335
-        );
336
-        $parentComponent->add($property);
337
-        $property->setXmlValue($value);
338
-    }
339
-
340
-    /**
341
-     * Sets the input data.
342
-     *
343
-     * @param resource|string $input
344
-     */
345
-    public function setInput($input)
346
-    {
347
-        if (is_resource($input)) {
348
-            $input = stream_get_contents($input);
349
-        }
350
-
351
-        if (is_string($input)) {
352
-            $reader = new SabreXml\Reader();
353
-            $reader->elementMap['{'.self::XCAL_NAMESPACE.'}period']
354
-                = XML\Element\KeyValue::class;
355
-            $reader->elementMap['{'.self::XCAL_NAMESPACE.'}recur']
356
-                = XML\Element\KeyValue::class;
357
-            $reader->xml($input);
358
-            $input = $reader->parse();
359
-        }
360
-
361
-        $this->input = $input;
362
-    }
363
-
364
-    /**
365
-     * Get tag name from a Clark notation.
366
-     *
367
-     * @param string $clarkedTagName
368
-     *
369
-     * @return string
370
-     */
371
-    protected static function getTagName($clarkedTagName)
372
-    {
373
-        list(, $tagName) = SabreXml\Service::parseClarkNotation($clarkedTagName);
374
-
375
-        return $tagName;
376
-    }
23
+	const XCAL_NAMESPACE = 'urn:ietf:params:xml:ns:icalendar-2.0';
24
+	const XCARD_NAMESPACE = 'urn:ietf:params:xml:ns:vcard-4.0';
25
+
26
+	/**
27
+	 * The input data.
28
+	 *
29
+	 * @var array
30
+	 */
31
+	protected $input;
32
+
33
+	/**
34
+	 * A pointer/reference to the input.
35
+	 *
36
+	 * @var array
37
+	 */
38
+	private $pointer;
39
+
40
+	/**
41
+	 * Document, root component.
42
+	 *
43
+	 * @var \Sabre\VObject\Document
44
+	 */
45
+	protected $root;
46
+
47
+	/**
48
+	 * Creates the parser.
49
+	 *
50
+	 * Optionally, it's possible to parse the input stream here.
51
+	 *
52
+	 * @param mixed $input
53
+	 * @param int   $options any parser options (OPTION constants)
54
+	 */
55
+	public function __construct($input = null, $options = 0)
56
+	{
57
+		if (0 === $options) {
58
+			$options = parent::OPTION_FORGIVING;
59
+		}
60
+
61
+		parent::__construct($input, $options);
62
+	}
63
+
64
+	/**
65
+	 * Parse xCal or xCard.
66
+	 *
67
+	 * @param resource|string $input
68
+	 * @param int             $options
69
+	 *
70
+	 * @throws \Exception
71
+	 *
72
+	 * @return \Sabre\VObject\Document
73
+	 */
74
+	public function parse($input = null, $options = 0)
75
+	{
76
+		if (!is_null($input)) {
77
+			$this->setInput($input);
78
+		}
79
+
80
+		if (0 !== $options) {
81
+			$this->options = $options;
82
+		}
83
+
84
+		if (is_null($this->input)) {
85
+			throw new EofException('End of input stream, or no input supplied');
86
+		}
87
+
88
+		switch ($this->input['name']) {
89
+			case '{'.self::XCAL_NAMESPACE.'}icalendar':
90
+				$this->root = new VCalendar([], false);
91
+				$this->pointer = &$this->input['value'][0];
92
+				$this->parseVCalendarComponents($this->root);
93
+				break;
94
+
95
+			case '{'.self::XCARD_NAMESPACE.'}vcards':
96
+				foreach ($this->input['value'] as &$vCard) {
97
+					$this->root = new VCard(['version' => '4.0'], false);
98
+					$this->pointer = &$vCard;
99
+					$this->parseVCardComponents($this->root);
100
+
101
+					// We just parse the first <vcard /> element.
102
+					break;
103
+				}
104
+				break;
105
+
106
+			default:
107
+				throw new ParseException('Unsupported XML standard');
108
+		}
109
+
110
+		return $this->root;
111
+	}
112
+
113
+	/**
114
+	 * Parse a xCalendar component.
115
+	 */
116
+	protected function parseVCalendarComponents(Component $parentComponent)
117
+	{
118
+		foreach ($this->pointer['value'] ?: [] as $children) {
119
+			switch (static::getTagName($children['name'])) {
120
+				case 'properties':
121
+					$this->pointer = &$children['value'];
122
+					$this->parseProperties($parentComponent);
123
+					break;
124
+
125
+				case 'components':
126
+					$this->pointer = &$children;
127
+					$this->parseComponent($parentComponent);
128
+					break;
129
+			}
130
+		}
131
+	}
132
+
133
+	/**
134
+	 * Parse a xCard component.
135
+	 */
136
+	protected function parseVCardComponents(Component $parentComponent)
137
+	{
138
+		$this->pointer = &$this->pointer['value'];
139
+		$this->parseProperties($parentComponent);
140
+	}
141
+
142
+	/**
143
+	 * Parse xCalendar and xCard properties.
144
+	 *
145
+	 * @param string $propertyNamePrefix
146
+	 */
147
+	protected function parseProperties(Component $parentComponent, $propertyNamePrefix = '')
148
+	{
149
+		foreach ($this->pointer ?: [] as $xmlProperty) {
150
+			list($namespace, $tagName) = SabreXml\Service::parseClarkNotation($xmlProperty['name']);
151
+
152
+			$propertyName = $tagName;
153
+			$propertyValue = [];
154
+			$propertyParameters = [];
155
+			$propertyType = 'text';
156
+
157
+			// A property which is not part of the standard.
158
+			if (self::XCAL_NAMESPACE !== $namespace
159
+				&& self::XCARD_NAMESPACE !== $namespace) {
160
+				$propertyName = 'xml';
161
+				$value = '<'.$tagName.' xmlns="'.$namespace.'"';
162
+
163
+				foreach ($xmlProperty['attributes'] as $attributeName => $attributeValue) {
164
+					$value .= ' '.$attributeName.'="'.str_replace('"', '\"', $attributeValue).'"';
165
+				}
166
+
167
+				$value .= '>'.$xmlProperty['value'].'</'.$tagName.'>';
168
+
169
+				$propertyValue = [$value];
170
+
171
+				$this->createProperty(
172
+					$parentComponent,
173
+					$propertyName,
174
+					$propertyParameters,
175
+					$propertyType,
176
+					$propertyValue
177
+				);
178
+
179
+				continue;
180
+			}
181
+
182
+			// xCard group.
183
+			if ('group' === $propertyName) {
184
+				if (!isset($xmlProperty['attributes']['name'])) {
185
+					continue;
186
+				}
187
+
188
+				$this->pointer = &$xmlProperty['value'];
189
+				$this->parseProperties(
190
+					$parentComponent,
191
+					strtoupper($xmlProperty['attributes']['name']).'.'
192
+				);
193
+
194
+				continue;
195
+			}
196
+
197
+			// Collect parameters.
198
+			foreach ($xmlProperty['value'] as $i => $xmlPropertyChild) {
199
+				if (!is_array($xmlPropertyChild)
200
+					|| 'parameters' !== static::getTagName($xmlPropertyChild['name'])) {
201
+					continue;
202
+				}
203
+
204
+				$xmlParameters = $xmlPropertyChild['value'];
205
+
206
+				foreach ($xmlParameters as $xmlParameter) {
207
+					$propertyParameterValues = [];
208
+
209
+					foreach ($xmlParameter['value'] as $xmlParameterValues) {
210
+						$propertyParameterValues[] = $xmlParameterValues['value'];
211
+					}
212
+
213
+					$propertyParameters[static::getTagName($xmlParameter['name'])]
214
+						= implode(',', $propertyParameterValues);
215
+				}
216
+
217
+				array_splice($xmlProperty['value'], $i, 1);
218
+			}
219
+
220
+			$propertyNameExtended = ($this->root instanceof VCalendar
221
+									  ? 'xcal'
222
+									  : 'xcard').':'.$propertyName;
223
+
224
+			switch ($propertyNameExtended) {
225
+				case 'xcal:geo':
226
+					$propertyType = 'float';
227
+					$propertyValue['latitude'] = 0;
228
+					$propertyValue['longitude'] = 0;
229
+
230
+					foreach ($xmlProperty['value'] as $xmlRequestChild) {
231
+						$propertyValue[static::getTagName($xmlRequestChild['name'])]
232
+							= $xmlRequestChild['value'];
233
+					}
234
+					break;
235
+
236
+				case 'xcal:request-status':
237
+					$propertyType = 'text';
238
+
239
+					foreach ($xmlProperty['value'] as $xmlRequestChild) {
240
+						$propertyValue[static::getTagName($xmlRequestChild['name'])]
241
+							= $xmlRequestChild['value'];
242
+					}
243
+					break;
244
+
245
+				case 'xcal:freebusy':
246
+					$propertyType = 'freebusy';
247
+					// We don't break because we only want to set
248
+					// another property type.
249
+
250
+					// no break
251
+				case 'xcal:categories':
252
+				case 'xcal:resources':
253
+				case 'xcal:exdate':
254
+					foreach ($xmlProperty['value'] as $specialChild) {
255
+						$propertyValue[static::getTagName($specialChild['name'])]
256
+							= $specialChild['value'];
257
+					}
258
+					break;
259
+
260
+				case 'xcal:rdate':
261
+					$propertyType = 'date-time';
262
+
263
+					foreach ($xmlProperty['value'] as $specialChild) {
264
+						$tagName = static::getTagName($specialChild['name']);
265
+
266
+						if ('period' === $tagName) {
267
+							$propertyParameters['value'] = 'PERIOD';
268
+							$propertyValue[] = implode('/', $specialChild['value']);
269
+						} else {
270
+							$propertyValue[] = $specialChild['value'];
271
+						}
272
+					}
273
+					break;
274
+
275
+				default:
276
+					$propertyType = static::getTagName($xmlProperty['value'][0]['name']);
277
+
278
+					foreach ($xmlProperty['value'] as $value) {
279
+						$propertyValue[] = $value['value'];
280
+					}
281
+
282
+					if ('date' === $propertyType) {
283
+						$propertyParameters['value'] = 'DATE';
284
+					}
285
+					break;
286
+			}
287
+
288
+			$this->createProperty(
289
+				$parentComponent,
290
+				$propertyNamePrefix.$propertyName,
291
+				$propertyParameters,
292
+				$propertyType,
293
+				$propertyValue
294
+			);
295
+		}
296
+	}
297
+
298
+	/**
299
+	 * Parse a component.
300
+	 */
301
+	protected function parseComponent(Component $parentComponent)
302
+	{
303
+		$components = $this->pointer['value'] ?: [];
304
+
305
+		foreach ($components as $component) {
306
+			$componentName = static::getTagName($component['name']);
307
+			$currentComponent = $this->root->createComponent(
308
+				$componentName,
309
+				null,
310
+				false
311
+			);
312
+
313
+			$this->pointer = &$component;
314
+			$this->parseVCalendarComponents($currentComponent);
315
+
316
+			$parentComponent->add($currentComponent);
317
+		}
318
+	}
319
+
320
+	/**
321
+	 * Create a property.
322
+	 *
323
+	 * @param string $name
324
+	 * @param array  $parameters
325
+	 * @param string $type
326
+	 * @param mixed  $value
327
+	 */
328
+	protected function createProperty(Component $parentComponent, $name, $parameters, $type, $value)
329
+	{
330
+		$property = $this->root->createProperty(
331
+			$name,
332
+			null,
333
+			$parameters,
334
+			$type
335
+		);
336
+		$parentComponent->add($property);
337
+		$property->setXmlValue($value);
338
+	}
339
+
340
+	/**
341
+	 * Sets the input data.
342
+	 *
343
+	 * @param resource|string $input
344
+	 */
345
+	public function setInput($input)
346
+	{
347
+		if (is_resource($input)) {
348
+			$input = stream_get_contents($input);
349
+		}
350
+
351
+		if (is_string($input)) {
352
+			$reader = new SabreXml\Reader();
353
+			$reader->elementMap['{'.self::XCAL_NAMESPACE.'}period']
354
+				= XML\Element\KeyValue::class;
355
+			$reader->elementMap['{'.self::XCAL_NAMESPACE.'}recur']
356
+				= XML\Element\KeyValue::class;
357
+			$reader->xml($input);
358
+			$input = $reader->parse();
359
+		}
360
+
361
+		$this->input = $input;
362
+	}
363
+
364
+	/**
365
+	 * Get tag name from a Clark notation.
366
+	 *
367
+	 * @param string $clarkedTagName
368
+	 *
369
+	 * @return string
370
+	 */
371
+	protected static function getTagName($clarkedTagName)
372
+	{
373
+		list(, $tagName) = SabreXml\Service::parseClarkNotation($clarkedTagName);
374
+
375
+		return $tagName;
376
+	}
377 377
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/vobject/lib/Parser/Json.php 1 patch
Indentation   +166 added lines, -166 removed lines patch added patch discarded remove patch
@@ -21,170 +21,170 @@
 block discarded – undo
21 21
  */
22 22
 class Json extends Parser
23 23
 {
24
-    /**
25
-     * The input data.
26
-     *
27
-     * @var array
28
-     */
29
-    protected $input;
30
-
31
-    /**
32
-     * Root component.
33
-     *
34
-     * @var Document
35
-     */
36
-    protected $root;
37
-
38
-    /**
39
-     * This method starts the parsing process.
40
-     *
41
-     * If the input was not supplied during construction, it's possible to pass
42
-     * it here instead.
43
-     *
44
-     * If either input or options are not supplied, the defaults will be used.
45
-     *
46
-     * @param resource|string|array|null $input
47
-     * @param int                        $options
48
-     *
49
-     * @return \Sabre\VObject\Document
50
-     */
51
-    public function parse($input = null, $options = 0)
52
-    {
53
-        if (!is_null($input)) {
54
-            $this->setInput($input);
55
-        }
56
-        if (is_null($this->input)) {
57
-            throw new EofException('End of input stream, or no input supplied');
58
-        }
59
-
60
-        if (0 !== $options) {
61
-            $this->options = $options;
62
-        }
63
-
64
-        switch ($this->input[0]) {
65
-            case 'vcalendar':
66
-                $this->root = new VCalendar([], false);
67
-                break;
68
-            case 'vcard':
69
-                $this->root = new VCard([], false);
70
-                break;
71
-            default:
72
-                throw new ParseException('The root component must either be a vcalendar, or a vcard');
73
-        }
74
-        foreach ($this->input[1] as $prop) {
75
-            $this->root->add($this->parseProperty($prop));
76
-        }
77
-        if (isset($this->input[2])) {
78
-            foreach ($this->input[2] as $comp) {
79
-                $this->root->add($this->parseComponent($comp));
80
-            }
81
-        }
82
-
83
-        // Resetting the input so we can throw an feof exception the next time.
84
-        $this->input = null;
85
-
86
-        return $this->root;
87
-    }
88
-
89
-    /**
90
-     * Parses a component.
91
-     *
92
-     * @return \Sabre\VObject\Component
93
-     */
94
-    public function parseComponent(array $jComp)
95
-    {
96
-        // We can remove $self from PHP 5.4 onward.
97
-        $self = $this;
98
-
99
-        $properties = array_map(
100
-            function ($jProp) use ($self) {
101
-                return $self->parseProperty($jProp);
102
-            },
103
-            $jComp[1]
104
-        );
105
-
106
-        if (isset($jComp[2])) {
107
-            $components = array_map(
108
-                function ($jComp) use ($self) {
109
-                    return $self->parseComponent($jComp);
110
-                },
111
-                $jComp[2]
112
-            );
113
-        } else {
114
-            $components = [];
115
-        }
116
-
117
-        return $this->root->createComponent(
118
-            $jComp[0],
119
-            array_merge($properties, $components),
120
-            $defaults = false
121
-        );
122
-    }
123
-
124
-    /**
125
-     * Parses properties.
126
-     *
127
-     * @return \Sabre\VObject\Property
128
-     */
129
-    public function parseProperty(array $jProp)
130
-    {
131
-        list(
132
-            $propertyName,
133
-            $parameters,
134
-            $valueType
135
-        ) = $jProp;
136
-
137
-        $propertyName = strtoupper($propertyName);
138
-
139
-        // This is the default class we would be using if we didn't know the
140
-        // value type. We're using this value later in this function.
141
-        $defaultPropertyClass = $this->root->getClassNameForPropertyName($propertyName);
142
-
143
-        $parameters = (array) $parameters;
144
-
145
-        $value = array_slice($jProp, 3);
146
-
147
-        $valueType = strtoupper($valueType);
148
-
149
-        if (isset($parameters['group'])) {
150
-            $propertyName = $parameters['group'].'.'.$propertyName;
151
-            unset($parameters['group']);
152
-        }
153
-
154
-        $prop = $this->root->createProperty($propertyName, null, $parameters, $valueType);
155
-        $prop->setJsonValue($value);
156
-
157
-        // We have to do something awkward here. FlatText as well as Text
158
-        // represents TEXT values. We have to normalize these here. In the
159
-        // future we can get rid of FlatText once we're allowed to break BC
160
-        // again.
161
-        if (FlatText::class === $defaultPropertyClass) {
162
-            $defaultPropertyClass = Text::class;
163
-        }
164
-
165
-        // If the value type we received (e.g.: TEXT) was not the default value
166
-        // type for the given property (e.g.: BDAY), we need to add a VALUE=
167
-        // parameter.
168
-        if ($defaultPropertyClass !== get_class($prop)) {
169
-            $prop['VALUE'] = $valueType;
170
-        }
171
-
172
-        return $prop;
173
-    }
174
-
175
-    /**
176
-     * Sets the input data.
177
-     *
178
-     * @param resource|string|array $input
179
-     */
180
-    public function setInput($input)
181
-    {
182
-        if (is_resource($input)) {
183
-            $input = stream_get_contents($input);
184
-        }
185
-        if (is_string($input)) {
186
-            $input = json_decode($input);
187
-        }
188
-        $this->input = $input;
189
-    }
24
+	/**
25
+	 * The input data.
26
+	 *
27
+	 * @var array
28
+	 */
29
+	protected $input;
30
+
31
+	/**
32
+	 * Root component.
33
+	 *
34
+	 * @var Document
35
+	 */
36
+	protected $root;
37
+
38
+	/**
39
+	 * This method starts the parsing process.
40
+	 *
41
+	 * If the input was not supplied during construction, it's possible to pass
42
+	 * it here instead.
43
+	 *
44
+	 * If either input or options are not supplied, the defaults will be used.
45
+	 *
46
+	 * @param resource|string|array|null $input
47
+	 * @param int                        $options
48
+	 *
49
+	 * @return \Sabre\VObject\Document
50
+	 */
51
+	public function parse($input = null, $options = 0)
52
+	{
53
+		if (!is_null($input)) {
54
+			$this->setInput($input);
55
+		}
56
+		if (is_null($this->input)) {
57
+			throw new EofException('End of input stream, or no input supplied');
58
+		}
59
+
60
+		if (0 !== $options) {
61
+			$this->options = $options;
62
+		}
63
+
64
+		switch ($this->input[0]) {
65
+			case 'vcalendar':
66
+				$this->root = new VCalendar([], false);
67
+				break;
68
+			case 'vcard':
69
+				$this->root = new VCard([], false);
70
+				break;
71
+			default:
72
+				throw new ParseException('The root component must either be a vcalendar, or a vcard');
73
+		}
74
+		foreach ($this->input[1] as $prop) {
75
+			$this->root->add($this->parseProperty($prop));
76
+		}
77
+		if (isset($this->input[2])) {
78
+			foreach ($this->input[2] as $comp) {
79
+				$this->root->add($this->parseComponent($comp));
80
+			}
81
+		}
82
+
83
+		// Resetting the input so we can throw an feof exception the next time.
84
+		$this->input = null;
85
+
86
+		return $this->root;
87
+	}
88
+
89
+	/**
90
+	 * Parses a component.
91
+	 *
92
+	 * @return \Sabre\VObject\Component
93
+	 */
94
+	public function parseComponent(array $jComp)
95
+	{
96
+		// We can remove $self from PHP 5.4 onward.
97
+		$self = $this;
98
+
99
+		$properties = array_map(
100
+			function ($jProp) use ($self) {
101
+				return $self->parseProperty($jProp);
102
+			},
103
+			$jComp[1]
104
+		);
105
+
106
+		if (isset($jComp[2])) {
107
+			$components = array_map(
108
+				function ($jComp) use ($self) {
109
+					return $self->parseComponent($jComp);
110
+				},
111
+				$jComp[2]
112
+			);
113
+		} else {
114
+			$components = [];
115
+		}
116
+
117
+		return $this->root->createComponent(
118
+			$jComp[0],
119
+			array_merge($properties, $components),
120
+			$defaults = false
121
+		);
122
+	}
123
+
124
+	/**
125
+	 * Parses properties.
126
+	 *
127
+	 * @return \Sabre\VObject\Property
128
+	 */
129
+	public function parseProperty(array $jProp)
130
+	{
131
+		list(
132
+			$propertyName,
133
+			$parameters,
134
+			$valueType
135
+		) = $jProp;
136
+
137
+		$propertyName = strtoupper($propertyName);
138
+
139
+		// This is the default class we would be using if we didn't know the
140
+		// value type. We're using this value later in this function.
141
+		$defaultPropertyClass = $this->root->getClassNameForPropertyName($propertyName);
142
+
143
+		$parameters = (array) $parameters;
144
+
145
+		$value = array_slice($jProp, 3);
146
+
147
+		$valueType = strtoupper($valueType);
148
+
149
+		if (isset($parameters['group'])) {
150
+			$propertyName = $parameters['group'].'.'.$propertyName;
151
+			unset($parameters['group']);
152
+		}
153
+
154
+		$prop = $this->root->createProperty($propertyName, null, $parameters, $valueType);
155
+		$prop->setJsonValue($value);
156
+
157
+		// We have to do something awkward here. FlatText as well as Text
158
+		// represents TEXT values. We have to normalize these here. In the
159
+		// future we can get rid of FlatText once we're allowed to break BC
160
+		// again.
161
+		if (FlatText::class === $defaultPropertyClass) {
162
+			$defaultPropertyClass = Text::class;
163
+		}
164
+
165
+		// If the value type we received (e.g.: TEXT) was not the default value
166
+		// type for the given property (e.g.: BDAY), we need to add a VALUE=
167
+		// parameter.
168
+		if ($defaultPropertyClass !== get_class($prop)) {
169
+			$prop['VALUE'] = $valueType;
170
+		}
171
+
172
+		return $prop;
173
+	}
174
+
175
+	/**
176
+	 * Sets the input data.
177
+	 *
178
+	 * @param resource|string|array $input
179
+	 */
180
+	public function setInput($input)
181
+	{
182
+		if (is_resource($input)) {
183
+			$input = stream_get_contents($input);
184
+		}
185
+		if (is_string($input)) {
186
+			$input = json_decode($input);
187
+		}
188
+		$this->input = $input;
189
+	}
190 190
 }
Please login to merge, or discard this patch.