Completed
Branch master (c3ca5f)
by Seth
04:51
created
phpicalendar/lib/bennu/iCalendar_parameters.php 3 patches
Doc Comments   +6 added lines patch added patch discarded remove patch
@@ -38,6 +38,9 @@  discard block
 block discarded – undo
38 38
         }
39 39
     }
40 40
 
41
+    /**
42
+     * @param iCalendar_property $parent_property
43
+     */
41 44
     function is_valid_value(&$parent_property, $parameter, $value) {
42 45
         switch($parameter) {
43 46
             // These must all be a URI
@@ -191,6 +194,9 @@  discard block
 block discarded – undo
191 194
         }
192 195
     }
193 196
 
197
+    /**
198
+     * @param string $parameter
199
+     */
194 200
     function do_value_formatting($parameter, $value) {
195 201
         switch($parameter) {
196 202
             // Parameters of type CAL-ADDRESS or URI MUST be double-quoted
Please login to merge, or discard this patch.
Indentation   +220 added lines, -220 removed lines patch added patch discarded remove patch
@@ -14,226 +14,226 @@
 block discarded – undo
14 14
  */
15 15
 
16 16
 class iCalendar_parameter {
17
-    function multiple_values_allowed($parameter) {
18
-        switch($parameter) {
19
-            case 'DELEGATED-FROM':
20
-            case 'DELEGATED-TO':
21
-            case 'MEMBER':
22
-                return true;
23
-            default:
24
-                return false;
25
-        }
26
-    }
27
-
28
-    function default_value($parameter) {
29
-        switch($parameter) {
30
-            case 'CUTYPE':   return 'INDIVIDUAL';
31
-            case 'FBTYPE':   return 'BUSY';
32
-            case 'PARTSTAT': return 'NEEDS-ACTION';
33
-            case 'RELATED':  return 'START';
34
-            case 'RELTYPE':  return 'PARENT';
35
-            case 'ROLE':     return 'REQ-PARTICIPANT';
36
-            case 'RSVP':     return 'FALSE';
37
-            default:         return NULL;
38
-        }
39
-    }
40
-
41
-    function is_valid_value(&$parent_property, $parameter, $value) {
42
-        switch($parameter) {
43
-            // These must all be a URI
44
-            case 'ALTREP':
45
-            case 'DIR':
46
-                return rfc2445_is_valid_value($value, RFC2445_TYPE_URI);
47
-            break;
48
-
49
-            // These must be CAL-ADDRESS, which is equivalent to URI
50
-            case 'DELEGATED-FROM':
51
-            case 'DELEGATED-TO':
52
-            case 'MEMBER':
53
-            case 'SENT-BY':
54
-                return rfc2445_is_valid_value($value, RFC2445_TYPE_CAL_ADDRESS);
55
-            break;
56
-
57
-            // These are textual parameters, so the MUST NOT contain double quotes
58
-            case 'CN':
59
-                return (strpos($value, '"') === false);
60
-            break;
61
-
62
-            // These have enumerated legal values
63
-            case 'CUTYPE':
64
-                $value = strtoupper($value);
65
-                return ($value == 'INDIVIDUAL' || $value == 'GROUP' || $value == 'RESOURCE' || $value == 'ROOM' || $value == 'UNKNOWN' || rfc2445_is_xname($value));
66
-            break;
67
-
68
-            case 'ENCODING':
69
-                $value = strtoupper($value);
70
-                return ($value == '8BIT' || $value == 'BASE64' || rfc2445_is_xname($value));
71
-            break;
72
-
73
-            case 'FBTYPE':
74
-                $value = strtoupper($value);
75
-                return ($value == 'FREE' || $value == 'BUSY' || $value == 'BUSY-UNAVAILABLE' || $value == 'BUSY-TENTATIVE' || rfc2445_is_xname($value));
76
-            break;
77
-
78
-            case 'FMTTYPE':
79
-                $fmttypes = array(
80
-                        'TEXT'        => array('PLAIN', 'RICHTEXT', 'ENRICHED', 'TAB-SEPARATED-VALUES', 'HTML', 'SGML',
81
-                                               'VND.LATEX-Z', 'VND.FMI.FLEXSTOR'),
82
-                        'MULTIPART'   => array('MIXED', 'ALTERNATIVE', 'DIGEST', 'PARALLEL', 'APPLEDOUBLE', 'HEADER-SET',
83
-                                               'FORM-DATA', 'RELATED', 'REPORT', 'VOICE-MESSAGE', 'SIGNED', 'ENCRYPTED',
84
-                                               'BYTERANGES'),
85
-                        'MESSAGE'     => array('RFC822', 'PARTIAL', 'EXTERNAL-BODY', 'NEWS', 'HTTP'),
86
-                        'APPLICATION' => array('OCTET-STREAM', 'POSTSCRIPT', 'ODA', 'ATOMICMAIL', 'ANDREW-INSET', 'SLATE',
87
-                                               'WITA', 'DEC-DX', 'DCA-RFT', 'ACTIVEMESSAGE', 'RTF', 'APPLEFILE',
88
-                                               'MAC-BINHEX40', 'NEWS-MESSAGE-ID', 'NEWS-TRANSMISSION', 'WORDPERFECT5.1',
89
-                                               'PDF', 'ZIP', 'MACWRITEII', 'MSWORD', 'REMOTE-PRINTING', 'MATHEMATICA',
90
-                                               'CYBERCASH', 'COMMONGROUND', 'IGES', 'RISCOS', 'ESHOP', 'X400-BP', 'SGML',
91
-                                               'CALS-1840', 'PGP-ENCRYPTED', 'PGP-SIGNATURE', 'PGP-KEYS', 'VND.FRAMEMAKER',
92
-                                               'VND.MIF', 'VND.MS-EXCEL', 'VND.MS-POWERPOINT', 'VND.MS-PROJECT',
93
-                                               'VND.MS-WORKS', 'VND.MS-TNEF', 'VND.SVD', 'VND.MUSIC-NIFF', 'VND.MS-ARTGALRY',
94
-                                               'VND.TRUEDOC', 'VND.KOAN', 'VND.STREET-STREAM', 'VND.FDF',
95
-                                               'SET-PAYMENT-INITIATION', 'SET-PAYMENT', 'SET-REGISTRATION-INITIATION',
96
-                                               'SET-REGISTRATION', 'VND.SEEMAIL', 'VND.BUSINESSOBJECTS',
97
-                                               'VND.MERIDIAN-SLINGSHOT', 'VND.XARA', 'SGML-OPEN-CATALOG', 'VND.RAPID',
98
-                                               'VND.ENLIVEN', 'VND.JAPANNET-REGISTRATION-WAKEUP', 
99
-                                               'VND.JAPANNET-VERIFICATION-WAKEUP', 'VND.JAPANNET-PAYMENT-WAKEUP',
100
-                                               'VND.JAPANNET-DIRECTORY-SERVICE', 'VND.INTERTRUST.DIGIBOX', 'VND.INTERTRUST.NNCP'),
101
-                        'IMAGE'       => array('JPEG', 'GIF', 'IEF', 'G3FAX', 'TIFF', 'CGM', 'NAPLPS', 'VND.DWG', 'VND.SVF',
102
-                                               'VND.DXF', 'PNG', 'VND.FPX', 'VND.NET-FPX'),
103
-                        'AUDIO'       => array('BASIC', '32KADPCM', 'VND.QCELP'),
104
-                        'VIDEO'       => array('MPEG', 'QUICKTIME', 'VND.VIVO', 'VND.MOTOROLA.VIDEO', 'VND.MOTOROLA.VIDEOP')
105
-                );
106
-                $value = strtoupper($value);
107
-                if(rfc2445_is_xname($value)) {
108
-                    return true;
109
-                }
110
-                @list($type, $subtype) = explode('/', $value);
111
-                if(empty($type) || empty($subtype)) {
112
-                    return false;
113
-                }
114
-                if(!isset($fmttypes[$type]) || !in_array($subtype, $fmttypes[$type])) {
115
-                    return false;
116
-                }
117
-                return true;
118
-            break;
119
-
120
-            case 'LANGUAGE':
121
-                $value = strtoupper($value);
122
-                $parts = explode('-', $value);
123
-                foreach($parts as $part) {
124
-                    if(empty($part)) {
125
-                        return false;
126
-                    }
127
-                    if(strspn($part, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') != strlen($part)) {
128
-                        return false;
129
-                    }
130
-                }
131
-                return true;
132
-            break;
133
-
134
-            case 'PARTSTAT':
135
-                $value = strtoupper($value);
136
-                switch($parent_property->parent_component) {
137
-                    case 'VEVENT':
138
-                        return ($value == 'NEEDS-ACTION' || $value == 'ACCEPTED' || $value == 'DECLINED' || $value == 'TENTATIVE'
139
-                                || $value == 'DELEGATED' || rfc2445_is_xname($value));
140
-                    break;
141
-                    case 'VTODO':
142
-                        return ($value == 'NEEDS-ACTION' || $value == 'ACCEPTED' || $value == 'DECLINED' || $value == 'TENTATIVE'
143
-                                || $value == 'DELEGATED' || $value == 'COMPLETED' || $value == 'IN-PROCESS' || rfc2445_is_xname($value));
144
-                    break;
145
-                    case 'VJOURNAL':
146
-                        return ($value == 'NEEDS-ACTION' || $value == 'ACCEPTED' || $value == 'DECLINED' || rfc2445_is_xname($value));
147
-                    break;
148
-                }
149
-                return false;
150
-            break;
151
-
152
-            case 'RANGE':
153
-                $value = strtoupper($value);
154
-                return ($value == 'THISANDPRIOR' || $value == 'THISANDFUTURE');
155
-            break;
156
-
157
-            case 'RELATED':
158
-                $value = strtoupper($value);
159
-                return ($value == 'START' || $value == 'END');
160
-            break;
161
-
162
-            case 'RELTYPE':
163
-                $value = strtoupper($value);
164
-                return ($value == 'PARENT' || $value == 'CHILD' || $value == 'SIBLING' || rfc2445_is_xname($value));
165
-            break;
166
-
167
-            case 'ROLE':
168
-                $value = strtoupper($value);
169
-                return ($value == 'CHAIR' || $value == 'REQ-PARTICIPANT' || $value == 'OPT-PARTICIPANT' || $value == 'NON-PARTICIPANT' || rfc2445_is_xname($value));
170
-            break;
171
-
172
-            case 'RSVP':
173
-                $value = strtoupper($value);
174
-                return ($value == 'TRUE' || $value == 'FALSE');
175
-            break;
176
-
177
-            case 'TZID':
178
-                if(empty($value)) {
179
-                    return false;
180
-                }
181
-                return (strcspn($value, '";:,') == strlen($value));
182
-            break;
183
-
184
-            case 'VALUE':
185
-                $value = strtoupper($value);
186
-                return ($value == 'BINARY'    || $value == 'BOOLEAN'    || $value == 'CAL-ADDRESS' || $value == 'DATE'    ||
187
-                        $value == 'DATE-TIME' || $value == 'DURATION'   || $value == 'FLOAT'       || $value == 'INTEGER' ||
188
-                        $value == 'PERIOD'    || $value == 'RECUR'      || $value == 'TEXT'        || $value == 'TIME'    ||
189
-                        $value == 'URI'       || $value == 'UTC-OFFSET' || rfc2445_is_xname($value));
190
-            break;
191
-        }
192
-    }
193
-
194
-    function do_value_formatting($parameter, $value) {
195
-        switch($parameter) {
196
-            // Parameters of type CAL-ADDRESS or URI MUST be double-quoted
197
-            case 'ALTREP':
198
-            case 'DIR':
199
-            case 'DELEGATED-FROM':
200
-            case 'DELEGATED-TO':
201
-            case 'MEMBER':
202
-            case 'SENT-BY':
203
-                return '"'.$value.'"';
204
-            break;
205
-
206
-            // Textual parameter types must be double quoted if they contain COLON, SEMICOLON
207
-            // or COMMA. Quoting always sounds easier and standards-conformant though.
208
-            case 'CN':
209
-                return '"'.$value.'"';
210
-            break;
211
-
212
-            // Parameters with enumerated legal values, just make them all caps
213
-            case 'CUTYPE':
214
-            case 'ENCODING':
215
-            case 'FBTYPE':
216
-            case 'FMTTYPE':
217
-            case 'LANGUAGE':
218
-            case 'PARTSTAT':
219
-            case 'RANGE':
220
-            case 'RELATED':
221
-            case 'RELTYPE':
222
-            case 'ROLE':
223
-            case 'RSVP':
224
-            case 'VALUE':
225
-                return strtoupper($value);
226
-            break;
227
-
228
-            // Parameters we shouldn't be messing with
229
-            case 'TZID':
230
-                return $value;
231
-            break;
232
-        }
233
-    }
234
-
235
-    function undo_value_formatting($parameter, $value) {
236
-    }
17
+	function multiple_values_allowed($parameter) {
18
+		switch($parameter) {
19
+			case 'DELEGATED-FROM':
20
+			case 'DELEGATED-TO':
21
+			case 'MEMBER':
22
+				return true;
23
+			default:
24
+				return false;
25
+		}
26
+	}
27
+
28
+	function default_value($parameter) {
29
+		switch($parameter) {
30
+			case 'CUTYPE':   return 'INDIVIDUAL';
31
+			case 'FBTYPE':   return 'BUSY';
32
+			case 'PARTSTAT': return 'NEEDS-ACTION';
33
+			case 'RELATED':  return 'START';
34
+			case 'RELTYPE':  return 'PARENT';
35
+			case 'ROLE':     return 'REQ-PARTICIPANT';
36
+			case 'RSVP':     return 'FALSE';
37
+			default:         return NULL;
38
+		}
39
+	}
40
+
41
+	function is_valid_value(&$parent_property, $parameter, $value) {
42
+		switch($parameter) {
43
+			// These must all be a URI
44
+			case 'ALTREP':
45
+			case 'DIR':
46
+				return rfc2445_is_valid_value($value, RFC2445_TYPE_URI);
47
+			break;
48
+
49
+			// These must be CAL-ADDRESS, which is equivalent to URI
50
+			case 'DELEGATED-FROM':
51
+			case 'DELEGATED-TO':
52
+			case 'MEMBER':
53
+			case 'SENT-BY':
54
+				return rfc2445_is_valid_value($value, RFC2445_TYPE_CAL_ADDRESS);
55
+			break;
56
+
57
+			// These are textual parameters, so the MUST NOT contain double quotes
58
+			case 'CN':
59
+				return (strpos($value, '"') === false);
60
+			break;
61
+
62
+			// These have enumerated legal values
63
+			case 'CUTYPE':
64
+				$value = strtoupper($value);
65
+				return ($value == 'INDIVIDUAL' || $value == 'GROUP' || $value == 'RESOURCE' || $value == 'ROOM' || $value == 'UNKNOWN' || rfc2445_is_xname($value));
66
+			break;
67
+
68
+			case 'ENCODING':
69
+				$value = strtoupper($value);
70
+				return ($value == '8BIT' || $value == 'BASE64' || rfc2445_is_xname($value));
71
+			break;
72
+
73
+			case 'FBTYPE':
74
+				$value = strtoupper($value);
75
+				return ($value == 'FREE' || $value == 'BUSY' || $value == 'BUSY-UNAVAILABLE' || $value == 'BUSY-TENTATIVE' || rfc2445_is_xname($value));
76
+			break;
77
+
78
+			case 'FMTTYPE':
79
+				$fmttypes = array(
80
+						'TEXT'        => array('PLAIN', 'RICHTEXT', 'ENRICHED', 'TAB-SEPARATED-VALUES', 'HTML', 'SGML',
81
+											   'VND.LATEX-Z', 'VND.FMI.FLEXSTOR'),
82
+						'MULTIPART'   => array('MIXED', 'ALTERNATIVE', 'DIGEST', 'PARALLEL', 'APPLEDOUBLE', 'HEADER-SET',
83
+											   'FORM-DATA', 'RELATED', 'REPORT', 'VOICE-MESSAGE', 'SIGNED', 'ENCRYPTED',
84
+											   'BYTERANGES'),
85
+						'MESSAGE'     => array('RFC822', 'PARTIAL', 'EXTERNAL-BODY', 'NEWS', 'HTTP'),
86
+						'APPLICATION' => array('OCTET-STREAM', 'POSTSCRIPT', 'ODA', 'ATOMICMAIL', 'ANDREW-INSET', 'SLATE',
87
+											   'WITA', 'DEC-DX', 'DCA-RFT', 'ACTIVEMESSAGE', 'RTF', 'APPLEFILE',
88
+											   'MAC-BINHEX40', 'NEWS-MESSAGE-ID', 'NEWS-TRANSMISSION', 'WORDPERFECT5.1',
89
+											   'PDF', 'ZIP', 'MACWRITEII', 'MSWORD', 'REMOTE-PRINTING', 'MATHEMATICA',
90
+											   'CYBERCASH', 'COMMONGROUND', 'IGES', 'RISCOS', 'ESHOP', 'X400-BP', 'SGML',
91
+											   'CALS-1840', 'PGP-ENCRYPTED', 'PGP-SIGNATURE', 'PGP-KEYS', 'VND.FRAMEMAKER',
92
+											   'VND.MIF', 'VND.MS-EXCEL', 'VND.MS-POWERPOINT', 'VND.MS-PROJECT',
93
+											   'VND.MS-WORKS', 'VND.MS-TNEF', 'VND.SVD', 'VND.MUSIC-NIFF', 'VND.MS-ARTGALRY',
94
+											   'VND.TRUEDOC', 'VND.KOAN', 'VND.STREET-STREAM', 'VND.FDF',
95
+											   'SET-PAYMENT-INITIATION', 'SET-PAYMENT', 'SET-REGISTRATION-INITIATION',
96
+											   'SET-REGISTRATION', 'VND.SEEMAIL', 'VND.BUSINESSOBJECTS',
97
+											   'VND.MERIDIAN-SLINGSHOT', 'VND.XARA', 'SGML-OPEN-CATALOG', 'VND.RAPID',
98
+											   'VND.ENLIVEN', 'VND.JAPANNET-REGISTRATION-WAKEUP', 
99
+											   'VND.JAPANNET-VERIFICATION-WAKEUP', 'VND.JAPANNET-PAYMENT-WAKEUP',
100
+											   'VND.JAPANNET-DIRECTORY-SERVICE', 'VND.INTERTRUST.DIGIBOX', 'VND.INTERTRUST.NNCP'),
101
+						'IMAGE'       => array('JPEG', 'GIF', 'IEF', 'G3FAX', 'TIFF', 'CGM', 'NAPLPS', 'VND.DWG', 'VND.SVF',
102
+											   'VND.DXF', 'PNG', 'VND.FPX', 'VND.NET-FPX'),
103
+						'AUDIO'       => array('BASIC', '32KADPCM', 'VND.QCELP'),
104
+						'VIDEO'       => array('MPEG', 'QUICKTIME', 'VND.VIVO', 'VND.MOTOROLA.VIDEO', 'VND.MOTOROLA.VIDEOP')
105
+				);
106
+				$value = strtoupper($value);
107
+				if(rfc2445_is_xname($value)) {
108
+					return true;
109
+				}
110
+				@list($type, $subtype) = explode('/', $value);
111
+				if(empty($type) || empty($subtype)) {
112
+					return false;
113
+				}
114
+				if(!isset($fmttypes[$type]) || !in_array($subtype, $fmttypes[$type])) {
115
+					return false;
116
+				}
117
+				return true;
118
+			break;
119
+
120
+			case 'LANGUAGE':
121
+				$value = strtoupper($value);
122
+				$parts = explode('-', $value);
123
+				foreach($parts as $part) {
124
+					if(empty($part)) {
125
+						return false;
126
+					}
127
+					if(strspn($part, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') != strlen($part)) {
128
+						return false;
129
+					}
130
+				}
131
+				return true;
132
+			break;
133
+
134
+			case 'PARTSTAT':
135
+				$value = strtoupper($value);
136
+				switch($parent_property->parent_component) {
137
+					case 'VEVENT':
138
+						return ($value == 'NEEDS-ACTION' || $value == 'ACCEPTED' || $value == 'DECLINED' || $value == 'TENTATIVE'
139
+								|| $value == 'DELEGATED' || rfc2445_is_xname($value));
140
+					break;
141
+					case 'VTODO':
142
+						return ($value == 'NEEDS-ACTION' || $value == 'ACCEPTED' || $value == 'DECLINED' || $value == 'TENTATIVE'
143
+								|| $value == 'DELEGATED' || $value == 'COMPLETED' || $value == 'IN-PROCESS' || rfc2445_is_xname($value));
144
+					break;
145
+					case 'VJOURNAL':
146
+						return ($value == 'NEEDS-ACTION' || $value == 'ACCEPTED' || $value == 'DECLINED' || rfc2445_is_xname($value));
147
+					break;
148
+				}
149
+				return false;
150
+			break;
151
+
152
+			case 'RANGE':
153
+				$value = strtoupper($value);
154
+				return ($value == 'THISANDPRIOR' || $value == 'THISANDFUTURE');
155
+			break;
156
+
157
+			case 'RELATED':
158
+				$value = strtoupper($value);
159
+				return ($value == 'START' || $value == 'END');
160
+			break;
161
+
162
+			case 'RELTYPE':
163
+				$value = strtoupper($value);
164
+				return ($value == 'PARENT' || $value == 'CHILD' || $value == 'SIBLING' || rfc2445_is_xname($value));
165
+			break;
166
+
167
+			case 'ROLE':
168
+				$value = strtoupper($value);
169
+				return ($value == 'CHAIR' || $value == 'REQ-PARTICIPANT' || $value == 'OPT-PARTICIPANT' || $value == 'NON-PARTICIPANT' || rfc2445_is_xname($value));
170
+			break;
171
+
172
+			case 'RSVP':
173
+				$value = strtoupper($value);
174
+				return ($value == 'TRUE' || $value == 'FALSE');
175
+			break;
176
+
177
+			case 'TZID':
178
+				if(empty($value)) {
179
+					return false;
180
+				}
181
+				return (strcspn($value, '";:,') == strlen($value));
182
+			break;
183
+
184
+			case 'VALUE':
185
+				$value = strtoupper($value);
186
+				return ($value == 'BINARY'    || $value == 'BOOLEAN'    || $value == 'CAL-ADDRESS' || $value == 'DATE'    ||
187
+						$value == 'DATE-TIME' || $value == 'DURATION'   || $value == 'FLOAT'       || $value == 'INTEGER' ||
188
+						$value == 'PERIOD'    || $value == 'RECUR'      || $value == 'TEXT'        || $value == 'TIME'    ||
189
+						$value == 'URI'       || $value == 'UTC-OFFSET' || rfc2445_is_xname($value));
190
+			break;
191
+		}
192
+	}
193
+
194
+	function do_value_formatting($parameter, $value) {
195
+		switch($parameter) {
196
+			// Parameters of type CAL-ADDRESS or URI MUST be double-quoted
197
+			case 'ALTREP':
198
+			case 'DIR':
199
+			case 'DELEGATED-FROM':
200
+			case 'DELEGATED-TO':
201
+			case 'MEMBER':
202
+			case 'SENT-BY':
203
+				return '"'.$value.'"';
204
+			break;
205
+
206
+			// Textual parameter types must be double quoted if they contain COLON, SEMICOLON
207
+			// or COMMA. Quoting always sounds easier and standards-conformant though.
208
+			case 'CN':
209
+				return '"'.$value.'"';
210
+			break;
211
+
212
+			// Parameters with enumerated legal values, just make them all caps
213
+			case 'CUTYPE':
214
+			case 'ENCODING':
215
+			case 'FBTYPE':
216
+			case 'FMTTYPE':
217
+			case 'LANGUAGE':
218
+			case 'PARTSTAT':
219
+			case 'RANGE':
220
+			case 'RELATED':
221
+			case 'RELTYPE':
222
+			case 'ROLE':
223
+			case 'RSVP':
224
+			case 'VALUE':
225
+				return strtoupper($value);
226
+			break;
227
+
228
+			// Parameters we shouldn't be messing with
229
+			case 'TZID':
230
+				return $value;
231
+			break;
232
+		}
233
+	}
234
+
235
+	function undo_value_formatting($parameter, $value) {
236
+	}
237 237
 }
238 238
 
239 239
 ?>
Please login to merge, or discard this patch.
Spacing   +16 added lines, -16 removed lines patch added patch discarded remove patch
@@ -15,7 +15,7 @@  discard block
 block discarded – undo
15 15
 
16 16
 class iCalendar_parameter {
17 17
     function multiple_values_allowed($parameter) {
18
-        switch($parameter) {
18
+        switch ($parameter) {
19 19
             case 'DELEGATED-FROM':
20 20
             case 'DELEGATED-TO':
21 21
             case 'MEMBER':
@@ -26,7 +26,7 @@  discard block
 block discarded – undo
26 26
     }
27 27
 
28 28
     function default_value($parameter) {
29
-        switch($parameter) {
29
+        switch ($parameter) {
30 30
             case 'CUTYPE':   return 'INDIVIDUAL';
31 31
             case 'FBTYPE':   return 'BUSY';
32 32
             case 'PARTSTAT': return 'NEEDS-ACTION';
@@ -39,7 +39,7 @@  discard block
 block discarded – undo
39 39
     }
40 40
 
41 41
     function is_valid_value(&$parent_property, $parameter, $value) {
42
-        switch($parameter) {
42
+        switch ($parameter) {
43 43
             // These must all be a URI
44 44
             case 'ALTREP':
45 45
             case 'DIR':
@@ -104,14 +104,14 @@  discard block
 block discarded – undo
104 104
                         'VIDEO'       => array('MPEG', 'QUICKTIME', 'VND.VIVO', 'VND.MOTOROLA.VIDEO', 'VND.MOTOROLA.VIDEOP')
105 105
                 );
106 106
                 $value = strtoupper($value);
107
-                if(rfc2445_is_xname($value)) {
107
+                if (rfc2445_is_xname($value)) {
108 108
                     return true;
109 109
                 }
110 110
                 @list($type, $subtype) = explode('/', $value);
111
-                if(empty($type) || empty($subtype)) {
111
+                if (empty($type) || empty($subtype)) {
112 112
                     return false;
113 113
                 }
114
-                if(!isset($fmttypes[$type]) || !in_array($subtype, $fmttypes[$type])) {
114
+                if (!isset($fmttypes[$type]) || !in_array($subtype, $fmttypes[$type])) {
115 115
                     return false;
116 116
                 }
117 117
                 return true;
@@ -120,11 +120,11 @@  discard block
 block discarded – undo
120 120
             case 'LANGUAGE':
121 121
                 $value = strtoupper($value);
122 122
                 $parts = explode('-', $value);
123
-                foreach($parts as $part) {
124
-                    if(empty($part)) {
123
+                foreach ($parts as $part) {
124
+                    if (empty($part)) {
125 125
                         return false;
126 126
                     }
127
-                    if(strspn($part, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') != strlen($part)) {
127
+                    if (strspn($part, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') != strlen($part)) {
128 128
                         return false;
129 129
                     }
130 130
                 }
@@ -133,7 +133,7 @@  discard block
 block discarded – undo
133 133
 
134 134
             case 'PARTSTAT':
135 135
                 $value = strtoupper($value);
136
-                switch($parent_property->parent_component) {
136
+                switch ($parent_property->parent_component) {
137 137
                     case 'VEVENT':
138 138
                         return ($value == 'NEEDS-ACTION' || $value == 'ACCEPTED' || $value == 'DECLINED' || $value == 'TENTATIVE'
139 139
                                 || $value == 'DELEGATED' || rfc2445_is_xname($value));
@@ -175,7 +175,7 @@  discard block
 block discarded – undo
175 175
             break;
176 176
 
177 177
             case 'TZID':
178
-                if(empty($value)) {
178
+                if (empty($value)) {
179 179
                     return false;
180 180
                 }
181 181
                 return (strcspn($value, '";:,') == strlen($value));
@@ -183,16 +183,16 @@  discard block
 block discarded – undo
183 183
 
184 184
             case 'VALUE':
185 185
                 $value = strtoupper($value);
186
-                return ($value == 'BINARY'    || $value == 'BOOLEAN'    || $value == 'CAL-ADDRESS' || $value == 'DATE'    ||
187
-                        $value == 'DATE-TIME' || $value == 'DURATION'   || $value == 'FLOAT'       || $value == 'INTEGER' ||
188
-                        $value == 'PERIOD'    || $value == 'RECUR'      || $value == 'TEXT'        || $value == 'TIME'    ||
189
-                        $value == 'URI'       || $value == 'UTC-OFFSET' || rfc2445_is_xname($value));
186
+                return ($value == 'BINARY' || $value == 'BOOLEAN' || $value == 'CAL-ADDRESS' || $value == 'DATE' ||
187
+                        $value == 'DATE-TIME' || $value == 'DURATION' || $value == 'FLOAT' || $value == 'INTEGER' ||
188
+                        $value == 'PERIOD' || $value == 'RECUR' || $value == 'TEXT' || $value == 'TIME' ||
189
+                        $value == 'URI' || $value == 'UTC-OFFSET' || rfc2445_is_xname($value));
190 190
             break;
191 191
         }
192 192
     }
193 193
 
194 194
     function do_value_formatting($parameter, $value) {
195
-        switch($parameter) {
195
+        switch ($parameter) {
196 196
             // Parameters of type CAL-ADDRESS or URI MUST be double-quoted
197 197
             case 'ALTREP':
198 198
             case 'DIR':
Please login to merge, or discard this patch.
phpicalendar/lib/bennu/iCalendar_properties.php 4 patches
Doc Comments   +7 added lines patch added patch discarded remove patch
@@ -35,6 +35,10 @@  discard block
 block discarded – undo
35 35
 
36 36
     // If some property needs extra care with its parameters, override this
37 37
     // IMPORTANT: the parameter name MUST BE CAPITALIZED!
38
+
39
+    /**
40
+     * @param string $parameter
41
+     */
38 42
     function is_valid_parameter($parameter, $value) {
39 43
 
40 44
         if(is_array($value)) {
@@ -1129,6 +1133,9 @@  discard block
 block discarded – undo
1129 1133
         );
1130 1134
     }
1131 1135
 
1136
+    /**
1137
+     * @param string $name
1138
+     */
1132 1139
     function set_name($name) {
1133 1140
 
1134 1141
         $name = strtoupper($name);
Please login to merge, or discard this patch.
Indentation   +960 added lines, -960 removed lines patch added patch discarded remove patch
@@ -14,203 +14,203 @@  discard block
 block discarded – undo
14 14
  */
15 15
 
16 16
 class iCalendar_property {
17
-    // Properties can have parameters, but cannot have other properties or components
18
-
19
-    var $parent_component = NULL;
20
-    var $value            = NULL;
21
-    var $parameters       = NULL;
22
-    var $valid_parameters = NULL;
23
-
24
-    // These are common for 95% of properties, so define them here and override as necessary
25
-    var $val_multi        = false;
26
-    var $val_default      = NULL;
27
-
28
-    function iCalendar_property() {
29
-        $this->construct();
30
-    }
31
-
32
-    function construct() {
33
-        $this->parameters = array();
34
-    }
35
-
36
-    // If some property needs extra care with its parameters, override this
37
-    // IMPORTANT: the parameter name MUST BE CAPITALIZED!
38
-    function is_valid_parameter($parameter, $value) {
39
-
40
-        if(is_array($value)) {
41
-            if(!iCalendar_parameter::multiple_values_allowed($parameter)) {
42
-                return false;
43
-            }
44
-            foreach($value as $item) {
45
-                if(!iCalendar_parameter::is_valid_value($this, $parameter, $item)) {
46
-                    return false;
47
-                }
48
-            }
49
-            return true;
50
-        }
51
-
52
-        return iCalendar_parameter::is_valid_value($this, $parameter, $value);
53
-    }
54
-
55
-    function invariant_holds() {
56
-        return true;
57
-    }
58
-
59
-    // If some property is very picky about its values, it should do the work itself
60
-    // Only data type validation is done here
61
-    function is_valid_value($value) {
62
-        if(is_array($value)) {
63
-            if(!$this->val_multi) {
64
-                return false;
65
-            }
66
-            else {
67
-                foreach($value as $oneval) {
68
-                    if(!rfc2445_is_valid_value($oneval, $this->val_type)) {
69
-                        return false;
70
-                    }
71
-                }
72
-            }
73
-            return true;
74
-        }
75
-        return rfc2445_is_valid_value($value, $this->val_type);
76
-    }
77
-
78
-    function default_value() {
79
-        return $this->val_default;
80
-    }
81
-
82
-    function set_parent_component($componentname) {
83
-        if(class_exists('iCalendar_'.strtolower(substr($componentname, 1)))) {
84
-            $this->parent_component = strtoupper($componentname);
85
-            return true;
86
-        }
87
-
88
-        return false;
89
-    }
90
-
91
-    function set_value($value) {
92
-        if($this->is_valid_value($value)) {
93
-            // This transparently formats any value type according to the iCalendar specs
94
-            if(is_array($value)) {
95
-                foreach($value as $key => $item) {
96
-                    $value[$key] = rfc2445_do_value_formatting($item, $this->val_type);
97
-                }
98
-                $this->value = implode(',', $value);
99
-            }
100
-            else {
101
-                $this->value = rfc2445_do_value_formatting($value, $this->val_type);
102
-            }
17
+	// Properties can have parameters, but cannot have other properties or components
18
+
19
+	var $parent_component = NULL;
20
+	var $value            = NULL;
21
+	var $parameters       = NULL;
22
+	var $valid_parameters = NULL;
23
+
24
+	// These are common for 95% of properties, so define them here and override as necessary
25
+	var $val_multi        = false;
26
+	var $val_default      = NULL;
27
+
28
+	function iCalendar_property() {
29
+		$this->construct();
30
+	}
31
+
32
+	function construct() {
33
+		$this->parameters = array();
34
+	}
35
+
36
+	// If some property needs extra care with its parameters, override this
37
+	// IMPORTANT: the parameter name MUST BE CAPITALIZED!
38
+	function is_valid_parameter($parameter, $value) {
39
+
40
+		if(is_array($value)) {
41
+			if(!iCalendar_parameter::multiple_values_allowed($parameter)) {
42
+				return false;
43
+			}
44
+			foreach($value as $item) {
45
+				if(!iCalendar_parameter::is_valid_value($this, $parameter, $item)) {
46
+					return false;
47
+				}
48
+			}
49
+			return true;
50
+		}
51
+
52
+		return iCalendar_parameter::is_valid_value($this, $parameter, $value);
53
+	}
54
+
55
+	function invariant_holds() {
56
+		return true;
57
+	}
58
+
59
+	// If some property is very picky about its values, it should do the work itself
60
+	// Only data type validation is done here
61
+	function is_valid_value($value) {
62
+		if(is_array($value)) {
63
+			if(!$this->val_multi) {
64
+				return false;
65
+			}
66
+			else {
67
+				foreach($value as $oneval) {
68
+					if(!rfc2445_is_valid_value($oneval, $this->val_type)) {
69
+						return false;
70
+					}
71
+				}
72
+			}
73
+			return true;
74
+		}
75
+		return rfc2445_is_valid_value($value, $this->val_type);
76
+	}
77
+
78
+	function default_value() {
79
+		return $this->val_default;
80
+	}
81
+
82
+	function set_parent_component($componentname) {
83
+		if(class_exists('iCalendar_'.strtolower(substr($componentname, 1)))) {
84
+			$this->parent_component = strtoupper($componentname);
85
+			return true;
86
+		}
87
+
88
+		return false;
89
+	}
90
+
91
+	function set_value($value) {
92
+		if($this->is_valid_value($value)) {
93
+			// This transparently formats any value type according to the iCalendar specs
94
+			if(is_array($value)) {
95
+				foreach($value as $key => $item) {
96
+					$value[$key] = rfc2445_do_value_formatting($item, $this->val_type);
97
+				}
98
+				$this->value = implode(',', $value);
99
+			}
100
+			else {
101
+				$this->value = rfc2445_do_value_formatting($value, $this->val_type);
102
+			}
103 103
             
104
-            return true;
105
-        }
106
-        return false;
107
-    }
108
-
109
-    function get_value() {
110
-        // First of all, assume that we have multiple values
111
-        $valarray = explode('\\,', $this->value);
112
-
113
-        // Undo transparent formatting
114
-        $replace_function = create_function('$a', 'return rfc2445_undo_value_formatting($a, '.$this->val_type.');');
115
-        $valarray = array_map($replace_function, $valarray);
116
-
117
-        // Now, if this property cannot have multiple values, don't return as an array
118
-        if(!$this->val_multi) {
119
-            return $valarray[0];
120
-        }
121
-
122
-        // Otherwise return an array even if it has one element, for uniformity
123
-        return $valarray;
124
-
125
-    }
126
-
127
-    function set_parameter($name, $value) {
128
-
129
-        // Uppercase
130
-        $name = strtoupper($name);
131
-
132
-        // Are we trying to add a valid parameter?
133
-        $xname = false;
134
-        if(!isset($this->valid_parameters[$name])) {
135
-            // If not, is it an x-name as per RFC 2445?
136
-            if(!rfc2445_is_xname($name)) {
137
-                return false;
138
-            }
139
-            // No more checks -- all components are supposed to allow x-name parameters
140
-            $xname = true;
141
-        }
142
-
143
-        if(!$this->is_valid_parameter($name, $value)) {
144
-            return false;
145
-        }
146
-
147
-        if(is_array($value)) {
148
-            foreach($value as $key => $element) {
149
-                $value[$key] = iCalendar_parameter::do_value_formatting($name, $element);
150
-            }
151
-        }
152
-        else {
153
-            $value = iCalendar_parameter::do_value_formatting($name, $value);
154
-        }
155
-
156
-        $this->parameters[$name] = $value;
157
-
158
-        // Special case: if we just changed the VALUE parameter, reflect this
159
-        // in the object's status so that it only accepts correct type values
160
-        if($name == 'VALUE') {
161
-            // TODO: what if this invalidates an already-set value?
162
-            $this->val_type = constant('RFC2445_TYPE_'.str_replace('-', '_', $value));
163
-        }
164
-
165
-        return true;
166
-
167
-    }
168
-
169
-    function get_parameter($name) {
170
-
171
-        // Uppercase
172
-        $name = strtoupper($name);
173
-
174
-        if(isset($this->parameters[$name])) {
175
-            // If there are any double quotes in the value, invisibly strip them
176
-            if(is_array($this->parameters[$name])) {
177
-                foreach($this->parameters[$name] as $key => $value) {
178
-                    if(substr($value, 0, 1) == '"') {
179
-                       $this->parameters[$name][$key] = substr($value, 1, strlen($value) - 2);
180
-                    }
181
-                }
182
-                return $this->parameters[$name];
183
-            }
184
-
185
-            else {
186
-                if(substr($this->parameters[$name], 0, 1) == '"') {
187
-                    return substr($this->parameters[$name], 1, strlen($this->parameters[$name]) - 2);
188
-                }
189
-            }
190
-        }
191
-
192
-        return NULL;
193
-    }
194
-
195
-    function serialize() {
196
-        $string = $this->name;
197
-
198
-        if(!empty($this->parameters)) {
199
-            foreach($this->parameters as $name => $value) {
200
-                $string .= ';'.$name.'=';
201
-                if(is_array($value)) {
202
-                    $string .= implode(',', $value);
203
-                }
204
-                else {
205
-                    $string .= $value;
206
-                }
207
-            }
208
-        }
209
-
210
-        $string .= ':'.$this->value;
211
-
212
-        return rfc2445_fold($string) . RFC2445_CRLF;
213
-    }
104
+			return true;
105
+		}
106
+		return false;
107
+	}
108
+
109
+	function get_value() {
110
+		// First of all, assume that we have multiple values
111
+		$valarray = explode('\\,', $this->value);
112
+
113
+		// Undo transparent formatting
114
+		$replace_function = create_function('$a', 'return rfc2445_undo_value_formatting($a, '.$this->val_type.');');
115
+		$valarray = array_map($replace_function, $valarray);
116
+
117
+		// Now, if this property cannot have multiple values, don't return as an array
118
+		if(!$this->val_multi) {
119
+			return $valarray[0];
120
+		}
121
+
122
+		// Otherwise return an array even if it has one element, for uniformity
123
+		return $valarray;
124
+
125
+	}
126
+
127
+	function set_parameter($name, $value) {
128
+
129
+		// Uppercase
130
+		$name = strtoupper($name);
131
+
132
+		// Are we trying to add a valid parameter?
133
+		$xname = false;
134
+		if(!isset($this->valid_parameters[$name])) {
135
+			// If not, is it an x-name as per RFC 2445?
136
+			if(!rfc2445_is_xname($name)) {
137
+				return false;
138
+			}
139
+			// No more checks -- all components are supposed to allow x-name parameters
140
+			$xname = true;
141
+		}
142
+
143
+		if(!$this->is_valid_parameter($name, $value)) {
144
+			return false;
145
+		}
146
+
147
+		if(is_array($value)) {
148
+			foreach($value as $key => $element) {
149
+				$value[$key] = iCalendar_parameter::do_value_formatting($name, $element);
150
+			}
151
+		}
152
+		else {
153
+			$value = iCalendar_parameter::do_value_formatting($name, $value);
154
+		}
155
+
156
+		$this->parameters[$name] = $value;
157
+
158
+		// Special case: if we just changed the VALUE parameter, reflect this
159
+		// in the object's status so that it only accepts correct type values
160
+		if($name == 'VALUE') {
161
+			// TODO: what if this invalidates an already-set value?
162
+			$this->val_type = constant('RFC2445_TYPE_'.str_replace('-', '_', $value));
163
+		}
164
+
165
+		return true;
166
+
167
+	}
168
+
169
+	function get_parameter($name) {
170
+
171
+		// Uppercase
172
+		$name = strtoupper($name);
173
+
174
+		if(isset($this->parameters[$name])) {
175
+			// If there are any double quotes in the value, invisibly strip them
176
+			if(is_array($this->parameters[$name])) {
177
+				foreach($this->parameters[$name] as $key => $value) {
178
+					if(substr($value, 0, 1) == '"') {
179
+					   $this->parameters[$name][$key] = substr($value, 1, strlen($value) - 2);
180
+					}
181
+				}
182
+				return $this->parameters[$name];
183
+			}
184
+
185
+			else {
186
+				if(substr($this->parameters[$name], 0, 1) == '"') {
187
+					return substr($this->parameters[$name], 1, strlen($this->parameters[$name]) - 2);
188
+				}
189
+			}
190
+		}
191
+
192
+		return NULL;
193
+	}
194
+
195
+	function serialize() {
196
+		$string = $this->name;
197
+
198
+		if(!empty($this->parameters)) {
199
+			foreach($this->parameters as $name => $value) {
200
+				$string .= ';'.$name.'=';
201
+				if(is_array($value)) {
202
+					$string .= implode(',', $value);
203
+				}
204
+				else {
205
+					$string .= $value;
206
+				}
207
+			}
208
+		}
209
+
210
+		$string .= ':'.$this->value;
211
+
212
+		return rfc2445_fold($string) . RFC2445_CRLF;
213
+	}
214 214
 }
215 215
 
216 216
 // 4.7 Calendar Properties
@@ -218,70 +218,70 @@  discard block
 block discarded – undo
218 218
 
219 219
 class iCalendar_property_calscale extends iCalendar_property {
220 220
 
221
-    var $name        = 'CALSCALE';
222
-    var $val_type    = RFC2445_TYPE_TEXT;
221
+	var $name        = 'CALSCALE';
222
+	var $val_type    = RFC2445_TYPE_TEXT;
223 223
 
224
-    function construct() {
225
-        $this->valid_parameters = array(
226
-            RFC2445_XNAME => RFC2445_OPTIONAL
227
-        );
228
-    }
224
+	function construct() {
225
+		$this->valid_parameters = array(
226
+			RFC2445_XNAME => RFC2445_OPTIONAL
227
+		);
228
+	}
229 229
 
230
-    function is_valid_value($value) {
231
-        // This is case-sensitive
232
-        return ($value === 'GREGORIAN');
233
-    }
230
+	function is_valid_value($value) {
231
+		// This is case-sensitive
232
+		return ($value === 'GREGORIAN');
233
+	}
234 234
 }
235 235
 
236 236
 class iCalendar_property_method extends iCalendar_property {
237 237
 
238
-    var $name        = 'METHOD';
239
-    var $val_type    = RFC2445_TYPE_TEXT;
240
-
241
-    function construct() {
242
-        $this->valid_parameters = array(
243
-            RFC2445_XNAME => RFC2445_OPTIONAL
244
-        );
245
-    }
246
-
247
-    function is_valid_value($value) {
248
-        // This is case-sensitive
249
-        // Methods from RFC 2446
250
-        $methods = array('PUBLISH', 'REQUEST', 'REPLY', 'ADD', 'CANCEL', 'REFRESH', 'COUNTER', 'DECLINECOUNTER');
251
-        return in_array($value, $methods);
252
-    }
238
+	var $name        = 'METHOD';
239
+	var $val_type    = RFC2445_TYPE_TEXT;
240
+
241
+	function construct() {
242
+		$this->valid_parameters = array(
243
+			RFC2445_XNAME => RFC2445_OPTIONAL
244
+		);
245
+	}
246
+
247
+	function is_valid_value($value) {
248
+		// This is case-sensitive
249
+		// Methods from RFC 2446
250
+		$methods = array('PUBLISH', 'REQUEST', 'REPLY', 'ADD', 'CANCEL', 'REFRESH', 'COUNTER', 'DECLINECOUNTER');
251
+		return in_array($value, $methods);
252
+	}
253 253
 }
254 254
 
255 255
 class iCalendar_property_prodid extends iCalendar_property {
256 256
 
257
-    var $name        = 'PRODID';
258
-    var $val_type    = RFC2445_TYPE_TEXT;
259
-    var $val_default = NULL;
257
+	var $name        = 'PRODID';
258
+	var $val_type    = RFC2445_TYPE_TEXT;
259
+	var $val_default = NULL;
260 260
 
261
-    function construct() {
262
-        $this->val_default = '-//John Papaioannou/NONSGML Bennu '._BENNU_VERSION.'//EN';
261
+	function construct() {
262
+		$this->val_default = '-//John Papaioannou/NONSGML Bennu '._BENNU_VERSION.'//EN';
263 263
 
264
-        $this->valid_parameters = array(
265
-            RFC2445_XNAME => RFC2445_OPTIONAL
266
-        );
267
-    }
264
+		$this->valid_parameters = array(
265
+			RFC2445_XNAME => RFC2445_OPTIONAL
266
+		);
267
+	}
268 268
 }
269 269
 
270 270
 class iCalendar_property_version extends iCalendar_property {
271 271
 
272
-    var $name        = 'VERSION';
273
-    var $val_type    = RFC2445_TYPE_TEXT;
274
-    var $val_default = '2.0';
272
+	var $name        = 'VERSION';
273
+	var $val_type    = RFC2445_TYPE_TEXT;
274
+	var $val_default = '2.0';
275 275
 
276
-    function construct() {
277
-        $this->valid_parameters = array(
278
-            RFC2445_XNAME => RFC2445_OPTIONAL
279
-        );
280
-    }
276
+	function construct() {
277
+		$this->valid_parameters = array(
278
+			RFC2445_XNAME => RFC2445_OPTIONAL
279
+		);
280
+	}
281 281
 
282
-    function is_valid_value($value) {
283
-        return($value === '2.0' || $value === 2.0);
284
-    }
282
+	function is_valid_value($value) {
283
+		return($value === '2.0' || $value === 2.0);
284
+	}
285 285
 }
286 286
 
287 287
 // 4.8.1 Descriptive Component Properties
@@ -289,261 +289,261 @@  discard block
 block discarded – undo
289 289
 
290 290
 class iCalendar_property_attach extends iCalendar_property {
291 291
 
292
-    var $name        = 'ATTACH';
293
-    var $val_type    = RFC2445_TYPE_URI;
292
+	var $name        = 'ATTACH';
293
+	var $val_type    = RFC2445_TYPE_URI;
294 294
 
295
-    function construct() {
296
-        $this->valid_parameters = array(
297
-            'FMTTYPE'     => RFC2445_OPTIONAL | RFC2445_ONCE,
298
-            'ENCODING'    => RFC2445_OPTIONAL | RFC2445_ONCE,
299
-            'VALUE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
300
-            RFC2445_XNAME => RFC2445_OPTIONAL
301
-        );
302
-    }
295
+	function construct() {
296
+		$this->valid_parameters = array(
297
+			'FMTTYPE'     => RFC2445_OPTIONAL | RFC2445_ONCE,
298
+			'ENCODING'    => RFC2445_OPTIONAL | RFC2445_ONCE,
299
+			'VALUE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
300
+			RFC2445_XNAME => RFC2445_OPTIONAL
301
+		);
302
+	}
303 303
 
304
-    function invariant_holds() {
305
-        if(isset($this->parameters['ENCODING']) && !isset($this->parameters['VALUE'])) {
306
-            return false;
307
-        }
308
-        if(isset($this->parameters['VALUE']) && !isset($this->parameters['ENCODING'])) {
309
-            return false;
310
-        }
304
+	function invariant_holds() {
305
+		if(isset($this->parameters['ENCODING']) && !isset($this->parameters['VALUE'])) {
306
+			return false;
307
+		}
308
+		if(isset($this->parameters['VALUE']) && !isset($this->parameters['ENCODING'])) {
309
+			return false;
310
+		}
311 311
 
312
-        return true;
313
-    }
312
+		return true;
313
+	}
314 314
 
315
-    function is_valid_parameter($parameter, $value) {
315
+	function is_valid_parameter($parameter, $value) {
316 316
 
317
-        $parameter = strtoupper($parameter);
317
+		$parameter = strtoupper($parameter);
318 318
 
319
-        if(!parent::is_valid_parameter($parameter, $value)) {
320
-            return false;
321
-        }
319
+		if(!parent::is_valid_parameter($parameter, $value)) {
320
+			return false;
321
+		}
322 322
 
323
-        if($parameter === 'ENCODING' && strtoupper($value) != 'BASE64') {
324
-            return false;
325
-        }
323
+		if($parameter === 'ENCODING' && strtoupper($value) != 'BASE64') {
324
+			return false;
325
+		}
326 326
 
327
-        if($parameter === 'VALUE' && strtoupper($value) != 'BINARY') {
328
-            return false;
329
-        }
327
+		if($parameter === 'VALUE' && strtoupper($value) != 'BINARY') {
328
+			return false;
329
+		}
330 330
 
331
-        return true;
332
-    }
331
+		return true;
332
+	}
333 333
 }
334 334
 
335 335
 class iCalendar_property_categories extends iCalendar_property {
336 336
 
337
-    var $name        = 'CATEGORIES';
338
-    var $val_type    = RFC2445_TYPE_TEXT;
339
-    var $val_multi   = true;
337
+	var $name        = 'CATEGORIES';
338
+	var $val_type    = RFC2445_TYPE_TEXT;
339
+	var $val_multi   = true;
340 340
 
341
-    function construct() {
342
-        $this->valid_parameters = array(
343
-            'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
344
-            RFC2445_XNAME => RFC2445_OPTIONAL
345
-        );
346
-    }
341
+	function construct() {
342
+		$this->valid_parameters = array(
343
+			'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
344
+			RFC2445_XNAME => RFC2445_OPTIONAL
345
+		);
346
+	}
347 347
 }
348 348
 
349 349
 class iCalendar_property_class extends iCalendar_property {
350 350
 
351
-    var $name        = 'CLASS';
352
-    var $val_type    = RFC2445_TYPE_TEXT;
353
-    var $val_default = 'PUBLIC';
351
+	var $name        = 'CLASS';
352
+	var $val_type    = RFC2445_TYPE_TEXT;
353
+	var $val_default = 'PUBLIC';
354 354
 
355
-    function construct() {
356
-        $this->valid_parameters = array(
357
-            RFC2445_XNAME => RFC2445_OPTIONAL
358
-        );
359
-    }
355
+	function construct() {
356
+		$this->valid_parameters = array(
357
+			RFC2445_XNAME => RFC2445_OPTIONAL
358
+		);
359
+	}
360 360
 
361
-    function is_valid_value($value) {
362
-        // If this is not an xname, it is case-sensitive
363
-        return ($value === 'PUBLIC' || $value === 'PRIVATE' || $value === 'CONFIDENTIAL' || rfc2445_is_xname(strtoupper($value)));
364
-    }
361
+	function is_valid_value($value) {
362
+		// If this is not an xname, it is case-sensitive
363
+		return ($value === 'PUBLIC' || $value === 'PRIVATE' || $value === 'CONFIDENTIAL' || rfc2445_is_xname(strtoupper($value)));
364
+	}
365 365
 }
366 366
 
367 367
 class iCalendar_property_comment extends iCalendar_property {
368 368
 
369
-    var $name        = 'COMMENT';
370
-    var $val_type    = RFC2445_TYPE_TEXT;
369
+	var $name        = 'COMMENT';
370
+	var $val_type    = RFC2445_TYPE_TEXT;
371 371
 
372
-    function construct() {
373
-        $this->valid_parameters = array(
374
-            'ALTREP'      => RFC2445_OPTIONAL | RFC2445_ONCE,
375
-            'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
376
-            RFC2445_XNAME => RFC2445_OPTIONAL
377
-        );
378
-    }
372
+	function construct() {
373
+		$this->valid_parameters = array(
374
+			'ALTREP'      => RFC2445_OPTIONAL | RFC2445_ONCE,
375
+			'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
376
+			RFC2445_XNAME => RFC2445_OPTIONAL
377
+		);
378
+	}
379 379
 }
380 380
 
381 381
 class iCalendar_property_description extends iCalendar_property {
382 382
 
383
-    var $name        = 'DESCRIPTION';
384
-    var $val_type    = RFC2445_TYPE_TEXT;
383
+	var $name        = 'DESCRIPTION';
384
+	var $val_type    = RFC2445_TYPE_TEXT;
385 385
 
386
-    function construct() {
387
-        $this->valid_parameters = array(
388
-            'ALTREP'      => RFC2445_OPTIONAL | RFC2445_ONCE,
389
-            'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
390
-            RFC2445_XNAME => RFC2445_OPTIONAL
391
-        );
392
-    }
386
+	function construct() {
387
+		$this->valid_parameters = array(
388
+			'ALTREP'      => RFC2445_OPTIONAL | RFC2445_ONCE,
389
+			'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
390
+			RFC2445_XNAME => RFC2445_OPTIONAL
391
+		);
392
+	}
393 393
 }
394 394
 
395 395
 class iCalendar_property_geo extends iCalendar_property {
396 396
 
397
-    var $name        = 'GEO';
398
-    var $val_type    = RFC2445_TYPE_TEXT;
399
-
400
-    function construct() {
401
-        $this->valid_parameters = array(
402
-            'ALTREP'      => RFC2445_OPTIONAL | RFC2445_ONCE,
403
-            'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
404
-            RFC2445_XNAME => RFC2445_OPTIONAL
405
-        );
406
-    }
407
-
408
-    function is_valid_value($value) {
409
-        // This MUST be two floats separated by a semicolon
410
-        if(!is_string($value)) {
411
-            return false;
412
-        }
413
-
414
-        $floats = explode(';', $value);
415
-        if(count($floats) != 2) {
416
-            return false;
417
-        }
418
-
419
-        return rfc2445_is_valid_value($floats[0], RFC2445_TYPE_FLOAT) && rfc2445_is_valid_value($floats[1], RFC2445_TYPE_FLOAT);
420
-    }
421
-
422
-    function set_value($value) {
423
-        // Must override this, otherwise the semicolon separating
424
-        // the two floats would get auto-quoted, which is illegal
425
-        if($this->is_valid_value($value)) {
426
-            $this->value = $value;
427
-            return true;
428
-        }
429
-
430
-        return false;
431
-    }
397
+	var $name        = 'GEO';
398
+	var $val_type    = RFC2445_TYPE_TEXT;
399
+
400
+	function construct() {
401
+		$this->valid_parameters = array(
402
+			'ALTREP'      => RFC2445_OPTIONAL | RFC2445_ONCE,
403
+			'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
404
+			RFC2445_XNAME => RFC2445_OPTIONAL
405
+		);
406
+	}
407
+
408
+	function is_valid_value($value) {
409
+		// This MUST be two floats separated by a semicolon
410
+		if(!is_string($value)) {
411
+			return false;
412
+		}
413
+
414
+		$floats = explode(';', $value);
415
+		if(count($floats) != 2) {
416
+			return false;
417
+		}
418
+
419
+		return rfc2445_is_valid_value($floats[0], RFC2445_TYPE_FLOAT) && rfc2445_is_valid_value($floats[1], RFC2445_TYPE_FLOAT);
420
+	}
421
+
422
+	function set_value($value) {
423
+		// Must override this, otherwise the semicolon separating
424
+		// the two floats would get auto-quoted, which is illegal
425
+		if($this->is_valid_value($value)) {
426
+			$this->value = $value;
427
+			return true;
428
+		}
429
+
430
+		return false;
431
+	}
432 432
 }
433 433
 
434 434
 class iCalendar_property_location extends iCalendar_property {
435 435
 
436
-    var $name        = 'LOCATION';
437
-    var $val_type    = RFC2445_TYPE_TEXT;
436
+	var $name        = 'LOCATION';
437
+	var $val_type    = RFC2445_TYPE_TEXT;
438 438
 
439
-    function construct() {
440
-        $this->valid_parameters = array(
441
-            'ALTREP'      => RFC2445_OPTIONAL | RFC2445_ONCE,
442
-            'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
443
-            RFC2445_XNAME => RFC2445_OPTIONAL
444
-        );
445
-    }
439
+	function construct() {
440
+		$this->valid_parameters = array(
441
+			'ALTREP'      => RFC2445_OPTIONAL | RFC2445_ONCE,
442
+			'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
443
+			RFC2445_XNAME => RFC2445_OPTIONAL
444
+		);
445
+	}
446 446
 }
447 447
 
448 448
 class iCalendar_property_percent_complete extends iCalendar_property {
449 449
 
450
-    var $name        = 'PERCENT-COMPLETE';
451
-    var $val_type    = RFC2445_TYPE_INTEGER;
452
-
453
-    function construct() {
454
-        $this->valid_parameters = array(
455
-            RFC2445_XNAME => RFC2445_OPTIONAL
456
-        );
457
-    }
458
-
459
-    function is_valid_value($value) {
460
-        // Only integers between 0 and 100 inclusive allowed
461
-        if(!parent::is_valid_value($value)) {
462
-            return false;
463
-        }
464
-        $value = intval($value);
465
-        return ($value >= 0 && $value <= 100);
466
-    }
450
+	var $name        = 'PERCENT-COMPLETE';
451
+	var $val_type    = RFC2445_TYPE_INTEGER;
452
+
453
+	function construct() {
454
+		$this->valid_parameters = array(
455
+			RFC2445_XNAME => RFC2445_OPTIONAL
456
+		);
457
+	}
458
+
459
+	function is_valid_value($value) {
460
+		// Only integers between 0 and 100 inclusive allowed
461
+		if(!parent::is_valid_value($value)) {
462
+			return false;
463
+		}
464
+		$value = intval($value);
465
+		return ($value >= 0 && $value <= 100);
466
+	}
467 467
 }
468 468
 
469 469
 class iCalendar_property_priority extends iCalendar_property {
470 470
 
471
-    var $name        = 'PRIORITY';
472
-    var $val_type    = RFC2445_TYPE_INTEGER;
471
+	var $name        = 'PRIORITY';
472
+	var $val_type    = RFC2445_TYPE_INTEGER;
473 473
 
474
-    function construct() {
475
-        $this->valid_parameters = array(
476
-            RFC2445_XNAME => RFC2445_OPTIONAL
477
-        );
478
-    }
474
+	function construct() {
475
+		$this->valid_parameters = array(
476
+			RFC2445_XNAME => RFC2445_OPTIONAL
477
+		);
478
+	}
479 479
 
480
-    function is_valid_value($value) {
481
-        // Only integers between 0 and 9 inclusive allowed        
482
-        if(!parent::is_valid_value($value)) {
483
-            return false;
484
-        }
480
+	function is_valid_value($value) {
481
+		// Only integers between 0 and 9 inclusive allowed        
482
+		if(!parent::is_valid_value($value)) {
483
+			return false;
484
+		}
485 485
 
486
-        $value = intval($value);
487
-        return ($value >= 0 && $value <= 9);
488
-    }
486
+		$value = intval($value);
487
+		return ($value >= 0 && $value <= 9);
488
+	}
489 489
 }
490 490
 
491 491
 class iCalendar_property_resources extends iCalendar_property {
492 492
 
493
-    var $name        = 'RESOURCES';
494
-    var $val_type    = RFC2445_TYPE_TEXT;
495
-    var $val_multi   = true;
496
-
497
-    function construct() {
498
-        $this->valid_parameters = array(
499
-            'ALTREP'      => RFC2445_OPTIONAL | RFC2445_ONCE,
500
-            'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
501
-            RFC2445_XNAME => RFC2445_OPTIONAL
502
-        );
503
-    }
493
+	var $name        = 'RESOURCES';
494
+	var $val_type    = RFC2445_TYPE_TEXT;
495
+	var $val_multi   = true;
496
+
497
+	function construct() {
498
+		$this->valid_parameters = array(
499
+			'ALTREP'      => RFC2445_OPTIONAL | RFC2445_ONCE,
500
+			'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
501
+			RFC2445_XNAME => RFC2445_OPTIONAL
502
+		);
503
+	}
504 504
 }
505 505
 
506 506
 class iCalendar_property_status extends iCalendar_property {
507 507
 
508
-    var $name        = 'STATUS';
509
-    var $val_type    = RFC2445_TYPE_TEXT;
510
-
511
-    function construct() {
512
-        $this->valid_parameters = array(
513
-            RFC2445_XNAME => RFC2445_OPTIONAL
514
-        );
515
-    }
516
-
517
-    function is_valid_value($value) {
518
-        // This is case-sensitive
519
-        switch ($this->parent_component) {
520
-            case 'VEVENT':
521
-                $allowed = array('TENTATIVE', 'CONFIRMED', 'CANCELLED');
522
-            break;
523
-            case 'VTODO':
524
-                $allowed = array('NEEDS-ACTION', 'COMPLETED', 'IN-PROCESS', 'CANCELLED');
525
-            break;
526
-            case 'VJOURNAL':
527
-                $allowed = array('DRAFT', 'FINAL', 'CANCELLED');
528
-            break;
529
-        }
530
-        return in_array($value, $allowed);
531
-
532
-    }
508
+	var $name        = 'STATUS';
509
+	var $val_type    = RFC2445_TYPE_TEXT;
510
+
511
+	function construct() {
512
+		$this->valid_parameters = array(
513
+			RFC2445_XNAME => RFC2445_OPTIONAL
514
+		);
515
+	}
516
+
517
+	function is_valid_value($value) {
518
+		// This is case-sensitive
519
+		switch ($this->parent_component) {
520
+			case 'VEVENT':
521
+				$allowed = array('TENTATIVE', 'CONFIRMED', 'CANCELLED');
522
+			break;
523
+			case 'VTODO':
524
+				$allowed = array('NEEDS-ACTION', 'COMPLETED', 'IN-PROCESS', 'CANCELLED');
525
+			break;
526
+			case 'VJOURNAL':
527
+				$allowed = array('DRAFT', 'FINAL', 'CANCELLED');
528
+			break;
529
+		}
530
+		return in_array($value, $allowed);
531
+
532
+	}
533 533
 }
534 534
 
535 535
 class iCalendar_property_summary extends iCalendar_property {
536 536
 
537
-    var $name        = 'SUMMARY';
538
-    var $val_type    = RFC2445_TYPE_TEXT;
537
+	var $name        = 'SUMMARY';
538
+	var $val_type    = RFC2445_TYPE_TEXT;
539 539
 
540
-    function construct() {
541
-        $this->valid_parameters = array(
542
-            'ALTREP'      => RFC2445_OPTIONAL | RFC2445_ONCE,
543
-            'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
544
-            RFC2445_XNAME => RFC2445_OPTIONAL
545
-        );
546
-    }
540
+	function construct() {
541
+		$this->valid_parameters = array(
542
+			'ALTREP'      => RFC2445_OPTIONAL | RFC2445_ONCE,
543
+			'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
544
+			RFC2445_XNAME => RFC2445_OPTIONAL
545
+		);
546
+	}
547 547
 }
548 548
 
549 549
 // 4.8.2 Date and Time Component Properties
@@ -551,221 +551,221 @@  discard block
 block discarded – undo
551 551
 
552 552
 class iCalendar_property_completed extends iCalendar_property {
553 553
 
554
-    var $name        = 'COMPLETED';
555
-    var $val_type    = RFC2445_TYPE_DATE_TIME;
556
-
557
-    function construct() {
558
-        $this->valid_parameters = array(
559
-            RFC2445_XNAME => RFC2445_OPTIONAL
560
-        );
561
-    }
562
-
563
-    function is_valid_value($value) {
564
-        if(!parent::is_valid_value($value)) {
565
-            return false;
566
-        }
567
-        // Time MUST be in UTC format
568
-        return(substr($value, -1) == 'Z');
569
-    }
554
+	var $name        = 'COMPLETED';
555
+	var $val_type    = RFC2445_TYPE_DATE_TIME;
556
+
557
+	function construct() {
558
+		$this->valid_parameters = array(
559
+			RFC2445_XNAME => RFC2445_OPTIONAL
560
+		);
561
+	}
562
+
563
+	function is_valid_value($value) {
564
+		if(!parent::is_valid_value($value)) {
565
+			return false;
566
+		}
567
+		// Time MUST be in UTC format
568
+		return(substr($value, -1) == 'Z');
569
+	}
570 570
 }
571 571
 
572 572
 class iCalendar_property_dtend extends iCalendar_property {
573 573
 
574
-    var $name        = 'DTEND';
575
-    var $val_type    = RFC2445_TYPE_DATE_TIME;
574
+	var $name        = 'DTEND';
575
+	var $val_type    = RFC2445_TYPE_DATE_TIME;
576 576
 
577
-    function construct() {
578
-        $this->valid_parameters = array(
579
-            'VALUE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
580
-            'TZID'        => RFC2445_OPTIONAL | RFC2445_ONCE,
581
-            RFC2445_XNAME => RFC2445_OPTIONAL
582
-        );
583
-    }
577
+	function construct() {
578
+		$this->valid_parameters = array(
579
+			'VALUE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
580
+			'TZID'        => RFC2445_OPTIONAL | RFC2445_ONCE,
581
+			RFC2445_XNAME => RFC2445_OPTIONAL
582
+		);
583
+	}
584 584
 
585
-    function is_valid_value($value) {
586
-        if(!parent::is_valid_value($value)) {
587
-            return false;
588
-        }
585
+	function is_valid_value($value) {
586
+		if(!parent::is_valid_value($value)) {
587
+			return false;
588
+		}
589 589
 
590
-        // If present in a FREEBUSY component, must be in UTC format
591
-        if($this->parent_component == 'VFREEBUSY' && substr($value, -1) != 'Z') {
592
-            return false;
593
-        }
590
+		// If present in a FREEBUSY component, must be in UTC format
591
+		if($this->parent_component == 'VFREEBUSY' && substr($value, -1) != 'Z') {
592
+			return false;
593
+		}
594 594
 
595
-        return true;
595
+		return true;
596 596
 
597
-    }
597
+	}
598 598
 
599
-    function is_valid_parameter($parameter, $value) {
599
+	function is_valid_parameter($parameter, $value) {
600 600
 
601
-        $parameter = strtoupper($parameter);
601
+		$parameter = strtoupper($parameter);
602 602
 
603
-        if(!parent::is_valid_parameter($parameter, $value)) {
604
-            return false;
605
-        }
606
-        if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
607
-            return false;
608
-        }
603
+		if(!parent::is_valid_parameter($parameter, $value)) {
604
+			return false;
605
+		}
606
+		if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
607
+			return false;
608
+		}
609 609
 
610
-        return true;
611
-    }
610
+		return true;
611
+	}
612 612
 }
613 613
 
614 614
 class iCalendar_property_due extends iCalendar_property {
615 615
 
616
-    var $name        = 'DUE';
617
-    var $val_type    = RFC2445_TYPE_DATE_TIME;
616
+	var $name        = 'DUE';
617
+	var $val_type    = RFC2445_TYPE_DATE_TIME;
618 618
 
619
-    function construct() {
620
-        $this->valid_parameters = array(
621
-            'VALUE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
622
-            'TZID'        => RFC2445_OPTIONAL | RFC2445_ONCE,
623
-            RFC2445_XNAME => RFC2445_OPTIONAL
624
-        );
625
-    }
619
+	function construct() {
620
+		$this->valid_parameters = array(
621
+			'VALUE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
622
+			'TZID'        => RFC2445_OPTIONAL | RFC2445_ONCE,
623
+			RFC2445_XNAME => RFC2445_OPTIONAL
624
+		);
625
+	}
626 626
 
627
-    function is_valid_value($value) {
628
-        if(!parent::is_valid_value($value)) {
629
-            return false;
630
-        }
627
+	function is_valid_value($value) {
628
+		if(!parent::is_valid_value($value)) {
629
+			return false;
630
+		}
631 631
 
632
-        // If present in a FREEBUSY component, must be in UTC format
633
-        if($this->parent_component == 'VFREEBUSY' && substr($value, -1) != 'Z') {
634
-            return false;
635
-        }
632
+		// If present in a FREEBUSY component, must be in UTC format
633
+		if($this->parent_component == 'VFREEBUSY' && substr($value, -1) != 'Z') {
634
+			return false;
635
+		}
636 636
 
637
-        return true;
637
+		return true;
638 638
 
639
-    }
639
+	}
640 640
 
641
-    function is_valid_parameter($parameter, $value) {
641
+	function is_valid_parameter($parameter, $value) {
642 642
 
643
-        $parameter = strtoupper($parameter);
643
+		$parameter = strtoupper($parameter);
644 644
 
645
-        if(!parent::is_valid_parameter($parameter, $value)) {
646
-            return false;
647
-        }
648
-        if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
649
-            return false;
650
-        }
645
+		if(!parent::is_valid_parameter($parameter, $value)) {
646
+			return false;
647
+		}
648
+		if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
649
+			return false;
650
+		}
651 651
 
652
-        return true;
653
-    }
652
+		return true;
653
+	}
654 654
 }
655 655
 
656 656
 class iCalendar_property_dtstart extends iCalendar_property {
657 657
 
658
-    var $name        = 'DTSTART';
659
-    var $val_type    = RFC2445_TYPE_DATE_TIME;
658
+	var $name        = 'DTSTART';
659
+	var $val_type    = RFC2445_TYPE_DATE_TIME;
660 660
 
661
-    function construct() {
662
-        $this->valid_parameters = array(
663
-            'VALUE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
664
-            'TZID'        => RFC2445_OPTIONAL | RFC2445_ONCE,
665
-            RFC2445_XNAME => RFC2445_OPTIONAL
666
-        );
667
-    }
661
+	function construct() {
662
+		$this->valid_parameters = array(
663
+			'VALUE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
664
+			'TZID'        => RFC2445_OPTIONAL | RFC2445_ONCE,
665
+			RFC2445_XNAME => RFC2445_OPTIONAL
666
+		);
667
+	}
668 668
 
669
-    // TODO: unimplemented stuff when parent is a VTIMEZONE component
669
+	// TODO: unimplemented stuff when parent is a VTIMEZONE component
670 670
 
671
-    function is_valid_value($value) {
672
-        if(!parent::is_valid_value($value)) {
673
-            return false;
674
-        }
671
+	function is_valid_value($value) {
672
+		if(!parent::is_valid_value($value)) {
673
+			return false;
674
+		}
675 675
 
676
-        // If present in a FREEBUSY component, must be in UTC format
677
-        if($this->parent_component == 'VFREEBUSY' && substr($value, -1) != 'Z') {
678
-            return false;
679
-        }
676
+		// If present in a FREEBUSY component, must be in UTC format
677
+		if($this->parent_component == 'VFREEBUSY' && substr($value, -1) != 'Z') {
678
+			return false;
679
+		}
680 680
 
681
-        return true;
682
-    }
681
+		return true;
682
+	}
683 683
 
684
-    function is_valid_parameter($parameter, $value) {
684
+	function is_valid_parameter($parameter, $value) {
685 685
 
686
-        $parameter = strtoupper($parameter);
686
+		$parameter = strtoupper($parameter);
687 687
 
688
-        if(!parent::is_valid_parameter($parameter, $value)) {
689
-            return false;
690
-        }
691
-        if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
692
-            return false;
693
-        }
688
+		if(!parent::is_valid_parameter($parameter, $value)) {
689
+			return false;
690
+		}
691
+		if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
692
+			return false;
693
+		}
694 694
 
695
-        return true;
696
-    }
695
+		return true;
696
+	}
697 697
 }
698 698
 
699 699
 class iCalendar_property_duration extends iCalendar_property {
700 700
 
701
-    var $name        = 'DURATION';
702
-    var $val_type    = RFC2445_TYPE_DURATION;
701
+	var $name        = 'DURATION';
702
+	var $val_type    = RFC2445_TYPE_DURATION;
703 703
 
704
-    function construct() {
705
-        $this->valid_parameters = array(
706
-            RFC2445_XNAME => RFC2445_OPTIONAL
707
-        );
708
-    }
704
+	function construct() {
705
+		$this->valid_parameters = array(
706
+			RFC2445_XNAME => RFC2445_OPTIONAL
707
+		);
708
+	}
709 709
 
710
-    function is_valid_value($value) {
711
-        if(!parent::is_valid_value($value)) {
712
-            return false;
713
-        }
710
+	function is_valid_value($value) {
711
+		if(!parent::is_valid_value($value)) {
712
+			return false;
713
+		}
714 714
 
715
-        // Value must be positive
716
-        return ($value{0} != '-');
717
-    }
715
+		// Value must be positive
716
+		return ($value{0} != '-');
717
+	}
718 718
 }
719 719
 
720 720
 class iCalendar_property_freebusy extends iCalendar_property {
721 721
 
722
-    var $name        = 'FREEBUSY';
723
-    var $val_type    = RFC2445_TYPE_PERIOD;
724
-    var $val_multi   = true;
725
-
726
-    function construct() {
727
-        $this->valid_parameters = array(
728
-            'FBTYPE'      => RFC2445_OPTIONAL | RFC2445_ONCE,
729
-            RFC2445_XNAME => RFC2445_OPTIONAL
730
-        );
731
-    }
732
-
733
-    function is_valid_value($value) {
734
-        if(!parent::is_valid_value($value)) {
735
-            return false;
736
-        }
737
-
738
-        $pos = strpos($value, '/'); // We know there's only one / in there
739
-        if($value{$pos - 1} != 'Z') {
740
-            // Start time MUST be in UTC
741
-            return false;
742
-        }
743
-        if($value{$pos + 1} != 'P' && $substr($value, -1) != 'Z') {
744
-            // If the second part is not a period, it MUST be in UTC
745
-            return false;
746
-        }
747
-
748
-        return true;
749
-    }
750
-
751
-    // TODO: these properties SHOULD be shorted in ascending order (by start time and end time as tiebreak)
722
+	var $name        = 'FREEBUSY';
723
+	var $val_type    = RFC2445_TYPE_PERIOD;
724
+	var $val_multi   = true;
725
+
726
+	function construct() {
727
+		$this->valid_parameters = array(
728
+			'FBTYPE'      => RFC2445_OPTIONAL | RFC2445_ONCE,
729
+			RFC2445_XNAME => RFC2445_OPTIONAL
730
+		);
731
+	}
732
+
733
+	function is_valid_value($value) {
734
+		if(!parent::is_valid_value($value)) {
735
+			return false;
736
+		}
737
+
738
+		$pos = strpos($value, '/'); // We know there's only one / in there
739
+		if($value{$pos - 1} != 'Z') {
740
+			// Start time MUST be in UTC
741
+			return false;
742
+		}
743
+		if($value{$pos + 1} != 'P' && $substr($value, -1) != 'Z') {
744
+			// If the second part is not a period, it MUST be in UTC
745
+			return false;
746
+		}
747
+
748
+		return true;
749
+	}
750
+
751
+	// TODO: these properties SHOULD be shorted in ascending order (by start time and end time as tiebreak)
752 752
 }
753 753
 
754 754
 class iCalendar_property_transp extends iCalendar_property {
755 755
 
756
-    var $name        = 'TRANSP';
757
-    var $val_type    = RFC2445_TYPE_TEXT;
758
-    var $val_default = 'OPAQUE';
756
+	var $name        = 'TRANSP';
757
+	var $val_type    = RFC2445_TYPE_TEXT;
758
+	var $val_default = 'OPAQUE';
759 759
 
760
-    function construct() {
761
-        $this->valid_parameters = array(
762
-            RFC2445_XNAME => RFC2445_OPTIONAL
763
-        );
764
-    }
760
+	function construct() {
761
+		$this->valid_parameters = array(
762
+			RFC2445_XNAME => RFC2445_OPTIONAL
763
+		);
764
+	}
765 765
 
766
-    function is_valid_value($value) {
767
-        return ($value === 'TRANSPARENT' || $value === 'OPAQUE');
768
-    }
766
+	function is_valid_value($value) {
767
+		return ($value === 'TRANSPARENT' || $value === 'OPAQUE');
768
+	}
769 769
 }
770 770
 
771 771
 // TODO: 4.8.3 timezone component properties
@@ -776,76 +776,76 @@  discard block
 block discarded – undo
776 776
 
777 777
 class iCalendar_property_attendee extends iCalendar_property {
778 778
 
779
-    var $name        = 'ATTENDEE';
780
-    var $val_type    = RFC2445_TYPE_CAL_ADDRESS;
781
-
782
-    // TODO: MUST NOT be specified when the calendar object has METHOD=PUBLISH
783
-    // TODO: standard has lots of detail here, make triple sure that we eventually conform
784
-
785
-    function construct() {
786
-        $this->valid_parameters = array(
787
-            'LANGUAGE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
788
-            'CN'             => RFC2445_OPTIONAL | RFC2445_ONCE,
789
-            'ROLE'           => RFC2445_OPTIONAL | RFC2445_ONCE,
790
-            'PARTSTAT'       => RFC2445_OPTIONAL | RFC2445_ONCE,
791
-            'RSVP'           => RFC2445_OPTIONAL | RFC2445_ONCE,
792
-            'CUTYPE'         => RFC2445_OPTIONAL | RFC2445_ONCE,
793
-            'MEMBER'         => RFC2445_OPTIONAL | RFC2445_ONCE,
794
-            'DELEGATED-TO'   => RFC2445_OPTIONAL | RFC2445_ONCE,
795
-            'DELEGATED-FROM' => RFC2445_OPTIONAL | RFC2445_ONCE,
796
-            'SENT-BY'        => RFC2445_OPTIONAL | RFC2445_ONCE,
797
-            'DIR'            => RFC2445_OPTIONAL | RFC2445_ONCE,
798
-            RFC2445_XNAME    => RFC2445_OPTIONAL
799
-        );
800
-    }
801
-
802
-    function set_parent_component($componentname) {
803
-        if(!parent::set_parent_component($componentname)) {
804
-            return false;
805
-        }
806
-
807
-        if($this->parent_component == 'VFREEBUSY' || $this->parent_component == 'VALARM') {
808
-            // Most parameters become invalid in this case, the full allowed set is now:
809
-            $this->valid_parameters = array(
810
-                'LANGUAGE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
811
-                RFC2445_XNAME    => RFC2445_OPTIONAL
812
-            );
813
-        }
814
-
815
-        return false;
816
-    }
779
+	var $name        = 'ATTENDEE';
780
+	var $val_type    = RFC2445_TYPE_CAL_ADDRESS;
781
+
782
+	// TODO: MUST NOT be specified when the calendar object has METHOD=PUBLISH
783
+	// TODO: standard has lots of detail here, make triple sure that we eventually conform
784
+
785
+	function construct() {
786
+		$this->valid_parameters = array(
787
+			'LANGUAGE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
788
+			'CN'             => RFC2445_OPTIONAL | RFC2445_ONCE,
789
+			'ROLE'           => RFC2445_OPTIONAL | RFC2445_ONCE,
790
+			'PARTSTAT'       => RFC2445_OPTIONAL | RFC2445_ONCE,
791
+			'RSVP'           => RFC2445_OPTIONAL | RFC2445_ONCE,
792
+			'CUTYPE'         => RFC2445_OPTIONAL | RFC2445_ONCE,
793
+			'MEMBER'         => RFC2445_OPTIONAL | RFC2445_ONCE,
794
+			'DELEGATED-TO'   => RFC2445_OPTIONAL | RFC2445_ONCE,
795
+			'DELEGATED-FROM' => RFC2445_OPTIONAL | RFC2445_ONCE,
796
+			'SENT-BY'        => RFC2445_OPTIONAL | RFC2445_ONCE,
797
+			'DIR'            => RFC2445_OPTIONAL | RFC2445_ONCE,
798
+			RFC2445_XNAME    => RFC2445_OPTIONAL
799
+		);
800
+	}
801
+
802
+	function set_parent_component($componentname) {
803
+		if(!parent::set_parent_component($componentname)) {
804
+			return false;
805
+		}
806
+
807
+		if($this->parent_component == 'VFREEBUSY' || $this->parent_component == 'VALARM') {
808
+			// Most parameters become invalid in this case, the full allowed set is now:
809
+			$this->valid_parameters = array(
810
+				'LANGUAGE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
811
+				RFC2445_XNAME    => RFC2445_OPTIONAL
812
+			);
813
+		}
814
+
815
+		return false;
816
+	}
817 817
 }
818 818
 
819 819
 class iCalendar_property_contact extends iCalendar_property {
820 820
 
821
-    var $name        = 'CONTACT';
822
-    var $val_type    = RFC2445_TYPE_TEXT;
821
+	var $name        = 'CONTACT';
822
+	var $val_type    = RFC2445_TYPE_TEXT;
823 823
 
824
-    function construct() {
825
-        $this->valid_parameters = array(
826
-            'ALTREP'      => RFC2445_OPTIONAL | RFC2445_ONCE,
827
-            'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
828
-            RFC2445_XNAME => RFC2445_OPTIONAL
829
-        );
830
-    }
824
+	function construct() {
825
+		$this->valid_parameters = array(
826
+			'ALTREP'      => RFC2445_OPTIONAL | RFC2445_ONCE,
827
+			'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
828
+			RFC2445_XNAME => RFC2445_OPTIONAL
829
+		);
830
+	}
831 831
 }
832 832
 
833 833
 class iCalendar_property_organizer extends iCalendar_property {
834 834
 
835
-    var $name        = 'ORGANIZER';
836
-    var $val_type    = RFC2445_TYPE_CAL_ADDRESS;
835
+	var $name        = 'ORGANIZER';
836
+	var $val_type    = RFC2445_TYPE_CAL_ADDRESS;
837 837
 
838
-    function construct() {
839
-        $this->valid_parameters = array(
840
-            'CN'          => RFC2445_OPTIONAL | RFC2445_ONCE,
841
-            'DIR'         => RFC2445_OPTIONAL | RFC2445_ONCE,
842
-            'SENT-BY'     => RFC2445_OPTIONAL | RFC2445_ONCE,
843
-            'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
844
-            RFC2445_XNAME => RFC2445_OPTIONAL
845
-        );
846
-    }
838
+	function construct() {
839
+		$this->valid_parameters = array(
840
+			'CN'          => RFC2445_OPTIONAL | RFC2445_ONCE,
841
+			'DIR'         => RFC2445_OPTIONAL | RFC2445_ONCE,
842
+			'SENT-BY'     => RFC2445_OPTIONAL | RFC2445_ONCE,
843
+			'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
844
+			RFC2445_XNAME => RFC2445_OPTIONAL
845
+		);
846
+	}
847 847
 
848
-    // TODO:
848
+	// TODO:
849 849
 /*    
850 850
    Conformance: This property MUST be specified in an iCalendar object
851 851
    that specifies a group scheduled calendar entity. This property MUST
@@ -860,7 +860,7 @@  discard block
 block discarded – undo
860 860
 
861 861
 class iCalendar_property_recurrence_id extends iCalendar_property {
862 862
 
863
-    // TODO: can only be specified when defining recurring components in the calendar
863
+	// TODO: can only be specified when defining recurring components in the calendar
864 864
 /*
865 865
    Conformance: This property can be specified in an iCalendar object
866 866
    containing a recurring calendar component.
@@ -872,75 +872,75 @@  discard block
 block discarded – undo
872 872
    recurrence set.
873 873
 */
874 874
 
875
-    var $name        = 'RECURRENCE-ID';
876
-    var $val_type    = RFC2445_TYPE_DATE_TIME;
875
+	var $name        = 'RECURRENCE-ID';
876
+	var $val_type    = RFC2445_TYPE_DATE_TIME;
877 877
 
878
-    function construct() {
879
-        $this->valid_parameters = array(
880
-            'RANGE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
881
-            'TZID'        => RFC2445_OPTIONAL | RFC2445_ONCE,
882
-            'VALUE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
883
-            RFC2445_XNAME => RFC2445_OPTIONAL
884
-        );
885
-    }
878
+	function construct() {
879
+		$this->valid_parameters = array(
880
+			'RANGE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
881
+			'TZID'        => RFC2445_OPTIONAL | RFC2445_ONCE,
882
+			'VALUE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
883
+			RFC2445_XNAME => RFC2445_OPTIONAL
884
+		);
885
+	}
886 886
 
887
-    function is_valid_parameter($parameter, $value) {
887
+	function is_valid_parameter($parameter, $value) {
888 888
 
889
-        $parameter = strtoupper($parameter);
889
+		$parameter = strtoupper($parameter);
890 890
 
891
-        if(!parent::is_valid_parameter($parameter, $value)) {
892
-            return false;
893
-        }
894
-        if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
895
-            return false;
896
-        }
891
+		if(!parent::is_valid_parameter($parameter, $value)) {
892
+			return false;
893
+		}
894
+		if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
895
+			return false;
896
+		}
897 897
 
898
-        return true;
899
-    }
898
+		return true;
899
+	}
900 900
 }
901 901
 
902 902
 class iCalendar_property_related_to extends iCalendar_property {
903 903
 
904
-    var $name        = 'RELATED-TO';
905
-    var $val_type    = RFC2445_TYPE_TEXT;
904
+	var $name        = 'RELATED-TO';
905
+	var $val_type    = RFC2445_TYPE_TEXT;
906 906
 
907
-    // TODO: the value of this property must reference another component's UID
907
+	// TODO: the value of this property must reference another component's UID
908 908
 
909
-    function construct() {
910
-        $this->valid_parameters = array(
911
-            'RELTYPE'     => RFC2445_OPTIONAL | RFC2445_ONCE,
912
-            RFC2445_XNAME => RFC2445_OPTIONAL
913
-        );
914
-    }
909
+	function construct() {
910
+		$this->valid_parameters = array(
911
+			'RELTYPE'     => RFC2445_OPTIONAL | RFC2445_ONCE,
912
+			RFC2445_XNAME => RFC2445_OPTIONAL
913
+		);
914
+	}
915 915
 }
916 916
 
917 917
 class iCalendar_property_url extends iCalendar_property {
918 918
 
919
-    var $name        = 'URL';
920
-    var $val_type    = RFC2445_TYPE_URI;
919
+	var $name        = 'URL';
920
+	var $val_type    = RFC2445_TYPE_URI;
921 921
 
922
-    function construct() {
923
-        $this->valid_parameters = array(
924
-            RFC2445_XNAME => RFC2445_OPTIONAL
925
-        );
926
-    }
922
+	function construct() {
923
+		$this->valid_parameters = array(
924
+			RFC2445_XNAME => RFC2445_OPTIONAL
925
+		);
926
+	}
927 927
 }
928 928
 
929 929
 class iCalendar_property_uid extends iCalendar_property {
930 930
 
931
-    var $name        = 'UID';
932
-    var $val_type    = RFC2445_TYPE_TEXT;
931
+	var $name        = 'UID';
932
+	var $val_type    = RFC2445_TYPE_TEXT;
933 933
 
934
-    function construct() {
935
-        $this->valid_parameters = array(
936
-            RFC2445_XNAME => RFC2445_OPTIONAL
937
-        );
934
+	function construct() {
935
+		$this->valid_parameters = array(
936
+			RFC2445_XNAME => RFC2445_OPTIONAL
937
+		);
938 938
 
939
-        // The exception to the rule: this is not a static value, so we
940
-        // generate it on-the-fly here. Guaranteed to be different for
941
-        // each instance of this property, too. Nice.
942
-        $this->val_default = Bennu::generate_guid();
943
-    }
939
+		// The exception to the rule: this is not a static value, so we
940
+		// generate it on-the-fly here. Guaranteed to be different for
941
+		// each instance of this property, too. Nice.
942
+		$this->val_default = Bennu::generate_guid();
943
+	}
944 944
 }
945 945
 
946 946
 // 4.8.5 Recurrence Component Properties
@@ -948,84 +948,84 @@  discard block
 block discarded – undo
948 948
 
949 949
 class iCalendar_property_exdate extends iCalendar_property {
950 950
 
951
-    var $name        = 'EXDATE';
952
-    var $val_type    = RFC2445_TYPE_DATE_TIME;
953
-    var $val_multi   = true;
951
+	var $name        = 'EXDATE';
952
+	var $val_type    = RFC2445_TYPE_DATE_TIME;
953
+	var $val_multi   = true;
954 954
 
955
-    function construct() {
956
-        $this->valid_parameters = array(
957
-            'TZID'        => RFC2445_OPTIONAL | RFC2445_ONCE,
958
-            'VALUE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
959
-            RFC2445_XNAME => RFC2445_OPTIONAL
960
-        );
961
-    }
955
+	function construct() {
956
+		$this->valid_parameters = array(
957
+			'TZID'        => RFC2445_OPTIONAL | RFC2445_ONCE,
958
+			'VALUE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
959
+			RFC2445_XNAME => RFC2445_OPTIONAL
960
+		);
961
+	}
962 962
 
963
-    function is_valid_parameter($parameter, $value) {
963
+	function is_valid_parameter($parameter, $value) {
964 964
 
965
-        $parameter = strtoupper($parameter);
965
+		$parameter = strtoupper($parameter);
966 966
 
967
-        if(!parent::is_valid_parameter($parameter, $value)) {
968
-            return false;
969
-        }
970
-        if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
971
-            return false;
972
-        }
967
+		if(!parent::is_valid_parameter($parameter, $value)) {
968
+			return false;
969
+		}
970
+		if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
971
+			return false;
972
+		}
973 973
 
974
-        return true;
975
-    }
974
+		return true;
975
+	}
976 976
 }
977 977
 
978 978
 class iCalendar_property_exrule extends iCalendar_property {
979 979
 
980
-    var $name        = 'EXRULE';
981
-    var $val_type    = RFC2445_TYPE_RECUR;
980
+	var $name        = 'EXRULE';
981
+	var $val_type    = RFC2445_TYPE_RECUR;
982 982
 
983
-    function construct() {
984
-        $this->valid_parameters = array(
985
-            RFC2445_XNAME => RFC2445_OPTIONAL
986
-        );
987
-    }
983
+	function construct() {
984
+		$this->valid_parameters = array(
985
+			RFC2445_XNAME => RFC2445_OPTIONAL
986
+		);
987
+	}
988 988
 }
989 989
 
990 990
 class iCalendar_property_rdate extends iCalendar_property {
991 991
 
992
-    var $name        = 'RDATE';
993
-    var $val_type    = RFC2445_TYPE_DATE_TIME;
994
-    var $val_multi   = true;
992
+	var $name        = 'RDATE';
993
+	var $val_type    = RFC2445_TYPE_DATE_TIME;
994
+	var $val_multi   = true;
995 995
 
996
-    function construct() {
997
-        $this->valid_parameters = array(
998
-            'TZID'        => RFC2445_OPTIONAL | RFC2445_ONCE,
999
-            'VALUE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
1000
-            RFC2445_XNAME => RFC2445_OPTIONAL
1001
-        );
1002
-    }
996
+	function construct() {
997
+		$this->valid_parameters = array(
998
+			'TZID'        => RFC2445_OPTIONAL | RFC2445_ONCE,
999
+			'VALUE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
1000
+			RFC2445_XNAME => RFC2445_OPTIONAL
1001
+		);
1002
+	}
1003 1003
 
1004
-    function is_valid_parameter($parameter, $value) {
1004
+	function is_valid_parameter($parameter, $value) {
1005 1005
 
1006
-        $parameter = strtoupper($parameter);
1006
+		$parameter = strtoupper($parameter);
1007 1007
 
1008
-        if(!parent::is_valid_parameter($parameter, $value)) {
1009
-            return false;
1010
-        }
1011
-        if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME' || $value == 'PERIOD')) {
1012
-            return false;
1013
-        }
1008
+		if(!parent::is_valid_parameter($parameter, $value)) {
1009
+			return false;
1010
+		}
1011
+		if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME' || $value == 'PERIOD')) {
1012
+			return false;
1013
+		}
1014 1014
 
1015
-        return true;
1016
-    }
1015
+		return true;
1016
+	}
1017 1017
 }
1018 1018
 
1019 1019
 class iCalendar_property_rrule extends iCalendar_property {
1020 1020
 
1021
-    var $name        = 'RRULE';
1022
-    var $val_type    = RFC2445_TYPE_RECUR;
1021
+	var $name        = 'RRULE';
1022
+	var $val_type    = RFC2445_TYPE_RECUR;
1023 1023
 
1024
-    function construct() {
1025
-        $this->valid_parameters = array(
1026
-            RFC2445_XNAME => RFC2445_OPTIONAL
1027
-        );
1028
-    }
1024
+	function construct() {
1025
+		$this->valid_parameters = array(
1026
+			RFC2445_XNAME => RFC2445_OPTIONAL
1027
+		);
1028
+	}
1029 1029
 }
1030 1030
 
1031 1031
 // TODO: 4.8.6 Alarm Component Properties
@@ -1035,83 +1035,83 @@  discard block
 block discarded – undo
1035 1035
 
1036 1036
 class iCalendar_property_created extends iCalendar_property {
1037 1037
 
1038
-    var $name        = 'CREATED';
1039
-    var $val_type    = RFC2445_TYPE_DATE_TIME;
1040
-
1041
-    function construct() {
1042
-        $this->valid_parameters = array(
1043
-            RFC2445_XNAME => RFC2445_OPTIONAL
1044
-        );
1045
-    }
1046
-
1047
-    function is_valid_value($value) {
1048
-        if(!parent::is_valid_value($value)) {
1049
-            return false;
1050
-        }
1051
-        // Time MUST be in UTC format
1052
-        return(substr($value, -1) == 'Z');
1053
-    }
1038
+	var $name        = 'CREATED';
1039
+	var $val_type    = RFC2445_TYPE_DATE_TIME;
1040
+
1041
+	function construct() {
1042
+		$this->valid_parameters = array(
1043
+			RFC2445_XNAME => RFC2445_OPTIONAL
1044
+		);
1045
+	}
1046
+
1047
+	function is_valid_value($value) {
1048
+		if(!parent::is_valid_value($value)) {
1049
+			return false;
1050
+		}
1051
+		// Time MUST be in UTC format
1052
+		return(substr($value, -1) == 'Z');
1053
+	}
1054 1054
 }
1055 1055
 
1056 1056
 class iCalendar_property_dtstamp extends iCalendar_property {
1057 1057
 
1058
-    var $name        = 'DTSTAMP';
1059
-    var $val_type    = RFC2445_TYPE_DATE_TIME;
1060
-
1061
-    function construct() {
1062
-        $this->valid_parameters = array(
1063
-            RFC2445_XNAME => RFC2445_OPTIONAL
1064
-        );
1065
-    }
1066
-
1067
-    function is_valid_value($value) {
1068
-        if(!parent::is_valid_value($value)) {
1069
-            return false;
1070
-        }
1071
-        // Time MUST be in UTC format
1072
-        return(substr($value, -1) == 'Z');
1073
-    }
1058
+	var $name        = 'DTSTAMP';
1059
+	var $val_type    = RFC2445_TYPE_DATE_TIME;
1060
+
1061
+	function construct() {
1062
+		$this->valid_parameters = array(
1063
+			RFC2445_XNAME => RFC2445_OPTIONAL
1064
+		);
1065
+	}
1066
+
1067
+	function is_valid_value($value) {
1068
+		if(!parent::is_valid_value($value)) {
1069
+			return false;
1070
+		}
1071
+		// Time MUST be in UTC format
1072
+		return(substr($value, -1) == 'Z');
1073
+	}
1074 1074
 }
1075 1075
 
1076 1076
 class iCalendar_property_last_modified extends iCalendar_property {
1077 1077
 
1078
-    var $name        = 'LAST-MODIFIED';
1079
-    var $val_type    = RFC2445_TYPE_DATE_TIME;
1080
-
1081
-    function construct() {
1082
-        $this->valid_parameters = array(
1083
-            RFC2445_XNAME => RFC2445_OPTIONAL
1084
-        );
1085
-    }
1086
-
1087
-    function is_valid_value($value) {
1088
-        if(!parent::is_valid_value($value)) {
1089
-            return false;
1090
-        }
1091
-        // Time MUST be in UTC format
1092
-        return(substr($value, -1) == 'Z');
1093
-    }
1078
+	var $name        = 'LAST-MODIFIED';
1079
+	var $val_type    = RFC2445_TYPE_DATE_TIME;
1080
+
1081
+	function construct() {
1082
+		$this->valid_parameters = array(
1083
+			RFC2445_XNAME => RFC2445_OPTIONAL
1084
+		);
1085
+	}
1086
+
1087
+	function is_valid_value($value) {
1088
+		if(!parent::is_valid_value($value)) {
1089
+			return false;
1090
+		}
1091
+		// Time MUST be in UTC format
1092
+		return(substr($value, -1) == 'Z');
1093
+	}
1094 1094
 }
1095 1095
 
1096 1096
 class iCalendar_property_sequence extends iCalendar_property {
1097 1097
 
1098
-    var $name        = 'SEQUENCE';
1099
-    var $val_type    = RFC2445_TYPE_INTEGER;
1100
-    var $val_default = 0;
1101
-
1102
-    function construct() {
1103
-        $this->valid_parameters = array(
1104
-            RFC2445_XNAME => RFC2445_OPTIONAL
1105
-        );
1106
-    }
1107
-
1108
-    function is_valid_value($value) {
1109
-        if(!parent::is_valid_value($value)) {
1110
-            return false;
1111
-        }
1112
-        $value = intval($value);
1113
-        return ($value >= 0);
1114
-    }
1098
+	var $name        = 'SEQUENCE';
1099
+	var $val_type    = RFC2445_TYPE_INTEGER;
1100
+	var $val_default = 0;
1101
+
1102
+	function construct() {
1103
+		$this->valid_parameters = array(
1104
+			RFC2445_XNAME => RFC2445_OPTIONAL
1105
+		);
1106
+	}
1107
+
1108
+	function is_valid_value($value) {
1109
+		if(!parent::is_valid_value($value)) {
1110
+			return false;
1111
+		}
1112
+		$value = intval($value);
1113
+		return ($value >= 0);
1114
+	}
1115 1115
 }
1116 1116
 
1117 1117
 // 4.8.8 Miscellaneous Component Properties
@@ -1119,156 +1119,156 @@  discard block
 block discarded – undo
1119 1119
 
1120 1120
 class iCalendar_property_x extends iCalendar_property {
1121 1121
 
1122
-    var $name        = RFC2445_XNAME;
1123
-    var $val_type    = NULL;
1122
+	var $name        = RFC2445_XNAME;
1123
+	var $val_type    = NULL;
1124 1124
 
1125
-    function construct() {
1126
-        $this->valid_parameters = array(
1127
-            'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
1128
-            RFC2445_XNAME => RFC2445_OPTIONAL
1129
-        );
1130
-    }
1125
+	function construct() {
1126
+		$this->valid_parameters = array(
1127
+			'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
1128
+			RFC2445_XNAME => RFC2445_OPTIONAL
1129
+		);
1130
+	}
1131 1131
 
1132
-    function set_name($name) {
1132
+	function set_name($name) {
1133 1133
 
1134
-        $name = strtoupper($name);
1134
+		$name = strtoupper($name);
1135 1135
 
1136
-        if(rfc2445_is_xname($name)) {
1137
-            $this->name = $name;
1138
-            return true;
1139
-        }
1136
+		if(rfc2445_is_xname($name)) {
1137
+			$this->name = $name;
1138
+			return true;
1139
+		}
1140 1140
 
1141
-        return false;
1142
-    }
1141
+		return false;
1142
+	}
1143 1143
 }
1144 1144
 
1145 1145
 class iCalendar_property_request_status extends iCalendar_property {
1146 1146
 
1147
-    // IMPORTANT NOTE: This property value includes TEXT fields
1148
-    // separated by semicolons. Unfortunately, auto-value-formatting
1149
-    // cannot be used in this case. As an exception, the value passed
1150
-    // to this property MUST be already escaped.
1151
-
1152
-    var $name        = 'REQUEST-STATUS';
1153
-    var $val_type    = RFC2445_TYPE_TEXT;
1154
-
1155
-    function construct() {
1156
-        $this->valid_parameters = array(
1157
-            'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
1158
-            RFC2445_XNAME => RFC2445_OPTIONAL
1159
-        );
1160
-    }
1161
-
1162
-    function is_valid_value($value) {
1163
-        if(!is_string($value) || empty($value)) {
1164
-            return false;
1165
-        }
1166
-
1167
-        $len   = strlen($value);
1168
-        $parts = array();
1169
-        $from  = 0;
1170
-        $escch = false;
1171
-
1172
-        for($i = 0; $i < $len; ++$i) {
1173
-            if($value{$i} == ';' && !$escch) {
1174
-                // Token completed
1175
-                $parts[] = substr($value, $from, $i - $from);
1176
-                $from = $i + 1;
1177
-                continue;
1178
-            }
1179
-            $escch = ($value{$i} == '\\');
1180
-        }
1181
-        // Add one last token with the remaining text; if the value
1182
-        // ended with a ';' it was illegal, so check that this token
1183
-        // is not the empty string.
1184
-        $parts[] = substr($value, $from);
1185
-
1186
-        $count = count($parts);
1187
-
1188
-        // May have 2 or 3 tokens (last one is optional)
1189
-        if($count != 2 && $count != 3) {
1190
-            return false;
1191
-        }
1192
-
1193
-        // REMEMBER: if ANY part is empty, we have an illegal value
1194
-
1195
-        // First token must be hierarchical numeric status (3 levels max)
1196
-        if(strlen($parts[0]) == 0) {
1197
-            return false;
1198
-        }
1199
-
1200
-        if($parts[0]{0} < '1' || $parts[0]{0} > '4') {
1201
-            return false;
1202
-        }
1203
-
1204
-        $len = strlen($parts[0]);
1205
-
1206
-        // Max 3 levels, and can't end with a period
1207
-        if($len > 5 || $parts[0]{$len - 1} == '.') {
1208
-            return false;
1209
-        }
1210
-
1211
-        for($i = 1; $i < $len; ++$i) {
1212
-            if(($i & 1) == 1 && $parts[0]{$i} != '.') {
1213
-                // Even-indexed chars must be periods
1214
-                return false;
1215
-            }
1216
-            else if(($i & 1) == 0 && ($parts[0]{$i} < '0' || $parts[0]{$i} > '9')) {
1217
-                // Odd-indexed chars must be numbers
1218
-                return false;
1219
-            }
1220
-        }
1221
-
1222
-        // Second and third tokens must be TEXT, and already escaped, so
1223
-        // they are not allowed to have UNESCAPED semicolons, commas, slashes,
1224
-        // or any newlines at all
1225
-
1226
-        for($i = 1; $i < $count; ++$i) {
1227
-            if(strpos($parts[$i], "\n") !== false) {
1228
-                return false;
1229
-            }
1230
-
1231
-            $len = strlen($parts[$i]);
1232
-            if($len == 0) {
1233
-                // Cannot be empty
1234
-                return false;
1235
-            }
1236
-
1237
-            $parts[$i] .= '#'; // This guard token saves some conditionals in the loop
1238
-
1239
-            for($j = 0; $j < $len; ++$j) {
1240
-                $thischar = $parts[$i]{$j};
1241
-                $nextchar = $parts[$i]{$j + 1};
1242
-                if($thischar == '\\') {
1243
-                    // Next char must now be one of ";,\nN"
1244
-                    if($nextchar != ';' && $nextchar != ',' && $nextchar != '\\' &&
1245
-                       $nextchar != 'n' && $nextchar != 'N') {
1246
-                        return false;
1247
-                    }
1248
-
1249
-                    // OK, this escaped sequence is correct, bypass next char
1250
-                    ++$j;
1251
-                    continue;
1252
-                }
1253
-                if($thischar == ';' || $thischar == ',' || $thischar == '\\') {
1254
-                    // This wasn't escaped as it should
1255
-                    return false;
1256
-                }
1257
-            }
1258
-        }
1259
-
1260
-        return true;
1261
-    }
1262
-
1263
-    function set_value($value) {
1264
-        // Must override this, otherwise the value would be quoted again
1265
-        if($this->is_valid_value($value)) {
1266
-            $this->value = $value;
1267
-            return true;
1268
-        }
1269
-
1270
-        return false;
1271
-    }
1147
+	// IMPORTANT NOTE: This property value includes TEXT fields
1148
+	// separated by semicolons. Unfortunately, auto-value-formatting
1149
+	// cannot be used in this case. As an exception, the value passed
1150
+	// to this property MUST be already escaped.
1151
+
1152
+	var $name        = 'REQUEST-STATUS';
1153
+	var $val_type    = RFC2445_TYPE_TEXT;
1154
+
1155
+	function construct() {
1156
+		$this->valid_parameters = array(
1157
+			'LANGUAGE'    => RFC2445_OPTIONAL | RFC2445_ONCE,
1158
+			RFC2445_XNAME => RFC2445_OPTIONAL
1159
+		);
1160
+	}
1161
+
1162
+	function is_valid_value($value) {
1163
+		if(!is_string($value) || empty($value)) {
1164
+			return false;
1165
+		}
1166
+
1167
+		$len   = strlen($value);
1168
+		$parts = array();
1169
+		$from  = 0;
1170
+		$escch = false;
1171
+
1172
+		for($i = 0; $i < $len; ++$i) {
1173
+			if($value{$i} == ';' && !$escch) {
1174
+				// Token completed
1175
+				$parts[] = substr($value, $from, $i - $from);
1176
+				$from = $i + 1;
1177
+				continue;
1178
+			}
1179
+			$escch = ($value{$i} == '\\');
1180
+		}
1181
+		// Add one last token with the remaining text; if the value
1182
+		// ended with a ';' it was illegal, so check that this token
1183
+		// is not the empty string.
1184
+		$parts[] = substr($value, $from);
1185
+
1186
+		$count = count($parts);
1187
+
1188
+		// May have 2 or 3 tokens (last one is optional)
1189
+		if($count != 2 && $count != 3) {
1190
+			return false;
1191
+		}
1192
+
1193
+		// REMEMBER: if ANY part is empty, we have an illegal value
1194
+
1195
+		// First token must be hierarchical numeric status (3 levels max)
1196
+		if(strlen($parts[0]) == 0) {
1197
+			return false;
1198
+		}
1199
+
1200
+		if($parts[0]{0} < '1' || $parts[0]{0} > '4') {
1201
+			return false;
1202
+		}
1203
+
1204
+		$len = strlen($parts[0]);
1205
+
1206
+		// Max 3 levels, and can't end with a period
1207
+		if($len > 5 || $parts[0]{$len - 1} == '.') {
1208
+			return false;
1209
+		}
1210
+
1211
+		for($i = 1; $i < $len; ++$i) {
1212
+			if(($i & 1) == 1 && $parts[0]{$i} != '.') {
1213
+				// Even-indexed chars must be periods
1214
+				return false;
1215
+			}
1216
+			else if(($i & 1) == 0 && ($parts[0]{$i} < '0' || $parts[0]{$i} > '9')) {
1217
+				// Odd-indexed chars must be numbers
1218
+				return false;
1219
+			}
1220
+		}
1221
+
1222
+		// Second and third tokens must be TEXT, and already escaped, so
1223
+		// they are not allowed to have UNESCAPED semicolons, commas, slashes,
1224
+		// or any newlines at all
1225
+
1226
+		for($i = 1; $i < $count; ++$i) {
1227
+			if(strpos($parts[$i], "\n") !== false) {
1228
+				return false;
1229
+			}
1230
+
1231
+			$len = strlen($parts[$i]);
1232
+			if($len == 0) {
1233
+				// Cannot be empty
1234
+				return false;
1235
+			}
1236
+
1237
+			$parts[$i] .= '#'; // This guard token saves some conditionals in the loop
1238
+
1239
+			for($j = 0; $j < $len; ++$j) {
1240
+				$thischar = $parts[$i]{$j};
1241
+				$nextchar = $parts[$i]{$j + 1};
1242
+				if($thischar == '\\') {
1243
+					// Next char must now be one of ";,\nN"
1244
+					if($nextchar != ';' && $nextchar != ',' && $nextchar != '\\' &&
1245
+					   $nextchar != 'n' && $nextchar != 'N') {
1246
+						return false;
1247
+					}
1248
+
1249
+					// OK, this escaped sequence is correct, bypass next char
1250
+					++$j;
1251
+					continue;
1252
+				}
1253
+				if($thischar == ';' || $thischar == ',' || $thischar == '\\') {
1254
+					// This wasn't escaped as it should
1255
+					return false;
1256
+				}
1257
+			}
1258
+		}
1259
+
1260
+		return true;
1261
+	}
1262
+
1263
+	function set_value($value) {
1264
+		// Must override this, otherwise the value would be quoted again
1265
+		if($this->is_valid_value($value)) {
1266
+			$this->value = $value;
1267
+			return true;
1268
+		}
1269
+
1270
+		return false;
1271
+	}
1272 1272
 }
1273 1273
 
1274 1274
 
Please login to merge, or discard this patch.
Spacing   +86 added lines, -86 removed lines patch added patch discarded remove patch
@@ -37,12 +37,12 @@  discard block
 block discarded – undo
37 37
     // IMPORTANT: the parameter name MUST BE CAPITALIZED!
38 38
     function is_valid_parameter($parameter, $value) {
39 39
 
40
-        if(is_array($value)) {
41
-            if(!iCalendar_parameter::multiple_values_allowed($parameter)) {
40
+        if (is_array($value)) {
41
+            if (!iCalendar_parameter::multiple_values_allowed($parameter)) {
42 42
                 return false;
43 43
             }
44
-            foreach($value as $item) {
45
-                if(!iCalendar_parameter::is_valid_value($this, $parameter, $item)) {
44
+            foreach ($value as $item) {
45
+                if (!iCalendar_parameter::is_valid_value($this, $parameter, $item)) {
46 46
                     return false;
47 47
                 }
48 48
             }
@@ -59,13 +59,13 @@  discard block
 block discarded – undo
59 59
     // If some property is very picky about its values, it should do the work itself
60 60
     // Only data type validation is done here
61 61
     function is_valid_value($value) {
62
-        if(is_array($value)) {
63
-            if(!$this->val_multi) {
62
+        if (is_array($value)) {
63
+            if (!$this->val_multi) {
64 64
                 return false;
65 65
             }
66 66
             else {
67
-                foreach($value as $oneval) {
68
-                    if(!rfc2445_is_valid_value($oneval, $this->val_type)) {
67
+                foreach ($value as $oneval) {
68
+                    if (!rfc2445_is_valid_value($oneval, $this->val_type)) {
69 69
                         return false;
70 70
                     }
71 71
                 }
@@ -80,7 +80,7 @@  discard block
 block discarded – undo
80 80
     }
81 81
 
82 82
     function set_parent_component($componentname) {
83
-        if(class_exists('iCalendar_'.strtolower(substr($componentname, 1)))) {
83
+        if (class_exists('iCalendar_'.strtolower(substr($componentname, 1)))) {
84 84
             $this->parent_component = strtoupper($componentname);
85 85
             return true;
86 86
         }
@@ -89,10 +89,10 @@  discard block
 block discarded – undo
89 89
     }
90 90
 
91 91
     function set_value($value) {
92
-        if($this->is_valid_value($value)) {
92
+        if ($this->is_valid_value($value)) {
93 93
             // This transparently formats any value type according to the iCalendar specs
94
-            if(is_array($value)) {
95
-                foreach($value as $key => $item) {
94
+            if (is_array($value)) {
95
+                foreach ($value as $key => $item) {
96 96
                     $value[$key] = rfc2445_do_value_formatting($item, $this->val_type);
97 97
                 }
98 98
                 $this->value = implode(',', $value);
@@ -115,7 +115,7 @@  discard block
 block discarded – undo
115 115
         $valarray = array_map($replace_function, $valarray);
116 116
 
117 117
         // Now, if this property cannot have multiple values, don't return as an array
118
-        if(!$this->val_multi) {
118
+        if (!$this->val_multi) {
119 119
             return $valarray[0];
120 120
         }
121 121
 
@@ -131,21 +131,21 @@  discard block
 block discarded – undo
131 131
 
132 132
         // Are we trying to add a valid parameter?
133 133
         $xname = false;
134
-        if(!isset($this->valid_parameters[$name])) {
134
+        if (!isset($this->valid_parameters[$name])) {
135 135
             // If not, is it an x-name as per RFC 2445?
136
-            if(!rfc2445_is_xname($name)) {
136
+            if (!rfc2445_is_xname($name)) {
137 137
                 return false;
138 138
             }
139 139
             // No more checks -- all components are supposed to allow x-name parameters
140 140
             $xname = true;
141 141
         }
142 142
 
143
-        if(!$this->is_valid_parameter($name, $value)) {
143
+        if (!$this->is_valid_parameter($name, $value)) {
144 144
             return false;
145 145
         }
146 146
 
147
-        if(is_array($value)) {
148
-            foreach($value as $key => $element) {
147
+        if (is_array($value)) {
148
+            foreach ($value as $key => $element) {
149 149
                 $value[$key] = iCalendar_parameter::do_value_formatting($name, $element);
150 150
             }
151 151
         }
@@ -157,7 +157,7 @@  discard block
 block discarded – undo
157 157
 
158 158
         // Special case: if we just changed the VALUE parameter, reflect this
159 159
         // in the object's status so that it only accepts correct type values
160
-        if($name == 'VALUE') {
160
+        if ($name == 'VALUE') {
161 161
             // TODO: what if this invalidates an already-set value?
162 162
             $this->val_type = constant('RFC2445_TYPE_'.str_replace('-', '_', $value));
163 163
         }
@@ -171,11 +171,11 @@  discard block
 block discarded – undo
171 171
         // Uppercase
172 172
         $name = strtoupper($name);
173 173
 
174
-        if(isset($this->parameters[$name])) {
174
+        if (isset($this->parameters[$name])) {
175 175
             // If there are any double quotes in the value, invisibly strip them
176
-            if(is_array($this->parameters[$name])) {
177
-                foreach($this->parameters[$name] as $key => $value) {
178
-                    if(substr($value, 0, 1) == '"') {
176
+            if (is_array($this->parameters[$name])) {
177
+                foreach ($this->parameters[$name] as $key => $value) {
178
+                    if (substr($value, 0, 1) == '"') {
179 179
                        $this->parameters[$name][$key] = substr($value, 1, strlen($value) - 2);
180 180
                     }
181 181
                 }
@@ -183,7 +183,7 @@  discard block
 block discarded – undo
183 183
             }
184 184
 
185 185
             else {
186
-                if(substr($this->parameters[$name], 0, 1) == '"') {
186
+                if (substr($this->parameters[$name], 0, 1) == '"') {
187 187
                     return substr($this->parameters[$name], 1, strlen($this->parameters[$name]) - 2);
188 188
                 }
189 189
             }
@@ -195,10 +195,10 @@  discard block
 block discarded – undo
195 195
     function serialize() {
196 196
         $string = $this->name;
197 197
 
198
-        if(!empty($this->parameters)) {
199
-            foreach($this->parameters as $name => $value) {
198
+        if (!empty($this->parameters)) {
199
+            foreach ($this->parameters as $name => $value) {
200 200
                 $string .= ';'.$name.'=';
201
-                if(is_array($value)) {
201
+                if (is_array($value)) {
202 202
                     $string .= implode(',', $value);
203 203
                 }
204 204
                 else {
@@ -209,7 +209,7 @@  discard block
 block discarded – undo
209 209
 
210 210
         $string .= ':'.$this->value;
211 211
 
212
-        return rfc2445_fold($string) . RFC2445_CRLF;
212
+        return rfc2445_fold($string).RFC2445_CRLF;
213 213
     }
214 214
 }
215 215
 
@@ -302,10 +302,10 @@  discard block
 block discarded – undo
302 302
     }
303 303
 
304 304
     function invariant_holds() {
305
-        if(isset($this->parameters['ENCODING']) && !isset($this->parameters['VALUE'])) {
305
+        if (isset($this->parameters['ENCODING']) && !isset($this->parameters['VALUE'])) {
306 306
             return false;
307 307
         }
308
-        if(isset($this->parameters['VALUE']) && !isset($this->parameters['ENCODING'])) {
308
+        if (isset($this->parameters['VALUE']) && !isset($this->parameters['ENCODING'])) {
309 309
             return false;
310 310
         }
311 311
 
@@ -316,15 +316,15 @@  discard block
 block discarded – undo
316 316
 
317 317
         $parameter = strtoupper($parameter);
318 318
 
319
-        if(!parent::is_valid_parameter($parameter, $value)) {
319
+        if (!parent::is_valid_parameter($parameter, $value)) {
320 320
             return false;
321 321
         }
322 322
 
323
-        if($parameter === 'ENCODING' && strtoupper($value) != 'BASE64') {
323
+        if ($parameter === 'ENCODING' && strtoupper($value) != 'BASE64') {
324 324
             return false;
325 325
         }
326 326
 
327
-        if($parameter === 'VALUE' && strtoupper($value) != 'BINARY') {
327
+        if ($parameter === 'VALUE' && strtoupper($value) != 'BINARY') {
328 328
             return false;
329 329
         }
330 330
 
@@ -407,12 +407,12 @@  discard block
 block discarded – undo
407 407
 
408 408
     function is_valid_value($value) {
409 409
         // This MUST be two floats separated by a semicolon
410
-        if(!is_string($value)) {
410
+        if (!is_string($value)) {
411 411
             return false;
412 412
         }
413 413
 
414 414
         $floats = explode(';', $value);
415
-        if(count($floats) != 2) {
415
+        if (count($floats) != 2) {
416 416
             return false;
417 417
         }
418 418
 
@@ -422,7 +422,7 @@  discard block
 block discarded – undo
422 422
     function set_value($value) {
423 423
         // Must override this, otherwise the semicolon separating
424 424
         // the two floats would get auto-quoted, which is illegal
425
-        if($this->is_valid_value($value)) {
425
+        if ($this->is_valid_value($value)) {
426 426
             $this->value = $value;
427 427
             return true;
428 428
         }
@@ -458,7 +458,7 @@  discard block
 block discarded – undo
458 458
 
459 459
     function is_valid_value($value) {
460 460
         // Only integers between 0 and 100 inclusive allowed
461
-        if(!parent::is_valid_value($value)) {
461
+        if (!parent::is_valid_value($value)) {
462 462
             return false;
463 463
         }
464 464
         $value = intval($value);
@@ -479,7 +479,7 @@  discard block
 block discarded – undo
479 479
 
480 480
     function is_valid_value($value) {
481 481
         // Only integers between 0 and 9 inclusive allowed        
482
-        if(!parent::is_valid_value($value)) {
482
+        if (!parent::is_valid_value($value)) {
483 483
             return false;
484 484
         }
485 485
 
@@ -561,7 +561,7 @@  discard block
 block discarded – undo
561 561
     }
562 562
 
563 563
     function is_valid_value($value) {
564
-        if(!parent::is_valid_value($value)) {
564
+        if (!parent::is_valid_value($value)) {
565 565
             return false;
566 566
         }
567 567
         // Time MUST be in UTC format
@@ -583,12 +583,12 @@  discard block
 block discarded – undo
583 583
     }
584 584
 
585 585
     function is_valid_value($value) {
586
-        if(!parent::is_valid_value($value)) {
586
+        if (!parent::is_valid_value($value)) {
587 587
             return false;
588 588
         }
589 589
 
590 590
         // If present in a FREEBUSY component, must be in UTC format
591
-        if($this->parent_component == 'VFREEBUSY' && substr($value, -1) != 'Z') {
591
+        if ($this->parent_component == 'VFREEBUSY' && substr($value, -1) != 'Z') {
592 592
             return false;
593 593
         }
594 594
 
@@ -600,10 +600,10 @@  discard block
 block discarded – undo
600 600
 
601 601
         $parameter = strtoupper($parameter);
602 602
 
603
-        if(!parent::is_valid_parameter($parameter, $value)) {
603
+        if (!parent::is_valid_parameter($parameter, $value)) {
604 604
             return false;
605 605
         }
606
-        if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
606
+        if ($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
607 607
             return false;
608 608
         }
609 609
 
@@ -625,12 +625,12 @@  discard block
 block discarded – undo
625 625
     }
626 626
 
627 627
     function is_valid_value($value) {
628
-        if(!parent::is_valid_value($value)) {
628
+        if (!parent::is_valid_value($value)) {
629 629
             return false;
630 630
         }
631 631
 
632 632
         // If present in a FREEBUSY component, must be in UTC format
633
-        if($this->parent_component == 'VFREEBUSY' && substr($value, -1) != 'Z') {
633
+        if ($this->parent_component == 'VFREEBUSY' && substr($value, -1) != 'Z') {
634 634
             return false;
635 635
         }
636 636
 
@@ -642,10 +642,10 @@  discard block
 block discarded – undo
642 642
 
643 643
         $parameter = strtoupper($parameter);
644 644
 
645
-        if(!parent::is_valid_parameter($parameter, $value)) {
645
+        if (!parent::is_valid_parameter($parameter, $value)) {
646 646
             return false;
647 647
         }
648
-        if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
648
+        if ($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
649 649
             return false;
650 650
         }
651 651
 
@@ -669,12 +669,12 @@  discard block
 block discarded – undo
669 669
     // TODO: unimplemented stuff when parent is a VTIMEZONE component
670 670
 
671 671
     function is_valid_value($value) {
672
-        if(!parent::is_valid_value($value)) {
672
+        if (!parent::is_valid_value($value)) {
673 673
             return false;
674 674
         }
675 675
 
676 676
         // If present in a FREEBUSY component, must be in UTC format
677
-        if($this->parent_component == 'VFREEBUSY' && substr($value, -1) != 'Z') {
677
+        if ($this->parent_component == 'VFREEBUSY' && substr($value, -1) != 'Z') {
678 678
             return false;
679 679
         }
680 680
 
@@ -685,10 +685,10 @@  discard block
 block discarded – undo
685 685
 
686 686
         $parameter = strtoupper($parameter);
687 687
 
688
-        if(!parent::is_valid_parameter($parameter, $value)) {
688
+        if (!parent::is_valid_parameter($parameter, $value)) {
689 689
             return false;
690 690
         }
691
-        if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
691
+        if ($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
692 692
             return false;
693 693
         }
694 694
 
@@ -708,7 +708,7 @@  discard block
 block discarded – undo
708 708
     }
709 709
 
710 710
     function is_valid_value($value) {
711
-        if(!parent::is_valid_value($value)) {
711
+        if (!parent::is_valid_value($value)) {
712 712
             return false;
713 713
         }
714 714
 
@@ -731,16 +731,16 @@  discard block
 block discarded – undo
731 731
     }
732 732
 
733 733
     function is_valid_value($value) {
734
-        if(!parent::is_valid_value($value)) {
734
+        if (!parent::is_valid_value($value)) {
735 735
             return false;
736 736
         }
737 737
 
738 738
         $pos = strpos($value, '/'); // We know there's only one / in there
739
-        if($value{$pos - 1} != 'Z') {
739
+        if ($value{$pos - 1} != 'Z') {
740 740
             // Start time MUST be in UTC
741 741
             return false;
742 742
         }
743
-        if($value{$pos + 1} != 'P' && $substr($value, -1) != 'Z') {
743
+        if ($value{$pos + 1} != 'P' && $substr($value, -1) != 'Z') {
744 744
             // If the second part is not a period, it MUST be in UTC
745 745
             return false;
746 746
         }
@@ -800,11 +800,11 @@  discard block
 block discarded – undo
800 800
     }
801 801
 
802 802
     function set_parent_component($componentname) {
803
-        if(!parent::set_parent_component($componentname)) {
803
+        if (!parent::set_parent_component($componentname)) {
804 804
             return false;
805 805
         }
806 806
 
807
-        if($this->parent_component == 'VFREEBUSY' || $this->parent_component == 'VALARM') {
807
+        if ($this->parent_component == 'VFREEBUSY' || $this->parent_component == 'VALARM') {
808 808
             // Most parameters become invalid in this case, the full allowed set is now:
809 809
             $this->valid_parameters = array(
810 810
                 'LANGUAGE'       => RFC2445_OPTIONAL | RFC2445_ONCE,
@@ -888,10 +888,10 @@  discard block
 block discarded – undo
888 888
 
889 889
         $parameter = strtoupper($parameter);
890 890
 
891
-        if(!parent::is_valid_parameter($parameter, $value)) {
891
+        if (!parent::is_valid_parameter($parameter, $value)) {
892 892
             return false;
893 893
         }
894
-        if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
894
+        if ($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
895 895
             return false;
896 896
         }
897 897
 
@@ -964,10 +964,10 @@  discard block
 block discarded – undo
964 964
 
965 965
         $parameter = strtoupper($parameter);
966 966
 
967
-        if(!parent::is_valid_parameter($parameter, $value)) {
967
+        if (!parent::is_valid_parameter($parameter, $value)) {
968 968
             return false;
969 969
         }
970
-        if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
970
+        if ($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME')) {
971 971
             return false;
972 972
         }
973 973
 
@@ -1005,10 +1005,10 @@  discard block
 block discarded – undo
1005 1005
 
1006 1006
         $parameter = strtoupper($parameter);
1007 1007
 
1008
-        if(!parent::is_valid_parameter($parameter, $value)) {
1008
+        if (!parent::is_valid_parameter($parameter, $value)) {
1009 1009
             return false;
1010 1010
         }
1011
-        if($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME' || $value == 'PERIOD')) {
1011
+        if ($parameter == 'VALUE' && !($value == 'DATE' || $value == 'DATE-TIME' || $value == 'PERIOD')) {
1012 1012
             return false;
1013 1013
         }
1014 1014
 
@@ -1045,7 +1045,7 @@  discard block
 block discarded – undo
1045 1045
     }
1046 1046
 
1047 1047
     function is_valid_value($value) {
1048
-        if(!parent::is_valid_value($value)) {
1048
+        if (!parent::is_valid_value($value)) {
1049 1049
             return false;
1050 1050
         }
1051 1051
         // Time MUST be in UTC format
@@ -1065,7 +1065,7 @@  discard block
 block discarded – undo
1065 1065
     }
1066 1066
 
1067 1067
     function is_valid_value($value) {
1068
-        if(!parent::is_valid_value($value)) {
1068
+        if (!parent::is_valid_value($value)) {
1069 1069
             return false;
1070 1070
         }
1071 1071
         // Time MUST be in UTC format
@@ -1085,7 +1085,7 @@  discard block
 block discarded – undo
1085 1085
     }
1086 1086
 
1087 1087
     function is_valid_value($value) {
1088
-        if(!parent::is_valid_value($value)) {
1088
+        if (!parent::is_valid_value($value)) {
1089 1089
             return false;
1090 1090
         }
1091 1091
         // Time MUST be in UTC format
@@ -1106,7 +1106,7 @@  discard block
 block discarded – undo
1106 1106
     }
1107 1107
 
1108 1108
     function is_valid_value($value) {
1109
-        if(!parent::is_valid_value($value)) {
1109
+        if (!parent::is_valid_value($value)) {
1110 1110
             return false;
1111 1111
         }
1112 1112
         $value = intval($value);
@@ -1133,7 +1133,7 @@  discard block
 block discarded – undo
1133 1133
 
1134 1134
         $name = strtoupper($name);
1135 1135
 
1136
-        if(rfc2445_is_xname($name)) {
1136
+        if (rfc2445_is_xname($name)) {
1137 1137
             $this->name = $name;
1138 1138
             return true;
1139 1139
         }
@@ -1160,7 +1160,7 @@  discard block
 block discarded – undo
1160 1160
     }
1161 1161
 
1162 1162
     function is_valid_value($value) {
1163
-        if(!is_string($value) || empty($value)) {
1163
+        if (!is_string($value) || empty($value)) {
1164 1164
             return false;
1165 1165
         }
1166 1166
 
@@ -1169,8 +1169,8 @@  discard block
 block discarded – undo
1169 1169
         $from  = 0;
1170 1170
         $escch = false;
1171 1171
 
1172
-        for($i = 0; $i < $len; ++$i) {
1173
-            if($value{$i} == ';' && !$escch) {
1172
+        for ($i = 0; $i < $len; ++$i) {
1173
+            if ($value{$i} == ';' && !$escch) {
1174 1174
                 // Token completed
1175 1175
                 $parts[] = substr($value, $from, $i - $from);
1176 1176
                 $from = $i + 1;
@@ -1186,34 +1186,34 @@  discard block
 block discarded – undo
1186 1186
         $count = count($parts);
1187 1187
 
1188 1188
         // May have 2 or 3 tokens (last one is optional)
1189
-        if($count != 2 && $count != 3) {
1189
+        if ($count != 2 && $count != 3) {
1190 1190
             return false;
1191 1191
         }
1192 1192
 
1193 1193
         // REMEMBER: if ANY part is empty, we have an illegal value
1194 1194
 
1195 1195
         // First token must be hierarchical numeric status (3 levels max)
1196
-        if(strlen($parts[0]) == 0) {
1196
+        if (strlen($parts[0]) == 0) {
1197 1197
             return false;
1198 1198
         }
1199 1199
 
1200
-        if($parts[0]{0} < '1' || $parts[0]{0} > '4') {
1200
+        if ($parts[0]{0} < '1' || $parts[0]{0} > '4') {
1201 1201
             return false;
1202 1202
         }
1203 1203
 
1204 1204
         $len = strlen($parts[0]);
1205 1205
 
1206 1206
         // Max 3 levels, and can't end with a period
1207
-        if($len > 5 || $parts[0]{$len - 1} == '.') {
1207
+        if ($len > 5 || $parts[0]{$len - 1} == '.') {
1208 1208
             return false;
1209 1209
         }
1210 1210
 
1211
-        for($i = 1; $i < $len; ++$i) {
1212
-            if(($i & 1) == 1 && $parts[0]{$i} != '.') {
1211
+        for ($i = 1; $i < $len; ++$i) {
1212
+            if (($i & 1) == 1 && $parts[0]{$i} != '.') {
1213 1213
                 // Even-indexed chars must be periods
1214 1214
                 return false;
1215 1215
             }
1216
-            else if(($i & 1) == 0 && ($parts[0]{$i} < '0' || $parts[0]{$i} > '9')) {
1216
+            else if (($i & 1) == 0 && ($parts[0]{$i} < '0' || $parts[0]{$i} > '9')) {
1217 1217
                 // Odd-indexed chars must be numbers
1218 1218
                 return false;
1219 1219
             }
@@ -1223,25 +1223,25 @@  discard block
 block discarded – undo
1223 1223
         // they are not allowed to have UNESCAPED semicolons, commas, slashes,
1224 1224
         // or any newlines at all
1225 1225
 
1226
-        for($i = 1; $i < $count; ++$i) {
1227
-            if(strpos($parts[$i], "\n") !== false) {
1226
+        for ($i = 1; $i < $count; ++$i) {
1227
+            if (strpos($parts[$i], "\n") !== false) {
1228 1228
                 return false;
1229 1229
             }
1230 1230
 
1231 1231
             $len = strlen($parts[$i]);
1232
-            if($len == 0) {
1232
+            if ($len == 0) {
1233 1233
                 // Cannot be empty
1234 1234
                 return false;
1235 1235
             }
1236 1236
 
1237 1237
             $parts[$i] .= '#'; // This guard token saves some conditionals in the loop
1238 1238
 
1239
-            for($j = 0; $j < $len; ++$j) {
1239
+            for ($j = 0; $j < $len; ++$j) {
1240 1240
                 $thischar = $parts[$i]{$j};
1241 1241
                 $nextchar = $parts[$i]{$j + 1};
1242
-                if($thischar == '\\') {
1242
+                if ($thischar == '\\') {
1243 1243
                     // Next char must now be one of ";,\nN"
1244
-                    if($nextchar != ';' && $nextchar != ',' && $nextchar != '\\' &&
1244
+                    if ($nextchar != ';' && $nextchar != ',' && $nextchar != '\\' &&
1245 1245
                        $nextchar != 'n' && $nextchar != 'N') {
1246 1246
                         return false;
1247 1247
                     }
@@ -1250,7 +1250,7 @@  discard block
 block discarded – undo
1250 1250
                     ++$j;
1251 1251
                     continue;
1252 1252
                 }
1253
-                if($thischar == ';' || $thischar == ',' || $thischar == '\\') {
1253
+                if ($thischar == ';' || $thischar == ',' || $thischar == '\\') {
1254 1254
                     // This wasn't escaped as it should
1255 1255
                     return false;
1256 1256
                 }
@@ -1262,7 +1262,7 @@  discard block
 block discarded – undo
1262 1262
 
1263 1263
     function set_value($value) {
1264 1264
         // Must override this, otherwise the value would be quoted again
1265
-        if($this->is_valid_value($value)) {
1265
+        if ($this->is_valid_value($value)) {
1266 1266
             $this->value = $value;
1267 1267
             return true;
1268 1268
         }
Please login to merge, or discard this patch.
Braces   +6 added lines, -13 removed lines patch added patch discarded remove patch
@@ -62,8 +62,7 @@  discard block
 block discarded – undo
62 62
         if(is_array($value)) {
63 63
             if(!$this->val_multi) {
64 64
                 return false;
65
-            }
66
-            else {
65
+            } else {
67 66
                 foreach($value as $oneval) {
68 67
                     if(!rfc2445_is_valid_value($oneval, $this->val_type)) {
69 68
                         return false;
@@ -96,8 +95,7 @@  discard block
 block discarded – undo
96 95
                     $value[$key] = rfc2445_do_value_formatting($item, $this->val_type);
97 96
                 }
98 97
                 $this->value = implode(',', $value);
99
-            }
100
-            else {
98
+            } else {
101 99
                 $this->value = rfc2445_do_value_formatting($value, $this->val_type);
102 100
             }
103 101
             
@@ -148,8 +146,7 @@  discard block
 block discarded – undo
148 146
             foreach($value as $key => $element) {
149 147
                 $value[$key] = iCalendar_parameter::do_value_formatting($name, $element);
150 148
             }
151
-        }
152
-        else {
149
+        } else {
153 150
             $value = iCalendar_parameter::do_value_formatting($name, $value);
154 151
         }
155 152
 
@@ -180,9 +177,7 @@  discard block
 block discarded – undo
180 177
                     }
181 178
                 }
182 179
                 return $this->parameters[$name];
183
-            }
184
-
185
-            else {
180
+            } else {
186 181
                 if(substr($this->parameters[$name], 0, 1) == '"') {
187 182
                     return substr($this->parameters[$name], 1, strlen($this->parameters[$name]) - 2);
188 183
                 }
@@ -200,8 +195,7 @@  discard block
 block discarded – undo
200 195
                 $string .= ';'.$name.'=';
201 196
                 if(is_array($value)) {
202 197
                     $string .= implode(',', $value);
203
-                }
204
-                else {
198
+                } else {
205 199
                     $string .= $value;
206 200
                 }
207 201
             }
@@ -1212,8 +1206,7 @@  discard block
 block discarded – undo
1212 1206
             if(($i & 1) == 1 && $parts[0]{$i} != '.') {
1213 1207
                 // Even-indexed chars must be periods
1214 1208
                 return false;
1215
-            }
1216
-            else if(($i & 1) == 0 && ($parts[0]{$i} < '0' || $parts[0]{$i} > '9')) {
1209
+            } else if(($i & 1) == 0 && ($parts[0]{$i} < '0' || $parts[0]{$i} > '9')) {
1217 1210
                 // Odd-indexed chars must be numbers
1218 1211
                 return false;
1219 1212
             }
Please login to merge, or discard this patch.
phpicalendar/lib/bennu/iCalendar_rfc2445.php 4 patches
Doc Comments   +6 added lines patch added patch discarded remove patch
@@ -53,6 +53,9 @@  discard block
 block discarded – undo
53 53
 define('RFC2445_TYPE_UTC_OFFSET',  13);
54 54
 
55 55
 
56
+/**
57
+ * @param string $string
58
+ */
56 59
 function rfc2445_fold($string) {
57 60
     if(strlen($string) <= RFC2445_FOLDED_LINE_LENGTH) {
58 61
         return $string;
@@ -79,6 +82,9 @@  discard block
 block discarded – undo
79 82
     return $string;
80 83
 }
81 84
 
85
+/**
86
+ * @param string $name
87
+ */
82 88
 function rfc2445_is_xname($name) {
83 89
 
84 90
     // If it's less than 3 chars, it cannot be legal
Please login to merge, or discard this patch.
Indentation   +678 added lines, -678 removed lines patch added patch discarded remove patch
@@ -54,732 +54,732 @@
 block discarded – undo
54 54
 
55 55
 
56 56
 function rfc2445_fold($string) {
57
-    if(strlen($string) <= RFC2445_FOLDED_LINE_LENGTH) {
58
-        return $string;
59
-    }
57
+	if(strlen($string) <= RFC2445_FOLDED_LINE_LENGTH) {
58
+		return $string;
59
+	}
60 60
 
61
-    $retval = '';
61
+	$retval = '';
62 62
 
63
-    while(strlen($string) > RFC2445_FOLDED_LINE_LENGTH) {
64
-        $retval .= substr($string, 0, RFC2445_FOLDED_LINE_LENGTH - 1) . RFC2445_CRLF . ' ';
65
-        $string  = substr($string, RFC2445_FOLDED_LINE_LENGTH - 1);
66
-    }
63
+	while(strlen($string) > RFC2445_FOLDED_LINE_LENGTH) {
64
+		$retval .= substr($string, 0, RFC2445_FOLDED_LINE_LENGTH - 1) . RFC2445_CRLF . ' ';
65
+		$string  = substr($string, RFC2445_FOLDED_LINE_LENGTH - 1);
66
+	}
67 67
 
68
-    $retval .= $string;
68
+	$retval .= $string;
69 69
     
70
-    return $retval;
70
+	return $retval;
71 71
 
72 72
 }
73 73
 
74 74
 function rfc2445_unfold($string) {
75
-    for($i = 0; $i < strlen(RFC2445_WSP); ++$i) {
76
-        $string = str_replace(RFC2445_CRLF.substr(RFC2445_WSP, $i, 1), '', $string);
77
-    }
75
+	for($i = 0; $i < strlen(RFC2445_WSP); ++$i) {
76
+		$string = str_replace(RFC2445_CRLF.substr(RFC2445_WSP, $i, 1), '', $string);
77
+	}
78 78
 
79
-    return $string;
79
+	return $string;
80 80
 }
81 81
 
82 82
 function rfc2445_is_xname($name) {
83 83
 
84
-    // If it's less than 3 chars, it cannot be legal
85
-    if(strlen($name) < 3) {
86
-        return false;
87
-    }
84
+	// If it's less than 3 chars, it cannot be legal
85
+	if(strlen($name) < 3) {
86
+		return false;
87
+	}
88 88
 
89
-    // If it contains an illegal char anywhere, reject it
90
-    if(strspn($name, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-') != strlen($name)) {
91
-        return false;
92
-    }
89
+	// If it contains an illegal char anywhere, reject it
90
+	if(strspn($name, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-') != strlen($name)) {
91
+		return false;
92
+	}
93 93
 
94
-    // To be legal, it must still start with "X-"
95
-    return substr($name, 0, 2) === 'X-';
94
+	// To be legal, it must still start with "X-"
95
+	return substr($name, 0, 2) === 'X-';
96 96
 }
97 97
 
98 98
 function rfc2445_is_valid_value($value, $type) {
99 99
 
100
-    // This branch should only be taken with xname values
101
-    if($type === NULL) {
102
-        return true;
103
-    }
100
+	// This branch should only be taken with xname values
101
+	if($type === NULL) {
102
+		return true;
103
+	}
104 104
 
105
-    switch($type) {
106
-        case RFC2445_TYPE_CAL_ADDRESS:
107
-        case RFC2445_TYPE_URI:
108
-            if(!is_string($value)) {
109
-                return false;
110
-            }
105
+	switch($type) {
106
+		case RFC2445_TYPE_CAL_ADDRESS:
107
+		case RFC2445_TYPE_URI:
108
+			if(!is_string($value)) {
109
+				return false;
110
+			}
111 111
 
112
-            $valid_schemes = array('ftp', 'http', 'ldap', 'gopher', 'mailto', 'news', 'nntp', 'telnet', 'wais', 'file', 'prospero');
112
+			$valid_schemes = array('ftp', 'http', 'ldap', 'gopher', 'mailto', 'news', 'nntp', 'telnet', 'wais', 'file', 'prospero');
113 113
 
114
-            $pos = strpos($value, ':');
115
-            if(!$pos) {
116
-                return false;
117
-            }
114
+			$pos = strpos($value, ':');
115
+			if(!$pos) {
116
+				return false;
117
+			}
118 118
         
119
-            $scheme = strtolower(substr($value, 0, $pos));
120
-            $remain = substr($value, $pos + 1);
119
+			$scheme = strtolower(substr($value, 0, $pos));
120
+			$remain = substr($value, $pos + 1);
121 121
             
122
-            if(!in_array($scheme, $valid_schemes)) {
123
-                return false;
124
-            }
122
+			if(!in_array($scheme, $valid_schemes)) {
123
+				return false;
124
+			}
125 125
         
126
-            if($scheme === 'mailto') {
127
-                $regexp = '^[a-zA-Z0-9]+[_a-zA-Z0-9\-]*(\.[_a-z0-9\-]+)*@(([0-9a-zA-Z\-]+\.)+[a-zA-Z][0-9a-zA-Z\-]+|([0-9]{1,3}\.){3}[0-9]{1,3})$';
128
-            }
129
-            else {
130
-                $regexp = '^//(.+(:.*)?@)?(([0-9a-zA-Z\-]+\.)+[a-zA-Z][0-9a-zA-Z\-]+|([0-9]{1,3}\.){3}[0-9]{1,3})(:[0-9]{1,5})?(/.*)?$';
131
-            }
126
+			if($scheme === 'mailto') {
127
+				$regexp = '^[a-zA-Z0-9]+[_a-zA-Z0-9\-]*(\.[_a-z0-9\-]+)*@(([0-9a-zA-Z\-]+\.)+[a-zA-Z][0-9a-zA-Z\-]+|([0-9]{1,3}\.){3}[0-9]{1,3})$';
128
+			}
129
+			else {
130
+				$regexp = '^//(.+(:.*)?@)?(([0-9a-zA-Z\-]+\.)+[a-zA-Z][0-9a-zA-Z\-]+|([0-9]{1,3}\.){3}[0-9]{1,3})(:[0-9]{1,5})?(/.*)?$';
131
+			}
132 132
         
133
-            return ereg($regexp, $remain);
134
-        break;
133
+			return ereg($regexp, $remain);
134
+		break;
135 135
 
136
-        case RFC2445_TYPE_BINARY:
137
-            if(!is_string($value)) {
138
-                return false;
139
-            }
136
+		case RFC2445_TYPE_BINARY:
137
+			if(!is_string($value)) {
138
+				return false;
139
+			}
140 140
 
141
-            $len = strlen($value);
141
+			$len = strlen($value);
142 142
             
143
-            if($len % 4 != 0) {
144
-                return false;
145
-            }
146
-
147
-            for($i = 0; $i < $len; ++$i) {
148
-                $ch = $value{$i};
149
-                if(!($ch >= 'a' && $ch <= 'z' || $ch >= 'A' && $ch <= 'Z' || $ch >= '0' && $ch <= '9' || $ch == '-' || $ch == '+')) {
150
-                    if($ch == '=' && $len - $i <= 2) {
151
-                        continue;
152
-                    }
153
-                    return false;
154
-                }
155
-            }
156
-            return true;
157
-        break;
158
-
159
-        case RFC2445_TYPE_BOOLEAN:
160
-            if(is_bool($value)) {
161
-                return true;
162
-            }
163
-            if(is_string($value)) {
164
-                $value = strtoupper($value);
165
-                return ($value == 'TRUE' || $value == 'FALSE');
166
-            }
167
-            return false;
168
-        break;
169
-
170
-        case RFC2445_TYPE_DATE:
171
-            if(is_int($value)) {
172
-                if($value < 0) {
173
-                    return false;
174
-                }
175
-                $value = "$value";
176
-            }
177
-            else if(!is_string($value)) {
178
-                return false;
179
-            }
180
-
181
-            if(strlen($value) != 8) {
182
-                return false;
183
-            }
184
-
185
-            $y = intval(substr($value, 0, 4));
186
-            $m = intval(substr($value, 4, 2));
187
-            $d = intval(substr($value, 6, 2));
188
-
189
-            return checkdate($m, $d, $y);
190
-        break;
191
-
192
-        case RFC2445_TYPE_DATE_TIME:
193
-            if(!is_string($value) || strlen($value) < 15) {
194
-                return false;
195
-            }
196
-
197
-            return($value{8} == 'T' && 
198
-                   rfc2445_is_valid_value(substr($value, 0, 8), RFC2445_TYPE_DATE) &&
199
-                   rfc2445_is_valid_value(substr($value, 9), RFC2445_TYPE_TIME));
200
-        break;
201
-
202
-        case RFC2445_TYPE_DURATION:
203
-            if(!is_string($value)) {
204
-                return false;
205
-            }
206
-
207
-            $len = strlen($value);
208
-
209
-            if($len < 3) {
210
-                // Minimum conformant length: "P1W"
211
-                return false;
212
-            }
213
-
214
-            if($value{0} == '+' || $value{0} == '-') {
215
-                $value = substr($value, 1);
216
-                --$len; // Don't forget to update this!
217
-            }
218
-
219
-            if($value{0} != 'P') {
220
-                return false;
221
-            }
222
-
223
-            // OK, now break it up
224
-            $num = '';
225
-            $allowed = 'WDT';
226
-
227
-            for($i = 1; $i < $len; ++$i) {
228
-                $ch = $value{$i};
229
-                if($ch >= '0' && $ch <= '9') {
230
-                    $num .= $ch;
231
-                    continue;
232
-                }
233
-                if(strpos($allowed, $ch) === false) {
234
-                    // Non-numeric character which shouldn't be here
235
-                    return false;
236
-                }
237
-                if($num === '' && $ch != 'T') {
238
-                    // Allowed non-numeric character, but no digits came before it
239
-                    return false;
240
-                }
241
-
242
-                // OK, $ch now holds a character which tells us what $num is
243
-                switch($ch) {
244
-                    case 'W':
245
-                        // If duration in weeks is specified, this must end the string
246
-                        return ($i == $len - 1);
247
-                    break;
248
-
249
-                    case 'D':
250
-                        // Days specified, now if anything comes after it must be a 'T'
251
-                        $allowed = 'T';
252
-                    break;
253
-
254
-                    case 'T':
255
-                        // Starting to specify time, H M S are now valid delimiters
256
-                        $allowed = 'HMS';
257
-                    break;
258
-
259
-                    case 'H':
260
-                        $allowed = 'M';
261
-                    break;
262
-
263
-                    case 'M':
264
-                        $allowed = 'S';
265
-                    break;
266
-
267
-                    case 'S':
268
-                        return ($i == $len - 1);
269
-                    break;
270
-                }
271
-
272
-                // If we 're going to continue, reset $num
273
-                $num = '';
274
-
275
-            }
276
-
277
-            // $num is kept for this reason: if we 're here, we ran out of chars
278
-            // therefore $num must be empty for the period to be legal
279
-            return ($num === '' && $ch != 'T');
280
-
281
-        break;
143
+			if($len % 4 != 0) {
144
+				return false;
145
+			}
146
+
147
+			for($i = 0; $i < $len; ++$i) {
148
+				$ch = $value{$i};
149
+				if(!($ch >= 'a' && $ch <= 'z' || $ch >= 'A' && $ch <= 'Z' || $ch >= '0' && $ch <= '9' || $ch == '-' || $ch == '+')) {
150
+					if($ch == '=' && $len - $i <= 2) {
151
+						continue;
152
+					}
153
+					return false;
154
+				}
155
+			}
156
+			return true;
157
+		break;
158
+
159
+		case RFC2445_TYPE_BOOLEAN:
160
+			if(is_bool($value)) {
161
+				return true;
162
+			}
163
+			if(is_string($value)) {
164
+				$value = strtoupper($value);
165
+				return ($value == 'TRUE' || $value == 'FALSE');
166
+			}
167
+			return false;
168
+		break;
169
+
170
+		case RFC2445_TYPE_DATE:
171
+			if(is_int($value)) {
172
+				if($value < 0) {
173
+					return false;
174
+				}
175
+				$value = "$value";
176
+			}
177
+			else if(!is_string($value)) {
178
+				return false;
179
+			}
180
+
181
+			if(strlen($value) != 8) {
182
+				return false;
183
+			}
184
+
185
+			$y = intval(substr($value, 0, 4));
186
+			$m = intval(substr($value, 4, 2));
187
+			$d = intval(substr($value, 6, 2));
188
+
189
+			return checkdate($m, $d, $y);
190
+		break;
191
+
192
+		case RFC2445_TYPE_DATE_TIME:
193
+			if(!is_string($value) || strlen($value) < 15) {
194
+				return false;
195
+			}
196
+
197
+			return($value{8} == 'T' && 
198
+				   rfc2445_is_valid_value(substr($value, 0, 8), RFC2445_TYPE_DATE) &&
199
+				   rfc2445_is_valid_value(substr($value, 9), RFC2445_TYPE_TIME));
200
+		break;
201
+
202
+		case RFC2445_TYPE_DURATION:
203
+			if(!is_string($value)) {
204
+				return false;
205
+			}
206
+
207
+			$len = strlen($value);
208
+
209
+			if($len < 3) {
210
+				// Minimum conformant length: "P1W"
211
+				return false;
212
+			}
213
+
214
+			if($value{0} == '+' || $value{0} == '-') {
215
+				$value = substr($value, 1);
216
+				--$len; // Don't forget to update this!
217
+			}
218
+
219
+			if($value{0} != 'P') {
220
+				return false;
221
+			}
222
+
223
+			// OK, now break it up
224
+			$num = '';
225
+			$allowed = 'WDT';
226
+
227
+			for($i = 1; $i < $len; ++$i) {
228
+				$ch = $value{$i};
229
+				if($ch >= '0' && $ch <= '9') {
230
+					$num .= $ch;
231
+					continue;
232
+				}
233
+				if(strpos($allowed, $ch) === false) {
234
+					// Non-numeric character which shouldn't be here
235
+					return false;
236
+				}
237
+				if($num === '' && $ch != 'T') {
238
+					// Allowed non-numeric character, but no digits came before it
239
+					return false;
240
+				}
241
+
242
+				// OK, $ch now holds a character which tells us what $num is
243
+				switch($ch) {
244
+					case 'W':
245
+						// If duration in weeks is specified, this must end the string
246
+						return ($i == $len - 1);
247
+					break;
248
+
249
+					case 'D':
250
+						// Days specified, now if anything comes after it must be a 'T'
251
+						$allowed = 'T';
252
+					break;
253
+
254
+					case 'T':
255
+						// Starting to specify time, H M S are now valid delimiters
256
+						$allowed = 'HMS';
257
+					break;
258
+
259
+					case 'H':
260
+						$allowed = 'M';
261
+					break;
262
+
263
+					case 'M':
264
+						$allowed = 'S';
265
+					break;
266
+
267
+					case 'S':
268
+						return ($i == $len - 1);
269
+					break;
270
+				}
271
+
272
+				// If we 're going to continue, reset $num
273
+				$num = '';
274
+
275
+			}
276
+
277
+			// $num is kept for this reason: if we 're here, we ran out of chars
278
+			// therefore $num must be empty for the period to be legal
279
+			return ($num === '' && $ch != 'T');
280
+
281
+		break;
282 282
         
283
-        case RFC2445_TYPE_FLOAT:
284
-            if(is_float($value)) {
285
-                return true;
286
-            }
287
-            if(!is_string($value) || $value === '') {
288
-                return false;
289
-            }
290
-
291
-            $dot = false;
292
-            $int = false;
293
-            $len = strlen($value);
294
-            for($i = 0; $i < $len; ++$i) {
295
-                switch($value{$i}) {
296
-                    case '-': case '+':
297
-                        // A sign can only be seen at position 0 and cannot be the only char
298
-                        if($i != 0 || $len == 1) {
299
-                            return false;
300
-                        }
301
-                    break;
302
-                    case '.':
303
-                        // A second dot is an error
304
-                        // Make sure we had at least one int before the dot
305
-                        if($dot || !$int) {
306
-                            return false;
307
-                        }
308
-                        $dot = true;
309
-                        // Make also sure that the float doesn't end with a dot
310
-                        if($i == $len - 1) {
311
-                            return false;
312
-                        }
313
-                    break;
314
-                    case '0': case '1': case '2': case '3': case '4':
315
-                    case '5': case '6': case '7': case '8': case '9':
316
-                        $int = true;
317
-                    break;
318
-                    default:
319
-                        // Any other char is a no-no
320
-                        return false;
321
-                    break;
322
-                }
323
-            }
324
-            return true;
325
-        break;
326
-
327
-        case RFC2445_TYPE_INTEGER:
328
-            if(is_int($value)) {
329
-                return true;
330
-            }
331
-            if(!is_string($value) || $value === '') {
332
-                return false;
333
-            }
334
-
335
-            if($value{0} == '+' || $value{0} == '-') {
336
-                if(strlen($value) == 1) {
337
-                    return false;
338
-                }
339
-                $value = substr($value, 1);
340
-            }
341
-
342
-            if(strspn($value, '0123456789') != strlen($value)) {
343
-                return false;
344
-            }
345
-
346
-            return ($value >= -2147483648 && $value <= 2147483647);
347
-        break;
348
-
349
-        case RFC2445_TYPE_PERIOD:
350
-            if(!is_string($value) || empty($value)) {
351
-                return false;
352
-            }
353
-
354
-            $parts = explode('/', $value);
355
-            if(count($parts) != 2) {
356
-                return false;
357
-            }
358
-
359
-            if(!rfc2445_is_valid_value($parts[0], RFC2445_TYPE_DATE_TIME)) {
360
-                return false;
361
-            }
362
-
363
-            // Two legal cases for the second part:
364
-            if(rfc2445_is_valid_value($parts[1], RFC2445_TYPE_DATE_TIME)) {
365
-                // It has to be after the start time, so
366
-                return ($parts[1] > $parts[0]);
367
-            }
368
-            else if(rfc2445_is_valid_value($parts[1], RFC2445_TYPE_DURATION)) {
369
-                // The period MUST NOT be negative
370
-                return ($parts[1]{0} != '-');
371
-            }
372
-
373
-            // It seems to be illegal
374
-            return false;
375
-        break;
376
-
377
-        case RFC2445_TYPE_RECUR:
378
-            if(!is_string($value)) {
379
-                return false;
380
-            }
381
-
382
-            $parts = explode(';', strtoupper($value));
383
-
384
-            // First of all, we need at least a FREQ and a UNTIL or COUNT part, so...
385
-            if(count($parts) < 2) {
386
-                return false;
387
-            }
388
-
389
-            // Let's get that into a more easily comprehensible format
390
-            $vars = array();
391
-            foreach($parts as $part) {
392
-
393
-                $pieces = explode('=', $part);
394
-                // There must be exactly 2 pieces, e.g. FREQ=WEEKLY
395
-                if(count($pieces) != 2) {
396
-                    return false;
397
-                }
398
-
399
-                // It's illegal for a variable to appear twice
400
-                if(isset($vars[$pieces[0]])) {
401
-                    return false;
402
-                }
403
-
404
-                // Sounds good
405
-                $vars[$pieces[0]] = $pieces[1];
406
-            }
407
-
408
-            // OK... now to test everything else
409
-
410
-            // FREQ must be the first thing appearing
411
-            reset($vars);
412
-            if(key($vars) != 'FREQ') {
413
-                return false;
414
-            }
415
-
416
-            // It's illegal to have both UNTIL and COUNT appear
417
-            if(isset($vars['UNTIL']) && isset($vars['COUNT'])) {
418
-                return false;
419
-            }
420
-
421
-            // Special case: BYWEEKNO is only valid for FREQ=YEARLY
422
-            if(isset($vars['BYWEEKNO']) && $vars['FREQ'] != 'YEARLY') {
423
-                return false;
424
-            }
425
-
426
-            // Special case: BYSETPOS is only valid if another BY option is specified
427
-            if(isset($vars['BYSETPOS'])) {
428
-                $options = array('BYSECOND', 'BYMINUTE', 'BYHOUR', 'BYDAY', 'BYMONTHDAY', 'BYYEARDAY', 'BYWEEKNO', 'BYMONTH');
429
-                $defined = array_keys($vars);
430
-                $common  = array_intersect($options, $defined);
431
-                if(empty($common)) {
432
-                    return false;
433
-                }
434
-            }
435
-
436
-            // OK, now simply check if each element has a valid value,
437
-            // unsetting them on the way. If at the end the array still
438
-            // has some elements, they are illegal.
439
-
440
-            if($vars['FREQ'] != 'SECONDLY' && $vars['FREQ'] != 'MINUTELY' && $vars['FREQ'] != 'HOURLY' && 
441
-               $vars['FREQ'] != 'DAILY'    && $vars['FREQ'] != 'WEEKLY' &&
442
-               $vars['FREQ'] != 'MONTHLY'  && $vars['FREQ'] != 'YEARLY') {
443
-                return false;
444
-            }
445
-            unset($vars['FREQ']);
446
-
447
-            // Set this, we may need it later
448
-            $weekdays = explode(',', RFC2445_WEEKDAYS);
449
-
450
-            if(isset($vars['UNTIL'])) {
451
-                if(rfc2445_is_valid_value($vars['UNTIL'], RFC2445_TYPE_DATE_TIME)) {
452
-                    // The time MUST be in UTC format
453
-                    if(!(substr($vars['UNTIL'], -1) == 'Z')) {
454
-                        return false;
455
-                    }
456
-                }
457
-                else if(!rfc2445_is_valid_value($vars['UNTIL'], RFC2445_TYPE_DATE_TIME)) {
458
-                    return false;
459
-                }
460
-            }
461
-            unset($vars['UNTIL']);
462
-
463
-
464
-            if(isset($vars['COUNT'])) {
465
-                if(empty($vars['COUNT'])) {
466
-                    // This also catches the string '0', which makes no sense
467
-                    return false;
468
-                }
469
-                if(strspn($vars['COUNT'], '0123456789') != strlen($vars['COUNT'])) {
470
-                    return false;
471
-                }
472
-            }
473
-            unset($vars['COUNT']);
283
+		case RFC2445_TYPE_FLOAT:
284
+			if(is_float($value)) {
285
+				return true;
286
+			}
287
+			if(!is_string($value) || $value === '') {
288
+				return false;
289
+			}
290
+
291
+			$dot = false;
292
+			$int = false;
293
+			$len = strlen($value);
294
+			for($i = 0; $i < $len; ++$i) {
295
+				switch($value{$i}) {
296
+					case '-': case '+':
297
+						// A sign can only be seen at position 0 and cannot be the only char
298
+						if($i != 0 || $len == 1) {
299
+							return false;
300
+						}
301
+					break;
302
+					case '.':
303
+						// A second dot is an error
304
+						// Make sure we had at least one int before the dot
305
+						if($dot || !$int) {
306
+							return false;
307
+						}
308
+						$dot = true;
309
+						// Make also sure that the float doesn't end with a dot
310
+						if($i == $len - 1) {
311
+							return false;
312
+						}
313
+					break;
314
+					case '0': case '1': case '2': case '3': case '4':
315
+					case '5': case '6': case '7': case '8': case '9':
316
+						$int = true;
317
+					break;
318
+					default:
319
+						// Any other char is a no-no
320
+						return false;
321
+					break;
322
+				}
323
+			}
324
+			return true;
325
+		break;
326
+
327
+		case RFC2445_TYPE_INTEGER:
328
+			if(is_int($value)) {
329
+				return true;
330
+			}
331
+			if(!is_string($value) || $value === '') {
332
+				return false;
333
+			}
334
+
335
+			if($value{0} == '+' || $value{0} == '-') {
336
+				if(strlen($value) == 1) {
337
+					return false;
338
+				}
339
+				$value = substr($value, 1);
340
+			}
341
+
342
+			if(strspn($value, '0123456789') != strlen($value)) {
343
+				return false;
344
+			}
345
+
346
+			return ($value >= -2147483648 && $value <= 2147483647);
347
+		break;
348
+
349
+		case RFC2445_TYPE_PERIOD:
350
+			if(!is_string($value) || empty($value)) {
351
+				return false;
352
+			}
353
+
354
+			$parts = explode('/', $value);
355
+			if(count($parts) != 2) {
356
+				return false;
357
+			}
358
+
359
+			if(!rfc2445_is_valid_value($parts[0], RFC2445_TYPE_DATE_TIME)) {
360
+				return false;
361
+			}
362
+
363
+			// Two legal cases for the second part:
364
+			if(rfc2445_is_valid_value($parts[1], RFC2445_TYPE_DATE_TIME)) {
365
+				// It has to be after the start time, so
366
+				return ($parts[1] > $parts[0]);
367
+			}
368
+			else if(rfc2445_is_valid_value($parts[1], RFC2445_TYPE_DURATION)) {
369
+				// The period MUST NOT be negative
370
+				return ($parts[1]{0} != '-');
371
+			}
372
+
373
+			// It seems to be illegal
374
+			return false;
375
+		break;
376
+
377
+		case RFC2445_TYPE_RECUR:
378
+			if(!is_string($value)) {
379
+				return false;
380
+			}
381
+
382
+			$parts = explode(';', strtoupper($value));
383
+
384
+			// First of all, we need at least a FREQ and a UNTIL or COUNT part, so...
385
+			if(count($parts) < 2) {
386
+				return false;
387
+			}
388
+
389
+			// Let's get that into a more easily comprehensible format
390
+			$vars = array();
391
+			foreach($parts as $part) {
392
+
393
+				$pieces = explode('=', $part);
394
+				// There must be exactly 2 pieces, e.g. FREQ=WEEKLY
395
+				if(count($pieces) != 2) {
396
+					return false;
397
+				}
398
+
399
+				// It's illegal for a variable to appear twice
400
+				if(isset($vars[$pieces[0]])) {
401
+					return false;
402
+				}
403
+
404
+				// Sounds good
405
+				$vars[$pieces[0]] = $pieces[1];
406
+			}
407
+
408
+			// OK... now to test everything else
409
+
410
+			// FREQ must be the first thing appearing
411
+			reset($vars);
412
+			if(key($vars) != 'FREQ') {
413
+				return false;
414
+			}
415
+
416
+			// It's illegal to have both UNTIL and COUNT appear
417
+			if(isset($vars['UNTIL']) && isset($vars['COUNT'])) {
418
+				return false;
419
+			}
420
+
421
+			// Special case: BYWEEKNO is only valid for FREQ=YEARLY
422
+			if(isset($vars['BYWEEKNO']) && $vars['FREQ'] != 'YEARLY') {
423
+				return false;
424
+			}
425
+
426
+			// Special case: BYSETPOS is only valid if another BY option is specified
427
+			if(isset($vars['BYSETPOS'])) {
428
+				$options = array('BYSECOND', 'BYMINUTE', 'BYHOUR', 'BYDAY', 'BYMONTHDAY', 'BYYEARDAY', 'BYWEEKNO', 'BYMONTH');
429
+				$defined = array_keys($vars);
430
+				$common  = array_intersect($options, $defined);
431
+				if(empty($common)) {
432
+					return false;
433
+				}
434
+			}
435
+
436
+			// OK, now simply check if each element has a valid value,
437
+			// unsetting them on the way. If at the end the array still
438
+			// has some elements, they are illegal.
439
+
440
+			if($vars['FREQ'] != 'SECONDLY' && $vars['FREQ'] != 'MINUTELY' && $vars['FREQ'] != 'HOURLY' && 
441
+			   $vars['FREQ'] != 'DAILY'    && $vars['FREQ'] != 'WEEKLY' &&
442
+			   $vars['FREQ'] != 'MONTHLY'  && $vars['FREQ'] != 'YEARLY') {
443
+				return false;
444
+			}
445
+			unset($vars['FREQ']);
446
+
447
+			// Set this, we may need it later
448
+			$weekdays = explode(',', RFC2445_WEEKDAYS);
449
+
450
+			if(isset($vars['UNTIL'])) {
451
+				if(rfc2445_is_valid_value($vars['UNTIL'], RFC2445_TYPE_DATE_TIME)) {
452
+					// The time MUST be in UTC format
453
+					if(!(substr($vars['UNTIL'], -1) == 'Z')) {
454
+						return false;
455
+					}
456
+				}
457
+				else if(!rfc2445_is_valid_value($vars['UNTIL'], RFC2445_TYPE_DATE_TIME)) {
458
+					return false;
459
+				}
460
+			}
461
+			unset($vars['UNTIL']);
462
+
463
+
464
+			if(isset($vars['COUNT'])) {
465
+				if(empty($vars['COUNT'])) {
466
+					// This also catches the string '0', which makes no sense
467
+					return false;
468
+				}
469
+				if(strspn($vars['COUNT'], '0123456789') != strlen($vars['COUNT'])) {
470
+					return false;
471
+				}
472
+			}
473
+			unset($vars['COUNT']);
474 474
 
475 475
             
476
-            if(isset($vars['INTERVAL'])) {
477
-                if(empty($vars['INTERVAL'])) {
478
-                    // This also catches the string '0', which makes no sense
479
-                    return false;
480
-                }
481
-                if(strspn($vars['INTERVAL'], '0123456789') != strlen($vars['INTERVAL'])) {
482
-                    return false;
483
-                }
484
-            }
485
-            unset($vars['INTERVAL']);
476
+			if(isset($vars['INTERVAL'])) {
477
+				if(empty($vars['INTERVAL'])) {
478
+					// This also catches the string '0', which makes no sense
479
+					return false;
480
+				}
481
+				if(strspn($vars['INTERVAL'], '0123456789') != strlen($vars['INTERVAL'])) {
482
+					return false;
483
+				}
484
+			}
485
+			unset($vars['INTERVAL']);
486 486
 
487 487
             
488
-            if(isset($vars['BYSECOND'])) {
489
-                if($vars['BYSECOND'] == '') {
490
-                    return false;
491
-                }
492
-                // Comma also allowed
493
-                if(strspn($vars['BYSECOND'], '0123456789,') != strlen($vars['BYSECOND'])) {
494
-                    return false;
495
-                }
496
-                $secs = explode(',', $vars['BYSECOND']);
497
-                foreach($secs as $sec) {
498
-                    if($sec == '' || $sec < 0 || $sec > 59) {
499
-                        return false;
500
-                    }
501
-                }
502
-            }
503
-            unset($vars['BYSECOND']);
488
+			if(isset($vars['BYSECOND'])) {
489
+				if($vars['BYSECOND'] == '') {
490
+					return false;
491
+				}
492
+				// Comma also allowed
493
+				if(strspn($vars['BYSECOND'], '0123456789,') != strlen($vars['BYSECOND'])) {
494
+					return false;
495
+				}
496
+				$secs = explode(',', $vars['BYSECOND']);
497
+				foreach($secs as $sec) {
498
+					if($sec == '' || $sec < 0 || $sec > 59) {
499
+						return false;
500
+					}
501
+				}
502
+			}
503
+			unset($vars['BYSECOND']);
504 504
 
505 505
             
506
-            if(isset($vars['BYMINUTE'])) {
507
-                if($vars['BYMINUTE'] == '') {
508
-                    return false;
509
-                }
510
-                // Comma also allowed
511
-                if(strspn($vars['BYMINUTE'], '0123456789,') != strlen($vars['BYMINUTE'])) {
512
-                    return false;
513
-                }
514
-                $mins = explode(',', $vars['BYMINUTE']);
515
-                foreach($mins as $min) {
516
-                    if($min == '' || $min < 0 || $min > 59) {
517
-                        return false;
518
-                    }
519
-                }
520
-            }
521
-            unset($vars['BYMINUTE']);
506
+			if(isset($vars['BYMINUTE'])) {
507
+				if($vars['BYMINUTE'] == '') {
508
+					return false;
509
+				}
510
+				// Comma also allowed
511
+				if(strspn($vars['BYMINUTE'], '0123456789,') != strlen($vars['BYMINUTE'])) {
512
+					return false;
513
+				}
514
+				$mins = explode(',', $vars['BYMINUTE']);
515
+				foreach($mins as $min) {
516
+					if($min == '' || $min < 0 || $min > 59) {
517
+						return false;
518
+					}
519
+				}
520
+			}
521
+			unset($vars['BYMINUTE']);
522 522
 
523 523
             
524
-            if(isset($vars['BYHOUR'])) {
525
-                if($vars['BYHOUR'] == '') {
526
-                    return false;
527
-                }
528
-                // Comma also allowed
529
-                if(strspn($vars['BYHOUR'], '0123456789,') != strlen($vars['BYHOUR'])) {
530
-                    return false;
531
-                }
532
-                $hours = explode(',', $vars['BYHOUR']);
533
-                foreach($hours as $hour) {
534
-                    if($hour == '' || $hour < 0 || $hour > 23) {
535
-                        return false;
536
-                    }
537
-                }
538
-            }
539
-            unset($vars['BYHOUR']);
524
+			if(isset($vars['BYHOUR'])) {
525
+				if($vars['BYHOUR'] == '') {
526
+					return false;
527
+				}
528
+				// Comma also allowed
529
+				if(strspn($vars['BYHOUR'], '0123456789,') != strlen($vars['BYHOUR'])) {
530
+					return false;
531
+				}
532
+				$hours = explode(',', $vars['BYHOUR']);
533
+				foreach($hours as $hour) {
534
+					if($hour == '' || $hour < 0 || $hour > 23) {
535
+						return false;
536
+					}
537
+				}
538
+			}
539
+			unset($vars['BYHOUR']);
540 540
             
541 541
 
542
-            if(isset($vars['BYDAY'])) {
543
-                if(empty($vars['BYDAY'])) {
544
-                    return false;
545
-                }
542
+			if(isset($vars['BYDAY'])) {
543
+				if(empty($vars['BYDAY'])) {
544
+					return false;
545
+				}
546 546
 
547
-                // First off, split up all values we may have
548
-                $days = explode(',', $vars['BYDAY']);
547
+				// First off, split up all values we may have
548
+				$days = explode(',', $vars['BYDAY']);
549 549
                 
550
-                foreach($days as $day) {
551
-                    $daypart = substr($day, -2);
552
-                    if(!in_array($daypart, $weekdays)) {
553
-                        return false;
554
-                    }
555
-
556
-                    if(strlen($day) > 2) {
557
-                        $intpart = substr($day, 0, strlen($day) - 2);
558
-                        if(!rfc2445_is_valid_value($intpart, RFC2445_TYPE_INTEGER)) {
559
-                            return false;
560
-                        }
561
-                        if(intval($intpart) == 0) {
562
-                            return false;
563
-                        }
564
-                    }
565
-                }
566
-            }
567
-            unset($vars['BYDAY']);
568
-
569
-
570
-            if(isset($vars['BYMONTHDAY'])) {
571
-                if(empty($vars['BYMONTHDAY'])) {
572
-                    return false;
573
-                }
574
-                $mdays = explode(',', $vars['BYMONTHDAY']);
575
-                foreach($mdays as $mday) {
576
-                    if(!rfc2445_is_valid_value($mday, RFC2445_TYPE_INTEGER)) {
577
-                        return false;
578
-                    }
579
-                    $mday = abs(intval($mday));
580
-                    if($mday == 0 || $mday > 31) {
581
-                        return false;
582
-                    }
583
-                }
584
-            }
585
-            unset($vars['BYMONTHDAY']);
586
-
587
-
588
-            if(isset($vars['BYYEARDAY'])) {
589
-                if(empty($vars['BYYEARDAY'])) {
590
-                    return false;
591
-                }
592
-                $ydays = explode(',', $vars['BYYEARDAY']);
593
-                foreach($ydays as $yday) {
594
-                    if(!rfc2445_is_valid_value($yday, RFC2445_TYPE_INTEGER)) {
595
-                        return false;
596
-                    }
597
-                    $yday = abs(intval($yday));
598
-                    if($yday == 0 || $yday > 366) {
599
-                        return false;
600
-                    }
601
-                }
602
-            }
603
-            unset($vars['BYYEARDAY']);
604
-
605
-
606
-            if(isset($vars['BYWEEKNO'])) {
607
-                if(empty($vars['BYWEEKNO'])) {
608
-                    return false;
609
-                }
610
-                $weeknos = explode(',', $vars['BYWEEKNO']);
611
-                foreach($weeknos as $weekno) {
612
-                    if(!rfc2445_is_valid_value($weekno, RFC2445_TYPE_INTEGER)) {
613
-                        return false;
614
-                    }
615
-                    $weekno = abs(intval($weekno));
616
-                    if($weekno == 0 || $weekno > 53) {
617
-                        return false;
618
-                    }
619
-                }
620
-            }
621
-            unset($vars['BYWEEKNO']);
622
-
623
-
624
-            if(isset($vars['BYMONTH'])) {
625
-                if(empty($vars['BYMONTH'])) {
626
-                    return false;
627
-                }
628
-                // Comma also allowed
629
-                if(strspn($vars['BYMONTH'], '0123456789,') != strlen($vars['BYMONTH'])) {
630
-                    return false;
631
-                }
632
-                $months = explode(',', $vars['BYMONTH']);
633
-                foreach($months as $month) {
634
-                    if($month == '' || $month < 1 || $month > 12) {
635
-                        return false;
636
-                    }
637
-                }
638
-            }
639
-            unset($vars['BYMONTH']);
640
-
641
-
642
-            if(isset($vars['BYSETPOS'])) {
643
-                if(empty($vars['BYSETPOS'])) {
644
-                    return false;
645
-                }
646
-                $sets = explode(',', $vars['BYSETPOS']);
647
-                foreach($sets as $set) {
648
-                    if(!rfc2445_is_valid_value($set, RFC2445_TYPE_INTEGER)) {
649
-                        return false;
650
-                    }
651
-                    $set = abs(intval($set));
652
-                    if($set == 0 || $set > 366) {
653
-                        return false;
654
-                    }
655
-                }
656
-            }
657
-            unset($vars['BYSETPOS']);
658
-
659
-
660
-            if(isset($vars['WKST'])) {
661
-                if(!in_array($vars['WKST'], $weekdays)) {
662
-                    return false;
663
-                }
664
-            }
665
-            unset($vars['WKST']);
666
-
667
-
668
-            // Any remaining vars must be x-names
669
-            if(empty($vars)) {
670
-                return true;
671
-            }
672
-
673
-            foreach($vars as $name => $var) {
674
-                if(!rfc2445_is_xname($name)) {
675
-                    return false;
676
-                }
677
-            }
678
-
679
-            // At last, all is OK!
680
-            return true;
681
-
682
-        break;
683
-
684
-        case RFC2445_TYPE_TEXT:
685
-            return true;
686
-        break;
687
-
688
-        case RFC2445_TYPE_TIME:
689
-            if(is_int($value)) {
690
-                if($value < 0) {
691
-                    return false;
692
-                }
693
-                $value = "$value";
694
-            }
695
-            else if(!is_string($value)) {
696
-                return false;
697
-            }
698
-
699
-            if(strlen($value) == 7) {
700
-                if(strtoupper(substr($value, -1)) != 'Z') {
701
-                    return false;
702
-                }
703
-                $value = substr($value, 0, 6);
704
-            }
705
-            if(strlen($value) != 6) {
706
-                return false;
707
-            }
708
-
709
-            $h = intval(substr($value, 0, 2));
710
-            $m = intval(substr($value, 2, 2));
711
-            $s = intval(substr($value, 4, 2));
712
-
713
-            return ($h <= 23 && $m <= 59 && $s <= 60);
714
-        break;
715
-
716
-        case RFC2445_TYPE_UTC_OFFSET:
717
-            if(is_int($value)) {
718
-                if($value >= 0) {
719
-                    $value = "+$value";
720
-                }
721
-                else {
722
-                    $value = "$value";
723
-                }
724
-            }
725
-            else if(!is_string($value)) {
726
-                return false;
727
-            }
728
-
729
-            if(strlen($value) == 7) {
730
-                $s = intval(substr($value, 5, 2));
731
-                $value = substr($value, 0, 5);
732
-            }
733
-            if(strlen($value) != 5 || $value == "-0000") {
734
-                return false;
735
-            }
736
-
737
-            if($value{0} != '+' && $value{0} != '-') {
738
-                return false;
739
-            }
740
-
741
-            $h = intval(substr($value, 1, 2));
742
-            $m = intval(substr($value, 3, 2));
743
-
744
-            return ($h <= 23 && $m <= 59 && $s <= 59);
745
-        break;
746
-    }
747
-
748
-    // TODO: remove this assertion
749
-    trigger_error('bad code path', E_USER_WARNING);
750
-    var_dump($type);
751
-    return false;
550
+				foreach($days as $day) {
551
+					$daypart = substr($day, -2);
552
+					if(!in_array($daypart, $weekdays)) {
553
+						return false;
554
+					}
555
+
556
+					if(strlen($day) > 2) {
557
+						$intpart = substr($day, 0, strlen($day) - 2);
558
+						if(!rfc2445_is_valid_value($intpart, RFC2445_TYPE_INTEGER)) {
559
+							return false;
560
+						}
561
+						if(intval($intpart) == 0) {
562
+							return false;
563
+						}
564
+					}
565
+				}
566
+			}
567
+			unset($vars['BYDAY']);
568
+
569
+
570
+			if(isset($vars['BYMONTHDAY'])) {
571
+				if(empty($vars['BYMONTHDAY'])) {
572
+					return false;
573
+				}
574
+				$mdays = explode(',', $vars['BYMONTHDAY']);
575
+				foreach($mdays as $mday) {
576
+					if(!rfc2445_is_valid_value($mday, RFC2445_TYPE_INTEGER)) {
577
+						return false;
578
+					}
579
+					$mday = abs(intval($mday));
580
+					if($mday == 0 || $mday > 31) {
581
+						return false;
582
+					}
583
+				}
584
+			}
585
+			unset($vars['BYMONTHDAY']);
586
+
587
+
588
+			if(isset($vars['BYYEARDAY'])) {
589
+				if(empty($vars['BYYEARDAY'])) {
590
+					return false;
591
+				}
592
+				$ydays = explode(',', $vars['BYYEARDAY']);
593
+				foreach($ydays as $yday) {
594
+					if(!rfc2445_is_valid_value($yday, RFC2445_TYPE_INTEGER)) {
595
+						return false;
596
+					}
597
+					$yday = abs(intval($yday));
598
+					if($yday == 0 || $yday > 366) {
599
+						return false;
600
+					}
601
+				}
602
+			}
603
+			unset($vars['BYYEARDAY']);
604
+
605
+
606
+			if(isset($vars['BYWEEKNO'])) {
607
+				if(empty($vars['BYWEEKNO'])) {
608
+					return false;
609
+				}
610
+				$weeknos = explode(',', $vars['BYWEEKNO']);
611
+				foreach($weeknos as $weekno) {
612
+					if(!rfc2445_is_valid_value($weekno, RFC2445_TYPE_INTEGER)) {
613
+						return false;
614
+					}
615
+					$weekno = abs(intval($weekno));
616
+					if($weekno == 0 || $weekno > 53) {
617
+						return false;
618
+					}
619
+				}
620
+			}
621
+			unset($vars['BYWEEKNO']);
622
+
623
+
624
+			if(isset($vars['BYMONTH'])) {
625
+				if(empty($vars['BYMONTH'])) {
626
+					return false;
627
+				}
628
+				// Comma also allowed
629
+				if(strspn($vars['BYMONTH'], '0123456789,') != strlen($vars['BYMONTH'])) {
630
+					return false;
631
+				}
632
+				$months = explode(',', $vars['BYMONTH']);
633
+				foreach($months as $month) {
634
+					if($month == '' || $month < 1 || $month > 12) {
635
+						return false;
636
+					}
637
+				}
638
+			}
639
+			unset($vars['BYMONTH']);
640
+
641
+
642
+			if(isset($vars['BYSETPOS'])) {
643
+				if(empty($vars['BYSETPOS'])) {
644
+					return false;
645
+				}
646
+				$sets = explode(',', $vars['BYSETPOS']);
647
+				foreach($sets as $set) {
648
+					if(!rfc2445_is_valid_value($set, RFC2445_TYPE_INTEGER)) {
649
+						return false;
650
+					}
651
+					$set = abs(intval($set));
652
+					if($set == 0 || $set > 366) {
653
+						return false;
654
+					}
655
+				}
656
+			}
657
+			unset($vars['BYSETPOS']);
658
+
659
+
660
+			if(isset($vars['WKST'])) {
661
+				if(!in_array($vars['WKST'], $weekdays)) {
662
+					return false;
663
+				}
664
+			}
665
+			unset($vars['WKST']);
666
+
667
+
668
+			// Any remaining vars must be x-names
669
+			if(empty($vars)) {
670
+				return true;
671
+			}
672
+
673
+			foreach($vars as $name => $var) {
674
+				if(!rfc2445_is_xname($name)) {
675
+					return false;
676
+				}
677
+			}
678
+
679
+			// At last, all is OK!
680
+			return true;
681
+
682
+		break;
683
+
684
+		case RFC2445_TYPE_TEXT:
685
+			return true;
686
+		break;
687
+
688
+		case RFC2445_TYPE_TIME:
689
+			if(is_int($value)) {
690
+				if($value < 0) {
691
+					return false;
692
+				}
693
+				$value = "$value";
694
+			}
695
+			else if(!is_string($value)) {
696
+				return false;
697
+			}
698
+
699
+			if(strlen($value) == 7) {
700
+				if(strtoupper(substr($value, -1)) != 'Z') {
701
+					return false;
702
+				}
703
+				$value = substr($value, 0, 6);
704
+			}
705
+			if(strlen($value) != 6) {
706
+				return false;
707
+			}
708
+
709
+			$h = intval(substr($value, 0, 2));
710
+			$m = intval(substr($value, 2, 2));
711
+			$s = intval(substr($value, 4, 2));
712
+
713
+			return ($h <= 23 && $m <= 59 && $s <= 60);
714
+		break;
715
+
716
+		case RFC2445_TYPE_UTC_OFFSET:
717
+			if(is_int($value)) {
718
+				if($value >= 0) {
719
+					$value = "+$value";
720
+				}
721
+				else {
722
+					$value = "$value";
723
+				}
724
+			}
725
+			else if(!is_string($value)) {
726
+				return false;
727
+			}
728
+
729
+			if(strlen($value) == 7) {
730
+				$s = intval(substr($value, 5, 2));
731
+				$value = substr($value, 0, 5);
732
+			}
733
+			if(strlen($value) != 5 || $value == "-0000") {
734
+				return false;
735
+			}
736
+
737
+			if($value{0} != '+' && $value{0} != '-') {
738
+				return false;
739
+			}
740
+
741
+			$h = intval(substr($value, 1, 2));
742
+			$m = intval(substr($value, 3, 2));
743
+
744
+			return ($h <= 23 && $m <= 59 && $s <= 59);
745
+		break;
746
+	}
747
+
748
+	// TODO: remove this assertion
749
+	trigger_error('bad code path', E_USER_WARNING);
750
+	var_dump($type);
751
+	return false;
752 752
 }
753 753
 
754 754
 function rfc2445_do_value_formatting($value, $type) {
755
-    // Note: this does not only do formatting; it also does conversion to string!
756
-    switch($type) {
757
-        case RFC2445_TYPE_CAL_ADDRESS:
758
-        case RFC2445_TYPE_URI:
759
-            // Enclose in double quotes
760
-            $value = '"'.$value.'"';
761
-        break;
762
-        case RFC2445_TYPE_TEXT:
763
-            // Escape entities
764
-            $value = strtr($value, array("\n" => '\\n', '\\' => '\\\\', ',' => '\\,', ';' => '\\;'));
765
-        break;
766
-    }
767
-    return $value;
755
+	// Note: this does not only do formatting; it also does conversion to string!
756
+	switch($type) {
757
+		case RFC2445_TYPE_CAL_ADDRESS:
758
+		case RFC2445_TYPE_URI:
759
+			// Enclose in double quotes
760
+			$value = '"'.$value.'"';
761
+		break;
762
+		case RFC2445_TYPE_TEXT:
763
+			// Escape entities
764
+			$value = strtr($value, array("\n" => '\\n', '\\' => '\\\\', ',' => '\\,', ';' => '\\;'));
765
+		break;
766
+	}
767
+	return $value;
768 768
 }
769 769
 
770 770
 function rfc2445_undo_value_formatting($value, $type) {
771
-    switch($type) {
772
-        case RFC2445_TYPE_CAL_ADDRESS:
773
-        case RFC2445_TYPE_URI:
774
-            // Trim beginning and end double quote
775
-            $value = substr($value, 1, strlen($value) - 2);
776
-        break;
777
-        case RFC2445_TYPE_TEXT:
778
-            // Unescape entities
779
-            $value = strtr($value, array('\\n' => "\n", '\\N' => "\n", '\\\\' => '\\', '\\,' => ',', '\\;' => ';'));
780
-        break;
781
-    }
782
-    return $value;
771
+	switch($type) {
772
+		case RFC2445_TYPE_CAL_ADDRESS:
773
+		case RFC2445_TYPE_URI:
774
+			// Trim beginning and end double quote
775
+			$value = substr($value, 1, strlen($value) - 2);
776
+		break;
777
+		case RFC2445_TYPE_TEXT:
778
+			// Unescape entities
779
+			$value = strtr($value, array('\\n' => "\n", '\\N' => "\n", '\\\\' => '\\', '\\,' => ',', '\\;' => ';'));
780
+		break;
781
+	}
782
+	return $value;
783 783
 }
784 784
 
785 785
 ?>
Please login to merge, or discard this patch.
Spacing   +160 added lines, -160 removed lines patch added patch discarded remove patch
@@ -22,46 +22,46 @@  discard block
 block discarded – undo
22 22
 
23 23
 */
24 24
 
25
-define('RFC2445_CRLF',               "\r\n");
26
-define('RFC2445_WSP',                "\t ");
27
-define('RFC2445_WEEKDAYS',           'MO,TU,WE,TH,FR,SA,SU');
25
+define('RFC2445_CRLF', "\r\n");
26
+define('RFC2445_WSP', "\t ");
27
+define('RFC2445_WEEKDAYS', 'MO,TU,WE,TH,FR,SA,SU');
28 28
 define('RFC2445_FOLDED_LINE_LENGTH', 75);
29 29
 
30 30
 define('RFC2445_REQUIRED', 0x01);
31 31
 define('RFC2445_OPTIONAL', 0x02);
32
-define('RFC2445_ONCE',     0x04);
32
+define('RFC2445_ONCE', 0x04);
33 33
 
34
-define('RFC2445_PROP_FLAGS',       0);
35
-define('RFC2445_PROP_TYPE',        1);
36
-define('RFC2445_PROP_DEFAULT',     2);
34
+define('RFC2445_PROP_FLAGS', 0);
35
+define('RFC2445_PROP_TYPE', 1);
36
+define('RFC2445_PROP_DEFAULT', 2);
37 37
 
38 38
 define('RFC2445_XNAME', 'X-');
39 39
 
40
-define('RFC2445_TYPE_BINARY',       0);
41
-define('RFC2445_TYPE_BOOLEAN',      1);
42
-define('RFC2445_TYPE_CAL_ADDRESS',  2);
43
-define('RFC2445_TYPE_DATE',         3);
44
-define('RFC2445_TYPE_DATE_TIME',    4);
45
-define('RFC2445_TYPE_DURATION',     5);
46
-define('RFC2445_TYPE_FLOAT',        6);
47
-define('RFC2445_TYPE_INTEGER',      7);
48
-define('RFC2445_TYPE_PERIOD',       8);
49
-define('RFC2445_TYPE_RECUR',        9);
50
-define('RFC2445_TYPE_TEXT',        10);
51
-define('RFC2445_TYPE_TIME',        11);
52
-define('RFC2445_TYPE_URI',         12); // CAL_ADDRESS === URI
53
-define('RFC2445_TYPE_UTC_OFFSET',  13);
40
+define('RFC2445_TYPE_BINARY', 0);
41
+define('RFC2445_TYPE_BOOLEAN', 1);
42
+define('RFC2445_TYPE_CAL_ADDRESS', 2);
43
+define('RFC2445_TYPE_DATE', 3);
44
+define('RFC2445_TYPE_DATE_TIME', 4);
45
+define('RFC2445_TYPE_DURATION', 5);
46
+define('RFC2445_TYPE_FLOAT', 6);
47
+define('RFC2445_TYPE_INTEGER', 7);
48
+define('RFC2445_TYPE_PERIOD', 8);
49
+define('RFC2445_TYPE_RECUR', 9);
50
+define('RFC2445_TYPE_TEXT', 10);
51
+define('RFC2445_TYPE_TIME', 11);
52
+define('RFC2445_TYPE_URI', 12); // CAL_ADDRESS === URI
53
+define('RFC2445_TYPE_UTC_OFFSET', 13);
54 54
 
55 55
 
56 56
 function rfc2445_fold($string) {
57
-    if(strlen($string) <= RFC2445_FOLDED_LINE_LENGTH) {
57
+    if (strlen($string) <= RFC2445_FOLDED_LINE_LENGTH) {
58 58
         return $string;
59 59
     }
60 60
 
61 61
     $retval = '';
62 62
 
63
-    while(strlen($string) > RFC2445_FOLDED_LINE_LENGTH) {
64
-        $retval .= substr($string, 0, RFC2445_FOLDED_LINE_LENGTH - 1) . RFC2445_CRLF . ' ';
63
+    while (strlen($string) > RFC2445_FOLDED_LINE_LENGTH) {
64
+        $retval .= substr($string, 0, RFC2445_FOLDED_LINE_LENGTH - 1).RFC2445_CRLF.' ';
65 65
         $string  = substr($string, RFC2445_FOLDED_LINE_LENGTH - 1);
66 66
     }
67 67
 
@@ -72,7 +72,7 @@  discard block
 block discarded – undo
72 72
 }
73 73
 
74 74
 function rfc2445_unfold($string) {
75
-    for($i = 0; $i < strlen(RFC2445_WSP); ++$i) {
75
+    for ($i = 0; $i < strlen(RFC2445_WSP); ++$i) {
76 76
         $string = str_replace(RFC2445_CRLF.substr(RFC2445_WSP, $i, 1), '', $string);
77 77
     }
78 78
 
@@ -82,12 +82,12 @@  discard block
 block discarded – undo
82 82
 function rfc2445_is_xname($name) {
83 83
 
84 84
     // If it's less than 3 chars, it cannot be legal
85
-    if(strlen($name) < 3) {
85
+    if (strlen($name) < 3) {
86 86
         return false;
87 87
     }
88 88
 
89 89
     // If it contains an illegal char anywhere, reject it
90
-    if(strspn($name, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-') != strlen($name)) {
90
+    if (strspn($name, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-') != strlen($name)) {
91 91
         return false;
92 92
     }
93 93
 
@@ -98,32 +98,32 @@  discard block
 block discarded – undo
98 98
 function rfc2445_is_valid_value($value, $type) {
99 99
 
100 100
     // This branch should only be taken with xname values
101
-    if($type === NULL) {
101
+    if ($type === NULL) {
102 102
         return true;
103 103
     }
104 104
 
105
-    switch($type) {
105
+    switch ($type) {
106 106
         case RFC2445_TYPE_CAL_ADDRESS:
107 107
         case RFC2445_TYPE_URI:
108
-            if(!is_string($value)) {
108
+            if (!is_string($value)) {
109 109
                 return false;
110 110
             }
111 111
 
112 112
             $valid_schemes = array('ftp', 'http', 'ldap', 'gopher', 'mailto', 'news', 'nntp', 'telnet', 'wais', 'file', 'prospero');
113 113
 
114 114
             $pos = strpos($value, ':');
115
-            if(!$pos) {
115
+            if (!$pos) {
116 116
                 return false;
117 117
             }
118 118
         
119 119
             $scheme = strtolower(substr($value, 0, $pos));
120 120
             $remain = substr($value, $pos + 1);
121 121
             
122
-            if(!in_array($scheme, $valid_schemes)) {
122
+            if (!in_array($scheme, $valid_schemes)) {
123 123
                 return false;
124 124
             }
125 125
         
126
-            if($scheme === 'mailto') {
126
+            if ($scheme === 'mailto') {
127 127
                 $regexp = '^[a-zA-Z0-9]+[_a-zA-Z0-9\-]*(\.[_a-z0-9\-]+)*@(([0-9a-zA-Z\-]+\.)+[a-zA-Z][0-9a-zA-Z\-]+|([0-9]{1,3}\.){3}[0-9]{1,3})$';
128 128
             }
129 129
             else {
@@ -134,20 +134,20 @@  discard block
 block discarded – undo
134 134
         break;
135 135
 
136 136
         case RFC2445_TYPE_BINARY:
137
-            if(!is_string($value)) {
137
+            if (!is_string($value)) {
138 138
                 return false;
139 139
             }
140 140
 
141 141
             $len = strlen($value);
142 142
             
143
-            if($len % 4 != 0) {
143
+            if ($len%4 != 0) {
144 144
                 return false;
145 145
             }
146 146
 
147
-            for($i = 0; $i < $len; ++$i) {
147
+            for ($i = 0; $i < $len; ++$i) {
148 148
                 $ch = $value{$i};
149
-                if(!($ch >= 'a' && $ch <= 'z' || $ch >= 'A' && $ch <= 'Z' || $ch >= '0' && $ch <= '9' || $ch == '-' || $ch == '+')) {
150
-                    if($ch == '=' && $len - $i <= 2) {
149
+                if (!($ch >= 'a' && $ch <= 'z' || $ch >= 'A' && $ch <= 'Z' || $ch >= '0' && $ch <= '9' || $ch == '-' || $ch == '+')) {
150
+                    if ($ch == '=' && $len - $i <= 2) {
151 151
                         continue;
152 152
                     }
153 153
                     return false;
@@ -157,10 +157,10 @@  discard block
 block discarded – undo
157 157
         break;
158 158
 
159 159
         case RFC2445_TYPE_BOOLEAN:
160
-            if(is_bool($value)) {
160
+            if (is_bool($value)) {
161 161
                 return true;
162 162
             }
163
-            if(is_string($value)) {
163
+            if (is_string($value)) {
164 164
                 $value = strtoupper($value);
165 165
                 return ($value == 'TRUE' || $value == 'FALSE');
166 166
             }
@@ -168,17 +168,17 @@  discard block
 block discarded – undo
168 168
         break;
169 169
 
170 170
         case RFC2445_TYPE_DATE:
171
-            if(is_int($value)) {
172
-                if($value < 0) {
171
+            if (is_int($value)) {
172
+                if ($value < 0) {
173 173
                     return false;
174 174
                 }
175 175
                 $value = "$value";
176 176
             }
177
-            else if(!is_string($value)) {
177
+            else if (!is_string($value)) {
178 178
                 return false;
179 179
             }
180 180
 
181
-            if(strlen($value) != 8) {
181
+            if (strlen($value) != 8) {
182 182
                 return false;
183 183
             }
184 184
 
@@ -190,7 +190,7 @@  discard block
 block discarded – undo
190 190
         break;
191 191
 
192 192
         case RFC2445_TYPE_DATE_TIME:
193
-            if(!is_string($value) || strlen($value) < 15) {
193
+            if (!is_string($value) || strlen($value) < 15) {
194 194
                 return false;
195 195
             }
196 196
 
@@ -200,23 +200,23 @@  discard block
 block discarded – undo
200 200
         break;
201 201
 
202 202
         case RFC2445_TYPE_DURATION:
203
-            if(!is_string($value)) {
203
+            if (!is_string($value)) {
204 204
                 return false;
205 205
             }
206 206
 
207 207
             $len = strlen($value);
208 208
 
209
-            if($len < 3) {
209
+            if ($len < 3) {
210 210
                 // Minimum conformant length: "P1W"
211 211
                 return false;
212 212
             }
213 213
 
214
-            if($value{0} == '+' || $value{0} == '-') {
214
+            if ($value{0} == '+' || $value{0} == '-') {
215 215
                 $value = substr($value, 1);
216 216
                 --$len; // Don't forget to update this!
217 217
             }
218 218
 
219
-            if($value{0} != 'P') {
219
+            if ($value{0} != 'P') {
220 220
                 return false;
221 221
             }
222 222
 
@@ -224,23 +224,23 @@  discard block
 block discarded – undo
224 224
             $num = '';
225 225
             $allowed = 'WDT';
226 226
 
227
-            for($i = 1; $i < $len; ++$i) {
227
+            for ($i = 1; $i < $len; ++$i) {
228 228
                 $ch = $value{$i};
229
-                if($ch >= '0' && $ch <= '9') {
229
+                if ($ch >= '0' && $ch <= '9') {
230 230
                     $num .= $ch;
231 231
                     continue;
232 232
                 }
233
-                if(strpos($allowed, $ch) === false) {
233
+                if (strpos($allowed, $ch) === false) {
234 234
                     // Non-numeric character which shouldn't be here
235 235
                     return false;
236 236
                 }
237
-                if($num === '' && $ch != 'T') {
237
+                if ($num === '' && $ch != 'T') {
238 238
                     // Allowed non-numeric character, but no digits came before it
239 239
                     return false;
240 240
                 }
241 241
 
242 242
                 // OK, $ch now holds a character which tells us what $num is
243
-                switch($ch) {
243
+                switch ($ch) {
244 244
                     case 'W':
245 245
                         // If duration in weeks is specified, this must end the string
246 246
                         return ($i == $len - 1);
@@ -281,33 +281,33 @@  discard block
 block discarded – undo
281 281
         break;
282 282
         
283 283
         case RFC2445_TYPE_FLOAT:
284
-            if(is_float($value)) {
284
+            if (is_float($value)) {
285 285
                 return true;
286 286
             }
287
-            if(!is_string($value) || $value === '') {
287
+            if (!is_string($value) || $value === '') {
288 288
                 return false;
289 289
             }
290 290
 
291 291
             $dot = false;
292 292
             $int = false;
293 293
             $len = strlen($value);
294
-            for($i = 0; $i < $len; ++$i) {
295
-                switch($value{$i}) {
294
+            for ($i = 0; $i < $len; ++$i) {
295
+                switch ($value{$i}) {
296 296
                     case '-': case '+':
297 297
                         // A sign can only be seen at position 0 and cannot be the only char
298
-                        if($i != 0 || $len == 1) {
298
+                        if ($i != 0 || $len == 1) {
299 299
                             return false;
300 300
                         }
301 301
                     break;
302 302
                     case '.':
303 303
                         // A second dot is an error
304 304
                         // Make sure we had at least one int before the dot
305
-                        if($dot || !$int) {
305
+                        if ($dot || !$int) {
306 306
                             return false;
307 307
                         }
308 308
                         $dot = true;
309 309
                         // Make also sure that the float doesn't end with a dot
310
-                        if($i == $len - 1) {
310
+                        if ($i == $len - 1) {
311 311
                             return false;
312 312
                         }
313 313
                     break;
@@ -325,21 +325,21 @@  discard block
 block discarded – undo
325 325
         break;
326 326
 
327 327
         case RFC2445_TYPE_INTEGER:
328
-            if(is_int($value)) {
328
+            if (is_int($value)) {
329 329
                 return true;
330 330
             }
331
-            if(!is_string($value) || $value === '') {
331
+            if (!is_string($value) || $value === '') {
332 332
                 return false;
333 333
             }
334 334
 
335
-            if($value{0} == '+' || $value{0} == '-') {
336
-                if(strlen($value) == 1) {
335
+            if ($value{0} == '+' || $value{0} == '-') {
336
+                if (strlen($value) == 1) {
337 337
                     return false;
338 338
                 }
339 339
                 $value = substr($value, 1);
340 340
             }
341 341
 
342
-            if(strspn($value, '0123456789') != strlen($value)) {
342
+            if (strspn($value, '0123456789') != strlen($value)) {
343 343
                 return false;
344 344
             }
345 345
 
@@ -347,25 +347,25 @@  discard block
 block discarded – undo
347 347
         break;
348 348
 
349 349
         case RFC2445_TYPE_PERIOD:
350
-            if(!is_string($value) || empty($value)) {
350
+            if (!is_string($value) || empty($value)) {
351 351
                 return false;
352 352
             }
353 353
 
354 354
             $parts = explode('/', $value);
355
-            if(count($parts) != 2) {
355
+            if (count($parts) != 2) {
356 356
                 return false;
357 357
             }
358 358
 
359
-            if(!rfc2445_is_valid_value($parts[0], RFC2445_TYPE_DATE_TIME)) {
359
+            if (!rfc2445_is_valid_value($parts[0], RFC2445_TYPE_DATE_TIME)) {
360 360
                 return false;
361 361
             }
362 362
 
363 363
             // Two legal cases for the second part:
364
-            if(rfc2445_is_valid_value($parts[1], RFC2445_TYPE_DATE_TIME)) {
364
+            if (rfc2445_is_valid_value($parts[1], RFC2445_TYPE_DATE_TIME)) {
365 365
                 // It has to be after the start time, so
366 366
                 return ($parts[1] > $parts[0]);
367 367
             }
368
-            else if(rfc2445_is_valid_value($parts[1], RFC2445_TYPE_DURATION)) {
368
+            else if (rfc2445_is_valid_value($parts[1], RFC2445_TYPE_DURATION)) {
369 369
                 // The period MUST NOT be negative
370 370
                 return ($parts[1]{0} != '-');
371 371
             }
@@ -375,29 +375,29 @@  discard block
 block discarded – undo
375 375
         break;
376 376
 
377 377
         case RFC2445_TYPE_RECUR:
378
-            if(!is_string($value)) {
378
+            if (!is_string($value)) {
379 379
                 return false;
380 380
             }
381 381
 
382 382
             $parts = explode(';', strtoupper($value));
383 383
 
384 384
             // First of all, we need at least a FREQ and a UNTIL or COUNT part, so...
385
-            if(count($parts) < 2) {
385
+            if (count($parts) < 2) {
386 386
                 return false;
387 387
             }
388 388
 
389 389
             // Let's get that into a more easily comprehensible format
390 390
             $vars = array();
391
-            foreach($parts as $part) {
391
+            foreach ($parts as $part) {
392 392
 
393 393
                 $pieces = explode('=', $part);
394 394
                 // There must be exactly 2 pieces, e.g. FREQ=WEEKLY
395
-                if(count($pieces) != 2) {
395
+                if (count($pieces) != 2) {
396 396
                     return false;
397 397
                 }
398 398
 
399 399
                 // It's illegal for a variable to appear twice
400
-                if(isset($vars[$pieces[0]])) {
400
+                if (isset($vars[$pieces[0]])) {
401 401
                     return false;
402 402
                 }
403 403
 
@@ -409,26 +409,26 @@  discard block
 block discarded – undo
409 409
 
410 410
             // FREQ must be the first thing appearing
411 411
             reset($vars);
412
-            if(key($vars) != 'FREQ') {
412
+            if (key($vars) != 'FREQ') {
413 413
                 return false;
414 414
             }
415 415
 
416 416
             // It's illegal to have both UNTIL and COUNT appear
417
-            if(isset($vars['UNTIL']) && isset($vars['COUNT'])) {
417
+            if (isset($vars['UNTIL']) && isset($vars['COUNT'])) {
418 418
                 return false;
419 419
             }
420 420
 
421 421
             // Special case: BYWEEKNO is only valid for FREQ=YEARLY
422
-            if(isset($vars['BYWEEKNO']) && $vars['FREQ'] != 'YEARLY') {
422
+            if (isset($vars['BYWEEKNO']) && $vars['FREQ'] != 'YEARLY') {
423 423
                 return false;
424 424
             }
425 425
 
426 426
             // Special case: BYSETPOS is only valid if another BY option is specified
427
-            if(isset($vars['BYSETPOS'])) {
427
+            if (isset($vars['BYSETPOS'])) {
428 428
                 $options = array('BYSECOND', 'BYMINUTE', 'BYHOUR', 'BYDAY', 'BYMONTHDAY', 'BYYEARDAY', 'BYWEEKNO', 'BYMONTH');
429 429
                 $defined = array_keys($vars);
430 430
                 $common  = array_intersect($options, $defined);
431
-                if(empty($common)) {
431
+                if (empty($common)) {
432 432
                     return false;
433 433
                 }
434 434
             }
@@ -437,9 +437,9 @@  discard block
 block discarded – undo
437 437
             // unsetting them on the way. If at the end the array still
438 438
             // has some elements, they are illegal.
439 439
 
440
-            if($vars['FREQ'] != 'SECONDLY' && $vars['FREQ'] != 'MINUTELY' && $vars['FREQ'] != 'HOURLY' && 
441
-               $vars['FREQ'] != 'DAILY'    && $vars['FREQ'] != 'WEEKLY' &&
442
-               $vars['FREQ'] != 'MONTHLY'  && $vars['FREQ'] != 'YEARLY') {
440
+            if ($vars['FREQ'] != 'SECONDLY' && $vars['FREQ'] != 'MINUTELY' && $vars['FREQ'] != 'HOURLY' && 
441
+               $vars['FREQ'] != 'DAILY' && $vars['FREQ'] != 'WEEKLY' &&
442
+               $vars['FREQ'] != 'MONTHLY' && $vars['FREQ'] != 'YEARLY') {
443 443
                 return false;
444 444
             }
445 445
             unset($vars['FREQ']);
@@ -447,55 +447,55 @@  discard block
 block discarded – undo
447 447
             // Set this, we may need it later
448 448
             $weekdays = explode(',', RFC2445_WEEKDAYS);
449 449
 
450
-            if(isset($vars['UNTIL'])) {
451
-                if(rfc2445_is_valid_value($vars['UNTIL'], RFC2445_TYPE_DATE_TIME)) {
450
+            if (isset($vars['UNTIL'])) {
451
+                if (rfc2445_is_valid_value($vars['UNTIL'], RFC2445_TYPE_DATE_TIME)) {
452 452
                     // The time MUST be in UTC format
453
-                    if(!(substr($vars['UNTIL'], -1) == 'Z')) {
453
+                    if (!(substr($vars['UNTIL'], -1) == 'Z')) {
454 454
                         return false;
455 455
                     }
456 456
                 }
457
-                else if(!rfc2445_is_valid_value($vars['UNTIL'], RFC2445_TYPE_DATE_TIME)) {
457
+                else if (!rfc2445_is_valid_value($vars['UNTIL'], RFC2445_TYPE_DATE_TIME)) {
458 458
                     return false;
459 459
                 }
460 460
             }
461 461
             unset($vars['UNTIL']);
462 462
 
463 463
 
464
-            if(isset($vars['COUNT'])) {
465
-                if(empty($vars['COUNT'])) {
464
+            if (isset($vars['COUNT'])) {
465
+                if (empty($vars['COUNT'])) {
466 466
                     // This also catches the string '0', which makes no sense
467 467
                     return false;
468 468
                 }
469
-                if(strspn($vars['COUNT'], '0123456789') != strlen($vars['COUNT'])) {
469
+                if (strspn($vars['COUNT'], '0123456789') != strlen($vars['COUNT'])) {
470 470
                     return false;
471 471
                 }
472 472
             }
473 473
             unset($vars['COUNT']);
474 474
 
475 475
             
476
-            if(isset($vars['INTERVAL'])) {
477
-                if(empty($vars['INTERVAL'])) {
476
+            if (isset($vars['INTERVAL'])) {
477
+                if (empty($vars['INTERVAL'])) {
478 478
                     // This also catches the string '0', which makes no sense
479 479
                     return false;
480 480
                 }
481
-                if(strspn($vars['INTERVAL'], '0123456789') != strlen($vars['INTERVAL'])) {
481
+                if (strspn($vars['INTERVAL'], '0123456789') != strlen($vars['INTERVAL'])) {
482 482
                     return false;
483 483
                 }
484 484
             }
485 485
             unset($vars['INTERVAL']);
486 486
 
487 487
             
488
-            if(isset($vars['BYSECOND'])) {
489
-                if($vars['BYSECOND'] == '') {
488
+            if (isset($vars['BYSECOND'])) {
489
+                if ($vars['BYSECOND'] == '') {
490 490
                     return false;
491 491
                 }
492 492
                 // Comma also allowed
493
-                if(strspn($vars['BYSECOND'], '0123456789,') != strlen($vars['BYSECOND'])) {
493
+                if (strspn($vars['BYSECOND'], '0123456789,') != strlen($vars['BYSECOND'])) {
494 494
                     return false;
495 495
                 }
496 496
                 $secs = explode(',', $vars['BYSECOND']);
497
-                foreach($secs as $sec) {
498
-                    if($sec == '' || $sec < 0 || $sec > 59) {
497
+                foreach ($secs as $sec) {
498
+                    if ($sec == '' || $sec < 0 || $sec > 59) {
499 499
                         return false;
500 500
                     }
501 501
                 }
@@ -503,17 +503,17 @@  discard block
 block discarded – undo
503 503
             unset($vars['BYSECOND']);
504 504
 
505 505
             
506
-            if(isset($vars['BYMINUTE'])) {
507
-                if($vars['BYMINUTE'] == '') {
506
+            if (isset($vars['BYMINUTE'])) {
507
+                if ($vars['BYMINUTE'] == '') {
508 508
                     return false;
509 509
                 }
510 510
                 // Comma also allowed
511
-                if(strspn($vars['BYMINUTE'], '0123456789,') != strlen($vars['BYMINUTE'])) {
511
+                if (strspn($vars['BYMINUTE'], '0123456789,') != strlen($vars['BYMINUTE'])) {
512 512
                     return false;
513 513
                 }
514 514
                 $mins = explode(',', $vars['BYMINUTE']);
515
-                foreach($mins as $min) {
516
-                    if($min == '' || $min < 0 || $min > 59) {
515
+                foreach ($mins as $min) {
516
+                    if ($min == '' || $min < 0 || $min > 59) {
517 517
                         return false;
518 518
                     }
519 519
                 }
@@ -521,17 +521,17 @@  discard block
 block discarded – undo
521 521
             unset($vars['BYMINUTE']);
522 522
 
523 523
             
524
-            if(isset($vars['BYHOUR'])) {
525
-                if($vars['BYHOUR'] == '') {
524
+            if (isset($vars['BYHOUR'])) {
525
+                if ($vars['BYHOUR'] == '') {
526 526
                     return false;
527 527
                 }
528 528
                 // Comma also allowed
529
-                if(strspn($vars['BYHOUR'], '0123456789,') != strlen($vars['BYHOUR'])) {
529
+                if (strspn($vars['BYHOUR'], '0123456789,') != strlen($vars['BYHOUR'])) {
530 530
                     return false;
531 531
                 }
532 532
                 $hours = explode(',', $vars['BYHOUR']);
533
-                foreach($hours as $hour) {
534
-                    if($hour == '' || $hour < 0 || $hour > 23) {
533
+                foreach ($hours as $hour) {
534
+                    if ($hour == '' || $hour < 0 || $hour > 23) {
535 535
                         return false;
536 536
                     }
537 537
                 }
@@ -539,26 +539,26 @@  discard block
 block discarded – undo
539 539
             unset($vars['BYHOUR']);
540 540
             
541 541
 
542
-            if(isset($vars['BYDAY'])) {
543
-                if(empty($vars['BYDAY'])) {
542
+            if (isset($vars['BYDAY'])) {
543
+                if (empty($vars['BYDAY'])) {
544 544
                     return false;
545 545
                 }
546 546
 
547 547
                 // First off, split up all values we may have
548 548
                 $days = explode(',', $vars['BYDAY']);
549 549
                 
550
-                foreach($days as $day) {
550
+                foreach ($days as $day) {
551 551
                     $daypart = substr($day, -2);
552
-                    if(!in_array($daypart, $weekdays)) {
552
+                    if (!in_array($daypart, $weekdays)) {
553 553
                         return false;
554 554
                     }
555 555
 
556
-                    if(strlen($day) > 2) {
556
+                    if (strlen($day) > 2) {
557 557
                         $intpart = substr($day, 0, strlen($day) - 2);
558
-                        if(!rfc2445_is_valid_value($intpart, RFC2445_TYPE_INTEGER)) {
558
+                        if (!rfc2445_is_valid_value($intpart, RFC2445_TYPE_INTEGER)) {
559 559
                             return false;
560 560
                         }
561
-                        if(intval($intpart) == 0) {
561
+                        if (intval($intpart) == 0) {
562 562
                             return false;
563 563
                         }
564 564
                     }
@@ -567,17 +567,17 @@  discard block
 block discarded – undo
567 567
             unset($vars['BYDAY']);
568 568
 
569 569
 
570
-            if(isset($vars['BYMONTHDAY'])) {
571
-                if(empty($vars['BYMONTHDAY'])) {
570
+            if (isset($vars['BYMONTHDAY'])) {
571
+                if (empty($vars['BYMONTHDAY'])) {
572 572
                     return false;
573 573
                 }
574 574
                 $mdays = explode(',', $vars['BYMONTHDAY']);
575
-                foreach($mdays as $mday) {
576
-                    if(!rfc2445_is_valid_value($mday, RFC2445_TYPE_INTEGER)) {
575
+                foreach ($mdays as $mday) {
576
+                    if (!rfc2445_is_valid_value($mday, RFC2445_TYPE_INTEGER)) {
577 577
                         return false;
578 578
                     }
579 579
                     $mday = abs(intval($mday));
580
-                    if($mday == 0 || $mday > 31) {
580
+                    if ($mday == 0 || $mday > 31) {
581 581
                         return false;
582 582
                     }
583 583
                 }
@@ -585,17 +585,17 @@  discard block
 block discarded – undo
585 585
             unset($vars['BYMONTHDAY']);
586 586
 
587 587
 
588
-            if(isset($vars['BYYEARDAY'])) {
589
-                if(empty($vars['BYYEARDAY'])) {
588
+            if (isset($vars['BYYEARDAY'])) {
589
+                if (empty($vars['BYYEARDAY'])) {
590 590
                     return false;
591 591
                 }
592 592
                 $ydays = explode(',', $vars['BYYEARDAY']);
593
-                foreach($ydays as $yday) {
594
-                    if(!rfc2445_is_valid_value($yday, RFC2445_TYPE_INTEGER)) {
593
+                foreach ($ydays as $yday) {
594
+                    if (!rfc2445_is_valid_value($yday, RFC2445_TYPE_INTEGER)) {
595 595
                         return false;
596 596
                     }
597 597
                     $yday = abs(intval($yday));
598
-                    if($yday == 0 || $yday > 366) {
598
+                    if ($yday == 0 || $yday > 366) {
599 599
                         return false;
600 600
                     }
601 601
                 }
@@ -603,17 +603,17 @@  discard block
 block discarded – undo
603 603
             unset($vars['BYYEARDAY']);
604 604
 
605 605
 
606
-            if(isset($vars['BYWEEKNO'])) {
607
-                if(empty($vars['BYWEEKNO'])) {
606
+            if (isset($vars['BYWEEKNO'])) {
607
+                if (empty($vars['BYWEEKNO'])) {
608 608
                     return false;
609 609
                 }
610 610
                 $weeknos = explode(',', $vars['BYWEEKNO']);
611
-                foreach($weeknos as $weekno) {
612
-                    if(!rfc2445_is_valid_value($weekno, RFC2445_TYPE_INTEGER)) {
611
+                foreach ($weeknos as $weekno) {
612
+                    if (!rfc2445_is_valid_value($weekno, RFC2445_TYPE_INTEGER)) {
613 613
                         return false;
614 614
                     }
615 615
                     $weekno = abs(intval($weekno));
616
-                    if($weekno == 0 || $weekno > 53) {
616
+                    if ($weekno == 0 || $weekno > 53) {
617 617
                         return false;
618 618
                     }
619 619
                 }
@@ -621,17 +621,17 @@  discard block
 block discarded – undo
621 621
             unset($vars['BYWEEKNO']);
622 622
 
623 623
 
624
-            if(isset($vars['BYMONTH'])) {
625
-                if(empty($vars['BYMONTH'])) {
624
+            if (isset($vars['BYMONTH'])) {
625
+                if (empty($vars['BYMONTH'])) {
626 626
                     return false;
627 627
                 }
628 628
                 // Comma also allowed
629
-                if(strspn($vars['BYMONTH'], '0123456789,') != strlen($vars['BYMONTH'])) {
629
+                if (strspn($vars['BYMONTH'], '0123456789,') != strlen($vars['BYMONTH'])) {
630 630
                     return false;
631 631
                 }
632 632
                 $months = explode(',', $vars['BYMONTH']);
633
-                foreach($months as $month) {
634
-                    if($month == '' || $month < 1 || $month > 12) {
633
+                foreach ($months as $month) {
634
+                    if ($month == '' || $month < 1 || $month > 12) {
635 635
                         return false;
636 636
                     }
637 637
                 }
@@ -639,17 +639,17 @@  discard block
 block discarded – undo
639 639
             unset($vars['BYMONTH']);
640 640
 
641 641
 
642
-            if(isset($vars['BYSETPOS'])) {
643
-                if(empty($vars['BYSETPOS'])) {
642
+            if (isset($vars['BYSETPOS'])) {
643
+                if (empty($vars['BYSETPOS'])) {
644 644
                     return false;
645 645
                 }
646 646
                 $sets = explode(',', $vars['BYSETPOS']);
647
-                foreach($sets as $set) {
648
-                    if(!rfc2445_is_valid_value($set, RFC2445_TYPE_INTEGER)) {
647
+                foreach ($sets as $set) {
648
+                    if (!rfc2445_is_valid_value($set, RFC2445_TYPE_INTEGER)) {
649 649
                         return false;
650 650
                     }
651 651
                     $set = abs(intval($set));
652
-                    if($set == 0 || $set > 366) {
652
+                    if ($set == 0 || $set > 366) {
653 653
                         return false;
654 654
                     }
655 655
                 }
@@ -657,8 +657,8 @@  discard block
 block discarded – undo
657 657
             unset($vars['BYSETPOS']);
658 658
 
659 659
 
660
-            if(isset($vars['WKST'])) {
661
-                if(!in_array($vars['WKST'], $weekdays)) {
660
+            if (isset($vars['WKST'])) {
661
+                if (!in_array($vars['WKST'], $weekdays)) {
662 662
                     return false;
663 663
                 }
664 664
             }
@@ -666,12 +666,12 @@  discard block
 block discarded – undo
666 666
 
667 667
 
668 668
             // Any remaining vars must be x-names
669
-            if(empty($vars)) {
669
+            if (empty($vars)) {
670 670
                 return true;
671 671
             }
672 672
 
673
-            foreach($vars as $name => $var) {
674
-                if(!rfc2445_is_xname($name)) {
673
+            foreach ($vars as $name => $var) {
674
+                if (!rfc2445_is_xname($name)) {
675 675
                     return false;
676 676
                 }
677 677
             }
@@ -686,23 +686,23 @@  discard block
 block discarded – undo
686 686
         break;
687 687
 
688 688
         case RFC2445_TYPE_TIME:
689
-            if(is_int($value)) {
690
-                if($value < 0) {
689
+            if (is_int($value)) {
690
+                if ($value < 0) {
691 691
                     return false;
692 692
                 }
693 693
                 $value = "$value";
694 694
             }
695
-            else if(!is_string($value)) {
695
+            else if (!is_string($value)) {
696 696
                 return false;
697 697
             }
698 698
 
699
-            if(strlen($value) == 7) {
700
-                if(strtoupper(substr($value, -1)) != 'Z') {
699
+            if (strlen($value) == 7) {
700
+                if (strtoupper(substr($value, -1)) != 'Z') {
701 701
                     return false;
702 702
                 }
703 703
                 $value = substr($value, 0, 6);
704 704
             }
705
-            if(strlen($value) != 6) {
705
+            if (strlen($value) != 6) {
706 706
                 return false;
707 707
             }
708 708
 
@@ -714,27 +714,27 @@  discard block
 block discarded – undo
714 714
         break;
715 715
 
716 716
         case RFC2445_TYPE_UTC_OFFSET:
717
-            if(is_int($value)) {
718
-                if($value >= 0) {
717
+            if (is_int($value)) {
718
+                if ($value >= 0) {
719 719
                     $value = "+$value";
720 720
                 }
721 721
                 else {
722 722
                     $value = "$value";
723 723
                 }
724 724
             }
725
-            else if(!is_string($value)) {
725
+            else if (!is_string($value)) {
726 726
                 return false;
727 727
             }
728 728
 
729
-            if(strlen($value) == 7) {
729
+            if (strlen($value) == 7) {
730 730
                 $s = intval(substr($value, 5, 2));
731 731
                 $value = substr($value, 0, 5);
732 732
             }
733
-            if(strlen($value) != 5 || $value == "-0000") {
733
+            if (strlen($value) != 5 || $value == "-0000") {
734 734
                 return false;
735 735
             }
736 736
 
737
-            if($value{0} != '+' && $value{0} != '-') {
737
+            if ($value{0} != '+' && $value{0} != '-') {
738 738
                 return false;
739 739
             }
740 740
 
@@ -753,7 +753,7 @@  discard block
 block discarded – undo
753 753
 
754 754
 function rfc2445_do_value_formatting($value, $type) {
755 755
     // Note: this does not only do formatting; it also does conversion to string!
756
-    switch($type) {
756
+    switch ($type) {
757 757
         case RFC2445_TYPE_CAL_ADDRESS:
758 758
         case RFC2445_TYPE_URI:
759 759
             // Enclose in double quotes
@@ -768,7 +768,7 @@  discard block
 block discarded – undo
768 768
 }
769 769
 
770 770
 function rfc2445_undo_value_formatting($value, $type) {
771
-    switch($type) {
771
+    switch ($type) {
772 772
         case RFC2445_TYPE_CAL_ADDRESS:
773 773
         case RFC2445_TYPE_URI:
774 774
             // Trim beginning and end double quote
Please login to merge, or discard this patch.
Braces   +7 added lines, -14 removed lines patch added patch discarded remove patch
@@ -125,8 +125,7 @@  discard block
 block discarded – undo
125 125
         
126 126
             if($scheme === 'mailto') {
127 127
                 $regexp = '^[a-zA-Z0-9]+[_a-zA-Z0-9\-]*(\.[_a-z0-9\-]+)*@(([0-9a-zA-Z\-]+\.)+[a-zA-Z][0-9a-zA-Z\-]+|([0-9]{1,3}\.){3}[0-9]{1,3})$';
128
-            }
129
-            else {
128
+            } else {
130 129
                 $regexp = '^//(.+(:.*)?@)?(([0-9a-zA-Z\-]+\.)+[a-zA-Z][0-9a-zA-Z\-]+|([0-9]{1,3}\.){3}[0-9]{1,3})(:[0-9]{1,5})?(/.*)?$';
131 130
             }
132 131
         
@@ -173,8 +172,7 @@  discard block
 block discarded – undo
173 172
                     return false;
174 173
                 }
175 174
                 $value = "$value";
176
-            }
177
-            else if(!is_string($value)) {
175
+            } else if(!is_string($value)) {
178 176
                 return false;
179 177
             }
180 178
 
@@ -364,8 +362,7 @@  discard block
 block discarded – undo
364 362
             if(rfc2445_is_valid_value($parts[1], RFC2445_TYPE_DATE_TIME)) {
365 363
                 // It has to be after the start time, so
366 364
                 return ($parts[1] > $parts[0]);
367
-            }
368
-            else if(rfc2445_is_valid_value($parts[1], RFC2445_TYPE_DURATION)) {
365
+            } else if(rfc2445_is_valid_value($parts[1], RFC2445_TYPE_DURATION)) {
369 366
                 // The period MUST NOT be negative
370 367
                 return ($parts[1]{0} != '-');
371 368
             }
@@ -453,8 +450,7 @@  discard block
 block discarded – undo
453 450
                     if(!(substr($vars['UNTIL'], -1) == 'Z')) {
454 451
                         return false;
455 452
                     }
456
-                }
457
-                else if(!rfc2445_is_valid_value($vars['UNTIL'], RFC2445_TYPE_DATE_TIME)) {
453
+                } else if(!rfc2445_is_valid_value($vars['UNTIL'], RFC2445_TYPE_DATE_TIME)) {
458 454
                     return false;
459 455
                 }
460 456
             }
@@ -691,8 +687,7 @@  discard block
 block discarded – undo
691 687
                     return false;
692 688
                 }
693 689
                 $value = "$value";
694
-            }
695
-            else if(!is_string($value)) {
690
+            } else if(!is_string($value)) {
696 691
                 return false;
697 692
             }
698 693
 
@@ -717,12 +712,10 @@  discard block
 block discarded – undo
717 712
             if(is_int($value)) {
718 713
                 if($value >= 0) {
719 714
                     $value = "+$value";
720
-                }
721
-                else {
715
+                } else {
722 716
                     $value = "$value";
723 717
                 }
724
-            }
725
-            else if(!is_string($value)) {
718
+            } else if(!is_string($value)) {
726 719
                 return false;
727 720
             }
728 721
 
Please login to merge, or discard this patch.
phpicalendar/lib/HTTP/CalDAV/Server.php 4 patches
Doc Comments   +2 added lines, -1 removed lines patch added patch discarded remove patch
@@ -49,6 +49,7 @@  discard block
 block discarded – undo
49 49
      *
50 50
      * @param string property name
51 51
      * @param string property value
52
+     * @param string $name
52 53
      * @return array string property namespace
53 54
      *               string property name
54 55
      *               string property value
@@ -62,7 +63,7 @@  discard block
 block discarded – undo
62 63
      * REPORT request helper - prepares data-structures from REPORT requests
63 64
      *
64 65
      * @param options
65
-     * @return void
66
+     * @return null|boolean
66 67
      * @access public
67 68
      */
68 69
     function report_request_helper(&$options)
Please login to merge, or discard this patch.
Indentation   +291 added lines, -291 removed lines patch added patch discarded remove patch
@@ -44,298 +44,298 @@
 block discarded – undo
44 44
  */
45 45
 class HTTP_CalDAV_Server extends HTTP_WebDAV_Server
46 46
 {
47
-    /**
48
-     * Make a property in the CalDAV namespace
49
-     *
50
-     * @param string property name
51
-     * @param string property value
52
-     * @return array string property namespace
53
-     *               string property name
54
-     *               string property value
55
-     */
56
-    function calDavProp($name, $value=null, $status=null) {
57
-        return $this->mkprop('urn:ietf:params:xml:ns:caldav', $name, $value,
58
-            $status);
59
-    }
60
-
61
-    /**
62
-     * REPORT request helper - prepares data-structures from REPORT requests
63
-     *
64
-     * @param options
65
-     * @return void
66
-     * @access public
67
-     */
68
-    function report_request_helper(&$options)
69
-    {
70
-        $options = array();
71
-        $options['path'] = $this->path;
72
-
73
-        /* The request MAY include a Depth header.  If no Depth header is
47
+	/**
48
+	 * Make a property in the CalDAV namespace
49
+	 *
50
+	 * @param string property name
51
+	 * @param string property value
52
+	 * @return array string property namespace
53
+	 *               string property name
54
+	 *               string property value
55
+	 */
56
+	function calDavProp($name, $value=null, $status=null) {
57
+		return $this->mkprop('urn:ietf:params:xml:ns:caldav', $name, $value,
58
+			$status);
59
+	}
60
+
61
+	/**
62
+	 * REPORT request helper - prepares data-structures from REPORT requests
63
+	 *
64
+	 * @param options
65
+	 * @return void
66
+	 * @access public
67
+	 */
68
+	function report_request_helper(&$options)
69
+	{
70
+		$options = array();
71
+		$options['path'] = $this->path;
72
+
73
+		/* The request MAY include a Depth header.  If no Depth header is
74 74
            included, Depth:0 is assumed. */
75
-        $options['depth'] = 0;
76
-        if (isset($_SERVER['HTTP_DEPTH'])) {
77
-            $options['depth'] = $_SERVER['HTTP_DEPTH'];
78
-        }
79
-
80
-        $parser = new ReportParser('php://input');
81
-        if (!$parser->success) {
82
-            $this->http_status('400 Bad Request');
83
-            return;
84
-        }
85
-
86
-        $options['props'] = $parser->props;
87
-        $options['filters'] = $parser->filters;
88
-
89
-        return true;
90
-    }
91
-
92
-    /**
93
-     * REPORT method wrapper
94
-     *
95
-     * @param void
96
-     * @return void
97
-     * @access public
98
-     */
99
-    function report_wrapper()
100
-    {
101
-        /* Prepare data-structure from REPORT request */
102
-        if (!$this->report_request_helper($options)) {
103
-            return;
104
-        }
105
-
106
-        /* Call user handler */
107
-        if (method_exists($this, 'report')) {
108
-            if (!$this->report($options, $files)) {
109
-                return;
110
-            }
111
-        } else {
112
-
113
-            /* Empulate REPORT using PROPFIND */
114
-            if (!$this->propfind($options, $files)) {
115
-                return;
116
-            }
117
-        }
118
-
119
-        /* Format REPORT response */
120
-
121
-        // TODO Make ns_hash a class variable so we can prettify C:
122
-        // Or make getNsName so we can return C:
123
-        $this->propfind_response_helper($options, $files);
124
-    }
125
-
126
-    function getProp($reqprop, $file, $options)
127
-    {
128
-        // check if property exists in response
129
-        foreach ($file['props'] as $prop) {
130
-            if ($reqprop['name'] == $prop['name'] &&
131
-                    $reqprop['ns'] == $prop['ns']) {
132
-                return $prop;
133
-            }
134
-        }
135
-
136
-        if ($reqprop['name'] == 'lockdiscovery' &&
137
-                $reqprop['ns'] == 'DAV:' &&
138
-                method_exists($this, 'getLocks')) {
139
-            return $this->mkprop('DAV:', 'lockdiscovery',
140
-                $this->getLocks($file['path']));
141
-        }
142
-
143
-        if ($reqprop['name'] == 'calendar-data' &&
144
-                $reqprop['ns'] == 'urn:ietf:params:xml:ns:caldav' &&
145
-                method_exists($this, 'get')) {
146
-            $filters = $options['filters'];
147
-
148
-            $options = array();
149
-            $options['path'] = $file['path'];
150
-
151
-            $status = $this->get($options);
152
-            if (empty($status)) {
153
-                $status = '404 Not Found';
154
-            }
155
-
156
-            if ($status !== true) {
157
-                return $this->calDavProp('calendar-data', null, $status);
158
-            }
159
-
160
-            if ($options['mimetype'] != 'text/calendar') {
161
-                return $this->calDavProp('calendar-data', null,
162
-                    '404 Not Found');
163
-            }
164
-
165
-            if ($options['stream']) {
166
-                $handle = $options['stream'];
167
-            } else if ($options['data']) {
168
-                // What about data?
169
-            } else {
170
-                return $this->calDavProp('calendar-data', null,
171
-                    '404 Not Found');
172
-            }
173
-
174
-            $parser = new ICalendarParser($handle, null, $reqprop['value'],
175
-                $filters);
176
-            if (!$parser->success) {
177
-                return $this->calDavProp('calendar-data', null,
178
-                    '404 Not Found');
179
-            }
180
-
181
-            return HTTP_CalDAV_Server::calDavProp('calendar-data',
182
-                $parser->comps[count($parser->comps) - 1]);
183
-        }
184
-
185
-        // incase the requested property had a value, like calendar-data
186
-        unset($reqprop['value']);
187
-        $reqprop['status'] = '404 Not Found';
188
-        return $reqprop;
189
-    }
190
-
191
-    function _multistatus($responses)
192
-    {
193
-        // now we generate the response header...
194
-        $this->http_status('207 Multi-Status');
195
-        header('Content-Type: text/xml; charset="utf-8"');
196
-
197
-        // ...and payload
198
-        echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
199
-        echo "<D:multistatus xmlns:D=\"DAV:\">\n";
200
-
201
-        foreach ($responses as $response) {
202
-
203
-            // ignore empty or incomplete entries
204
-            if (!is_array($response) || empty($response)) {
205
-                continue;
206
-            }
207
-
208
-            $ns_defs = array();
209
-            foreach ($response['ns_hash'] as $name => $prefix) {
210
-                $ns_defs[] = "xmlns:$prefix=\"$name\"";
211
-            }
212
-            echo ' <D:response ' . implode(' ', $ns_defs) . ">\n";
213
-            echo "  <D:href>$response[href]</D:href>\n";
214
-
215
-            // report all found properties and their values (if any)
216
-            // nothing to do if no properties were returend for a file
217
-            if (isset($response['propstat']) &&
218
-                    is_array($response['propstat'])) {
219
-
220
-                foreach ($response['propstat'] as $status => $props) {
221
-                    echo "  <D:propstat>\n";
222
-                    echo "   <D:prop>\n";
223
-
224
-                    foreach ($props as $prop) {
225
-                        if (!is_array($prop) || !isset($prop['name'])) {
226
-                            continue;
227
-                        }
228
-
229
-                        // empty properties (cannot use empty for check as '0'
230
-                        // is a legal value here)
231
-                        if (!isset($prop['value']) || empty($prop['value']) &&
232
-                                $prop['value'] !== 0) {
233
-                            if ($prop['ns'] == 'DAV:') {
234
-                                echo "    <D:$prop[name]/>\n";
235
-                                continue;
236
-                            }
237
-
238
-                            if (!empty($prop['ns'])) {
239
-                                echo '    <' .
240
-                                    $response['ns_hash'][$prop['ns']] .
241
-                                    ":$prop[name]/>\n";
242
-                                continue;
243
-                            }
244
-
245
-                            echo "    <$prop[name] xmlns=\"\"/>";
246
-                            continue;
247
-                        }
248
-
249
-                        // some WebDAV properties need special treatment
250
-                        if ($prop['ns'] == 'DAV:') {
251
-
252
-                            switch ($prop['name']) {
253
-                            case 'creationdate':
254
-                                echo "    <D:creationdate ns0:dt=\"dateTime.tz\">\n";
255
-                                echo '     ' . gmdate('Y-m-d\TH:i:s\Z', $prop['value']) . "\n";
256
-                                echo "    </D:creationdate>\n";
257
-                                break;
258
-
259
-                            case 'getlastmodified':
260
-                                echo "    <D:getlastmodified ns0:dt=\"dateTime.rfc1123\">\n";
261
-                                echo '     ' . gmdate('D, d M Y H:i:s', $prop['value']) . " GMT\n";
262
-                                echo "    </D:getlastmodified>\n";
263
-                                break;
264
-
265
-                            case 'resourcetype':
266
-                                echo "    <D:resourcetype>\n";
267
-                                echo "     <D:$prop[value]/>\n";
268
-                                echo "    </D:resourcetype>\n";
269
-                                break;
270
-
271
-                            case 'supportedlock':
272
-
273
-                                if (is_array($prop[value])) {
274
-                                    $prop[value] = $this->_lockentries($prop[value]);
275
-                                }
276
-                                echo "    <D:supportedlock>\n";
277
-                                echo "     $prop[value]\n";
278
-                                echo "    </D:supportedlock>\n";
279
-                                break;
280
-
281
-                            case 'lockdiscovery':
282
-
283
-                                if (is_array($prop[value])) {
284
-                                    $prop[value] = $this->_activelocks($prop[value]);
285
-                                }
286
-                                echo "    <D:lockdiscovery>\n";
287
-                                echo "     $prop[value]\n";
288
-                                echo "    </D:lockdiscovery>\n";
289
-                                break;
290
-
291
-                            default:
292
-                                echo "    <D:$prop[name]>\n";
293
-                                echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
294
-                                echo "    </D:$prop[name]>\n";
295
-                            }
296
-
297
-                            continue;
298
-                        }
299
-
300
-                        if ($prop['name'] == 'calendar-data' &&
301
-                                is_object($prop['value'])) {
302
-                            $prop['value'] = $prop['value']->serialize();
303
-                        }
304
-
305
-                        if (!empty($prop['ns'])) {
306
-                            echo '    <' . $response['ns_hash'][$prop['ns']] . ":$prop[name]>\n";
307
-                            echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
308
-                            echo '    </' . $response['ns_hash'][$prop['ns']] . ":$prop[name]>\n";
309
-
310
-                            continue;
311
-                        }
312
-
313
-                        echo "    <$prop[name] xmlns=\"\">\n";
314
-                        echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
315
-                        echo "    </$prop[name]>\n";
316
-                    }
317
-
318
-                    echo "   </D:prop>\n";
319
-                    echo "   <D:status>HTTP/1.1 $status</D:status>\n";
320
-                    echo "  </D:propstat>\n";
321
-                }
322
-            }
323
-
324
-            if (isset($response['status'])) {
325
-                echo "  <D:status>HTTP/1.1 $status</D:status>\n";
326
-            }
327
-
328
-            if (isset($response['responsedescription'])) {
329
-                echo "  <D:responsedescription>\n";
330
-                echo '   ' . $this->_prop_encode(htmlspecialchars($response['responsedescription'])) . "\n";
331
-                echo "  </D:responsedescription>\n";
332
-            }
333
-
334
-            echo " </D:response>\n";
335
-        }
336
-
337
-        echo "</D:multistatus>\n";
338
-    }
75
+		$options['depth'] = 0;
76
+		if (isset($_SERVER['HTTP_DEPTH'])) {
77
+			$options['depth'] = $_SERVER['HTTP_DEPTH'];
78
+		}
79
+
80
+		$parser = new ReportParser('php://input');
81
+		if (!$parser->success) {
82
+			$this->http_status('400 Bad Request');
83
+			return;
84
+		}
85
+
86
+		$options['props'] = $parser->props;
87
+		$options['filters'] = $parser->filters;
88
+
89
+		return true;
90
+	}
91
+
92
+	/**
93
+	 * REPORT method wrapper
94
+	 *
95
+	 * @param void
96
+	 * @return void
97
+	 * @access public
98
+	 */
99
+	function report_wrapper()
100
+	{
101
+		/* Prepare data-structure from REPORT request */
102
+		if (!$this->report_request_helper($options)) {
103
+			return;
104
+		}
105
+
106
+		/* Call user handler */
107
+		if (method_exists($this, 'report')) {
108
+			if (!$this->report($options, $files)) {
109
+				return;
110
+			}
111
+		} else {
112
+
113
+			/* Empulate REPORT using PROPFIND */
114
+			if (!$this->propfind($options, $files)) {
115
+				return;
116
+			}
117
+		}
118
+
119
+		/* Format REPORT response */
120
+
121
+		// TODO Make ns_hash a class variable so we can prettify C:
122
+		// Or make getNsName so we can return C:
123
+		$this->propfind_response_helper($options, $files);
124
+	}
125
+
126
+	function getProp($reqprop, $file, $options)
127
+	{
128
+		// check if property exists in response
129
+		foreach ($file['props'] as $prop) {
130
+			if ($reqprop['name'] == $prop['name'] &&
131
+					$reqprop['ns'] == $prop['ns']) {
132
+				return $prop;
133
+			}
134
+		}
135
+
136
+		if ($reqprop['name'] == 'lockdiscovery' &&
137
+				$reqprop['ns'] == 'DAV:' &&
138
+				method_exists($this, 'getLocks')) {
139
+			return $this->mkprop('DAV:', 'lockdiscovery',
140
+				$this->getLocks($file['path']));
141
+		}
142
+
143
+		if ($reqprop['name'] == 'calendar-data' &&
144
+				$reqprop['ns'] == 'urn:ietf:params:xml:ns:caldav' &&
145
+				method_exists($this, 'get')) {
146
+			$filters = $options['filters'];
147
+
148
+			$options = array();
149
+			$options['path'] = $file['path'];
150
+
151
+			$status = $this->get($options);
152
+			if (empty($status)) {
153
+				$status = '404 Not Found';
154
+			}
155
+
156
+			if ($status !== true) {
157
+				return $this->calDavProp('calendar-data', null, $status);
158
+			}
159
+
160
+			if ($options['mimetype'] != 'text/calendar') {
161
+				return $this->calDavProp('calendar-data', null,
162
+					'404 Not Found');
163
+			}
164
+
165
+			if ($options['stream']) {
166
+				$handle = $options['stream'];
167
+			} else if ($options['data']) {
168
+				// What about data?
169
+			} else {
170
+				return $this->calDavProp('calendar-data', null,
171
+					'404 Not Found');
172
+			}
173
+
174
+			$parser = new ICalendarParser($handle, null, $reqprop['value'],
175
+				$filters);
176
+			if (!$parser->success) {
177
+				return $this->calDavProp('calendar-data', null,
178
+					'404 Not Found');
179
+			}
180
+
181
+			return HTTP_CalDAV_Server::calDavProp('calendar-data',
182
+				$parser->comps[count($parser->comps) - 1]);
183
+		}
184
+
185
+		// incase the requested property had a value, like calendar-data
186
+		unset($reqprop['value']);
187
+		$reqprop['status'] = '404 Not Found';
188
+		return $reqprop;
189
+	}
190
+
191
+	function _multistatus($responses)
192
+	{
193
+		// now we generate the response header...
194
+		$this->http_status('207 Multi-Status');
195
+		header('Content-Type: text/xml; charset="utf-8"');
196
+
197
+		// ...and payload
198
+		echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
199
+		echo "<D:multistatus xmlns:D=\"DAV:\">\n";
200
+
201
+		foreach ($responses as $response) {
202
+
203
+			// ignore empty or incomplete entries
204
+			if (!is_array($response) || empty($response)) {
205
+				continue;
206
+			}
207
+
208
+			$ns_defs = array();
209
+			foreach ($response['ns_hash'] as $name => $prefix) {
210
+				$ns_defs[] = "xmlns:$prefix=\"$name\"";
211
+			}
212
+			echo ' <D:response ' . implode(' ', $ns_defs) . ">\n";
213
+			echo "  <D:href>$response[href]</D:href>\n";
214
+
215
+			// report all found properties and their values (if any)
216
+			// nothing to do if no properties were returend for a file
217
+			if (isset($response['propstat']) &&
218
+					is_array($response['propstat'])) {
219
+
220
+				foreach ($response['propstat'] as $status => $props) {
221
+					echo "  <D:propstat>\n";
222
+					echo "   <D:prop>\n";
223
+
224
+					foreach ($props as $prop) {
225
+						if (!is_array($prop) || !isset($prop['name'])) {
226
+							continue;
227
+						}
228
+
229
+						// empty properties (cannot use empty for check as '0'
230
+						// is a legal value here)
231
+						if (!isset($prop['value']) || empty($prop['value']) &&
232
+								$prop['value'] !== 0) {
233
+							if ($prop['ns'] == 'DAV:') {
234
+								echo "    <D:$prop[name]/>\n";
235
+								continue;
236
+							}
237
+
238
+							if (!empty($prop['ns'])) {
239
+								echo '    <' .
240
+									$response['ns_hash'][$prop['ns']] .
241
+									":$prop[name]/>\n";
242
+								continue;
243
+							}
244
+
245
+							echo "    <$prop[name] xmlns=\"\"/>";
246
+							continue;
247
+						}
248
+
249
+						// some WebDAV properties need special treatment
250
+						if ($prop['ns'] == 'DAV:') {
251
+
252
+							switch ($prop['name']) {
253
+							case 'creationdate':
254
+								echo "    <D:creationdate ns0:dt=\"dateTime.tz\">\n";
255
+								echo '     ' . gmdate('Y-m-d\TH:i:s\Z', $prop['value']) . "\n";
256
+								echo "    </D:creationdate>\n";
257
+								break;
258
+
259
+							case 'getlastmodified':
260
+								echo "    <D:getlastmodified ns0:dt=\"dateTime.rfc1123\">\n";
261
+								echo '     ' . gmdate('D, d M Y H:i:s', $prop['value']) . " GMT\n";
262
+								echo "    </D:getlastmodified>\n";
263
+								break;
264
+
265
+							case 'resourcetype':
266
+								echo "    <D:resourcetype>\n";
267
+								echo "     <D:$prop[value]/>\n";
268
+								echo "    </D:resourcetype>\n";
269
+								break;
270
+
271
+							case 'supportedlock':
272
+
273
+								if (is_array($prop[value])) {
274
+									$prop[value] = $this->_lockentries($prop[value]);
275
+								}
276
+								echo "    <D:supportedlock>\n";
277
+								echo "     $prop[value]\n";
278
+								echo "    </D:supportedlock>\n";
279
+								break;
280
+
281
+							case 'lockdiscovery':
282
+
283
+								if (is_array($prop[value])) {
284
+									$prop[value] = $this->_activelocks($prop[value]);
285
+								}
286
+								echo "    <D:lockdiscovery>\n";
287
+								echo "     $prop[value]\n";
288
+								echo "    </D:lockdiscovery>\n";
289
+								break;
290
+
291
+							default:
292
+								echo "    <D:$prop[name]>\n";
293
+								echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
294
+								echo "    </D:$prop[name]>\n";
295
+							}
296
+
297
+							continue;
298
+						}
299
+
300
+						if ($prop['name'] == 'calendar-data' &&
301
+								is_object($prop['value'])) {
302
+							$prop['value'] = $prop['value']->serialize();
303
+						}
304
+
305
+						if (!empty($prop['ns'])) {
306
+							echo '    <' . $response['ns_hash'][$prop['ns']] . ":$prop[name]>\n";
307
+							echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
308
+							echo '    </' . $response['ns_hash'][$prop['ns']] . ":$prop[name]>\n";
309
+
310
+							continue;
311
+						}
312
+
313
+						echo "    <$prop[name] xmlns=\"\">\n";
314
+						echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
315
+						echo "    </$prop[name]>\n";
316
+					}
317
+
318
+					echo "   </D:prop>\n";
319
+					echo "   <D:status>HTTP/1.1 $status</D:status>\n";
320
+					echo "  </D:propstat>\n";
321
+				}
322
+			}
323
+
324
+			if (isset($response['status'])) {
325
+				echo "  <D:status>HTTP/1.1 $status</D:status>\n";
326
+			}
327
+
328
+			if (isset($response['responsedescription'])) {
329
+				echo "  <D:responsedescription>\n";
330
+				echo '   ' . $this->_prop_encode(htmlspecialchars($response['responsedescription'])) . "\n";
331
+				echo "  </D:responsedescription>\n";
332
+			}
333
+
334
+			echo " </D:response>\n";
335
+		}
336
+
337
+		echo "</D:multistatus>\n";
338
+	}
339 339
 }
340 340
 
341 341
 /*
Please login to merge, or discard this patch.
Switch Indentation   +42 added lines, -42 removed lines patch added patch discarded remove patch
@@ -250,48 +250,48 @@
 block discarded – undo
250 250
                         if ($prop['ns'] == 'DAV:') {
251 251
 
252 252
                             switch ($prop['name']) {
253
-                            case 'creationdate':
254
-                                echo "    <D:creationdate ns0:dt=\"dateTime.tz\">\n";
255
-                                echo '     ' . gmdate('Y-m-d\TH:i:s\Z', $prop['value']) . "\n";
256
-                                echo "    </D:creationdate>\n";
257
-                                break;
258
-
259
-                            case 'getlastmodified':
260
-                                echo "    <D:getlastmodified ns0:dt=\"dateTime.rfc1123\">\n";
261
-                                echo '     ' . gmdate('D, d M Y H:i:s', $prop['value']) . " GMT\n";
262
-                                echo "    </D:getlastmodified>\n";
263
-                                break;
264
-
265
-                            case 'resourcetype':
266
-                                echo "    <D:resourcetype>\n";
267
-                                echo "     <D:$prop[value]/>\n";
268
-                                echo "    </D:resourcetype>\n";
269
-                                break;
270
-
271
-                            case 'supportedlock':
272
-
273
-                                if (is_array($prop[value])) {
274
-                                    $prop[value] = $this->_lockentries($prop[value]);
275
-                                }
276
-                                echo "    <D:supportedlock>\n";
277
-                                echo "     $prop[value]\n";
278
-                                echo "    </D:supportedlock>\n";
279
-                                break;
280
-
281
-                            case 'lockdiscovery':
282
-
283
-                                if (is_array($prop[value])) {
284
-                                    $prop[value] = $this->_activelocks($prop[value]);
285
-                                }
286
-                                echo "    <D:lockdiscovery>\n";
287
-                                echo "     $prop[value]\n";
288
-                                echo "    </D:lockdiscovery>\n";
289
-                                break;
290
-
291
-                            default:
292
-                                echo "    <D:$prop[name]>\n";
293
-                                echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
294
-                                echo "    </D:$prop[name]>\n";
253
+                            	case 'creationdate':
254
+                                	echo "    <D:creationdate ns0:dt=\"dateTime.tz\">\n";
255
+                                	echo '     ' . gmdate('Y-m-d\TH:i:s\Z', $prop['value']) . "\n";
256
+                                	echo "    </D:creationdate>\n";
257
+                                	break;
258
+
259
+                            	case 'getlastmodified':
260
+                                	echo "    <D:getlastmodified ns0:dt=\"dateTime.rfc1123\">\n";
261
+                                	echo '     ' . gmdate('D, d M Y H:i:s', $prop['value']) . " GMT\n";
262
+                                	echo "    </D:getlastmodified>\n";
263
+                                	break;
264
+
265
+                            	case 'resourcetype':
266
+                                	echo "    <D:resourcetype>\n";
267
+                                	echo "     <D:$prop[value]/>\n";
268
+                                	echo "    </D:resourcetype>\n";
269
+                                	break;
270
+
271
+                            	case 'supportedlock':
272
+
273
+                                	if (is_array($prop[value])) {
274
+                                    	$prop[value] = $this->_lockentries($prop[value]);
275
+                                	}
276
+                                	echo "    <D:supportedlock>\n";
277
+                                	echo "     $prop[value]\n";
278
+                                	echo "    </D:supportedlock>\n";
279
+                                	break;
280
+
281
+                            	case 'lockdiscovery':
282
+
283
+                                	if (is_array($prop[value])) {
284
+                                    	$prop[value] = $this->_activelocks($prop[value]);
285
+                                	}
286
+                                	echo "    <D:lockdiscovery>\n";
287
+                                	echo "     $prop[value]\n";
288
+                                	echo "    </D:lockdiscovery>\n";
289
+                                	break;
290
+
291
+                            	default:
292
+                                	echo "    <D:$prop[name]>\n";
293
+                                	echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
294
+                                	echo "    </D:$prop[name]>\n";
295 295
                             }
296 296
 
297 297
                             continue;
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -53,7 +53,7 @@  discard block
 block discarded – undo
53 53
      *               string property name
54 54
      *               string property value
55 55
      */
56
-    function calDavProp($name, $value=null, $status=null) {
56
+    function calDavProp($name, $value = null, $status = null) {
57 57
         return $this->mkprop('urn:ietf:params:xml:ns:caldav', $name, $value,
58 58
             $status);
59 59
     }
@@ -209,7 +209,7 @@  discard block
 block discarded – undo
209 209
             foreach ($response['ns_hash'] as $name => $prefix) {
210 210
                 $ns_defs[] = "xmlns:$prefix=\"$name\"";
211 211
             }
212
-            echo ' <D:response ' . implode(' ', $ns_defs) . ">\n";
212
+            echo ' <D:response '.implode(' ', $ns_defs).">\n";
213 213
             echo "  <D:href>$response[href]</D:href>\n";
214 214
 
215 215
             // report all found properties and their values (if any)
@@ -236,8 +236,8 @@  discard block
 block discarded – undo
236 236
                             }
237 237
 
238 238
                             if (!empty($prop['ns'])) {
239
-                                echo '    <' .
240
-                                    $response['ns_hash'][$prop['ns']] .
239
+                                echo '    <'.
240
+                                    $response['ns_hash'][$prop['ns']].
241 241
                                     ":$prop[name]/>\n";
242 242
                                 continue;
243 243
                             }
@@ -252,13 +252,13 @@  discard block
 block discarded – undo
252 252
                             switch ($prop['name']) {
253 253
                             case 'creationdate':
254 254
                                 echo "    <D:creationdate ns0:dt=\"dateTime.tz\">\n";
255
-                                echo '     ' . gmdate('Y-m-d\TH:i:s\Z', $prop['value']) . "\n";
255
+                                echo '     '.gmdate('Y-m-d\TH:i:s\Z', $prop['value'])."\n";
256 256
                                 echo "    </D:creationdate>\n";
257 257
                                 break;
258 258
 
259 259
                             case 'getlastmodified':
260 260
                                 echo "    <D:getlastmodified ns0:dt=\"dateTime.rfc1123\">\n";
261
-                                echo '     ' . gmdate('D, d M Y H:i:s', $prop['value']) . " GMT\n";
261
+                                echo '     '.gmdate('D, d M Y H:i:s', $prop['value'])." GMT\n";
262 262
                                 echo "    </D:getlastmodified>\n";
263 263
                                 break;
264 264
 
@@ -290,7 +290,7 @@  discard block
 block discarded – undo
290 290
 
291 291
                             default:
292 292
                                 echo "    <D:$prop[name]>\n";
293
-                                echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
293
+                                echo '     '.$this->_prop_encode(htmlspecialchars($prop['value']))."\n";
294 294
                                 echo "    </D:$prop[name]>\n";
295 295
                             }
296 296
 
@@ -303,15 +303,15 @@  discard block
 block discarded – undo
303 303
                         }
304 304
 
305 305
                         if (!empty($prop['ns'])) {
306
-                            echo '    <' . $response['ns_hash'][$prop['ns']] . ":$prop[name]>\n";
307
-                            echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
308
-                            echo '    </' . $response['ns_hash'][$prop['ns']] . ":$prop[name]>\n";
306
+                            echo '    <'.$response['ns_hash'][$prop['ns']].":$prop[name]>\n";
307
+                            echo '     '.$this->_prop_encode(htmlspecialchars($prop['value']))."\n";
308
+                            echo '    </'.$response['ns_hash'][$prop['ns']].":$prop[name]>\n";
309 309
 
310 310
                             continue;
311 311
                         }
312 312
 
313 313
                         echo "    <$prop[name] xmlns=\"\">\n";
314
-                        echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
314
+                        echo '     '.$this->_prop_encode(htmlspecialchars($prop['value']))."\n";
315 315
                         echo "    </$prop[name]>\n";
316 316
                     }
317 317
 
@@ -327,7 +327,7 @@  discard block
 block discarded – undo
327 327
 
328 328
             if (isset($response['responsedescription'])) {
329 329
                 echo "  <D:responsedescription>\n";
330
-                echo '   ' . $this->_prop_encode(htmlspecialchars($response['responsedescription'])) . "\n";
330
+                echo '   '.$this->_prop_encode(htmlspecialchars($response['responsedescription']))."\n";
331 331
                 echo "  </D:responsedescription>\n";
332 332
             }
333 333
 
Please login to merge, or discard this patch.
phpicalendar/lib/HTTP/CalDAV/Tools/ReportParser.php 3 patches
Doc Comments   +1 added lines patch added patch discarded remove patch
@@ -93,6 +93,7 @@
 block discarded – undo
93 93
      * Constructor
94 94
      *
95 95
      * @param string path to report input data
96
+     * @param string $input
96 97
      * @access public
97 98
      */
98 99
     function ReportParser($input)
Please login to merge, or discard this patch.
Indentation   +226 added lines, -226 removed lines patch added patch discarded remove patch
@@ -41,232 +41,232 @@
 block discarded – undo
41 41
  */
42 42
 class ReportParser
43 43
 {
44
-    /**
45
-     * Success state flag
46
-     *
47
-     * @var bool
48
-     * @access public
49
-     */
50
-    var $success = false;
51
-
52
-    /**
53
-     * Name of the requested report
54
-     *
55
-     * @var string
56
-     * @access public
57
-     */
58
-    var $report;
59
-
60
-    /**
61
-     * Found properties are collected here
62
-     *
63
-     * @var array
64
-     * @access public
65
-     */
66
-    var $props = array();
67
-
68
-    /**
69
-     * Found filters are collected here
70
-     *
71
-     * @var array
72
-     * @access public
73
-     */
74
-    var $filters = array();
75
-
76
-    /**
77
-     * Stack of ancestor tag names
78
-     *
79
-     * @var array
80
-     * @access private
81
-     */
82
-    var $_names = array();
83
-
84
-    /**
85
-     * Stack of component data
86
-     *
87
-     * @var array
88
-     * @access private
89
-     */
90
-    var $_comps = array();
91
-
92
-    /**
93
-     * Constructor
94
-     *
95
-     * @param string path to report input data
96
-     * @access public
97
-     */
98
-    function ReportParser($input)
99
-    {
100
-        // FIXME Take a handle, not a path
101
-        $handle = fopen($input, 'r');
102
-        if (!$handle) {
103
-            return;
104
-        }
105
-
106
-        $parser = xml_parser_create_ns('UTF-8', ' ');
107
-        xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false);
108
-        xml_set_element_handler($parser, array(&$this, '_startElement'),
109
-            array(&$this, '_endElement'));
110
-
111
-        $this->success = true;
112
-        while (($line = fgets($handle, 4096)) !== false) {
113
-            $this->success = xml_parse($parser, $line);
114
-            if (!$this->success) {
115
-                return;
116
-            }
117
-        }
118
-
119
-        if (!feof($handle)) {
120
-            $this->success = false;
121
-            return;
122
-        }
123
-
124
-        xml_parser_free($parser);
125
-        fclose($handle);
126
-
127
-        if (empty($this->props)) {
128
-            $this->props = 'allprop';
129
-        }
130
-    }
131
-
132
-    /**
133
-     * Start tag handler
134
-     *
135
-     * @param object parser
136
-     * @param string tag name
137
-     * @param array tag attributes
138
-     * @access private
139
-     */
140
-    function _startElement($parser, $name, $attrs)
141
-    {
142
-        $nameComponents = explode(' ', $name);
143
-        if (count($nameComponents) > 2) {
144
-            $this->success = false;
145
-            return;
146
-        }
147
-
148
-        if (count($nameComponents) == 2) {
149
-            list ($ns, $name) = $nameComponents;
150
-            if (empty($ns)) {
151
-                $this->success = false;
152
-                return;
153
-            }
154
-        }
155
-
156
-        if (empty($this->_names)) {
157
-            $this->report = $name;
158
-            $this->_names[] = $name;
159
-            return;
160
-        }
161
-
162
-        if (count($this->_names) == 1 &&
163
-                ($name == 'allprop' || $name == 'propname')) {
164
-            $this->props = $name;
165
-            $this->_names[] = $name;
166
-            return;
167
-        }
168
-
169
-        if (count($this->_names) == 2 && end($this->_names) == 'prop') {
170
-            $prop = array('name' => $name, 'ns' => $ns);
171
-
172
-            if ($name == 'calendar-data') {
173
-                $prop['value'] = array();
174
-                $this->_comps[] =& $prop['value'];
175
-            }
176
-
177
-            $this->props[] = $prop;
178
-            $this->_names[] = $name;
179
-            return;
180
-        }
181
-
182
-        if ($name == 'comp') {
183
-            if (!is_array($this->_comps[count($this->_comps) - 1]['comps'])) {
184
-                $this->_comps[count($this->_comps) - 1]['comps'] = array();
185
-            }
186
-
187
-            $this->_comps[count($this->_comps) - 1]['comps'][$attrs['name']] =
188
-                array();
189
-            $this->_comps[] =& $this->_comps[count($this->_comps) - 1]['comps']
190
-                [$attrs['name']];
191
-            $this->_names[] = $name;
192
-            return;
193
-        }
194
-
195
-        if (end($this->_names) == 'comp' && $name == 'prop') {
196
-            if (!is_array($this->_comps[count($this->_comps) - 1]['props'])) {
197
-                $this->_comps[count($this->_comps) - 1]['props'] = array();
198
-            }
199
-
200
-            $this->_comps[count($this->_comps) - 1]['props'][] = $attrs['name'];
201
-            $this->_names[] = $name;
202
-            return;
203
-        }
204
-
205
-        if (count($this->_names) == 1 && $name == 'filter') {
206
-            $this->_comps[] =& $this->filters;
207
-            $this->_names[] = $name;
208
-            return;
209
-        }
210
-
211
-        if ($name == 'comp-filter') {
212
-            if (!is_array($this->_comps[count($this->_comps) - 1]['comps'])) {
213
-                $this->_comps[count($this->_comps) - 1]['comps'] = array();
214
-            }
215
-
216
-            $this->_comps[count($this->_comps) - 1]['comps'][$attrs['name']] =
217
-                array();
218
-            $this->_comps[] =& $this->_comps[count($this->_comps) - 1]['comps']
219
-                [$attrs['name']];
220
-            $this->_names[] = $name;
221
-            return;
222
-        }
223
-
224
-        if (end($this->_names) == 'comp-filter') {
225
-            if (!is_array($this->_comps[count($this->_comps) - 1]['filters'])) {
226
-                $this->_comps[count($this->_comps) - 1]['filters'] = array();
227
-            }
228
-
229
-            $this->_comps[count($this->_comps) - 1]['filters'][] =
230
-                array('name' => $name, 'value' => $attrs);
231
-            $this->_names[] = $name;
232
-            return;
233
-        }
234
-
235
-        $this->_names[] = $name;
236
-    }
237
-
238
-    /**
239
-     * End tag handler
240
-     *
241
-     * @param object parser
242
-     * @param string tag name
243
-     * @param array tag attributes
244
-     * @access private
245
-     */
246
-    function _endElement($parser, $name) {
247
-        $nameComponents = explode(' ', $name);
248
-        if (count($nameComponents) > 2) {
249
-            $this->success = false;
250
-            return;
251
-        }
252
-
253
-        if (count($nameComponents) == 2) {
254
-            list ($ns, $name) = $nameComponents;
255
-            if (empty($ns)) {
256
-                $this->success = false;
257
-                return;
258
-            }
259
-        }
260
-
261
-        // Any need to pop at end of calendar-data?
262
-        // Yes - $this->_comps is re-used for parsing filters
263
-        if ($name == 'comp' || $name == 'calendar-data' ||
264
-                $name == 'comp-filter' || $name == 'filter') {
265
-            array_pop($this->_comps);
266
-        }
267
-
268
-        array_pop($this->_names);
269
-    }
44
+	/**
45
+	 * Success state flag
46
+	 *
47
+	 * @var bool
48
+	 * @access public
49
+	 */
50
+	var $success = false;
51
+
52
+	/**
53
+	 * Name of the requested report
54
+	 *
55
+	 * @var string
56
+	 * @access public
57
+	 */
58
+	var $report;
59
+
60
+	/**
61
+	 * Found properties are collected here
62
+	 *
63
+	 * @var array
64
+	 * @access public
65
+	 */
66
+	var $props = array();
67
+
68
+	/**
69
+	 * Found filters are collected here
70
+	 *
71
+	 * @var array
72
+	 * @access public
73
+	 */
74
+	var $filters = array();
75
+
76
+	/**
77
+	 * Stack of ancestor tag names
78
+	 *
79
+	 * @var array
80
+	 * @access private
81
+	 */
82
+	var $_names = array();
83
+
84
+	/**
85
+	 * Stack of component data
86
+	 *
87
+	 * @var array
88
+	 * @access private
89
+	 */
90
+	var $_comps = array();
91
+
92
+	/**
93
+	 * Constructor
94
+	 *
95
+	 * @param string path to report input data
96
+	 * @access public
97
+	 */
98
+	function ReportParser($input)
99
+	{
100
+		// FIXME Take a handle, not a path
101
+		$handle = fopen($input, 'r');
102
+		if (!$handle) {
103
+			return;
104
+		}
105
+
106
+		$parser = xml_parser_create_ns('UTF-8', ' ');
107
+		xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false);
108
+		xml_set_element_handler($parser, array(&$this, '_startElement'),
109
+			array(&$this, '_endElement'));
110
+
111
+		$this->success = true;
112
+		while (($line = fgets($handle, 4096)) !== false) {
113
+			$this->success = xml_parse($parser, $line);
114
+			if (!$this->success) {
115
+				return;
116
+			}
117
+		}
118
+
119
+		if (!feof($handle)) {
120
+			$this->success = false;
121
+			return;
122
+		}
123
+
124
+		xml_parser_free($parser);
125
+		fclose($handle);
126
+
127
+		if (empty($this->props)) {
128
+			$this->props = 'allprop';
129
+		}
130
+	}
131
+
132
+	/**
133
+	 * Start tag handler
134
+	 *
135
+	 * @param object parser
136
+	 * @param string tag name
137
+	 * @param array tag attributes
138
+	 * @access private
139
+	 */
140
+	function _startElement($parser, $name, $attrs)
141
+	{
142
+		$nameComponents = explode(' ', $name);
143
+		if (count($nameComponents) > 2) {
144
+			$this->success = false;
145
+			return;
146
+		}
147
+
148
+		if (count($nameComponents) == 2) {
149
+			list ($ns, $name) = $nameComponents;
150
+			if (empty($ns)) {
151
+				$this->success = false;
152
+				return;
153
+			}
154
+		}
155
+
156
+		if (empty($this->_names)) {
157
+			$this->report = $name;
158
+			$this->_names[] = $name;
159
+			return;
160
+		}
161
+
162
+		if (count($this->_names) == 1 &&
163
+				($name == 'allprop' || $name == 'propname')) {
164
+			$this->props = $name;
165
+			$this->_names[] = $name;
166
+			return;
167
+		}
168
+
169
+		if (count($this->_names) == 2 && end($this->_names) == 'prop') {
170
+			$prop = array('name' => $name, 'ns' => $ns);
171
+
172
+			if ($name == 'calendar-data') {
173
+				$prop['value'] = array();
174
+				$this->_comps[] =& $prop['value'];
175
+			}
176
+
177
+			$this->props[] = $prop;
178
+			$this->_names[] = $name;
179
+			return;
180
+		}
181
+
182
+		if ($name == 'comp') {
183
+			if (!is_array($this->_comps[count($this->_comps) - 1]['comps'])) {
184
+				$this->_comps[count($this->_comps) - 1]['comps'] = array();
185
+			}
186
+
187
+			$this->_comps[count($this->_comps) - 1]['comps'][$attrs['name']] =
188
+				array();
189
+			$this->_comps[] =& $this->_comps[count($this->_comps) - 1]['comps']
190
+				[$attrs['name']];
191
+			$this->_names[] = $name;
192
+			return;
193
+		}
194
+
195
+		if (end($this->_names) == 'comp' && $name == 'prop') {
196
+			if (!is_array($this->_comps[count($this->_comps) - 1]['props'])) {
197
+				$this->_comps[count($this->_comps) - 1]['props'] = array();
198
+			}
199
+
200
+			$this->_comps[count($this->_comps) - 1]['props'][] = $attrs['name'];
201
+			$this->_names[] = $name;
202
+			return;
203
+		}
204
+
205
+		if (count($this->_names) == 1 && $name == 'filter') {
206
+			$this->_comps[] =& $this->filters;
207
+			$this->_names[] = $name;
208
+			return;
209
+		}
210
+
211
+		if ($name == 'comp-filter') {
212
+			if (!is_array($this->_comps[count($this->_comps) - 1]['comps'])) {
213
+				$this->_comps[count($this->_comps) - 1]['comps'] = array();
214
+			}
215
+
216
+			$this->_comps[count($this->_comps) - 1]['comps'][$attrs['name']] =
217
+				array();
218
+			$this->_comps[] =& $this->_comps[count($this->_comps) - 1]['comps']
219
+				[$attrs['name']];
220
+			$this->_names[] = $name;
221
+			return;
222
+		}
223
+
224
+		if (end($this->_names) == 'comp-filter') {
225
+			if (!is_array($this->_comps[count($this->_comps) - 1]['filters'])) {
226
+				$this->_comps[count($this->_comps) - 1]['filters'] = array();
227
+			}
228
+
229
+			$this->_comps[count($this->_comps) - 1]['filters'][] =
230
+				array('name' => $name, 'value' => $attrs);
231
+			$this->_names[] = $name;
232
+			return;
233
+		}
234
+
235
+		$this->_names[] = $name;
236
+	}
237
+
238
+	/**
239
+	 * End tag handler
240
+	 *
241
+	 * @param object parser
242
+	 * @param string tag name
243
+	 * @param array tag attributes
244
+	 * @access private
245
+	 */
246
+	function _endElement($parser, $name) {
247
+		$nameComponents = explode(' ', $name);
248
+		if (count($nameComponents) > 2) {
249
+			$this->success = false;
250
+			return;
251
+		}
252
+
253
+		if (count($nameComponents) == 2) {
254
+			list ($ns, $name) = $nameComponents;
255
+			if (empty($ns)) {
256
+				$this->success = false;
257
+				return;
258
+			}
259
+		}
260
+
261
+		// Any need to pop at end of calendar-data?
262
+		// Yes - $this->_comps is re-used for parsing filters
263
+		if ($name == 'comp' || $name == 'calendar-data' ||
264
+				$name == 'comp-filter' || $name == 'filter') {
265
+			array_pop($this->_comps);
266
+		}
267
+
268
+		array_pop($this->_names);
269
+	}
270 270
 }
271 271
 
272 272
 /*
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -171,7 +171,7 @@  discard block
 block discarded – undo
171 171
 
172 172
             if ($name == 'calendar-data') {
173 173
                 $prop['value'] = array();
174
-                $this->_comps[] =& $prop['value'];
174
+                $this->_comps[] = & $prop['value'];
175 175
             }
176 176
 
177 177
             $this->props[] = $prop;
@@ -186,7 +186,7 @@  discard block
 block discarded – undo
186 186
 
187 187
             $this->_comps[count($this->_comps) - 1]['comps'][$attrs['name']] =
188 188
                 array();
189
-            $this->_comps[] =& $this->_comps[count($this->_comps) - 1]['comps']
189
+            $this->_comps[] = & $this->_comps[count($this->_comps) - 1]['comps']
190 190
                 [$attrs['name']];
191 191
             $this->_names[] = $name;
192 192
             return;
@@ -203,7 +203,7 @@  discard block
 block discarded – undo
203 203
         }
204 204
 
205 205
         if (count($this->_names) == 1 && $name == 'filter') {
206
-            $this->_comps[] =& $this->filters;
206
+            $this->_comps[] = & $this->filters;
207 207
             $this->_names[] = $name;
208 208
             return;
209 209
         }
@@ -215,7 +215,7 @@  discard block
 block discarded – undo
215 215
 
216 216
             $this->_comps[count($this->_comps) - 1]['comps'][$attrs['name']] =
217 217
                 array();
218
-            $this->_comps[] =& $this->_comps[count($this->_comps) - 1]['comps']
218
+            $this->_comps[] = & $this->_comps[count($this->_comps) - 1]['comps']
219 219
                 [$attrs['name']];
220 220
             $this->_names[] = $name;
221 221
             return;
Please login to merge, or discard this patch.
phpicalendar/lib/HTTP/WebDAV/Server.php 5 patches
Doc Comments   +13 added lines, -9 removed lines patch added patch discarded remove patch
@@ -456,7 +456,7 @@  discard block
 block discarded – undo
456 456
      * PROPFIND request helper - prepares data-structures from PROPFIND requests
457 457
      *
458 458
      * @param options
459
-     * @return void
459
+     * @return null|boolean
460 460
      */
461 461
     function propfind_request_helper(&$options)
462 462
     {
@@ -761,7 +761,7 @@  discard block
 block discarded – undo
761 761
      * PROPPATCH request helper - prepares data-structures from PROPPATCH requests
762 762
      *
763 763
      * @param options
764
-     * @return void
764
+     * @return null|boolean
765 765
      */
766 766
     function proppatch_request_helper(&$options)
767 767
     {
@@ -894,7 +894,7 @@  discard block
 block discarded – undo
894 894
      * GET request helper - prepares data-structures from GET requests
895 895
      *
896 896
      * @param options
897
-     * @return void
897
+     * @return boolean
898 898
      */
899 899
     function get_request_helper(&$options)
900 900
     {
@@ -1270,7 +1270,7 @@  discard block
 block discarded – undo
1270 1270
      * PUT request helper - prepares data-structures from PUT requests
1271 1271
      *
1272 1272
      * @param options
1273
-     * @return void
1273
+     * @return null|boolean
1274 1274
      */
1275 1275
     function put_request_helper(&$options)
1276 1276
     {
@@ -1489,7 +1489,7 @@  discard block
 block discarded – undo
1489 1489
      * requests
1490 1490
      *
1491 1491
      * @param options
1492
-     * @return void
1492
+     * @return null|boolean
1493 1493
      */
1494 1494
     function copymove_request_helper(&$options)
1495 1495
     {
@@ -1631,7 +1631,7 @@  discard block
 block discarded – undo
1631 1631
      * LOCK request helper - prepares data-structures from LOCK requests
1632 1632
      *
1633 1633
      * @param options
1634
-     * @return void
1634
+     * @return boolean|null
1635 1635
      */
1636 1636
     function lock_request_helper(&$options)
1637 1637
     {
@@ -1771,7 +1771,7 @@  discard block
 block discarded – undo
1771 1771
      * UNLOCK request helper - prepares data-structures from UNLOCK requests
1772 1772
      *
1773 1773
      * @param options
1774
-     * @return void
1774
+     * @return boolean
1775 1775
      */
1776 1776
     function unlock_request_helper(&$options)
1777 1777
     {
@@ -1843,6 +1843,9 @@  discard block
 block discarded – undo
1843 1843
         return $reqprop;
1844 1844
     }
1845 1845
 
1846
+    /**
1847
+     * @param string $path
1848
+     */
1846 1849
     function getDescendentsLocks($path)
1847 1850
     {
1848 1851
         $options = array();
@@ -1865,7 +1868,7 @@  discard block
 block discarded – undo
1865 1868
      * list implemented methods
1866 1869
      *
1867 1870
      * @param void
1868
-     * @return array something
1871
+     * @return string[] something
1869 1872
      */
1870 1873
     function _allow()
1871 1874
     {
@@ -2156,7 +2159,7 @@  discard block
 block discarded – undo
2156 2159
      * defined in RFC2518 9.4
2157 2160
      *
2158 2161
      * @param  void
2159
-     * @return void
2162
+     * @return boolean|null
2160 2163
      */
2161 2164
     function _check_if_header_conditions()
2162 2165
     {
@@ -2367,6 +2370,7 @@  discard block
 block discarded – undo
2367 2370
      * UTF-8 encode property values if not already done so
2368 2371
      *
2369 2372
      * @param  string  text to encode
2373
+     * @param string $text
2370 2374
      * @return string  utf-8 encoded text
2371 2375
      */
2372 2376
     function _prop_encode($text)
Please login to merge, or discard this patch.
Indentation   +2255 added lines, -2255 removed lines patch added patch discarded remove patch
@@ -33,2266 +33,2266 @@  discard block
 block discarded – undo
33 33
  */
34 34
 class HTTP_WebDAV_Server
35 35
 {
36
-    // {{{ Member Variables
37
-
38
-    /**
39
-     * URI path for this request
40
-     *
41
-     * @var string
42
-     */
43
-    var $path;
44
-
45
-    /**
46
-     * base URI for this request
47
-     *
48
-     * @var string
49
-     */
50
-    var $base_uri;
51
-
52
-    /**
53
-     * Realm string to be used in authentification popups
54
-     *
55
-     * @var string
56
-     */
57
-    var $http_auth_realm = 'PHP WebDAV';
58
-
59
-    /**
60
-     * String to be used in "X-Dav-Powered-By" header
61
-     *
62
-     * @var string
63
-     */
64
-    var $dav_powered_by = '';
65
-
66
-    /**
67
-     * Remember parsed If: (RFC2518 9.4) header conditions
68
-     *
69
-     * @var array
70
-     */
71
-    var $_if_header_uris = array();
72
-
73
-    /**
74
-     * HTTP response status/message
75
-     *
76
-     * @var string
77
-     */
78
-    var $_http_status = '200 OK';
79
-
80
-    /**
81
-     * encoding of property values passed in
82
-     *
83
-     * @var string
84
-     */
85
-    var $_prop_encoding = 'utf-8';
86
-
87
-    // }}}
88
-
89
-    // {{{ ServeRequest
90
-
91
-    /**
92
-     * Serve WebDAV HTTP request
93
-     *
94
-     * dispatch WebDAV HTTP request to the apropriate method wrapper
95
-     *
96
-     * @param void
97
-     * @return void
98
-     */
99
-    function ServeRequest()
100
-    {
101
-        // identify ourselves
102
-        if (empty($this->dav_powered_by)) {
103
-            $this->dav_powered_by = 'PHP class: ' . get_class($this);
104
-        }
105
-        header('X-Dav-Powered-By: ' . $this->dav_powered_by);
106
-
107
-        // set path
108
-        if (empty($this->path)) {
109
-            $this->path = $this->_urldecode($_SERVER['PATH_INFO']);
110
-            $this->path = ltrim($this->path, '/');
111
-            $this->path = rtrim($this->path, '/');
112
-        }
113
-
114
-        if (ini_get('magic_quotes_gpc')) {
115
-            $this->path = stripslashes($this->path);
116
-        }
117
-
118
-        // set base uri
119
-        if (empty($this->base_uri)) {
120
-            $path_info = $this->_urldecode($_SERVER['PATH_INFO']);
121
-            $request_uri = $this->_urldecode($_SERVER['REQUEST_URI']);
122
-            $this->base_uri = substr($request_uri, 0, strlen($request_uri) -
123
-                strlen($path_info));
124
-            $this->base_uri = rtrim($this->base_uri, '/');
125
-        }
126
-
127
-        // check authentication
128
-        if (!$this->check_auth_wrapper()) {
129
-
130
-            // RFC2518 says we must use Digest instead of Basic
131
-            // but Microsoft Clients do not support Digest
132
-            // and we don't support NTLM or Kerberos
133
-            // so we are stuck with Basic here
134
-            header('WWW-Authenticate: Basic realm="' . ($this->http_auth_realm) . '"');
135
-
136
-            // Windows seems to require this being the last header sent
137
-            // (changed according to PECL bug #3138)
138
-            $this->http_status('401 Authentication Required');
139
-
140
-            return;
141
-        }
142
-
143
-        // check
144
-        if (! $this->_check_if_header_conditions()) {
145
-            $this->http_status('412 Precondition Failed');
146
-            return;
147
-        }
148
-
149
-        // detect requested method names
150
-        $method = strtolower($_SERVER['REQUEST_METHOD']);
151
-        $wrapper = $method . '_wrapper';
152
-
153
-        // emulate HEAD using GET if no HEAD method found
154
-        if ($wrapper == 'head_wrapper' &&
155
-                !method_exists($this, 'head')) {
156
-            $method = 'get';
157
-        }
158
-
159
-        if (method_exists($this, $method) &&
160
-                method_exists($this, $wrapper) ||
161
-                $method == 'options') {
162
-            $this->$wrapper();
163
-            return;
164
-        }
165
-
166
-        // method not found/implemented
167
-        if ($method == 'lock') {
168
-            $this->http_status('412 Precondition Failed');
169
-            return;
170
-        }
171
-
172
-        // tell client what's allowed
173
-        header('Allow: ' . implode(', ', $this->_allow()));
174
-        $this->http_status('405 Method Not Allowed');
175
-    }
176
-
177
-    // }}}
178
-
179
-    // {{{ abstract WebDAV methods
180
-
181
-    // {{{ GET
182
-
183
-    /**
184
-     * GET implementation
185
-     *
186
-     * overload this method to retrieve resources from your server
187
-     * <br>
188
-     *
189
-     *
190
-     * @abstract
191
-     * @param array &$params array of input and output parameters
192
-     * <br><b>input</b><ul>
193
-     * <li> path -
194
-     * </ul>
195
-     * <br><b>output</b><ul>
196
-     * <li> size -
197
-     * </ul>
198
-     * @returns int HTTP-Statuscode
199
-     */
200
-
201
-    /* abstract
36
+	// {{{ Member Variables
37
+
38
+	/**
39
+	 * URI path for this request
40
+	 *
41
+	 * @var string
42
+	 */
43
+	var $path;
44
+
45
+	/**
46
+	 * base URI for this request
47
+	 *
48
+	 * @var string
49
+	 */
50
+	var $base_uri;
51
+
52
+	/**
53
+	 * Realm string to be used in authentification popups
54
+	 *
55
+	 * @var string
56
+	 */
57
+	var $http_auth_realm = 'PHP WebDAV';
58
+
59
+	/**
60
+	 * String to be used in "X-Dav-Powered-By" header
61
+	 *
62
+	 * @var string
63
+	 */
64
+	var $dav_powered_by = '';
65
+
66
+	/**
67
+	 * Remember parsed If: (RFC2518 9.4) header conditions
68
+	 *
69
+	 * @var array
70
+	 */
71
+	var $_if_header_uris = array();
72
+
73
+	/**
74
+	 * HTTP response status/message
75
+	 *
76
+	 * @var string
77
+	 */
78
+	var $_http_status = '200 OK';
79
+
80
+	/**
81
+	 * encoding of property values passed in
82
+	 *
83
+	 * @var string
84
+	 */
85
+	var $_prop_encoding = 'utf-8';
86
+
87
+	// }}}
88
+
89
+	// {{{ ServeRequest
90
+
91
+	/**
92
+	 * Serve WebDAV HTTP request
93
+	 *
94
+	 * dispatch WebDAV HTTP request to the apropriate method wrapper
95
+	 *
96
+	 * @param void
97
+	 * @return void
98
+	 */
99
+	function ServeRequest()
100
+	{
101
+		// identify ourselves
102
+		if (empty($this->dav_powered_by)) {
103
+			$this->dav_powered_by = 'PHP class: ' . get_class($this);
104
+		}
105
+		header('X-Dav-Powered-By: ' . $this->dav_powered_by);
106
+
107
+		// set path
108
+		if (empty($this->path)) {
109
+			$this->path = $this->_urldecode($_SERVER['PATH_INFO']);
110
+			$this->path = ltrim($this->path, '/');
111
+			$this->path = rtrim($this->path, '/');
112
+		}
113
+
114
+		if (ini_get('magic_quotes_gpc')) {
115
+			$this->path = stripslashes($this->path);
116
+		}
117
+
118
+		// set base uri
119
+		if (empty($this->base_uri)) {
120
+			$path_info = $this->_urldecode($_SERVER['PATH_INFO']);
121
+			$request_uri = $this->_urldecode($_SERVER['REQUEST_URI']);
122
+			$this->base_uri = substr($request_uri, 0, strlen($request_uri) -
123
+				strlen($path_info));
124
+			$this->base_uri = rtrim($this->base_uri, '/');
125
+		}
126
+
127
+		// check authentication
128
+		if (!$this->check_auth_wrapper()) {
129
+
130
+			// RFC2518 says we must use Digest instead of Basic
131
+			// but Microsoft Clients do not support Digest
132
+			// and we don't support NTLM or Kerberos
133
+			// so we are stuck with Basic here
134
+			header('WWW-Authenticate: Basic realm="' . ($this->http_auth_realm) . '"');
135
+
136
+			// Windows seems to require this being the last header sent
137
+			// (changed according to PECL bug #3138)
138
+			$this->http_status('401 Authentication Required');
139
+
140
+			return;
141
+		}
142
+
143
+		// check
144
+		if (! $this->_check_if_header_conditions()) {
145
+			$this->http_status('412 Precondition Failed');
146
+			return;
147
+		}
148
+
149
+		// detect requested method names
150
+		$method = strtolower($_SERVER['REQUEST_METHOD']);
151
+		$wrapper = $method . '_wrapper';
152
+
153
+		// emulate HEAD using GET if no HEAD method found
154
+		if ($wrapper == 'head_wrapper' &&
155
+				!method_exists($this, 'head')) {
156
+			$method = 'get';
157
+		}
158
+
159
+		if (method_exists($this, $method) &&
160
+				method_exists($this, $wrapper) ||
161
+				$method == 'options') {
162
+			$this->$wrapper();
163
+			return;
164
+		}
165
+
166
+		// method not found/implemented
167
+		if ($method == 'lock') {
168
+			$this->http_status('412 Precondition Failed');
169
+			return;
170
+		}
171
+
172
+		// tell client what's allowed
173
+		header('Allow: ' . implode(', ', $this->_allow()));
174
+		$this->http_status('405 Method Not Allowed');
175
+	}
176
+
177
+	// }}}
178
+
179
+	// {{{ abstract WebDAV methods
180
+
181
+	// {{{ GET
182
+
183
+	/**
184
+	 * GET implementation
185
+	 *
186
+	 * overload this method to retrieve resources from your server
187
+	 * <br>
188
+	 *
189
+	 *
190
+	 * @abstract
191
+	 * @param array &$params array of input and output parameters
192
+	 * <br><b>input</b><ul>
193
+	 * <li> path -
194
+	 * </ul>
195
+	 * <br><b>output</b><ul>
196
+	 * <li> size -
197
+	 * </ul>
198
+	 * @returns int HTTP-Statuscode
199
+	 */
200
+
201
+	/* abstract
202 202
        function GET()
203 203
        {
204 204
            // dummy entry for PHPDoc
205 205
        }
206 206
     */
207 207
 
208
-    // }}}
208
+	// }}}
209 209
 
210
-    // {{{ PUT
210
+	// {{{ PUT
211 211
 
212
-    /**
213
-     * PUT implementation
214
-     *
215
-     * @abstract
216
-     * @param array &$params
217
-     * @returns int HTTP-Statuscode
218
-     */
212
+	/**
213
+	 * PUT implementation
214
+	 *
215
+	 * @abstract
216
+	 * @param array &$params
217
+	 * @returns int HTTP-Statuscode
218
+	 */
219 219
 
220
-    /* abstract
220
+	/* abstract
221 221
        function PUT()
222 222
        {
223 223
            // dummy entry for PHPDoc
224 224
        }
225 225
     */
226 226
 
227
-    // }}}
227
+	// }}}
228 228
 
229
-    // {{{ COPY
229
+	// {{{ COPY
230 230
 
231
-    /**
232
-     * COPY implementation
233
-     *
234
-     * @abstract
235
-     * @param array &$params
236
-     * @returns int HTTP-Statuscode
237
-     */
231
+	/**
232
+	 * COPY implementation
233
+	 *
234
+	 * @abstract
235
+	 * @param array &$params
236
+	 * @returns int HTTP-Statuscode
237
+	 */
238 238
 
239
-    /* abstract
239
+	/* abstract
240 240
        function COPY()
241 241
        {
242 242
            // dummy entry for PHPDoc
243 243
        }
244 244
     */
245 245
 
246
-    // }}}
246
+	// }}}
247 247
 
248
-    // {{{ MOVE
248
+	// {{{ MOVE
249 249
 
250
-    /**
251
-     * MOVE implementation
252
-     *
253
-     * @abstract
254
-     * @param array &$params
255
-     * @returns int HTTP-Statuscode
256
-     */
250
+	/**
251
+	 * MOVE implementation
252
+	 *
253
+	 * @abstract
254
+	 * @param array &$params
255
+	 * @returns int HTTP-Statuscode
256
+	 */
257 257
 
258
-    /* abstract
258
+	/* abstract
259 259
        function MOVE()
260 260
        {
261 261
            // dummy entry for PHPDoc
262 262
        }
263 263
     */
264 264
 
265
-    // }}}
265
+	// }}}
266 266
 
267
-    // {{{ DELETE
267
+	// {{{ DELETE
268 268
 
269
-    /**
270
-     * DELETE implementation
271
-     *
272
-     * @abstract
273
-     * @param array &$params
274
-     * @returns int HTTP-Statuscode
275
-     */
269
+	/**
270
+	 * DELETE implementation
271
+	 *
272
+	 * @abstract
273
+	 * @param array &$params
274
+	 * @returns int HTTP-Statuscode
275
+	 */
276 276
 
277
-    /* abstract
277
+	/* abstract
278 278
        function DELETE()
279 279
        {
280 280
            // dummy entry for PHPDoc
281 281
        }
282 282
     */
283 283
 
284
-    // }}}
284
+	// }}}
285 285
 
286
-    // {{{ PROPFIND
286
+	// {{{ PROPFIND
287 287
 
288
-    /**
289
-     * PROPFIND implementation
290
-     *
291
-     * @abstract
292
-     * @param array &$params
293
-     * @returns int HTTP-Statuscode
294
-     */
288
+	/**
289
+	 * PROPFIND implementation
290
+	 *
291
+	 * @abstract
292
+	 * @param array &$params
293
+	 * @returns int HTTP-Statuscode
294
+	 */
295 295
 
296
-    /* abstract
296
+	/* abstract
297 297
        function PROPFIND()
298 298
        {
299 299
            // dummy entry for PHPDoc
300 300
        }
301 301
     */
302 302
 
303
-    // }}}
303
+	// }}}
304 304
 
305
-    // {{{ PROPPATCH
305
+	// {{{ PROPPATCH
306 306
 
307
-    /**
308
-     * PROPPATCH implementation
309
-     *
310
-     * @abstract
311
-     * @param array &$params
312
-     * @returns int HTTP-Statuscode
313
-     */
307
+	/**
308
+	 * PROPPATCH implementation
309
+	 *
310
+	 * @abstract
311
+	 * @param array &$params
312
+	 * @returns int HTTP-Statuscode
313
+	 */
314 314
 
315
-    /* abstract
315
+	/* abstract
316 316
        function PROPPATCH()
317 317
        {
318 318
            // dummy entry for PHPDoc
319 319
        }
320 320
     */
321 321
 
322
-    // }}}
322
+	// }}}
323 323
 
324
-    // {{{ LOCK
324
+	// {{{ LOCK
325 325
 
326
-    /**
327
-     * LOCK implementation
328
-     *
329
-     * @abstract
330
-     * @param array &$params
331
-     * @returns int HTTP-Statuscode
332
-     */
326
+	/**
327
+	 * LOCK implementation
328
+	 *
329
+	 * @abstract
330
+	 * @param array &$params
331
+	 * @returns int HTTP-Statuscode
332
+	 */
333 333
 
334
-    /* abstract
334
+	/* abstract
335 335
        function LOCK()
336 336
        {
337 337
            // dummy entry for PHPDoc
338 338
        }
339 339
     */
340 340
 
341
-    // }}}
341
+	// }}}
342 342
 
343
-    // {{{ UNLOCK
343
+	// {{{ UNLOCK
344 344
 
345
-    /**
346
-     * UNLOCK implementation
347
-     *
348
-     * @abstract
349
-     * @param array &$params
350
-     * @returns int HTTP-Statuscode
351
-     */
345
+	/**
346
+	 * UNLOCK implementation
347
+	 *
348
+	 * @abstract
349
+	 * @param array &$params
350
+	 * @returns int HTTP-Statuscode
351
+	 */
352 352
 
353
-    /* abstract
353
+	/* abstract
354 354
        function UNLOCK()
355 355
        {
356 356
            // dummy entry for PHPDoc
357 357
        }
358 358
     */
359 359
 
360
-    // }}}
360
+	// }}}
361 361
 
362
-    // }}}
362
+	// }}}
363 363
 
364
-    // {{{ other abstract methods
364
+	// {{{ other abstract methods
365 365
 
366
-    // {{{ checkAuth
366
+	// {{{ checkAuth
367 367
 
368
-    /**
369
-     * check authentication
370
-     *
371
-     * overload this method to retrieve and confirm authentication information
372
-     *
373
-     * @abstract
374
-     * @param string type Authentication type, e.g. "basic" or "digest"
375
-     * @param string username Transmitted username
376
-     * @param string passwort Transmitted password
377
-     * @returns bool Authentication status
378
-     */
368
+	/**
369
+	 * check authentication
370
+	 *
371
+	 * overload this method to retrieve and confirm authentication information
372
+	 *
373
+	 * @abstract
374
+	 * @param string type Authentication type, e.g. "basic" or "digest"
375
+	 * @param string username Transmitted username
376
+	 * @param string passwort Transmitted password
377
+	 * @returns bool Authentication status
378
+	 */
379 379
 
380
-    /* abstract
380
+	/* abstract
381 381
        function checkAuth($type, $username, $password)
382 382
        {
383 383
            // dummy entry for PHPDoc
384 384
        }
385 385
     */
386 386
 
387
-    // }}}
387
+	// }}}
388 388
 
389
-    // {{{ getLocks
389
+	// {{{ getLocks
390 390
 
391
-    /**
392
-     * get lock entries for a resource
393
-     *
394
-     * overload this method to return shared and exclusive locks
395
-     * active for this resource
396
-     *
397
-     * @abstract
398
-     * @param string resource path to check
399
-     * @returns array of lock entries each consisting
400
-     *                of 'type' ('shared'/'exclusive'), 'token' and 'timeout'
401
-     */
391
+	/**
392
+	 * get lock entries for a resource
393
+	 *
394
+	 * overload this method to return shared and exclusive locks
395
+	 * active for this resource
396
+	 *
397
+	 * @abstract
398
+	 * @param string resource path to check
399
+	 * @returns array of lock entries each consisting
400
+	 *                of 'type' ('shared'/'exclusive'), 'token' and 'timeout'
401
+	 */
402 402
 
403
-    /* abstract
403
+	/* abstract
404 404
        function getLocks($path)
405 405
        {
406 406
            // dummy entry for PHPDoc
407 407
        }
408 408
     */
409 409
 
410
-    // }}}
411
-
412
-    // }}}
413
-
414
-    // {{{ WebDAV HTTP method wrappers
415
-
416
-    // {{{ options
417
-
418
-    /**
419
-     * OPTIONS method handler
420
-     *
421
-     * The OPTIONS method handler creates a valid OPTIONS reply
422
-     * including Dav: and Allowed: heaers
423
-     * based on the implemented methods found in the actual instance
424
-     *
425
-     * @param void
426
-     * @return void
427
-     */
428
-    function options()
429
-    {
430
-        // get allowed methods
431
-        $allow = $this->_allow();
432
-
433
-        // dav header
434
-        $dav = array(1); // assume we are always dav class 1 compliant
435
-        if (in_array('LOCK', $allow) && in_array('UNLOCK', $allow)) {
436
-            $dav[] = 2; // dav class 2 requires that locking is supported
437
-        }
438
-
439
-        // tell clients what we found
440
-        header('Allow: ' . implode(', ', $allow));
441
-        header('DAV: ' . implode(',', $dav));
442
-        header('Content-Length: 0');
443
-
444
-        // Microsoft clients default to the Frontpage protocol
445
-        // unless we tell them to use WebDAV
446
-        header('MS-Author-Via: DAV');
447
-
448
-        $this->http_status('200 OK');
449
-    }
450
-
451
-    // }}}
452
-
453
-    // {{{ propfind_request_helper
454
-
455
-    /**
456
-     * PROPFIND request helper - prepares data-structures from PROPFIND requests
457
-     *
458
-     * @param options
459
-     * @return void
460
-     */
461
-    function propfind_request_helper(&$options)
462
-    {
463
-        $options = array();
464
-        $options['path'] = $this->path;
465
-
466
-        // get depth from header (default is 'infinity')
467
-        $options['depth'] = 'infinity';
468
-        if (isset($_SERVER['HTTP_DEPTH'])) {
469
-            $options['depth'] = $_SERVER['HTTP_DEPTH'];
470
-        }
471
-
472
-        // analyze request payload
473
-        $parser = new _parse_propfind('php://input');
474
-        if (!$parser->success) {
475
-            $this->http_status('400 Bad Request');
476
-            return;
477
-        }
478
-
479
-        $options['props'] = $parser->props;
480
-
481
-        return true;
482
-    }
483
-
484
-    // }}}
485
-
486
-    // {{{ propfind_response_helper
487
-
488
-    /**
489
-     * PROPFIND response helper - format PROPFIND response
490
-     *
491
-     * @param options
492
-     * @param files
493
-     * @return void
494
-     */
495
-    function propfind_response_helper($options, $files)
496
-    {
497
-        $responses = array();
498
-
499
-        // now loop over all returned files
500
-        foreach ($files as $file) {
501
-
502
-            // collect namespaces here
503
-            // Microsoft need this special namespace for date and time values
504
-            $ns_hash = array(
505
-                'urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882' => 'ns0');
506
-
507
-            $response = array();
508
-
509
-            $response['href'] = $this->getHref($file['path']);
510
-            if (isset($file['href'])) {
511
-                $response['href'] = $file['href'];
512
-            }
513
-
514
-            $response['propstat'] = array();
515
-
516
-            if (is_array($options['props'])) {
517
-
518
-                // loop over all requested properties
519
-                foreach ($options['props'] as $reqprop) {
520
-                    $status = '200 OK';
521
-                    $prop = $this->getProp($reqprop, $file, $options);
522
-
523
-                    if (isset($prop['status'])) {
524
-                        $status = $prop['status'];
525
-                    }
526
-
527
-                    if (!isset($response['propstat'][$status])) {
528
-                        $response['propstat'][$status] = array();
529
-                    }
530
-
531
-                    $response['propstat'][$status][] = $prop;
532
-
533
-                    // namespace handling
534
-                    if (empty($prop['ns']) || // empty namespace
535
-                            $prop['ns'] == 'DAV:' || // default namespace
536
-                            isset($ns_hash[$prop['ns']])) { // already known
537
-                        continue;
538
-                    }
539
-
540
-                    // register namespace
541
-                    $ns_hash[$prop['ns']] = 'ns' . count($ns_hash);
542
-                }
543
-            } else if (is_array($file['props'])) {
544
-
545
-                // loop over all returned properties
546
-                foreach ($file['props'] as $prop) {
547
-                    $status = '200 OK';
548
-
549
-                    if (isset($prop['status'])) {
550
-                        $status = $prop['status'];
551
-                    }
552
-
553
-                    if (!isset($response['propstat'][$status])) {
554
-                        $response['propstat'][$status] = array();
555
-                    }
556
-
557
-                    if ($options['props'] == 'propname') {
558
-
559
-                        // only names of all existing properties were requested
560
-                        // so remove values
561
-                        unset($prop['value']);
562
-                    }
563
-
564
-                    $response['propstat'][$status][] = $prop;
565
-                        unset($prop['value']);
566
-
567
-                    // namespace handling
568
-                    if (empty($prop['ns']) || // empty namespace
569
-                            $prop['ns'] == 'DAV:' || // default namespace
570
-                            isset($ns_hash[$prop['ns']])) { // already known
571
-                        continue;
572
-                    }
573
-
574
-                    // register namespace
575
-                    $ns_hash[$prop['ns']] = 'ns' . count($ns_hash);
576
-                }
577
-            }
578
-
579
-            $response['ns_hash'] = $ns_hash;
580
-            $responses[] = $response;
581
-        }
582
-
583
-        $this->_multistatus($responses);
584
-    }
585
-
586
-    function _multistatus($responses)
587
-    {
588
-        // now we generate the response header...
589
-        $this->http_status('207 Multi-Status');
590
-        header('Content-Type: text/xml; charset="utf-8"');
591
-
592
-        // ...and payload
593
-        echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
594
-        echo "<D:multistatus xmlns:D=\"DAV:\">\n";
595
-
596
-        foreach ($responses as $response) {
597
-
598
-            // ignore empty or incomplete entries
599
-            if (!is_array($response) || empty($response)) {
600
-                continue;
601
-            }
602
-
603
-            $ns_defs = array();
604
-            foreach ($response['ns_hash'] as $name => $prefix) {
605
-                $ns_defs[] = "xmlns:$prefix=\"$name\"";
606
-            }
607
-            echo ' <D:response ' . implode(' ', $ns_defs) . ">\n";
608
-            echo "  <D:href>$response[href]</D:href>\n";
609
-
610
-            // report all found properties and their values (if any)
611
-            // nothing to do if no properties were returend for a file
612
-            if (isset($response['propstat']) &&
613
-                    is_array($response['propstat'])) {
614
-
615
-                foreach ($response['propstat'] as $status => $props) {
616
-                    echo "  <D:propstat>\n";
617
-                    echo "   <D:prop>\n";
618
-
619
-                    foreach ($props as $prop) {
620
-                        if (!is_array($prop) || !isset($prop['name'])) {
621
-                            continue;
622
-                        }
623
-
624
-                        // empty properties (cannot use empty for check as '0'
625
-                        // is a legal value here)
626
-                        if (!isset($prop['value']) || empty($prop['value']) &&
627
-                                $prop['value'] !== 0) {
628
-                            if ($prop['ns'] == 'DAV:') {
629
-                                echo "    <D:$prop[name]/>\n";
630
-                                continue;
631
-                            }
632
-
633
-                            if (!empty($prop['ns'])) {
634
-                                echo '    <' .
635
-                                    $response['ns_hash'][$prop['ns']] .
636
-                                    ":$prop[name]/>\n";
637
-                                continue;
638
-                            }
639
-
640
-                            echo "    <$prop[name] xmlns=\"\"/>";
641
-                            continue;
642
-                        }
643
-
644
-                        // some WebDAV properties need special treatment
645
-                        if ($prop['ns'] == 'DAV:') {
646
-
647
-                            switch ($prop['name']) {
648
-                            case 'creationdate':
649
-                                echo "    <D:creationdate ns0:dt=\"dateTime.tz\">\n";
650
-                                echo '     ' . gmdate('Y-m-d\TH:i:s\Z', $prop['value']) . "\n";
651
-                                echo "    </D:creationdate>\n";
652
-                                break;
653
-
654
-                            case 'getlastmodified':
655
-                                echo "    <D:getlastmodified ns0:dt=\"dateTime.rfc1123\">\n";
656
-                                echo '     ' . gmdate('D, d M Y H:i:s', $prop['value']) . " GMT\n";
657
-                                echo "    </D:getlastmodified>\n";
658
-                                break;
659
-
660
-                            case 'resourcetype':
661
-                                echo "    <D:resourcetype>\n";
662
-                                echo "     <D:$prop[value]/>\n";
663
-                                echo "    </D:resourcetype>\n";
664
-                                break;
665
-
666
-                            case 'supportedlock':
667
-
668
-                                if (is_array($prop[value])) {
669
-                                    $prop[value] = $this->_lockentries($prop[value]);
670
-                                }
671
-                                echo "    <D:supportedlock>\n";
672
-                                echo "     $prop[value]\n";
673
-                                echo "    </D:supportedlock>\n";
674
-                                break;
675
-
676
-                            case 'lockdiscovery':
677
-
678
-                                if (is_array($prop[value])) {
679
-                                    $prop[value] = $this->_activelocks($prop[value]);
680
-                                }
681
-                                echo "    <D:lockdiscovery>\n";
682
-                                echo "     $prop[value]\n";
683
-                                echo "    </D:lockdiscovery>\n";
684
-                                break;
685
-
686
-                            default:
687
-                                echo "    <D:$prop[name]>\n";
688
-                                echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
689
-                                echo "    </D:$prop[name]>\n";
690
-                            }
691
-
692
-                            continue;
693
-                        }
694
-
695
-                        if (!empty($prop['ns'])) {
696
-                            echo '    <' . $response['ns_hash'][$prop['ns']] . ":$prop[name]>\n";
697
-                            echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
698
-                            echo '    </' . $response['ns_hash'][$prop['ns']] . ":$prop[name]>\n";
699
-
700
-                            continue;
701
-                        }
702
-
703
-                        echo "    <$prop[name] xmlns=\"\">\n";
704
-                        echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
705
-                        echo "    </$prop[name]>\n";
706
-                    }
707
-
708
-                    echo "   </D:prop>\n";
709
-                    echo "   <D:status>HTTP/1.1 $status</D:status>\n";
710
-                    echo "  </D:propstat>\n";
711
-                }
712
-            }
713
-
714
-            if (isset($response['status'])) {
715
-                echo "  <D:status>HTTP/1.1 $status</D:status>\n";
716
-            }
717
-
718
-            if (isset($response['responsedescription'])) {
719
-                echo "  <D:responsedescription>\n";
720
-                echo '   ' . $this->_prop_encode(htmlspecialchars($response['responsedescription'])) . "\n";
721
-                echo "  </D:responsedescription>\n";
722
-            }
723
-
724
-            echo " </D:response>\n";
725
-        }
726
-
727
-        echo "</D:multistatus>\n";
728
-    }
729
-
730
-    // }}}
731
-
732
-    // {{{ propfind_wrapper
733
-
734
-    /**
735
-     * PROPFIND method wrapper
736
-     *
737
-     * @param void
738
-     * @return void
739
-     */
740
-    function propfind_wrapper()
741
-    {
742
-        // prepare data-structure from PROPFIND request
743
-        if (!$this->propfind_request_helper($options)) {
744
-            return;
745
-        }
746
-
747
-        // call user handler
748
-        if (!$this->propfind($options, $files)) {
749
-            return;
750
-        }
751
-
752
-        // format PROPFIND response
753
-        $this->propfind_response_helper($options, $files);
754
-    }
755
-
756
-    // }}}
757
-
758
-    // {{{ proppatch_request_helper
759
-
760
-    /**
761
-     * PROPPATCH request helper - prepares data-structures from PROPPATCH requests
762
-     *
763
-     * @param options
764
-     * @return void
765
-     */
766
-    function proppatch_request_helper(&$options)
767
-    {
768
-        $options = array();
769
-        $options['path'] = $this->path;
770
-
771
-        $propinfo = new _parse_proppatch('php://input');
772
-
773
-        if (!$propinfo->success) {
774
-            $this->http_status('400 Bad Request');
775
-            return;
776
-        }
777
-
778
-        $options['props'] = $propinfo->props;
779
-
780
-        return true;
781
-    }
782
-
783
-    // }}}
784
-
785
-    // {{{ proppatch_response_helper
786
-
787
-    /**
788
-     * PROPPATCH response helper - format PROPPATCH response
789
-     *
790
-     * @param options
791
-     * @param responsedescr
792
-     * @return void
793
-     */
794
-    function proppatch_response_helper($options, $responsedescription=null)
795
-    {
796
-        $response = array();
797
-
798
-        $response['href'] = $this->getHref($options['path']);
799
-        if (isset($options['href'])) {
800
-            $response['href'] = $options['href'];
801
-        }
802
-
803
-        $response['propstat'] = array();
804
-
805
-        // collect namespaces here
806
-        $ns_hash = array();
807
-
808
-        if (isset($options['props']) && is_array($options['props'])) {
809
-            foreach ($options['props'] as $prop) {
810
-                $status = '200 OK';
811
-                if (isset($prop['status'])) {
812
-                    $status = $prop['status'];
813
-                }
814
-
815
-                if (!isset($response['propstat'][$status])) {
816
-                    $response['propstat'][$status] = array();
817
-                }
818
-
819
-                $response['propstat'][$status][] = $prop;
820
-
821
-                // namespace handling
822
-                if (empty($prop['ns']) || // empty namespace
823
-                        $prop['ns'] == 'DAV:' || // default namespace
824
-                        isset($ns_hash[$prop['ns']])) { // already known
825
-                    continue;
826
-                }
827
-
828
-                // register namespace
829
-                $ns_hash[$prop['ns']] = 'ns' . count($ns_hash);
830
-            }
831
-        }
832
-
833
-        $response['ns_hash'] = $ns_hash;
834
-        $response['responsedescription'] = $responsedescription;
835
-
836
-        $this->_multistatus(array($response));
837
-    }
838
-
839
-    // }}}
840
-
841
-    // {{{ proppatch_wrapper
842
-
843
-    /**
844
-     * PROPPATCH method wrapper
845
-     *
846
-     * @param void
847
-     * @return void
848
-     */
849
-    function proppatch_wrapper()
850
-    {
851
-        // check resource is not locked
852
-        if (!$this->check_lock_wrapper($this->path)) {
853
-            $this->http_status('423 Locked');
854
-            return;
855
-        }
856
-
857
-        // perpare data-structure from PROPATCH request
858
-        if (!$this->proppatch_request_helper($options)) {
859
-            return;
860
-        }
861
-
862
-        // call user handler
863
-        $responsedescription = $this->proppatch($options);
864
-
865
-        // format PROPPATCH response
866
-        $this->proppatch_response_helper($options, $responsedescription);
867
-    }
868
-
869
-    // }}}
870
-
871
-    // {{{ mkcol_wrapper
872
-
873
-    /**
874
-     * MKCOL method wrapper
875
-     *
876
-     * @param void
877
-     * @return void
878
-     */
879
-    function mkcol_wrapper()
880
-    {
881
-        $options = array();
882
-        $options['path'] = $this->path;
883
-
884
-        $status = $this->mkcol($options);
885
-
886
-        $this->http_status($status);
887
-    }
888
-
889
-    // }}}
890
-
891
-    // {{{ get_request_helper
892
-
893
-    /**
894
-     * GET request helper - prepares data-structures from GET requests
895
-     *
896
-     * @param options
897
-     * @return void
898
-     */
899
-    function get_request_helper(&$options)
900
-    {
901
-        // TODO check for invalid stream
902
-
903
-        $options = array();
904
-        $options['path'] = $this->path;
905
-
906
-        $this->_get_ranges($options);
907
-
908
-        return true;
909
-    }
910
-
911
-    /**
912
-     * parse HTTP Range: header
913
-     *
914
-     * @param  array options array to store result in
915
-     * @return void
916
-     */
917
-    function _get_ranges(&$options)
918
-    {
919
-        // process Range: header if present
920
-        if (isset($_SERVER['HTTP_RANGE'])) {
921
-
922
-            // we only support standard 'bytes' range specifications for now
923
-            if (ereg('bytes[[:space:]]*=[[:space:]]*(.+)', $_SERVER['HTTP_RANGE'], $matches)) {
924
-                $options['ranges'] = array();
925
-
926
-                // ranges are comma separated
927
-                foreach (explode(',', $matches[1]) as $range) {
928
-                    // ranges are either from-to pairs or just end positions
929
-                    list($start, $end) = explode('-', $range);
930
-                    $options['ranges'][] = ($start === '')
931
-                        ? array('last' => $end)
932
-                        : array('start' => $start, 'end' => $end);
933
-                }
934
-            }
935
-        }
936
-    }
937
-
938
-    // }}}
939
-
940
-    // {{{ get_response_helper
941
-
942
-    /**
943
-     * GET response helper - format GET response
944
-     *
945
-     * @param options
946
-     * @param status
947
-     * @return void
948
-     */
949
-    function get_response_helper($options, $status)
950
-    {
951
-        if (empty($status)) {
952
-            $status = '404 Not Found';
953
-        }
954
-
955
-        // set headers before we start printing
956
-        $this->http_status($status);
957
-
958
-        if ($status !== true) {
959
-            return;
960
-        }
961
-
962
-        if (!isset($options['mimetype'])) {
963
-            $options['mimetype'] = 'application/octet-stream';
964
-        }
965
-        header("Content-Type: $options[mimetype]");
966
-
967
-        if (isset($options['mtime'])) {
968
-            header('Last-Modified:' .
969
-                gmdate('D, d M Y H:i:s', $options['mtime']) . 'GMT');
970
-        }
971
-
972
-        if ($options['stream']) {
973
-            // GET handler returned a stream
974
-
975
-            if (!empty($options['ranges']) &&
976
-                    (fseek($options['stream'], 0, SEEK_SET) === 0)) {
977
-                // partial request and stream is seekable
978
-
979
-                if (count($options['ranges']) === 1) {
980
-                    $range = $options['ranges'][0];
981
-
982
-                    if (isset($range['start'])) {
983
-                        fseek($options['stream'], $range['start'], SEEK_SET);
984
-                        if (feof($options['stream'])) {
985
-                            $this->http_status('416 Requested Range Not Satisfiable');
986
-                            return;
987
-                        }
988
-
989
-                        if (isset($range['end'])) {
990
-                            $size = $range['end'] - $range['start'] + 1;
991
-                            $this->http_status('206 Partial');
992
-                            header("Content-Length: $size");
993
-                            header("Content-Range: $range[start]-$range[end]/" .
994
-                                (isset($options['size']) ? $options['size'] : '*'));
995
-                            while ($size && !feof($options['stream'])) {
996
-                                $buffer = fread($options['stream'], 4096);
997
-                                $size -= strlen($buffer);
998
-                                echo $buffer;
999
-                            }
1000
-                        } else {
1001
-                            $this->http_status('206 Partial');
1002
-                            if (isset($options['size'])) {
1003
-                                header("Content-Length: " .
1004
-                                    ($options['size'] - $range['start']));
1005
-                                header("Content-Range: $start-$end/" .
1006
-                                    (isset($options['size']) ? $options['size'] : '*'));
1007
-                            }
1008
-                            fpassthru($options['stream']);
1009
-                        }
1010
-                    } else {
1011
-                        header("Content-Length: $range[last]");
1012
-                        fseek($options['stream'], -$range['last'], SEEK_END);
1013
-                        fpassthru($options['stream']);
1014
-                    }
1015
-                } else {
1016
-                    $this->_multipart_byterange_header(); // init multipart
1017
-                    foreach ($options['ranges'] as $range) {
1018
-
1019
-                        // TODO what if size unknown? 500?
1020
-                        if (isset($range['start'])) {
1021
-                            $from = $range['start'];
1022
-                            $to = !empty($range['end']) ? $range['end'] : $options['size'] - 1;
1023
-                        } else {
1024
-                            $from = $options['size'] - $range['last'] - 1;
1025
-                            $to = $options['size'] - 1;
1026
-                        }
1027
-                        $total = isset($options['size']) ? $options['size'] : '*';
1028
-                        $size = $to - $from + 1;
1029
-                        $this->_multipart_byterange_header($options['mimetype'],
1030
-                            $from, $to, $total);
1031
-
1032
-                        fseek($options['stream'], $start, SEEK_SET);
1033
-                        while ($size && !feof($options['stream'])) {
1034
-                            $buffer = fread($options['stream'], 4096);
1035
-                            $size -= strlen($buffer);
1036
-                            echo $buffer;
1037
-                        }
1038
-                    }
1039
-                    $this->_multipart_byterange_header(); // end multipart
1040
-                }
1041
-            } else {
1042
-                // normal request or stream isn't seekable, return full content
1043
-                if (isset($options['size'])) {
1044
-                    header("Content-Length: $options[size]");
1045
-                }
1046
-
1047
-                fpassthru($options['stream']);
1048
-            }
1049
-        } else if (isset($options['data']))  {
1050
-            if (is_array($options['data'])) {
1051
-                // reply to partial request
1052
-            } else {
1053
-                header("Content-Length: " . strlen($options['data']));
1054
-                echo $options['data'];
1055
-            }
1056
-        }
1057
-    }
1058
-
1059
-    /**
1060
-     * generate separator headers for multipart response
1061
-     *
1062
-     * first and last call happen without parameters to generate
1063
-     * the initial header and closing sequence, all calls inbetween
1064
-     * require content mimetype, start and end byte position and
1065
-     * optionaly the total byte length of the requested resource
1066
-     *
1067
-     * @param  string  mimetype
1068
-     * @param  int     start byte position
1069
-     * @param  int     end   byte position
1070
-     * @param  int     total resource byte size
1071
-     */
1072
-    function _multipart_byterange_header($mimetype = false, $from = false,
1073
-        $to = false, $total = false)
1074
-    {
1075
-        if ($mimetype === false) {
1076
-            if (!isset($this->multipart_separator)) {
1077
-                // init
1078
-                // a little naive, this sequence *might* be part of the content
1079
-                // but it's really not likely and rather expensive to check
1080
-                $this->multipart_separator = 'SEPARATOR_' . md5(microtime());
1081
-
1082
-                // generate HTTP header
1083
-                header('Content-Type: multipart/byteranges; boundary=' .
1084
-                    $this->multipart_separator);
1085
-
1086
-                return;
1087
-            }
1088
-
1089
-            // end
1090
-            // generate closing multipart sequence
1091
-            echo "\n--{$this->multipart_separator}--";
1092
-
1093
-            return;
1094
-        }
1095
-
1096
-        // generate separator and header for next part
1097
-        echo "\n--{$this->multipart_separator}\n";
1098
-        echo "Content-Type: $mimetype\n";
1099
-        echo "Content-Range: $from-$to/"
1100
-            . ($total === false ? "*" : $total) . "\n\n";
1101
-    }
1102
-
1103
-    // }}}
1104
-
1105
-    // {{{ get_wrapper
1106
-
1107
-    /**
1108
-     * GET method wrapper
1109
-     *
1110
-     * @param void
1111
-     * @return void
1112
-     */
1113
-    function get_wrapper()
1114
-    {
1115
-        // perpare data-structure from GET request
1116
-        if (!$this->get_request_helper($options)) {
1117
-            return;
1118
-        }
1119
-
1120
-        // call user handler
1121
-        $status = $this->get($options);
1122
-
1123
-        // format GET response
1124
-        $this->get_response_helper($options, $status);
1125
-    }
1126
-
1127
-    // }}}
1128
-
1129
-    // {{{ head_response_helper
1130
-
1131
-    /**
1132
-     * HEAD response helper - format HEAD response
1133
-     *
1134
-     * @param options
1135
-     * @param status
1136
-     * @return void
1137
-     */
1138
-    function head_response_helper($options, $status)
1139
-    {
1140
-        if (empty($status)) {
1141
-            $status('404 Not Found');
1142
-        }
1143
-
1144
-        // set headers before we start printing
1145
-        $this->http_status($status);
1146
-
1147
-        if ($status !== true) {
1148
-            return;
1149
-        }
1150
-
1151
-        if (!isset($options['mimetype'])) {
1152
-            $options['mimetype'] = 'application/octet-stream';
1153
-        }
1154
-        header("Content-Type: $options[mimetype]");
1155
-
1156
-        if (isset($options['mtime'])) {
1157
-            header('Last-Modified:' .
1158
-                gmdate('D, d M Y H:i:s', $options['mtime']) . 'GMT');
1159
-        }
1160
-
1161
-        if (isset($options['stream'])) {
1162
-            // GET handler returned a stream
1163
-
1164
-            if (!empty($options['ranges']) &&
1165
-                    (fseek($options['stream'], 0, SEEK_SET) === 0)) {
1166
-                // partial request and stream is seekable
1167
-
1168
-                if (count($options['ranges']) === 1) {
1169
-                    $range = $options['ranges'][0];
1170
-
1171
-                    if (isset($range['start'])) {
1172
-                        fseek($options['stream'], $range['start'], SEEK_SET);
1173
-                        if (feof($options['stream'])) {
1174
-                            $this->http_status('416 Requested Range Not Satisfiable');
1175
-                            return;
1176
-                        }
1177
-
1178
-                        if (isset($range['end'])) {
1179
-                            $size = $range['end'] - $range['start'] + 1;
1180
-                            $this->http_status('206 Partial');
1181
-                            header("Content-Length: $size");
1182
-                            header("Content-Range: $range[start]-$range[end]/" .
1183
-                                (isset($options['size']) ? $options['size'] : '*'));
1184
-                        } else {
1185
-                            $this->http_status('206 Partial');
1186
-                            if (isset($options['size'])) {
1187
-                                header("Content-Length: " .
1188
-                                    ($options['size'] - $range['start']));
1189
-                                header("Content-Range: $start-$end/" .
1190
-                                    (isset($options['size']) ? $options['size'] : '*'));
1191
-                            }
1192
-                        }
1193
-                    } else {
1194
-                        header("Content-Length: $range[last]");
1195
-                        fseek($options['stream'], -$range['last'], SEEK_END);
1196
-                    }
1197
-                } else {
1198
-                    $this->_multipart_byterange_header(); // init multipart
1199
-                    foreach ($options['ranges'] as $range) {
1200
-
1201
-                        // TODO what if size unknown? 500?
1202
-                        if (isset($range['start'])) {
1203
-                            $from = $range['start'];
1204
-                            $to = !empty($range['end']) ? $range['end'] :
1205
-                                $options['size'] - 1;
1206
-                        } else {
1207
-                            $from = $options['size'] - $range['last'] - 1;
1208
-                            $to = $options['size'] - 1;
1209
-                        }
1210
-                        $total = isset($options['size']) ? $options['size'] :
1211
-                            '*';
1212
-                        $size = $to - $from + 1;
1213
-                        $this->_multipart_byterange_header($options['mimetype'],
1214
-                            $from, $to, $total);
1215
-
1216
-                        fseek($options['stream'], $start, SEEK_SET);
1217
-                    }
1218
-                    $this->_multipart_byterange_header(); // end multipart
1219
-                }
1220
-            } else {
1221
-                // normal request or stream isn't seekable, return full content
1222
-                if (isset($options['size'])) {
1223
-                    header("Content-Length: $options[size]");
1224
-                }
1225
-            }
1226
-        } else if (isset($options['data']))  {
1227
-            if (is_array($options['data'])) {
1228
-                // reply to partial request
1229
-            } else {
1230
-                header("Content-Length: " . strlen($options['data']));
1231
-            }
1232
-        }
1233
-    }
1234
-
1235
-    // }}}
1236
-
1237
-    // {{{ head_wrapper
1238
-
1239
-    /**
1240
-     * HEAD method wrapper
1241
-     *
1242
-     * @param void
1243
-     * @return void
1244
-     */
1245
-    function head_wrapper()
1246
-    {
1247
-        $options = array();
1248
-        $options['path'] = $this->path;
1249
-
1250
-        // call user handler
1251
-        if (method_exists($this, 'head')) {
1252
-            $status = $this->head($options);
1253
-        } else {
1254
-
1255
-            // can emulate HEAD using GET
1256
-            ob_start();
1257
-            $status = $this->get($options);
1258
-            ob_end_clean();
1259
-        }
1260
-
1261
-        // format HEAD response
1262
-        $this->head_response_helper($options, $status);
1263
-    }
1264
-
1265
-    // }}}
1266
-
1267
-    // {{{ put_request_helper
1268
-
1269
-    /**
1270
-     * PUT request helper - prepares data-structures from PUT requests
1271
-     *
1272
-     * @param options
1273
-     * @return void
1274
-     */
1275
-    function put_request_helper(&$options)
1276
-    {
1277
-        $options = array();
1278
-        $options['path'] = $this->path;
1279
-        $options['content_length'] = $_SERVER['CONTENT_LENGTH'];
1280
-
1281
-        // get the content-type
1282
-        if (isset($_SERVER['CONTENT_TYPE'])) {
1283
-
1284
-            // for now we do not support any sort of multipart requests
1285
-            if (!strncmp($_SERVER['CONTENT_TYPE'], 'multipart/', 10)) {
1286
-                $this->http_status('501 Not Implemented');
1287
-                echo 'The service does not support mulipart PUT requests';
1288
-                return;
1289
-            }
1290
-
1291
-            $options['content_type'] = $_SERVER['CONTENT_TYPE'];
1292
-        } else {
1293
-
1294
-            // default content type if none given
1295
-            $options['content_type'] = 'application/unknown';
1296
-        }
1297
-
1298
-        // RFC2616 2.6 says: The recipient of the entity MUST NOT
1299
-        // ignore any Content-* (e.g. Content-Range) headers that it
1300
-        // does not understand or implement and MUST return a 501
1301
-        // (Not Implemented) response in such cases.
1302
-        foreach ($_SERVER as $key => $value) {
1303
-            if (strncmp($key, 'HTTP_CONTENT', 11)) continue;
1304
-            switch ($key) {
1305
-            case 'HTTP_CONTENT_ENCODING': // RFC2616 14.11
1306
-
1307
-                // TODO support this if ext/zlib filters are available
1308
-                $this->http_status('501 Not Implemented');
1309
-                echo "The service does not support '$value' content encoding";
1310
-                return;
1311
-
1312
-            case 'HTTP_CONTENT_LANGUAGE': // RFC2616 14.12
1313
-
1314
-                // we assume it is not critical if this one is ignored
1315
-                // in the actual PUT implementation...
1316
-                $options['content_language'] = $value;
1317
-                break;
1318
-
1319
-            case 'HTTP_CONTENT_LOCATION': // RFC2616 14.14
1320
-
1321
-                // The meaning of the Content-Location header in PUT
1322
-                // or POST requests is undefined; servers are free
1323
-                // to ignore it in those cases. */
1324
-                break;
1325
-
1326
-            case 'HTTP_CONTENT_RANGE': // RFC2616 14.16
1327
-
1328
-                // single byte range requests are supported
1329
-                // the header format is also specified in RFC2616 14.16
1330
-                // TODO we have to ensure that implementations support this or send 501 instead
1331
-                if (!preg_match('@bytes\s+(\d+)-(\d+)/((\d+)|\*)@', $value, $matches)) {
1332
-                    $this->http_status('400 Bad Request');
1333
-                    echo 'The service does only support single byte ranges';
1334
-                    return;
1335
-                }
1336
-
1337
-                $range = array('start' => $matches[1], 'end' => $matches[2]);
1338
-                if (is_numeric($matches[3])) {
1339
-                    $range['total_length'] = $matches[3];
1340
-                }
1341
-                $option['ranges'][] = $range;
1342
-
1343
-                // TODO make sure the implementation supports partial PUT
1344
-                // this has to be done in advance to avoid data being overwritten
1345
-                // on implementations that do not support this...
1346
-                break;
1347
-
1348
-            case 'HTTP_CONTENT_MD5': // RFC2616 14.15
1349
-
1350
-                // TODO maybe we can just pretend here?
1351
-                $this->http_status('501 Not Implemented');
1352
-                echo 'The service does not support content MD5 checksum verification';
1353
-                return;
1354
-
1355
-            default:
1356
-
1357
-                // any other unknown Content-* headers
1358
-                $this->http_status('501 Not Implemented');
1359
-                echo "The service does not support '$key'";
1360
-                return;
1361
-            }
1362
-        }
1363
-
1364
-        $options['stream'] = fopen('php://input', 'r');
1365
-
1366
-        return true;
1367
-    }
1368
-
1369
-    // }}}
1370
-
1371
-    // {{{ put_response_helper
1372
-
1373
-    /**
1374
-     * PUT response helper - format PUT response
1375
-     *
1376
-     * @param options
1377
-     * @param status
1378
-     * @return void
1379
-     */
1380
-    function put_response_helper($options, $status)
1381
-    {
1382
-        if (empty($status)) {
1383
-            $status = '403 Forbidden';
1384
-        } else if (is_resource($status) &&
1385
-                get_resource_type($status) == 'stream') {
1386
-            $stream = $status;
1387
-            $status = $options['new'] === false ? '204 No Content' :
1388
-                '201 Created';
1389
-
1390
-            if (!empty($options['ranges'])) {
1391
-
1392
-                // TODO multipart support is missing (see also above)
1393
-                if (0 == fseek($stream, $range[0]['start'], SEEK_SET)) {
1394
-                    $length = $range[0]['end'] - $range[0]['start'] + 1;
1395
-                    if (!fwrite($stream, fread($options['stream'], $length))) {
1396
-                        $status = '403 Forbidden';
1397
-                    }
1398
-                } else {
1399
-                    $status = '403 Forbidden';
1400
-                }
1401
-            } else {
1402
-                while (!feof($options['stream'])) {
1403
-                    $buf = fread($options['stream'], 4096);
1404
-                    if (fwrite($stream, $buf) != 4096) {
1405
-                        break;
1406
-                    }
1407
-                }
1408
-            }
1409
-
1410
-            fclose($stream);
1411
-        }
1412
-
1413
-        $this->http_status($status);
1414
-    }
1415
-
1416
-    // }}}
1417
-
1418
-    // {{{ put_wrapper
1419
-
1420
-    /**
1421
-     * PUT method wrapper
1422
-     *
1423
-     * @param void
1424
-     * @return void
1425
-     */
1426
-    function put_wrapper()
1427
-    {
1428
-        // check resource is not locked
1429
-        if (!$this->check_lock_wrapper($this->path)) {
1430
-            $this->http_status('423 Locked');
1431
-            return;
1432
-        }
1433
-
1434
-        // perpare data-structure from PUT request
1435
-        if (!$this->put_request_helper($options)) {
1436
-            return;
1437
-        }
1438
-
1439
-        // call user handler
1440
-        $status = $this->put($options);
1441
-
1442
-        // format PUT response
1443
-        $this->put_response_helper($options, $status);
1444
-    }
1445
-
1446
-    // }}}
1447
-
1448
-    // {{{ delete_wrapper
1449
-
1450
-    /**
1451
-     * DELETE method wrapper
1452
-     *
1453
-     * @param void
1454
-     * @return void
1455
-     */
1456
-    function delete_wrapper()
1457
-    {
1458
-        // RFC2518 9.2 last paragraph
1459
-        if (isset($_SERVER['HTTP_DEPTH']) &&
1460
-                $_SERVER['HTTP_DEPTH'] != 'infinity') {
1461
-            $this->http_status('400 Bad Request');
1462
-            return;
1463
-        }
1464
-
1465
-        // check resource is not locked
1466
-        if (!$this->check_lock_wrapper($this->path)) {
1467
-            $this->http_status('423 Locked');
1468
-            return;
1469
-        }
1470
-
1471
-        $options = array();
1472
-        $options['path'] = $this->path;
1473
-
1474
-        // call user handler
1475
-        $status = $this->delete($options);
1476
-        if ($status === true) {
1477
-            $status = '204 No Content';
1478
-        }
1479
-
1480
-        $this->http_status($status);
1481
-    }
1482
-
1483
-    // }}}
1484
-
1485
-    // {{{ copymove_request_helper
1486
-
1487
-    /**
1488
-     * COPY/MOVE request helper - prepares data-structures from COPY/MOVE
1489
-     * requests
1490
-     *
1491
-     * @param options
1492
-     * @return void
1493
-     */
1494
-    function copymove_request_helper(&$options)
1495
-    {
1496
-        $options = array();
1497
-        $options['path'] = $this->path;
1498
-
1499
-        $options['depth'] = 'infinity';
1500
-        if (isset($_SERVER['HTTP_DEPTH'])) {
1501
-            $options['depth'] = $_SERVER['HTTP_DEPTH'];
1502
-        }
1503
-
1504
-        // RFC2518 9.6, 8.8.4 and 8.9.3
1505
-        $options['overwrite'] = true;
1506
-        if (isset($_SERVER['HTTP_OVERWRITE'])) {
1507
-            $options['overwrite'] = $_SERVER['HTTP_OVERWRITE'] == 'T';
1508
-        }
1509
-
1510
-        list ($src_host, $src_port) = explode(':', $_SERVER['HTTP_HOST']);
1511
-        if (empty($src_port)) {
1512
-            $src_port = 80;
1513
-        }
1514
-
1515
-        $dst_url = parse_url($_SERVER['HTTP_DESTINATION']);
1516
-        $dst_host = $dst_url['host'];
1517
-
1518
-        $dst_port = $dst_url['port'];
1519
-        if (empty($dst_port)) {
1520
-            $dst_port = 80;
1521
-        }
1522
-
1523
-        $dst_path = $dst_url['path'];
1524
-
1525
-        // base_uri is urldecoded
1526
-        $dst_path = $this->_urldecode($dst_path);
1527
-
1528
-        // does the destination resource belong on this server?
1529
-        if ($dst_host == $src_host && $dst_port == $src_port &&
1530
-                !strncmp($dst_path, $this->base_uri, strlen($this->base_uri))) {
1531
-            $options['dest'] = substr($dst_path, strlen($this->base_uri));
1532
-
1533
-            $options['dest'] = ltrim($options['dest'], '/');
1534
-
1535
-            // check source & destination are not the same - data could be lost
1536
-            // if overwrite is true - RFC2518 8.8.5
1537
-            if ($options['dest'] == $this->path) {
1538
-                $this->http_status('403 Forbidden');
1539
-                return;
1540
-            }
1541
-
1542
-            return true;
1543
-        }
1544
-
1545
-        $options['dest_url'] = $_SERVER['HTTP_DESTINATION'];
1546
-
1547
-        return true;
1548
-    }
1549
-
1550
-    // }}}
1551
-
1552
-    // {{{ copy_wrapper
1553
-
1554
-    /**
1555
-     * COPY method wrapper
1556
-     *
1557
-     * @param void
1558
-     * @return void
1559
-     */
1560
-    function copy_wrapper()
1561
-    {
1562
-        // no need to check source is not locked
1563
-
1564
-        // perpare data-structure from COPY request
1565
-        if (!$this->copymove_request_helper($options)) {
1566
-            return;
1567
-        }
1568
-
1569
-        // check destination is not locked
1570
-        if (isset($options['dest']) &&
1571
-                !$this->check_lock_wrapper($options['dest'])) {
1572
-            $this->http_status('423 Locked');
1573
-            return;
1574
-        }
1575
-
1576
-        // call user handler
1577
-        $status = $this->copy($options);
1578
-        if ($status === true) {
1579
-            $status = $options['new'] === false ? '204 No Content' :
1580
-                '201 Created';
1581
-        }
1582
-
1583
-        $this->http_status($status);
1584
-    }
1585
-
1586
-    // }}}
1587
-
1588
-    // {{{ move_wrapper
1589
-
1590
-    /**
1591
-     * MOVE method wrapper
1592
-     *
1593
-     * @param void
1594
-     * @return void
1595
-     */
1596
-    function move_wrapper()
1597
-    {
1598
-        // check resource is not locked
1599
-        if (!$this->check_lock_wrapper($this->path)) {
1600
-            $this->http_status('423 Locked');
1601
-            return;
1602
-        }
1603
-
1604
-        // perpare data-structure from MOVE request
1605
-        if (!$this->copymove_request_helper($options)) {
1606
-            return;
1607
-        }
1608
-
1609
-        // check destination is not locked
1610
-        if (isset($options['dest']) &&
1611
-                !$this->check_lock_wrapper($options['dest'])) {
1612
-            $this->http_status('423 Locked');
1613
-            return;
1614
-        }
1615
-
1616
-        // call user handler
1617
-        $status = $this->move($options);
1618
-        if ($status === true) {
1619
-            $status = $options['new'] === false ? '204 No Content' :
1620
-                '201 Created';
1621
-        }
1622
-
1623
-        $this->http_status($status);
1624
-    }
1625
-
1626
-    // }}}
1627
-
1628
-    // {{{ lock_request_helper
1629
-
1630
-    /**
1631
-     * LOCK request helper - prepares data-structures from LOCK requests
1632
-     *
1633
-     * @param options
1634
-     * @return void
1635
-     */
1636
-    function lock_request_helper(&$options)
1637
-    {
1638
-        $options = array();
1639
-        $options['path'] = $this->path;
1640
-
1641
-        $options['depth'] = 'infinity';
1642
-        if (isset($_SERVER['HTTP_DEPTH'])) {
1643
-            $options['depth'] = $_SERVER['HTTP_DEPTH'];
1644
-        }
1645
-
1646
-        if (isset($_SERVER['HTTP_TIMEOUT'])) {
1647
-            $options['timeout'] = explode(',', $_SERVER['HTTP_TIMEOUT']);
1648
-        }
1649
-
1650
-        if (empty($_SERVER['CONTENT_LENGTH']) && !empty($_SERVER['HTTP_IF'])) {
1651
-
1652
-            // refresh lock
1653
-            $options['update'] = substr($_SERVER['HTTP_IF'], 2, -2);
1654
-
1655
-            return true;
1656
-        }
1657
-
1658
-        // extract lock request information from request XML payload
1659
-        $lockinfo = new _parse_lockinfo('php://input');
1660
-        if (!$lockinfo->success) {
1661
-            $this->http_status('400 Bad Request');
1662
-            return;
1663
-        }
1664
-
1665
-        // new lock
1666
-        $options['scope'] = $lockinfo->lockscope;
1667
-        $options['type']  = $lockinfo->locktype;
1668
-        $options['owner'] = $lockinfo->owner;
1669
-
1670
-        $options['token'] = $this->_new_locktoken();
1671
-
1672
-        return true;
1673
-    }
1674
-
1675
-    // }}}
1676
-
1677
-    // {{{ lock_response_helper
1678
-
1679
-    /**
1680
-     * LOCK response helper - format LOCK response
1681
-     *
1682
-     * @param options
1683
-     * @param status
1684
-     * @return void
1685
-     */
1686
-    function lock_response_helper($options, $status)
1687
-    {
1688
-        if (isset($options['locks']) && is_array($options['locks'])) {
1689
-            $this->http_status('409 Conflict');
1690
-
1691
-            $responses = array();
1692
-            foreach ($options['locks'] as $lock) {
1693
-                $response = array();
1694
-
1695
-                $response['href'] = $this->getHref($lock['path']);
1696
-                if (isset($lock['href'])) {
1697
-                    $response['href'] = $lock['href'];
1698
-                }
1699
-
1700
-                $response['status'] = '423 Locked';
1701
-
1702
-                $responses[] = $response;
1703
-            }
1704
-
1705
-            $this->_multistatus($responses);
1706
-            return;
1707
-        }
1708
-
1709
-        if (is_bool($status)) {
1710
-            $status = $status ? '200 OK' : '423 Locked';
1711
-        }
1712
-
1713
-        // set headers before we start printing
1714
-        $this->http_status($status);
1715
-
1716
-        if ($status{0} == 2) { // 2xx states are ok
1717
-            header('Content-Type: text/xml; charset="utf-8"');
1718
-            header("Lock-Token: <$options[token]>");
1719
-
1720
-            echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
1721
-            echo "<D:prop xmlns:D=\"DAV:\">\n";
1722
-            echo " <D:lockdiscovery>\n";
1723
-            echo '  ' . $this->_activelocks(array($options)) . "\n";
1724
-            echo " </D:lockdiscovery>\n";
1725
-            echo "</D:prop>\n";
1726
-        }
1727
-    }
1728
-
1729
-    // }}}
1730
-
1731
-    // {{{ lock_wrapper
1732
-
1733
-    /**
1734
-     * LOCK method wrapper
1735
-     *
1736
-     * @param void
1737
-     * @return void
1738
-     */
1739
-    function lock_wrapper()
1740
-    {
1741
-        // perpare data-structure from LOCK request
1742
-        if (!$this->lock_request_helper($options)) {
1743
-            return;
1744
-        }
1745
-
1746
-        // check resource is not locked
1747
-        if (isset($options['update']) &&
1748
-                !$this->check_lock_wrapper($this->path) ||
1749
-                !$this->check_lock_wrapper($this->path,
1750
-                $options['scope'] == 'shared')) {
1751
-            $this->http_status('423 Locked');
1752
-            return;
1753
-        }
1754
-
1755
-        $options['locks'] = $this->getDescendentsLocks($this->path);
1756
-        if (empty($options['locks'])) {
1757
-
1758
-            // call user handler
1759
-            $status = $this->lock($options);
1760
-        }
1761
-
1762
-        // format LOCK response
1763
-        $this->lock_response_helper($options, $status);
1764
-    }
1765
-
1766
-    // }}}
1767
-
1768
-    // {{{ unlock_request_helper
1769
-
1770
-    /**
1771
-     * UNLOCK request helper - prepares data-structures from UNLOCK requests
1772
-     *
1773
-     * @param options
1774
-     * @return void
1775
-     */
1776
-    function unlock_request_helper(&$options)
1777
-    {
1778
-        $options = array();
1779
-        $options['path'] = $this->path;
1780
-
1781
-        // strip surrounding <>
1782
-        $options['token'] = substr(trim($_SERVER['HTTP_LOCK_TOKEN']), 1, -1);
1783
-
1784
-        return true;
1785
-    }
1786
-
1787
-    // }}}
1788
-
1789
-    // {{{ unlock_wrapper
1790
-
1791
-    /**
1792
-     * UNLOCK method wrapper
1793
-     *
1794
-     * @param void
1795
-     * @return void
1796
-     */
1797
-    function unlock_wrapper()
1798
-    {
1799
-        // perpare data-structure from DELETE request
1800
-        if (!$this->unlock_request_helper($options)) {
1801
-            return;
1802
-        }
1803
-
1804
-        // call user handler
1805
-        $status = $this->unlock($options);
1806
-
1807
-        // RFC2518 8.11.1
1808
-        if ($status === true) {
1809
-            $status = '204 No Content';
1810
-        }
1811
-
1812
-        $this->http_status($status);
1813
-    }
1814
-
1815
-    // }}}
1816
-
1817
-    function getHref($path)
1818
-    {
1819
-        return $this->base_uri . '/' . $path;
1820
-    }
1821
-
1822
-    function getProp($reqprop, $file, $options)
1823
-    {
1824
-        // check if property exists in response
1825
-        foreach ($file['props'] as $prop) {
1826
-            if ($reqprop['name'] == $prop['name'] &&
1827
-                    $reqprop['ns'] == $prop['ns']) {
1828
-                return $prop;
1829
-            }
1830
-        }
1831
-
1832
-        if ($reqprop['name'] == 'lockdiscovery' &&
1833
-                $reqprop['ns'] == 'DAV:' &&
1834
-                method_exists($this, 'getLocks')) {
1835
-
1836
-            return $this->mkprop('DAV:', 'lockdiscovery',
1837
-                $this->getLocks($file['path']));
1838
-        }
1839
-
1840
-        // incase the requested property had a value, like calendar-data
1841
-        unset($reqprop['value']);
1842
-        $reqprop['status'] = '404 Not Found';
1843
-        return $reqprop;
1844
-    }
1845
-
1846
-    function getDescendentsLocks($path)
1847
-    {
1848
-        $options = array();
1849
-        $options['path'] = $path;
1850
-        $options['depth'] = 'infinity';
1851
-        $options['props'] = array();
1852
-        $options['props'][] = $this->mkprop('DAV:', 'lockdiscovery', null);
1853
-
1854
-        // call user handler
1855
-        if (!$this->propfind($options, $files)) {
1856
-            return;
1857
-        }
1858
-
1859
-        return $files;
1860
-    }
1861
-
1862
-    // {{{ _allow()
1863
-
1864
-    /**
1865
-     * list implemented methods
1866
-     *
1867
-     * @param void
1868
-     * @return array something
1869
-     */
1870
-    function _allow()
1871
-    {
1872
-        // OPTIONS is always there
1873
-        $allow = array('OPTIONS');
1874
-
1875
-        // all other methods need both a method_wrapper() and a method()
1876
-        // implementation
1877
-        // the base class defines only wrappers
1878
-        foreach(get_class_methods($this) as $method) {
1879
-
1880
-            // strncmp breaks with negative len -
1881
-            // http://bugs.php.net/bug.php?id=36944
1882
-            //if (!strncmp('_wrapper', $method, -8)) {
1883
-            if (!strcmp(substr($method, -8), '_wrapper')) {
1884
-                $method = strtolower(substr($method, 0, -8));
1885
-                if (method_exists($this, $method) &&
1886
-                        ($method != 'lock' && $method != 'unlock' ||
1887
-                        method_exists($this, 'getLocks'))) {
1888
-                    $allow[] = $method;
1889
-                }
1890
-            }
1891
-        }
1892
-
1893
-        // we can emulate a missing HEAD implemetation using GET
1894
-        if (in_array('GET', $allow)) {
1895
-            $allow[] = 'HEAD';
1896
-        }
1897
-
1898
-        return $allow;
1899
-    }
1900
-
1901
-    // }}}
1902
-
1903
-    // {{{ mkprop
1904
-
1905
-    /**
1906
-     * helper for property element creation
1907
-     *
1908
-     * @param  string XML namespace (optional)
1909
-     * @param  string property name
1910
-     * @param  string property value
1911
-     * @return array  property array
1912
-     */
1913
-    function mkprop()
1914
-    {
1915
-        $args = func_get_args();
1916
-
1917
-        $prop = array();
1918
-        $prop['ns'] = 'DAV:';
1919
-        if (count($args) > 2) {
1920
-            $prop['ns'] = array_shift($args);
1921
-        }
1922
-
1923
-        $prop['name'] = array_shift($args);
1924
-        $prop['value'] = array_shift($args);
1925
-        $prop['status'] = array_shift($args);
1926
-
1927
-        return $prop;
1928
-    }
1929
-
1930
-    // }}}
1931
-
1932
-    // {{{ check_auth_wrapper
1933
-
1934
-    /**
1935
-     * check authentication if implemented
1936
-     *
1937
-     * @param  void
1938
-     * @return bool  true if authentication succeded or not necessary
1939
-     */
1940
-    function check_auth_wrapper()
1941
-    {
1942
-        if (method_exists($this, 'checkAuth')) {
1943
-
1944
-            // PEAR style method name
1945
-            return $this->checkAuth(@$_SERVER['AUTH_TYPE'],
1946
-                @$_SERVER['PHP_AUTH_USER'],
1947
-                @$_SERVER['PHP_AUTH_PW']);
1948
-        }
1949
-
1950
-        if (method_exists($this, 'check_auth')) {
1951
-
1952
-            // old (pre 1.0) method name
1953
-            return $this->check_auth(@$_SERVER['AUTH_TYPE'],
1954
-                @$_SERVER['PHP_AUTH_USER'],
1955
-                @$_SERVER['PHP_AUTH_PW']);
1956
-        }
1957
-
1958
-        // no method found -> no authentication required
1959
-        return true;
1960
-    }
1961
-
1962
-    // }}}
1963
-
1964
-    // {{{ UUID stuff
1965
-
1966
-    /**
1967
-     * generate Unique Universal IDentifier for lock token
1968
-     *
1969
-     * @param void
1970
-     * @return string a new UUID
1971
-     */
1972
-    function _new_uuid()
1973
-    {
1974
-        // use uuid extension from PECL if available
1975
-        if (function_exists('uuid_create')) {
1976
-            return uuid_create();
1977
-        }
1978
-
1979
-        // fallback
1980
-        $uuid = md5(microtime() . getmypid()); // this should be random enough for now
1981
-
1982
-        // set variant and version fields for 'true' random uuid
1983
-        $uuid{12} = '4';
1984
-        $n = 8 + (ord($uuid{16}) & 3);
1985
-        $hex = '0123456789abcdef';
1986
-        $uuid{16} = $hex{$n};
1987
-
1988
-        // return formated uuid
1989
-        return substr($uuid,  0, 8) . '-' .
1990
-            substr($uuid,  8, 4) . '-' .
1991
-            substr($uuid, 12, 4) . '-' .
1992
-            substr($uuid, 16, 4) . '-' .
1993
-            substr($uuid, 20);
1994
-    }
1995
-
1996
-    /**
1997
-     * create a new opaque lock token as defined in RFC2518
1998
-     *
1999
-     * @param  void
2000
-     * @return string new RFC2518 opaque lock token
2001
-     */
2002
-    function _new_locktoken()
2003
-    {
2004
-        return 'opaquelocktoken:' . $this->_new_uuid();
2005
-    }
2006
-
2007
-    // }}}
2008
-
2009
-    // {{{ WebDAV If: header parsing
2010
-
2011
-    /**
2012
-     *
2013
-     *
2014
-     * @param string header string to parse
2015
-     * @param int current parsing position
2016
-     * @return array next token (type and value)
2017
-     */
2018
-    function _if_header_lexer($string, &$pos)
2019
-    {
2020
-        // skip whitespace
2021
-        while (ctype_space($string{$pos})) {
2022
-            ++$pos;
2023
-        }
2024
-
2025
-        // already at end of string?
2026
-        if (strlen($string) <= $pos) {
2027
-            return;
2028
-        }
2029
-
2030
-        // get next character
2031
-        $c = $string{$pos++};
2032
-
2033
-        // now it depends on what we found
2034
-        switch ($c) {
2035
-
2036
-            // URIs are enclosed in <...>
2037
-            case '<':
2038
-                $pos2 = strpos($string, '>', $pos);
2039
-                $uri = substr($string, $pos, $pos2 - $pos);
2040
-                $pos = $pos2 + 1;
2041
-                return array('URI', $uri);
2042
-
2043
-            // ETags are enclosed in [...]
2044
-            case '[':
2045
-                $type = 'ETAG_STRONG';
2046
-                if ($string{$pos} == 'W') {
2047
-                    $type = 'ETAG_WEAK';
2048
-                    $pos += 2;
2049
-                }
2050
-
2051
-                $pos2 = strpos($string, ']', $pos);
2052
-                $etag = substr($string, $pos + 1, $pos2 - $pos - 2);
2053
-                $pos = $pos2 + 1;
2054
-                return array($type, $etag);
2055
-
2056
-            // 'N' indicates negation
2057
-            case 'N':
2058
-                $pos += 2;
2059
-                return array('NOT', 'Not');
2060
-
2061
-            // anything else is passed verbatim char by char
2062
-            default:
2063
-                return array('CHAR', $c);
2064
-        }
2065
-    }
2066
-
2067
-    /**
2068
-     * parse If: header
2069
-     *
2070
-     * @param  string  header string
2071
-     * @return array   URIs and their conditions
2072
-     */
2073
-    function _if_header_parser($str)
2074
-    {
2075
-        $pos = 0;
2076
-        $len = strlen($str);
2077
-
2078
-        $uris = array();
2079
-
2080
-        // parser loop
2081
-        while ($pos < $len) {
2082
-
2083
-            // get next token
2084
-            $token = $this->_if_header_lexer($str, $pos);
2085
-
2086
-            // check for URI
2087
-            $uri = '';
2088
-            if ($token[0] == 'URI') {
2089
-                $uri = $token[1]; // remember URI
2090
-                $token = $this->_if_header_lexer($str, $pos); // get next token
2091
-            }
2092
-
2093
-            // sanity check
2094
-            if ($token[0] != 'CHAR' || $token[1] != '(') {
2095
-                return;
2096
-            }
2097
-
2098
-            $list = array();
2099
-            $level = 1;
2100
-            while ($level) {
2101
-                $token = $this->_if_header_lexer($str, $pos);
2102
-
2103
-                $not = '';
2104
-                if ($token[0] == 'NOT') {
2105
-                    $not = '!';
2106
-                    $token = $this->_if_header_lexer($str, $pos);
2107
-                }
2108
-
2109
-                switch ($token[0]) {
2110
-                    case 'CHAR':
2111
-                        switch ($token[1]) {
2112
-                            case '(':
2113
-                                $level++;
2114
-                                break;
2115
-
2116
-                            case ')':
2117
-                                $level--;
2118
-                                break;
2119
-
2120
-                            default:
2121
-                                return;
2122
-                        }
2123
-                        break;
2124
-
2125
-                    case 'URI':
2126
-                        $list[] = $not . "<$token[1]>";
2127
-                        break;
2128
-
2129
-                    case 'ETAG_WEAK':
2130
-                        $list[] = $not . "[W/'$token[1]']>";
2131
-                        break;
2132
-
2133
-                    case 'ETAG_STRONG':
2134
-                        $list[] = $not . "['$token[1]']>";
2135
-                        break;
2136
-
2137
-                    default:
2138
-                        return;
2139
-                }
2140
-            }
2141
-
2142
-            if (is_array($uris[$uri])) {
2143
-                $uris[$uri] = array_merge($uris[$uri], $list);
2144
-                continue;
2145
-            }
2146
-            $uris[$uri] = $list;
2147
-        }
2148
-
2149
-        return $uris;
2150
-    }
2151
-
2152
-    /**
2153
-     * check if conditions from If: headers are met
2154
-     *
2155
-     * the If: header is an extension to HTTP/1.1
2156
-     * defined in RFC2518 9.4
2157
-     *
2158
-     * @param  void
2159
-     * @return void
2160
-     */
2161
-    function _check_if_header_conditions()
2162
-    {
2163
-        if (!isset($_SERVER['HTTP_IF'])) {
2164
-            return true;
2165
-        }
2166
-
2167
-        $this->_if_header_uris =
2168
-            $this->_if_header_parser($_SERVER['HTTP_IF']);
2169
-
2170
-        // any match is ok
2171
-        foreach($this->_if_header_uris as $uri => $conditions) {
2172
-            if (empty($uri)) {
2173
-                $uri = $this->base_uri . '/' . $this->path;
2174
-            }
2175
-
2176
-            // all must match
2177
-            foreach ($conditions as $condition) {
2178
-
2179
-                // lock tokens may be free form (RFC2518 6.3)
2180
-                // but if opaquelocktokens are used (RFC2518 6.4)
2181
-                // we have to check the format (litmus tests this)
2182
-                if (!strncmp($condition, '<opaquelocktoken:', strlen('<opaquelocktoken'))) {
2183
-                    if (!ereg('^<opaquelocktoken:[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}>$', $condition)) {
2184
-                        return;
2185
-                    }
2186
-                }
2187
-
2188
-                if (!$this->_check_uri_condition($uri, $condition)) {
2189
-                    continue (2);
2190
-                }
2191
-            }
2192
-
2193
-            return true;
2194
-        }
2195
-    }
2196
-
2197
-    /**
2198
-     * Check a single URI condition parsed from an if-header
2199
-     *
2200
-     * @abstract
2201
-     * @param string $uri URI to check
2202
-     * @param string $condition Condition to check for this URI
2203
-     * @returns bool Condition check result
2204
-     */
2205
-    function _check_uri_condition($uri, $condition)
2206
-    {
2207
-        // not really implemented here,
2208
-        // implementations must override
2209
-        return true;
2210
-    }
2211
-
2212
-    /**
2213
-     * @param array of locks
2214
-     * @param bool exclusive lock?
2215
-     */
2216
-    function check_lock_helper($lock, $exclusive_only = false)
2217
-    {
2218
-        if (!is_array($lock) || empty($lock)) {
2219
-            return true;
2220
-        }
2221
-
2222
-        // FIXME doesn't check uri restrictions yet
2223
-        if (strstr($_SERVER['HTTP_IF'], $lock['token'])) {
2224
-            return true;
2225
-        }
2226
-
2227
-        if ($exclusive_only && ($lock['scope'] == 'shared')) {
2228
-            return true;
2229
-        }
2230
-    }
2231
-
2232
-    /**
2233
-     * @param string path of resource to check
2234
-     * @param bool exclusive lock?
2235
-     */
2236
-    function check_lock_wrapper($path, $exclusive_only = false)
2237
-    {
2238
-        if (!method_exists($this, 'getLocks')) {
2239
-            return true;
2240
-        }
2241
-
2242
-        $lock = $this->getLocks($path);
2243
-
2244
-        return $this->check_lock_helper($lock, $exclusive_only);
2245
-    }
2246
-
2247
-    // }}}
2248
-
2249
-    function _lockentries($locks)
2250
-    {
2251
-        if (!is_array($locks) || empty($locks)) {
2252
-            return '';
2253
-        }
2254
-
2255
-        foreach ($locks as $key => $lock) {
2256
-            if (!is_array($lock) || empty($lock)) {
2257
-                continue;
2258
-            }
2259
-
2260
-            $locks[$key] = "<D:lockentry>
410
+	// }}}
411
+
412
+	// }}}
413
+
414
+	// {{{ WebDAV HTTP method wrappers
415
+
416
+	// {{{ options
417
+
418
+	/**
419
+	 * OPTIONS method handler
420
+	 *
421
+	 * The OPTIONS method handler creates a valid OPTIONS reply
422
+	 * including Dav: and Allowed: heaers
423
+	 * based on the implemented methods found in the actual instance
424
+	 *
425
+	 * @param void
426
+	 * @return void
427
+	 */
428
+	function options()
429
+	{
430
+		// get allowed methods
431
+		$allow = $this->_allow();
432
+
433
+		// dav header
434
+		$dav = array(1); // assume we are always dav class 1 compliant
435
+		if (in_array('LOCK', $allow) && in_array('UNLOCK', $allow)) {
436
+			$dav[] = 2; // dav class 2 requires that locking is supported
437
+		}
438
+
439
+		// tell clients what we found
440
+		header('Allow: ' . implode(', ', $allow));
441
+		header('DAV: ' . implode(',', $dav));
442
+		header('Content-Length: 0');
443
+
444
+		// Microsoft clients default to the Frontpage protocol
445
+		// unless we tell them to use WebDAV
446
+		header('MS-Author-Via: DAV');
447
+
448
+		$this->http_status('200 OK');
449
+	}
450
+
451
+	// }}}
452
+
453
+	// {{{ propfind_request_helper
454
+
455
+	/**
456
+	 * PROPFIND request helper - prepares data-structures from PROPFIND requests
457
+	 *
458
+	 * @param options
459
+	 * @return void
460
+	 */
461
+	function propfind_request_helper(&$options)
462
+	{
463
+		$options = array();
464
+		$options['path'] = $this->path;
465
+
466
+		// get depth from header (default is 'infinity')
467
+		$options['depth'] = 'infinity';
468
+		if (isset($_SERVER['HTTP_DEPTH'])) {
469
+			$options['depth'] = $_SERVER['HTTP_DEPTH'];
470
+		}
471
+
472
+		// analyze request payload
473
+		$parser = new _parse_propfind('php://input');
474
+		if (!$parser->success) {
475
+			$this->http_status('400 Bad Request');
476
+			return;
477
+		}
478
+
479
+		$options['props'] = $parser->props;
480
+
481
+		return true;
482
+	}
483
+
484
+	// }}}
485
+
486
+	// {{{ propfind_response_helper
487
+
488
+	/**
489
+	 * PROPFIND response helper - format PROPFIND response
490
+	 *
491
+	 * @param options
492
+	 * @param files
493
+	 * @return void
494
+	 */
495
+	function propfind_response_helper($options, $files)
496
+	{
497
+		$responses = array();
498
+
499
+		// now loop over all returned files
500
+		foreach ($files as $file) {
501
+
502
+			// collect namespaces here
503
+			// Microsoft need this special namespace for date and time values
504
+			$ns_hash = array(
505
+				'urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882' => 'ns0');
506
+
507
+			$response = array();
508
+
509
+			$response['href'] = $this->getHref($file['path']);
510
+			if (isset($file['href'])) {
511
+				$response['href'] = $file['href'];
512
+			}
513
+
514
+			$response['propstat'] = array();
515
+
516
+			if (is_array($options['props'])) {
517
+
518
+				// loop over all requested properties
519
+				foreach ($options['props'] as $reqprop) {
520
+					$status = '200 OK';
521
+					$prop = $this->getProp($reqprop, $file, $options);
522
+
523
+					if (isset($prop['status'])) {
524
+						$status = $prop['status'];
525
+					}
526
+
527
+					if (!isset($response['propstat'][$status])) {
528
+						$response['propstat'][$status] = array();
529
+					}
530
+
531
+					$response['propstat'][$status][] = $prop;
532
+
533
+					// namespace handling
534
+					if (empty($prop['ns']) || // empty namespace
535
+							$prop['ns'] == 'DAV:' || // default namespace
536
+							isset($ns_hash[$prop['ns']])) { // already known
537
+						continue;
538
+					}
539
+
540
+					// register namespace
541
+					$ns_hash[$prop['ns']] = 'ns' . count($ns_hash);
542
+				}
543
+			} else if (is_array($file['props'])) {
544
+
545
+				// loop over all returned properties
546
+				foreach ($file['props'] as $prop) {
547
+					$status = '200 OK';
548
+
549
+					if (isset($prop['status'])) {
550
+						$status = $prop['status'];
551
+					}
552
+
553
+					if (!isset($response['propstat'][$status])) {
554
+						$response['propstat'][$status] = array();
555
+					}
556
+
557
+					if ($options['props'] == 'propname') {
558
+
559
+						// only names of all existing properties were requested
560
+						// so remove values
561
+						unset($prop['value']);
562
+					}
563
+
564
+					$response['propstat'][$status][] = $prop;
565
+						unset($prop['value']);
566
+
567
+					// namespace handling
568
+					if (empty($prop['ns']) || // empty namespace
569
+							$prop['ns'] == 'DAV:' || // default namespace
570
+							isset($ns_hash[$prop['ns']])) { // already known
571
+						continue;
572
+					}
573
+
574
+					// register namespace
575
+					$ns_hash[$prop['ns']] = 'ns' . count($ns_hash);
576
+				}
577
+			}
578
+
579
+			$response['ns_hash'] = $ns_hash;
580
+			$responses[] = $response;
581
+		}
582
+
583
+		$this->_multistatus($responses);
584
+	}
585
+
586
+	function _multistatus($responses)
587
+	{
588
+		// now we generate the response header...
589
+		$this->http_status('207 Multi-Status');
590
+		header('Content-Type: text/xml; charset="utf-8"');
591
+
592
+		// ...and payload
593
+		echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
594
+		echo "<D:multistatus xmlns:D=\"DAV:\">\n";
595
+
596
+		foreach ($responses as $response) {
597
+
598
+			// ignore empty or incomplete entries
599
+			if (!is_array($response) || empty($response)) {
600
+				continue;
601
+			}
602
+
603
+			$ns_defs = array();
604
+			foreach ($response['ns_hash'] as $name => $prefix) {
605
+				$ns_defs[] = "xmlns:$prefix=\"$name\"";
606
+			}
607
+			echo ' <D:response ' . implode(' ', $ns_defs) . ">\n";
608
+			echo "  <D:href>$response[href]</D:href>\n";
609
+
610
+			// report all found properties and their values (if any)
611
+			// nothing to do if no properties were returend for a file
612
+			if (isset($response['propstat']) &&
613
+					is_array($response['propstat'])) {
614
+
615
+				foreach ($response['propstat'] as $status => $props) {
616
+					echo "  <D:propstat>\n";
617
+					echo "   <D:prop>\n";
618
+
619
+					foreach ($props as $prop) {
620
+						if (!is_array($prop) || !isset($prop['name'])) {
621
+							continue;
622
+						}
623
+
624
+						// empty properties (cannot use empty for check as '0'
625
+						// is a legal value here)
626
+						if (!isset($prop['value']) || empty($prop['value']) &&
627
+								$prop['value'] !== 0) {
628
+							if ($prop['ns'] == 'DAV:') {
629
+								echo "    <D:$prop[name]/>\n";
630
+								continue;
631
+							}
632
+
633
+							if (!empty($prop['ns'])) {
634
+								echo '    <' .
635
+									$response['ns_hash'][$prop['ns']] .
636
+									":$prop[name]/>\n";
637
+								continue;
638
+							}
639
+
640
+							echo "    <$prop[name] xmlns=\"\"/>";
641
+							continue;
642
+						}
643
+
644
+						// some WebDAV properties need special treatment
645
+						if ($prop['ns'] == 'DAV:') {
646
+
647
+							switch ($prop['name']) {
648
+							case 'creationdate':
649
+								echo "    <D:creationdate ns0:dt=\"dateTime.tz\">\n";
650
+								echo '     ' . gmdate('Y-m-d\TH:i:s\Z', $prop['value']) . "\n";
651
+								echo "    </D:creationdate>\n";
652
+								break;
653
+
654
+							case 'getlastmodified':
655
+								echo "    <D:getlastmodified ns0:dt=\"dateTime.rfc1123\">\n";
656
+								echo '     ' . gmdate('D, d M Y H:i:s', $prop['value']) . " GMT\n";
657
+								echo "    </D:getlastmodified>\n";
658
+								break;
659
+
660
+							case 'resourcetype':
661
+								echo "    <D:resourcetype>\n";
662
+								echo "     <D:$prop[value]/>\n";
663
+								echo "    </D:resourcetype>\n";
664
+								break;
665
+
666
+							case 'supportedlock':
667
+
668
+								if (is_array($prop[value])) {
669
+									$prop[value] = $this->_lockentries($prop[value]);
670
+								}
671
+								echo "    <D:supportedlock>\n";
672
+								echo "     $prop[value]\n";
673
+								echo "    </D:supportedlock>\n";
674
+								break;
675
+
676
+							case 'lockdiscovery':
677
+
678
+								if (is_array($prop[value])) {
679
+									$prop[value] = $this->_activelocks($prop[value]);
680
+								}
681
+								echo "    <D:lockdiscovery>\n";
682
+								echo "     $prop[value]\n";
683
+								echo "    </D:lockdiscovery>\n";
684
+								break;
685
+
686
+							default:
687
+								echo "    <D:$prop[name]>\n";
688
+								echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
689
+								echo "    </D:$prop[name]>\n";
690
+							}
691
+
692
+							continue;
693
+						}
694
+
695
+						if (!empty($prop['ns'])) {
696
+							echo '    <' . $response['ns_hash'][$prop['ns']] . ":$prop[name]>\n";
697
+							echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
698
+							echo '    </' . $response['ns_hash'][$prop['ns']] . ":$prop[name]>\n";
699
+
700
+							continue;
701
+						}
702
+
703
+						echo "    <$prop[name] xmlns=\"\">\n";
704
+						echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
705
+						echo "    </$prop[name]>\n";
706
+					}
707
+
708
+					echo "   </D:prop>\n";
709
+					echo "   <D:status>HTTP/1.1 $status</D:status>\n";
710
+					echo "  </D:propstat>\n";
711
+				}
712
+			}
713
+
714
+			if (isset($response['status'])) {
715
+				echo "  <D:status>HTTP/1.1 $status</D:status>\n";
716
+			}
717
+
718
+			if (isset($response['responsedescription'])) {
719
+				echo "  <D:responsedescription>\n";
720
+				echo '   ' . $this->_prop_encode(htmlspecialchars($response['responsedescription'])) . "\n";
721
+				echo "  </D:responsedescription>\n";
722
+			}
723
+
724
+			echo " </D:response>\n";
725
+		}
726
+
727
+		echo "</D:multistatus>\n";
728
+	}
729
+
730
+	// }}}
731
+
732
+	// {{{ propfind_wrapper
733
+
734
+	/**
735
+	 * PROPFIND method wrapper
736
+	 *
737
+	 * @param void
738
+	 * @return void
739
+	 */
740
+	function propfind_wrapper()
741
+	{
742
+		// prepare data-structure from PROPFIND request
743
+		if (!$this->propfind_request_helper($options)) {
744
+			return;
745
+		}
746
+
747
+		// call user handler
748
+		if (!$this->propfind($options, $files)) {
749
+			return;
750
+		}
751
+
752
+		// format PROPFIND response
753
+		$this->propfind_response_helper($options, $files);
754
+	}
755
+
756
+	// }}}
757
+
758
+	// {{{ proppatch_request_helper
759
+
760
+	/**
761
+	 * PROPPATCH request helper - prepares data-structures from PROPPATCH requests
762
+	 *
763
+	 * @param options
764
+	 * @return void
765
+	 */
766
+	function proppatch_request_helper(&$options)
767
+	{
768
+		$options = array();
769
+		$options['path'] = $this->path;
770
+
771
+		$propinfo = new _parse_proppatch('php://input');
772
+
773
+		if (!$propinfo->success) {
774
+			$this->http_status('400 Bad Request');
775
+			return;
776
+		}
777
+
778
+		$options['props'] = $propinfo->props;
779
+
780
+		return true;
781
+	}
782
+
783
+	// }}}
784
+
785
+	// {{{ proppatch_response_helper
786
+
787
+	/**
788
+	 * PROPPATCH response helper - format PROPPATCH response
789
+	 *
790
+	 * @param options
791
+	 * @param responsedescr
792
+	 * @return void
793
+	 */
794
+	function proppatch_response_helper($options, $responsedescription=null)
795
+	{
796
+		$response = array();
797
+
798
+		$response['href'] = $this->getHref($options['path']);
799
+		if (isset($options['href'])) {
800
+			$response['href'] = $options['href'];
801
+		}
802
+
803
+		$response['propstat'] = array();
804
+
805
+		// collect namespaces here
806
+		$ns_hash = array();
807
+
808
+		if (isset($options['props']) && is_array($options['props'])) {
809
+			foreach ($options['props'] as $prop) {
810
+				$status = '200 OK';
811
+				if (isset($prop['status'])) {
812
+					$status = $prop['status'];
813
+				}
814
+
815
+				if (!isset($response['propstat'][$status])) {
816
+					$response['propstat'][$status] = array();
817
+				}
818
+
819
+				$response['propstat'][$status][] = $prop;
820
+
821
+				// namespace handling
822
+				if (empty($prop['ns']) || // empty namespace
823
+						$prop['ns'] == 'DAV:' || // default namespace
824
+						isset($ns_hash[$prop['ns']])) { // already known
825
+					continue;
826
+				}
827
+
828
+				// register namespace
829
+				$ns_hash[$prop['ns']] = 'ns' . count($ns_hash);
830
+			}
831
+		}
832
+
833
+		$response['ns_hash'] = $ns_hash;
834
+		$response['responsedescription'] = $responsedescription;
835
+
836
+		$this->_multistatus(array($response));
837
+	}
838
+
839
+	// }}}
840
+
841
+	// {{{ proppatch_wrapper
842
+
843
+	/**
844
+	 * PROPPATCH method wrapper
845
+	 *
846
+	 * @param void
847
+	 * @return void
848
+	 */
849
+	function proppatch_wrapper()
850
+	{
851
+		// check resource is not locked
852
+		if (!$this->check_lock_wrapper($this->path)) {
853
+			$this->http_status('423 Locked');
854
+			return;
855
+		}
856
+
857
+		// perpare data-structure from PROPATCH request
858
+		if (!$this->proppatch_request_helper($options)) {
859
+			return;
860
+		}
861
+
862
+		// call user handler
863
+		$responsedescription = $this->proppatch($options);
864
+
865
+		// format PROPPATCH response
866
+		$this->proppatch_response_helper($options, $responsedescription);
867
+	}
868
+
869
+	// }}}
870
+
871
+	// {{{ mkcol_wrapper
872
+
873
+	/**
874
+	 * MKCOL method wrapper
875
+	 *
876
+	 * @param void
877
+	 * @return void
878
+	 */
879
+	function mkcol_wrapper()
880
+	{
881
+		$options = array();
882
+		$options['path'] = $this->path;
883
+
884
+		$status = $this->mkcol($options);
885
+
886
+		$this->http_status($status);
887
+	}
888
+
889
+	// }}}
890
+
891
+	// {{{ get_request_helper
892
+
893
+	/**
894
+	 * GET request helper - prepares data-structures from GET requests
895
+	 *
896
+	 * @param options
897
+	 * @return void
898
+	 */
899
+	function get_request_helper(&$options)
900
+	{
901
+		// TODO check for invalid stream
902
+
903
+		$options = array();
904
+		$options['path'] = $this->path;
905
+
906
+		$this->_get_ranges($options);
907
+
908
+		return true;
909
+	}
910
+
911
+	/**
912
+	 * parse HTTP Range: header
913
+	 *
914
+	 * @param  array options array to store result in
915
+	 * @return void
916
+	 */
917
+	function _get_ranges(&$options)
918
+	{
919
+		// process Range: header if present
920
+		if (isset($_SERVER['HTTP_RANGE'])) {
921
+
922
+			// we only support standard 'bytes' range specifications for now
923
+			if (ereg('bytes[[:space:]]*=[[:space:]]*(.+)', $_SERVER['HTTP_RANGE'], $matches)) {
924
+				$options['ranges'] = array();
925
+
926
+				// ranges are comma separated
927
+				foreach (explode(',', $matches[1]) as $range) {
928
+					// ranges are either from-to pairs or just end positions
929
+					list($start, $end) = explode('-', $range);
930
+					$options['ranges'][] = ($start === '')
931
+						? array('last' => $end)
932
+						: array('start' => $start, 'end' => $end);
933
+				}
934
+			}
935
+		}
936
+	}
937
+
938
+	// }}}
939
+
940
+	// {{{ get_response_helper
941
+
942
+	/**
943
+	 * GET response helper - format GET response
944
+	 *
945
+	 * @param options
946
+	 * @param status
947
+	 * @return void
948
+	 */
949
+	function get_response_helper($options, $status)
950
+	{
951
+		if (empty($status)) {
952
+			$status = '404 Not Found';
953
+		}
954
+
955
+		// set headers before we start printing
956
+		$this->http_status($status);
957
+
958
+		if ($status !== true) {
959
+			return;
960
+		}
961
+
962
+		if (!isset($options['mimetype'])) {
963
+			$options['mimetype'] = 'application/octet-stream';
964
+		}
965
+		header("Content-Type: $options[mimetype]");
966
+
967
+		if (isset($options['mtime'])) {
968
+			header('Last-Modified:' .
969
+				gmdate('D, d M Y H:i:s', $options['mtime']) . 'GMT');
970
+		}
971
+
972
+		if ($options['stream']) {
973
+			// GET handler returned a stream
974
+
975
+			if (!empty($options['ranges']) &&
976
+					(fseek($options['stream'], 0, SEEK_SET) === 0)) {
977
+				// partial request and stream is seekable
978
+
979
+				if (count($options['ranges']) === 1) {
980
+					$range = $options['ranges'][0];
981
+
982
+					if (isset($range['start'])) {
983
+						fseek($options['stream'], $range['start'], SEEK_SET);
984
+						if (feof($options['stream'])) {
985
+							$this->http_status('416 Requested Range Not Satisfiable');
986
+							return;
987
+						}
988
+
989
+						if (isset($range['end'])) {
990
+							$size = $range['end'] - $range['start'] + 1;
991
+							$this->http_status('206 Partial');
992
+							header("Content-Length: $size");
993
+							header("Content-Range: $range[start]-$range[end]/" .
994
+								(isset($options['size']) ? $options['size'] : '*'));
995
+							while ($size && !feof($options['stream'])) {
996
+								$buffer = fread($options['stream'], 4096);
997
+								$size -= strlen($buffer);
998
+								echo $buffer;
999
+							}
1000
+						} else {
1001
+							$this->http_status('206 Partial');
1002
+							if (isset($options['size'])) {
1003
+								header("Content-Length: " .
1004
+									($options['size'] - $range['start']));
1005
+								header("Content-Range: $start-$end/" .
1006
+									(isset($options['size']) ? $options['size'] : '*'));
1007
+							}
1008
+							fpassthru($options['stream']);
1009
+						}
1010
+					} else {
1011
+						header("Content-Length: $range[last]");
1012
+						fseek($options['stream'], -$range['last'], SEEK_END);
1013
+						fpassthru($options['stream']);
1014
+					}
1015
+				} else {
1016
+					$this->_multipart_byterange_header(); // init multipart
1017
+					foreach ($options['ranges'] as $range) {
1018
+
1019
+						// TODO what if size unknown? 500?
1020
+						if (isset($range['start'])) {
1021
+							$from = $range['start'];
1022
+							$to = !empty($range['end']) ? $range['end'] : $options['size'] - 1;
1023
+						} else {
1024
+							$from = $options['size'] - $range['last'] - 1;
1025
+							$to = $options['size'] - 1;
1026
+						}
1027
+						$total = isset($options['size']) ? $options['size'] : '*';
1028
+						$size = $to - $from + 1;
1029
+						$this->_multipart_byterange_header($options['mimetype'],
1030
+							$from, $to, $total);
1031
+
1032
+						fseek($options['stream'], $start, SEEK_SET);
1033
+						while ($size && !feof($options['stream'])) {
1034
+							$buffer = fread($options['stream'], 4096);
1035
+							$size -= strlen($buffer);
1036
+							echo $buffer;
1037
+						}
1038
+					}
1039
+					$this->_multipart_byterange_header(); // end multipart
1040
+				}
1041
+			} else {
1042
+				// normal request or stream isn't seekable, return full content
1043
+				if (isset($options['size'])) {
1044
+					header("Content-Length: $options[size]");
1045
+				}
1046
+
1047
+				fpassthru($options['stream']);
1048
+			}
1049
+		} else if (isset($options['data']))  {
1050
+			if (is_array($options['data'])) {
1051
+				// reply to partial request
1052
+			} else {
1053
+				header("Content-Length: " . strlen($options['data']));
1054
+				echo $options['data'];
1055
+			}
1056
+		}
1057
+	}
1058
+
1059
+	/**
1060
+	 * generate separator headers for multipart response
1061
+	 *
1062
+	 * first and last call happen without parameters to generate
1063
+	 * the initial header and closing sequence, all calls inbetween
1064
+	 * require content mimetype, start and end byte position and
1065
+	 * optionaly the total byte length of the requested resource
1066
+	 *
1067
+	 * @param  string  mimetype
1068
+	 * @param  int     start byte position
1069
+	 * @param  int     end   byte position
1070
+	 * @param  int     total resource byte size
1071
+	 */
1072
+	function _multipart_byterange_header($mimetype = false, $from = false,
1073
+		$to = false, $total = false)
1074
+	{
1075
+		if ($mimetype === false) {
1076
+			if (!isset($this->multipart_separator)) {
1077
+				// init
1078
+				// a little naive, this sequence *might* be part of the content
1079
+				// but it's really not likely and rather expensive to check
1080
+				$this->multipart_separator = 'SEPARATOR_' . md5(microtime());
1081
+
1082
+				// generate HTTP header
1083
+				header('Content-Type: multipart/byteranges; boundary=' .
1084
+					$this->multipart_separator);
1085
+
1086
+				return;
1087
+			}
1088
+
1089
+			// end
1090
+			// generate closing multipart sequence
1091
+			echo "\n--{$this->multipart_separator}--";
1092
+
1093
+			return;
1094
+		}
1095
+
1096
+		// generate separator and header for next part
1097
+		echo "\n--{$this->multipart_separator}\n";
1098
+		echo "Content-Type: $mimetype\n";
1099
+		echo "Content-Range: $from-$to/"
1100
+			. ($total === false ? "*" : $total) . "\n\n";
1101
+	}
1102
+
1103
+	// }}}
1104
+
1105
+	// {{{ get_wrapper
1106
+
1107
+	/**
1108
+	 * GET method wrapper
1109
+	 *
1110
+	 * @param void
1111
+	 * @return void
1112
+	 */
1113
+	function get_wrapper()
1114
+	{
1115
+		// perpare data-structure from GET request
1116
+		if (!$this->get_request_helper($options)) {
1117
+			return;
1118
+		}
1119
+
1120
+		// call user handler
1121
+		$status = $this->get($options);
1122
+
1123
+		// format GET response
1124
+		$this->get_response_helper($options, $status);
1125
+	}
1126
+
1127
+	// }}}
1128
+
1129
+	// {{{ head_response_helper
1130
+
1131
+	/**
1132
+	 * HEAD response helper - format HEAD response
1133
+	 *
1134
+	 * @param options
1135
+	 * @param status
1136
+	 * @return void
1137
+	 */
1138
+	function head_response_helper($options, $status)
1139
+	{
1140
+		if (empty($status)) {
1141
+			$status('404 Not Found');
1142
+		}
1143
+
1144
+		// set headers before we start printing
1145
+		$this->http_status($status);
1146
+
1147
+		if ($status !== true) {
1148
+			return;
1149
+		}
1150
+
1151
+		if (!isset($options['mimetype'])) {
1152
+			$options['mimetype'] = 'application/octet-stream';
1153
+		}
1154
+		header("Content-Type: $options[mimetype]");
1155
+
1156
+		if (isset($options['mtime'])) {
1157
+			header('Last-Modified:' .
1158
+				gmdate('D, d M Y H:i:s', $options['mtime']) . 'GMT');
1159
+		}
1160
+
1161
+		if (isset($options['stream'])) {
1162
+			// GET handler returned a stream
1163
+
1164
+			if (!empty($options['ranges']) &&
1165
+					(fseek($options['stream'], 0, SEEK_SET) === 0)) {
1166
+				// partial request and stream is seekable
1167
+
1168
+				if (count($options['ranges']) === 1) {
1169
+					$range = $options['ranges'][0];
1170
+
1171
+					if (isset($range['start'])) {
1172
+						fseek($options['stream'], $range['start'], SEEK_SET);
1173
+						if (feof($options['stream'])) {
1174
+							$this->http_status('416 Requested Range Not Satisfiable');
1175
+							return;
1176
+						}
1177
+
1178
+						if (isset($range['end'])) {
1179
+							$size = $range['end'] - $range['start'] + 1;
1180
+							$this->http_status('206 Partial');
1181
+							header("Content-Length: $size");
1182
+							header("Content-Range: $range[start]-$range[end]/" .
1183
+								(isset($options['size']) ? $options['size'] : '*'));
1184
+						} else {
1185
+							$this->http_status('206 Partial');
1186
+							if (isset($options['size'])) {
1187
+								header("Content-Length: " .
1188
+									($options['size'] - $range['start']));
1189
+								header("Content-Range: $start-$end/" .
1190
+									(isset($options['size']) ? $options['size'] : '*'));
1191
+							}
1192
+						}
1193
+					} else {
1194
+						header("Content-Length: $range[last]");
1195
+						fseek($options['stream'], -$range['last'], SEEK_END);
1196
+					}
1197
+				} else {
1198
+					$this->_multipart_byterange_header(); // init multipart
1199
+					foreach ($options['ranges'] as $range) {
1200
+
1201
+						// TODO what if size unknown? 500?
1202
+						if (isset($range['start'])) {
1203
+							$from = $range['start'];
1204
+							$to = !empty($range['end']) ? $range['end'] :
1205
+								$options['size'] - 1;
1206
+						} else {
1207
+							$from = $options['size'] - $range['last'] - 1;
1208
+							$to = $options['size'] - 1;
1209
+						}
1210
+						$total = isset($options['size']) ? $options['size'] :
1211
+							'*';
1212
+						$size = $to - $from + 1;
1213
+						$this->_multipart_byterange_header($options['mimetype'],
1214
+							$from, $to, $total);
1215
+
1216
+						fseek($options['stream'], $start, SEEK_SET);
1217
+					}
1218
+					$this->_multipart_byterange_header(); // end multipart
1219
+				}
1220
+			} else {
1221
+				// normal request or stream isn't seekable, return full content
1222
+				if (isset($options['size'])) {
1223
+					header("Content-Length: $options[size]");
1224
+				}
1225
+			}
1226
+		} else if (isset($options['data']))  {
1227
+			if (is_array($options['data'])) {
1228
+				// reply to partial request
1229
+			} else {
1230
+				header("Content-Length: " . strlen($options['data']));
1231
+			}
1232
+		}
1233
+	}
1234
+
1235
+	// }}}
1236
+
1237
+	// {{{ head_wrapper
1238
+
1239
+	/**
1240
+	 * HEAD method wrapper
1241
+	 *
1242
+	 * @param void
1243
+	 * @return void
1244
+	 */
1245
+	function head_wrapper()
1246
+	{
1247
+		$options = array();
1248
+		$options['path'] = $this->path;
1249
+
1250
+		// call user handler
1251
+		if (method_exists($this, 'head')) {
1252
+			$status = $this->head($options);
1253
+		} else {
1254
+
1255
+			// can emulate HEAD using GET
1256
+			ob_start();
1257
+			$status = $this->get($options);
1258
+			ob_end_clean();
1259
+		}
1260
+
1261
+		// format HEAD response
1262
+		$this->head_response_helper($options, $status);
1263
+	}
1264
+
1265
+	// }}}
1266
+
1267
+	// {{{ put_request_helper
1268
+
1269
+	/**
1270
+	 * PUT request helper - prepares data-structures from PUT requests
1271
+	 *
1272
+	 * @param options
1273
+	 * @return void
1274
+	 */
1275
+	function put_request_helper(&$options)
1276
+	{
1277
+		$options = array();
1278
+		$options['path'] = $this->path;
1279
+		$options['content_length'] = $_SERVER['CONTENT_LENGTH'];
1280
+
1281
+		// get the content-type
1282
+		if (isset($_SERVER['CONTENT_TYPE'])) {
1283
+
1284
+			// for now we do not support any sort of multipart requests
1285
+			if (!strncmp($_SERVER['CONTENT_TYPE'], 'multipart/', 10)) {
1286
+				$this->http_status('501 Not Implemented');
1287
+				echo 'The service does not support mulipart PUT requests';
1288
+				return;
1289
+			}
1290
+
1291
+			$options['content_type'] = $_SERVER['CONTENT_TYPE'];
1292
+		} else {
1293
+
1294
+			// default content type if none given
1295
+			$options['content_type'] = 'application/unknown';
1296
+		}
1297
+
1298
+		// RFC2616 2.6 says: The recipient of the entity MUST NOT
1299
+		// ignore any Content-* (e.g. Content-Range) headers that it
1300
+		// does not understand or implement and MUST return a 501
1301
+		// (Not Implemented) response in such cases.
1302
+		foreach ($_SERVER as $key => $value) {
1303
+			if (strncmp($key, 'HTTP_CONTENT', 11)) continue;
1304
+			switch ($key) {
1305
+			case 'HTTP_CONTENT_ENCODING': // RFC2616 14.11
1306
+
1307
+				// TODO support this if ext/zlib filters are available
1308
+				$this->http_status('501 Not Implemented');
1309
+				echo "The service does not support '$value' content encoding";
1310
+				return;
1311
+
1312
+			case 'HTTP_CONTENT_LANGUAGE': // RFC2616 14.12
1313
+
1314
+				// we assume it is not critical if this one is ignored
1315
+				// in the actual PUT implementation...
1316
+				$options['content_language'] = $value;
1317
+				break;
1318
+
1319
+			case 'HTTP_CONTENT_LOCATION': // RFC2616 14.14
1320
+
1321
+				// The meaning of the Content-Location header in PUT
1322
+				// or POST requests is undefined; servers are free
1323
+				// to ignore it in those cases. */
1324
+				break;
1325
+
1326
+			case 'HTTP_CONTENT_RANGE': // RFC2616 14.16
1327
+
1328
+				// single byte range requests are supported
1329
+				// the header format is also specified in RFC2616 14.16
1330
+				// TODO we have to ensure that implementations support this or send 501 instead
1331
+				if (!preg_match('@bytes\s+(\d+)-(\d+)/((\d+)|\*)@', $value, $matches)) {
1332
+					$this->http_status('400 Bad Request');
1333
+					echo 'The service does only support single byte ranges';
1334
+					return;
1335
+				}
1336
+
1337
+				$range = array('start' => $matches[1], 'end' => $matches[2]);
1338
+				if (is_numeric($matches[3])) {
1339
+					$range['total_length'] = $matches[3];
1340
+				}
1341
+				$option['ranges'][] = $range;
1342
+
1343
+				// TODO make sure the implementation supports partial PUT
1344
+				// this has to be done in advance to avoid data being overwritten
1345
+				// on implementations that do not support this...
1346
+				break;
1347
+
1348
+			case 'HTTP_CONTENT_MD5': // RFC2616 14.15
1349
+
1350
+				// TODO maybe we can just pretend here?
1351
+				$this->http_status('501 Not Implemented');
1352
+				echo 'The service does not support content MD5 checksum verification';
1353
+				return;
1354
+
1355
+			default:
1356
+
1357
+				// any other unknown Content-* headers
1358
+				$this->http_status('501 Not Implemented');
1359
+				echo "The service does not support '$key'";
1360
+				return;
1361
+			}
1362
+		}
1363
+
1364
+		$options['stream'] = fopen('php://input', 'r');
1365
+
1366
+		return true;
1367
+	}
1368
+
1369
+	// }}}
1370
+
1371
+	// {{{ put_response_helper
1372
+
1373
+	/**
1374
+	 * PUT response helper - format PUT response
1375
+	 *
1376
+	 * @param options
1377
+	 * @param status
1378
+	 * @return void
1379
+	 */
1380
+	function put_response_helper($options, $status)
1381
+	{
1382
+		if (empty($status)) {
1383
+			$status = '403 Forbidden';
1384
+		} else if (is_resource($status) &&
1385
+				get_resource_type($status) == 'stream') {
1386
+			$stream = $status;
1387
+			$status = $options['new'] === false ? '204 No Content' :
1388
+				'201 Created';
1389
+
1390
+			if (!empty($options['ranges'])) {
1391
+
1392
+				// TODO multipart support is missing (see also above)
1393
+				if (0 == fseek($stream, $range[0]['start'], SEEK_SET)) {
1394
+					$length = $range[0]['end'] - $range[0]['start'] + 1;
1395
+					if (!fwrite($stream, fread($options['stream'], $length))) {
1396
+						$status = '403 Forbidden';
1397
+					}
1398
+				} else {
1399
+					$status = '403 Forbidden';
1400
+				}
1401
+			} else {
1402
+				while (!feof($options['stream'])) {
1403
+					$buf = fread($options['stream'], 4096);
1404
+					if (fwrite($stream, $buf) != 4096) {
1405
+						break;
1406
+					}
1407
+				}
1408
+			}
1409
+
1410
+			fclose($stream);
1411
+		}
1412
+
1413
+		$this->http_status($status);
1414
+	}
1415
+
1416
+	// }}}
1417
+
1418
+	// {{{ put_wrapper
1419
+
1420
+	/**
1421
+	 * PUT method wrapper
1422
+	 *
1423
+	 * @param void
1424
+	 * @return void
1425
+	 */
1426
+	function put_wrapper()
1427
+	{
1428
+		// check resource is not locked
1429
+		if (!$this->check_lock_wrapper($this->path)) {
1430
+			$this->http_status('423 Locked');
1431
+			return;
1432
+		}
1433
+
1434
+		// perpare data-structure from PUT request
1435
+		if (!$this->put_request_helper($options)) {
1436
+			return;
1437
+		}
1438
+
1439
+		// call user handler
1440
+		$status = $this->put($options);
1441
+
1442
+		// format PUT response
1443
+		$this->put_response_helper($options, $status);
1444
+	}
1445
+
1446
+	// }}}
1447
+
1448
+	// {{{ delete_wrapper
1449
+
1450
+	/**
1451
+	 * DELETE method wrapper
1452
+	 *
1453
+	 * @param void
1454
+	 * @return void
1455
+	 */
1456
+	function delete_wrapper()
1457
+	{
1458
+		// RFC2518 9.2 last paragraph
1459
+		if (isset($_SERVER['HTTP_DEPTH']) &&
1460
+				$_SERVER['HTTP_DEPTH'] != 'infinity') {
1461
+			$this->http_status('400 Bad Request');
1462
+			return;
1463
+		}
1464
+
1465
+		// check resource is not locked
1466
+		if (!$this->check_lock_wrapper($this->path)) {
1467
+			$this->http_status('423 Locked');
1468
+			return;
1469
+		}
1470
+
1471
+		$options = array();
1472
+		$options['path'] = $this->path;
1473
+
1474
+		// call user handler
1475
+		$status = $this->delete($options);
1476
+		if ($status === true) {
1477
+			$status = '204 No Content';
1478
+		}
1479
+
1480
+		$this->http_status($status);
1481
+	}
1482
+
1483
+	// }}}
1484
+
1485
+	// {{{ copymove_request_helper
1486
+
1487
+	/**
1488
+	 * COPY/MOVE request helper - prepares data-structures from COPY/MOVE
1489
+	 * requests
1490
+	 *
1491
+	 * @param options
1492
+	 * @return void
1493
+	 */
1494
+	function copymove_request_helper(&$options)
1495
+	{
1496
+		$options = array();
1497
+		$options['path'] = $this->path;
1498
+
1499
+		$options['depth'] = 'infinity';
1500
+		if (isset($_SERVER['HTTP_DEPTH'])) {
1501
+			$options['depth'] = $_SERVER['HTTP_DEPTH'];
1502
+		}
1503
+
1504
+		// RFC2518 9.6, 8.8.4 and 8.9.3
1505
+		$options['overwrite'] = true;
1506
+		if (isset($_SERVER['HTTP_OVERWRITE'])) {
1507
+			$options['overwrite'] = $_SERVER['HTTP_OVERWRITE'] == 'T';
1508
+		}
1509
+
1510
+		list ($src_host, $src_port) = explode(':', $_SERVER['HTTP_HOST']);
1511
+		if (empty($src_port)) {
1512
+			$src_port = 80;
1513
+		}
1514
+
1515
+		$dst_url = parse_url($_SERVER['HTTP_DESTINATION']);
1516
+		$dst_host = $dst_url['host'];
1517
+
1518
+		$dst_port = $dst_url['port'];
1519
+		if (empty($dst_port)) {
1520
+			$dst_port = 80;
1521
+		}
1522
+
1523
+		$dst_path = $dst_url['path'];
1524
+
1525
+		// base_uri is urldecoded
1526
+		$dst_path = $this->_urldecode($dst_path);
1527
+
1528
+		// does the destination resource belong on this server?
1529
+		if ($dst_host == $src_host && $dst_port == $src_port &&
1530
+				!strncmp($dst_path, $this->base_uri, strlen($this->base_uri))) {
1531
+			$options['dest'] = substr($dst_path, strlen($this->base_uri));
1532
+
1533
+			$options['dest'] = ltrim($options['dest'], '/');
1534
+
1535
+			// check source & destination are not the same - data could be lost
1536
+			// if overwrite is true - RFC2518 8.8.5
1537
+			if ($options['dest'] == $this->path) {
1538
+				$this->http_status('403 Forbidden');
1539
+				return;
1540
+			}
1541
+
1542
+			return true;
1543
+		}
1544
+
1545
+		$options['dest_url'] = $_SERVER['HTTP_DESTINATION'];
1546
+
1547
+		return true;
1548
+	}
1549
+
1550
+	// }}}
1551
+
1552
+	// {{{ copy_wrapper
1553
+
1554
+	/**
1555
+	 * COPY method wrapper
1556
+	 *
1557
+	 * @param void
1558
+	 * @return void
1559
+	 */
1560
+	function copy_wrapper()
1561
+	{
1562
+		// no need to check source is not locked
1563
+
1564
+		// perpare data-structure from COPY request
1565
+		if (!$this->copymove_request_helper($options)) {
1566
+			return;
1567
+		}
1568
+
1569
+		// check destination is not locked
1570
+		if (isset($options['dest']) &&
1571
+				!$this->check_lock_wrapper($options['dest'])) {
1572
+			$this->http_status('423 Locked');
1573
+			return;
1574
+		}
1575
+
1576
+		// call user handler
1577
+		$status = $this->copy($options);
1578
+		if ($status === true) {
1579
+			$status = $options['new'] === false ? '204 No Content' :
1580
+				'201 Created';
1581
+		}
1582
+
1583
+		$this->http_status($status);
1584
+	}
1585
+
1586
+	// }}}
1587
+
1588
+	// {{{ move_wrapper
1589
+
1590
+	/**
1591
+	 * MOVE method wrapper
1592
+	 *
1593
+	 * @param void
1594
+	 * @return void
1595
+	 */
1596
+	function move_wrapper()
1597
+	{
1598
+		// check resource is not locked
1599
+		if (!$this->check_lock_wrapper($this->path)) {
1600
+			$this->http_status('423 Locked');
1601
+			return;
1602
+		}
1603
+
1604
+		// perpare data-structure from MOVE request
1605
+		if (!$this->copymove_request_helper($options)) {
1606
+			return;
1607
+		}
1608
+
1609
+		// check destination is not locked
1610
+		if (isset($options['dest']) &&
1611
+				!$this->check_lock_wrapper($options['dest'])) {
1612
+			$this->http_status('423 Locked');
1613
+			return;
1614
+		}
1615
+
1616
+		// call user handler
1617
+		$status = $this->move($options);
1618
+		if ($status === true) {
1619
+			$status = $options['new'] === false ? '204 No Content' :
1620
+				'201 Created';
1621
+		}
1622
+
1623
+		$this->http_status($status);
1624
+	}
1625
+
1626
+	// }}}
1627
+
1628
+	// {{{ lock_request_helper
1629
+
1630
+	/**
1631
+	 * LOCK request helper - prepares data-structures from LOCK requests
1632
+	 *
1633
+	 * @param options
1634
+	 * @return void
1635
+	 */
1636
+	function lock_request_helper(&$options)
1637
+	{
1638
+		$options = array();
1639
+		$options['path'] = $this->path;
1640
+
1641
+		$options['depth'] = 'infinity';
1642
+		if (isset($_SERVER['HTTP_DEPTH'])) {
1643
+			$options['depth'] = $_SERVER['HTTP_DEPTH'];
1644
+		}
1645
+
1646
+		if (isset($_SERVER['HTTP_TIMEOUT'])) {
1647
+			$options['timeout'] = explode(',', $_SERVER['HTTP_TIMEOUT']);
1648
+		}
1649
+
1650
+		if (empty($_SERVER['CONTENT_LENGTH']) && !empty($_SERVER['HTTP_IF'])) {
1651
+
1652
+			// refresh lock
1653
+			$options['update'] = substr($_SERVER['HTTP_IF'], 2, -2);
1654
+
1655
+			return true;
1656
+		}
1657
+
1658
+		// extract lock request information from request XML payload
1659
+		$lockinfo = new _parse_lockinfo('php://input');
1660
+		if (!$lockinfo->success) {
1661
+			$this->http_status('400 Bad Request');
1662
+			return;
1663
+		}
1664
+
1665
+		// new lock
1666
+		$options['scope'] = $lockinfo->lockscope;
1667
+		$options['type']  = $lockinfo->locktype;
1668
+		$options['owner'] = $lockinfo->owner;
1669
+
1670
+		$options['token'] = $this->_new_locktoken();
1671
+
1672
+		return true;
1673
+	}
1674
+
1675
+	// }}}
1676
+
1677
+	// {{{ lock_response_helper
1678
+
1679
+	/**
1680
+	 * LOCK response helper - format LOCK response
1681
+	 *
1682
+	 * @param options
1683
+	 * @param status
1684
+	 * @return void
1685
+	 */
1686
+	function lock_response_helper($options, $status)
1687
+	{
1688
+		if (isset($options['locks']) && is_array($options['locks'])) {
1689
+			$this->http_status('409 Conflict');
1690
+
1691
+			$responses = array();
1692
+			foreach ($options['locks'] as $lock) {
1693
+				$response = array();
1694
+
1695
+				$response['href'] = $this->getHref($lock['path']);
1696
+				if (isset($lock['href'])) {
1697
+					$response['href'] = $lock['href'];
1698
+				}
1699
+
1700
+				$response['status'] = '423 Locked';
1701
+
1702
+				$responses[] = $response;
1703
+			}
1704
+
1705
+			$this->_multistatus($responses);
1706
+			return;
1707
+		}
1708
+
1709
+		if (is_bool($status)) {
1710
+			$status = $status ? '200 OK' : '423 Locked';
1711
+		}
1712
+
1713
+		// set headers before we start printing
1714
+		$this->http_status($status);
1715
+
1716
+		if ($status{0} == 2) { // 2xx states are ok
1717
+			header('Content-Type: text/xml; charset="utf-8"');
1718
+			header("Lock-Token: <$options[token]>");
1719
+
1720
+			echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
1721
+			echo "<D:prop xmlns:D=\"DAV:\">\n";
1722
+			echo " <D:lockdiscovery>\n";
1723
+			echo '  ' . $this->_activelocks(array($options)) . "\n";
1724
+			echo " </D:lockdiscovery>\n";
1725
+			echo "</D:prop>\n";
1726
+		}
1727
+	}
1728
+
1729
+	// }}}
1730
+
1731
+	// {{{ lock_wrapper
1732
+
1733
+	/**
1734
+	 * LOCK method wrapper
1735
+	 *
1736
+	 * @param void
1737
+	 * @return void
1738
+	 */
1739
+	function lock_wrapper()
1740
+	{
1741
+		// perpare data-structure from LOCK request
1742
+		if (!$this->lock_request_helper($options)) {
1743
+			return;
1744
+		}
1745
+
1746
+		// check resource is not locked
1747
+		if (isset($options['update']) &&
1748
+				!$this->check_lock_wrapper($this->path) ||
1749
+				!$this->check_lock_wrapper($this->path,
1750
+				$options['scope'] == 'shared')) {
1751
+			$this->http_status('423 Locked');
1752
+			return;
1753
+		}
1754
+
1755
+		$options['locks'] = $this->getDescendentsLocks($this->path);
1756
+		if (empty($options['locks'])) {
1757
+
1758
+			// call user handler
1759
+			$status = $this->lock($options);
1760
+		}
1761
+
1762
+		// format LOCK response
1763
+		$this->lock_response_helper($options, $status);
1764
+	}
1765
+
1766
+	// }}}
1767
+
1768
+	// {{{ unlock_request_helper
1769
+
1770
+	/**
1771
+	 * UNLOCK request helper - prepares data-structures from UNLOCK requests
1772
+	 *
1773
+	 * @param options
1774
+	 * @return void
1775
+	 */
1776
+	function unlock_request_helper(&$options)
1777
+	{
1778
+		$options = array();
1779
+		$options['path'] = $this->path;
1780
+
1781
+		// strip surrounding <>
1782
+		$options['token'] = substr(trim($_SERVER['HTTP_LOCK_TOKEN']), 1, -1);
1783
+
1784
+		return true;
1785
+	}
1786
+
1787
+	// }}}
1788
+
1789
+	// {{{ unlock_wrapper
1790
+
1791
+	/**
1792
+	 * UNLOCK method wrapper
1793
+	 *
1794
+	 * @param void
1795
+	 * @return void
1796
+	 */
1797
+	function unlock_wrapper()
1798
+	{
1799
+		// perpare data-structure from DELETE request
1800
+		if (!$this->unlock_request_helper($options)) {
1801
+			return;
1802
+		}
1803
+
1804
+		// call user handler
1805
+		$status = $this->unlock($options);
1806
+
1807
+		// RFC2518 8.11.1
1808
+		if ($status === true) {
1809
+			$status = '204 No Content';
1810
+		}
1811
+
1812
+		$this->http_status($status);
1813
+	}
1814
+
1815
+	// }}}
1816
+
1817
+	function getHref($path)
1818
+	{
1819
+		return $this->base_uri . '/' . $path;
1820
+	}
1821
+
1822
+	function getProp($reqprop, $file, $options)
1823
+	{
1824
+		// check if property exists in response
1825
+		foreach ($file['props'] as $prop) {
1826
+			if ($reqprop['name'] == $prop['name'] &&
1827
+					$reqprop['ns'] == $prop['ns']) {
1828
+				return $prop;
1829
+			}
1830
+		}
1831
+
1832
+		if ($reqprop['name'] == 'lockdiscovery' &&
1833
+				$reqprop['ns'] == 'DAV:' &&
1834
+				method_exists($this, 'getLocks')) {
1835
+
1836
+			return $this->mkprop('DAV:', 'lockdiscovery',
1837
+				$this->getLocks($file['path']));
1838
+		}
1839
+
1840
+		// incase the requested property had a value, like calendar-data
1841
+		unset($reqprop['value']);
1842
+		$reqprop['status'] = '404 Not Found';
1843
+		return $reqprop;
1844
+	}
1845
+
1846
+	function getDescendentsLocks($path)
1847
+	{
1848
+		$options = array();
1849
+		$options['path'] = $path;
1850
+		$options['depth'] = 'infinity';
1851
+		$options['props'] = array();
1852
+		$options['props'][] = $this->mkprop('DAV:', 'lockdiscovery', null);
1853
+
1854
+		// call user handler
1855
+		if (!$this->propfind($options, $files)) {
1856
+			return;
1857
+		}
1858
+
1859
+		return $files;
1860
+	}
1861
+
1862
+	// {{{ _allow()
1863
+
1864
+	/**
1865
+	 * list implemented methods
1866
+	 *
1867
+	 * @param void
1868
+	 * @return array something
1869
+	 */
1870
+	function _allow()
1871
+	{
1872
+		// OPTIONS is always there
1873
+		$allow = array('OPTIONS');
1874
+
1875
+		// all other methods need both a method_wrapper() and a method()
1876
+		// implementation
1877
+		// the base class defines only wrappers
1878
+		foreach(get_class_methods($this) as $method) {
1879
+
1880
+			// strncmp breaks with negative len -
1881
+			// http://bugs.php.net/bug.php?id=36944
1882
+			//if (!strncmp('_wrapper', $method, -8)) {
1883
+			if (!strcmp(substr($method, -8), '_wrapper')) {
1884
+				$method = strtolower(substr($method, 0, -8));
1885
+				if (method_exists($this, $method) &&
1886
+						($method != 'lock' && $method != 'unlock' ||
1887
+						method_exists($this, 'getLocks'))) {
1888
+					$allow[] = $method;
1889
+				}
1890
+			}
1891
+		}
1892
+
1893
+		// we can emulate a missing HEAD implemetation using GET
1894
+		if (in_array('GET', $allow)) {
1895
+			$allow[] = 'HEAD';
1896
+		}
1897
+
1898
+		return $allow;
1899
+	}
1900
+
1901
+	// }}}
1902
+
1903
+	// {{{ mkprop
1904
+
1905
+	/**
1906
+	 * helper for property element creation
1907
+	 *
1908
+	 * @param  string XML namespace (optional)
1909
+	 * @param  string property name
1910
+	 * @param  string property value
1911
+	 * @return array  property array
1912
+	 */
1913
+	function mkprop()
1914
+	{
1915
+		$args = func_get_args();
1916
+
1917
+		$prop = array();
1918
+		$prop['ns'] = 'DAV:';
1919
+		if (count($args) > 2) {
1920
+			$prop['ns'] = array_shift($args);
1921
+		}
1922
+
1923
+		$prop['name'] = array_shift($args);
1924
+		$prop['value'] = array_shift($args);
1925
+		$prop['status'] = array_shift($args);
1926
+
1927
+		return $prop;
1928
+	}
1929
+
1930
+	// }}}
1931
+
1932
+	// {{{ check_auth_wrapper
1933
+
1934
+	/**
1935
+	 * check authentication if implemented
1936
+	 *
1937
+	 * @param  void
1938
+	 * @return bool  true if authentication succeded or not necessary
1939
+	 */
1940
+	function check_auth_wrapper()
1941
+	{
1942
+		if (method_exists($this, 'checkAuth')) {
1943
+
1944
+			// PEAR style method name
1945
+			return $this->checkAuth(@$_SERVER['AUTH_TYPE'],
1946
+				@$_SERVER['PHP_AUTH_USER'],
1947
+				@$_SERVER['PHP_AUTH_PW']);
1948
+		}
1949
+
1950
+		if (method_exists($this, 'check_auth')) {
1951
+
1952
+			// old (pre 1.0) method name
1953
+			return $this->check_auth(@$_SERVER['AUTH_TYPE'],
1954
+				@$_SERVER['PHP_AUTH_USER'],
1955
+				@$_SERVER['PHP_AUTH_PW']);
1956
+		}
1957
+
1958
+		// no method found -> no authentication required
1959
+		return true;
1960
+	}
1961
+
1962
+	// }}}
1963
+
1964
+	// {{{ UUID stuff
1965
+
1966
+	/**
1967
+	 * generate Unique Universal IDentifier for lock token
1968
+	 *
1969
+	 * @param void
1970
+	 * @return string a new UUID
1971
+	 */
1972
+	function _new_uuid()
1973
+	{
1974
+		// use uuid extension from PECL if available
1975
+		if (function_exists('uuid_create')) {
1976
+			return uuid_create();
1977
+		}
1978
+
1979
+		// fallback
1980
+		$uuid = md5(microtime() . getmypid()); // this should be random enough for now
1981
+
1982
+		// set variant and version fields for 'true' random uuid
1983
+		$uuid{12} = '4';
1984
+		$n = 8 + (ord($uuid{16}) & 3);
1985
+		$hex = '0123456789abcdef';
1986
+		$uuid{16} = $hex{$n};
1987
+
1988
+		// return formated uuid
1989
+		return substr($uuid,  0, 8) . '-' .
1990
+			substr($uuid,  8, 4) . '-' .
1991
+			substr($uuid, 12, 4) . '-' .
1992
+			substr($uuid, 16, 4) . '-' .
1993
+			substr($uuid, 20);
1994
+	}
1995
+
1996
+	/**
1997
+	 * create a new opaque lock token as defined in RFC2518
1998
+	 *
1999
+	 * @param  void
2000
+	 * @return string new RFC2518 opaque lock token
2001
+	 */
2002
+	function _new_locktoken()
2003
+	{
2004
+		return 'opaquelocktoken:' . $this->_new_uuid();
2005
+	}
2006
+
2007
+	// }}}
2008
+
2009
+	// {{{ WebDAV If: header parsing
2010
+
2011
+	/**
2012
+	 *
2013
+	 *
2014
+	 * @param string header string to parse
2015
+	 * @param int current parsing position
2016
+	 * @return array next token (type and value)
2017
+	 */
2018
+	function _if_header_lexer($string, &$pos)
2019
+	{
2020
+		// skip whitespace
2021
+		while (ctype_space($string{$pos})) {
2022
+			++$pos;
2023
+		}
2024
+
2025
+		// already at end of string?
2026
+		if (strlen($string) <= $pos) {
2027
+			return;
2028
+		}
2029
+
2030
+		// get next character
2031
+		$c = $string{$pos++};
2032
+
2033
+		// now it depends on what we found
2034
+		switch ($c) {
2035
+
2036
+			// URIs are enclosed in <...>
2037
+			case '<':
2038
+				$pos2 = strpos($string, '>', $pos);
2039
+				$uri = substr($string, $pos, $pos2 - $pos);
2040
+				$pos = $pos2 + 1;
2041
+				return array('URI', $uri);
2042
+
2043
+			// ETags are enclosed in [...]
2044
+			case '[':
2045
+				$type = 'ETAG_STRONG';
2046
+				if ($string{$pos} == 'W') {
2047
+					$type = 'ETAG_WEAK';
2048
+					$pos += 2;
2049
+				}
2050
+
2051
+				$pos2 = strpos($string, ']', $pos);
2052
+				$etag = substr($string, $pos + 1, $pos2 - $pos - 2);
2053
+				$pos = $pos2 + 1;
2054
+				return array($type, $etag);
2055
+
2056
+			// 'N' indicates negation
2057
+			case 'N':
2058
+				$pos += 2;
2059
+				return array('NOT', 'Not');
2060
+
2061
+			// anything else is passed verbatim char by char
2062
+			default:
2063
+				return array('CHAR', $c);
2064
+		}
2065
+	}
2066
+
2067
+	/**
2068
+	 * parse If: header
2069
+	 *
2070
+	 * @param  string  header string
2071
+	 * @return array   URIs and their conditions
2072
+	 */
2073
+	function _if_header_parser($str)
2074
+	{
2075
+		$pos = 0;
2076
+		$len = strlen($str);
2077
+
2078
+		$uris = array();
2079
+
2080
+		// parser loop
2081
+		while ($pos < $len) {
2082
+
2083
+			// get next token
2084
+			$token = $this->_if_header_lexer($str, $pos);
2085
+
2086
+			// check for URI
2087
+			$uri = '';
2088
+			if ($token[0] == 'URI') {
2089
+				$uri = $token[1]; // remember URI
2090
+				$token = $this->_if_header_lexer($str, $pos); // get next token
2091
+			}
2092
+
2093
+			// sanity check
2094
+			if ($token[0] != 'CHAR' || $token[1] != '(') {
2095
+				return;
2096
+			}
2097
+
2098
+			$list = array();
2099
+			$level = 1;
2100
+			while ($level) {
2101
+				$token = $this->_if_header_lexer($str, $pos);
2102
+
2103
+				$not = '';
2104
+				if ($token[0] == 'NOT') {
2105
+					$not = '!';
2106
+					$token = $this->_if_header_lexer($str, $pos);
2107
+				}
2108
+
2109
+				switch ($token[0]) {
2110
+					case 'CHAR':
2111
+						switch ($token[1]) {
2112
+							case '(':
2113
+								$level++;
2114
+								break;
2115
+
2116
+							case ')':
2117
+								$level--;
2118
+								break;
2119
+
2120
+							default:
2121
+								return;
2122
+						}
2123
+						break;
2124
+
2125
+					case 'URI':
2126
+						$list[] = $not . "<$token[1]>";
2127
+						break;
2128
+
2129
+					case 'ETAG_WEAK':
2130
+						$list[] = $not . "[W/'$token[1]']>";
2131
+						break;
2132
+
2133
+					case 'ETAG_STRONG':
2134
+						$list[] = $not . "['$token[1]']>";
2135
+						break;
2136
+
2137
+					default:
2138
+						return;
2139
+				}
2140
+			}
2141
+
2142
+			if (is_array($uris[$uri])) {
2143
+				$uris[$uri] = array_merge($uris[$uri], $list);
2144
+				continue;
2145
+			}
2146
+			$uris[$uri] = $list;
2147
+		}
2148
+
2149
+		return $uris;
2150
+	}
2151
+
2152
+	/**
2153
+	 * check if conditions from If: headers are met
2154
+	 *
2155
+	 * the If: header is an extension to HTTP/1.1
2156
+	 * defined in RFC2518 9.4
2157
+	 *
2158
+	 * @param  void
2159
+	 * @return void
2160
+	 */
2161
+	function _check_if_header_conditions()
2162
+	{
2163
+		if (!isset($_SERVER['HTTP_IF'])) {
2164
+			return true;
2165
+		}
2166
+
2167
+		$this->_if_header_uris =
2168
+			$this->_if_header_parser($_SERVER['HTTP_IF']);
2169
+
2170
+		// any match is ok
2171
+		foreach($this->_if_header_uris as $uri => $conditions) {
2172
+			if (empty($uri)) {
2173
+				$uri = $this->base_uri . '/' . $this->path;
2174
+			}
2175
+
2176
+			// all must match
2177
+			foreach ($conditions as $condition) {
2178
+
2179
+				// lock tokens may be free form (RFC2518 6.3)
2180
+				// but if opaquelocktokens are used (RFC2518 6.4)
2181
+				// we have to check the format (litmus tests this)
2182
+				if (!strncmp($condition, '<opaquelocktoken:', strlen('<opaquelocktoken'))) {
2183
+					if (!ereg('^<opaquelocktoken:[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}>$', $condition)) {
2184
+						return;
2185
+					}
2186
+				}
2187
+
2188
+				if (!$this->_check_uri_condition($uri, $condition)) {
2189
+					continue (2);
2190
+				}
2191
+			}
2192
+
2193
+			return true;
2194
+		}
2195
+	}
2196
+
2197
+	/**
2198
+	 * Check a single URI condition parsed from an if-header
2199
+	 *
2200
+	 * @abstract
2201
+	 * @param string $uri URI to check
2202
+	 * @param string $condition Condition to check for this URI
2203
+	 * @returns bool Condition check result
2204
+	 */
2205
+	function _check_uri_condition($uri, $condition)
2206
+	{
2207
+		// not really implemented here,
2208
+		// implementations must override
2209
+		return true;
2210
+	}
2211
+
2212
+	/**
2213
+	 * @param array of locks
2214
+	 * @param bool exclusive lock?
2215
+	 */
2216
+	function check_lock_helper($lock, $exclusive_only = false)
2217
+	{
2218
+		if (!is_array($lock) || empty($lock)) {
2219
+			return true;
2220
+		}
2221
+
2222
+		// FIXME doesn't check uri restrictions yet
2223
+		if (strstr($_SERVER['HTTP_IF'], $lock['token'])) {
2224
+			return true;
2225
+		}
2226
+
2227
+		if ($exclusive_only && ($lock['scope'] == 'shared')) {
2228
+			return true;
2229
+		}
2230
+	}
2231
+
2232
+	/**
2233
+	 * @param string path of resource to check
2234
+	 * @param bool exclusive lock?
2235
+	 */
2236
+	function check_lock_wrapper($path, $exclusive_only = false)
2237
+	{
2238
+		if (!method_exists($this, 'getLocks')) {
2239
+			return true;
2240
+		}
2241
+
2242
+		$lock = $this->getLocks($path);
2243
+
2244
+		return $this->check_lock_helper($lock, $exclusive_only);
2245
+	}
2246
+
2247
+	// }}}
2248
+
2249
+	function _lockentries($locks)
2250
+	{
2251
+		if (!is_array($locks) || empty($locks)) {
2252
+			return '';
2253
+		}
2254
+
2255
+		foreach ($locks as $key => $lock) {
2256
+			if (!is_array($lock) || empty($lock)) {
2257
+				continue;
2258
+			}
2259
+
2260
+			$locks[$key] = "<D:lockentry>
2261 2261
        <D:lockscope><D:$lock[scope]/></D:lockscope>
2262 2262
        <D:locktype><D:$lock[type]/></D:locktype>
2263 2263
       </D:lockentry>";
2264
-        }
2265
-
2266
-        return implode('', $locks);
2267
-    }
2268
-
2269
-    function _activelocks($locks)
2270
-    {
2271
-        if (!is_array($locks) || empty($locks)) {
2272
-            return '';
2273
-        }
2274
-
2275
-        foreach ($locks as $key => $lock) {
2276
-            if (!is_array($lock) || empty($lock)) {
2277
-                continue;
2278
-            }
2279
-
2280
-            // check for 'timeout' or 'expires'
2281
-            $timeout = 'Infinite';
2282
-            if (!empty($lock['expires'])) {
2283
-                $timeout = 'Second-' . ($lock['expires'] - time());
2284
-            } else if (!empty($lock['timeout'])) {
2285
-
2286
-                // more than a million is considered an absolute timestamp
2287
-                // less is more likely a relative value
2288
-                $timeout = "Second-$lock[timeout]";
2289
-                if ($lock['timeout'] > 1000000) {
2290
-                    $timeout = 'Second-' . ($lock['timeout'] - time());
2291
-                }
2292
-            }
2293
-
2294
-            // genreate response block
2295
-                $locks[$key] = "<D:activelock>
2264
+		}
2265
+
2266
+		return implode('', $locks);
2267
+	}
2268
+
2269
+	function _activelocks($locks)
2270
+	{
2271
+		if (!is_array($locks) || empty($locks)) {
2272
+			return '';
2273
+		}
2274
+
2275
+		foreach ($locks as $key => $lock) {
2276
+			if (!is_array($lock) || empty($lock)) {
2277
+				continue;
2278
+			}
2279
+
2280
+			// check for 'timeout' or 'expires'
2281
+			$timeout = 'Infinite';
2282
+			if (!empty($lock['expires'])) {
2283
+				$timeout = 'Second-' . ($lock['expires'] - time());
2284
+			} else if (!empty($lock['timeout'])) {
2285
+
2286
+				// more than a million is considered an absolute timestamp
2287
+				// less is more likely a relative value
2288
+				$timeout = "Second-$lock[timeout]";
2289
+				if ($lock['timeout'] > 1000000) {
2290
+					$timeout = 'Second-' . ($lock['timeout'] - time());
2291
+				}
2292
+			}
2293
+
2294
+			// genreate response block
2295
+				$locks[$key] = "<D:activelock>
2296 2296
        <D:lockscope><D:$lock[scope]/></D:lockscope>
2297 2297
        <D:locktype><D:$lock[type]/></D:locktype>
2298 2298
        <D:depth>$lock[depth]</D:depth>
@@ -2300,102 +2300,102 @@  discard block
 block discarded – undo
2300 2300
        <D:timeout>$timeout</D:timeout>
2301 2301
        <D:locktoken><D:href>$lock[token]</D:href></D:locktoken>
2302 2302
       </D:activelock>";
2303
-        }
2304
-
2305
-        return implode('', $locks);
2306
-    }
2307
-
2308
-    /**
2309
-     * set HTTP return status and mirror it in a private header
2310
-     *
2311
-     * @param string status code and message
2312
-     * @return void
2313
-     */
2314
-    function http_status($status)
2315
-    {
2316
-        // simplified success case
2317
-        if ($status === true) {
2318
-            $status = '200 OK';
2319
-        }
2320
-
2321
-        // didn't set a more specific status code
2322
-        if (empty($status)) {
2323
-            $status = '500 Internal Server Error';
2324
-        }
2325
-
2326
-        // remember status
2327
-        $this->_http_status = $status;
2328
-
2329
-        // generate HTTP status response
2330
-        header("HTTP/1.1 $status");
2331
-        header("X-WebDAV-Status: $status", true);
2332
-    }
2333
-
2334
-    /**
2335
-     * private minimalistic version of PHP urlencode
2336
-     *
2337
-     * only blanks and XML special chars must be encoded here
2338
-     * full urlencode encoding confuses some clients...
2339
-     *
2340
-     * @param  string  URL to encode
2341
-     * @return string  encoded URL
2342
-     */
2343
-    function _urlencode($url)
2344
-    {
2345
-        return strtr($url, array(
2346
-                ' ' => '%20',
2347
-                '&' => '%26',
2348
-                '<' => '%3C',
2349
-                '>' => '%3E',
2350
-            ));
2351
-    }
2352
-
2353
-    /**
2354
-     * private version of PHP urldecode
2355
-     *
2356
-     * not really needed but added for completenes
2357
-     *
2358
-     * @param  string  URL to decode
2359
-     * @return string  decoded URL
2360
-     */
2361
-    function _urldecode($path)
2362
-    {
2363
-        return urldecode($path);
2364
-    }
2365
-
2366
-    /**
2367
-     * UTF-8 encode property values if not already done so
2368
-     *
2369
-     * @param  string  text to encode
2370
-     * @return string  utf-8 encoded text
2371
-     */
2372
-    function _prop_encode($text)
2373
-    {
2374
-        switch (strtolower($this->_prop_encoding)) {
2375
-        case 'utf-8':
2376
-            return $text;
2377
-        case 'iso-8859-1':
2378
-        case 'iso-8859-15':
2379
-        case 'latin-1':
2380
-        default:
2381
-            return utf8_encode($text);
2382
-        }
2383
-    }
2384
-
2385
-    /**
2386
-     * slashify - make sure path ends in a slash
2387
-     *
2388
-     * @param  string directory path
2389
-     * @return string directory path with trailing slash
2390
-     */
2391
-    function _slashify($path)
2392
-    {
2393
-        if (substr($path, -1) != '/') {
2394
-            $path .= '/';
2395
-        }
2396
-
2397
-        return $path;
2398
-    }
2303
+		}
2304
+
2305
+		return implode('', $locks);
2306
+	}
2307
+
2308
+	/**
2309
+	 * set HTTP return status and mirror it in a private header
2310
+	 *
2311
+	 * @param string status code and message
2312
+	 * @return void
2313
+	 */
2314
+	function http_status($status)
2315
+	{
2316
+		// simplified success case
2317
+		if ($status === true) {
2318
+			$status = '200 OK';
2319
+		}
2320
+
2321
+		// didn't set a more specific status code
2322
+		if (empty($status)) {
2323
+			$status = '500 Internal Server Error';
2324
+		}
2325
+
2326
+		// remember status
2327
+		$this->_http_status = $status;
2328
+
2329
+		// generate HTTP status response
2330
+		header("HTTP/1.1 $status");
2331
+		header("X-WebDAV-Status: $status", true);
2332
+	}
2333
+
2334
+	/**
2335
+	 * private minimalistic version of PHP urlencode
2336
+	 *
2337
+	 * only blanks and XML special chars must be encoded here
2338
+	 * full urlencode encoding confuses some clients...
2339
+	 *
2340
+	 * @param  string  URL to encode
2341
+	 * @return string  encoded URL
2342
+	 */
2343
+	function _urlencode($url)
2344
+	{
2345
+		return strtr($url, array(
2346
+				' ' => '%20',
2347
+				'&' => '%26',
2348
+				'<' => '%3C',
2349
+				'>' => '%3E',
2350
+			));
2351
+	}
2352
+
2353
+	/**
2354
+	 * private version of PHP urldecode
2355
+	 *
2356
+	 * not really needed but added for completenes
2357
+	 *
2358
+	 * @param  string  URL to decode
2359
+	 * @return string  decoded URL
2360
+	 */
2361
+	function _urldecode($path)
2362
+	{
2363
+		return urldecode($path);
2364
+	}
2365
+
2366
+	/**
2367
+	 * UTF-8 encode property values if not already done so
2368
+	 *
2369
+	 * @param  string  text to encode
2370
+	 * @return string  utf-8 encoded text
2371
+	 */
2372
+	function _prop_encode($text)
2373
+	{
2374
+		switch (strtolower($this->_prop_encoding)) {
2375
+		case 'utf-8':
2376
+			return $text;
2377
+		case 'iso-8859-1':
2378
+		case 'iso-8859-15':
2379
+		case 'latin-1':
2380
+		default:
2381
+			return utf8_encode($text);
2382
+		}
2383
+	}
2384
+
2385
+	/**
2386
+	 * slashify - make sure path ends in a slash
2387
+	 *
2388
+	 * @param  string directory path
2389
+	 * @return string directory path with trailing slash
2390
+	 */
2391
+	function _slashify($path)
2392
+	{
2393
+		if (substr($path, -1) != '/') {
2394
+			$path .= '/';
2395
+		}
2396
+
2397
+		return $path;
2398
+	}
2399 2399
 }
2400 2400
 
2401 2401
 // Local variables:
Please login to merge, or discard this patch.
Switch Indentation   +105 added lines, -105 removed lines patch added patch discarded remove patch
@@ -645,48 +645,48 @@  discard block
 block discarded – undo
645 645
                         if ($prop['ns'] == 'DAV:') {
646 646
 
647 647
                             switch ($prop['name']) {
648
-                            case 'creationdate':
649
-                                echo "    <D:creationdate ns0:dt=\"dateTime.tz\">\n";
650
-                                echo '     ' . gmdate('Y-m-d\TH:i:s\Z', $prop['value']) . "\n";
651
-                                echo "    </D:creationdate>\n";
652
-                                break;
653
-
654
-                            case 'getlastmodified':
655
-                                echo "    <D:getlastmodified ns0:dt=\"dateTime.rfc1123\">\n";
656
-                                echo '     ' . gmdate('D, d M Y H:i:s', $prop['value']) . " GMT\n";
657
-                                echo "    </D:getlastmodified>\n";
658
-                                break;
659
-
660
-                            case 'resourcetype':
661
-                                echo "    <D:resourcetype>\n";
662
-                                echo "     <D:$prop[value]/>\n";
663
-                                echo "    </D:resourcetype>\n";
664
-                                break;
665
-
666
-                            case 'supportedlock':
667
-
668
-                                if (is_array($prop[value])) {
669
-                                    $prop[value] = $this->_lockentries($prop[value]);
670
-                                }
671
-                                echo "    <D:supportedlock>\n";
672
-                                echo "     $prop[value]\n";
673
-                                echo "    </D:supportedlock>\n";
674
-                                break;
675
-
676
-                            case 'lockdiscovery':
677
-
678
-                                if (is_array($prop[value])) {
679
-                                    $prop[value] = $this->_activelocks($prop[value]);
680
-                                }
681
-                                echo "    <D:lockdiscovery>\n";
682
-                                echo "     $prop[value]\n";
683
-                                echo "    </D:lockdiscovery>\n";
684
-                                break;
685
-
686
-                            default:
687
-                                echo "    <D:$prop[name]>\n";
688
-                                echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
689
-                                echo "    </D:$prop[name]>\n";
648
+                            	case 'creationdate':
649
+                                	echo "    <D:creationdate ns0:dt=\"dateTime.tz\">\n";
650
+                                	echo '     ' . gmdate('Y-m-d\TH:i:s\Z', $prop['value']) . "\n";
651
+                                	echo "    </D:creationdate>\n";
652
+                                	break;
653
+
654
+                            	case 'getlastmodified':
655
+                                	echo "    <D:getlastmodified ns0:dt=\"dateTime.rfc1123\">\n";
656
+                                	echo '     ' . gmdate('D, d M Y H:i:s', $prop['value']) . " GMT\n";
657
+                                	echo "    </D:getlastmodified>\n";
658
+                                	break;
659
+
660
+                            	case 'resourcetype':
661
+                                	echo "    <D:resourcetype>\n";
662
+                                	echo "     <D:$prop[value]/>\n";
663
+                                	echo "    </D:resourcetype>\n";
664
+                                	break;
665
+
666
+                            	case 'supportedlock':
667
+
668
+                                	if (is_array($prop[value])) {
669
+                                    	$prop[value] = $this->_lockentries($prop[value]);
670
+                                	}
671
+                                	echo "    <D:supportedlock>\n";
672
+                                	echo "     $prop[value]\n";
673
+                                	echo "    </D:supportedlock>\n";
674
+                                	break;
675
+
676
+                            	case 'lockdiscovery':
677
+
678
+                                	if (is_array($prop[value])) {
679
+                                    	$prop[value] = $this->_activelocks($prop[value]);
680
+                                	}
681
+                                	echo "    <D:lockdiscovery>\n";
682
+                                	echo "     $prop[value]\n";
683
+                                	echo "    </D:lockdiscovery>\n";
684
+                                	break;
685
+
686
+                            	default:
687
+                                	echo "    <D:$prop[name]>\n";
688
+                                	echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
689
+                                	echo "    </D:$prop[name]>\n";
690 690
                             }
691 691
 
692 692
                             continue;
@@ -1302,62 +1302,62 @@  discard block
 block discarded – undo
1302 1302
         foreach ($_SERVER as $key => $value) {
1303 1303
             if (strncmp($key, 'HTTP_CONTENT', 11)) continue;
1304 1304
             switch ($key) {
1305
-            case 'HTTP_CONTENT_ENCODING': // RFC2616 14.11
1306
-
1307
-                // TODO support this if ext/zlib filters are available
1308
-                $this->http_status('501 Not Implemented');
1309
-                echo "The service does not support '$value' content encoding";
1310
-                return;
1311
-
1312
-            case 'HTTP_CONTENT_LANGUAGE': // RFC2616 14.12
1313
-
1314
-                // we assume it is not critical if this one is ignored
1315
-                // in the actual PUT implementation...
1316
-                $options['content_language'] = $value;
1317
-                break;
1318
-
1319
-            case 'HTTP_CONTENT_LOCATION': // RFC2616 14.14
1320
-
1321
-                // The meaning of the Content-Location header in PUT
1322
-                // or POST requests is undefined; servers are free
1323
-                // to ignore it in those cases. */
1324
-                break;
1325
-
1326
-            case 'HTTP_CONTENT_RANGE': // RFC2616 14.16
1327
-
1328
-                // single byte range requests are supported
1329
-                // the header format is also specified in RFC2616 14.16
1330
-                // TODO we have to ensure that implementations support this or send 501 instead
1331
-                if (!preg_match('@bytes\s+(\d+)-(\d+)/((\d+)|\*)@', $value, $matches)) {
1332
-                    $this->http_status('400 Bad Request');
1333
-                    echo 'The service does only support single byte ranges';
1334
-                    return;
1335
-                }
1336
-
1337
-                $range = array('start' => $matches[1], 'end' => $matches[2]);
1338
-                if (is_numeric($matches[3])) {
1339
-                    $range['total_length'] = $matches[3];
1340
-                }
1341
-                $option['ranges'][] = $range;
1342
-
1343
-                // TODO make sure the implementation supports partial PUT
1344
-                // this has to be done in advance to avoid data being overwritten
1345
-                // on implementations that do not support this...
1346
-                break;
1347
-
1348
-            case 'HTTP_CONTENT_MD5': // RFC2616 14.15
1349
-
1350
-                // TODO maybe we can just pretend here?
1351
-                $this->http_status('501 Not Implemented');
1352
-                echo 'The service does not support content MD5 checksum verification';
1353
-                return;
1354
-
1355
-            default:
1356
-
1357
-                // any other unknown Content-* headers
1358
-                $this->http_status('501 Not Implemented');
1359
-                echo "The service does not support '$key'";
1360
-                return;
1305
+            	case 'HTTP_CONTENT_ENCODING': // RFC2616 14.11
1306
+
1307
+                	// TODO support this if ext/zlib filters are available
1308
+                	$this->http_status('501 Not Implemented');
1309
+                	echo "The service does not support '$value' content encoding";
1310
+                	return;
1311
+
1312
+            	case 'HTTP_CONTENT_LANGUAGE': // RFC2616 14.12
1313
+
1314
+                	// we assume it is not critical if this one is ignored
1315
+                	// in the actual PUT implementation...
1316
+                	$options['content_language'] = $value;
1317
+                	break;
1318
+
1319
+            	case 'HTTP_CONTENT_LOCATION': // RFC2616 14.14
1320
+
1321
+                	// The meaning of the Content-Location header in PUT
1322
+                	// or POST requests is undefined; servers are free
1323
+                	// to ignore it in those cases. */
1324
+                	break;
1325
+
1326
+            	case 'HTTP_CONTENT_RANGE': // RFC2616 14.16
1327
+
1328
+                	// single byte range requests are supported
1329
+                	// the header format is also specified in RFC2616 14.16
1330
+                	// TODO we have to ensure that implementations support this or send 501 instead
1331
+                	if (!preg_match('@bytes\s+(\d+)-(\d+)/((\d+)|\*)@', $value, $matches)) {
1332
+                    	$this->http_status('400 Bad Request');
1333
+                    	echo 'The service does only support single byte ranges';
1334
+                    	return;
1335
+                	}
1336
+
1337
+                	$range = array('start' => $matches[1], 'end' => $matches[2]);
1338
+                	if (is_numeric($matches[3])) {
1339
+                    	$range['total_length'] = $matches[3];
1340
+                	}
1341
+                	$option['ranges'][] = $range;
1342
+
1343
+                	// TODO make sure the implementation supports partial PUT
1344
+                	// this has to be done in advance to avoid data being overwritten
1345
+                	// on implementations that do not support this...
1346
+                	break;
1347
+
1348
+            	case 'HTTP_CONTENT_MD5': // RFC2616 14.15
1349
+
1350
+                	// TODO maybe we can just pretend here?
1351
+                	$this->http_status('501 Not Implemented');
1352
+                	echo 'The service does not support content MD5 checksum verification';
1353
+                	return;
1354
+
1355
+            	default:
1356
+
1357
+                	// any other unknown Content-* headers
1358
+                	$this->http_status('501 Not Implemented');
1359
+                	echo "The service does not support '$key'";
1360
+                	return;
1361 1361
             }
1362 1362
         }
1363 1363
 
@@ -2372,13 +2372,13 @@  discard block
 block discarded – undo
2372 2372
     function _prop_encode($text)
2373 2373
     {
2374 2374
         switch (strtolower($this->_prop_encoding)) {
2375
-        case 'utf-8':
2376
-            return $text;
2377
-        case 'iso-8859-1':
2378
-        case 'iso-8859-15':
2379
-        case 'latin-1':
2380
-        default:
2381
-            return utf8_encode($text);
2375
+        	case 'utf-8':
2376
+            	return $text;
2377
+        	case 'iso-8859-1':
2378
+        	case 'iso-8859-15':
2379
+        	case 'latin-1':
2380
+        	default:
2381
+            	return utf8_encode($text);
2382 2382
         }
2383 2383
     }
2384 2384
 
Please login to merge, or discard this patch.
Spacing   +61 added lines, -66 removed lines patch added patch discarded remove patch
@@ -100,9 +100,9 @@  discard block
 block discarded – undo
100 100
     {
101 101
         // identify ourselves
102 102
         if (empty($this->dav_powered_by)) {
103
-            $this->dav_powered_by = 'PHP class: ' . get_class($this);
103
+            $this->dav_powered_by = 'PHP class: '.get_class($this);
104 104
         }
105
-        header('X-Dav-Powered-By: ' . $this->dav_powered_by);
105
+        header('X-Dav-Powered-By: '.$this->dav_powered_by);
106 106
 
107 107
         // set path
108 108
         if (empty($this->path)) {
@@ -131,7 +131,7 @@  discard block
 block discarded – undo
131 131
             // but Microsoft Clients do not support Digest
132 132
             // and we don't support NTLM or Kerberos
133 133
             // so we are stuck with Basic here
134
-            header('WWW-Authenticate: Basic realm="' . ($this->http_auth_realm) . '"');
134
+            header('WWW-Authenticate: Basic realm="'.($this->http_auth_realm).'"');
135 135
 
136 136
             // Windows seems to require this being the last header sent
137 137
             // (changed according to PECL bug #3138)
@@ -141,14 +141,14 @@  discard block
 block discarded – undo
141 141
         }
142 142
 
143 143
         // check
144
-        if (! $this->_check_if_header_conditions()) {
144
+        if (!$this->_check_if_header_conditions()) {
145 145
             $this->http_status('412 Precondition Failed');
146 146
             return;
147 147
         }
148 148
 
149 149
         // detect requested method names
150 150
         $method = strtolower($_SERVER['REQUEST_METHOD']);
151
-        $wrapper = $method . '_wrapper';
151
+        $wrapper = $method.'_wrapper';
152 152
 
153 153
         // emulate HEAD using GET if no HEAD method found
154 154
         if ($wrapper == 'head_wrapper' &&
@@ -170,7 +170,7 @@  discard block
 block discarded – undo
170 170
         }
171 171
 
172 172
         // tell client what's allowed
173
-        header('Allow: ' . implode(', ', $this->_allow()));
173
+        header('Allow: '.implode(', ', $this->_allow()));
174 174
         $this->http_status('405 Method Not Allowed');
175 175
     }
176 176
 
@@ -437,8 +437,8 @@  discard block
 block discarded – undo
437 437
         }
438 438
 
439 439
         // tell clients what we found
440
-        header('Allow: ' . implode(', ', $allow));
441
-        header('DAV: ' . implode(',', $dav));
440
+        header('Allow: '.implode(', ', $allow));
441
+        header('DAV: '.implode(',', $dav));
442 442
         header('Content-Length: 0');
443 443
 
444 444
         // Microsoft clients default to the Frontpage protocol
@@ -538,7 +538,7 @@  discard block
 block discarded – undo
538 538
                     }
539 539
 
540 540
                     // register namespace
541
-                    $ns_hash[$prop['ns']] = 'ns' . count($ns_hash);
541
+                    $ns_hash[$prop['ns']] = 'ns'.count($ns_hash);
542 542
                 }
543 543
             } else if (is_array($file['props'])) {
544 544
 
@@ -572,7 +572,7 @@  discard block
 block discarded – undo
572 572
                     }
573 573
 
574 574
                     // register namespace
575
-                    $ns_hash[$prop['ns']] = 'ns' . count($ns_hash);
575
+                    $ns_hash[$prop['ns']] = 'ns'.count($ns_hash);
576 576
                 }
577 577
             }
578 578
 
@@ -604,7 +604,7 @@  discard block
 block discarded – undo
604 604
             foreach ($response['ns_hash'] as $name => $prefix) {
605 605
                 $ns_defs[] = "xmlns:$prefix=\"$name\"";
606 606
             }
607
-            echo ' <D:response ' . implode(' ', $ns_defs) . ">\n";
607
+            echo ' <D:response '.implode(' ', $ns_defs).">\n";
608 608
             echo "  <D:href>$response[href]</D:href>\n";
609 609
 
610 610
             // report all found properties and their values (if any)
@@ -631,8 +631,8 @@  discard block
 block discarded – undo
631 631
                             }
632 632
 
633 633
                             if (!empty($prop['ns'])) {
634
-                                echo '    <' .
635
-                                    $response['ns_hash'][$prop['ns']] .
634
+                                echo '    <'.
635
+                                    $response['ns_hash'][$prop['ns']].
636 636
                                     ":$prop[name]/>\n";
637 637
                                 continue;
638 638
                             }
@@ -647,13 +647,13 @@  discard block
 block discarded – undo
647 647
                             switch ($prop['name']) {
648 648
                             case 'creationdate':
649 649
                                 echo "    <D:creationdate ns0:dt=\"dateTime.tz\">\n";
650
-                                echo '     ' . gmdate('Y-m-d\TH:i:s\Z', $prop['value']) . "\n";
650
+                                echo '     '.gmdate('Y-m-d\TH:i:s\Z', $prop['value'])."\n";
651 651
                                 echo "    </D:creationdate>\n";
652 652
                                 break;
653 653
 
654 654
                             case 'getlastmodified':
655 655
                                 echo "    <D:getlastmodified ns0:dt=\"dateTime.rfc1123\">\n";
656
-                                echo '     ' . gmdate('D, d M Y H:i:s', $prop['value']) . " GMT\n";
656
+                                echo '     '.gmdate('D, d M Y H:i:s', $prop['value'])." GMT\n";
657 657
                                 echo "    </D:getlastmodified>\n";
658 658
                                 break;
659 659
 
@@ -685,7 +685,7 @@  discard block
 block discarded – undo
685 685
 
686 686
                             default:
687 687
                                 echo "    <D:$prop[name]>\n";
688
-                                echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
688
+                                echo '     '.$this->_prop_encode(htmlspecialchars($prop['value']))."\n";
689 689
                                 echo "    </D:$prop[name]>\n";
690 690
                             }
691 691
 
@@ -693,15 +693,15 @@  discard block
 block discarded – undo
693 693
                         }
694 694
 
695 695
                         if (!empty($prop['ns'])) {
696
-                            echo '    <' . $response['ns_hash'][$prop['ns']] . ":$prop[name]>\n";
697
-                            echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
698
-                            echo '    </' . $response['ns_hash'][$prop['ns']] . ":$prop[name]>\n";
696
+                            echo '    <'.$response['ns_hash'][$prop['ns']].":$prop[name]>\n";
697
+                            echo '     '.$this->_prop_encode(htmlspecialchars($prop['value']))."\n";
698
+                            echo '    </'.$response['ns_hash'][$prop['ns']].":$prop[name]>\n";
699 699
 
700 700
                             continue;
701 701
                         }
702 702
 
703 703
                         echo "    <$prop[name] xmlns=\"\">\n";
704
-                        echo '     ' . $this->_prop_encode(htmlspecialchars($prop['value'])) . "\n";
704
+                        echo '     '.$this->_prop_encode(htmlspecialchars($prop['value']))."\n";
705 705
                         echo "    </$prop[name]>\n";
706 706
                     }
707 707
 
@@ -717,7 +717,7 @@  discard block
 block discarded – undo
717 717
 
718 718
             if (isset($response['responsedescription'])) {
719 719
                 echo "  <D:responsedescription>\n";
720
-                echo '   ' . $this->_prop_encode(htmlspecialchars($response['responsedescription'])) . "\n";
720
+                echo '   '.$this->_prop_encode(htmlspecialchars($response['responsedescription']))."\n";
721 721
                 echo "  </D:responsedescription>\n";
722 722
             }
723 723
 
@@ -791,7 +791,7 @@  discard block
 block discarded – undo
791 791
      * @param responsedescr
792 792
      * @return void
793 793
      */
794
-    function proppatch_response_helper($options, $responsedescription=null)
794
+    function proppatch_response_helper($options, $responsedescription = null)
795 795
     {
796 796
         $response = array();
797 797
 
@@ -826,7 +826,7 @@  discard block
 block discarded – undo
826 826
                 }
827 827
 
828 828
                 // register namespace
829
-                $ns_hash[$prop['ns']] = 'ns' . count($ns_hash);
829
+                $ns_hash[$prop['ns']] = 'ns'.count($ns_hash);
830 830
             }
831 831
         }
832 832
 
@@ -965,8 +965,8 @@  discard block
 block discarded – undo
965 965
         header("Content-Type: $options[mimetype]");
966 966
 
967 967
         if (isset($options['mtime'])) {
968
-            header('Last-Modified:' .
969
-                gmdate('D, d M Y H:i:s', $options['mtime']) . 'GMT');
968
+            header('Last-Modified:'.
969
+                gmdate('D, d M Y H:i:s', $options['mtime']).'GMT');
970 970
         }
971 971
 
972 972
         if ($options['stream']) {
@@ -990,7 +990,7 @@  discard block
 block discarded – undo
990 990
                             $size = $range['end'] - $range['start'] + 1;
991 991
                             $this->http_status('206 Partial');
992 992
                             header("Content-Length: $size");
993
-                            header("Content-Range: $range[start]-$range[end]/" .
993
+                            header("Content-Range: $range[start]-$range[end]/".
994 994
                                 (isset($options['size']) ? $options['size'] : '*'));
995 995
                             while ($size && !feof($options['stream'])) {
996 996
                                 $buffer = fread($options['stream'], 4096);
@@ -1000,9 +1000,9 @@  discard block
 block discarded – undo
1000 1000
                         } else {
1001 1001
                             $this->http_status('206 Partial');
1002 1002
                             if (isset($options['size'])) {
1003
-                                header("Content-Length: " .
1003
+                                header("Content-Length: ".
1004 1004
                                     ($options['size'] - $range['start']));
1005
-                                header("Content-Range: $start-$end/" .
1005
+                                header("Content-Range: $start-$end/".
1006 1006
                                     (isset($options['size']) ? $options['size'] : '*'));
1007 1007
                             }
1008 1008
                             fpassthru($options['stream']);
@@ -1046,11 +1046,11 @@  discard block
 block discarded – undo
1046 1046
 
1047 1047
                 fpassthru($options['stream']);
1048 1048
             }
1049
-        } else if (isset($options['data']))  {
1049
+        } else if (isset($options['data'])) {
1050 1050
             if (is_array($options['data'])) {
1051 1051
                 // reply to partial request
1052 1052
             } else {
1053
-                header("Content-Length: " . strlen($options['data']));
1053
+                header("Content-Length: ".strlen($options['data']));
1054 1054
                 echo $options['data'];
1055 1055
             }
1056 1056
         }
@@ -1077,10 +1077,10 @@  discard block
 block discarded – undo
1077 1077
                 // init
1078 1078
                 // a little naive, this sequence *might* be part of the content
1079 1079
                 // but it's really not likely and rather expensive to check
1080
-                $this->multipart_separator = 'SEPARATOR_' . md5(microtime());
1080
+                $this->multipart_separator = 'SEPARATOR_'.md5(microtime());
1081 1081
 
1082 1082
                 // generate HTTP header
1083
-                header('Content-Type: multipart/byteranges; boundary=' .
1083
+                header('Content-Type: multipart/byteranges; boundary='.
1084 1084
                     $this->multipart_separator);
1085 1085
 
1086 1086
                 return;
@@ -1097,7 +1097,7 @@  discard block
 block discarded – undo
1097 1097
         echo "\n--{$this->multipart_separator}\n";
1098 1098
         echo "Content-Type: $mimetype\n";
1099 1099
         echo "Content-Range: $from-$to/"
1100
-            . ($total === false ? "*" : $total) . "\n\n";
1100
+            . ($total === false ? "*" : $total)."\n\n";
1101 1101
     }
1102 1102
 
1103 1103
     // }}}
@@ -1154,8 +1154,8 @@  discard block
 block discarded – undo
1154 1154
         header("Content-Type: $options[mimetype]");
1155 1155
 
1156 1156
         if (isset($options['mtime'])) {
1157
-            header('Last-Modified:' .
1158
-                gmdate('D, d M Y H:i:s', $options['mtime']) . 'GMT');
1157
+            header('Last-Modified:'.
1158
+                gmdate('D, d M Y H:i:s', $options['mtime']).'GMT');
1159 1159
         }
1160 1160
 
1161 1161
         if (isset($options['stream'])) {
@@ -1179,14 +1179,14 @@  discard block
 block discarded – undo
1179 1179
                             $size = $range['end'] - $range['start'] + 1;
1180 1180
                             $this->http_status('206 Partial');
1181 1181
                             header("Content-Length: $size");
1182
-                            header("Content-Range: $range[start]-$range[end]/" .
1182
+                            header("Content-Range: $range[start]-$range[end]/".
1183 1183
                                 (isset($options['size']) ? $options['size'] : '*'));
1184 1184
                         } else {
1185 1185
                             $this->http_status('206 Partial');
1186 1186
                             if (isset($options['size'])) {
1187
-                                header("Content-Length: " .
1187
+                                header("Content-Length: ".
1188 1188
                                     ($options['size'] - $range['start']));
1189
-                                header("Content-Range: $start-$end/" .
1189
+                                header("Content-Range: $start-$end/".
1190 1190
                                     (isset($options['size']) ? $options['size'] : '*'));
1191 1191
                             }
1192 1192
                         }
@@ -1201,14 +1201,12 @@  discard block
 block discarded – undo
1201 1201
                         // TODO what if size unknown? 500?
1202 1202
                         if (isset($range['start'])) {
1203 1203
                             $from = $range['start'];
1204
-                            $to = !empty($range['end']) ? $range['end'] :
1205
-                                $options['size'] - 1;
1204
+                            $to = !empty($range['end']) ? $range['end'] : $options['size'] - 1;
1206 1205
                         } else {
1207 1206
                             $from = $options['size'] - $range['last'] - 1;
1208 1207
                             $to = $options['size'] - 1;
1209 1208
                         }
1210
-                        $total = isset($options['size']) ? $options['size'] :
1211
-                            '*';
1209
+                        $total = isset($options['size']) ? $options['size'] : '*';
1212 1210
                         $size = $to - $from + 1;
1213 1211
                         $this->_multipart_byterange_header($options['mimetype'],
1214 1212
                             $from, $to, $total);
@@ -1223,11 +1221,11 @@  discard block
 block discarded – undo
1223 1221
                     header("Content-Length: $options[size]");
1224 1222
                 }
1225 1223
             }
1226
-        } else if (isset($options['data']))  {
1224
+        } else if (isset($options['data'])) {
1227 1225
             if (is_array($options['data'])) {
1228 1226
                 // reply to partial request
1229 1227
             } else {
1230
-                header("Content-Length: " . strlen($options['data']));
1228
+                header("Content-Length: ".strlen($options['data']));
1231 1229
             }
1232 1230
         }
1233 1231
     }
@@ -1384,8 +1382,7 @@  discard block
 block discarded – undo
1384 1382
         } else if (is_resource($status) &&
1385 1383
                 get_resource_type($status) == 'stream') {
1386 1384
             $stream = $status;
1387
-            $status = $options['new'] === false ? '204 No Content' :
1388
-                '201 Created';
1385
+            $status = $options['new'] === false ? '204 No Content' : '201 Created';
1389 1386
 
1390 1387
             if (!empty($options['ranges'])) {
1391 1388
 
@@ -1576,8 +1573,7 @@  discard block
 block discarded – undo
1576 1573
         // call user handler
1577 1574
         $status = $this->copy($options);
1578 1575
         if ($status === true) {
1579
-            $status = $options['new'] === false ? '204 No Content' :
1580
-                '201 Created';
1576
+            $status = $options['new'] === false ? '204 No Content' : '201 Created';
1581 1577
         }
1582 1578
 
1583 1579
         $this->http_status($status);
@@ -1616,8 +1612,7 @@  discard block
 block discarded – undo
1616 1612
         // call user handler
1617 1613
         $status = $this->move($options);
1618 1614
         if ($status === true) {
1619
-            $status = $options['new'] === false ? '204 No Content' :
1620
-                '201 Created';
1615
+            $status = $options['new'] === false ? '204 No Content' : '201 Created';
1621 1616
         }
1622 1617
 
1623 1618
         $this->http_status($status);
@@ -1720,7 +1715,7 @@  discard block
 block discarded – undo
1720 1715
             echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
1721 1716
             echo "<D:prop xmlns:D=\"DAV:\">\n";
1722 1717
             echo " <D:lockdiscovery>\n";
1723
-            echo '  ' . $this->_activelocks(array($options)) . "\n";
1718
+            echo '  '.$this->_activelocks(array($options))."\n";
1724 1719
             echo " </D:lockdiscovery>\n";
1725 1720
             echo "</D:prop>\n";
1726 1721
         }
@@ -1816,7 +1811,7 @@  discard block
 block discarded – undo
1816 1811
 
1817 1812
     function getHref($path)
1818 1813
     {
1819
-        return $this->base_uri . '/' . $path;
1814
+        return $this->base_uri.'/'.$path;
1820 1815
     }
1821 1816
 
1822 1817
     function getProp($reqprop, $file, $options)
@@ -1875,7 +1870,7 @@  discard block
 block discarded – undo
1875 1870
         // all other methods need both a method_wrapper() and a method()
1876 1871
         // implementation
1877 1872
         // the base class defines only wrappers
1878
-        foreach(get_class_methods($this) as $method) {
1873
+        foreach (get_class_methods($this) as $method) {
1879 1874
 
1880 1875
             // strncmp breaks with negative len -
1881 1876
             // http://bugs.php.net/bug.php?id=36944
@@ -1977,7 +1972,7 @@  discard block
 block discarded – undo
1977 1972
         }
1978 1973
 
1979 1974
         // fallback
1980
-        $uuid = md5(microtime() . getmypid()); // this should be random enough for now
1975
+        $uuid = md5(microtime().getmypid()); // this should be random enough for now
1981 1976
 
1982 1977
         // set variant and version fields for 'true' random uuid
1983 1978
         $uuid{12} = '4';
@@ -1986,10 +1981,10 @@  discard block
 block discarded – undo
1986 1981
         $uuid{16} = $hex{$n};
1987 1982
 
1988 1983
         // return formated uuid
1989
-        return substr($uuid,  0, 8) . '-' .
1990
-            substr($uuid,  8, 4) . '-' .
1991
-            substr($uuid, 12, 4) . '-' .
1992
-            substr($uuid, 16, 4) . '-' .
1984
+        return substr($uuid, 0, 8).'-'.
1985
+            substr($uuid, 8, 4).'-'.
1986
+            substr($uuid, 12, 4).'-'.
1987
+            substr($uuid, 16, 4).'-'.
1993 1988
             substr($uuid, 20);
1994 1989
     }
1995 1990
 
@@ -2001,7 +1996,7 @@  discard block
 block discarded – undo
2001 1996
      */
2002 1997
     function _new_locktoken()
2003 1998
     {
2004
-        return 'opaquelocktoken:' . $this->_new_uuid();
1999
+        return 'opaquelocktoken:'.$this->_new_uuid();
2005 2000
     }
2006 2001
 
2007 2002
     // }}}
@@ -2123,15 +2118,15 @@  discard block
 block discarded – undo
2123 2118
                         break;
2124 2119
 
2125 2120
                     case 'URI':
2126
-                        $list[] = $not . "<$token[1]>";
2121
+                        $list[] = $not."<$token[1]>";
2127 2122
                         break;
2128 2123
 
2129 2124
                     case 'ETAG_WEAK':
2130
-                        $list[] = $not . "[W/'$token[1]']>";
2125
+                        $list[] = $not."[W/'$token[1]']>";
2131 2126
                         break;
2132 2127
 
2133 2128
                     case 'ETAG_STRONG':
2134
-                        $list[] = $not . "['$token[1]']>";
2129
+                        $list[] = $not."['$token[1]']>";
2135 2130
                         break;
2136 2131
 
2137 2132
                     default:
@@ -2168,9 +2163,9 @@  discard block
 block discarded – undo
2168 2163
             $this->_if_header_parser($_SERVER['HTTP_IF']);
2169 2164
 
2170 2165
         // any match is ok
2171
-        foreach($this->_if_header_uris as $uri => $conditions) {
2166
+        foreach ($this->_if_header_uris as $uri => $conditions) {
2172 2167
             if (empty($uri)) {
2173
-                $uri = $this->base_uri . '/' . $this->path;
2168
+                $uri = $this->base_uri.'/'.$this->path;
2174 2169
             }
2175 2170
 
2176 2171
             // all must match
@@ -2280,14 +2275,14 @@  discard block
 block discarded – undo
2280 2275
             // check for 'timeout' or 'expires'
2281 2276
             $timeout = 'Infinite';
2282 2277
             if (!empty($lock['expires'])) {
2283
-                $timeout = 'Second-' . ($lock['expires'] - time());
2278
+                $timeout = 'Second-'.($lock['expires'] - time());
2284 2279
             } else if (!empty($lock['timeout'])) {
2285 2280
 
2286 2281
                 // more than a million is considered an absolute timestamp
2287 2282
                 // less is more likely a relative value
2288 2283
                 $timeout = "Second-$lock[timeout]";
2289 2284
                 if ($lock['timeout'] > 1000000) {
2290
-                    $timeout = 'Second-' . ($lock['timeout'] - time());
2285
+                    $timeout = 'Second-'.($lock['timeout'] - time());
2291 2286
                 }
2292 2287
             }
2293 2288
 
Please login to merge, or discard this patch.
Braces   +3 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1300,7 +1300,9 @@
 block discarded – undo
1300 1300
         // does not understand or implement and MUST return a 501
1301 1301
         // (Not Implemented) response in such cases.
1302 1302
         foreach ($_SERVER as $key => $value) {
1303
-            if (strncmp($key, 'HTTP_CONTENT', 11)) continue;
1303
+            if (strncmp($key, 'HTTP_CONTENT', 11)) {
1304
+            	continue;
1305
+            }
1304 1306
             switch ($key) {
1305 1307
             case 'HTTP_CONTENT_ENCODING': // RFC2616 14.11
1306 1308
 
Please login to merge, or discard this patch.
phpicalendar/lib/HTTP/WebDAV/Tools/_parse_lockinfo.php 3 patches
Doc Comments   +1 added lines patch added patch discarded remove patch
@@ -73,6 +73,7 @@
 block discarded – undo
73 73
 	 * constructor
74 74
 	 *
75 75
 	 * @param  string  path of stream to read
76
+	 * @param string $path
76 77
 	 * @access public
77 78
 	 */
78 79
     function _parse_lockinfo($path) 
Please login to merge, or discard this patch.
Indentation   +35 added lines, -35 removed lines patch added patch discarded remove patch
@@ -75,7 +75,7 @@  discard block
 block discarded – undo
75 75
 	 * @param  string  path of stream to read
76 76
 	 * @access public
77 77
 	 */
78
-    function _parse_lockinfo($path) 
78
+	function _parse_lockinfo($path) 
79 79
 	{
80 80
 		// we assume success unless problems occur
81 81
 		$this->success = true;
@@ -139,32 +139,32 @@  discard block
 block discarded – undo
139 139
 	 * @return void
140 140
 	 * @access private
141 141
 	 */
142
-    function _startElement($parser, $name, $attrs) 
143
-    {
142
+	function _startElement($parser, $name, $attrs) 
143
+	{
144 144
 		// namespace handling
145
-        if (strstr($name, " ")) {
146
-            list($ns, $tag) = explode(" ", $name);
147
-        } else {
148
-            $ns = "";
149
-            $tag = $name;
150
-        }
145
+		if (strstr($name, " ")) {
146
+			list($ns, $tag) = explode(" ", $name);
147
+		} else {
148
+			$ns = "";
149
+			$tag = $name;
150
+		}
151 151
 		
152 152
   
153
-        if ($this->collect_owner) {
153
+		if ($this->collect_owner) {
154 154
 			// everything within the <owner> tag needs to be collected
155
-            $ns_short = "";
156
-            $ns_attr = "";
157
-            if ($ns) {
158
-                if ($ns == "DAV:") {
159
-                    $ns_short = "D:";
160
-                } else {
161
-                    $ns_attr = " xmlns='$ns'";
162
-                }
163
-            }
164
-            $this->owner .= "<$ns_short$tag$ns_attr>";
165
-        } else if ($ns == "DAV:") {
155
+			$ns_short = "";
156
+			$ns_attr = "";
157
+			if ($ns) {
158
+				if ($ns == "DAV:") {
159
+					$ns_short = "D:";
160
+				} else {
161
+					$ns_attr = " xmlns='$ns'";
162
+				}
163
+			}
164
+			$this->owner .= "<$ns_short$tag$ns_attr>";
165
+		} else if ($ns == "DAV:") {
166 166
 			// parse only the essential tags
167
-            switch ($tag) {
167
+			switch ($tag) {
168 168
 			case "write":
169 169
 				$this->locktype = $tag;
170 170
 				break;
@@ -175,9 +175,9 @@  discard block
 block discarded – undo
175 175
 			case "owner":
176 176
 				$this->collect_owner = true;
177 177
 				break;
178
-            }
179
-        }
180
-    }
178
+			}
179
+		}
180
+	}
181 181
 	
182 182
 	/**
183 183
 	 * data handler
@@ -187,13 +187,13 @@  discard block
 block discarded – undo
187 187
 	 * @return void
188 188
 	 * @access private
189 189
 	 */
190
-    function _data($parser, $data) 
191
-    {
190
+	function _data($parser, $data) 
191
+	{
192 192
 		// only the <owner> tag has data content
193
-        if ($this->collect_owner) {
194
-            $this->owner .= $data;
195
-        }
196
-    }
193
+		if ($this->collect_owner) {
194
+			$this->owner .= $data;
195
+		}
196
+	}
197 197
 
198 198
 	/**
199 199
 	 * tag end handler
@@ -203,8 +203,8 @@  discard block
 block discarded – undo
203 203
 	 * @return void
204 204
 	 * @access private
205 205
 	 */
206
-    function _endElement($parser, $name) 
207
-    {
206
+	function _endElement($parser, $name) 
207
+	{
208 208
 		// namespace handling
209 209
 		if (strstr($name, " ")) {
210 210
 			list($ns, $tag) = explode(" ", $name);
@@ -224,14 +224,14 @@  discard block
 block discarded – undo
224 224
 			$ns_attr = "";
225 225
 			if ($ns) {
226 226
 				if ($ns == "DAV:") {
227
-                    $ns_short = "D:";
227
+					$ns_short = "D:";
228 228
 				} else {
229 229
 					$ns_attr = " xmlns='$ns'";
230 230
 				}
231 231
 			}
232 232
 			$this->owner .= "</$ns_short$tag$ns_attr>";
233 233
 		}
234
-    }
234
+	}
235 235
 }
236 236
 
237 237
 ?>
238 238
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -105,7 +105,7 @@  discard block
 block discarded – undo
105 105
 							  XML_OPTION_CASE_FOLDING, false);
106 106
 
107 107
 		// parse input
108
-		while($this->success && !feof($f_in)) {
108
+		while ($this->success && !feof($f_in)) {
109 109
 			$line = fgets($f_in);
110 110
 			if (is_string($line)) {
111 111
 				$had_input = true;
@@ -114,7 +114,7 @@  discard block
 block discarded – undo
114 114
 		} 
115 115
 
116 116
 		// finish parsing
117
-		if($had_input) {
117
+		if ($had_input) {
118 118
 			$this->success &= xml_parse($xml_parser, "", true);
119 119
 		}
120 120
 
Please login to merge, or discard this patch.
phpicalendar/lib/HTTP/WebDAV/Tools/_parse_propfind.php 2 patches
Doc Comments   +1 added lines patch added patch discarded remove patch
@@ -55,6 +55,7 @@
 block discarded – undo
55 55
      * constructor
56 56
      *
57 57
      * @access public
58
+     * @param string $input
58 59
      */
59 60
     function _parse_propfind($input)
60 61
     {
Please login to merge, or discard this patch.
Indentation   +136 added lines, -136 removed lines patch added patch discarded remove patch
@@ -27,141 +27,141 @@
 block discarded – undo
27 27
  */
28 28
 class _parse_propfind
29 29
 {
30
-    /**
31
-     * success state flag
32
-     *
33
-     * @var bool
34
-     * @access public
35
-     */
36
-    var $success = false;
37
-
38
-    /**
39
-     * found properties are collected here
40
-     *
41
-     * @var array
42
-     * @access public
43
-     */
44
-    var $props = false;
45
-
46
-    /**
47
-     * internal tag nesting depth counter
48
-     *
49
-     * @var int
50
-     * @access private
51
-     */
52
-    var $depth = 0;
53
-
54
-    /**
55
-     * constructor
56
-     *
57
-     * @access public
58
-     */
59
-    function _parse_propfind($input)
60
-    {
61
-        // success state flag
62
-        $this->success = true;
63
-
64
-        // property storage array
65
-        $this->props = array();
66
-
67
-        // internal tag depth counter
68
-        $this->depth = 0;
69
-
70
-        // remember if any input was parsed
71
-        $had_input = false;
72
-
73
-        // open input stream
74
-        $handle = fopen($input, 'r');
75
-        if (!$handle) {
76
-            $this->success = false;
77
-            return;
78
-        }
79
-
80
-        // create XML parser
81
-        $parser = xml_parser_create_ns('UTF-8', ' ');
82
-
83
-        // set tag and data handlers
84
-        xml_set_element_handler($parser, array(&$this, '_startElement'),
85
-            array(&$this, '_endElement'));
86
-
87
-        // we want a case sensitive parser
88
-        xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false);
89
-
90
-        // parse input
91
-        while ($this->success && !feof($handle)) {
92
-            $line = fgets($handle);
93
-            if (is_string($line)) {
94
-                $had_input = true;
95
-                $this->success &= xml_parse($parser, $line, false);
96
-            }
97
-        }
98
-
99
-        // finish parsing
100
-        if ($had_input) {
101
-            $this->success &= xml_parse($parser, '', true);
102
-        }
103
-
104
-        // free parser
105
-        xml_parser_free($parser);
106
-
107
-        // close input stream
108
-        fclose($handle);
109
-
110
-        // if no input was parsed it was a request
111
-        if (empty($this->props)) {
112
-            $this->props = 'allprop';
113
-        }
114
-    }
115
-
116
-    /**
117
-     * start tag handler
118
-     *
119
-     * @access private
120
-     * @param resource parser
121
-     * @param string tag name
122
-     * @param array tag attributes
123
-     */
124
-    function _startElement($parser, $name, $attrs)
125
-    {
126
-        // name space handling
127
-        if (strstr($name, ' ')) {
128
-            list ($ns, $name) = explode(' ', $name);
129
-            if (!$ns) {
130
-                $this->success = false;
131
-            }
132
-        }
133
-
134
-        // special tags at level 1: <allprop> and <propname>
135
-        if ($this->depth == 1) {
136
-            if ($name == 'allprop' || $name == 'propname') {
137
-                $this->props = $name;
138
-            }
139
-        }
140
-
141
-        // requested properties are found at level 2
142
-        if ($this->depth == 2) {
143
-            $prop = array('name' => $name);
144
-            if ($ns) {
145
-                $prop['ns'] = $ns;
146
-            }
147
-            $this->props[] = $prop;
148
-        }
149
-
150
-        // increment depth count
151
-        $this->depth++;
152
-    }
153
-
154
-    /**
155
-     * end tag handler
156
-     *
157
-     * @access private
158
-     * @param resource parser
159
-     * @param string tag name
160
-     */
161
-    function _endElement($parser, $name)
162
-    {
163
-        // here we only need to decrement the depth count
164
-        $this->depth--;
165
-    }
30
+	/**
31
+	 * success state flag
32
+	 *
33
+	 * @var bool
34
+	 * @access public
35
+	 */
36
+	var $success = false;
37
+
38
+	/**
39
+	 * found properties are collected here
40
+	 *
41
+	 * @var array
42
+	 * @access public
43
+	 */
44
+	var $props = false;
45
+
46
+	/**
47
+	 * internal tag nesting depth counter
48
+	 *
49
+	 * @var int
50
+	 * @access private
51
+	 */
52
+	var $depth = 0;
53
+
54
+	/**
55
+	 * constructor
56
+	 *
57
+	 * @access public
58
+	 */
59
+	function _parse_propfind($input)
60
+	{
61
+		// success state flag
62
+		$this->success = true;
63
+
64
+		// property storage array
65
+		$this->props = array();
66
+
67
+		// internal tag depth counter
68
+		$this->depth = 0;
69
+
70
+		// remember if any input was parsed
71
+		$had_input = false;
72
+
73
+		// open input stream
74
+		$handle = fopen($input, 'r');
75
+		if (!$handle) {
76
+			$this->success = false;
77
+			return;
78
+		}
79
+
80
+		// create XML parser
81
+		$parser = xml_parser_create_ns('UTF-8', ' ');
82
+
83
+		// set tag and data handlers
84
+		xml_set_element_handler($parser, array(&$this, '_startElement'),
85
+			array(&$this, '_endElement'));
86
+
87
+		// we want a case sensitive parser
88
+		xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false);
89
+
90
+		// parse input
91
+		while ($this->success && !feof($handle)) {
92
+			$line = fgets($handle);
93
+			if (is_string($line)) {
94
+				$had_input = true;
95
+				$this->success &= xml_parse($parser, $line, false);
96
+			}
97
+		}
98
+
99
+		// finish parsing
100
+		if ($had_input) {
101
+			$this->success &= xml_parse($parser, '', true);
102
+		}
103
+
104
+		// free parser
105
+		xml_parser_free($parser);
106
+
107
+		// close input stream
108
+		fclose($handle);
109
+
110
+		// if no input was parsed it was a request
111
+		if (empty($this->props)) {
112
+			$this->props = 'allprop';
113
+		}
114
+	}
115
+
116
+	/**
117
+	 * start tag handler
118
+	 *
119
+	 * @access private
120
+	 * @param resource parser
121
+	 * @param string tag name
122
+	 * @param array tag attributes
123
+	 */
124
+	function _startElement($parser, $name, $attrs)
125
+	{
126
+		// name space handling
127
+		if (strstr($name, ' ')) {
128
+			list ($ns, $name) = explode(' ', $name);
129
+			if (!$ns) {
130
+				$this->success = false;
131
+			}
132
+		}
133
+
134
+		// special tags at level 1: <allprop> and <propname>
135
+		if ($this->depth == 1) {
136
+			if ($name == 'allprop' || $name == 'propname') {
137
+				$this->props = $name;
138
+			}
139
+		}
140
+
141
+		// requested properties are found at level 2
142
+		if ($this->depth == 2) {
143
+			$prop = array('name' => $name);
144
+			if ($ns) {
145
+				$prop['ns'] = $ns;
146
+			}
147
+			$this->props[] = $prop;
148
+		}
149
+
150
+		// increment depth count
151
+		$this->depth++;
152
+	}
153
+
154
+	/**
155
+	 * end tag handler
156
+	 *
157
+	 * @access private
158
+	 * @param resource parser
159
+	 * @param string tag name
160
+	 */
161
+	function _endElement($parser, $name)
162
+	{
163
+		// here we only need to decrement the depth count
164
+		$this->depth--;
165
+	}
166 166
 }
167 167
 ?>
Please login to merge, or discard this patch.
phpicalendar/lib/HTTP/WebDAV/Tools/_parse_proppatch.php 4 patches
Doc Comments   +2 added lines, -1 removed lines patch added patch discarded remove patch
@@ -72,7 +72,8 @@
 block discarded – undo
72 72
     /**
73 73
      * constructor
74 74
      * 
75
-     * @param  string  path of input stream 
75
+     * @param  string  path of input stream
76
+     * @param string $path 
76 77
      * @access public
77 78
      */
78 79
     function _parse_proppatch($path) 
Please login to merge, or discard this patch.
Indentation   +176 added lines, -176 removed lines patch added patch discarded remove patch
@@ -29,186 +29,186 @@
 block discarded – undo
29 29
  */
30 30
 class _parse_proppatch 
31 31
 {
32
-    /**
33
-     *
34
-     * 
35
-     * @var
36
-     * @access
37
-     */
38
-    var $success;
39
-
40
-    /**
41
-     *
42
-     * 
43
-     * @var
44
-     * @access
45
-     */
46
-    var $props;
47
-
48
-    /**
49
-     *
50
-     * 
51
-     * @var
52
-     * @access
53
-     */
54
-    var $depth;
55
-
56
-    /**
57
-     *
58
-     * 
59
-     * @var
60
-     * @access
61
-     */
62
-    var $mode;
63
-
64
-    /**
65
-     *
66
-     * 
67
-     * @var
68
-     * @access
69
-     */
70
-    var $current;
71
-
72
-    /**
73
-     * constructor
74
-     * 
75
-     * @param  string  path of input stream 
76
-     * @access public
77
-     */
78
-    function _parse_proppatch($path) 
79
-    {
80
-        $this->success = true;
81
-
82
-        $this->depth = 0;
83
-        $this->props = array();
84
-        $had_input = false;
85
-
86
-        $f_in = fopen($path, "r");
87
-        if (!$f_in) {
88
-            $this->success = false;
89
-            return;
90
-        }
91
-
92
-        $xml_parser = xml_parser_create_ns("UTF-8", " ");
93
-
94
-        xml_set_element_handler($xml_parser,
95
-                                array(&$this, "_startElement"),
96
-                                array(&$this, "_endElement"));
97
-
98
-        xml_set_character_data_handler($xml_parser,
99
-                                       array(&$this, "_data"));
100
-
101
-        xml_parser_set_option($xml_parser,
102
-                              XML_OPTION_CASE_FOLDING, false);
103
-
104
-        while($this->success && !feof($f_in)) {
105
-            $line = fgets($f_in);
106
-            if (is_string($line)) {
107
-                $had_input = true;
108
-                $this->success &= xml_parse($xml_parser, $line, false);
109
-            }
110
-        } 
32
+	/**
33
+	 *
34
+	 * 
35
+	 * @var
36
+	 * @access
37
+	 */
38
+	var $success;
39
+
40
+	/**
41
+	 *
42
+	 * 
43
+	 * @var
44
+	 * @access
45
+	 */
46
+	var $props;
47
+
48
+	/**
49
+	 *
50
+	 * 
51
+	 * @var
52
+	 * @access
53
+	 */
54
+	var $depth;
55
+
56
+	/**
57
+	 *
58
+	 * 
59
+	 * @var
60
+	 * @access
61
+	 */
62
+	var $mode;
63
+
64
+	/**
65
+	 *
66
+	 * 
67
+	 * @var
68
+	 * @access
69
+	 */
70
+	var $current;
71
+
72
+	/**
73
+	 * constructor
74
+	 * 
75
+	 * @param  string  path of input stream 
76
+	 * @access public
77
+	 */
78
+	function _parse_proppatch($path) 
79
+	{
80
+		$this->success = true;
81
+
82
+		$this->depth = 0;
83
+		$this->props = array();
84
+		$had_input = false;
85
+
86
+		$f_in = fopen($path, "r");
87
+		if (!$f_in) {
88
+			$this->success = false;
89
+			return;
90
+		}
91
+
92
+		$xml_parser = xml_parser_create_ns("UTF-8", " ");
93
+
94
+		xml_set_element_handler($xml_parser,
95
+								array(&$this, "_startElement"),
96
+								array(&$this, "_endElement"));
97
+
98
+		xml_set_character_data_handler($xml_parser,
99
+									   array(&$this, "_data"));
100
+
101
+		xml_parser_set_option($xml_parser,
102
+							  XML_OPTION_CASE_FOLDING, false);
103
+
104
+		while($this->success && !feof($f_in)) {
105
+			$line = fgets($f_in);
106
+			if (is_string($line)) {
107
+				$had_input = true;
108
+				$this->success &= xml_parse($xml_parser, $line, false);
109
+			}
110
+		} 
111 111
         
112
-        if($had_input) {
113
-            $this->success &= xml_parse($xml_parser, "", true);
114
-        }
115
-
116
-        xml_parser_free($xml_parser);
117
-
118
-        fclose($f_in);
119
-    }
120
-
121
-    /**
122
-     * tag start handler
123
-     *
124
-     * @param  resource  parser
125
-     * @param  string    tag name
126
-     * @param  array     tag attributes
127
-     * @return void
128
-     * @access private
129
-     */
130
-    function _startElement($parser, $name, $attrs) 
131
-    {
132
-        if (strstr($name, " ")) {
133
-            list($ns, $tag) = explode(" ", $name);
134
-            if ($ns == "")
135
-                $this->success = false;
136
-        } else {
137
-            $ns = "";
138
-            $tag = $name;
139
-        }
140
-
141
-        if ($this->depth == 1) {
142
-            $this->mode = $tag;
143
-        } 
144
-
145
-        if ($this->depth == 3) {
146
-            $prop = array("name" => $tag);
147
-            $this->current = array("name" => $tag, "ns" => $ns, "status"=> 200);
148
-            if ($this->mode == "set") {
149
-                $this->current["val"] = "";     // default set val
150
-            }
151
-        }
152
-
153
-        if ($this->depth >= 4) {
154
-            $this->current["val"] .= "<$tag";
155
-            foreach ($attr as $key => $val) {
156
-                $this->current["val"] .= ' '.$key.'="'.str_replace('"','&quot;', $val).'"';
157
-            }
158
-            $this->current["val"] .= ">";
159
-        }
112
+		if($had_input) {
113
+			$this->success &= xml_parse($xml_parser, "", true);
114
+		}
115
+
116
+		xml_parser_free($xml_parser);
117
+
118
+		fclose($f_in);
119
+	}
120
+
121
+	/**
122
+	 * tag start handler
123
+	 *
124
+	 * @param  resource  parser
125
+	 * @param  string    tag name
126
+	 * @param  array     tag attributes
127
+	 * @return void
128
+	 * @access private
129
+	 */
130
+	function _startElement($parser, $name, $attrs) 
131
+	{
132
+		if (strstr($name, " ")) {
133
+			list($ns, $tag) = explode(" ", $name);
134
+			if ($ns == "")
135
+				$this->success = false;
136
+		} else {
137
+			$ns = "";
138
+			$tag = $name;
139
+		}
140
+
141
+		if ($this->depth == 1) {
142
+			$this->mode = $tag;
143
+		} 
144
+
145
+		if ($this->depth == 3) {
146
+			$prop = array("name" => $tag);
147
+			$this->current = array("name" => $tag, "ns" => $ns, "status"=> 200);
148
+			if ($this->mode == "set") {
149
+				$this->current["val"] = "";     // default set val
150
+			}
151
+		}
152
+
153
+		if ($this->depth >= 4) {
154
+			$this->current["val"] .= "<$tag";
155
+			foreach ($attr as $key => $val) {
156
+				$this->current["val"] .= ' '.$key.'="'.str_replace('"','&quot;', $val).'"';
157
+			}
158
+			$this->current["val"] .= ">";
159
+		}
160 160
 
161 161
         
162 162
 
163
-        $this->depth++;
164
-    }
165
-
166
-    /**
167
-     * tag end handler
168
-     *
169
-     * @param  resource  parser
170
-     * @param  string    tag name
171
-     * @return void
172
-     * @access private
173
-     */
174
-    function _endElement($parser, $name) 
175
-    {
176
-        if (strstr($name, " ")) {
177
-            list($ns, $tag) = explode(" ", $name);
178
-            if ($ns == "")
179
-                $this->success = false;
180
-        } else {
181
-            $ns = "";
182
-            $tag = $name;
183
-        }
184
-
185
-        $this->depth--;
186
-
187
-        if ($this->depth >= 4) {
188
-            $this->current["val"] .= "</$tag>";
189
-        }
190
-
191
-        if ($this->depth == 3) {
192
-            if (isset($this->current)) {
193
-                $this->props[] = $this->current;
194
-                unset($this->current);
195
-            }
196
-        }
197
-    }
198
-
199
-    /**
200
-     * input data handler
201
-     *
202
-     * @param  resource  parser
203
-     * @param  string    data
204
-     * @return void
205
-     * @access private
206
-     */
207
-    function _data($parser, $data) {
208
-        if (isset($this->current)) {
209
-            $this->current["val"] .= $data;
210
-        }
211
-    }
163
+		$this->depth++;
164
+	}
165
+
166
+	/**
167
+	 * tag end handler
168
+	 *
169
+	 * @param  resource  parser
170
+	 * @param  string    tag name
171
+	 * @return void
172
+	 * @access private
173
+	 */
174
+	function _endElement($parser, $name) 
175
+	{
176
+		if (strstr($name, " ")) {
177
+			list($ns, $tag) = explode(" ", $name);
178
+			if ($ns == "")
179
+				$this->success = false;
180
+		} else {
181
+			$ns = "";
182
+			$tag = $name;
183
+		}
184
+
185
+		$this->depth--;
186
+
187
+		if ($this->depth >= 4) {
188
+			$this->current["val"] .= "</$tag>";
189
+		}
190
+
191
+		if ($this->depth == 3) {
192
+			if (isset($this->current)) {
193
+				$this->props[] = $this->current;
194
+				unset($this->current);
195
+			}
196
+		}
197
+	}
198
+
199
+	/**
200
+	 * input data handler
201
+	 *
202
+	 * @param  resource  parser
203
+	 * @param  string    data
204
+	 * @return void
205
+	 * @access private
206
+	 */
207
+	function _data($parser, $data) {
208
+		if (isset($this->current)) {
209
+			$this->current["val"] .= $data;
210
+		}
211
+	}
212 212
 }
213 213
 
214 214
 ?>
215 215
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -101,7 +101,7 @@  discard block
 block discarded – undo
101 101
         xml_parser_set_option($xml_parser,
102 102
                               XML_OPTION_CASE_FOLDING, false);
103 103
 
104
-        while($this->success && !feof($f_in)) {
104
+        while ($this->success && !feof($f_in)) {
105 105
             $line = fgets($f_in);
106 106
             if (is_string($line)) {
107 107
                 $had_input = true;
@@ -109,7 +109,7 @@  discard block
 block discarded – undo
109 109
             }
110 110
         } 
111 111
         
112
-        if($had_input) {
112
+        if ($had_input) {
113 113
             $this->success &= xml_parse($xml_parser, "", true);
114 114
         }
115 115
 
@@ -146,14 +146,14 @@  discard block
 block discarded – undo
146 146
             $prop = array("name" => $tag);
147 147
             $this->current = array("name" => $tag, "ns" => $ns, "status"=> 200);
148 148
             if ($this->mode == "set") {
149
-                $this->current["val"] = "";     // default set val
149
+                $this->current["val"] = ""; // default set val
150 150
             }
151 151
         }
152 152
 
153 153
         if ($this->depth >= 4) {
154 154
             $this->current["val"] .= "<$tag";
155 155
             foreach ($attr as $key => $val) {
156
-                $this->current["val"] .= ' '.$key.'="'.str_replace('"','&quot;', $val).'"';
156
+                $this->current["val"] .= ' '.$key.'="'.str_replace('"', '&quot;', $val).'"';
157 157
             }
158 158
             $this->current["val"] .= ">";
159 159
         }
Please login to merge, or discard this patch.
Braces   +6 added lines, -4 removed lines patch added patch discarded remove patch
@@ -131,8 +131,9 @@  discard block
 block discarded – undo
131 131
     {
132 132
         if (strstr($name, " ")) {
133 133
             list($ns, $tag) = explode(" ", $name);
134
-            if ($ns == "")
135
-                $this->success = false;
134
+            if ($ns == "") {
135
+                            $this->success = false;
136
+            }
136 137
         } else {
137 138
             $ns = "";
138 139
             $tag = $name;
@@ -175,8 +176,9 @@  discard block
 block discarded – undo
175 176
     {
176 177
         if (strstr($name, " ")) {
177 178
             list($ns, $tag) = explode(" ", $name);
178
-            if ($ns == "")
179
-                $this->success = false;
179
+            if ($ns == "") {
180
+                            $this->success = false;
181
+            }
180 182
         } else {
181 183
             $ns = "";
182 184
             $tag = $name;
Please login to merge, or discard this patch.