Completed
Push — developer ( d751a3...e1a3df )
by Błażej
164:44 queued 111:37
created
libraries/SabreDAV/VObject/Node.php 1 patch
Indentation   +250 added lines, -250 removed lines patch added patch discarded remove patch
@@ -12,254 +12,254 @@
 block discarded – undo
12 12
  * @license http://sabre.io/license/ Modified BSD License
13 13
  */
14 14
 abstract class Node
15
-    implements \IteratorAggregate,
16
-               \ArrayAccess,
17
-               \Countable,
18
-               \JsonSerializable,
19
-               Xml\XmlSerializable {
20
-
21
-    /**
22
-     * The following constants are used by the validate() method.
23
-     *
24
-     * If REPAIR is set, the validator will attempt to repair any broken data
25
-     * (if possible).
26
-     */
27
-    const REPAIR = 1;
28
-
29
-    /**
30
-     * If this option is set, the validator will operate on the vcards on the
31
-     * assumption that the vcards need to be valid for CardDAV.
32
-     *
33
-     * This means for example that the UID is required, whereas it is not for
34
-     * regular vcards.
35
-     */
36
-    const PROFILE_CARDDAV = 2;
37
-
38
-    /**
39
-     * If this option is set, the validator will operate on iCalendar objects
40
-     * on the assumption that the vcards need to be valid for CalDAV.
41
-     *
42
-     * This means for example that calendars can only contain objects with
43
-     * identical component types and UIDs.
44
-     */
45
-    const PROFILE_CALDAV = 4;
46
-
47
-    /**
48
-     * Reference to the parent object, if this is not the top object.
49
-     *
50
-     * @var Node
51
-     */
52
-    public $parent;
53
-
54
-    /**
55
-     * Iterator override.
56
-     *
57
-     * @var ElementList
58
-     */
59
-    protected $iterator = null;
60
-
61
-    /**
62
-     * The root document.
63
-     *
64
-     * @var Component
65
-     */
66
-    protected $root;
67
-
68
-    /**
69
-     * Serializes the node into a mimedir format.
70
-     *
71
-     * @return string
72
-     */
73
-    abstract function serialize();
74
-
75
-    /**
76
-     * This method returns an array, with the representation as it should be
77
-     * encoded in JSON. This is used to create jCard or jCal documents.
78
-     *
79
-     * @return array
80
-     */
81
-    abstract function jsonSerialize();
82
-
83
-    /**
84
-     * This method serializes the data into XML. This is used to create xCard or
85
-     * xCal documents.
86
-     *
87
-     * @param Xml\Writer $writer  XML writer.
88
-     *
89
-     * @return void
90
-     */
91
-    abstract function xmlSerialize(Xml\Writer $writer);
92
-
93
-    /**
94
-     * Call this method on a document if you're done using it.
95
-     *
96
-     * It's intended to remove all circular references, so PHP can easily clean
97
-     * it up.
98
-     *
99
-     * @return void
100
-     */
101
-    public function destroy() {
102
-
103
-        $this->parent = null;
104
-        $this->root = null;
105
-
106
-    }
107
-
108
-    /* {{{ IteratorAggregator interface */
109
-
110
-    /**
111
-     * Returns the iterator for this object.
112
-     *
113
-     * @return ElementList
114
-     */
115
-    public function getIterator() {
116
-
117
-        if (!is_null($this->iterator)) {
118
-            return $this->iterator;
119
-        }
120
-
121
-        return new ElementList([$this]);
122
-
123
-    }
124
-
125
-    /**
126
-     * Sets the overridden iterator.
127
-     *
128
-     * Note that this is not actually part of the iterator interface
129
-     *
130
-     * @param ElementList $iterator
131
-     *
132
-     * @return void
133
-     */
134
-    public function setIterator(ElementList $iterator) {
135
-
136
-        $this->iterator = $iterator;
137
-
138
-    }
139
-
140
-    /**
141
-     * Validates the node for correctness.
142
-     *
143
-     * The following options are supported:
144
-     *   Node::REPAIR - May attempt to automatically repair the problem.
145
-     *
146
-     * This method returns an array with detected problems.
147
-     * Every element has the following properties:
148
-     *
149
-     *  * level - problem level.
150
-     *  * message - A human-readable string describing the issue.
151
-     *  * node - A reference to the problematic node.
152
-     *
153
-     * The level means:
154
-     *   1 - The issue was repaired (only happens if REPAIR was turned on)
155
-     *   2 - An inconsequential issue
156
-     *   3 - A severe issue.
157
-     *
158
-     * @param int $options
159
-     *
160
-     * @return array
161
-     */
162
-    public function validate($options = 0) {
163
-
164
-        return [];
165
-
166
-    }
167
-
168
-    /* }}} */
169
-
170
-    /* {{{ Countable interface */
171
-
172
-    /**
173
-     * Returns the number of elements.
174
-     *
175
-     * @return int
176
-     */
177
-    public function count() {
178
-
179
-        $it = $this->getIterator();
180
-        return $it->count();
181
-
182
-    }
183
-
184
-    /* }}} */
185
-
186
-    /* {{{ ArrayAccess Interface */
187
-
188
-
189
-    /**
190
-     * Checks if an item exists through ArrayAccess.
191
-     *
192
-     * This method just forwards the request to the inner iterator
193
-     *
194
-     * @param int $offset
195
-     *
196
-     * @return bool
197
-     */
198
-    public function offsetExists($offset) {
199
-
200
-        $iterator = $this->getIterator();
201
-        return $iterator->offsetExists($offset);
202
-
203
-    }
204
-
205
-    /**
206
-     * Gets an item through ArrayAccess.
207
-     *
208
-     * This method just forwards the request to the inner iterator
209
-     *
210
-     * @param int $offset
211
-     *
212
-     * @return mixed
213
-     */
214
-    public function offsetGet($offset) {
215
-
216
-        $iterator = $this->getIterator();
217
-        return $iterator->offsetGet($offset);
218
-
219
-    }
220
-
221
-    /**
222
-     * Sets an item through ArrayAccess.
223
-     *
224
-     * This method just forwards the request to the inner iterator
225
-     *
226
-     * @param int $offset
227
-     * @param mixed $value
228
-     *
229
-     * @return void
230
-     */
231
-    public function offsetSet($offset, $value) {
232
-
233
-        $iterator = $this->getIterator();
234
-        $iterator->offsetSet($offset, $value);
235
-
236
-    // @codeCoverageIgnoreStart
237
-    //
238
-    // This method always throws an exception, so we ignore the closing
239
-    // brace
240
-    }
241
-    // @codeCoverageIgnoreEnd
242
-
243
-    /**
244
-     * Sets an item through ArrayAccess.
245
-     *
246
-     * This method just forwards the request to the inner iterator
247
-     *
248
-     * @param int $offset
249
-     *
250
-     * @return void
251
-     */
252
-    public function offsetUnset($offset) {
253
-
254
-        $iterator = $this->getIterator();
255
-        $iterator->offsetUnset($offset);
256
-
257
-    // @codeCoverageIgnoreStart
258
-    //
259
-    // This method always throws an exception, so we ignore the closing
260
-    // brace
261
-    }
262
-    // @codeCoverageIgnoreEnd
263
-
264
-    /* }}} */
15
+	implements \IteratorAggregate,
16
+			   \ArrayAccess,
17
+			   \Countable,
18
+			   \JsonSerializable,
19
+			   Xml\XmlSerializable {
20
+
21
+	/**
22
+	 * The following constants are used by the validate() method.
23
+	 *
24
+	 * If REPAIR is set, the validator will attempt to repair any broken data
25
+	 * (if possible).
26
+	 */
27
+	const REPAIR = 1;
28
+
29
+	/**
30
+	 * If this option is set, the validator will operate on the vcards on the
31
+	 * assumption that the vcards need to be valid for CardDAV.
32
+	 *
33
+	 * This means for example that the UID is required, whereas it is not for
34
+	 * regular vcards.
35
+	 */
36
+	const PROFILE_CARDDAV = 2;
37
+
38
+	/**
39
+	 * If this option is set, the validator will operate on iCalendar objects
40
+	 * on the assumption that the vcards need to be valid for CalDAV.
41
+	 *
42
+	 * This means for example that calendars can only contain objects with
43
+	 * identical component types and UIDs.
44
+	 */
45
+	const PROFILE_CALDAV = 4;
46
+
47
+	/**
48
+	 * Reference to the parent object, if this is not the top object.
49
+	 *
50
+	 * @var Node
51
+	 */
52
+	public $parent;
53
+
54
+	/**
55
+	 * Iterator override.
56
+	 *
57
+	 * @var ElementList
58
+	 */
59
+	protected $iterator = null;
60
+
61
+	/**
62
+	 * The root document.
63
+	 *
64
+	 * @var Component
65
+	 */
66
+	protected $root;
67
+
68
+	/**
69
+	 * Serializes the node into a mimedir format.
70
+	 *
71
+	 * @return string
72
+	 */
73
+	abstract function serialize();
74
+
75
+	/**
76
+	 * This method returns an array, with the representation as it should be
77
+	 * encoded in JSON. This is used to create jCard or jCal documents.
78
+	 *
79
+	 * @return array
80
+	 */
81
+	abstract function jsonSerialize();
82
+
83
+	/**
84
+	 * This method serializes the data into XML. This is used to create xCard or
85
+	 * xCal documents.
86
+	 *
87
+	 * @param Xml\Writer $writer  XML writer.
88
+	 *
89
+	 * @return void
90
+	 */
91
+	abstract function xmlSerialize(Xml\Writer $writer);
92
+
93
+	/**
94
+	 * Call this method on a document if you're done using it.
95
+	 *
96
+	 * It's intended to remove all circular references, so PHP can easily clean
97
+	 * it up.
98
+	 *
99
+	 * @return void
100
+	 */
101
+	public function destroy() {
102
+
103
+		$this->parent = null;
104
+		$this->root = null;
105
+
106
+	}
107
+
108
+	/* {{{ IteratorAggregator interface */
109
+
110
+	/**
111
+	 * Returns the iterator for this object.
112
+	 *
113
+	 * @return ElementList
114
+	 */
115
+	public function getIterator() {
116
+
117
+		if (!is_null($this->iterator)) {
118
+			return $this->iterator;
119
+		}
120
+
121
+		return new ElementList([$this]);
122
+
123
+	}
124
+
125
+	/**
126
+	 * Sets the overridden iterator.
127
+	 *
128
+	 * Note that this is not actually part of the iterator interface
129
+	 *
130
+	 * @param ElementList $iterator
131
+	 *
132
+	 * @return void
133
+	 */
134
+	public function setIterator(ElementList $iterator) {
135
+
136
+		$this->iterator = $iterator;
137
+
138
+	}
139
+
140
+	/**
141
+	 * Validates the node for correctness.
142
+	 *
143
+	 * The following options are supported:
144
+	 *   Node::REPAIR - May attempt to automatically repair the problem.
145
+	 *
146
+	 * This method returns an array with detected problems.
147
+	 * Every element has the following properties:
148
+	 *
149
+	 *  * level - problem level.
150
+	 *  * message - A human-readable string describing the issue.
151
+	 *  * node - A reference to the problematic node.
152
+	 *
153
+	 * The level means:
154
+	 *   1 - The issue was repaired (only happens if REPAIR was turned on)
155
+	 *   2 - An inconsequential issue
156
+	 *   3 - A severe issue.
157
+	 *
158
+	 * @param int $options
159
+	 *
160
+	 * @return array
161
+	 */
162
+	public function validate($options = 0) {
163
+
164
+		return [];
165
+
166
+	}
167
+
168
+	/* }}} */
169
+
170
+	/* {{{ Countable interface */
171
+
172
+	/**
173
+	 * Returns the number of elements.
174
+	 *
175
+	 * @return int
176
+	 */
177
+	public function count() {
178
+
179
+		$it = $this->getIterator();
180
+		return $it->count();
181
+
182
+	}
183
+
184
+	/* }}} */
185
+
186
+	/* {{{ ArrayAccess Interface */
187
+
188
+
189
+	/**
190
+	 * Checks if an item exists through ArrayAccess.
191
+	 *
192
+	 * This method just forwards the request to the inner iterator
193
+	 *
194
+	 * @param int $offset
195
+	 *
196
+	 * @return bool
197
+	 */
198
+	public function offsetExists($offset) {
199
+
200
+		$iterator = $this->getIterator();
201
+		return $iterator->offsetExists($offset);
202
+
203
+	}
204
+
205
+	/**
206
+	 * Gets an item through ArrayAccess.
207
+	 *
208
+	 * This method just forwards the request to the inner iterator
209
+	 *
210
+	 * @param int $offset
211
+	 *
212
+	 * @return mixed
213
+	 */
214
+	public function offsetGet($offset) {
215
+
216
+		$iterator = $this->getIterator();
217
+		return $iterator->offsetGet($offset);
218
+
219
+	}
220
+
221
+	/**
222
+	 * Sets an item through ArrayAccess.
223
+	 *
224
+	 * This method just forwards the request to the inner iterator
225
+	 *
226
+	 * @param int $offset
227
+	 * @param mixed $value
228
+	 *
229
+	 * @return void
230
+	 */
231
+	public function offsetSet($offset, $value) {
232
+
233
+		$iterator = $this->getIterator();
234
+		$iterator->offsetSet($offset, $value);
235
+
236
+	// @codeCoverageIgnoreStart
237
+	//
238
+	// This method always throws an exception, so we ignore the closing
239
+	// brace
240
+	}
241
+	// @codeCoverageIgnoreEnd
242
+
243
+	/**
244
+	 * Sets an item through ArrayAccess.
245
+	 *
246
+	 * This method just forwards the request to the inner iterator
247
+	 *
248
+	 * @param int $offset
249
+	 *
250
+	 * @return void
251
+	 */
252
+	public function offsetUnset($offset) {
253
+
254
+		$iterator = $this->getIterator();
255
+		$iterator->offsetUnset($offset);
256
+
257
+	// @codeCoverageIgnoreStart
258
+	//
259
+	// This method always throws an exception, so we ignore the closing
260
+	// brace
261
+	}
262
+	// @codeCoverageIgnoreEnd
263
+
264
+	/* }}} */
265 265
 }
Please login to merge, or discard this patch.
libraries/SabreDAV/VObject/Parser/MimeDir.php 1 patch
Indentation   +646 added lines, -646 removed lines patch added patch discarded remove patch
@@ -24,328 +24,328 @@  discard block
 block discarded – undo
24 24
  */
25 25
 class MimeDir extends Parser {
26 26
 
27
-    /**
28
-     * The input stream.
29
-     *
30
-     * @var resource
31
-     */
32
-    protected $input;
33
-
34
-    /**
35
-     * Root component.
36
-     *
37
-     * @var Component
38
-     */
39
-    protected $root;
40
-
41
-    /**
42
-     * By default all input will be assumed to be UTF-8.
43
-     *
44
-     * However, both iCalendar and vCard might be encoded using different
45
-     * character sets. The character set is usually set in the mime-type.
46
-     *
47
-     * If this is the case, use setEncoding to specify that a different
48
-     * encoding will be used. If this is set, the parser will automatically
49
-     * convert all incoming data to UTF-8.
50
-     *
51
-     * @var string
52
-     */
53
-    protected $charset = 'UTF-8';
54
-
55
-    /**
56
-     * The list of character sets we support when decoding.
57
-     *
58
-     * This would be a const expression but for now we need to support PHP 5.5
59
-     */
60
-    protected static $SUPPORTED_CHARSETS = [
61
-        'UTF-8',
62
-        'ISO-8859-1',
63
-        'Windows-1252',
64
-    ];
65
-
66
-    /**
67
-     * Parses an iCalendar or vCard file.
68
-     *
69
-     * Pass a stream or a string. If null is parsed, the existing buffer is
70
-     * used.
71
-     *
72
-     * @param string|resource|null $input
73
-     * @param int $options
74
-     *
75
-     * @return Sabre\VObject\Document
76
-     */
77
-    public function parse($input = null, $options = 0) {
78
-
79
-        $this->root = null;
80
-
81
-        if (!is_null($input)) {
82
-            $this->setInput($input);
83
-        }
84
-
85
-        if (0 !== $options) {
86
-            $this->options = $options;
87
-        }
88
-
89
-        $this->parseDocument();
90
-
91
-        return $this->root;
92
-
93
-    }
94
-
95
-    /**
96
-     * By default all input will be assumed to be UTF-8.
97
-     *
98
-     * However, both iCalendar and vCard might be encoded using different
99
-     * character sets. The character set is usually set in the mime-type.
100
-     *
101
-     * If this is the case, use setEncoding to specify that a different
102
-     * encoding will be used. If this is set, the parser will automatically
103
-     * convert all incoming data to UTF-8.
104
-     *
105
-     * @param string $charset
106
-     */
107
-    public function setCharset($charset) {
108
-
109
-        if (!in_array($charset, self::$SUPPORTED_CHARSETS)) {
110
-            throw new \InvalidArgumentException('Unsupported encoding. (Supported encodings: ' . implode(', ', self::$SUPPORTED_CHARSETS) . ')');
111
-        }
112
-        $this->charset = $charset;
113
-
114
-    }
115
-
116
-    /**
117
-     * Sets the input buffer. Must be a string or stream.
118
-     *
119
-     * @param resource|string $input
120
-     *
121
-     * @return void
122
-     */
123
-    public function setInput($input) {
124
-
125
-        // Resetting the parser
126
-        $this->lineIndex = 0;
127
-        $this->startLine = 0;
128
-
129
-        if (is_string($input)) {
130
-            // Convering to a stream.
131
-            $stream = fopen('php://temp', 'r+');
132
-            fwrite($stream, $input);
133
-            rewind($stream);
134
-            $this->input = $stream;
135
-        } elseif (is_resource($input)) {
136
-            $this->input = $input;
137
-        } else {
138
-            throw new \InvalidArgumentException('This parser can only read from strings or streams.');
139
-        }
140
-
141
-    }
142
-
143
-    /**
144
-     * Parses an entire document.
145
-     *
146
-     * @return void
147
-     */
148
-    protected function parseDocument() {
149
-
150
-        $line = $this->readLine();
151
-
152
-        // BOM is ZERO WIDTH NO-BREAK SPACE (U+FEFF).
153
-        // It's 0xEF 0xBB 0xBF in UTF-8 hex.
154
-        if (3 <= strlen($line)
155
-            && ord($line[0]) === 0xef
156
-            && ord($line[1]) === 0xbb
157
-            && ord($line[2]) === 0xbf) {
158
-            $line = substr($line, 3);
159
-        }
160
-
161
-        switch (strtoupper($line)) {
162
-            case 'BEGIN:VCALENDAR' :
163
-                $class = VCalendar::$componentMap['VCALENDAR'];
164
-                break;
165
-            case 'BEGIN:VCARD' :
166
-                $class = VCard::$componentMap['VCARD'];
167
-                break;
168
-            default :
169
-                throw new ParseException('This parser only supports VCARD and VCALENDAR files');
170
-        }
171
-
172
-        $this->root = new $class([], false);
173
-
174
-        while (true) {
175
-
176
-            // Reading until we hit END:
177
-            $line = $this->readLine();
178
-            if (strtoupper(substr($line, 0, 4)) === 'END:') {
179
-                break;
180
-            }
181
-            $result = $this->parseLine($line);
182
-            if ($result) {
183
-                $this->root->add($result);
184
-            }
185
-
186
-        }
187
-
188
-        $name = strtoupper(substr($line, 4));
189
-        if ($name !== $this->root->name) {
190
-            throw new ParseException('Invalid MimeDir file. expected: "END:' . $this->root->name . '" got: "END:' . $name . '"');
191
-        }
192
-
193
-    }
194
-
195
-    /**
196
-     * Parses a line, and if it hits a component, it will also attempt to parse
197
-     * the entire component.
198
-     *
199
-     * @param string $line Unfolded line
200
-     *
201
-     * @return Node
202
-     */
203
-    protected function parseLine($line) {
204
-
205
-        // Start of a new component
206
-        if (strtoupper(substr($line, 0, 6)) === 'BEGIN:') {
207
-
208
-            $component = $this->root->createComponent(substr($line, 6), [], false);
209
-
210
-            while (true) {
211
-
212
-                // Reading until we hit END:
213
-                $line = $this->readLine();
214
-                if (strtoupper(substr($line, 0, 4)) === 'END:') {
215
-                    break;
216
-                }
217
-                $result = $this->parseLine($line);
218
-                if ($result) {
219
-                    $component->add($result);
220
-                }
221
-
222
-            }
223
-
224
-            $name = strtoupper(substr($line, 4));
225
-            if ($name !== $component->name) {
226
-                throw new ParseException('Invalid MimeDir file. expected: "END:' . $component->name . '" got: "END:' . $name . '"');
227
-            }
228
-
229
-            return $component;
230
-
231
-        } else {
232
-
233
-            // Property reader
234
-            $property = $this->readProperty($line);
235
-            if (!$property) {
236
-                // Ignored line
237
-                return false;
238
-            }
239
-            return $property;
240
-
241
-        }
242
-
243
-    }
244
-
245
-    /**
246
-     * We need to look ahead 1 line every time to see if we need to 'unfold'
247
-     * the next line.
248
-     *
249
-     * If that was not the case, we store it here.
250
-     *
251
-     * @var null|string
252
-     */
253
-    protected $lineBuffer;
254
-
255
-    /**
256
-     * The real current line number.
257
-     */
258
-    protected $lineIndex = 0;
259
-
260
-    /**
261
-     * In the case of unfolded lines, this property holds the line number for
262
-     * the start of the line.
263
-     *
264
-     * @var int
265
-     */
266
-    protected $startLine = 0;
267
-
268
-    /**
269
-     * Contains a 'raw' representation of the current line.
270
-     *
271
-     * @var string
272
-     */
273
-    protected $rawLine;
274
-
275
-    /**
276
-     * Reads a single line from the buffer.
277
-     *
278
-     * This method strips any newlines and also takes care of unfolding.
279
-     *
280
-     * @throws \Sabre\VObject\EofException
281
-     *
282
-     * @return string
283
-     */
284
-    protected function readLine() {
285
-
286
-        if (!is_null($this->lineBuffer)) {
287
-            $rawLine = $this->lineBuffer;
288
-            $this->lineBuffer = null;
289
-        } else {
290
-            do {
291
-                $eof = feof($this->input);
292
-
293
-                $rawLine = fgets($this->input);
294
-
295
-                if ($eof || (feof($this->input) && $rawLine === false)) {
296
-                    throw new EofException('End of document reached prematurely');
297
-                }
298
-                if ($rawLine === false) {
299
-                    throw new ParseException('Error reading from input stream');
300
-                }
301
-                $rawLine = rtrim($rawLine, "\r\n");
302
-            } while ($rawLine === ''); // Skipping empty lines
303
-            $this->lineIndex++;
304
-        }
305
-        $line = $rawLine;
306
-
307
-        $this->startLine = $this->lineIndex;
308
-
309
-        // Looking ahead for folded lines.
310
-        while (true) {
311
-
312
-            $nextLine = rtrim(fgets($this->input), "\r\n");
313
-            $this->lineIndex++;
314
-            if (!$nextLine) {
315
-                break;
316
-            }
317
-            if ($nextLine[0] === "\t" || $nextLine[0] === " ") {
318
-                $line .= substr($nextLine, 1);
319
-                $rawLine .= "\n " . substr($nextLine, 1);
320
-            } else {
321
-                $this->lineBuffer = $nextLine;
322
-                break;
323
-            }
324
-
325
-        }
326
-        $this->rawLine = $rawLine;
327
-        return $line;
328
-
329
-    }
330
-
331
-    /**
332
-     * Reads a property or component from a line.
333
-     *
334
-     * @return void
335
-     */
336
-    protected function readProperty($line) {
337
-
338
-        if ($this->options & self::OPTION_FORGIVING) {
339
-            $propNameToken = 'A-Z0-9\-\._\\/';
340
-        } else {
341
-            $propNameToken = 'A-Z0-9\-\.';
342
-        }
343
-
344
-        $paramNameToken = 'A-Z0-9\-';
345
-        $safeChar = '^";:,';
346
-        $qSafeChar = '^"';
347
-
348
-        $regex = "/
27
+	/**
28
+	 * The input stream.
29
+	 *
30
+	 * @var resource
31
+	 */
32
+	protected $input;
33
+
34
+	/**
35
+	 * Root component.
36
+	 *
37
+	 * @var Component
38
+	 */
39
+	protected $root;
40
+
41
+	/**
42
+	 * By default all input will be assumed to be UTF-8.
43
+	 *
44
+	 * However, both iCalendar and vCard might be encoded using different
45
+	 * character sets. The character set is usually set in the mime-type.
46
+	 *
47
+	 * If this is the case, use setEncoding to specify that a different
48
+	 * encoding will be used. If this is set, the parser will automatically
49
+	 * convert all incoming data to UTF-8.
50
+	 *
51
+	 * @var string
52
+	 */
53
+	protected $charset = 'UTF-8';
54
+
55
+	/**
56
+	 * The list of character sets we support when decoding.
57
+	 *
58
+	 * This would be a const expression but for now we need to support PHP 5.5
59
+	 */
60
+	protected static $SUPPORTED_CHARSETS = [
61
+		'UTF-8',
62
+		'ISO-8859-1',
63
+		'Windows-1252',
64
+	];
65
+
66
+	/**
67
+	 * Parses an iCalendar or vCard file.
68
+	 *
69
+	 * Pass a stream or a string. If null is parsed, the existing buffer is
70
+	 * used.
71
+	 *
72
+	 * @param string|resource|null $input
73
+	 * @param int $options
74
+	 *
75
+	 * @return Sabre\VObject\Document
76
+	 */
77
+	public function parse($input = null, $options = 0) {
78
+
79
+		$this->root = null;
80
+
81
+		if (!is_null($input)) {
82
+			$this->setInput($input);
83
+		}
84
+
85
+		if (0 !== $options) {
86
+			$this->options = $options;
87
+		}
88
+
89
+		$this->parseDocument();
90
+
91
+		return $this->root;
92
+
93
+	}
94
+
95
+	/**
96
+	 * By default all input will be assumed to be UTF-8.
97
+	 *
98
+	 * However, both iCalendar and vCard might be encoded using different
99
+	 * character sets. The character set is usually set in the mime-type.
100
+	 *
101
+	 * If this is the case, use setEncoding to specify that a different
102
+	 * encoding will be used. If this is set, the parser will automatically
103
+	 * convert all incoming data to UTF-8.
104
+	 *
105
+	 * @param string $charset
106
+	 */
107
+	public function setCharset($charset) {
108
+
109
+		if (!in_array($charset, self::$SUPPORTED_CHARSETS)) {
110
+			throw new \InvalidArgumentException('Unsupported encoding. (Supported encodings: ' . implode(', ', self::$SUPPORTED_CHARSETS) . ')');
111
+		}
112
+		$this->charset = $charset;
113
+
114
+	}
115
+
116
+	/**
117
+	 * Sets the input buffer. Must be a string or stream.
118
+	 *
119
+	 * @param resource|string $input
120
+	 *
121
+	 * @return void
122
+	 */
123
+	public function setInput($input) {
124
+
125
+		// Resetting the parser
126
+		$this->lineIndex = 0;
127
+		$this->startLine = 0;
128
+
129
+		if (is_string($input)) {
130
+			// Convering to a stream.
131
+			$stream = fopen('php://temp', 'r+');
132
+			fwrite($stream, $input);
133
+			rewind($stream);
134
+			$this->input = $stream;
135
+		} elseif (is_resource($input)) {
136
+			$this->input = $input;
137
+		} else {
138
+			throw new \InvalidArgumentException('This parser can only read from strings or streams.');
139
+		}
140
+
141
+	}
142
+
143
+	/**
144
+	 * Parses an entire document.
145
+	 *
146
+	 * @return void
147
+	 */
148
+	protected function parseDocument() {
149
+
150
+		$line = $this->readLine();
151
+
152
+		// BOM is ZERO WIDTH NO-BREAK SPACE (U+FEFF).
153
+		// It's 0xEF 0xBB 0xBF in UTF-8 hex.
154
+		if (3 <= strlen($line)
155
+			&& ord($line[0]) === 0xef
156
+			&& ord($line[1]) === 0xbb
157
+			&& ord($line[2]) === 0xbf) {
158
+			$line = substr($line, 3);
159
+		}
160
+
161
+		switch (strtoupper($line)) {
162
+			case 'BEGIN:VCALENDAR' :
163
+				$class = VCalendar::$componentMap['VCALENDAR'];
164
+				break;
165
+			case 'BEGIN:VCARD' :
166
+				$class = VCard::$componentMap['VCARD'];
167
+				break;
168
+			default :
169
+				throw new ParseException('This parser only supports VCARD and VCALENDAR files');
170
+		}
171
+
172
+		$this->root = new $class([], false);
173
+
174
+		while (true) {
175
+
176
+			// Reading until we hit END:
177
+			$line = $this->readLine();
178
+			if (strtoupper(substr($line, 0, 4)) === 'END:') {
179
+				break;
180
+			}
181
+			$result = $this->parseLine($line);
182
+			if ($result) {
183
+				$this->root->add($result);
184
+			}
185
+
186
+		}
187
+
188
+		$name = strtoupper(substr($line, 4));
189
+		if ($name !== $this->root->name) {
190
+			throw new ParseException('Invalid MimeDir file. expected: "END:' . $this->root->name . '" got: "END:' . $name . '"');
191
+		}
192
+
193
+	}
194
+
195
+	/**
196
+	 * Parses a line, and if it hits a component, it will also attempt to parse
197
+	 * the entire component.
198
+	 *
199
+	 * @param string $line Unfolded line
200
+	 *
201
+	 * @return Node
202
+	 */
203
+	protected function parseLine($line) {
204
+
205
+		// Start of a new component
206
+		if (strtoupper(substr($line, 0, 6)) === 'BEGIN:') {
207
+
208
+			$component = $this->root->createComponent(substr($line, 6), [], false);
209
+
210
+			while (true) {
211
+
212
+				// Reading until we hit END:
213
+				$line = $this->readLine();
214
+				if (strtoupper(substr($line, 0, 4)) === 'END:') {
215
+					break;
216
+				}
217
+				$result = $this->parseLine($line);
218
+				if ($result) {
219
+					$component->add($result);
220
+				}
221
+
222
+			}
223
+
224
+			$name = strtoupper(substr($line, 4));
225
+			if ($name !== $component->name) {
226
+				throw new ParseException('Invalid MimeDir file. expected: "END:' . $component->name . '" got: "END:' . $name . '"');
227
+			}
228
+
229
+			return $component;
230
+
231
+		} else {
232
+
233
+			// Property reader
234
+			$property = $this->readProperty($line);
235
+			if (!$property) {
236
+				// Ignored line
237
+				return false;
238
+			}
239
+			return $property;
240
+
241
+		}
242
+
243
+	}
244
+
245
+	/**
246
+	 * We need to look ahead 1 line every time to see if we need to 'unfold'
247
+	 * the next line.
248
+	 *
249
+	 * If that was not the case, we store it here.
250
+	 *
251
+	 * @var null|string
252
+	 */
253
+	protected $lineBuffer;
254
+
255
+	/**
256
+	 * The real current line number.
257
+	 */
258
+	protected $lineIndex = 0;
259
+
260
+	/**
261
+	 * In the case of unfolded lines, this property holds the line number for
262
+	 * the start of the line.
263
+	 *
264
+	 * @var int
265
+	 */
266
+	protected $startLine = 0;
267
+
268
+	/**
269
+	 * Contains a 'raw' representation of the current line.
270
+	 *
271
+	 * @var string
272
+	 */
273
+	protected $rawLine;
274
+
275
+	/**
276
+	 * Reads a single line from the buffer.
277
+	 *
278
+	 * This method strips any newlines and also takes care of unfolding.
279
+	 *
280
+	 * @throws \Sabre\VObject\EofException
281
+	 *
282
+	 * @return string
283
+	 */
284
+	protected function readLine() {
285
+
286
+		if (!is_null($this->lineBuffer)) {
287
+			$rawLine = $this->lineBuffer;
288
+			$this->lineBuffer = null;
289
+		} else {
290
+			do {
291
+				$eof = feof($this->input);
292
+
293
+				$rawLine = fgets($this->input);
294
+
295
+				if ($eof || (feof($this->input) && $rawLine === false)) {
296
+					throw new EofException('End of document reached prematurely');
297
+				}
298
+				if ($rawLine === false) {
299
+					throw new ParseException('Error reading from input stream');
300
+				}
301
+				$rawLine = rtrim($rawLine, "\r\n");
302
+			} while ($rawLine === ''); // Skipping empty lines
303
+			$this->lineIndex++;
304
+		}
305
+		$line = $rawLine;
306
+
307
+		$this->startLine = $this->lineIndex;
308
+
309
+		// Looking ahead for folded lines.
310
+		while (true) {
311
+
312
+			$nextLine = rtrim(fgets($this->input), "\r\n");
313
+			$this->lineIndex++;
314
+			if (!$nextLine) {
315
+				break;
316
+			}
317
+			if ($nextLine[0] === "\t" || $nextLine[0] === " ") {
318
+				$line .= substr($nextLine, 1);
319
+				$rawLine .= "\n " . substr($nextLine, 1);
320
+			} else {
321
+				$this->lineBuffer = $nextLine;
322
+				break;
323
+			}
324
+
325
+		}
326
+		$this->rawLine = $rawLine;
327
+		return $line;
328
+
329
+	}
330
+
331
+	/**
332
+	 * Reads a property or component from a line.
333
+	 *
334
+	 * @return void
335
+	 */
336
+	protected function readProperty($line) {
337
+
338
+		if ($this->options & self::OPTION_FORGIVING) {
339
+			$propNameToken = 'A-Z0-9\-\._\\/';
340
+		} else {
341
+			$propNameToken = 'A-Z0-9\-\.';
342
+		}
343
+
344
+		$paramNameToken = 'A-Z0-9\-';
345
+		$safeChar = '^";:,';
346
+		$qSafeChar = '^"';
347
+
348
+		$regex = "/
349 349
             ^(?P<name> [$propNameToken]+ ) (?=[;:])        # property name
350 350
             |
351 351
             (?<=:)(?P<propValue> .+)$                      # property value
@@ -358,339 +358,339 @@  discard block
 block discarded – undo
358 358
             ) (?=[;:,])
359 359
             /xi";
360 360
 
361
-        //echo $regex, "\n"; die();
362
-        preg_match_all($regex, $line, $matches,  PREG_SET_ORDER);
363
-
364
-        $property = [
365
-            'name'       => null,
366
-            'parameters' => [],
367
-            'value'      => null
368
-        ];
369
-
370
-        $lastParam = null;
371
-
372
-        /**
373
-         * Looping through all the tokens.
374
-         *
375
-         * Note that we are looping through them in reverse order, because if a
376
-         * sub-pattern matched, the subsequent named patterns will not show up
377
-         * in the result.
378
-         */
379
-        foreach ($matches as $match) {
380
-
381
-            if (isset($match['paramValue'])) {
382
-                if ($match['paramValue'] && $match['paramValue'][0] === '"') {
383
-                    $value = substr($match['paramValue'], 1, -1);
384
-                } else {
385
-                    $value = $match['paramValue'];
386
-                }
387
-
388
-                $value = $this->unescapeParam($value);
389
-
390
-                if (is_null($lastParam)) {
391
-                    throw new ParseException('Invalid Mimedir file. Line starting at ' . $this->startLine . ' did not follow iCalendar/vCard conventions');
392
-                }
393
-                if (is_null($property['parameters'][$lastParam])) {
394
-                    $property['parameters'][$lastParam] = $value;
395
-                } elseif (is_array($property['parameters'][$lastParam])) {
396
-                    $property['parameters'][$lastParam][] = $value;
397
-                } else {
398
-                    $property['parameters'][$lastParam] = [
399
-                        $property['parameters'][$lastParam],
400
-                        $value
401
-                    ];
402
-                }
403
-                continue;
404
-            }
405
-            if (isset($match['paramName'])) {
406
-                $lastParam = strtoupper($match['paramName']);
407
-                if (!isset($property['parameters'][$lastParam])) {
408
-                    $property['parameters'][$lastParam] = null;
409
-                }
410
-                continue;
411
-            }
412
-            if (isset($match['propValue'])) {
413
-                $property['value'] = $match['propValue'];
414
-                continue;
415
-            }
416
-            if (isset($match['name']) && $match['name']) {
417
-                $property['name'] = strtoupper($match['name']);
418
-                continue;
419
-            }
420
-
421
-            // @codeCoverageIgnoreStart
422
-            throw new \LogicException('This code should not be reachable');
423
-            // @codeCoverageIgnoreEnd
424
-
425
-        }
426
-
427
-        if (is_null($property['value'])) {
428
-            $property['value'] = '';
429
-        }
430
-        if (!$property['name']) {
431
-            if ($this->options & self::OPTION_IGNORE_INVALID_LINES) {
432
-                return false;
433
-            }
434
-            throw new ParseException('Invalid Mimedir file. Line starting at ' . $this->startLine . ' did not follow iCalendar/vCard conventions');
435
-        }
436
-
437
-        // vCard 2.1 states that parameters may appear without a name, and only
438
-        // a value. We can deduce the value based on it's name.
439
-        //
440
-        // Our parser will get those as parameters without a value instead, so
441
-        // we're filtering these parameters out first.
442
-        $namedParameters = [];
443
-        $namelessParameters = [];
444
-
445
-        foreach ($property['parameters'] as $name => $value) {
446
-            if (!is_null($value)) {
447
-                $namedParameters[$name] = $value;
448
-            } else {
449
-                $namelessParameters[] = $name;
450
-            }
451
-        }
452
-
453
-        $propObj = $this->root->createProperty($property['name'], null, $namedParameters);
454
-
455
-        foreach ($namelessParameters as $namelessParameter) {
456
-            $propObj->add(null, $namelessParameter);
457
-        }
458
-
459
-        if (strtoupper($propObj['ENCODING']) === 'QUOTED-PRINTABLE') {
460
-            $propObj->setQuotedPrintableValue($this->extractQuotedPrintableValue());
461
-        } else {
462
-            $charset = $this->charset;
463
-            if ($this->root->getDocumentType() === Document::VCARD21 && isset($propObj['CHARSET'])) {
464
-                // vCard 2.1 allows the character set to be specified per property.
465
-                $charset = (string)$propObj['CHARSET'];
466
-            }
467
-            switch ($charset) {
468
-                case 'UTF-8' :
469
-                    break;
470
-                case 'ISO-8859-1' :
471
-                    $property['value'] = utf8_encode($property['value']);
472
-                    break;
473
-                case 'Windows-1252' :
474
-                    $property['value'] = mb_convert_encoding($property['value'], 'UTF-8', $charset);
475
-                    break;
476
-                default :
477
-                    throw new ParseException('Unsupported CHARSET: ' . $propObj['CHARSET']);
478
-            }
479
-            $propObj->setRawMimeDirValue($property['value']);
480
-        }
481
-
482
-        return $propObj;
483
-
484
-    }
485
-
486
-    /**
487
-     * Unescapes a property value.
488
-     *
489
-     * vCard 2.1 says:
490
-     *   * Semi-colons must be escaped in some property values, specifically
491
-     *     ADR, ORG and N.
492
-     *   * Semi-colons must be escaped in parameter values, because semi-colons
493
-     *     are also use to separate values.
494
-     *   * No mention of escaping backslashes with another backslash.
495
-     *   * newlines are not escaped either, instead QUOTED-PRINTABLE is used to
496
-     *     span values over more than 1 line.
497
-     *
498
-     * vCard 3.0 says:
499
-     *   * (rfc2425) Backslashes, newlines (\n or \N) and comma's must be
500
-     *     escaped, all time time.
501
-     *   * Comma's are used for delimeters in multiple values
502
-     *   * (rfc2426) Adds to to this that the semi-colon MUST also be escaped,
503
-     *     as in some properties semi-colon is used for separators.
504
-     *   * Properties using semi-colons: N, ADR, GEO, ORG
505
-     *   * Both ADR and N's individual parts may be broken up further with a
506
-     *     comma.
507
-     *   * Properties using commas: NICKNAME, CATEGORIES
508
-     *
509
-     * vCard 4.0 (rfc6350) says:
510
-     *   * Commas must be escaped.
511
-     *   * Semi-colons may be escaped, an unescaped semi-colon _may_ be a
512
-     *     delimiter, depending on the property.
513
-     *   * Backslashes must be escaped
514
-     *   * Newlines must be escaped as either \N or \n.
515
-     *   * Some compound properties may contain multiple parts themselves, so a
516
-     *     comma within a semi-colon delimited property may also be unescaped
517
-     *     to denote multiple parts _within_ the compound property.
518
-     *   * Text-properties using semi-colons: N, ADR, ORG, CLIENTPIDMAP.
519
-     *   * Text-properties using commas: NICKNAME, RELATED, CATEGORIES, PID.
520
-     *
521
-     * Even though the spec says that commas must always be escaped, the
522
-     * example for GEO in Section 6.5.2 seems to violate this.
523
-     *
524
-     * iCalendar 2.0 (rfc5545) says:
525
-     *   * Commas or semi-colons may be used as delimiters, depending on the
526
-     *     property.
527
-     *   * Commas, semi-colons, backslashes, newline (\N or \n) are always
528
-     *     escaped, unless they are delimiters.
529
-     *   * Colons shall not be escaped.
530
-     *   * Commas can be considered the 'default delimiter' and is described as
531
-     *     the delimiter in cases where the order of the multiple values is
532
-     *     insignificant.
533
-     *   * Semi-colons are described as the delimiter for 'structured values'.
534
-     *     They are specifically used in Semi-colons are used as a delimiter in
535
-     *     REQUEST-STATUS, RRULE, GEO and EXRULE. EXRULE is deprecated however.
536
-     *
537
-     * Now for the parameters
538
-     *
539
-     * If delimiter is not set (null) this method will just return a string.
540
-     * If it's a comma or a semi-colon the string will be split on those
541
-     * characters, and always return an array.
542
-     *
543
-     * @param string $input
544
-     * @param string $delimiter
545
-     *
546
-     * @return string|string[]
547
-     */
548
-    static function unescapeValue($input, $delimiter = ';') {
549
-
550
-        $regex = '#  (?: (\\\\ (?: \\\\ | N | n | ; | , ) )';
551
-        if ($delimiter) {
552
-            $regex .= ' | (' . $delimiter . ')';
553
-        }
554
-        $regex .= ') #x';
555
-
556
-        $matches = preg_split($regex, $input, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
557
-
558
-        $resultArray = [];
559
-        $result = '';
560
-
561
-        foreach ($matches as $match) {
562
-
563
-            switch ($match) {
564
-                case '\\\\' :
565
-                    $result .= '\\';
566
-                    break;
567
-                case '\N' :
568
-                case '\n' :
569
-                    $result .= "\n";
570
-                    break;
571
-                case '\;' :
572
-                    $result .= ';';
573
-                    break;
574
-                case '\,' :
575
-                    $result .= ',';
576
-                    break;
577
-                case $delimiter :
578
-                    $resultArray[] = $result;
579
-                    $result = '';
580
-                    break;
581
-                default :
582
-                    $result .= $match;
583
-                    break;
584
-
585
-            }
586
-
587
-        }
588
-
589
-        $resultArray[] = $result;
590
-        return $delimiter ? $resultArray : $result;
591
-
592
-    }
593
-
594
-    /**
595
-     * Unescapes a parameter value.
596
-     *
597
-     * vCard 2.1:
598
-     *   * Does not mention a mechanism for this. In addition, double quotes
599
-     *     are never used to wrap values.
600
-     *   * This means that parameters can simply not contain colons or
601
-     *     semi-colons.
602
-     *
603
-     * vCard 3.0 (rfc2425, rfc2426):
604
-     *   * Parameters _may_ be surrounded by double quotes.
605
-     *   * If this is not the case, semi-colon, colon and comma may simply not
606
-     *     occur (the comma used for multiple parameter values though).
607
-     *   * If it is surrounded by double-quotes, it may simply not contain
608
-     *     double-quotes.
609
-     *   * This means that a parameter can in no case encode double-quotes, or
610
-     *     newlines.
611
-     *
612
-     * vCard 4.0 (rfc6350)
613
-     *   * Behavior seems to be identical to vCard 3.0
614
-     *
615
-     * iCalendar 2.0 (rfc5545)
616
-     *   * Behavior seems to be identical to vCard 3.0
617
-     *
618
-     * Parameter escaping mechanism (rfc6868) :
619
-     *   * This rfc describes a new way to escape parameter values.
620
-     *   * New-line is encoded as ^n
621
-     *   * ^ is encoded as ^^.
622
-     *   * " is encoded as ^'
623
-     *
624
-     * @param string $input
625
-     *
626
-     * @return void
627
-     */
628
-    private function unescapeParam($input) {
629
-
630
-        return
631
-            preg_replace_callback(
632
-                '#(\^(\^|n|\'))#',
633
-                public function($matches) {
634
-                    switch ($matches[2]) {
635
-                        case 'n' :
636
-                            return "\n";
637
-                        case '^' :
638
-                            return '^';
639
-                        case '\'' :
640
-                            return '"';
641
-
642
-                    // @codeCoverageIgnoreStart
643
-                    }
644
-                    // @codeCoverageIgnoreEnd
645
-                },
646
-                $input
647
-            );
648
-    }
649
-
650
-    /**
651
-     * Gets the full quoted printable value.
652
-     *
653
-     * We need a special method for this, because newlines have both a meaning
654
-     * in vCards, and in QuotedPrintable.
655
-     *
656
-     * This method does not do any decoding.
657
-     *
658
-     * @return string
659
-     */
660
-    private function extractQuotedPrintableValue() {
661
-
662
-        // We need to parse the raw line again to get the start of the value.
663
-        //
664
-        // We are basically looking for the first colon (:), but we need to
665
-        // skip over the parameters first, as they may contain one.
666
-        $regex = '/^
361
+		//echo $regex, "\n"; die();
362
+		preg_match_all($regex, $line, $matches,  PREG_SET_ORDER);
363
+
364
+		$property = [
365
+			'name'       => null,
366
+			'parameters' => [],
367
+			'value'      => null
368
+		];
369
+
370
+		$lastParam = null;
371
+
372
+		/**
373
+		 * Looping through all the tokens.
374
+		 *
375
+		 * Note that we are looping through them in reverse order, because if a
376
+		 * sub-pattern matched, the subsequent named patterns will not show up
377
+		 * in the result.
378
+		 */
379
+		foreach ($matches as $match) {
380
+
381
+			if (isset($match['paramValue'])) {
382
+				if ($match['paramValue'] && $match['paramValue'][0] === '"') {
383
+					$value = substr($match['paramValue'], 1, -1);
384
+				} else {
385
+					$value = $match['paramValue'];
386
+				}
387
+
388
+				$value = $this->unescapeParam($value);
389
+
390
+				if (is_null($lastParam)) {
391
+					throw new ParseException('Invalid Mimedir file. Line starting at ' . $this->startLine . ' did not follow iCalendar/vCard conventions');
392
+				}
393
+				if (is_null($property['parameters'][$lastParam])) {
394
+					$property['parameters'][$lastParam] = $value;
395
+				} elseif (is_array($property['parameters'][$lastParam])) {
396
+					$property['parameters'][$lastParam][] = $value;
397
+				} else {
398
+					$property['parameters'][$lastParam] = [
399
+						$property['parameters'][$lastParam],
400
+						$value
401
+					];
402
+				}
403
+				continue;
404
+			}
405
+			if (isset($match['paramName'])) {
406
+				$lastParam = strtoupper($match['paramName']);
407
+				if (!isset($property['parameters'][$lastParam])) {
408
+					$property['parameters'][$lastParam] = null;
409
+				}
410
+				continue;
411
+			}
412
+			if (isset($match['propValue'])) {
413
+				$property['value'] = $match['propValue'];
414
+				continue;
415
+			}
416
+			if (isset($match['name']) && $match['name']) {
417
+				$property['name'] = strtoupper($match['name']);
418
+				continue;
419
+			}
420
+
421
+			// @codeCoverageIgnoreStart
422
+			throw new \LogicException('This code should not be reachable');
423
+			// @codeCoverageIgnoreEnd
424
+
425
+		}
426
+
427
+		if (is_null($property['value'])) {
428
+			$property['value'] = '';
429
+		}
430
+		if (!$property['name']) {
431
+			if ($this->options & self::OPTION_IGNORE_INVALID_LINES) {
432
+				return false;
433
+			}
434
+			throw new ParseException('Invalid Mimedir file. Line starting at ' . $this->startLine . ' did not follow iCalendar/vCard conventions');
435
+		}
436
+
437
+		// vCard 2.1 states that parameters may appear without a name, and only
438
+		// a value. We can deduce the value based on it's name.
439
+		//
440
+		// Our parser will get those as parameters without a value instead, so
441
+		// we're filtering these parameters out first.
442
+		$namedParameters = [];
443
+		$namelessParameters = [];
444
+
445
+		foreach ($property['parameters'] as $name => $value) {
446
+			if (!is_null($value)) {
447
+				$namedParameters[$name] = $value;
448
+			} else {
449
+				$namelessParameters[] = $name;
450
+			}
451
+		}
452
+
453
+		$propObj = $this->root->createProperty($property['name'], null, $namedParameters);
454
+
455
+		foreach ($namelessParameters as $namelessParameter) {
456
+			$propObj->add(null, $namelessParameter);
457
+		}
458
+
459
+		if (strtoupper($propObj['ENCODING']) === 'QUOTED-PRINTABLE') {
460
+			$propObj->setQuotedPrintableValue($this->extractQuotedPrintableValue());
461
+		} else {
462
+			$charset = $this->charset;
463
+			if ($this->root->getDocumentType() === Document::VCARD21 && isset($propObj['CHARSET'])) {
464
+				// vCard 2.1 allows the character set to be specified per property.
465
+				$charset = (string)$propObj['CHARSET'];
466
+			}
467
+			switch ($charset) {
468
+				case 'UTF-8' :
469
+					break;
470
+				case 'ISO-8859-1' :
471
+					$property['value'] = utf8_encode($property['value']);
472
+					break;
473
+				case 'Windows-1252' :
474
+					$property['value'] = mb_convert_encoding($property['value'], 'UTF-8', $charset);
475
+					break;
476
+				default :
477
+					throw new ParseException('Unsupported CHARSET: ' . $propObj['CHARSET']);
478
+			}
479
+			$propObj->setRawMimeDirValue($property['value']);
480
+		}
481
+
482
+		return $propObj;
483
+
484
+	}
485
+
486
+	/**
487
+	 * Unescapes a property value.
488
+	 *
489
+	 * vCard 2.1 says:
490
+	 *   * Semi-colons must be escaped in some property values, specifically
491
+	 *     ADR, ORG and N.
492
+	 *   * Semi-colons must be escaped in parameter values, because semi-colons
493
+	 *     are also use to separate values.
494
+	 *   * No mention of escaping backslashes with another backslash.
495
+	 *   * newlines are not escaped either, instead QUOTED-PRINTABLE is used to
496
+	 *     span values over more than 1 line.
497
+	 *
498
+	 * vCard 3.0 says:
499
+	 *   * (rfc2425) Backslashes, newlines (\n or \N) and comma's must be
500
+	 *     escaped, all time time.
501
+	 *   * Comma's are used for delimeters in multiple values
502
+	 *   * (rfc2426) Adds to to this that the semi-colon MUST also be escaped,
503
+	 *     as in some properties semi-colon is used for separators.
504
+	 *   * Properties using semi-colons: N, ADR, GEO, ORG
505
+	 *   * Both ADR and N's individual parts may be broken up further with a
506
+	 *     comma.
507
+	 *   * Properties using commas: NICKNAME, CATEGORIES
508
+	 *
509
+	 * vCard 4.0 (rfc6350) says:
510
+	 *   * Commas must be escaped.
511
+	 *   * Semi-colons may be escaped, an unescaped semi-colon _may_ be a
512
+	 *     delimiter, depending on the property.
513
+	 *   * Backslashes must be escaped
514
+	 *   * Newlines must be escaped as either \N or \n.
515
+	 *   * Some compound properties may contain multiple parts themselves, so a
516
+	 *     comma within a semi-colon delimited property may also be unescaped
517
+	 *     to denote multiple parts _within_ the compound property.
518
+	 *   * Text-properties using semi-colons: N, ADR, ORG, CLIENTPIDMAP.
519
+	 *   * Text-properties using commas: NICKNAME, RELATED, CATEGORIES, PID.
520
+	 *
521
+	 * Even though the spec says that commas must always be escaped, the
522
+	 * example for GEO in Section 6.5.2 seems to violate this.
523
+	 *
524
+	 * iCalendar 2.0 (rfc5545) says:
525
+	 *   * Commas or semi-colons may be used as delimiters, depending on the
526
+	 *     property.
527
+	 *   * Commas, semi-colons, backslashes, newline (\N or \n) are always
528
+	 *     escaped, unless they are delimiters.
529
+	 *   * Colons shall not be escaped.
530
+	 *   * Commas can be considered the 'default delimiter' and is described as
531
+	 *     the delimiter in cases where the order of the multiple values is
532
+	 *     insignificant.
533
+	 *   * Semi-colons are described as the delimiter for 'structured values'.
534
+	 *     They are specifically used in Semi-colons are used as a delimiter in
535
+	 *     REQUEST-STATUS, RRULE, GEO and EXRULE. EXRULE is deprecated however.
536
+	 *
537
+	 * Now for the parameters
538
+	 *
539
+	 * If delimiter is not set (null) this method will just return a string.
540
+	 * If it's a comma or a semi-colon the string will be split on those
541
+	 * characters, and always return an array.
542
+	 *
543
+	 * @param string $input
544
+	 * @param string $delimiter
545
+	 *
546
+	 * @return string|string[]
547
+	 */
548
+	static function unescapeValue($input, $delimiter = ';') {
549
+
550
+		$regex = '#  (?: (\\\\ (?: \\\\ | N | n | ; | , ) )';
551
+		if ($delimiter) {
552
+			$regex .= ' | (' . $delimiter . ')';
553
+		}
554
+		$regex .= ') #x';
555
+
556
+		$matches = preg_split($regex, $input, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
557
+
558
+		$resultArray = [];
559
+		$result = '';
560
+
561
+		foreach ($matches as $match) {
562
+
563
+			switch ($match) {
564
+				case '\\\\' :
565
+					$result .= '\\';
566
+					break;
567
+				case '\N' :
568
+				case '\n' :
569
+					$result .= "\n";
570
+					break;
571
+				case '\;' :
572
+					$result .= ';';
573
+					break;
574
+				case '\,' :
575
+					$result .= ',';
576
+					break;
577
+				case $delimiter :
578
+					$resultArray[] = $result;
579
+					$result = '';
580
+					break;
581
+				default :
582
+					$result .= $match;
583
+					break;
584
+
585
+			}
586
+
587
+		}
588
+
589
+		$resultArray[] = $result;
590
+		return $delimiter ? $resultArray : $result;
591
+
592
+	}
593
+
594
+	/**
595
+	 * Unescapes a parameter value.
596
+	 *
597
+	 * vCard 2.1:
598
+	 *   * Does not mention a mechanism for this. In addition, double quotes
599
+	 *     are never used to wrap values.
600
+	 *   * This means that parameters can simply not contain colons or
601
+	 *     semi-colons.
602
+	 *
603
+	 * vCard 3.0 (rfc2425, rfc2426):
604
+	 *   * Parameters _may_ be surrounded by double quotes.
605
+	 *   * If this is not the case, semi-colon, colon and comma may simply not
606
+	 *     occur (the comma used for multiple parameter values though).
607
+	 *   * If it is surrounded by double-quotes, it may simply not contain
608
+	 *     double-quotes.
609
+	 *   * This means that a parameter can in no case encode double-quotes, or
610
+	 *     newlines.
611
+	 *
612
+	 * vCard 4.0 (rfc6350)
613
+	 *   * Behavior seems to be identical to vCard 3.0
614
+	 *
615
+	 * iCalendar 2.0 (rfc5545)
616
+	 *   * Behavior seems to be identical to vCard 3.0
617
+	 *
618
+	 * Parameter escaping mechanism (rfc6868) :
619
+	 *   * This rfc describes a new way to escape parameter values.
620
+	 *   * New-line is encoded as ^n
621
+	 *   * ^ is encoded as ^^.
622
+	 *   * " is encoded as ^'
623
+	 *
624
+	 * @param string $input
625
+	 *
626
+	 * @return void
627
+	 */
628
+	private function unescapeParam($input) {
629
+
630
+		return
631
+			preg_replace_callback(
632
+				'#(\^(\^|n|\'))#',
633
+				public function($matches) {
634
+					switch ($matches[2]) {
635
+						case 'n' :
636
+							return "\n";
637
+						case '^' :
638
+							return '^';
639
+						case '\'' :
640
+							return '"';
641
+
642
+					// @codeCoverageIgnoreStart
643
+					}
644
+					// @codeCoverageIgnoreEnd
645
+				},
646
+				$input
647
+			);
648
+	}
649
+
650
+	/**
651
+	 * Gets the full quoted printable value.
652
+	 *
653
+	 * We need a special method for this, because newlines have both a meaning
654
+	 * in vCards, and in QuotedPrintable.
655
+	 *
656
+	 * This method does not do any decoding.
657
+	 *
658
+	 * @return string
659
+	 */
660
+	private function extractQuotedPrintableValue() {
661
+
662
+		// We need to parse the raw line again to get the start of the value.
663
+		//
664
+		// We are basically looking for the first colon (:), but we need to
665
+		// skip over the parameters first, as they may contain one.
666
+		$regex = '/^
667 667
             (?: [^:])+ # Anything but a colon
668 668
             (?: "[^"]")* # A parameter in double quotes
669 669
             : # start of the value we really care about
670 670
             (.*)$
671 671
         /xs';
672 672
 
673
-        preg_match($regex, $this->rawLine, $matches);
673
+		preg_match($regex, $this->rawLine, $matches);
674 674
 
675
-        $value = $matches[1];
676
-        // Removing the first whitespace character from every line. Kind of
677
-        // like unfolding, but we keep the newline.
678
-        $value = str_replace("\n ", "\n", $value);
675
+		$value = $matches[1];
676
+		// Removing the first whitespace character from every line. Kind of
677
+		// like unfolding, but we keep the newline.
678
+		$value = str_replace("\n ", "\n", $value);
679 679
 
680
-        // Microsoft products don't always correctly fold lines, they may be
681
-        // missing a whitespace. So if 'forgiving' is turned on, we will take
682
-        // those as well.
683
-        if ($this->options & self::OPTION_FORGIVING) {
684
-            while (substr($value, -1) === '=') {
685
-                // Reading the line
686
-                $this->readLine();
687
-                // Grabbing the raw form
688
-                $value .= "\n" . $this->rawLine;
689
-            }
690
-        }
680
+		// Microsoft products don't always correctly fold lines, they may be
681
+		// missing a whitespace. So if 'forgiving' is turned on, we will take
682
+		// those as well.
683
+		if ($this->options & self::OPTION_FORGIVING) {
684
+			while (substr($value, -1) === '=') {
685
+				// Reading the line
686
+				$this->readLine();
687
+				// Grabbing the raw form
688
+				$value .= "\n" . $this->rawLine;
689
+			}
690
+		}
691 691
 
692
-        return $value;
692
+		return $value;
693 693
 
694
-    }
694
+	}
695 695
 
696 696
 }
Please login to merge, or discard this patch.
libraries/SabreDAV/VObject/Parser/Parser.php 1 patch
Indentation   +57 added lines, -57 removed lines patch added patch discarded remove patch
@@ -13,68 +13,68 @@
 block discarded – undo
13 13
  */
14 14
 abstract class Parser {
15 15
 
16
-    /**
17
-     * Turning on this option makes the parser more forgiving.
18
-     *
19
-     * In the case of the MimeDir parser, this means that the parser will
20
-     * accept slashes and underscores in property names, and it will also
21
-     * attempt to fix Microsoft vCard 2.1's broken line folding.
22
-     */
23
-    const OPTION_FORGIVING = 1;
16
+	/**
17
+	 * Turning on this option makes the parser more forgiving.
18
+	 *
19
+	 * In the case of the MimeDir parser, this means that the parser will
20
+	 * accept slashes and underscores in property names, and it will also
21
+	 * attempt to fix Microsoft vCard 2.1's broken line folding.
22
+	 */
23
+	const OPTION_FORGIVING = 1;
24 24
 
25
-    /**
26
-     * If this option is turned on, any lines we cannot parse will be ignored
27
-     * by the reader.
28
-     */
29
-    const OPTION_IGNORE_INVALID_LINES = 2;
25
+	/**
26
+	 * If this option is turned on, any lines we cannot parse will be ignored
27
+	 * by the reader.
28
+	 */
29
+	const OPTION_IGNORE_INVALID_LINES = 2;
30 30
 
31
-    /**
32
-     * Bitmask of parser options.
33
-     *
34
-     * @var int
35
-     */
36
-    protected $options;
31
+	/**
32
+	 * Bitmask of parser options.
33
+	 *
34
+	 * @var int
35
+	 */
36
+	protected $options;
37 37
 
38
-    /**
39
-     * Creates the parser.
40
-     *
41
-     * Optionally, it's possible to parse the input stream here.
42
-     *
43
-     * @param mixed $input
44
-     * @param int $options Any parser options (OPTION constants).
45
-     *
46
-     * @return void
47
-     */
48
-    public function __construct($input = null, $options = 0) {
38
+	/**
39
+	 * Creates the parser.
40
+	 *
41
+	 * Optionally, it's possible to parse the input stream here.
42
+	 *
43
+	 * @param mixed $input
44
+	 * @param int $options Any parser options (OPTION constants).
45
+	 *
46
+	 * @return void
47
+	 */
48
+	public function __construct($input = null, $options = 0) {
49 49
 
50
-        if (!is_null($input)) {
51
-            $this->setInput($input);
52
-        }
53
-        $this->options = $options;
54
-    }
50
+		if (!is_null($input)) {
51
+			$this->setInput($input);
52
+		}
53
+		$this->options = $options;
54
+	}
55 55
 
56
-    /**
57
-     * This method starts the parsing process.
58
-     *
59
-     * If the input was not supplied during construction, it's possible to pass
60
-     * it here instead.
61
-     *
62
-     * If either input or options are not supplied, the defaults will be used.
63
-     *
64
-     * @param mixed $input
65
-     * @param int $options
66
-     *
67
-     * @return array
68
-     */
69
-    abstract function parse($input = null, $options = 0);
56
+	/**
57
+	 * This method starts the parsing process.
58
+	 *
59
+	 * If the input was not supplied during construction, it's possible to pass
60
+	 * it here instead.
61
+	 *
62
+	 * If either input or options are not supplied, the defaults will be used.
63
+	 *
64
+	 * @param mixed $input
65
+	 * @param int $options
66
+	 *
67
+	 * @return array
68
+	 */
69
+	abstract function parse($input = null, $options = 0);
70 70
 
71
-    /**
72
-     * Sets the input data.
73
-     *
74
-     * @param mixed $input
75
-     *
76
-     * @return void
77
-     */
78
-    abstract function setInput($input);
71
+	/**
72
+	 * Sets the input data.
73
+	 *
74
+	 * @param mixed $input
75
+	 *
76
+	 * @return void
77
+	 */
78
+	abstract function setInput($input);
79 79
 
80 80
 }
Please login to merge, or discard this patch.
libraries/SabreDAV/VObject/Parser/Json.php 1 patch
Indentation   +175 added lines, -175 removed lines patch added patch discarded remove patch
@@ -18,180 +18,180 @@
 block discarded – undo
18 18
  */
19 19
 class Json extends Parser {
20 20
 
21
-    /**
22
-     * The input data.
23
-     *
24
-     * @var array
25
-     */
26
-    protected $input;
27
-
28
-    /**
29
-     * Root component.
30
-     *
31
-     * @var Document
32
-     */
33
-    protected $root;
34
-
35
-    /**
36
-     * This method starts the parsing process.
37
-     *
38
-     * If the input was not supplied during construction, it's possible to pass
39
-     * it here instead.
40
-     *
41
-     * If either input or options are not supplied, the defaults will be used.
42
-     *
43
-     * @param resource|string|array|null $input
44
-     * @param int $options
45
-     *
46
-     * @return Sabre\VObject\Document
47
-     */
48
-    public function parse($input = null, $options = 0) {
49
-
50
-        if (!is_null($input)) {
51
-            $this->setInput($input);
52
-        }
53
-        if (is_null($this->input)) {
54
-            throw new EofException('End of input stream, or no input supplied');
55
-        }
56
-
57
-        if (0 !== $options) {
58
-            $this->options = $options;
59
-        }
60
-
61
-        switch ($this->input[0]) {
62
-            case 'vcalendar' :
63
-                $this->root = new VCalendar([], false);
64
-                break;
65
-            case 'vcard' :
66
-                $this->root = new VCard([], false);
67
-                break;
68
-            default :
69
-                throw new ParseException('The root component must either be a vcalendar, or a vcard');
70
-
71
-        }
72
-        foreach ($this->input[1] as $prop) {
73
-            $this->root->add($this->parseProperty($prop));
74
-        }
75
-        if (isset($this->input[2])) foreach ($this->input[2] as $comp) {
76
-            $this->root->add($this->parseComponent($comp));
77
-        }
78
-
79
-        // Resetting the input so we can throw an feof exception the next time.
80
-        $this->input = null;
81
-
82
-        return $this->root;
83
-
84
-    }
85
-
86
-    /**
87
-     * Parses a component.
88
-     *
89
-     * @param array $jComp
90
-     *
91
-     * @return \Sabre\VObject\Component
92
-     */
93
-    public function parseComponent(array $jComp) {
94
-
95
-        // We can remove $self from PHP 5.4 onward.
96
-        $self = $this;
97
-
98
-        $properties = array_map(
99
-            public function($jProp) use ($self) {
100
-                return $self->parseProperty($jProp);
101
-            },
102
-            $jComp[1]
103
-        );
104
-
105
-        if (isset($jComp[2])) {
106
-
107
-            $components = array_map(
108
-                public function($jComp) use ($self) {
109
-                    return $self->parseComponent($jComp);
110
-                },
111
-                $jComp[2]
112
-            );
113
-
114
-        } else $components = [];
115
-
116
-        return $this->root->createComponent(
117
-            $jComp[0],
118
-            array_merge($properties, $components),
119
-            $defaults = false
120
-        );
121
-
122
-    }
123
-
124
-    /**
125
-     * Parses properties.
126
-     *
127
-     * @param array $jProp
128
-     *
129
-     * @return \Sabre\VObject\Property
130
-     */
131
-    public function parseProperty(array $jProp) {
132
-
133
-        list(
134
-            $propertyName,
135
-            $parameters,
136
-            $valueType
137
-        ) = $jProp;
138
-
139
-        $propertyName = strtoupper($propertyName);
140
-
141
-        // This is the default class we would be using if we didn't know the
142
-        // value type. We're using this value later in this function.
143
-        $defaultPropertyClass = $this->root->getClassNameForPropertyName($propertyName);
144
-
145
-        $parameters = (array)$parameters;
146
-
147
-        $value = array_slice($jProp, 3);
148
-
149
-        $valueType = strtoupper($valueType);
150
-
151
-        if (isset($parameters['group'])) {
152
-            $propertyName = $parameters['group'] . '.' . $propertyName;
153
-            unset($parameters['group']);
154
-        }
155
-
156
-        $prop = $this->root->createProperty($propertyName, null, $parameters, $valueType);
157
-        $prop->setJsonValue($value);
158
-
159
-        // We have to do something awkward here. FlatText as well as Text
160
-        // represents TEXT values. We have to normalize these here. In the
161
-        // future we can get rid of FlatText once we're allowed to break BC
162
-        // again.
163
-        if ($defaultPropertyClass === 'Sabre\VObject\Property\FlatText') {
164
-            $defaultPropertyClass = 'Sabre\VObject\Property\Text';
165
-        }
166
-
167
-        // If the value type we received (e.g.: TEXT) was not the default value
168
-        // type for the given property (e.g.: BDAY), we need to add a VALUE=
169
-        // parameter.
170
-        if ($defaultPropertyClass !== get_class($prop)) {
171
-            $prop["VALUE"] = $valueType;
172
-        }
173
-
174
-        return $prop;
175
-
176
-    }
177
-
178
-    /**
179
-     * Sets the input data.
180
-     *
181
-     * @param resource|string|array $input
182
-     *
183
-     * @return void
184
-     */
185
-    public function setInput($input) {
186
-
187
-        if (is_resource($input)) {
188
-            $input = stream_get_contents($input);
189
-        }
190
-        if (is_string($input)) {
191
-            $input = json_decode($input);
192
-        }
193
-        $this->input = $input;
194
-
195
-    }
21
+	/**
22
+	 * The input data.
23
+	 *
24
+	 * @var array
25
+	 */
26
+	protected $input;
27
+
28
+	/**
29
+	 * Root component.
30
+	 *
31
+	 * @var Document
32
+	 */
33
+	protected $root;
34
+
35
+	/**
36
+	 * This method starts the parsing process.
37
+	 *
38
+	 * If the input was not supplied during construction, it's possible to pass
39
+	 * it here instead.
40
+	 *
41
+	 * If either input or options are not supplied, the defaults will be used.
42
+	 *
43
+	 * @param resource|string|array|null $input
44
+	 * @param int $options
45
+	 *
46
+	 * @return Sabre\VObject\Document
47
+	 */
48
+	public function parse($input = null, $options = 0) {
49
+
50
+		if (!is_null($input)) {
51
+			$this->setInput($input);
52
+		}
53
+		if (is_null($this->input)) {
54
+			throw new EofException('End of input stream, or no input supplied');
55
+		}
56
+
57
+		if (0 !== $options) {
58
+			$this->options = $options;
59
+		}
60
+
61
+		switch ($this->input[0]) {
62
+			case 'vcalendar' :
63
+				$this->root = new VCalendar([], false);
64
+				break;
65
+			case 'vcard' :
66
+				$this->root = new VCard([], false);
67
+				break;
68
+			default :
69
+				throw new ParseException('The root component must either be a vcalendar, or a vcard');
70
+
71
+		}
72
+		foreach ($this->input[1] as $prop) {
73
+			$this->root->add($this->parseProperty($prop));
74
+		}
75
+		if (isset($this->input[2])) foreach ($this->input[2] as $comp) {
76
+			$this->root->add($this->parseComponent($comp));
77
+		}
78
+
79
+		// Resetting the input so we can throw an feof exception the next time.
80
+		$this->input = null;
81
+
82
+		return $this->root;
83
+
84
+	}
85
+
86
+	/**
87
+	 * Parses a component.
88
+	 *
89
+	 * @param array $jComp
90
+	 *
91
+	 * @return \Sabre\VObject\Component
92
+	 */
93
+	public function parseComponent(array $jComp) {
94
+
95
+		// We can remove $self from PHP 5.4 onward.
96
+		$self = $this;
97
+
98
+		$properties = array_map(
99
+			public function($jProp) use ($self) {
100
+				return $self->parseProperty($jProp);
101
+			},
102
+			$jComp[1]
103
+		);
104
+
105
+		if (isset($jComp[2])) {
106
+
107
+			$components = array_map(
108
+				public function($jComp) use ($self) {
109
+					return $self->parseComponent($jComp);
110
+				},
111
+				$jComp[2]
112
+			);
113
+
114
+		} else $components = [];
115
+
116
+		return $this->root->createComponent(
117
+			$jComp[0],
118
+			array_merge($properties, $components),
119
+			$defaults = false
120
+		);
121
+
122
+	}
123
+
124
+	/**
125
+	 * Parses properties.
126
+	 *
127
+	 * @param array $jProp
128
+	 *
129
+	 * @return \Sabre\VObject\Property
130
+	 */
131
+	public function parseProperty(array $jProp) {
132
+
133
+		list(
134
+			$propertyName,
135
+			$parameters,
136
+			$valueType
137
+		) = $jProp;
138
+
139
+		$propertyName = strtoupper($propertyName);
140
+
141
+		// This is the default class we would be using if we didn't know the
142
+		// value type. We're using this value later in this function.
143
+		$defaultPropertyClass = $this->root->getClassNameForPropertyName($propertyName);
144
+
145
+		$parameters = (array)$parameters;
146
+
147
+		$value = array_slice($jProp, 3);
148
+
149
+		$valueType = strtoupper($valueType);
150
+
151
+		if (isset($parameters['group'])) {
152
+			$propertyName = $parameters['group'] . '.' . $propertyName;
153
+			unset($parameters['group']);
154
+		}
155
+
156
+		$prop = $this->root->createProperty($propertyName, null, $parameters, $valueType);
157
+		$prop->setJsonValue($value);
158
+
159
+		// We have to do something awkward here. FlatText as well as Text
160
+		// represents TEXT values. We have to normalize these here. In the
161
+		// future we can get rid of FlatText once we're allowed to break BC
162
+		// again.
163
+		if ($defaultPropertyClass === 'Sabre\VObject\Property\FlatText') {
164
+			$defaultPropertyClass = 'Sabre\VObject\Property\Text';
165
+		}
166
+
167
+		// If the value type we received (e.g.: TEXT) was not the default value
168
+		// type for the given property (e.g.: BDAY), we need to add a VALUE=
169
+		// parameter.
170
+		if ($defaultPropertyClass !== get_class($prop)) {
171
+			$prop["VALUE"] = $valueType;
172
+		}
173
+
174
+		return $prop;
175
+
176
+	}
177
+
178
+	/**
179
+	 * Sets the input data.
180
+	 *
181
+	 * @param resource|string|array $input
182
+	 *
183
+	 * @return void
184
+	 */
185
+	public function setInput($input) {
186
+
187
+		if (is_resource($input)) {
188
+			$input = stream_get_contents($input);
189
+		}
190
+		if (is_string($input)) {
191
+			$input = json_decode($input);
192
+		}
193
+		$this->input = $input;
194
+
195
+	}
196 196
 
197 197
 }
Please login to merge, or discard this patch.
libraries/SabreDAV/Uri/functions.php 1 patch
Indentation   +186 added lines, -186 removed lines patch added patch discarded remove patch
@@ -22,80 +22,80 @@  discard block
 block discarded – undo
22 22
  */
23 23
 function resolve($basePath, $newPath) {
24 24
 
25
-    $base = parse($basePath);
26
-    $delta = parse($newPath);
27
-
28
-    $pick = function($part) use ($base, $delta) {
29
-
30
-        if ($delta[$part]) {
31
-            return $delta[$part];
32
-        } elseif ($base[$part]) {
33
-            return $base[$part];
34
-        }
35
-        return null;
36
-
37
-    };
38
-
39
-    // If the new path defines a scheme, it's absolute and we can just return
40
-    // that.
41
-    if ($delta['scheme']) {
42
-        return build($delta);
43
-    }
44
-
45
-    $newParts = [];
46
-
47
-    $newParts['scheme'] = $pick('scheme');
48
-    $newParts['host']   = $pick('host');
49
-    $newParts['port']   = $pick('port');
50
-
51
-    $path = '';
52
-    if ($delta['path']) {
53
-        // If the path starts with a slash
54
-        if ($delta['path'][0] === '/') {
55
-            $path = $delta['path'];
56
-        } else {
57
-            // Removing last component from base path.
58
-            $path = $base['path'];
59
-            if (strpos($path, '/') !== false) {
60
-                $path = substr($path, 0, strrpos($path, '/'));
61
-            }
62
-            $path .= '/' . $delta['path'];
63
-        }
64
-    } else {
65
-        $path = $base['path'] ?: '/';
66
-    }
67
-    // Removing .. and .
68
-    $pathParts = explode('/', $path);
69
-    $newPathParts = [];
70
-    foreach ($pathParts as $pathPart) {
71
-
72
-        switch ($pathPart) {
73
-            //case '' :
74
-            case '.' :
75
-                break;
76
-            case '..' :
77
-                array_pop($newPathParts);
78
-                break;
79
-            default :
80
-                $newPathParts[] = $pathPart;
81
-                break;
82
-        }
83
-    }
84
-
85
-    $path = implode('/', $newPathParts);
86
-
87
-    // If the source url ended with a /, we want to preserve that.
88
-    $newParts['path'] = $path;
89
-    if ($delta['query']) {
90
-        $newParts['query'] = $delta['query'];
91
-    } elseif (!empty($base['query']) && empty($delta['host']) && empty($delta['path'])) {
92
-        // Keep the old query if host and path didn't change
93
-        $newParts['query'] = $base['query'];
94
-    }
95
-    if ($delta['fragment']) {
96
-        $newParts['fragment'] = $delta['fragment'];
97
-    }
98
-    return build($newParts);
25
+	$base = parse($basePath);
26
+	$delta = parse($newPath);
27
+
28
+	$pick = function($part) use ($base, $delta) {
29
+
30
+		if ($delta[$part]) {
31
+			return $delta[$part];
32
+		} elseif ($base[$part]) {
33
+			return $base[$part];
34
+		}
35
+		return null;
36
+
37
+	};
38
+
39
+	// If the new path defines a scheme, it's absolute and we can just return
40
+	// that.
41
+	if ($delta['scheme']) {
42
+		return build($delta);
43
+	}
44
+
45
+	$newParts = [];
46
+
47
+	$newParts['scheme'] = $pick('scheme');
48
+	$newParts['host']   = $pick('host');
49
+	$newParts['port']   = $pick('port');
50
+
51
+	$path = '';
52
+	if ($delta['path']) {
53
+		// If the path starts with a slash
54
+		if ($delta['path'][0] === '/') {
55
+			$path = $delta['path'];
56
+		} else {
57
+			// Removing last component from base path.
58
+			$path = $base['path'];
59
+			if (strpos($path, '/') !== false) {
60
+				$path = substr($path, 0, strrpos($path, '/'));
61
+			}
62
+			$path .= '/' . $delta['path'];
63
+		}
64
+	} else {
65
+		$path = $base['path'] ?: '/';
66
+	}
67
+	// Removing .. and .
68
+	$pathParts = explode('/', $path);
69
+	$newPathParts = [];
70
+	foreach ($pathParts as $pathPart) {
71
+
72
+		switch ($pathPart) {
73
+			//case '' :
74
+			case '.' :
75
+				break;
76
+			case '..' :
77
+				array_pop($newPathParts);
78
+				break;
79
+			default :
80
+				$newPathParts[] = $pathPart;
81
+				break;
82
+		}
83
+	}
84
+
85
+	$path = implode('/', $newPathParts);
86
+
87
+	// If the source url ended with a /, we want to preserve that.
88
+	$newParts['path'] = $path;
89
+	if ($delta['query']) {
90
+		$newParts['query'] = $delta['query'];
91
+	} elseif (!empty($base['query']) && empty($delta['host']) && empty($delta['path'])) {
92
+		// Keep the old query if host and path didn't change
93
+		$newParts['query'] = $base['query'];
94
+	}
95
+	if ($delta['fragment']) {
96
+		$newParts['fragment'] = $delta['fragment'];
97
+	}
98
+	return build($newParts);
99 99
 
100 100
 }
101 101
 
@@ -113,55 +113,55 @@  discard block
 block discarded – undo
113 113
  */
114 114
 function normalize($uri) {
115 115
 
116
-    $parts = parse($uri);
117
-
118
-    if (!empty($parts['path'])) {
119
-        $pathParts = explode('/', ltrim($parts['path'], '/'));
120
-        $newPathParts = [];
121
-        foreach ($pathParts as $pathPart) {
122
-            switch ($pathPart) {
123
-                case '.':
124
-                    // skip
125
-                    break;
126
-                case '..' :
127
-                    // One level up in the hierarchy
128
-                    array_pop($newPathParts);
129
-                    break;
130
-                default :
131
-                    // Ensuring that everything is correctly percent-encoded.
132
-                    $newPathParts[] = rawurlencode(rawurldecode($pathPart));
133
-                    break;
134
-            }
135
-        }
136
-        $parts['path'] = '/' . implode('/', $newPathParts);
137
-    }
138
-
139
-    if ($parts['scheme']) {
140
-        $parts['scheme'] = strtolower($parts['scheme']);
141
-        $defaultPorts = [
142
-            'http'  => '80',
143
-            'https' => '443',
144
-        ];
145
-
146
-        if (!empty($parts['port']) && isset($defaultPorts[$parts['scheme']]) && $defaultPorts[$parts['scheme']] == $parts['port']) {
147
-            // Removing default ports.
148
-            unset($parts['port']);
149
-        }
150
-        // A few HTTP specific rules.
151
-        switch ($parts['scheme']) {
152
-            case 'http' :
153
-            case 'https' :
154
-                if (empty($parts['path'])) {
155
-                    // An empty path is equivalent to / in http.
156
-                    $parts['path'] = '/';
157
-                }
158
-                break;
159
-        }
160
-    }
161
-
162
-    if ($parts['host']) $parts['host'] = strtolower($parts['host']);
163
-
164
-    return build($parts);
116
+	$parts = parse($uri);
117
+
118
+	if (!empty($parts['path'])) {
119
+		$pathParts = explode('/', ltrim($parts['path'], '/'));
120
+		$newPathParts = [];
121
+		foreach ($pathParts as $pathPart) {
122
+			switch ($pathPart) {
123
+				case '.':
124
+					// skip
125
+					break;
126
+				case '..' :
127
+					// One level up in the hierarchy
128
+					array_pop($newPathParts);
129
+					break;
130
+				default :
131
+					// Ensuring that everything is correctly percent-encoded.
132
+					$newPathParts[] = rawurlencode(rawurldecode($pathPart));
133
+					break;
134
+			}
135
+		}
136
+		$parts['path'] = '/' . implode('/', $newPathParts);
137
+	}
138
+
139
+	if ($parts['scheme']) {
140
+		$parts['scheme'] = strtolower($parts['scheme']);
141
+		$defaultPorts = [
142
+			'http'  => '80',
143
+			'https' => '443',
144
+		];
145
+
146
+		if (!empty($parts['port']) && isset($defaultPorts[$parts['scheme']]) && $defaultPorts[$parts['scheme']] == $parts['port']) {
147
+			// Removing default ports.
148
+			unset($parts['port']);
149
+		}
150
+		// A few HTTP specific rules.
151
+		switch ($parts['scheme']) {
152
+			case 'http' :
153
+			case 'https' :
154
+				if (empty($parts['path'])) {
155
+					// An empty path is equivalent to / in http.
156
+					$parts['path'] = '/';
157
+				}
158
+				break;
159
+		}
160
+	}
161
+
162
+	if ($parts['host']) $parts['host'] = strtolower($parts['host']);
163
+
164
+	return build($parts);
165 165
 
166 166
 }
167 167
 
@@ -180,29 +180,29 @@  discard block
 block discarded – undo
180 180
  */
181 181
 function parse($uri) {
182 182
 
183
-    // Normally a URI must be ASCII, however. However, often it's not and
184
-    // parse_url might corrupt these strings.
185
-    //
186
-    // For that reason we take any non-ascii characters from the uri and
187
-    // uriencode them first.
188
-    $uri = preg_replace_callback(
189
-        '/[^[:ascii:]]/u',
190
-        public function($matches) {
191
-            return rawurlencode($matches[0]);
192
-        },
193
-        $uri
194
-    );
195
-
196
-    return
197
-        parse_url($uri) + [
198
-            'scheme'   => null,
199
-            'host'     => null,
200
-            'path'     => null,
201
-            'port'     => null,
202
-            'user'     => null,
203
-            'query'    => null,
204
-            'fragment' => null,
205
-        ];
183
+	// Normally a URI must be ASCII, however. However, often it's not and
184
+	// parse_url might corrupt these strings.
185
+	//
186
+	// For that reason we take any non-ascii characters from the uri and
187
+	// uriencode them first.
188
+	$uri = preg_replace_callback(
189
+		'/[^[:ascii:]]/u',
190
+		public function($matches) {
191
+			return rawurlencode($matches[0]);
192
+		},
193
+		$uri
194
+	);
195
+
196
+	return
197
+		parse_url($uri) + [
198
+			'scheme'   => null,
199
+			'host'     => null,
200
+			'path'     => null,
201
+			'port'     => null,
202
+			'user'     => null,
203
+			'query'    => null,
204
+			'fragment' => null,
205
+		];
206 206
 
207 207
 }
208 208
 
@@ -215,41 +215,41 @@  discard block
 block discarded – undo
215 215
  */
216 216
 function build(array $parts) {
217 217
 
218
-    $uri = '';
219
-
220
-    $authority = '';
221
-    if (!empty($parts['host'])) {
222
-        $authority = $parts['host'];
223
-        if (!empty($parts['user'])) {
224
-            $authority = $parts['user'] . '@' . $authority;
225
-        }
226
-        if (!empty($parts['port'])) {
227
-            $authority = $authority . ':' . $parts['port'];
228
-        }
229
-    }
230
-
231
-    if (!empty($parts['scheme'])) {
232
-        // If there's a scheme, there's also a host.
233
-        $uri = $parts['scheme'] . ':';
234
-
235
-    }
236
-    if ($authority) {
237
-        // No scheme, but there is a host.
238
-        $uri .= '//' . $authority;
239
-
240
-    }
241
-
242
-    if (!empty($parts['path'])) {
243
-        $uri .= $parts['path'];
244
-    }
245
-    if (!empty($parts['query'])) {
246
-        $uri .= '?' . $parts['query'];
247
-    }
248
-    if (!empty($parts['fragment'])) {
249
-        $uri .= '#' . $parts['fragment'];
250
-    }
251
-
252
-    return $uri;
218
+	$uri = '';
219
+
220
+	$authority = '';
221
+	if (!empty($parts['host'])) {
222
+		$authority = $parts['host'];
223
+		if (!empty($parts['user'])) {
224
+			$authority = $parts['user'] . '@' . $authority;
225
+		}
226
+		if (!empty($parts['port'])) {
227
+			$authority = $authority . ':' . $parts['port'];
228
+		}
229
+	}
230
+
231
+	if (!empty($parts['scheme'])) {
232
+		// If there's a scheme, there's also a host.
233
+		$uri = $parts['scheme'] . ':';
234
+
235
+	}
236
+	if ($authority) {
237
+		// No scheme, but there is a host.
238
+		$uri .= '//' . $authority;
239
+
240
+	}
241
+
242
+	if (!empty($parts['path'])) {
243
+		$uri .= $parts['path'];
244
+	}
245
+	if (!empty($parts['query'])) {
246
+		$uri .= '?' . $parts['query'];
247
+	}
248
+	if (!empty($parts['fragment'])) {
249
+		$uri .= '#' . $parts['fragment'];
250
+	}
251
+
252
+	return $uri;
253 253
 
254 254
 }
255 255
 
@@ -273,10 +273,10 @@  discard block
 block discarded – undo
273 273
  */
274 274
 function split($path) {
275 275
 
276
-    $matches = [];
277
-    if (preg_match('/^(?:(?:(.*)(?:\/+))?([^\/]+))(?:\/?)$/u', $path, $matches)) {
278
-        return [$matches[1], $matches[2]];
279
-    }
280
-    return [null,null];
276
+	$matches = [];
277
+	if (preg_match('/^(?:(?:(.*)(?:\/+))?([^\/]+))(?:\/?)$/u', $path, $matches)) {
278
+		return [$matches[1], $matches[2]];
279
+	}
280
+	return [null,null];
281 281
 
282 282
 }
Please login to merge, or discard this patch.
libraries/SabreDAV/Yeti/WebDAV_File.php 1 patch
Indentation   +54 added lines, -54 removed lines patch added patch discarded remove patch
@@ -11,78 +11,78 @@
 block discarded – undo
11 11
  */
12 12
 class WebDAV_File extends WebDAV_Node implements DAV\IFile {
13 13
 
14
-    /**
15
-     * Updates the data
16
-     *
17
-     * @param resource $data
18
-     * @return void
19
-     */
20
-    public function put($data) {
14
+	/**
15
+	 * Updates the data
16
+	 *
17
+	 * @param resource $data
18
+	 * @return void
19
+	 */
20
+	public function put($data) {
21 21
 		
22
-    }
22
+	}
23 23
 
24
-    /**
25
-     * Returns the data
26
-     *
27
-     * @return string
28
-     */
29
-    public function get() {
24
+	/**
25
+	 * Returns the data
26
+	 *
27
+	 * @return string
28
+	 */
29
+	public function get() {
30 30
 		$stmt = $this->exData->pdo->prepare('UPDATE vtiger_files SET downloadcount=downloadcount+1 WHERE filesid=?;');
31 31
 		$stmt->execute([$this->filesid]);
32 32
 	
33 33
 		$path = $this->exData->localStorageDir . $this->localPath;
34
-        return fopen($path,'r');
35
-    }
34
+		return fopen($path,'r');
35
+	}
36 36
 
37
-    /**
38
-     * Delete the current file
39
-     *
40
-     * @return void
41
-     */
42
-    public function delete() {
37
+	/**
38
+	 * Delete the current file
39
+	 *
40
+	 * @return void
41
+	 */
42
+	public function delete() {
43 43
 		$path = $this->exData->localStorageDir . $this->localPath;
44 44
 		$stmt = $this->exData->pdo->prepare('UPDATE vtiger_crmentity SET deleted = ? WHERE crmid = ?;');
45 45
 		$stmt->execute([1,$this->filesid]);
46 46
 		//unlink($path);
47
-    }
47
+	}
48 48
 
49
-    /**
50
-     * Returns the size of the node, in bytes
51
-     *
52
-     * @return int
53
-     */
54
-    public function getSize() {
49
+	/**
50
+	 * Returns the size of the node, in bytes
51
+	 *
52
+	 * @return int
53
+	 */
54
+	public function getSize() {
55 55
 		if (isset($this->size)) {
56 56
 			return $this->size;
57 57
 		}
58 58
 		$path = $this->exData->localStorageDir . $this->localPath;
59
-        return filesize($path);
60
-    }
59
+		return filesize($path);
60
+	}
61 61
 
62
-    /**
63
-     * Returns the ETag for a file
64
-     *
65
-     * An ETag is a unique identifier representing the current version of the file. If the file changes, the ETag MUST change.
66
-     * The ETag is an arbitrary string, but MUST be surrounded by double-quotes.
67
-     *
68
-     * Return null if the ETag can not effectively be determined
69
-     *
70
-     * @return mixed
71
-     */
72
-    public function getETag() {
73
-        return null;
74
-    }
62
+	/**
63
+	 * Returns the ETag for a file
64
+	 *
65
+	 * An ETag is a unique identifier representing the current version of the file. If the file changes, the ETag MUST change.
66
+	 * The ETag is an arbitrary string, but MUST be surrounded by double-quotes.
67
+	 *
68
+	 * Return null if the ETag can not effectively be determined
69
+	 *
70
+	 * @return mixed
71
+	 */
72
+	public function getETag() {
73
+		return null;
74
+	}
75 75
 
76
-    /**
77
-     * Returns the mime-type for a file
78
-     *
79
-     * If null is returned, we'll assume application/octet-stream
80
-     *
81
-     * @return mixed
82
-     */
83
-    public function getContentType() {
84
-        return null;
85
-    }
76
+	/**
77
+	 * Returns the mime-type for a file
78
+	 *
79
+	 * If null is returned, we'll assume application/octet-stream
80
+	 *
81
+	 * @return mixed
82
+	 */
83
+	public function getContentType() {
84
+		return null;
85
+	}
86 86
 
87 87
 	/**
88 88
 	 * Renames the node
Please login to merge, or discard this patch.
libraries/SabreDAV/Yeti/WebDAV_Directory.php 1 patch
Indentation   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -237,27 +237,27 @@
 block discarded – undo
237 237
 		$this->path = $newPath;
238 238
 	}
239 239
 	
240
-    /**
241
-     * Moves a node into this collection.
242
-     *
243
-     * It is up to the implementors to:
244
-     *   1. Create the new resource.
245
-     *   2. Remove the old resource.
246
-     *   3. Transfer any properties or other data.
247
-     *
248
-     * Generally you should make very sure that your collection can easily move
249
-     * the move.
250
-     *
251
-     * If you don't, just return false, which will trigger sabre/dav to handle
252
-     * the move itself. If you return true from this function, the assumption
253
-     * is that the move was successful.
254
-     *
255
-     * @param string $targetName New local file/collection name.
256
-     * @param string $sourcePath Full path to source node
257
-     * @param DAV\INode $sourceNode Source node itself
258
-     * @return bool
259
-     */
260
-    public function moveInto($targetName, $sourcePath, DAV\INode $sourceNode) {
240
+	/**
241
+	 * Moves a node into this collection.
242
+	 *
243
+	 * It is up to the implementors to:
244
+	 *   1. Create the new resource.
245
+	 *   2. Remove the old resource.
246
+	 *   3. Transfer any properties or other data.
247
+	 *
248
+	 * Generally you should make very sure that your collection can easily move
249
+	 * the move.
250
+	 *
251
+	 * If you don't, just return false, which will trigger sabre/dav to handle
252
+	 * the move itself. If you return true from this function, the assumption
253
+	 * is that the move was successful.
254
+	 *
255
+	 * @param string $targetName New local file/collection name.
256
+	 * @param string $sourcePath Full path to source node
257
+	 * @param DAV\INode $sourceNode Source node itself
258
+	 * @return bool
259
+	 */
260
+	public function moveInto($targetName, $sourcePath, DAV\INode $sourceNode) {
261 261
 		$log = print_r([$targetName, $sourcePath, $sourceNode,$this], true);
262 262
 		file_put_contents('cache/logs/xxebug.log', ' --- '.date('Y-m-d H:i:s').' --- RequestInterface --- '.PHP_EOL.$log, FILE_APPEND);
263 263
 
Please login to merge, or discard this patch.
libraries/SabreDAV/DAV/ICollection.php 1 patch
Indentation   +55 added lines, -55 removed lines patch added patch discarded remove patch
@@ -13,64 +13,64 @@
 block discarded – undo
13 13
  */
14 14
 interface ICollection extends INode {
15 15
 
16
-    /**
17
-     * Creates a new file in the directory
18
-     *
19
-     * Data will either be supplied as a stream resource, or in certain cases
20
-     * as a string. Keep in mind that you may have to support either.
21
-     *
22
-     * After successful creation of the file, you may choose to return the ETag
23
-     * of the new file here.
24
-     *
25
-     * The returned ETag must be surrounded by double-quotes (The quotes should
26
-     * be part of the actual string).
27
-     *
28
-     * If you cannot accurately determine the ETag, you should not return it.
29
-     * If you don't store the file exactly as-is (you're transforming it
30
-     * somehow) you should also not return an ETag.
31
-     *
32
-     * This means that if a subsequent GET to this new file does not exactly
33
-     * return the same contents of what was submitted here, you are strongly
34
-     * recommended to omit the ETag.
35
-     *
36
-     * @param string $name Name of the file
37
-     * @param resource|string $data Initial payload
38
-     * @return null|string
39
-     */
40
-    public function createFile($name, $data = null);
16
+	/**
17
+	 * Creates a new file in the directory
18
+	 *
19
+	 * Data will either be supplied as a stream resource, or in certain cases
20
+	 * as a string. Keep in mind that you may have to support either.
21
+	 *
22
+	 * After successful creation of the file, you may choose to return the ETag
23
+	 * of the new file here.
24
+	 *
25
+	 * The returned ETag must be surrounded by double-quotes (The quotes should
26
+	 * be part of the actual string).
27
+	 *
28
+	 * If you cannot accurately determine the ETag, you should not return it.
29
+	 * If you don't store the file exactly as-is (you're transforming it
30
+	 * somehow) you should also not return an ETag.
31
+	 *
32
+	 * This means that if a subsequent GET to this new file does not exactly
33
+	 * return the same contents of what was submitted here, you are strongly
34
+	 * recommended to omit the ETag.
35
+	 *
36
+	 * @param string $name Name of the file
37
+	 * @param resource|string $data Initial payload
38
+	 * @return null|string
39
+	 */
40
+	public function createFile($name, $data = null);
41 41
 
42
-    /**
43
-     * Creates a new subdirectory
44
-     *
45
-     * @param string $name
46
-     * @return void
47
-     */
48
-    public function createDirectory($name);
42
+	/**
43
+	 * Creates a new subdirectory
44
+	 *
45
+	 * @param string $name
46
+	 * @return void
47
+	 */
48
+	public function createDirectory($name);
49 49
 
50
-    /**
51
-     * Returns a specific child node, referenced by its name
52
-     *
53
-     * This method must throw Sabre\DAV\Exception\NotFound if the node does not
54
-     * exist.
55
-     *
56
-     * @param string $name
57
-     * @return DAV\INode
58
-     */
59
-    public function getChild($name);
50
+	/**
51
+	 * Returns a specific child node, referenced by its name
52
+	 *
53
+	 * This method must throw Sabre\DAV\Exception\NotFound if the node does not
54
+	 * exist.
55
+	 *
56
+	 * @param string $name
57
+	 * @return DAV\INode
58
+	 */
59
+	public function getChild($name);
60 60
 
61
-    /**
62
-     * Returns an array with all the child nodes
63
-     *
64
-     * @return DAV\INode[]
65
-     */
66
-    public function getChildren();
61
+	/**
62
+	 * Returns an array with all the child nodes
63
+	 *
64
+	 * @return DAV\INode[]
65
+	 */
66
+	public function getChildren();
67 67
 
68
-    /**
69
-     * Checks if a child-node with the specified name exists
70
-     *
71
-     * @param string $name
72
-     * @return bool
73
-     */
74
-    public function childExists($name);
68
+	/**
69
+	 * Checks if a child-node with the specified name exists
70
+	 *
71
+	 * @param string $name
72
+	 * @return bool
73
+	 */
74
+	public function childExists($name);
75 75
 
76 76
 }
Please login to merge, or discard this patch.
libraries/SabreDAV/DAV/Exception.php 1 patch
Indentation   +36 added lines, -36 removed lines patch added patch discarded remove patch
@@ -17,41 +17,41 @@
 block discarded – undo
17 17
  */
18 18
 class Exception extends \Exception {
19 19
 
20
-    /**
21
-     * Returns the HTTP statuscode for this exception
22
-     *
23
-     * @return int
24
-     */
25
-    public function getHTTPCode() {
26
-
27
-        return 500;
28
-
29
-    }
30
-
31
-    /**
32
-     * This method allows the exception to include additional information into the WebDAV error response
33
-     *
34
-     * @param Server $server
35
-     * @param \DOMElement $errorNode
36
-     * @return void
37
-     */
38
-    public function serialize(Server $server, \DOMElement $errorNode) {
39
-
40
-
41
-    }
42
-
43
-    /**
44
-     * This method allows the exception to return any extra HTTP response headers.
45
-     *
46
-     * The headers must be returned as an array.
47
-     *
48
-     * @param Server $server
49
-     * @return array
50
-     */
51
-    public function getHTTPHeaders(Server $server) {
52
-
53
-        return [];
54
-
55
-    }
20
+	/**
21
+	 * Returns the HTTP statuscode for this exception
22
+	 *
23
+	 * @return int
24
+	 */
25
+	public function getHTTPCode() {
26
+
27
+		return 500;
28
+
29
+	}
30
+
31
+	/**
32
+	 * This method allows the exception to include additional information into the WebDAV error response
33
+	 *
34
+	 * @param Server $server
35
+	 * @param \DOMElement $errorNode
36
+	 * @return void
37
+	 */
38
+	public function serialize(Server $server, \DOMElement $errorNode) {
39
+
40
+
41
+	}
42
+
43
+	/**
44
+	 * This method allows the exception to return any extra HTTP response headers.
45
+	 *
46
+	 * The headers must be returned as an array.
47
+	 *
48
+	 * @param Server $server
49
+	 * @return array
50
+	 */
51
+	public function getHTTPHeaders(Server $server) {
52
+
53
+		return [];
54
+
55
+	}
56 56
 
57 57
 }
Please login to merge, or discard this patch.