1 |
0aee3c58
|
Assos Assos
|
<?php
|
2 |
|
|
|
3 |
|
|
|
4 |
|
|
|
5 |
|
|
|
6 |
|
|
|
7 |
|
|
|
8 |
|
|
|
9 |
|
|
|
10 |
|
|
|
11 |
|
|
|
12 |
|
|
|
13 |
|
|
|
14 |
|
|
|
15 |
|
|
|
16 |
|
|
|
17 |
|
|
|
18 |
|
|
|
19 |
|
|
|
20 |
|
|
|
21 |
|
|
|
22 |
|
|
|
23 |
|
|
|
24 |
|
|
|
25 |
|
|
|
26 |
|
|
|
27 |
|
|
|
28 |
|
|
|
29 |
|
|
|
30 |
|
|
|
31 |
|
|
|
32 |
|
|
|
33 |
|
|
|
34 |
|
|
|
35 |
|
|
|
36 |
|
|
|
37 |
|
|
|
38 |
|
|
|
39 |
|
|
|
40 |
|
|
|
41 |
|
|
|
42 |
|
|
|
43 |
|
|
|
44 |
|
|
|
45 |
|
|
|
46 |
|
|
function iCal2XML( $calendar ) {
|
47 |
|
|
|
48 |
|
|
$xmlstr = '<?xml version="1.0" encoding="utf-8"?><icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0">';
|
49 |
|
|
$xmlstr .= '<!-- created '.gmdate( 'Ymd\THis\Z' );
|
50 |
|
|
$xmlstr .= ' using kigkonsult.se '.ICALCREATOR_VERSION.' iCal2XMl (rfc6321) -->';
|
51 |
|
|
$xmlstr .= '</icalendar>';
|
52 |
|
|
$xml = new SimpleXMLElement( $xmlstr );
|
53 |
|
|
$vcalendar = $xml->addChild( 'vcalendar' );
|
54 |
|
|
|
55 |
|
|
$properties = $vcalendar->addChild( 'properties' );
|
56 |
|
|
$calProps = array( 'version', 'prodid', 'calscale', 'method' );
|
57 |
|
|
foreach( $calProps as $calProp ) {
|
58 |
|
|
if( FALSE !== ( $content = $calendar->getProperty( $calProp )))
|
59 |
|
|
_addXMLchild( $properties, $calProp, 'text', $content );
|
60 |
|
|
}
|
61 |
|
|
while( FALSE !== ( $content = $calendar->getProperty( FALSE, FALSE, TRUE )))
|
62 |
|
|
_addXMLchild( $properties, $content[0], 'unknown', $content[1]['value'], $content[1]['params'] );
|
63 |
|
|
$langCal = $calendar->getConfig( 'language' );
|
64 |
|
|
|
65 |
|
|
$components = $vcalendar->addChild( 'components' );
|
66 |
|
|
|
67 |
|
|
while( FALSE !== ( $component = $calendar->getComponent())) {
|
68 |
|
|
$compName = $component->objName;
|
69 |
|
|
$child = $components->addChild( $compName );
|
70 |
|
|
$properties = $child->addChild( 'properties' );
|
71 |
|
|
$langComp = $component->getConfig( 'language' );
|
72 |
|
|
$props = $component->getConfig( 'setPropertyNames' );
|
73 |
|
|
foreach( $props as $prop ) {
|
74 |
|
|
switch( strtolower( $prop )) {
|
75 |
|
|
case 'attach':
|
76 |
|
|
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
|
77 |
|
|
$type = ( isset( $content['params']['VALUE'] ) && ( 'BINARY' == $content['params']['VALUE'] )) ? 'binary' : 'uri';
|
78 |
|
|
unset( $content['params']['VALUE'] );
|
79 |
|
|
_addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] );
|
80 |
|
|
}
|
81 |
|
|
break;
|
82 |
|
|
case 'attendee':
|
83 |
|
|
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
|
84 |
|
|
if( isset( $content['params']['CN'] ) && !isset( $content['params']['LANGUAGE'] )) {
|
85 |
|
|
if( $langComp )
|
86 |
|
|
$content['params']['LANGUAGE'] = $langComp;
|
87 |
|
|
elseif( $langCal )
|
88 |
|
|
$content['params']['LANGUAGE'] = $langCal;
|
89 |
|
|
}
|
90 |
|
|
_addXMLchild( $properties, $prop, 'cal-address', $content['value'], $content['params'] );
|
91 |
|
|
}
|
92 |
|
|
break;
|
93 |
|
|
case 'exdate':
|
94 |
|
|
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
|
95 |
|
|
$type = ( isset( $content['params']['VALUE'] ) && ( 'DATE' == $content['params']['VALUE'] )) ? 'date' : 'date-time';
|
96 |
|
|
unset( $content['params']['VALUE'] );
|
97 |
|
|
_addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] );
|
98 |
|
|
}
|
99 |
|
|
break;
|
100 |
|
|
case 'freebusy':
|
101 |
|
|
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
|
102 |
|
|
if( is_array( $content ) && isset( $content['value']['fbtype'] )) {
|
103 |
|
|
$content['params']['FBTYPE'] = $content['value']['fbtype'];
|
104 |
|
|
unset( $content['value']['fbtype'] );
|
105 |
|
|
}
|
106 |
|
|
_addXMLchild( $properties, $prop, 'period', $content['value'], $content['params'] );
|
107 |
|
|
}
|
108 |
|
|
break;
|
109 |
|
|
case 'request-status':
|
110 |
|
|
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
|
111 |
|
|
if( !isset( $content['params']['LANGUAGE'] )) {
|
112 |
|
|
if( $langComp )
|
113 |
|
|
$content['params']['LANGUAGE'] = $langComp;
|
114 |
|
|
elseif( $langCal )
|
115 |
|
|
$content['params']['LANGUAGE'] = $langCal;
|
116 |
|
|
}
|
117 |
|
|
_addXMLchild( $properties, $prop, 'rstatus', $content['value'], $content['params'] );
|
118 |
|
|
}
|
119 |
|
|
break;
|
120 |
|
|
case 'rdate':
|
121 |
|
|
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
|
122 |
|
|
$type = 'date-time';
|
123 |
|
|
if( isset( $content['params']['VALUE'] )) {
|
124 |
|
|
if( 'DATE' == $content['params']['VALUE'] )
|
125 |
|
|
$type = 'date';
|
126 |
|
|
elseif( 'PERIOD' == $content['params']['VALUE'] )
|
127 |
|
|
$type = 'period';
|
128 |
|
|
}
|
129 |
|
|
unset( $content['params']['VALUE'] );
|
130 |
|
|
_addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] );
|
131 |
|
|
}
|
132 |
|
|
break;
|
133 |
|
|
case 'categories':
|
134 |
|
|
case 'comment':
|
135 |
|
|
case 'contact':
|
136 |
|
|
case 'description':
|
137 |
|
|
case 'related-to':
|
138 |
|
|
case 'resources':
|
139 |
|
|
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
|
140 |
|
|
if(( 'related-to' != $prop ) && !isset( $content['params']['LANGUAGE'] )) {
|
141 |
|
|
if( $langComp )
|
142 |
|
|
$content['params']['LANGUAGE'] = $langComp;
|
143 |
|
|
elseif( $langCal )
|
144 |
|
|
$content['params']['LANGUAGE'] = $langCal;
|
145 |
|
|
}
|
146 |
|
|
_addXMLchild( $properties, $prop, 'text', $content['value'], $content['params'] );
|
147 |
|
|
}
|
148 |
|
|
break;
|
149 |
|
|
case 'x-prop':
|
150 |
|
|
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE )))
|
151 |
|
|
_addXMLchild( $properties, $content[0], 'unknown', $content[1]['value'], $content[1]['params'] );
|
152 |
|
|
break;
|
153 |
|
|
case 'created':
|
154 |
|
|
case 'completed':
|
155 |
|
|
case 'dtstamp':
|
156 |
|
|
case 'last-modified':
|
157 |
|
|
$utcDate = TRUE;
|
158 |
|
|
case 'dtstart':
|
159 |
|
|
case 'dtend':
|
160 |
|
|
case 'due':
|
161 |
|
|
case 'recurrence-id':
|
162 |
|
|
if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
|
163 |
|
|
$type = ( isset( $content['params']['VALUE'] ) && ( 'DATE' == $content['params']['VALUE'] )) ? 'date' : 'date-time';
|
164 |
|
|
unset( $content['params']['VALUE'] );
|
165 |
|
|
if(( isset( $content['params']['TZID'] ) && empty( $content['params']['TZID'] )) || @is_null( $content['params']['TZID'] ))
|
166 |
|
|
unset( $content['params']['TZID'] );
|
167 |
|
|
_addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] );
|
168 |
|
|
}
|
169 |
|
|
unset( $utcDate );
|
170 |
|
|
break;
|
171 |
|
|
case 'duration':
|
172 |
|
|
if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE )))
|
173 |
|
|
_addXMLchild( $properties, $prop, 'duration', $content['value'], $content['params'] );
|
174 |
|
|
break;
|
175 |
|
|
case 'exrule':
|
176 |
|
|
case 'rrule':
|
177 |
|
|
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE )))
|
178 |
|
|
_addXMLchild( $properties, $prop, 'recur', $content['value'], $content['params'] );
|
179 |
|
|
break;
|
180 |
|
|
case 'class':
|
181 |
|
|
case 'location':
|
182 |
|
|
case 'status':
|
183 |
|
|
case 'summary':
|
184 |
|
|
case 'transp':
|
185 |
|
|
case 'tzid':
|
186 |
|
|
case 'uid':
|
187 |
|
|
if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
|
188 |
|
|
if((( 'location' == $prop ) || ( 'summary' == $prop )) && !isset( $content['params']['LANGUAGE'] )) {
|
189 |
|
|
if( $langComp )
|
190 |
|
|
$content['params']['LANGUAGE'] = $langComp;
|
191 |
|
|
elseif( $langCal )
|
192 |
|
|
$content['params']['LANGUAGE'] = $langCal;
|
193 |
|
|
}
|
194 |
|
|
_addXMLchild( $properties, $prop, 'text', $content['value'], $content['params'] );
|
195 |
|
|
}
|
196 |
|
|
break;
|
197 |
|
|
case 'geo':
|
198 |
|
|
if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE )))
|
199 |
|
|
_addXMLchild( $properties, $prop, 'geo', $content['value'], $content['params'] );
|
200 |
|
|
break;
|
201 |
|
|
case 'organizer':
|
202 |
|
|
if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
|
203 |
|
|
if( isset( $content['params']['CN'] ) && !isset( $content['params']['LANGUAGE'] )) {
|
204 |
|
|
if( $langComp )
|
205 |
|
|
$content['params']['LANGUAGE'] = $langComp;
|
206 |
|
|
elseif( $langCal )
|
207 |
|
|
$content['params']['LANGUAGE'] = $langCal;
|
208 |
|
|
}
|
209 |
|
|
_addXMLchild( $properties, $prop, 'cal-address', $content['value'], $content['params'] );
|
210 |
|
|
}
|
211 |
|
|
break;
|
212 |
|
|
case 'percent-complete':
|
213 |
|
|
case 'priority':
|
214 |
|
|
case 'sequence':
|
215 |
|
|
if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE )))
|
216 |
|
|
_addXMLchild( $properties, $prop, 'integer', $content['value'], $content['params'] );
|
217 |
|
|
break;
|
218 |
|
|
case 'tzurl':
|
219 |
|
|
case 'url':
|
220 |
|
|
if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE )))
|
221 |
|
|
_addXMLchild( $properties, $prop, 'uri', $content['value'], $content['params'] );
|
222 |
|
|
break;
|
223 |
|
|
}
|
224 |
|
|
}
|
225 |
|
|
|
226 |
|
|
while( FALSE !== ( $subcomp = $component->getComponent())) {
|
227 |
|
|
$subCompName = $subcomp->objName;
|
228 |
|
|
$child2 = $child->addChild( $subCompName );
|
229 |
|
|
$properties = $child2->addChild( 'properties' );
|
230 |
|
|
$langComp = $subcomp->getConfig( 'language' );
|
231 |
|
|
$subCompProps = $subcomp->getConfig( 'setPropertyNames' );
|
232 |
|
|
foreach( $subCompProps as $prop ) {
|
233 |
|
|
switch( strtolower( $prop )) {
|
234 |
|
|
case 'attach':
|
235 |
|
|
while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) {
|
236 |
|
|
$type = ( isset( $content['params']['VALUE'] ) && ( 'BINARY' == $content['params']['VALUE'] )) ? 'binary' : 'uri';
|
237 |
|
|
unset( $content['params']['VALUE'] );
|
238 |
|
|
_addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] );
|
239 |
|
|
}
|
240 |
|
|
break;
|
241 |
|
|
case 'attendee':
|
242 |
|
|
while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) {
|
243 |
|
|
if( isset( $content['params']['CN'] ) && !isset( $content['params']['LANGUAGE'] )) {
|
244 |
|
|
if( $langComp )
|
245 |
|
|
$content['params']['LANGUAGE'] = $langComp;
|
246 |
|
|
elseif( $langCal )
|
247 |
|
|
$content['params']['LANGUAGE'] = $langCal;
|
248 |
|
|
}
|
249 |
|
|
_addXMLchild( $properties, $prop, 'cal-address', $content['value'], $content['params'] );
|
250 |
|
|
}
|
251 |
|
|
break;
|
252 |
|
|
case 'comment':
|
253 |
|
|
case 'tzname':
|
254 |
|
|
while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) {
|
255 |
|
|
if( !isset( $content['params']['LANGUAGE'] )) {
|
256 |
|
|
if( $langComp )
|
257 |
|
|
$content['params']['LANGUAGE'] = $langComp;
|
258 |
|
|
elseif( $langCal )
|
259 |
|
|
$content['params']['LANGUAGE'] = $langCal;
|
260 |
|
|
}
|
261 |
|
|
_addXMLchild( $properties, $prop, 'text', $content['value'], $content['params'] );
|
262 |
|
|
}
|
263 |
|
|
break;
|
264 |
|
|
case 'rdate':
|
265 |
|
|
while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) {
|
266 |
|
|
$type = 'date-time';
|
267 |
|
|
if( isset( $content['params']['VALUE'] )) {
|
268 |
|
|
if( 'DATE' == $content['params']['VALUE'] )
|
269 |
|
|
$type = 'date';
|
270 |
|
|
elseif( 'PERIOD' == $content['params']['VALUE'] )
|
271 |
|
|
$type = 'period';
|
272 |
|
|
}
|
273 |
|
|
unset( $content['params']['VALUE'] );
|
274 |
|
|
_addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] );
|
275 |
|
|
}
|
276 |
|
|
break;
|
277 |
|
|
case 'x-prop':
|
278 |
|
|
while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE )))
|
279 |
|
|
_addXMLchild( $properties, $content[0], 'unknown', $content[1]['value'], $content[1]['params'] );
|
280 |
|
|
break;
|
281 |
|
|
case 'action':
|
282 |
|
|
case 'description':
|
283 |
|
|
case 'summary':
|
284 |
|
|
if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) {
|
285 |
|
|
if(( 'action' != $prop ) && !isset( $content['params']['LANGUAGE'] )) {
|
286 |
|
|
if( $langComp )
|
287 |
|
|
$content['params']['LANGUAGE'] = $langComp;
|
288 |
|
|
elseif( $langCal )
|
289 |
|
|
$content['params']['LANGUAGE'] = $langCal;
|
290 |
|
|
}
|
291 |
|
|
_addXMLchild( $properties, $prop, 'text', $content['value'], $content['params'] );
|
292 |
|
|
}
|
293 |
|
|
break;
|
294 |
|
|
case 'dtstart':
|
295 |
|
|
if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) {
|
296 |
|
|
unset( $content['value']['tz'], $content['params']['VALUE'] );
|
297 |
|
|
_addXMLchild( $properties, $prop, 'date-time', $content['value'], $content['params'] );
|
298 |
|
|
}
|
299 |
|
|
break;
|
300 |
|
|
case 'duration':
|
301 |
|
|
if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE )))
|
302 |
|
|
_addXMLchild( $properties, $prop, 'duration', $content['value'], $content['params'] );
|
303 |
|
|
break;
|
304 |
|
|
case 'repeat':
|
305 |
|
|
if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE )))
|
306 |
|
|
_addXMLchild( $properties, $prop, 'integer', $content['value'], $content['params'] );
|
307 |
|
|
break;
|
308 |
|
|
case 'trigger':
|
309 |
|
|
if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) {
|
310 |
|
|
if( isset( $content['value']['year'] ) &&
|
311 |
|
|
isset( $content['value']['month'] ) &&
|
312 |
|
|
isset( $content['value']['day'] ))
|
313 |
|
|
$type = 'date-time';
|
314 |
|
|
else {
|
315 |
|
|
$type = 'duration';
|
316 |
|
|
if( !isset( $content['value']['relatedStart'] ) || ( TRUE !== $content['value']['relatedStart'] ))
|
317 |
|
|
$content['params']['RELATED'] = 'END';
|
318 |
|
|
}
|
319 |
|
|
_addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] );
|
320 |
|
|
}
|
321 |
|
|
break;
|
322 |
|
|
case 'tzoffsetto':
|
323 |
|
|
case 'tzoffsetfrom':
|
324 |
|
|
if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE )))
|
325 |
|
|
_addXMLchild( $properties, $prop, 'utc-offset', $content['value'], $content['params'] );
|
326 |
|
|
break;
|
327 |
|
|
case 'rrule':
|
328 |
|
|
while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE )))
|
329 |
|
|
_addXMLchild( $properties, $prop, 'recur', $content['value'], $content['params'] );
|
330 |
|
|
break;
|
331 |
|
|
}
|
332 |
|
|
}
|
333 |
|
|
}
|
334 |
|
|
}
|
335 |
|
|
return $xml->asXML();
|
336 |
|
|
}
|
337 |
|
|
|
338 |
|
|
|
339 |
|
|
|
340 |
|
|
|
341 |
|
|
|
342 |
|
|
|
343 |
|
|
|
344 |
|
|
|
345 |
|
|
|
346 |
|
|
|
347 |
|
|
|
348 |
|
|
|
349 |
|
|
|
350 |
|
|
|
351 |
|
|
|
352 |
|
|
|
353 |
|
|
function _addXMLchild( & $parent, $name, $type, $content, $params=array()) {
|
354 |
|
|
static $fmtYmd = '%04d-%02d-%02d';
|
355 |
|
|
static $fmtYmdHis = '%04d-%02d-%02dT%02d:%02d:%02d';
|
356 |
|
|
|
357 |
|
|
$name = strtolower( $name );
|
358 |
|
|
$child = $parent->addChild( $name );
|
359 |
|
|
if( !empty( $params )) {
|
360 |
|
|
$parameters = $child->addChild( 'parameters' );
|
361 |
|
|
foreach( $params as $param => $parVal ) {
|
362 |
|
|
if( 'VALUE' == $param )
|
363 |
|
|
continue;
|
364 |
|
|
$param = strtolower( $param );
|
365 |
|
|
if( 'x-' == substr( $param, 0, 2 )) {
|
366 |
|
|
$p1 = $parameters->addChild( $param );
|
367 |
|
|
$p2 = $p1->addChild( 'unknown', htmlspecialchars( $parVal ));
|
368 |
|
|
}
|
369 |
|
|
else {
|
370 |
|
|
$p1 = $parameters->addChild( $param );
|
371 |
|
|
switch( $param ) {
|
372 |
|
|
case 'altrep':
|
373 |
|
|
case 'dir': $ptype = 'uri'; break;
|
374 |
|
|
case 'delegated-from':
|
375 |
|
|
case 'delegated-to':
|
376 |
|
|
case 'member':
|
377 |
|
|
case 'sent-by': $ptype = 'cal-address'; break;
|
378 |
|
|
case 'rsvp': $ptype = 'boolean'; break ;
|
379 |
|
|
default: $ptype = 'text'; break;
|
380 |
|
|
}
|
381 |
|
|
if( is_array( $parVal )) {
|
382 |
|
|
foreach( $parVal as $pV )
|
383 |
|
|
$p2 = $p1->addChild( $ptype, htmlspecialchars( $pV ));
|
384 |
|
|
}
|
385 |
|
|
else
|
386 |
|
|
$p2 = $p1->addChild( $ptype, htmlspecialchars( $parVal ));
|
387 |
|
|
}
|
388 |
|
|
}
|
389 |
|
|
}
|
390 |
|
|
if(( empty( $content ) && ( '0' != $content )) || ( !is_array( $content) && ( '-' != substr( $content, 0, 1 ) && ( 0 > $content ))))
|
391 |
|
|
return;
|
392 |
|
|
|
393 |
|
|
switch( $type ) {
|
394 |
|
|
case 'binary':
|
395 |
|
|
$v = $child->addChild( $type, $content );
|
396 |
|
|
break;
|
397 |
|
|
case 'boolean':
|
398 |
|
|
break;
|
399 |
|
|
case 'cal-address':
|
400 |
|
|
$v = $child->addChild( $type, $content );
|
401 |
|
|
break;
|
402 |
|
|
case 'date':
|
403 |
|
|
if( array_key_exists( 'year', $content ))
|
404 |
|
|
$content = array( $content );
|
405 |
|
|
foreach( $content as $date ) {
|
406 |
|
|
$str = sprintf( $fmtYmd, (int) $date['year'], (int) $date['month'], (int) $date['day'] );
|
407 |
|
|
$v = $child->addChild( $type, $str );
|
408 |
|
|
}
|
409 |
|
|
break;
|
410 |
|
|
case 'date-time':
|
411 |
|
|
if( array_key_exists( 'year', $content ))
|
412 |
|
|
$content = array( $content );
|
413 |
|
|
foreach( $content as $dt ) {
|
414 |
|
|
if( !isset( $dt['hour'] )) $dt['hour'] = 0;
|
415 |
|
|
if( !isset( $dt['min'] )) $dt['min'] = 0;
|
416 |
|
|
if( !isset( $dt['sec'] )) $dt['sec'] = 0;
|
417 |
|
|
$str = sprintf( $fmtYmdHis, (int) $dt['year'], (int) $dt['month'], (int) $dt['day'], (int) $dt['hour'], (int) $dt['min'], (int) $dt['sec'] );
|
418 |
|
|
if( isset( $dt['tz'] ) && ( 'Z' == $dt['tz'] ))
|
419 |
|
|
$str .= 'Z';
|
420 |
|
|
$v = $child->addChild( $type, $str );
|
421 |
|
|
}
|
422 |
|
|
break;
|
423 |
|
|
case 'duration':
|
424 |
|
|
$output = (( 'trigger' == $name ) && ( FALSE !== $content['before'] )) ? '-' : '';
|
425 |
|
|
$v = $child->addChild( $type, $output.iCalUtilityFunctions::_duration2str( $content ) );
|
426 |
|
|
break;
|
427 |
|
|
case 'geo':
|
428 |
|
|
if( !empty( $content )) {
|
429 |
|
|
$v1 = $child->addChild( 'latitude', iCalUtilityFunctions::_geo2str2( $content['latitude'], iCalUtilityFunctions::$geoLatFmt ));
|
430 |
|
|
$v1 = $child->addChild( 'longitude', iCalUtilityFunctions::_geo2str2( $content['longitude'], iCalUtilityFunctions::$geoLongFmt ));
|
431 |
|
|
}
|
432 |
|
|
break;
|
433 |
|
|
case 'integer':
|
434 |
|
|
$v = $child->addChild( $type, (string) $content );
|
435 |
|
|
break;
|
436 |
|
|
case 'period':
|
437 |
|
|
if( !is_array( $content ))
|
438 |
|
|
break;
|
439 |
|
|
foreach( $content as $period ) {
|
440 |
|
|
$v1 = $child->addChild( $type );
|
441 |
|
|
$str = sprintf( $fmtYmdHis, (int) $period[0]['year'], (int) $period[0]['month'], (int) $period[0]['day'], (int) $period[0]['hour'], (int) $period[0]['min'], (int) $period[0]['sec'] );
|
442 |
|
|
if( isset( $period[0]['tz'] ) && ( 'Z' == $period[0]['tz'] ))
|
443 |
|
|
$str .= 'Z';
|
444 |
|
|
$v2 = $v1->addChild( 'start', $str );
|
445 |
|
|
if( array_key_exists( 'year', $period[1] )) {
|
446 |
|
|
$str = sprintf( $fmtYmdHis, (int) $period[1]['year'], (int) $period[1]['month'], (int) $period[1]['day'], (int) $period[1]['hour'], (int) $period[1]['min'], (int) $period[1]['sec'] );
|
447 |
|
|
if( isset($period[1]['tz'] ) && ( 'Z' == $period[1]['tz'] ))
|
448 |
|
|
$str .= 'Z';
|
449 |
|
|
$v2 = $v1->addChild( 'end', $str );
|
450 |
|
|
}
|
451 |
|
|
else
|
452 |
|
|
$v2 = $v1->addChild( 'duration', iCalUtilityFunctions::_duration2str( $period[1] ));
|
453 |
|
|
}
|
454 |
|
|
break;
|
455 |
|
|
case 'recur':
|
456 |
|
|
$content = array_change_key_case( $content );
|
457 |
|
|
foreach( $content as $rulelabel => $rulevalue ) {
|
458 |
|
|
switch( $rulelabel ) {
|
459 |
|
|
case 'until':
|
460 |
|
|
if( isset( $rulevalue['hour'] ))
|
461 |
|
|
$str = sprintf( $fmtYmdHis, (int) $rulevalue['year'], (int) $rulevalue['month'], (int) $rulevalue['day'], (int) $rulevalue['hour'], (int) $rulevalue['min'], (int) $rulevalue['sec'] ).'Z';
|
462 |
|
|
else
|
463 |
|
|
$str = sprintf( $fmtYmd, (int) $rulevalue['year'], (int) $rulevalue['month'], (int) $rulevalue['day'] );
|
464 |
|
|
$v = $child->addChild( $rulelabel, $str );
|
465 |
|
|
break;
|
466 |
|
|
case 'bysecond':
|
467 |
|
|
case 'byminute':
|
468 |
|
|
case 'byhour':
|
469 |
|
|
case 'bymonthday':
|
470 |
|
|
case 'byyearday':
|
471 |
|
|
case 'byweekno':
|
472 |
|
|
case 'bymonth':
|
473 |
|
|
case 'bysetpos': {
|
474 |
|
|
if( is_array( $rulevalue )) {
|
475 |
|
|
foreach( $rulevalue as $vix => $valuePart )
|
476 |
|
|
$v = $child->addChild( $rulelabel, $valuePart );
|
477 |
|
|
}
|
478 |
|
|
else
|
479 |
|
|
$v = $child->addChild( $rulelabel, $rulevalue );
|
480 |
|
|
break;
|
481 |
|
|
}
|
482 |
|
|
case 'byday': {
|
483 |
|
|
if( isset( $rulevalue['DAY'] )) {
|
484 |
|
|
$str = ( isset( $rulevalue[0] )) ? $rulevalue[0] : '';
|
485 |
|
|
$str .= $rulevalue['DAY'];
|
486 |
|
|
$p = $child->addChild( $rulelabel, $str );
|
487 |
|
|
}
|
488 |
|
|
else {
|
489 |
|
|
foreach( $rulevalue as $valuePart ) {
|
490 |
|
|
if( isset( $valuePart['DAY'] )) {
|
491 |
|
|
$str = ( isset( $valuePart[0] )) ? $valuePart[0] : '';
|
492 |
|
|
$str .= $valuePart['DAY'];
|
493 |
|
|
$p = $child->addChild( $rulelabel, $str );
|
494 |
|
|
}
|
495 |
|
|
else
|
496 |
|
|
$p = $child->addChild( $rulelabel, $valuePart );
|
497 |
|
|
}
|
498 |
|
|
}
|
499 |
|
|
break;
|
500 |
|
|
}
|
501 |
|
|
case 'freq':
|
502 |
|
|
case 'count':
|
503 |
|
|
case 'interval':
|
504 |
|
|
case 'wkst':
|
505 |
|
|
default:
|
506 |
|
|
$p = $child->addChild( $rulelabel, $rulevalue );
|
507 |
|
|
break;
|
508 |
|
|
}
|
509 |
|
|
}
|
510 |
|
|
break;
|
511 |
|
|
case 'rstatus':
|
512 |
|
|
$v = $child->addChild( 'code', number_format( (float) $content['statcode'], 2, '.', ''));
|
513 |
|
|
$v = $child->addChild( 'description', htmlspecialchars( $content['text'] ));
|
514 |
|
|
if( isset( $content['extdata'] ))
|
515 |
|
|
$v = $child->addChild( 'data', htmlspecialchars( $content['extdata'] ));
|
516 |
|
|
break;
|
517 |
|
|
case 'text':
|
518 |
|
|
if( !is_array( $content ))
|
519 |
|
|
$content = array( $content );
|
520 |
|
|
foreach( $content as $part )
|
521 |
|
|
$v = $child->addChild( $type, htmlspecialchars( $part ));
|
522 |
|
|
break;
|
523 |
|
|
case 'time':
|
524 |
|
|
break;
|
525 |
|
|
case 'uri':
|
526 |
|
|
$v = $child->addChild( $type, $content );
|
527 |
|
|
break;
|
528 |
|
|
case 'utc-offset':
|
529 |
|
|
if( in_array( substr( $content, 0, 1 ), array( '-', '+' ))) {
|
530 |
|
|
$str = substr( $content, 0, 1 );
|
531 |
|
|
$content = substr( $content, 1 );
|
532 |
|
|
}
|
533 |
|
|
else
|
534 |
|
|
$str = '+';
|
535 |
|
|
$str .= substr( $content, 0, 2 ).':'.substr( $content, 2, 2 );
|
536 |
|
|
if( 4 < strlen( $content ))
|
537 |
|
|
$str .= ':'.substr( $content, 4 );
|
538 |
|
|
$v = $child->addChild( $type, $str );
|
539 |
|
|
break;
|
540 |
|
|
case 'unknown':
|
541 |
|
|
default:
|
542 |
|
|
if( is_array( $content ))
|
543 |
|
|
$content = implode( '', $content );
|
544 |
|
|
$v = $child->addChild( 'unknown', htmlspecialchars( $content ));
|
545 |
|
|
break;
|
546 |
|
|
}
|
547 |
|
|
}
|
548 |
|
|
|
549 |
|
|
|
550 |
|
|
|
551 |
|
|
|
552 |
|
|
|
553 |
|
|
|
554 |
|
|
|
555 |
|
|
|
556 |
|
|
|
557 |
|
|
function XMLfile2iCal( $xmlfile, $iCalcfg=array()) {
|
558 |
|
|
if( FALSE === ( $xmlstr = file_get_contents( $xmlfile )))
|
559 |
|
|
return FALSE;
|
560 |
|
|
return xml2iCal( $xmlstr, $iCalcfg );
|
561 |
|
|
}
|
562 |
|
|
|
563 |
|
|
|
564 |
|
|
|
565 |
|
|
|
566 |
|
|
|
567 |
|
|
|
568 |
|
|
|
569 |
|
|
|
570 |
|
|
|
571 |
|
|
function XMLstr2iCal( $xmlstr, $iCalcfg=array()) {
|
572 |
|
|
return XML2iCal( $xmlstr, $iCalcfg);
|
573 |
|
|
}
|
574 |
|
|
|
575 |
|
|
|
576 |
|
|
|
577 |
|
|
|
578 |
|
|
|
579 |
|
|
|
580 |
|
|
|
581 |
|
|
|
582 |
|
|
|
583 |
|
|
|
584 |
|
|
|
585 |
|
|
function XML2iCal( $xmlstr, $iCalcfg=array()) {
|
586 |
|
|
$xmlstr = str_replace( array( "\r\n", "\n\r", "\n", "\r" ), '', $xmlstr );
|
587 |
|
|
$xml = XMLgetTagContent1( $xmlstr, 'vcalendar', $endIx );
|
588 |
|
|
$iCal = new vcalendar( $iCalcfg );
|
589 |
|
|
XMLgetComps( $iCal, $xmlstr );
|
590 |
|
|
unset( $xmlstr );
|
591 |
|
|
return $iCal;
|
592 |
|
|
}
|
593 |
|
|
|
594 |
|
|
|
595 |
|
|
|
596 |
|
|
|
597 |
|
|
|
598 |
|
|
|
599 |
|
|
|
600 |
|
|
|
601 |
|
|
|
602 |
|
|
|
603 |
|
|
|
604 |
|
|
|
605 |
|
|
|
606 |
|
|
|
607 |
|
|
|
608 |
|
|
|
609 |
|
|
function XMLgetComps( $iCal, $xml ) {
|
610 |
|
|
$sx = 0;
|
611 |
|
|
while(( FALSE !== substr( $xml, ( $sx + 11 ), 1 )) &&
|
612 |
|
|
( '<properties>' != substr( $xml, $sx, 12 )) && ( '<components>' != substr( $xml, $sx, 12 )))
|
613 |
|
|
$sx += 1;
|
614 |
|
|
if( FALSE === substr( $xml, ( $sx + 11 ), 1 ))
|
615 |
|
|
return FALSE;
|
616 |
|
|
if( '<properties>' == substr( $xml, $sx, 12 )) {
|
617 |
|
|
$xml2 = XMLgetTagContent1( $xml, 'properties', $endIx );
|
618 |
|
|
XMLgetProps( $iCal, $xml2 );
|
619 |
|
|
$xml = substr( $xml, $endIx );
|
620 |
|
|
}
|
621 |
|
|
if( '<components>' == substr( $xml, 0, 12 ))
|
622 |
|
|
$xml = XMLgetTagContent1( $xml, 'components', $endIx );
|
623 |
|
|
while( ! empty( $xml )) {
|
624 |
|
|
$xml2 = XMLgetTagContent2( $xml, $tagName, $endIx );
|
625 |
|
|
if( in_array( strtolower( $tagName ), iCalUtilityFunctions::$allComps ) &&
|
626 |
|
|
( FALSE !== ( $subComp = $iCal->newComponent( $tagName ))))
|
627 |
|
|
XMLgetComps( $subComp, $xml2 );
|
628 |
|
|
$xml = substr( $xml, $endIx);
|
629 |
|
|
}
|
630 |
|
|
unset( $xml );
|
631 |
|
|
return $iCal;
|
632 |
|
|
}
|
633 |
|
|
|
634 |
|
|
|
635 |
|
|
|
636 |
|
|
|
637 |
|
|
|
638 |
|
|
|
639 |
|
|
|
640 |
|
|
|
641 |
|
|
|
642 |
|
|
|
643 |
|
|
|
644 |
|
|
|
645 |
|
|
|
646 |
|
|
|
647 |
|
|
function XMLgetProps( $iCal, $xml) {
|
648 |
|
|
while( ! empty( $xml )) {
|
649 |
|
|
$xml2 = XMLgetTagContent2( $xml, $propName, $endIx );
|
650 |
|
|
$propName = strtoupper( $propName );
|
651 |
|
|
if( empty( $xml2 ) && ( '0' != $xml2 )) {
|
652 |
|
|
$iCal->setProperty( $propName );
|
653 |
|
|
$xml = substr( $xml, $endIx);
|
654 |
|
|
continue;
|
655 |
|
|
}
|
656 |
|
|
$params = array();
|
657 |
|
|
if( '<parameters/>' == substr( $xml2, 0, 13 ))
|
658 |
|
|
$xml2 = substr( $xml2, 13 );
|
659 |
|
|
elseif( '<parameters>' == substr( $xml2, 0, 12 )) {
|
660 |
|
|
$xml3 = XMLgetTagContent1( $xml2, 'parameters', $endIx2 );
|
661 |
|
|
while( ! empty( $xml3 )) {
|
662 |
|
|
$xml4 = XMLgetTagContent2( $xml3, $paramKey, $endIx3 );
|
663 |
|
|
$pType = FALSE;
|
664 |
|
|
$paramKey = strtoupper( $paramKey );
|
665 |
|
|
static $mParams = array( 'DELEGATED-FROM', 'DELEGATED-TO', 'MEMBER' );
|
666 |
|
|
if( in_array( $paramKey, $mParams )) {
|
667 |
|
|
while( ! empty( $xml4 )) {
|
668 |
|
|
if( ! isset( $params[$paramKey] ))
|
669 |
|
|
$params[$paramKey] = array( XMLgetTagContent1( $xml4, 'cal-address', $endIx4 ));
|
670 |
|
|
else
|
671 |
|
|
$params[$paramKey][] = XMLgetTagContent1( $xml4, 'cal-address', $endIx4 );
|
672 |
|
|
$xml4 = substr( $xml4, $endIx4 );
|
673 |
|
|
}
|
674 |
|
|
}
|
675 |
|
|
else {
|
676 |
|
|
if( ! isset( $params[$paramKey] ))
|
677 |
|
|
$params[$paramKey] = html_entity_decode( XMLgetTagContent2( $xml4, $pType, $endIx4 ));
|
678 |
|
|
else
|
679 |
|
|
$params[$paramKey] .= ','.html_entity_decode( XMLgetTagContent2( $xml4, $pType, $endIx4 ));
|
680 |
|
|
}
|
681 |
|
|
$xml3 = substr( $xml3, $endIx3 );
|
682 |
|
|
}
|
683 |
|
|
$xml2 = substr( $xml2, $endIx2 );
|
684 |
|
|
}
|
685 |
|
|
$valueType = FALSE;
|
686 |
|
|
$value = ( ! empty( $xml2 ) || ( '0' == $xml2 )) ? XMLgetTagContent2( $xml2, $valueType, $endIx3 ) : '';
|
687 |
|
|
switch( $propName ) {
|
688 |
|
|
case 'CATEGORIES':
|
689 |
|
|
case 'RESOURCES':
|
690 |
|
|
$tValue = array();
|
691 |
|
|
while( ! empty( $xml2 )) {
|
692 |
|
|
$tValue[] = html_entity_decode( XMLgetTagContent2( $xml2, $valueType, $endIx4 ));
|
693 |
|
|
$xml2 = substr( $xml2, $endIx4 );
|
694 |
|
|
}
|
695 |
|
|
$value = $tValue;
|
696 |
|
|
break;
|
697 |
|
|
case 'EXDATE':
|
698 |
|
|
case 'RDATE':
|
699 |
|
|
if( 'period' != $valueType ) {
|
700 |
|
|
if( 'date' == $valueType )
|
701 |
|
|
$params['VALUE'] = 'DATE';
|
702 |
|
|
$t = array();
|
703 |
|
|
while( ! empty( $xml2 ) && ( '<date' == substr( $xml2, 0, 5 ))) {
|
704 |
|
|
$t[] = XMLgetTagContent2( $xml2, $pType, $endIx4 );
|
705 |
|
|
$xml2 = substr( $xml2, $endIx4 );
|
706 |
|
|
}
|
707 |
|
|
$value = $t;
|
708 |
|
|
break;
|
709 |
|
|
}
|
710 |
|
|
case 'FREEBUSY':
|
711 |
|
|
if( 'RDATE' == $propName )
|
712 |
|
|
$params['VALUE'] = 'PERIOD';
|
713 |
|
|
$value = array();
|
714 |
|
|
while( ! empty( $xml2 ) && ( '<period>' == substr( $xml2, 0, 8 ))) {
|
715 |
|
|
$xml3 = XMLgetTagContent1( $xml2, 'period', $endIx4 );
|
716 |
|
|
$t = array();
|
717 |
|
|
while( ! empty( $xml3 )) {
|
718 |
|
|
$t[] = XMLgetTagContent2( $xml3, $pType, $endIx5 );
|
719 |
|
|
$xml3 = substr( $xml3, $endIx5 );
|
720 |
|
|
}
|
721 |
|
|
$value[] = $t;
|
722 |
|
|
$xml2 = substr( $xml2, $endIx4 );
|
723 |
|
|
}
|
724 |
|
|
break;
|
725 |
|
|
case 'TZOFFSETTO':
|
726 |
|
|
case 'TZOFFSETFROM':
|
727 |
|
|
$value = str_replace( ':', '', $value );
|
728 |
|
|
break;
|
729 |
|
|
case 'GEO':
|
730 |
|
|
$tValue = array( 'latitude' => $value );
|
731 |
|
|
$tValue['longitude'] = XMLgetTagContent1( substr( $xml2, $endIx3 ), 'longitude', $endIx3 );
|
732 |
|
|
$value = $tValue;
|
733 |
|
|
break;
|
734 |
|
|
case 'EXRULE':
|
735 |
|
|
case 'RRULE':
|
736 |
|
|
$tValue = array( $valueType => $value );
|
737 |
|
|
$xml2 = substr( $xml2, $endIx3 );
|
738 |
|
|
$valueType = FALSE;
|
739 |
|
|
while( ! empty( $xml2 )) {
|
740 |
|
|
$t = XMLgetTagContent2( $xml2, $valueType, $endIx4 );
|
741 |
|
|
switch( $valueType ) {
|
742 |
|
|
case 'freq':
|
743 |
|
|
case 'count':
|
744 |
|
|
case 'until':
|
745 |
|
|
case 'interval':
|
746 |
|
|
case 'wkst':
|
747 |
|
|
$tValue[$valueType] = $t;
|
748 |
|
|
break;
|
749 |
|
|
case 'byday':
|
750 |
|
|
if( 2 == strlen( $t ))
|
751 |
|
|
$tValue[$valueType][] = array( 'DAY' => $t );
|
752 |
|
|
else {
|
753 |
|
|
$day = substr( $t, -2 );
|
754 |
|
|
$key = substr( $t, 0, ( strlen( $t ) - 2 ));
|
755 |
|
|
$tValue[$valueType][] = array( $key, 'DAY' => $day );
|
756 |
|
|
}
|
757 |
|
|
break;
|
758 |
|
|
default:
|
759 |
|
|
$tValue[$valueType][] = $t;
|
760 |
|
|
}
|
761 |
|
|
$xml2 = substr( $xml2, $endIx4 );
|
762 |
|
|
}
|
763 |
|
|
$value = $tValue;
|
764 |
|
|
break;
|
765 |
|
|
case 'REQUEST-STATUS':
|
766 |
|
|
$tValue = array();
|
767 |
|
|
while( ! empty( $xml2 )) {
|
768 |
|
|
$t = html_entity_decode( XMLgetTagContent2( $xml2, $valueType, $endIx4 ));
|
769 |
|
|
$tValue[$valueType] = $t;
|
770 |
|
|
$xml2 = substr( $xml2, $endIx4 );
|
771 |
|
|
}
|
772 |
|
|
if( ! empty( $tValue ))
|
773 |
|
|
$value = $tValue;
|
774 |
|
|
else
|
775 |
|
|
$value = array( 'code' => null, 'description' => null );
|
776 |
|
|
break;
|
777 |
|
|
default:
|
778 |
|
|
switch( $valueType ) {
|
779 |
|
|
case 'binary': $params['VALUE'] = 'BINARY'; break;
|
780 |
|
|
case 'date': $params['VALUE'] = 'DATE'; break;
|
781 |
|
|
case 'date-time': $params['VALUE'] = 'DATE-TIME'; break;
|
782 |
|
|
case 'text':
|
783 |
|
|
case 'unknown': $value = html_entity_decode( $value ); break;
|
784 |
|
|
}
|
785 |
|
|
break;
|
786 |
|
|
}
|
787 |
|
|
if( 'FREEBUSY' == $propName ) {
|
788 |
|
|
$fbtype = $params['FBTYPE'];
|
789 |
|
|
unset( $params['FBTYPE'] );
|
790 |
|
|
$iCal->setProperty( $propName, $fbtype, $value, $params );
|
791 |
|
|
}
|
792 |
|
|
elseif( 'GEO' == $propName )
|
793 |
|
|
$iCal->setProperty( $propName, $value['latitude'], $value['longitude'], $params );
|
794 |
|
|
elseif( 'REQUEST-STATUS' == $propName ) {
|
795 |
|
|
if( !isset( $value['data'] ))
|
796 |
|
|
$value['data'] = FALSE;
|
797 |
|
|
$iCal->setProperty( $propName, $value['code'], $value['description'], $value['data'], $params );
|
798 |
|
|
}
|
799 |
|
|
else {
|
800 |
|
|
if( empty( $value ) && ( is_array( $value ) || ( '0' > $value )))
|
801 |
|
|
$value = '';
|
802 |
|
|
$iCal->setProperty( $propName, $value, $params );
|
803 |
|
|
}
|
804 |
|
|
$xml = substr( $xml, $endIx);
|
805 |
|
|
}
|
806 |
|
|
}
|
807 |
|
|
|
808 |
|
|
|
809 |
|
|
|
810 |
|
|
|
811 |
|
|
|
812 |
|
|
|
813 |
|
|
|
814 |
|
|
|
815 |
|
|
|
816 |
|
|
|
817 |
|
|
function XMLgetTagContent1( $xml, $tagName, & $endIx=0 ) {
|
818 |
|
|
$strlen = strlen( $tagName );
|
819 |
|
|
$sx1 = 0;
|
820 |
|
|
while( FALSE !== substr( $xml, $sx1, 1 )) {
|
821 |
|
|
if(( FALSE !== substr( $xml, ( $sx1 + $strlen + 1 ), 1 )) &&
|
822 |
|
|
( strtolower( "<$tagName>" ) == strtolower( substr( $xml, $sx1, ( $strlen + 2 )))))
|
823 |
|
|
break;
|
824 |
|
|
if(( FALSE !== substr( $xml, ( $sx1 + $strlen + 3 ), 1 )) &&
|
825 |
|
|
( strtolower( "<$tagName />" ) == strtolower( substr( $xml, $sx1, ( $strlen + 4 ))))) {
|
826 |
|
|
$endIx = $strlen + 5;
|
827 |
|
|
return '';
|
828 |
|
|
}
|
829 |
|
|
if(( FALSE !== substr( $xml, ( $sx1 + $strlen + 2 ), 1 )) &&
|
830 |
|
|
( strtolower( "<$tagName/>" ) == strtolower( substr( $xml, $sx1, ( $strlen + 3 ))))) {
|
831 |
|
|
$endIx = $strlen + 4;
|
832 |
|
|
return '';
|
833 |
|
|
}
|
834 |
|
|
$sx1 += 1;
|
835 |
|
|
}
|
836 |
|
|
if( FALSE === substr( $xml, $sx1, 1 )) {
|
837 |
|
|
$endIx = ( empty( $sx )) ? 0 : $sx - 1;
|
838 |
|
|
return '';
|
839 |
|
|
}
|
840 |
|
|
if( FALSE === ( $pos = stripos( $xml, "</$tagName>" ))) {
|
841 |
|
|
$endIx = strlen( $xml ) + 1;
|
842 |
|
|
return '';
|
843 |
|
|
}
|
844 |
|
|
$endIx = $pos + $strlen + 3;
|
845 |
|
|
return substr( $xml, ( $sx1 + $strlen + 2 ), ( $pos - $sx1 - 2 - $strlen ));
|
846 |
|
|
}
|
847 |
|
|
|
848 |
|
|
|
849 |
|
|
|
850 |
|
|
|
851 |
|
|
|
852 |
|
|
|
853 |
|
|
|
854 |
|
|
|
855 |
|
|
|
856 |
|
|
|
857 |
|
|
function XMLgetTagContent2( $xml, & $tagName, & $endIx ) {
|
858 |
|
|
$endIx = strlen( $xml ) + 1;
|
859 |
|
|
$sx1 = 0;
|
860 |
|
|
while( FALSE !== substr( $xml, $sx1, 1 )) {
|
861 |
|
|
if( '<' == substr( $xml, $sx1, 1 )) {
|
862 |
|
|
if(( FALSE !== substr( $xml, ( $sx1 + 3 ), 1 )) && ( '<!--' == substr( $xml, $sx1, 4 )))
|
863 |
|
|
$sx1 += 1;
|
864 |
|
|
else
|
865 |
|
|
break;
|
866 |
|
|
}
|
867 |
|
|
else
|
868 |
|
|
$sx1 += 1;
|
869 |
|
|
}
|
870 |
|
|
$sx2 = $sx1;
|
871 |
|
|
while( FALSE !== substr( $xml, $sx2 )) {
|
872 |
|
|
if(( FALSE !== substr( $xml, ( $sx2 + 1 ), 1 )) && ( '/>' == substr( $xml, $sx2, 2 ))) {
|
873 |
|
|
$tagName = trim( substr( $xml, ( $sx1 + 1 ), ( $sx2 - $sx1 - 1 )));
|
874 |
|
|
$endIx = $sx2 + 2;
|
875 |
|
|
return '';
|
876 |
|
|
}
|
877 |
|
|
if( '>' == substr( $xml, $sx2, 1 ))
|
878 |
|
|
break;
|
879 |
|
|
$sx2 += 1;
|
880 |
|
|
}
|
881 |
|
|
$tagName = substr( $xml, ( $sx1 + 1 ), ( $sx2 - $sx1 - 1 ));
|
882 |
|
|
$endIx = $sx2 + 1;
|
883 |
|
|
if( FALSE === substr( $xml, $sx2, 1 )) {
|
884 |
|
|
return '';
|
885 |
|
|
}
|
886 |
|
|
$strlen = strlen( $tagName );
|
887 |
|
|
if(( 'duration' == $tagName ) &&
|
888 |
|
|
( FALSE !== ( $pos1 = stripos( $xml, "<duration>", $sx1+1 ))) &&
|
889 |
|
|
( FALSE !== ( $pos2 = stripos( $xml, "</duration>", $pos1+1 ))) &&
|
890 |
|
|
( FALSE !== ( $pos3 = stripos( $xml, "</duration>", $pos2+1 ))) &&
|
891 |
|
|
( $pos1 < $pos2 ) && ( $pos2 < $pos3 ))
|
892 |
|
|
$pos = $pos3;
|
893 |
|
|
elseif( FALSE === ( $pos = stripos( $xml, "</$tagName>", $sx2 )))
|
894 |
|
|
return '';
|
895 |
|
|
$endIx = $pos + $strlen + 3;
|
896 |
|
|
return substr( $xml, ( $sx1 + $strlen + 2 ), ( $pos - $strlen - 2 ));
|
897 |
|
|
} |