1
|
|
|
<?php |
2
|
|
|
/*********************************************************************************/ |
3
|
|
|
/** |
4
|
|
|
* iCalcreator class v2.6 |
5
|
|
|
* copyright (c) 2007-2008 Kjell-Inge Gustafsson kigkonsult |
6
|
|
|
* www.kigkonsult.se/iCalcreator/index.php |
7
|
|
|
* [email protected] |
8
|
|
|
* |
9
|
|
|
* Description: |
10
|
|
|
* This file is a PHP implementation of RFC 2445. |
11
|
|
|
* |
12
|
|
|
* This library is free software; you can redistribute it and/or |
13
|
|
|
* modify it under the terms of the GNU Lesser General Public |
14
|
|
|
* License as published by the Free Software Foundation; either |
15
|
|
|
* version 2.1 of the License, or (at your option) any later version. |
16
|
|
|
* |
17
|
|
|
* This library is distributed in the hope that it will be useful, |
18
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
19
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
20
|
|
|
* Lesser General Public License for more details. |
21
|
|
|
* |
22
|
|
|
* You should have received a copy of the GNU Lesser General Public |
23
|
|
|
* License along with this library; if not, write to the Free Software |
24
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
25
|
|
|
*/ |
26
|
|
|
/*********************************************************************************/ |
27
|
|
|
/*********************************************************************************/ |
28
|
|
|
/* A little setup */ |
29
|
|
|
/*********************************************************************************/ |
30
|
|
|
/* your local language code */ |
31
|
|
|
// define( 'ICAL_LANG', 'sv' ); |
32
|
|
|
// alt. autosetting |
33
|
|
|
/* |
34
|
|
|
$langstr = $_SERVER['HTTP_ACCEPT_LANGUAGE']; |
35
|
|
|
$pos = strpos( $langstr, ';' ); |
36
|
|
|
if ($pos !== false) { |
37
|
|
|
$langstr = substr( $langstr, 0, $pos ); |
38
|
|
|
$pos = strpos( $langstr, ',' ); |
39
|
|
|
if ($pos !== false) { |
40
|
|
|
$pos = strpos( $langstr, ',' ); |
41
|
|
|
$langstr = substr( $langstr, 0, $pos ); |
42
|
|
|
} |
43
|
|
|
define( 'ICAL_LANG', $langstr ); |
44
|
|
|
} |
45
|
|
|
*/ |
46
|
|
|
/* only for phpversion 5.x, date management, default timezone setting */ |
47
|
|
|
if( substr( phpversion(), 0, 1) >= '5' ) // && ( 'UTC' == date_default_timezone_get() )) { |
48
|
|
|
date_default_timezone_set( 'Europe/Stockholm' ); |
49
|
|
|
/* version string, do NOT remove!! */ |
50
|
|
|
define( 'ICALCREATOR_VERSION', 'iCalcreator 2.6' ); |
51
|
|
|
/*********************************************************************************/ |
52
|
|
|
/*********************************************************************************/ |
53
|
|
|
/** |
54
|
|
|
* vcalendar class |
55
|
|
|
* |
56
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
57
|
|
|
* @since 2.2.13 - 2007-12-30 |
58
|
|
|
*/ |
59
|
|
|
class vcalendar { |
60
|
|
|
// calendar property variables |
61
|
|
|
var $calscale; |
62
|
|
|
var $method; |
63
|
|
|
var $prodid; |
64
|
|
|
var $version; |
65
|
|
|
var $xprop; |
66
|
|
|
// container for calendar components |
67
|
|
|
var $components; |
68
|
|
|
// component config variables |
69
|
|
|
var $allowEmpty; |
70
|
|
|
var $unique_id; |
71
|
|
|
var $language; |
72
|
|
|
var $directory; |
73
|
|
|
var $filename; |
74
|
|
|
var $url; |
75
|
|
|
var $delimiter; |
76
|
|
|
var $nl; |
77
|
|
|
var $format; |
78
|
|
|
// component internal variables |
79
|
|
|
var $attributeDelimiter; |
80
|
|
|
var $valueInit; |
81
|
|
|
// component xCal declaration container |
82
|
|
|
var $xcaldecl; |
83
|
|
|
/* |
84
|
|
|
* constructor for calendar object |
85
|
|
|
* |
86
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
87
|
|
|
* @since 2.2.13 - 2007-12-30 |
88
|
|
|
* @return void |
|
|
|
|
89
|
|
|
*/ |
90
|
|
|
function __construct() { |
91
|
|
|
$this->_makeVersion(); |
92
|
|
|
$this->calscale = null; |
93
|
|
|
$this->method = null; |
94
|
|
|
$this->_makeUnique_id(); |
95
|
|
|
$this->prodid = null; |
96
|
|
|
$this->xprop = array(); |
97
|
|
|
/** |
98
|
|
|
* language = <Text identifying a language, as defined in [RFC 1766]> |
99
|
|
|
*/ |
100
|
|
|
if( defined( 'ICAL_LANG' )) |
101
|
|
|
$this->setConfig( 'language', ICAL_LANG ); |
102
|
|
|
$this->setConfig( 'allowEmpty', TRUE ); |
103
|
|
|
$this->setConfig( 'nl', "\n" ); |
104
|
|
|
$this->setConfig( 'format', 'iCal'); |
105
|
|
|
$this->directory = null; |
106
|
|
|
$this->filename = null; |
107
|
|
|
$this->url = null; |
108
|
|
|
$this->setConfig( 'delimiter', DIRECTORY_SEPARATOR ); |
109
|
|
|
$this->xcaldecl = array(); |
110
|
|
|
$this->components = array(); |
111
|
|
|
} |
112
|
|
|
/*********************************************************************************/ |
113
|
|
|
/** |
114
|
|
|
* Property Name: CALSCALE |
115
|
|
|
*/ |
116
|
|
|
/** |
117
|
|
|
* creates formatted output for calendar property calscale |
118
|
|
|
* |
119
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
120
|
|
|
* @since 2.4.8 - 2008-10-21 |
121
|
|
|
* @return string |
122
|
|
|
*/ |
123
|
|
View Code Duplication |
function createCalscale() { |
124
|
|
|
if( empty( $this->calscale )) return FALSE; |
125
|
|
|
switch( $this->format ) { |
126
|
|
|
case 'xcal': |
127
|
|
|
return ' calscale="'.$this->calscale.'"'.$this->nl; |
128
|
|
|
break; |
129
|
|
|
default: |
130
|
|
|
return 'CALSCALE:'.$this->calscale.$this->nl; |
131
|
|
|
break; |
132
|
|
|
} |
133
|
|
|
} |
134
|
|
|
/** |
135
|
|
|
* set calendar property calscale |
136
|
|
|
* |
137
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
138
|
|
|
* @since 2.4.8 - 2008-10-21 |
139
|
|
|
* @param string $value |
140
|
|
|
* @return void |
141
|
|
|
*/ |
142
|
|
|
function setCalscale( $value ) { |
143
|
|
|
if( empty( $value )) return FALSE; |
144
|
|
|
$this->calscale = $value; |
145
|
|
|
} |
146
|
|
|
/*********************************************************************************/ |
147
|
|
|
/** |
148
|
|
|
* Property Name: METHOD |
149
|
|
|
*/ |
150
|
|
|
/** |
151
|
|
|
* creates formatted output for calendar property method |
152
|
|
|
* |
153
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
154
|
|
|
* @since 0.9.7 - 2006-11-20 |
155
|
|
|
* @return string |
156
|
|
|
*/ |
157
|
|
View Code Duplication |
function createMethod() { |
158
|
|
|
if( empty( $this->method )) return FALSE; |
159
|
|
|
switch( $this->format ) { |
160
|
|
|
case 'xcal': |
161
|
|
|
return ' method="'.$this->method.'"'.$this->nl; |
162
|
|
|
break; |
163
|
|
|
default: |
164
|
|
|
return 'METHOD:'.$this->method.$this->nl; |
165
|
|
|
break; |
166
|
|
|
} |
167
|
|
|
} |
168
|
|
|
/** |
169
|
|
|
* set calendar property method |
170
|
|
|
* |
171
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
172
|
|
|
* @since 2.4.8 - 2008-20-23 |
173
|
|
|
* @param string $value |
174
|
|
|
* @return bool |
175
|
|
|
*/ |
176
|
|
|
function setMethod( $value ) { |
177
|
|
|
if( empty( $value )) return FALSE; |
178
|
|
|
$this->method = $value; |
179
|
|
|
return TRUE; |
180
|
|
|
} |
181
|
|
|
/*********************************************************************************/ |
182
|
|
|
/** |
183
|
|
|
* Property Name: PRODID |
184
|
|
|
* |
185
|
|
|
* The identifier is RECOMMENDED to be the identical syntax to the |
186
|
|
|
* [RFC 822] addr-spec. A good method to assure uniqueness is to put the |
187
|
|
|
* domain name or a domain literal IP address of the host on which.. . |
188
|
|
|
*/ |
189
|
|
|
/** |
190
|
|
|
* creates formatted output for calendar property prodid |
191
|
|
|
* |
192
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
193
|
|
|
* @since 0.9.7 - 2006-11-20 |
194
|
|
|
* @return string |
195
|
|
|
*/ |
196
|
|
|
function createProdid() { |
197
|
|
|
if( !isset( $this->prodid )) |
198
|
|
|
$this->_makeProdid(); |
199
|
|
|
switch( $this->format ) { |
200
|
|
|
case 'xcal': |
201
|
|
|
return ' prodid="'.$this->prodid.'"'.$this->nl; |
202
|
|
|
break; |
203
|
|
|
default: |
204
|
|
|
return 'PRODID:'.$this->prodid.$this->nl; |
205
|
|
|
break; |
206
|
|
|
} |
207
|
|
|
} |
208
|
|
|
/** |
209
|
|
|
* make default value for calendar prodid |
210
|
|
|
* |
211
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
212
|
|
|
* @since 0.3.0 - 2006-08-10 |
213
|
|
|
* @return void |
214
|
|
|
*/ |
215
|
|
|
function _makeProdid() { |
216
|
|
|
$this->prodid = '-//'.$this->unique_id.'//NONSGML '.ICALCREATOR_VERSION.'//'.strtoupper( $this->language ); |
217
|
|
|
} |
218
|
|
|
/** |
219
|
|
|
* Conformance: The property MUST be specified once in an iCalendar object. |
220
|
|
|
* Description: The vendor of the implementation SHOULD assure that this |
221
|
|
|
* is a globally unique identifier; using some technique such as an FPI |
222
|
|
|
* value, as defined in [ISO 9070]. |
223
|
|
|
*/ |
224
|
|
|
/** |
225
|
|
|
* make default unique_id for calendar prodid |
226
|
|
|
* |
227
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
228
|
|
|
* @since 0.3.0 - 2006-08-10 |
229
|
|
|
* @return void |
230
|
|
|
*/ |
231
|
|
|
function _makeUnique_id() { |
232
|
|
|
$this->unique_id = ( isset( $_SERVER['SERVER_NAME'] )) ? gethostbyname( $_SERVER['SERVER_NAME'] ) : 'localhost'; |
233
|
|
|
} |
234
|
|
|
/*********************************************************************************/ |
235
|
|
|
/** |
236
|
|
|
* Property Name: VERSION |
237
|
|
|
* |
238
|
|
|
* Description: A value of "2.0" corresponds to this memo. |
239
|
|
|
*/ |
240
|
|
|
/** |
241
|
|
|
* creates formatted output for calendar property version |
242
|
|
|
|
243
|
|
|
* |
244
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
245
|
|
|
* @since 0.9.7 - 2006-11-20 |
246
|
|
|
* @return string |
247
|
|
|
*/ |
248
|
|
View Code Duplication |
function createVersion() { |
249
|
|
|
if( empty( $this->version )) |
250
|
|
|
$this->_makeVersion(); |
251
|
|
|
switch( $this->format ) { |
252
|
|
|
case 'xcal': |
253
|
|
|
return ' version="'.$this->version.'"'.$this->nl; |
254
|
|
|
break; |
255
|
|
|
default: |
256
|
|
|
return 'VERSION:'.$this->version.$this->nl; |
257
|
|
|
break; |
258
|
|
|
} |
259
|
|
|
} |
260
|
|
|
/** |
261
|
|
|
* set default calendar version |
262
|
|
|
* |
263
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
264
|
|
|
* @since 0.3.0 - 2006-08-10 |
265
|
|
|
* @return void |
266
|
|
|
*/ |
267
|
|
|
function _makeVersion() { |
268
|
|
|
$this->version = '2.0'; |
269
|
|
|
} |
270
|
|
|
/** |
271
|
|
|
* set calendar version |
272
|
|
|
* |
273
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
274
|
|
|
* @since 2.4.8 - 2008-10-23 |
275
|
|
|
* @param string $value |
276
|
|
|
* @return void |
277
|
|
|
*/ |
278
|
|
|
function setVersion( $value ) { |
279
|
|
|
if( empty( $value )) return FALSE; |
280
|
|
|
$this->version = $value; |
281
|
|
|
return TRUE; |
282
|
|
|
} |
283
|
|
|
/*********************************************************************************/ |
284
|
|
|
/** |
285
|
|
|
* Property Name: x-prop |
286
|
|
|
*/ |
287
|
|
|
/** |
288
|
|
|
* creates formatted output for calendar property x-prop, iCal format only |
289
|
|
|
* |
290
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
291
|
|
|
* @since 2.4.11 - 2008-11-03 |
292
|
|
|
* @return string |
293
|
|
|
*/ |
294
|
|
|
function createXprop() { |
295
|
|
|
if( 'xcal' == $this->format ) |
296
|
|
|
return false; |
297
|
|
|
if( 0 >= count( $this->xprop )) |
298
|
|
|
return; |
299
|
|
|
$output = null; |
300
|
|
|
$toolbox = new calendarComponent(); |
301
|
|
|
$toolbox->setConfig( 'language', $this->getConfig( 'language' )); |
302
|
|
|
$toolbox->setConfig( 'nl', $this->getConfig( 'nl' )); |
303
|
|
|
$toolbox->_createFormat( $this->getConfig( 'format' )); |
304
|
|
|
foreach( $this->xprop as $label => $xpropPart ) { |
305
|
|
|
if( empty( $xpropPart['value'] )) { |
306
|
|
|
$output .= $toolbox->_createElement( $label ); |
307
|
|
|
continue; |
308
|
|
|
} |
309
|
|
|
$attributes = $toolbox->_createParams( $xpropPart['params'], array( 'LANGUAGE' )); |
310
|
|
|
if( is_array( $xpropPart['value'] )) { |
311
|
|
|
foreach( $xpropPart['value'] as $pix => $theXpart ) |
312
|
|
|
$xpropPart['value'][$pix] = $toolbox->_strrep( $theXpart ); |
313
|
|
|
$xpropPart['value'] = implode( ',', $xpropPart['value'] ); |
314
|
|
|
} |
315
|
|
|
else |
316
|
|
|
$xpropPart['value'] = $toolbox->_strrep( $xpropPart['value'] ); |
317
|
|
|
$output .= $toolbox->_createElement( $label, $attributes, $xpropPart['value'] ); |
318
|
|
|
} |
319
|
|
|
return $output; |
320
|
|
|
} |
321
|
|
|
/** |
322
|
|
|
* set calendar property x-prop |
323
|
|
|
* |
324
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
325
|
|
|
* @since 2.4.11 - 2008-11-04 |
326
|
|
|
* @param string $label |
327
|
|
|
* @param string $value |
328
|
|
|
* @param array $params optional |
329
|
|
|
* @return bool |
330
|
|
|
*/ |
331
|
|
View Code Duplication |
function setXprop( $label, $value, $params=FALSE ) { |
332
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
333
|
|
|
if( empty( $label )) return FALSE; |
334
|
|
|
$xprop = array( 'value' => $value ); |
335
|
|
|
$toolbox = new calendarComponent(); |
336
|
|
|
$xprop['params'] = $toolbox->_setParams( $params ); |
|
|
|
|
337
|
|
|
if( !is_array( $this->xprop )) $this->xprop = array(); |
338
|
|
|
$this->xprop[strtoupper( $label )] = $xprop; |
339
|
|
|
return TRUE; |
340
|
|
|
} |
341
|
|
|
/*********************************************************************************/ |
342
|
|
|
/** |
343
|
|
|
* delete calendar property value |
344
|
|
|
* |
345
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
346
|
|
|
* @since 2.4.5 - 2008-11-14 |
347
|
|
|
* @param mixed $propName, bool FALSE => X-property |
|
|
|
|
348
|
|
|
* @param int @propix, optional, if specific property is wanted in case of multiply occurences |
349
|
|
|
* @return bool, if successfull delete |
|
|
|
|
350
|
|
|
*/ |
351
|
|
|
function deleteProperty( $propName, $propix=FALSE ) { |
352
|
|
|
$propName = ( $propName ) ? strtoupper( $propName ) : 'X-PROP'; |
353
|
|
|
if( !$propix ) |
354
|
|
|
$propix = ( isset( $this->propdelix[$propName] )) ? $this->propdelix[$propName] + 2 : 1; |
355
|
|
|
$this->propdelix[$propName] = --$propix; |
356
|
|
|
$return = FALSE; |
357
|
|
|
switch( $propName ) { |
358
|
|
View Code Duplication |
case 'CALSCALE': |
359
|
|
|
if( isset( $this->calscale )) { |
360
|
|
|
$this->calscale = null; |
361
|
|
|
$return = TRUE; |
362
|
|
|
} |
363
|
|
|
break; |
364
|
|
View Code Duplication |
case 'METHOD': |
365
|
|
|
if( isset( $this->method )) { |
366
|
|
|
$this->method = null; |
367
|
|
|
$return = TRUE; |
368
|
|
|
} |
369
|
|
|
break; |
370
|
|
View Code Duplication |
default: |
371
|
|
|
$reduced = array(); |
372
|
|
|
if( $propName != 'X-PROP' ) { |
373
|
|
|
if( !isset( $this->xprop[$propName] )) return FALSE; |
374
|
|
|
foreach( $this->xprop as $k => $a ) { |
375
|
|
|
if(( $k != $propName ) && !empty( $a )) |
376
|
|
|
$reduced[$k] = $a; |
377
|
|
|
} |
378
|
|
|
} |
379
|
|
|
else { |
380
|
|
|
if( count( $this->xprop ) <= $propix ) return FALSE; |
381
|
|
|
$xpropno = 0; |
382
|
|
|
foreach( $this->xprop as $xpropkey => $xpropvalue ) { |
383
|
|
|
if( $propix != $xpropno ) |
384
|
|
|
$reduced[$xpropkey] = $xpropvalue; |
385
|
|
|
$xpropno++; |
386
|
|
|
} |
387
|
|
|
} |
388
|
|
|
$this->xprop = $reduced; |
389
|
|
|
return TRUE; |
390
|
|
|
} |
391
|
|
|
return $return; |
392
|
|
|
} |
393
|
|
|
/** |
394
|
|
|
* get calendar property value/params |
395
|
|
|
* |
396
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
397
|
|
|
* @since 2.5.1 - 2008-11-02 |
398
|
|
|
* @param string $propName, optional |
|
|
|
|
399
|
|
|
* @param int @propix, optional, if specific property is wanted in case of multiply occurences |
400
|
|
|
* @param bool $inclParam=FALSE |
|
|
|
|
401
|
|
|
* @return mixed |
402
|
|
|
*/ |
403
|
|
|
function getProperty( $propName=FALSE, $propix=FALSE, $inclParam=FALSE ) { |
404
|
|
|
$propName = ( $propName ) ? strtoupper( $propName ) : 'X-PROP'; |
405
|
|
|
if( 'X-PROP' == $propName ) { |
406
|
|
|
if( !$propix ) |
407
|
|
|
$propix = ( isset( $this->propix[$propName] )) ? $this->propix[$propName] + 2 : 1; |
408
|
|
|
$this->propix[$propName] = --$propix; |
409
|
|
|
} |
410
|
|
|
switch( $propName ) { |
411
|
|
|
case 'CALSCALE': |
412
|
|
|
return ( !empty( $this->calscale )) ? $this->calscale : null; |
413
|
|
|
break; |
414
|
|
|
case 'METHOD': |
415
|
|
|
return ( !empty( $this->method )) ? $this->method : null; |
416
|
|
|
break; |
417
|
|
|
case 'PRODID': |
418
|
|
|
if( empty( $this->prodid )) |
419
|
|
|
$this->_makeProdid(); |
420
|
|
|
return $this->prodid; |
421
|
|
|
break; |
422
|
|
|
case 'VERSION': |
423
|
|
|
return ( !empty( $this->version )) ? $this->version : null; |
424
|
|
|
break; |
425
|
|
View Code Duplication |
default: |
426
|
|
|
if( $propName != 'X-PROP' ) { |
427
|
|
|
if( !isset( $this->xprop[$propName] )) return FALSE; |
428
|
|
|
return ( $inclParam ) ? array( $propName, $this->xprop[$propName] ) |
429
|
|
|
: array( $propName, $this->xprop[$propName]['value'] ); |
430
|
|
|
} |
431
|
|
|
else { |
432
|
|
|
if( empty( $this->xprop )) return FALSE; |
433
|
|
|
$xpropno = 0; |
434
|
|
|
foreach( $this->xprop as $xpropkey => $xpropvalue ) { |
435
|
|
|
if( $propix == $xpropno ) |
436
|
|
|
return ( $inclParam ) ? array( $xpropkey, $this->xprop[$xpropkey] ) |
437
|
|
|
: array( $xpropkey, $this->xprop[$xpropkey]['value'] ); |
438
|
|
|
else |
439
|
|
|
$xpropno++; |
440
|
|
|
} |
441
|
|
|
return FALSE; // not found ?? |
442
|
|
|
} |
443
|
|
|
} |
444
|
|
|
return FALSE; |
445
|
|
|
} |
446
|
|
|
/** |
447
|
|
|
* general vcalendar property setting |
448
|
|
|
* |
449
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
450
|
|
|
* @since 2.2.13 - 2007-11-04 |
451
|
|
|
* @param mixed $args variable number of function arguments, |
|
|
|
|
452
|
|
|
* first argument is ALWAYS component name, |
453
|
|
|
* second ALWAYS component value! |
454
|
|
|
* @return bool |
455
|
|
|
*/ |
456
|
|
|
function setProperty () { |
457
|
|
|
$numargs = func_num_args(); |
458
|
|
|
if( 1 > $numargs ) |
459
|
|
|
return FALSE; |
460
|
|
|
$arglist = func_get_args(); |
461
|
|
|
$arglist[0] = strtoupper( $arglist[0] ); |
462
|
|
|
switch( $arglist[0] ) { |
463
|
|
|
case 'CALSCALE': |
464
|
|
|
return $this->setCalscale( $arglist[1] ); |
465
|
|
|
case 'METHOD': |
466
|
|
|
return $this->setMethod( $arglist[1] ); |
467
|
|
|
case 'VERSION': |
468
|
|
|
return $this->setVersion( $arglist[1] ); |
469
|
|
|
default: |
470
|
|
|
if( !isset( $arglist[1] )) $arglist[1] = null; |
471
|
|
|
if( !isset( $arglist[2] )) $arglist[2] = null; |
472
|
|
|
return $this->setXprop( $arglist[0], $arglist[1], $arglist[2] ); |
473
|
|
|
} |
474
|
|
|
return FALSE; |
|
|
|
|
475
|
|
|
} |
476
|
|
|
/*********************************************************************************/ |
477
|
|
|
/** |
478
|
|
|
* get vcalendar config values or * calendar components |
479
|
|
|
* |
480
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
481
|
|
|
* @since 2.4.10 - 2008-10-23 |
482
|
|
|
* @param string $config |
483
|
|
|
* @return value |
484
|
|
|
*/ |
485
|
|
|
function getConfig( $config ) { |
486
|
|
|
switch( strtoupper( $config )) { |
487
|
|
|
case 'ALLOWEMPTY': |
488
|
|
|
return $this->allowEmpty; |
489
|
|
|
break; |
490
|
|
View Code Duplication |
case 'COMPSINFO': |
491
|
|
|
unset( $this->compix ); |
492
|
|
|
$info = array(); |
493
|
|
|
foreach( $this->components as $cix => $component ) { |
494
|
|
|
if( empty( $component )) continue; |
495
|
|
|
unset( $component->propix ); |
496
|
|
|
$info[$cix]['ordno'] = $cix + 1; |
497
|
|
|
$info[$cix]['type'] = $component->objName; |
498
|
|
|
$info[$cix]['uid'] = $component->getProperty( 'uid' ); |
499
|
|
|
$info[$cix]['props'] = $component->getConfig( 'propinfo' ); |
500
|
|
|
$info[$cix]['sub'] = $component->getConfig( 'compsinfo' ); |
501
|
|
|
unset( $component->propix ); |
502
|
|
|
} |
503
|
|
|
return $info; |
504
|
|
|
break; |
505
|
|
|
case 'DELIMITER': |
506
|
|
|
return $this->delimiter; |
507
|
|
|
break; |
508
|
|
|
case 'DIRECTORY': |
509
|
|
|
if( empty( $this->directory )) |
510
|
|
|
$this->directory = '.'; |
511
|
|
|
return $this->directory; |
512
|
|
|
break; |
513
|
|
|
case 'DIRFILE': |
514
|
|
|
return $this->getConfig( 'directory' ).$this->getConfig( 'delimiter' ).$this->getConfig( 'filename' ); |
515
|
|
|
break; |
516
|
|
|
case 'FILEINFO': |
517
|
|
|
return array( $this->getConfig( 'directory' ) |
518
|
|
|
, $this->getConfig( 'filename' ) |
519
|
|
|
, $this->getConfig( 'filesize' )); |
520
|
|
|
break; |
521
|
|
|
case 'FILENAME': |
522
|
|
|
if( empty( $this->filename )) { |
523
|
|
|
if( 'xcal' == $this->format ) |
524
|
|
|
$this->filename = date( 'YmdHis' ).'.xml'; // recommended xcs.. . |
525
|
|
|
else |
526
|
|
|
$this->filename = date( 'YmdHis' ).'.ics'; |
527
|
|
|
} |
528
|
|
|
return $this->filename; |
529
|
|
|
break; |
530
|
|
|
case 'FILESIZE': |
531
|
|
|
$size = 0; |
532
|
|
|
if( empty( $this->url )) { |
533
|
|
|
$dirfile = $this->getConfig( 'dirfile' ); |
534
|
|
|
if( FALSE === ( $size = filesize( $dirfile ))) |
535
|
|
|
$size = 0; |
536
|
|
|
clearstatcache(); |
537
|
|
|
} |
538
|
|
|
return $size; |
539
|
|
|
break; |
540
|
|
|
case 'FORMAT': |
541
|
|
|
return $this->format; |
542
|
|
|
break; |
543
|
|
|
case 'LANGUAGE': |
544
|
|
|
/* get language for calendar component as defined in [RFC 1766] */ |
545
|
|
|
return $this->language; |
546
|
|
|
break; |
547
|
|
|
case 'NL': |
548
|
|
|
case 'NEWLINECHAR': |
549
|
|
|
return $this->nl; |
550
|
|
|
break; |
551
|
|
|
case 'UNIQUE_ID': |
552
|
|
|
return $this->unique_id; |
553
|
|
|
break; |
554
|
|
|
case 'URL': |
555
|
|
|
if( !empty( $this->url )) |
556
|
|
|
return $this->url; |
557
|
|
|
else |
558
|
|
|
return FALSE; |
559
|
|
|
break; |
|
|
|
|
560
|
|
|
} |
561
|
|
|
} |
562
|
|
|
/** |
563
|
|
|
* general vcalendar config setting |
564
|
|
|
* |
565
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
566
|
|
|
* @since 2.4.8 - 2008-10-24 |
567
|
|
|
* @param string $config |
568
|
|
|
* @param string $value |
569
|
|
|
* @return void |
570
|
|
|
*/ |
571
|
|
|
function setConfig( $config, $value ) { |
572
|
|
|
$res = FALSE; |
573
|
|
|
switch( strtoupper( $config )) { |
574
|
|
View Code Duplication |
case 'ALLOWEMPTY': |
575
|
|
|
$this->allowEmpty = $value; |
576
|
|
|
$subcfg = array( 'ALLOWEMPTY' => $value ); |
577
|
|
|
$res = TRUE; |
578
|
|
|
break; |
579
|
|
|
case 'DELIMITER': |
580
|
|
|
$this->delimiter = $value; |
581
|
|
|
return TRUE; |
582
|
|
|
break; |
583
|
|
|
case 'DIRECTORY': |
584
|
|
|
$value = trim( $value ); |
585
|
|
|
$nl = $this->getConfig('delimiter'); |
586
|
|
View Code Duplication |
if( $nl == substr( $value, ( 0 - strlen( $nl )))) |
587
|
|
|
$value = substr( $value, 0, ( strlen( $value ) - strlen( $nl ))); |
588
|
|
|
if( is_dir( $value )) { |
589
|
|
|
/* local directory */ |
590
|
|
|
clearstatcache(); |
591
|
|
|
$this->directory = $value; |
592
|
|
|
$this->url = null; |
593
|
|
|
return TRUE; |
594
|
|
|
} |
595
|
|
|
else |
596
|
|
|
return FALSE; |
597
|
|
|
break; |
|
|
|
|
598
|
|
|
case 'FILENAME': |
599
|
|
|
$value = trim( $value ); |
600
|
|
|
if( !empty( $this->url )) { |
601
|
|
|
/* remote directory+file - URL */ |
602
|
|
|
$this->filename = $value; |
603
|
|
|
return TRUE; |
604
|
|
|
} |
605
|
|
|
$dirfile = $this->getConfig( 'directory' ).$this->getConfig( 'delimiter' ).$value; |
606
|
|
|
if( file_exists( $dirfile )) { |
607
|
|
|
/* local existing file */ |
608
|
|
|
if( is_readable( $dirfile ) || is_writable( $dirfile )) { |
609
|
|
|
clearstatcache(); |
610
|
|
|
$this->filename = $value; |
611
|
|
|
return TRUE; |
612
|
|
|
} |
613
|
|
|
else |
614
|
|
|
return FALSE; |
615
|
|
|
} |
616
|
|
|
elseif( FALSE !== touch( $dirfile )) { |
617
|
|
|
/* new local file created */ |
618
|
|
|
$this->filename = $value; |
619
|
|
|
return TRUE; |
620
|
|
|
} |
621
|
|
|
else |
622
|
|
|
return FALSE; |
623
|
|
|
break; |
|
|
|
|
624
|
|
|
case 'FORMAT': |
625
|
|
|
$value = trim( $value ); |
626
|
|
|
if( 'xcal' == strtolower( $value )) { |
627
|
|
|
$this->format = 'xcal'; |
628
|
|
|
$this->attributeDelimiter = $this->nl; |
629
|
|
|
$this->valueInit = null; |
630
|
|
|
} |
631
|
|
|
else { |
632
|
|
|
$this->format = null; |
633
|
|
|
$this->attributeDelimiter = ';'; |
634
|
|
|
$this->valueInit = ':'; |
635
|
|
|
} |
636
|
|
|
$subcfg = array( 'FORMAT' => $value ); |
637
|
|
|
$res = TRUE; |
638
|
|
|
break; |
639
|
|
View Code Duplication |
case 'LANGUAGE': |
640
|
|
|
// set language for calendar component as defined in [RFC 1766] |
641
|
|
|
$value = trim( $value ); |
642
|
|
|
$this->language = $value; |
643
|
|
|
$subcfg = array( 'LANGUAGE' => $value ); |
644
|
|
|
$res = TRUE; |
645
|
|
|
break; |
646
|
|
|
case 'NL': |
647
|
|
View Code Duplication |
case 'NEWLINECHAR': |
648
|
|
|
$this->nl = $value; |
649
|
|
|
$subcfg = array( 'NL' => $value ); |
650
|
|
|
$res = TRUE; |
651
|
|
|
break; |
652
|
|
View Code Duplication |
case 'UNIQUE_ID': |
653
|
|
|
$value = trim( $value ); |
654
|
|
|
$this->unique_id = $value; |
655
|
|
|
$subcfg = array( 'UNIQUE_ID' => $value ); |
656
|
|
|
$res = TRUE; |
657
|
|
|
break; |
658
|
|
|
case 'URL': |
659
|
|
|
/* remote file - URL */ |
660
|
|
|
$value = trim( $value ); |
661
|
|
|
$value = str_replace( 'HTTP://', 'http://', $value ); |
662
|
|
|
$value = str_replace( 'WEBCAL://', 'http://', $value ); |
663
|
|
|
$value = str_replace( 'webcal://', 'http://', $value ); |
664
|
|
|
$this->url = $value; |
665
|
|
|
$this->directory = null; |
666
|
|
|
$parts = pathinfo( $value ); |
667
|
|
|
return $this->setConfig( 'filename', $parts['basename'] ); |
668
|
|
|
break; |
669
|
|
|
} |
670
|
|
|
if( !$res ) return FALSE; |
671
|
|
View Code Duplication |
if( isset( $subcfg ) && !empty( $this->components )) { |
672
|
|
|
foreach( $subcfg as $cfgkey => $cfgvalue ) { |
673
|
|
|
foreach( $this->components as $cix => $component ) { |
674
|
|
|
$res = $component->setConfig( $cfgkey, $cfgvalue ); |
675
|
|
|
if( !$res ) |
676
|
|
|
break 2; |
677
|
|
|
$this->components[$cix] = $component->copy(); // PHP4 compliant |
678
|
|
|
} |
679
|
|
|
} |
680
|
|
|
} |
681
|
|
|
return $res; |
682
|
|
|
} |
683
|
|
|
/*********************************************************************************/ |
684
|
|
|
/** |
685
|
|
|
* add calendar component to container |
686
|
|
|
* |
687
|
|
|
* alias to setComponent |
688
|
|
|
* |
689
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
690
|
|
|
* @since 1.x.x - 2007-04-24 |
691
|
|
|
* @param object $component calendar component |
692
|
|
|
* @return void |
693
|
|
|
*/ |
694
|
|
|
function addComponent( $component ) { |
695
|
|
|
$this->setComponent( $component ); |
696
|
|
|
} |
697
|
|
|
/** |
698
|
|
|
* delete calendar component from container |
699
|
|
|
* |
700
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
701
|
|
|
* @since 2.4.10 - 2008-08-05 |
702
|
|
|
* @param mixed $arg1 ordno / component type / component uid |
703
|
|
|
* @param mixed $arg2 optional, ordno if arg1 = component type |
704
|
|
|
* @return void |
705
|
|
|
*/ |
706
|
|
View Code Duplication |
function deleteComponent( $arg1, $arg2=FALSE ) { |
707
|
|
|
$argType = $index = null; |
708
|
|
|
if ( ctype_digit( (string) $arg1 )) { |
709
|
|
|
$argType = 'INDEX'; |
710
|
|
|
$index = (int) $arg1 - 1; |
711
|
|
|
} |
712
|
|
|
elseif(( strlen( $arg1 ) <= strlen( 'vfreebusy' )) && ( FALSE === strpos( $arg1, '@' ))) { |
713
|
|
|
$argType = strtolower( $arg1 ); |
714
|
|
|
$index = ( !empty( $arg2 ) && ctype_digit( (string) $arg2 )) ? (( int ) $arg2 - 1 ) : 0; |
715
|
|
|
} |
716
|
|
|
$cix1dC = 0; |
717
|
|
|
foreach ( $this->components as $cix => $component) { |
718
|
|
|
if( empty( $component )) continue; |
719
|
|
|
unset( $component->propix ); |
720
|
|
|
if(( 'INDEX' == $argType ) && ( $index == $cix )) { |
721
|
|
|
unset( $this->components[$cix] ); |
722
|
|
|
return TRUE; |
723
|
|
|
} |
724
|
|
|
elseif( $argType == $component->objName ) { |
725
|
|
|
if( $index == $cix1dC ) { |
726
|
|
|
unset( $this->components[$cix] ); |
727
|
|
|
return TRUE; |
728
|
|
|
} |
729
|
|
|
$cix1dC++; |
730
|
|
|
} |
731
|
|
|
elseif( !$argType && ($arg1 == $component->getProperty( 'uid' ))) { |
732
|
|
|
unset( $this->components[$cix] ); |
733
|
|
|
return TRUE; |
734
|
|
|
} |
735
|
|
|
} |
736
|
|
|
return FALSE; |
737
|
|
|
} |
738
|
|
|
/** |
739
|
|
|
* get calendar component from container |
740
|
|
|
* |
741
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
742
|
|
|
* @since 2.4.10 - 2008-08-06 |
743
|
|
|
* @param mixed $arg1 optional, ordno/component type/ component uid |
744
|
|
|
* @param mixed $arg2 optional, ordno if arg1 = component type |
745
|
|
|
* @return object |
746
|
|
|
*/ |
747
|
|
View Code Duplication |
function getComponent( $arg1=FALSE, $arg2=FALSE ) { |
748
|
|
|
$index = $argType = null; |
749
|
|
|
if ( !$arg1 ) { |
750
|
|
|
$argType = 'INDEX'; |
751
|
|
|
$index = $this->compix['INDEX'] = |
752
|
|
|
( isset( $this->compix['INDEX'] )) ? $this->compix['INDEX'] + 1 : 1; |
753
|
|
|
} |
754
|
|
|
elseif ( ctype_digit( (string) $arg1 )) { |
755
|
|
|
$argType = 'INDEX'; |
756
|
|
|
$index = (int) $arg1; |
757
|
|
|
unset( $this->compix ); |
758
|
|
|
} |
759
|
|
|
elseif(( strlen( $arg1 ) <= strlen( 'vfreebusy' )) && ( FALSE === strpos( $arg1, '@' ))) { |
760
|
|
|
unset( $this->compix['INDEX'] ); |
761
|
|
|
$argType = strtolower( $arg1 ); |
762
|
|
|
if( !$arg2 ) |
763
|
|
|
$index = $this->compix[$argType] = |
764
|
|
|
( isset( $this->compix[$argType] )) ? $this->compix[$argType] + 1 : 1; |
765
|
|
|
else |
766
|
|
|
$index = (int) $arg2; |
767
|
|
|
} |
768
|
|
|
$index -= 1; |
769
|
|
|
$ckeys = array_keys( $this->components ); |
770
|
|
|
if( !empty( $index) && ( $index > end( $ckeys ))) |
771
|
|
|
return FALSE; |
772
|
|
|
$cix1gC = 0; |
773
|
|
|
foreach ( $this->components as $cix => $component) { |
774
|
|
|
if( empty( $component )) continue; |
775
|
|
|
unset( $component->propix ); |
776
|
|
|
if(( 'INDEX' == $argType ) && ( $index == $cix )) |
777
|
|
|
return $component->copy(); |
778
|
|
|
elseif( $argType == $component->objName ) { |
779
|
|
|
if( $index == $cix1gC ) |
780
|
|
|
return $component->copy(); |
781
|
|
|
$cix1gC++; |
782
|
|
|
} |
783
|
|
|
elseif( !$argType && ($arg1 == $component->getProperty( 'uid' ))) { |
784
|
|
|
unset( $component->propix ); |
785
|
|
|
return $component->copy(); |
786
|
|
|
} |
787
|
|
|
} |
788
|
|
|
/* not found.. . */ |
789
|
|
|
unset( $this->compix ); |
790
|
|
|
return FALSE; |
791
|
|
|
} |
792
|
|
|
/** |
793
|
|
|
* select components from calendar on date basis |
794
|
|
|
* |
795
|
|
|
* Ensure DTSTART is set for every component. |
796
|
|
|
* No date controls occurs. |
797
|
|
|
* |
798
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
799
|
|
|
* @since 2.4.16 - 2008-10-18 |
800
|
|
|
* @param int $startY optional, start Year, default current Year |
801
|
|
|
* @param int $startM optional, start Month, default current Month |
802
|
|
|
* @param int $startD optional, start Day, default current Day |
803
|
|
|
* @param int $endY optional, end Year, default $startY |
804
|
|
|
* @param int $endY optional, end Month, default $startM |
805
|
|
|
* @param int $endY optional, end Day, default $startD |
806
|
|
|
* @param mixed $cType optional, calendar component type(-s), default FALSE=all else string/array type(-s) |
807
|
|
|
* @param bool $flat optional, FALSE (default) => output : array[Year][Month][Day][] |
808
|
|
|
* TRUE => output : array[] (ignores split) |
809
|
|
|
* @param bool $any optional, TRUE (default) - select component that take place within period |
810
|
|
|
* FALSE - only components that starts within period |
811
|
|
|
* @param bool $split optional, TRUE (default) - one component copy every day it take place during the |
812
|
|
|
* period (implies flat=FALSE) |
813
|
|
|
* FALSE - one occurance of component only in output array</tr> |
814
|
|
|
* @return array or FALSE |
815
|
|
|
*/ |
816
|
|
|
function selectComponents( $startY=FALSE, $startM=FALSE, $startD=FALSE, $endY=FALSE, $endM=FALSE, $endD=FALSE, $cType=FALSE, $flat=FALSE, $any=TRUE, $split=TRUE ) { |
817
|
|
|
/* check if empty calendar */ |
818
|
|
|
if( 0 >= count( $this->components )) return FALSE; |
819
|
|
|
/* check default dates */ |
820
|
|
|
if( !$startY ) $startY = date( 'Y' ); |
|
|
|
|
821
|
|
|
if( !$startM ) $startM = date( 'm' ); |
|
|
|
|
822
|
|
|
if( !$startD ) $startD = date( 'd' ); |
|
|
|
|
823
|
|
|
$startDate = mktime( 0, 0, 0, $startM, $startD, $startY ); |
824
|
|
|
if( !$endY ) $endY = $startY; |
|
|
|
|
825
|
|
|
if( !$endM ) $endM = $startM; |
826
|
|
|
if( !$endD ) $endD = $startD; |
827
|
|
|
$endDate = mktime( 23, 59, 59, $endM, $endD, $endY ); |
828
|
|
|
/* check component types */ |
829
|
|
|
$validTypes = array('vevent', 'vtodo', 'vjournal', 'vfreebusy' ); |
830
|
|
|
if( is_array( $cType )) { |
831
|
|
|
foreach( $cType as $cix => $theType ) { |
832
|
|
|
$cType[$cix] = $theType = strtolower( $theType ); |
833
|
|
|
if( !in_array( $theType, $validTypes )) |
834
|
|
|
$cType[$cix] = 'vevent'; |
835
|
|
|
} |
836
|
|
|
$cType = array_unique( $cType ); |
837
|
|
|
} |
838
|
|
|
elseif( !empty( $cType )) { |
839
|
|
|
$cType = strtolower( $cType ); |
840
|
|
|
if( !in_array( $cType, $validTypes )) |
841
|
|
|
$cType = array( 'vevent' ); |
842
|
|
|
else |
843
|
|
|
$cType = array( $cType ); |
844
|
|
|
} |
845
|
|
|
else |
846
|
|
|
$cType = $validTypes; |
847
|
|
|
if( 0 >= count( $cType )) |
848
|
|
|
$cType = $validTypes; |
849
|
|
|
/* iterate components */ |
850
|
|
|
$result = array(); |
851
|
|
|
foreach ( $this->components as $cix => $component ) { |
852
|
|
|
if( empty( $component )) continue; |
853
|
|
|
unset( $component->propix, $start ); |
854
|
|
|
/* deselect unvalid type components */ |
855
|
|
|
if( !in_array( $component->objName, $cType )) continue; |
856
|
|
|
/* deselect components without dtstart set */ |
857
|
|
|
if( FALSE === ( $start = $component->getProperty( 'dtstart' ))) continue; |
858
|
|
|
$dtendExist = $dueExist = $durationExist = $endAllDayEvent = FALSE; |
859
|
|
|
unset( $end, $startWdate, $endWdate, $rdurWsecs, $rdur, $exdatelist, $workstart, $workend ); // clean up |
860
|
|
|
$startWdate = $component->_date2timestamp( $start ); |
861
|
|
|
$startDateFormat = ( isset( $start['hour'] )) ? 'Y-m-d H:i:s' : 'Y-m-d'; |
862
|
|
|
/* get end date from dtend/due/duration properties */ |
863
|
|
|
$end = $component->getProperty( 'dtend' ); |
864
|
|
View Code Duplication |
if( !empty( $end )) { |
865
|
|
|
$dtendExist = TRUE; |
866
|
|
|
$endDateFormat = ( isset( $end['hour'] )) ? 'Y-m-d H:i:s' : 'Y-m-d'; |
867
|
|
|
} |
868
|
|
|
// if( !empty($end)) echo 'selectComp 1 start='.implode('-',$start).' end='.implode('-',$end)."<br />\n"; // test ### |
869
|
|
|
if( empty($end) && ( $component->objName == 'vtodo' )) { |
870
|
|
|
$end = $component->getProperty( 'due' ); |
871
|
|
View Code Duplication |
if( !empty( $end )) { |
872
|
|
|
$dueExist = TRUE; |
873
|
|
|
$endDateFormat = ( isset( $end['hour'] )) ? 'Y-m-d H:i:s' : 'Y-m-d'; |
874
|
|
|
} |
875
|
|
|
// if( !empty($end)) echo 'selectComp 2 start='.implode('-',$start).' end='.implode('-',$end)."<br />\n"; // test ### |
876
|
|
|
} |
877
|
|
|
if( !empty( $end ) && !isset( $end['hour'] )) { |
878
|
|
|
/* a DTEND without time part regards an event that ends the day before, |
879
|
|
|
for an all-day event DTSTART=20071201 DTEND=20071202 (taking place 20071201!!! */ |
880
|
|
|
$endAllDayEvent = TRUE; |
881
|
|
|
$endWdate = mktime( 23, 59, 59, $end['month'], ($end['day'] - 1), $end['year'] ); |
882
|
|
|
$end['year'] = date( 'Y', $endWdate ); |
883
|
|
|
$end['month'] = date( 'm', $endWdate ); |
884
|
|
|
$end['day'] = date( 'd', $endWdate ); |
885
|
|
|
$end['hour'] = 23; |
886
|
|
|
$end['min'] = $end['sec'] = 59; |
887
|
|
|
// if( !empty($end)) echo 'selectComp 3 start='.implode('-',$start).' end='.implode('-',$end)."<br />\n"; // test ### |
888
|
|
|
} |
889
|
|
|
if( empty( $end )) { |
890
|
|
|
$end = $component->getProperty( 'duration', FALSE, FALSE, TRUE );// in dtend (array) format |
891
|
|
|
if( !empty( $end )) |
892
|
|
|
$durationExist = TRUE; |
893
|
|
|
// if( !empty($end)) echo 'selectComp 4 start='.implode('-',$start).' end='.implode('-',$end)."<br />\n"; // test ### |
894
|
|
|
} |
895
|
|
|
if( empty( $end )) { // assume one day duration if missing end date |
896
|
|
|
$end = array( 'year' => $start['year'], 'month' => $start['month'], 'day' => $start['day'], 'hour' => 23, 'min' => 59, 'sec' => 59 ); |
897
|
|
|
// if( isset($end)) echo 'selectComp 5 start='.implode('-',$start).' end='.implode('-',$end)."<br />\n"; // test ### |
898
|
|
|
} |
899
|
|
|
$endWdate = $component->_date2timestamp( $end ); |
900
|
|
|
if( $endWdate < $startWdate ) { // MUST be after start date!! |
901
|
|
|
$end = array( 'year' => $start['year'], 'month' => $start['month'], 'day' => $start['day'], 'hour' => 23, 'min' => 59, 'sec' => 59 ); |
902
|
|
|
$endWdate = $component->_date2timestamp( $end ); |
903
|
|
|
} |
904
|
|
|
$rdurWsecs = $endWdate - $startWdate; // compute component duration in seconds |
905
|
|
|
$rdur = $component->_date2duration( $start, $end ); // compute component duration, array |
906
|
|
|
/* make a list of optional exclude dates for component occurence from exrule and exdate */ |
907
|
|
|
$exdatelist = array(); |
908
|
|
|
$workstart = $component->_timestamp2date(( $startDate - $rdurWsecs ), 6); |
909
|
|
|
$workend = $component->_timestamp2date(( $endDate + $rdurWsecs ), 6); |
910
|
|
|
while( FALSE !== ( $exrule = $component->getProperty( 'exrule' ))) // check exrule |
911
|
|
|
$component->_recur2date( $exdatelist, $exrule, $start, $workstart, $workend ); |
912
|
|
|
while( FALSE !== ( $exdate = $component->getProperty( 'exdate' ))) { // check exdate |
913
|
|
|
foreach( $exdate as $theExdate ) { |
914
|
|
|
$exWdate = $component->_date2timestamp( $theExdate ); |
915
|
|
|
if((( $startDate - $rdurWsecs ) <= $exWdate ) && ( $endDate >= $exWdate )) |
916
|
|
|
$exdatelist[$exWdate] = TRUE; |
917
|
|
|
} |
918
|
|
|
} |
919
|
|
|
/* if 'any' components, check repeating components, removing all excluding dates */ |
920
|
|
|
if( TRUE === $any ) { |
921
|
|
|
/* make a list of optional repeating dates for component occurence, rrule, rdate */ |
922
|
|
|
$recurlist = array(); |
923
|
|
|
while( FALSE !== ( $rrule = $component->getProperty( 'rrule' ))) // check rrule |
924
|
|
|
$component->_recur2date( $recurlist, $rrule, $start, $workstart, $workend ); |
925
|
|
|
foreach( $recurlist as $recurkey => $recurvalue ) // key=match date as timestamp |
926
|
|
|
$recurlist[$recurkey] = $rdurWsecs; // add duration in seconds |
927
|
|
|
while( FALSE !== ( $rdate = $component->getProperty( 'rdate' ))) { // check rdate |
928
|
|
|
foreach( $rdate as $theRdate ) { |
929
|
|
|
if( is_array( $theRdate ) && ( 2 == count( $theRdate )) && // all days within PERIOD |
930
|
|
|
array_key_exists( '0', $theRdate ) && array_key_exists( '1', $theRdate )) { |
931
|
|
|
$rstart = $component->_date2timestamp( $theRdate[0] ); |
932
|
|
|
if(( $rstart < ( $startDate - $rdurWsecs )) || ( $rstart > $endDate )) |
933
|
|
|
continue; |
934
|
|
|
if( isset( $theRdate[1]['year'] )) // date-date period |
935
|
|
|
$rend = $component->_date2timestamp( $theRdate[1] ); |
936
|
|
|
else { // date-duration period |
937
|
|
|
$rend = $component->duration2date( $theRdate[0], $theRdate[1] ); |
938
|
|
|
$rend = $component->_date2timestamp( $rend ); |
939
|
|
|
} |
940
|
|
|
if((( $startDate - $rdurWsecs ) <= $rstart ) && ( $endDate >= $rstart )) |
941
|
|
|
$recurlist[$rstart] = ( $rstart - $rend ); // set start date + rdate duration in seconds |
942
|
|
|
} // PERIOD end |
943
|
|
|
else { // single date |
944
|
|
|
$theRdate = $component->_date2timestamp( $theRdate ); |
945
|
|
|
if((( $startDate - $rdurWsecs ) <= $theRdate ) && ( $endDate >= $theRdate )) |
946
|
|
|
$recurlist[$theRdate] = $rdurWsecs; // set start date + event duration in seconds |
947
|
|
|
} |
948
|
|
|
} |
949
|
|
|
} |
950
|
|
|
if( 0 < count( $recurlist )) { |
951
|
|
|
ksort( $recurlist ); |
952
|
|
|
foreach( $recurlist as $recurkey => $durvalue ) { |
953
|
|
|
if((( $startDate - $rdurWsecs ) > $recurkey ) || ( $endDate < $recurkey )) // not within period |
954
|
|
|
continue; |
955
|
|
|
if( isset( $exdatelist[$recurkey] )) // check excluded dates |
956
|
|
|
continue; |
957
|
|
|
if( $startWdate >= $recurkey ) // exclude component start date |
958
|
|
|
continue; |
959
|
|
|
$component2 = $component->copy(); |
960
|
|
|
$rstart = $component2->_timestamp2date( $recurkey, 6); |
961
|
|
|
$datevalue = $rstart['month'].'/'.$rstart['day'].'/'.$rstart['year']; |
962
|
|
View Code Duplication |
if( isset( $start['hour'] ) || isset( $start['min'] ) || isset( $start['sec'] )) { |
963
|
|
|
$datevalue .= ( isset( $rstart['hour'] )) ? ' '.$rstart['hour'] : ' 00'; |
964
|
|
|
$datevalue .= ( isset( $rstart['min'] )) ? ':'.$rstart['min'] : ':00'; |
965
|
|
|
$datevalue .= ( isset( $rstart['sec'] )) ? ':'.$rstart['sec'] : ':00'; |
966
|
|
|
} |
967
|
|
|
$datestring = date( $startDateFormat, strtotime( $datevalue )); |
968
|
|
|
if( isset( $start['tz'] )) |
969
|
|
|
$datestring .= ' '.$start['tz']; |
970
|
|
|
$component2->setProperty( 'X-CURRENT-DTSTART', $datestring ); |
971
|
|
|
$rend = $component2->_timestamp2date(( $recurkey + $durvalue ), 6); |
972
|
|
|
if( $dtendExist || $dueExist ) { |
973
|
|
|
if( $endAllDayEvent ) { |
974
|
|
|
$rend2 = mktime( 0, 0, 0, $rend['month'], ($rend['day'] + 1), $rend['year'] ); |
975
|
|
|
$datevalue = date( 'm', $rend2 ).'/'.date( 'd', $rend2 ).'/'.date( 'Y', $rend2 ); |
976
|
|
|
} |
977
|
|
|
else { |
978
|
|
|
$datevalue = $rend['month'].'/'.$rend['day'].'/'.$rend['year']; |
979
|
|
View Code Duplication |
if( isset( $end['hour'] ) || isset( $end['min'] ) || isset( $end['sec'] )) { |
980
|
|
|
$datevalue .= ( isset( $rend['hour'] )) ? ' '.$rend['hour'] : ' 00'; |
981
|
|
|
$datevalue .= ( isset( $rend['min'] )) ? ':'.$rend['min'] : ':00'; |
982
|
|
|
$datevalue .= ( isset( $rend['sec'] )) ? ':'.$rend['sec'] : ':00'; |
983
|
|
|
} |
984
|
|
|
} |
985
|
|
|
$datestring = date( $endDateFormat, strtotime( $datevalue )); |
986
|
|
|
if( isset( $end['tz'] )) |
987
|
|
|
$datestring .= ' '.$end['tz']; |
988
|
|
|
if( $dtendExist ) |
989
|
|
|
$component2->setProperty( 'X-CURRENT-DTEND', $datestring ); |
990
|
|
|
elseif( $dueExist ) |
991
|
|
|
$component2->setProperty( 'X-CURRENT-DUE', $datestring ); |
992
|
|
|
} |
993
|
|
|
$rend = $component2->_date2timestamp( $rend ); |
994
|
|
|
$rstart = $recurkey; |
995
|
|
|
/* add repeating components within valid dates to output array, only start date */ |
996
|
|
View Code Duplication |
if( $flat ) |
997
|
|
|
$result[] = $component2->copy(); // copy to output |
998
|
|
|
elseif( $split ) { |
999
|
|
|
if( $rend > $endDate ) |
1000
|
|
|
$rend = $endDate; |
1001
|
|
|
while( $rstart <= $rend ) { // iterate |
1002
|
|
|
$wd = getdate( $rstart ); |
1003
|
|
|
if(( $rstart > $startDate ) && // date after dtstart |
1004
|
|
|
!isset( $exdatelist[$rstart] )) // check exclude date |
1005
|
|
|
$result[$wd['year']][$wd['mon']][$wd['mday']][] = $component2->copy(); // copy to output |
1006
|
|
|
$rstart += ( 24*60*60 ); // step one day |
1007
|
|
|
} |
1008
|
|
|
} |
1009
|
|
|
elseif(( $rstart >= $startDate ) && // date within period |
1010
|
|
|
!isset( $exdatelist[$rstart] )) { // check exclude date |
1011
|
|
|
$wd = getdate( $rstart ); |
1012
|
|
|
$result[$wd['year']][$wd['mon']][$wd['mday']][] = $component2->copy(); // copy to output |
1013
|
|
|
} |
1014
|
|
|
} |
1015
|
|
|
} |
1016
|
|
|
/* deselect components with startdate/enddate not within period */ |
1017
|
|
|
if(( $endWdate < $startDate ) || ( $startWdate > $endDate )) continue; |
1018
|
|
|
} |
1019
|
|
|
/* deselect components with startdate not within period */ |
1020
|
|
|
elseif(( $startWdate < $startDate ) || ( $startWdate > $endDate )) continue; |
1021
|
|
|
/* add selected components within valid dates to output array */ |
1022
|
|
View Code Duplication |
if( $flat ) |
1023
|
|
|
$result[] = $component->copy(); // copy to output; |
1024
|
|
|
elseif( $split ) { |
1025
|
|
|
if( $endWdate > $endDate ) |
1026
|
|
|
$endWdate = $endDate; // use period end date |
1027
|
|
|
if( !isset( $exdatelist[$startWdate] )) { // check excluded dates |
1028
|
|
|
if( $startWdate < $startDate ) |
1029
|
|
|
$startWdate = $startDate; // use period start date |
1030
|
|
|
while( $startWdate <= $endWdate ) { // iterate |
1031
|
|
|
$wd = getdate( $startWdate ); |
1032
|
|
|
$result[$wd['year']][$wd['mon']][$wd['mday']][] = $component->copy(); // copy to output |
1033
|
|
|
$startWdate += ( 24*60*60 ); // step one day |
1034
|
|
|
} |
1035
|
|
|
} |
1036
|
|
|
} // use component date |
1037
|
|
|
elseif( !isset( $exdatelist[$startWdate] ) && // check excluded dates |
1038
|
|
|
( $startWdate >= $startDate )) { // within period |
1039
|
|
|
$wd = getdate( $startWdate ); |
1040
|
|
|
$result[$wd['year']][$wd['mon']][$wd['mday']][] = $component->copy(); // copy to output |
1041
|
|
|
} |
1042
|
|
|
} |
1043
|
|
|
if( 0 >= count( $result )) return FALSE; |
1044
|
|
|
elseif( !$flat ) { |
1045
|
|
|
foreach( $result as $y => $yeararr ) { |
1046
|
|
|
foreach( $yeararr as $m => $montharr ) { |
1047
|
|
|
ksort( $result[$y][$m] ); |
1048
|
|
|
} |
1049
|
|
|
ksort( $result[$y] ); |
1050
|
|
|
} |
1051
|
|
|
ksort( $result ); |
1052
|
|
|
} |
1053
|
|
|
return $result; |
1054
|
|
|
} |
1055
|
|
|
/** |
1056
|
|
|
* add calendar component to container |
1057
|
|
|
* |
1058
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
1059
|
|
|
* @since 2.4.10 - 2008-08-06 |
1060
|
|
|
* @param object $component calendar component |
1061
|
|
|
* @param mixed $arg1 optional, ordno/component type/ component uid |
1062
|
|
|
* @param mixed $arg2 optional, ordno if arg1 = component type |
1063
|
|
|
* @return void |
1064
|
|
|
*/ |
1065
|
|
|
function setComponent( $component, $arg1=FALSE, $arg2=FALSE ) { |
1066
|
|
|
if( '' >= $component->getConfig( 'language')) |
1067
|
|
|
$component->setConfig( 'language', $this->getConfig( 'language' )); |
1068
|
|
|
$component->setConfig( 'allowEmpty', $this->getConfig( 'allowEmpty' )); |
1069
|
|
|
$component->setConfig( 'nl', $this->getConfig( 'nl' )); |
1070
|
|
|
$component->setConfig( 'unique_id', $this->getConfig( 'unique_id' )); |
1071
|
|
|
$component->setConfig( 'format', $this->getConfig( 'format' )); |
1072
|
|
View Code Duplication |
if( !in_array( $component->objName, array( 'valarm', 'vtimezone' ))) { |
1073
|
|
|
unset( $component->propix ); |
1074
|
|
|
/* make sure dtstamp and uid is set */ |
1075
|
|
|
$dummy1 = $component->getProperty( 'dtstamp' ); |
1076
|
|
|
$dummy2 = $component->getProperty( 'uid' ); |
1077
|
|
|
} |
1078
|
|
|
if( !$arg1 ) { |
1079
|
|
|
$this->components[] = $component->copy(); |
1080
|
|
|
return TRUE; |
1081
|
|
|
} |
1082
|
|
|
$argType = $index = null; |
1083
|
|
|
if ( ctype_digit( (string) $arg1 )) { |
1084
|
|
|
$argType = 'INDEX'; |
1085
|
|
|
$index = (int) $arg1 - 1; |
1086
|
|
|
} |
1087
|
|
|
elseif(( strlen( $arg1 ) <= strlen( 'vfreebusy' )) && ( FALSE === strpos( $arg1, '@' ))) { |
1088
|
|
|
$argType = strtolower( $arg1 ); |
1089
|
|
|
$index = ( ctype_digit( (string) $arg2 )) ? ((int) $arg2) - 1 : 0; |
1090
|
|
|
} |
1091
|
|
|
$cix1sC = 0; |
1092
|
|
View Code Duplication |
foreach ( $this->components as $cix => $component2) { |
1093
|
|
|
if( empty( $component2 )) continue; |
1094
|
|
|
unset( $component2->propix ); |
1095
|
|
|
if(( 'INDEX' == $argType ) && ( $index == $cix )) { |
1096
|
|
|
$this->components[$cix] = $component->copy(); |
1097
|
|
|
return TRUE; |
1098
|
|
|
} |
1099
|
|
|
elseif( $argType == $component2->objName ) { |
1100
|
|
|
if( $index == $cix1sC ) { |
1101
|
|
|
$this->components[$cix] = $component->copy(); |
1102
|
|
|
return TRUE; |
1103
|
|
|
} |
1104
|
|
|
$cix1sC++; |
1105
|
|
|
} |
1106
|
|
|
elseif( !$argType && ( $arg1 == $component2->getProperty( 'uid' ))) { |
1107
|
|
|
$this->components[$cix] = $component->copy(); |
1108
|
|
|
return TRUE; |
1109
|
|
|
} |
1110
|
|
|
} |
1111
|
|
|
/* not found.. . insert last in chain anyway .. .*/ |
1112
|
|
|
$this->components[] = $component->copy(); |
1113
|
|
|
return TRUE; |
1114
|
|
|
} |
1115
|
|
|
/** |
1116
|
|
|
* sort iCal compoments, only local date sort |
1117
|
|
|
* |
1118
|
|
|
* ascending sort on properties (if exist) x-current-dtstart, dtstart, |
1119
|
|
|
* x-current-dtend, dtend, x-current-due, due, duration, created, dtstamp, uid |
1120
|
|
|
* |
1121
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
1122
|
|
|
* @since 2.4.10 - 2008-09-24 |
1123
|
|
|
* @return sort param |
1124
|
|
|
* |
1125
|
|
|
*/ |
1126
|
|
|
function sort() { |
1127
|
|
|
if( is_array( $this->components )) { |
1128
|
|
|
$this->_sortkeys = array( 'year', 'month', 'day', 'hour', 'min', 'sec' ); |
1129
|
|
|
usort( $this->components, array( $this, '_cmpfcn' )); |
1130
|
|
|
} |
1131
|
|
|
} |
1132
|
|
|
function _cmpfcn( $a, $b ) { |
1133
|
|
|
if( empty( $a )) return -1; |
1134
|
|
|
if( empty( $b )) return 1; |
1135
|
|
|
if( 'vtimezone' == $a->objName) return -1; |
1136
|
|
|
if( 'vtimezone' == $b->objName) return 1; |
1137
|
|
|
$astart = ( isset( $a->xprop['X-CURRENT-DTSTART']['value'] )) ? $a->_date_time_string( $a->xprop['X-CURRENT-DTSTART']['value'] ) : null; |
1138
|
|
|
if( empty( $astart ) && isset( $a->dtstart['value'] )) |
1139
|
|
|
$astart = & $a->dtstart['value']; |
1140
|
|
|
$bstart = ( isset( $b->xprop['X-CURRENT-DTSTART']['value'] )) ? $b->_date_time_string( $b->xprop['X-CURRENT-DTSTART']['value'] ) : null; |
1141
|
|
|
if( empty( $bstart ) && isset( $b->dtstart['value'] )) |
1142
|
|
|
$bstart = & $b->dtstart['value']; |
1143
|
|
|
if( empty( $astart )) return -1; |
1144
|
|
|
elseif( empty( $bstart )) return 1; |
1145
|
|
|
foreach( $this->_sortkeys as $key ) { |
1146
|
|
|
if ( empty( $astart[$key] )) return -1; |
1147
|
|
|
elseif( empty( $bstart[$key] )) return 1; |
1148
|
|
|
if ( $astart[$key] == $bstart[$key]) continue; |
1149
|
|
|
if (( (int) $astart[$key] ) < ((int) $bstart[$key] )) |
1150
|
|
|
return -1; |
1151
|
|
|
elseif(( (int) $astart[$key] ) > ((int) $bstart[$key] )) |
1152
|
|
|
return 1; |
1153
|
|
|
} |
1154
|
|
|
$c = ( isset( $a->xprop['X-CURRENT-DTEND']['value'] )) ? $a->_date_time_string( $a->xprop['X-CURRENT-DTEND']['value'] ) : null; |
1155
|
|
View Code Duplication |
if( empty( $c ) && !empty( $a->dtend['value'] )) |
1156
|
|
|
$c = & $a->dtend['value']; |
1157
|
|
View Code Duplication |
if( empty( $c ) && isset( $a->xprop['X-CURRENT-DUE']['value'] )) |
1158
|
|
|
$c = $a->_date_time_string( $a->xprop['X-CURRENT-DUE']['value'] ); |
1159
|
|
View Code Duplication |
if( empty( $c ) && !empty( $a->due['value'] )) |
1160
|
|
|
$c = & $a->due['value']; |
1161
|
|
|
if( empty( $c ) && !empty( $a->duration['value'] )) |
1162
|
|
|
$c = $a->duration2date(); |
1163
|
|
|
$d = ( isset( $b->xprop['X-CURRENT-DTEND']['value'] )) ? $b->_date_time_string( $b->xprop['X-CURRENT-DTEND']['value'] ) : null; |
1164
|
|
View Code Duplication |
if( empty( $d ) && !empty( $b->dtend['value'] )) |
1165
|
|
|
$d = & $b->dtend['value']; |
1166
|
|
View Code Duplication |
if( empty( $d ) && isset( $b->xprop['X-CURRENT-DUE']['value'] )) |
1167
|
|
|
$d = $b->_date_time_string( $b->xprop['X-CURRENT-DUE']['value'] ); |
1168
|
|
View Code Duplication |
if( empty( $d ) && !empty( $b->due['value'] )) |
1169
|
|
|
$d = & $b->due['value']; |
1170
|
|
|
if( empty( $d ) && !empty( $b->duration['value'] )) |
1171
|
|
|
$d = $b->duration2date(); |
1172
|
|
|
if( empty( $c )) return -1; |
1173
|
|
|
elseif( empty( $d )) return 1; |
1174
|
|
View Code Duplication |
foreach( $this->_sortkeys as $key ) { |
1175
|
|
|
if ( !isset( $c[$key] )) return -1; |
1176
|
|
|
elseif( !isset( $d[$key] )) return 1; |
1177
|
|
|
if ( $c[$key] == $d[$key] ) continue; |
1178
|
|
|
if (( (int) $c[$key] ) < ((int) $d[$key])) return -1; |
1179
|
|
|
elseif(( (int) $c[$key] ) > ((int) $d[$key])) return 1; |
1180
|
|
|
} |
1181
|
|
|
if( isset( $a->created['value'] )) |
1182
|
|
|
$e = & $a->created['value']; |
1183
|
|
|
else |
1184
|
|
|
$e = & $a->dtstamp['value']; |
1185
|
|
|
if( isset( $b->created['value'] )) |
1186
|
|
|
$f = & $b->created['value']; |
1187
|
|
|
else |
1188
|
|
|
$f = & $b->dtstamp['value']; |
1189
|
|
View Code Duplication |
foreach( $this->_sortkeys as $key ) { |
1190
|
|
|
if( !isset( $e[$key] )) return -1; |
1191
|
|
|
elseif( !isset( $f[$key] )) return 1; |
1192
|
|
|
if ( $e[$key] == $f[$key] ) continue; |
1193
|
|
|
if (( (int) $e[$key] ) < ((int) $f[$key])) return -1; |
1194
|
|
|
elseif(( (int) $e[$key] ) > ((int) $f[$key])) return 1; |
1195
|
|
|
} |
1196
|
|
|
if (( $a->uid['value'] ) < |
1197
|
|
|
( $b->uid['value'] )) return -1; |
1198
|
|
|
elseif(( $a->uid['value'] ) > |
1199
|
|
|
( $b->uid['value'] )) return 1; |
1200
|
|
|
return 0; |
1201
|
|
|
} |
1202
|
|
|
/** |
1203
|
|
|
* parse iCal file into vcalendar, components, properties and parameters |
1204
|
|
|
* |
1205
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
1206
|
|
|
* @since 2.4.10 - 2008-08-06 |
1207
|
|
|
* @param string $filename optional filname (incl. opt. directory/path) or URL |
1208
|
|
|
* @return bool FALSE if error occurs during parsing |
1209
|
|
|
* |
1210
|
|
|
*/ |
1211
|
|
|
function parse( $filename=FALSE ) { |
1212
|
|
|
if( !$filename ) { |
1213
|
|
|
/* directory/filename previous set via setConfig directory+filename / url */ |
1214
|
|
|
if( FALSE === ( $filename = $this->getConfig( 'url' ))) |
1215
|
|
|
$filename = $this->getConfig( 'dirfile' ); |
1216
|
|
|
} |
1217
|
|
|
elseif(( 'http://' == strtolower( substr( $filename, 0, 7 ))) || |
1218
|
|
|
( 'webcal://' == strtolower( substr( $filename, 0, 9 )))) { |
1219
|
|
|
/* remote file - URL */ |
1220
|
|
|
$this->setConfig( 'URL', $filename ); |
1221
|
|
|
if( !$filename = $this->getConfig( 'url' )) |
1222
|
|
|
return FALSE; /* err 2 */ |
1223
|
|
|
} |
1224
|
|
|
else { |
1225
|
|
|
/* local directory/filename */ |
1226
|
|
|
$parts = pathinfo( $filename ); |
1227
|
|
|
if( !empty( $parts['dirname'] ) && ( '.' != $parts['dirname'] )) { |
1228
|
|
|
if( !$this->setConfig( 'directory', $parts['dirname'] )) |
1229
|
|
|
return FALSE; /* err 3 */ |
1230
|
|
|
} |
1231
|
|
|
if( !$this->setConfig( 'filename', $parts['basename'] )) |
1232
|
|
|
return FALSE; /* err 4 */ |
1233
|
|
|
} |
1234
|
|
|
if( 'http://' != substr( $filename, 0, 7 )) { |
1235
|
|
|
/* local file error tests */ |
1236
|
|
|
if( !is_file( $filename )) /* err 5 */ |
1237
|
|
|
return FALSE; |
1238
|
|
|
if( !is_readable( $filename )) |
1239
|
|
|
return FALSE; /* err 6 */ |
1240
|
|
|
if( !filesize( $filename )) |
1241
|
|
|
return FALSE; /* err 7 */ |
1242
|
|
|
clearstatcache(); |
1243
|
|
|
} |
1244
|
|
|
/* READ FILE */ |
1245
|
|
|
if( FALSE === ( $rows = file( $filename ))) |
1246
|
|
|
return FALSE; /* err 1 */ |
1247
|
|
|
/* identify BEGIN:VCALENDAR, MUST be first row */ |
1248
|
|
|
if( 'BEGIN:VCALENDAR' != strtoupper( trim( $rows[0] ))) |
1249
|
|
|
return FALSE; /* err 8 */ |
1250
|
|
|
/* remove empty trailing lines */ |
1251
|
|
|
while( '' == trim( $rows[count( $rows ) - 1] )) { |
1252
|
|
|
unset( $rows[count( $rows ) - 1] ); |
1253
|
|
|
$rows = array_values( $rows ); |
1254
|
|
|
} |
1255
|
|
|
/* identify ending END:VCALENDAR row */ |
1256
|
|
|
if( 'END:VCALENDAR' != strtoupper( trim( $rows[count( $rows ) - 1] ))) { |
1257
|
|
|
return FALSE; /* err 9 */ |
1258
|
|
|
} |
1259
|
|
|
if( 3 > count( $rows )) |
1260
|
|
|
return FALSE; /* err 10 */ |
1261
|
|
|
$comp = $subcomp = null; |
1262
|
|
|
$actcomp = & $this; |
1263
|
|
|
$nl = $this->getConfig( 'nl' ); |
1264
|
|
|
$calsync = 0; |
1265
|
|
|
/* identify components and update unparsed data within component */ |
1266
|
|
|
foreach( $rows as $line ) { |
1267
|
|
|
if( '' == trim( $line )) |
1268
|
|
|
continue; |
1269
|
|
View Code Duplication |
if( $nl == substr( $line, 0 - strlen( $nl ))) |
1270
|
|
|
$line = substr( $line, 0, ( strlen( $line ) - strlen( $nl ))).'\n'; |
1271
|
|
|
if( 'BEGIN:VCALENDAR' == strtoupper( substr( $line, 0, 15 ))) { |
1272
|
|
|
$calsync++; |
1273
|
|
|
continue; |
1274
|
|
|
} |
1275
|
|
|
elseif( 'END:VCALENDAR' == strtoupper( substr( $line, 0, 13 ))) { |
1276
|
|
|
$calsync--; |
1277
|
|
|
continue; |
1278
|
|
|
} |
1279
|
|
|
elseif( 1 != $calsync ) |
1280
|
|
|
return FALSE; /* err 20 */ |
1281
|
|
|
if( 'END:' == strtoupper( substr( $line, 0, 4 ))) { |
1282
|
|
|
if( null != $subcomp ) { |
1283
|
|
|
$comp->setComponent( $subcomp ); |
1284
|
|
|
$subcomp = null; |
1285
|
|
|
} |
1286
|
|
|
else { |
1287
|
|
|
$this->setComponent( $comp ); |
|
|
|
|
1288
|
|
|
$comp = null; |
1289
|
|
|
} |
1290
|
|
|
$actcomp = null; |
1291
|
|
|
continue; |
1292
|
|
|
} // end - if ( 'END:' ==.. . |
1293
|
|
|
elseif( 'BEGIN:' == strtoupper( substr( $line, 0, 6 ))) { |
1294
|
|
|
$line = str_replace( '\n', '', $line ); |
1295
|
|
|
$compname = trim (strtoupper( substr( $line, 6 ))); |
1296
|
|
|
if( null != $comp ) { |
1297
|
|
|
if( 'VALARM' == $compname ) |
1298
|
|
|
$subcomp = new valarm(); |
1299
|
|
|
elseif( 'STANDARD' == $compname ) |
1300
|
|
|
$subcomp = new vtimezone( 'STANDARD' ); |
1301
|
|
|
elseif( 'DAYLIGHT' == $compname ) |
1302
|
|
|
$subcomp = new vtimezone( 'DAYLIGHT' ); |
1303
|
|
|
else |
1304
|
|
|
return FALSE; /* err 6 */ |
1305
|
|
|
$actcomp = & $subcomp; |
1306
|
|
|
} |
1307
|
|
|
else { |
1308
|
|
|
switch( $compname ) { |
1309
|
|
|
case 'VALARM': |
1310
|
|
|
$comp = new valarm(); |
1311
|
|
|
break; |
1312
|
|
|
case 'VEVENT': |
1313
|
|
|
$comp = new vevent(); |
1314
|
|
|
break; |
1315
|
|
|
case 'VFREEBUSY': |
1316
|
|
|
$comp = new vfreebusy(); |
1317
|
|
|
break; |
1318
|
|
|
case 'VJOURNAL': |
1319
|
|
|
$comp = new vjournal(); |
1320
|
|
|
break; |
1321
|
|
|
case 'VTODO': |
1322
|
|
|
$comp = new vtodo(); |
1323
|
|
|
break; |
1324
|
|
|
case 'VTIMEZONE': |
1325
|
|
|
$comp = new vtimezone(); |
1326
|
|
|
break; |
1327
|
|
|
default: |
1328
|
|
|
return FALSE; // err 7 |
1329
|
|
|
break; |
1330
|
|
|
} // end - switch |
1331
|
|
|
$actcomp = & $comp; |
1332
|
|
|
} |
1333
|
|
|
continue; |
1334
|
|
|
} // end - elsif ( 'BEGIN:'.. . |
1335
|
|
|
/* update selected component with unparsed data */ |
1336
|
|
|
$actcomp->unparsed[] = $line; |
1337
|
|
|
} // end - foreach( rows.. . |
1338
|
|
|
/* parse data for calendar (this) object */ |
1339
|
|
|
if( is_array( $this->unparsed ) && ( 0 < count( $this->unparsed ))) { |
1340
|
|
|
/* concatenate property values spread over several lines */ |
1341
|
|
|
$lastix = -1; |
1342
|
|
|
$propnames = array( 'calscale','method','prodid','version','x-' ); |
1343
|
|
|
$proprows = array(); |
1344
|
|
View Code Duplication |
foreach( $this->unparsed as $line ) { |
1345
|
|
|
$newProp = FALSE; |
1346
|
|
|
foreach ( $propnames as $propname ) { |
1347
|
|
|
if( $propname == strtolower( substr( $line, 0, strlen( $propname )))) { |
1348
|
|
|
$newProp = TRUE; |
1349
|
|
|
break; |
1350
|
|
|
} |
1351
|
|
|
} |
1352
|
|
|
if( $newProp ) { |
1353
|
|
|
$newProp = FALSE; |
1354
|
|
|
$lastix++; |
1355
|
|
|
$proprows[$lastix] = $line; |
1356
|
|
|
} |
1357
|
|
|
else { |
1358
|
|
|
/* remove line breaks */ |
1359
|
|
|
if(( '\n' == substr( $proprows[$lastix], -2 )) && |
1360
|
|
|
( ' ' == substr( $line, 0, 1 ))) { |
1361
|
|
|
$proprows[$lastix] = substr( $proprows[$lastix], 0, strlen( $proprows[$lastix] ) - 2 ); |
1362
|
|
|
$line = substr( $line, 1 ); |
1363
|
|
|
} |
1364
|
|
|
$proprows[$lastix] .= $line; |
1365
|
|
|
} |
1366
|
|
|
} |
1367
|
|
|
$toolbox = new calendarComponent(); |
1368
|
|
|
foreach( $proprows as $line ) { |
1369
|
|
View Code Duplication |
if( '\n' == substr( $line, -2 )) |
1370
|
|
|
$line = substr( $line, 0, strlen( $line ) - 2 ); |
1371
|
|
|
/* get propname */ |
1372
|
|
|
$cix = $propname = null; |
1373
|
|
View Code Duplication |
for( $cix=0; $cix < strlen( $line ); $cix++ ) { |
1374
|
|
|
if( in_array( $line{$cix}, array( ':', ';' ))) |
1375
|
|
|
break; |
1376
|
|
|
else |
1377
|
|
|
$propname .= $line{$cix}; |
1378
|
|
|
} |
1379
|
|
|
/* ignore version/prodid properties */ |
1380
|
|
|
if( in_array( strtoupper( $propname ), array( 'VERSION', 'PRODID' ))) |
1381
|
|
|
continue; |
1382
|
|
|
$line = substr( $line, $cix); |
1383
|
|
|
/* separate attributes from value */ |
1384
|
|
|
$attr = array(); |
1385
|
|
|
$attrix = -1; |
1386
|
|
|
$strlen = strlen( $line ); |
1387
|
|
View Code Duplication |
for( $cix=0; $cix < $strlen; $cix++ ) { |
1388
|
|
|
if(( ':' == $line{$cix} ) && |
1389
|
|
|
( '://' != substr( $line, $cix, 3 )) && |
1390
|
|
|
( 'mailto:' != strtolower( substr( $line, $cix - 6, 7 )))) { |
1391
|
|
|
$attrEnd = TRUE; |
1392
|
|
|
if(( $cix < ( $strlen - 4 )) && |
1393
|
|
|
ctype_digit( substr( $line, $cix+1, 4 ))) { // an URI with a (4pos) portnr?? |
1394
|
|
|
for( $c2ix = $cix; 3 < $c2ix; $c2ix-- ) { |
1395
|
|
|
if( '://' == substr( $line, $c2ix - 2, 3 )) { |
1396
|
|
|
$attrEnd = FALSE; |
1397
|
|
|
break; // an URI with a portnr!! |
1398
|
|
|
} |
1399
|
|
|
} |
1400
|
|
|
} |
1401
|
|
|
if( $attrEnd) { |
1402
|
|
|
$line = substr( $line, $cix + 1 ); |
1403
|
|
|
break; |
1404
|
|
|
} |
1405
|
|
|
} |
1406
|
|
|
if( ';' == $line{$cix} ) |
1407
|
|
|
$attr[++$attrix] = null; |
1408
|
|
|
else |
1409
|
|
|
$attr[$attrix] .= $line{$cix}; |
1410
|
|
|
} |
1411
|
|
|
|
1412
|
|
|
/* make attributes in array format */ |
1413
|
|
|
$propattr = array(); |
1414
|
|
View Code Duplication |
foreach( $attr as $attribute ) { |
1415
|
|
|
$attrsplit = explode( '=', $attribute, 2 ); |
1416
|
|
|
if( 1 < count( $attrsplit )) |
1417
|
|
|
$propattr[$attrsplit[0]] = $attrsplit[1]; |
1418
|
|
|
else |
1419
|
|
|
$propattr[] = $attribute; |
1420
|
|
|
} |
1421
|
|
|
/* update Property */ |
1422
|
|
|
if( FALSE !== strpos( $line, ',' )) { |
1423
|
|
|
$content = explode( ',', $line ); |
1424
|
|
|
$clen = count( $content ); |
1425
|
|
View Code Duplication |
for( $cix = 0; $cix < $clen; $cix++ ) { |
1426
|
|
|
if( "\\" == substr( $content[$cix], -1 )) { |
1427
|
|
|
$content[$cix] .= ','.$content[$cix + 1]; |
1428
|
|
|
unset( $content[$cix + 1] ); |
1429
|
|
|
$cix++; |
1430
|
|
|
} |
1431
|
|
|
} |
1432
|
|
View Code Duplication |
if( 1 < count( $content )) { |
1433
|
|
|
foreach( $content as $cix => $contentPart ) |
1434
|
|
|
$content[$cix] = $toolbox->_strunrep( $contentPart ); |
1435
|
|
|
$this->setProperty( $propname, $content, $propattr ); |
1436
|
|
|
continue; |
1437
|
|
|
} |
1438
|
|
|
else |
1439
|
|
|
$line = reset( $content ); |
1440
|
|
|
$line = $toolbox->_strunrep( $line ); |
1441
|
|
|
} |
1442
|
|
|
$this->setProperty( $propname, trim( $line ), $propattr ); |
1443
|
|
|
} // end - foreach( $this->unparsed.. . |
1444
|
|
|
} // end - if( is_array( $this->unparsed.. . |
1445
|
|
|
/* parse Components */ |
1446
|
|
|
if( is_array( $this->components ) && ( 0 < count( $this->components ))) { |
1447
|
|
View Code Duplication |
for( $six = 0; $six < count( $this->components ); $six++ ) { |
1448
|
|
|
if( !empty( $this->components[$six] )) |
1449
|
|
|
$this->components[$six]->parse(); |
1450
|
|
|
} |
1451
|
|
|
} |
1452
|
|
|
else |
1453
|
|
|
return FALSE; /* err 91 or something.. . */ |
1454
|
|
|
return TRUE; |
1455
|
|
|
} |
1456
|
|
|
/*********************************************************************************/ |
1457
|
|
|
/** |
1458
|
|
|
* creates formatted output for calendar object instance |
1459
|
|
|
* |
1460
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
1461
|
|
|
* @since 2.4.10 - 2008-08-06 |
1462
|
|
|
* @return string |
1463
|
|
|
*/ |
1464
|
|
|
function createCalendar() { |
1465
|
|
|
$calendarInit1 = $calendarInit2 = $calendarxCaldecl = $calendarStart = $calendar = null; |
1466
|
|
|
switch( $this->format ) { |
1467
|
|
|
case 'xcal': |
1468
|
|
|
$calendarInit1 = '<?xml version="1.0" encoding="UTF-8"?>'.$this->nl. |
1469
|
|
|
'<!DOCTYPE iCalendar PUBLIC "-//IETF//DTD XCAL/iCalendar XML//EN"'.$this->nl. |
1470
|
|
|
'"http://www.ietf.org/internet-drafts/draft-ietf-calsch-many-xcal-01.txt"'; |
1471
|
|
|
$calendarInit2 = '>'.$this->nl; |
1472
|
|
|
$calendarStart = '<vcalendar'; |
1473
|
|
|
break; |
1474
|
|
|
default: |
1475
|
|
|
$calendarStart = 'BEGIN:VCALENDAR'.$this->nl; |
1476
|
|
|
break; |
1477
|
|
|
} |
1478
|
|
|
$calendarStart .= $this->createCalscale(); |
1479
|
|
|
$calendarStart .= $this->createMethod(); |
1480
|
|
|
$calendarStart .= $this->createProdid(); |
1481
|
|
|
$calendarStart .= $this->createVersion(); |
1482
|
|
|
switch( $this->format ) { |
1483
|
|
|
case 'xcal': |
1484
|
|
|
$nlstrlen = strlen( $this->nl ); |
1485
|
|
|
if( $this->nl == substr( $calendarStart, ( 0 - $nlstrlen ))) |
1486
|
|
|
$calendarStart = substr( $calendarStart, 0, ( strlen( $calendarStart ) - $nlstrlen )); |
1487
|
|
|
$calendarStart .= '>'.$this->nl; |
1488
|
|
|
break; |
1489
|
|
|
default: |
1490
|
|
|
break; |
1491
|
|
|
} |
1492
|
|
|
$calendar .= $this->createXprop(); |
1493
|
|
View Code Duplication |
foreach( $this->components as $component ) { |
1494
|
|
|
if( empty( $component )) continue; |
1495
|
|
|
if( '' >= $component->getConfig( 'language')) |
1496
|
|
|
$component->setConfig( 'language', $this->getConfig( 'language' )); |
1497
|
|
|
$component->setConfig( 'allowEmpty', $this->getConfig( 'allowEmpty' )); |
1498
|
|
|
$component->setConfig( 'nl', $this->getConfig( 'nl' )); |
1499
|
|
|
$component->setConfig( 'unique_id', $this->getConfig( 'unique_id' )); |
1500
|
|
|
$component->setConfig( 'format', $this->getConfig( 'format' )); |
1501
|
|
|
$calendar .= $component->createComponent( $this->xcaldecl ); |
1502
|
|
|
} |
1503
|
|
|
if(( 0 < count( $this->xcaldecl )) && ( 'xcal' == $this->format )) { // xCal only |
1504
|
|
|
$calendarInit1 .= $this->nl.'['.$this->nl; |
1505
|
|
|
$old_xcaldecl = array(); |
1506
|
|
|
foreach( $this->xcaldecl as $declix => $declPart ) { |
1507
|
|
|
if(( 0 < count( $old_xcaldecl)) && |
1508
|
|
|
( in_array( $declPart['uri'], $old_xcaldecl['uri'] )) && |
1509
|
|
|
( in_array( $declPart['external'], $old_xcaldecl['external'] ))) |
1510
|
|
|
continue; // no duplicate uri and ext. references |
1511
|
|
|
$calendarxCaldecl .= '<!'; |
1512
|
|
|
foreach( $declPart as $declKey => $declValue ) { |
1513
|
|
|
switch( $declKey ) { // index |
1514
|
|
|
case 'xmldecl': // no 1 |
1515
|
|
|
$calendarxCaldecl .= $declValue.' '; |
1516
|
|
|
break; |
1517
|
|
|
case 'uri': // no 2 |
1518
|
|
|
$calendarxCaldecl .= $declValue.' '; |
1519
|
|
|
$old_xcaldecl['uri'][] = $declValue; |
1520
|
|
|
break; |
1521
|
|
|
case 'ref': // no 3 |
1522
|
|
|
$calendarxCaldecl .= $declValue.' '; |
1523
|
|
|
break; |
1524
|
|
|
case 'external': // no 4 |
1525
|
|
|
$calendarxCaldecl .= '"'.$declValue.'" '; |
1526
|
|
|
$old_xcaldecl['external'][] = $declValue; |
1527
|
|
|
break; |
1528
|
|
|
case 'type': // no 5 |
1529
|
|
|
$calendarxCaldecl .= $declValue.' '; |
1530
|
|
|
break; |
1531
|
|
|
case 'type2': // no 6 |
1532
|
|
|
$calendarxCaldecl .= $declValue; |
1533
|
|
|
break; |
1534
|
|
|
} |
1535
|
|
|
} |
1536
|
|
|
$calendarxCaldecl .= '>'.$this->nl; |
1537
|
|
|
} |
1538
|
|
|
$calendarInit2 = ']'.$calendarInit2; |
1539
|
|
|
} |
1540
|
|
|
switch( $this->format ) { |
1541
|
|
|
case 'xcal': |
1542
|
|
|
$calendar .= '</vcalendar>'.$this->nl; |
1543
|
|
|
break; |
1544
|
|
|
default: |
1545
|
|
|
$calendar .= 'END:VCALENDAR'.$this->nl; |
1546
|
|
|
break; |
1547
|
|
|
} |
1548
|
|
|
return $calendarInit1.$calendarxCaldecl.$calendarInit2.$calendarStart.$calendar; |
1549
|
|
|
} |
1550
|
|
|
/** |
1551
|
|
|
* a HTTP redirect header is sent with created, updated and/or parsed calendar |
1552
|
|
|
* |
1553
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
1554
|
|
|
* @since 2.2.12 - 2007-10-23 |
1555
|
|
|
* @return redirect |
1556
|
|
|
*/ |
1557
|
|
|
function returnCalendar() { |
1558
|
|
|
$filename = $this->getConfig( 'filename' ); |
1559
|
|
|
$output = $this->createCalendar(); |
1560
|
|
|
$filesize = strlen( $output ); |
1561
|
|
|
// if( headers_sent( $filename, $linenum )) |
1562
|
|
|
// die( "Headers already sent in $filename on line $linenum\n" ); |
1563
|
|
|
if( 'xcal' == $this->format ) |
1564
|
|
|
header( 'Content-Type: application/calendar+xml; charset=utf-8' ); |
1565
|
|
|
else |
1566
|
|
|
header( 'Content-Type: text/calendar; charset=utf-8' ); |
1567
|
|
|
header( 'Content-Length: '.$filesize ); |
1568
|
|
|
header( 'Content-Disposition: attachment; filename="'.$filename.'"' ); |
1569
|
|
|
header( 'Cache-Control: max-age=10' ); |
1570
|
|
|
echo $output; |
1571
|
|
|
die(); |
1572
|
|
|
} |
1573
|
|
|
/** |
1574
|
|
|
* save content in a file |
1575
|
|
|
* |
1576
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
1577
|
|
|
* @since 2.2.12 - 2007-12-30 |
1578
|
|
|
* @param string $directory optional |
1579
|
|
|
* @param string $filename optional |
1580
|
|
|
* @param string $delimiter optional |
1581
|
|
|
* @return bool |
1582
|
|
|
*/ |
1583
|
|
|
function saveCalendar( $directory=FALSE, $filename=FALSE, $delimiter=FALSE ) { |
1584
|
|
|
if( $directory ) |
1585
|
|
|
$this->setConfig( 'directory', $directory ); |
1586
|
|
|
if( $filename ) |
1587
|
|
|
$this->setConfig( 'filename', $filename ); |
1588
|
|
|
if( $delimiter && ($delimiter != DIRECTORY_SEPARATOR )) |
1589
|
|
|
$this->setConfig( 'delimiter', $delimiter ); |
1590
|
|
|
if( FALSE === ( $dirfile = $this->getConfig( 'url' ))) |
1591
|
|
|
$dirfile = $this->getConfig( 'dirfile' ); |
1592
|
|
|
$iCalFile = @fopen( $dirfile, 'w' ); |
1593
|
|
|
if( $iCalFile ) { |
1594
|
|
|
if( FALSE === fwrite( $iCalFile, $this->createCalendar() )) |
1595
|
|
|
return FALSE; |
1596
|
|
|
fclose( $iCalFile ); |
1597
|
|
|
return TRUE; |
1598
|
|
|
} |
1599
|
|
|
else |
1600
|
|
|
return FALSE; |
1601
|
|
|
} |
1602
|
|
|
/** |
1603
|
|
|
* if recent version of calendar file exists (default one hour), an HTTP redirect header is sent |
1604
|
|
|
* else FALSE is returned |
1605
|
|
|
* |
1606
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
1607
|
|
|
* @since 2.2.12 - 2007-10-28 |
1608
|
|
|
* @param string $directory optional alt. int timeout |
1609
|
|
|
* @param string $filename optional |
1610
|
|
|
* @param string $delimiter optional |
1611
|
|
|
* @param int timeout optional, default 3600 sec |
1612
|
|
|
* @return redirect/FALSE |
|
|
|
|
1613
|
|
|
*/ |
1614
|
|
|
function useCachedCalendar( $directory=FALSE, $filename=FALSE, $delimiter=FALSE, $timeout=3600) { |
1615
|
|
|
if ( $directory && ctype_digit( (string) $directory ) && !$filename ) { |
1616
|
|
|
$timeout = (int) $directory; |
1617
|
|
|
$directory = FALSE; |
1618
|
|
|
} |
1619
|
|
|
if( $directory ) |
1620
|
|
|
$this->setConfig( 'directory', $directory ); |
1621
|
|
|
if( $filename ) |
1622
|
|
|
$this->setConfig( 'filename', $filename ); |
1623
|
|
|
if( $delimiter && ( $delimiter != DIRECTORY_SEPARATOR )) |
1624
|
|
|
$this->setConfig( 'delimiter', $delimiter ); |
1625
|
|
|
$filesize = $this->getConfig( 'filesize' ); |
1626
|
|
|
if( 0 >= $filesize ) |
1627
|
|
|
return FALSE; |
1628
|
|
|
$dirfile = $this->getConfig( 'dirfile' ); |
1629
|
|
|
if( time() - filemtime( $dirfile ) < $timeout) { |
1630
|
|
|
clearstatcache(); |
1631
|
|
|
$dirfile = $this->getConfig( 'dirfile' ); |
1632
|
|
|
$filename = $this->getConfig( 'filename' ); |
1633
|
|
|
// if( headers_sent( $filename, $linenum )) |
1634
|
|
|
// die( "Headers already sent in $filename on line $linenum\n" ); |
1635
|
|
|
if( 'xcal' == $this->format ) |
1636
|
|
|
header( 'Content-Type: application/calendar+xml; charset=utf-8' ); |
1637
|
|
|
else |
1638
|
|
|
header( 'Content-Type: text/calendar; charset=utf-8' ); |
1639
|
|
|
header( 'Content-Length: '.$filesize ); |
1640
|
|
|
header( 'Content-Disposition: attachment; filename="'.$filename.'"' ); |
1641
|
|
|
header( 'Cache-Control: max-age=10' ); |
1642
|
|
|
$fp = @$fopen( $dirfile, 'r' ); |
|
|
|
|
1643
|
|
|
if( $fp ) { |
1644
|
|
|
fpassthru( $fp ); |
1645
|
|
|
fclose( $fp ); |
1646
|
|
|
} |
1647
|
|
|
die(); |
1648
|
|
|
} |
1649
|
|
|
else |
1650
|
|
|
return FALSE; |
1651
|
|
|
} |
1652
|
|
|
} |
1653
|
|
|
/*********************************************************************************/ |
1654
|
|
|
/*********************************************************************************/ |
1655
|
|
|
/** |
1656
|
|
|
* abstract class for calendar components |
1657
|
|
|
* |
1658
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
1659
|
|
|
* @since 2.4.19 - 2008-10-12 |
1660
|
|
|
*/ |
1661
|
|
|
class calendarComponent { |
1662
|
|
|
// component property variables |
1663
|
|
|
var $uid; |
1664
|
|
|
var $dtstamp; |
1665
|
|
|
|
1666
|
|
|
// component config variables |
1667
|
|
|
var $allowEmpty; |
1668
|
|
|
var $language; |
1669
|
|
|
var $nl; |
1670
|
|
|
var $unique_id; |
1671
|
|
|
var $format; |
1672
|
|
|
var $objName; // created automatically at instance creation |
1673
|
|
|
// component internal variables |
1674
|
|
|
var $componentStart1; |
1675
|
|
|
var $componentStart2; |
1676
|
|
|
var $componentEnd1; |
1677
|
|
|
var $componentEnd2; |
1678
|
|
|
var $elementStart1; |
1679
|
|
|
var $elementStart2; |
1680
|
|
|
var $elementEnd1; |
1681
|
|
|
var $elementEnd2; |
1682
|
|
|
var $intAttrDelimiter; |
1683
|
|
|
var $attributeDelimiter; |
1684
|
|
|
var $valueInit; |
1685
|
|
|
// component xCal declaration container |
1686
|
|
|
var $xcaldecl; |
1687
|
|
|
/** |
1688
|
|
|
* constructor for calendar component object |
1689
|
|
|
* |
1690
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
1691
|
|
|
* @since 2.4.19 - 2008-10-23 |
1692
|
|
|
*/ |
1693
|
|
|
function __construct() { |
1694
|
|
|
$this->objName = ( isset( $this->timezonetype )) ? |
1695
|
|
|
strtolower( $this->timezonetype ) : get_class ( $this ); |
1696
|
|
|
$this->uid = array(); |
1697
|
|
|
$this->dtstamp = array(); |
1698
|
|
|
|
1699
|
|
|
$this->language = null; |
1700
|
|
|
$this->nl = null; |
1701
|
|
|
$this->unique_id = null; |
1702
|
|
|
$this->format = null; |
1703
|
|
|
$this->allowEmpty = TRUE; |
1704
|
|
|
$this->xcaldecl = array(); |
1705
|
|
|
|
1706
|
|
|
$this->_createFormat(); |
1707
|
|
|
$this->_makeDtstamp(); |
1708
|
|
|
} |
1709
|
|
|
/*********************************************************************************/ |
1710
|
|
|
/** |
1711
|
|
|
* Property Name: ACTION |
1712
|
|
|
*/ |
1713
|
|
|
/** |
1714
|
|
|
* creates formatted output for calendar component property action |
1715
|
|
|
* |
1716
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
1717
|
|
|
* @since 2.4.8 - 2008-10-22 |
1718
|
|
|
* @return string |
1719
|
|
|
*/ |
1720
|
|
|
function createAction() { |
1721
|
|
|
if( empty( $this->action )) return FALSE; |
1722
|
|
|
if( empty( $this->action['value'] )) |
1723
|
|
|
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'ACTION' ) : FALSE; |
1724
|
|
|
$attributes = $this->_createParams( $this->action['params'] ); |
1725
|
|
|
return $this->_createElement( 'ACTION', $attributes, $this->action['value'] ); |
1726
|
|
|
} |
1727
|
|
|
/** |
1728
|
|
|
* set calendar component property action |
1729
|
|
|
* |
1730
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
1731
|
|
|
* @since 2.4.8 - 2008-11-04 |
1732
|
|
|
* @param string $value "AUDIO" / "DISPLAY" / "EMAIL" / "PROCEDURE" |
1733
|
|
|
* @param mixed $params |
1734
|
|
|
* @return bool |
1735
|
|
|
*/ |
1736
|
|
|
function setAction( $value, $params=FALSE ) { |
1737
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
1738
|
|
|
$this->action = array( 'value' => $value, 'params' => $this->_setParams( $params )); |
1739
|
|
|
return TRUE; |
1740
|
|
|
} |
1741
|
|
|
/*********************************************************************************/ |
1742
|
|
|
/** |
1743
|
|
|
* Property Name: ATTACH |
1744
|
|
|
*/ |
1745
|
|
|
/** |
1746
|
|
|
* creates formatted output for calendar component property attach |
1747
|
|
|
* |
1748
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
1749
|
|
|
* @since 0.9.7 - 2006-11-23 |
1750
|
|
|
* @return string |
1751
|
|
|
*/ |
1752
|
|
View Code Duplication |
function createAttach() { |
1753
|
|
|
if( empty( $this->attach )) return FALSE; |
1754
|
|
|
$output = null; |
1755
|
|
|
foreach( $this->attach as $attachPart ) { |
1756
|
|
|
if(! empty( $attachPart['value'] )) { |
1757
|
|
|
$attributes = $this->_createParams( $attachPart['params'] ); |
1758
|
|
|
$output .= $this->_createElement( 'ATTACH', $attributes, $attachPart['value'] ); |
1759
|
|
|
} |
1760
|
|
|
elseif( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'ATTACH' ); |
1761
|
|
|
} |
1762
|
|
|
return $output; |
1763
|
|
|
} |
1764
|
|
|
/** |
1765
|
|
|
* set calendar component property attach |
1766
|
|
|
* |
1767
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
1768
|
|
|
* @since 2.5.1 - 2008-11-06 |
1769
|
|
|
* @param string $value |
1770
|
|
|
* @param array $params, optional |
|
|
|
|
1771
|
|
|
* @param integer $index, optional |
|
|
|
|
1772
|
|
|
* @return bool |
1773
|
|
|
*/ |
1774
|
|
|
function setAttach( $value, $params=FALSE, $index=FALSE ) { |
1775
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
1776
|
|
|
$this->_setMval( $this->attach, $value, $params, FALSE, $index ); |
1777
|
|
|
return TRUE; |
1778
|
|
|
} |
1779
|
|
|
/*********************************************************************************/ |
1780
|
|
|
/** |
1781
|
|
|
* Property Name: ATTENDEE |
1782
|
|
|
*/ |
1783
|
|
|
/** |
1784
|
|
|
* creates formatted output for calendar component property attendee |
1785
|
|
|
* |
1786
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
1787
|
|
|
* @since 2.4.8 - 2008-09-23 |
1788
|
|
|
* @return string |
1789
|
|
|
*/ |
1790
|
|
|
function createAttendee() { |
1791
|
|
|
if( empty( $this->attendee )) return FALSE; |
1792
|
|
|
$output = null; |
1793
|
|
|
foreach( $this->attendee as $attendeePart ) { // start foreach 1 |
1794
|
|
|
if( empty( $attendeePart['value'] )) { |
1795
|
|
|
if( $this->getConfig( 'allowEmpty' )) |
1796
|
|
|
$output .= $this->_createElement( 'ATTENDEE' ); |
1797
|
|
|
continue; |
1798
|
|
|
} |
1799
|
|
|
$attendee1 = $attendee2 = $attendeeLANG = $attendeeCN = null; |
1800
|
|
|
foreach( $attendeePart as $paramlabel => $paramvalue ) { // start foreach 2 |
1801
|
|
|
if( 'value' == $paramlabel ) |
1802
|
|
|
$attendee2 .= 'MAILTO:'.$paramvalue; |
1803
|
|
|
elseif(( 'params' == $paramlabel ) && ( is_array( $paramvalue ))) { // start elseif |
1804
|
|
|
foreach( $paramvalue as $optparamlabel => $optparamvalue ) { // start foreach 3 |
1805
|
|
|
$attendee11 = $attendee12 = null; |
1806
|
|
|
if( is_int( $optparamlabel )) { |
1807
|
|
|
$attendee1 .= $this->intAttrDelimiter.$optparamvalue; |
1808
|
|
|
continue; |
1809
|
|
|
} |
1810
|
|
|
switch( $optparamlabel ) { // start switch |
1811
|
|
|
case 'CUTYPE': |
1812
|
|
|
case 'PARTSTAT': |
1813
|
|
|
case 'ROLE': |
1814
|
|
|
case 'RSVP': |
1815
|
|
|
$attendee1 .= $this->intAttrDelimiter.$optparamlabel.'="'.$optparamvalue.'"'; |
1816
|
|
|
break; |
1817
|
|
|
case 'SENT-BY': |
1818
|
|
|
$attendee1 .= $this->intAttrDelimiter.'SENT-BY="MAILTO:'.$optparamvalue.'"'; |
1819
|
|
|
break; |
1820
|
|
|
case 'MEMBER': |
1821
|
|
|
$attendee11 = $this->intAttrDelimiter.'MEMBER='; |
1822
|
|
|
//no break |
1823
|
|
|
case 'DELEGATED-TO': |
1824
|
|
|
$attendee11 = ( !$attendee11 ) ? $this->intAttrDelimiter.'DELEGATED-TO=' : $attendee11; |
1825
|
|
|
//no break |
1826
|
|
|
case 'DELEGATED-FROM': |
1827
|
|
|
$attendee11 = ( !$attendee11 ) ? $this->intAttrDelimiter.'DELEGATED-FROM=' : $attendee11; |
1828
|
|
|
foreach( $optparamvalue as $cix => $calUserAddress ) { |
1829
|
|
|
$attendee12 .= ( $cix ) ? ',' : null; |
1830
|
|
|
$attendee12 .= '"MAILTO:'.$calUserAddress.'"'; |
1831
|
|
|
} |
1832
|
|
|
$attendee1 .= $attendee11.$attendee12; |
1833
|
|
|
break; |
1834
|
|
|
case 'CN': |
1835
|
|
|
$attendeeCN .= $this->intAttrDelimiter.'CN="'.$optparamvalue.'"'; |
1836
|
|
|
break; |
1837
|
|
|
case 'DIR': |
1838
|
|
|
$attendee1 .= $this->intAttrDelimiter.'DIR="'.$optparamvalue.'"'; |
1839
|
|
|
break; |
1840
|
|
|
case 'LANGUAGE': |
1841
|
|
|
$attendeeLANG .= $this->intAttrDelimiter.'LANGUAGE='.$optparamvalue; |
1842
|
|
|
break; |
1843
|
|
|
default: |
1844
|
|
|
$attendee1 .= $this->intAttrDelimiter."$optparamlabel=$optparamvalue"; |
1845
|
|
|
break; |
1846
|
|
|
} // end switch |
1847
|
|
|
} // end foreach 3 |
1848
|
|
|
} // end elseif |
1849
|
|
|
} // end foreach 2 |
1850
|
|
|
$output .= $this->_createElement( 'ATTENDEE', $attendee1.$attendeeLANG.$attendeeCN, $attendee2 ); |
1851
|
|
|
} // end foreach 1 |
1852
|
|
|
return $output; |
1853
|
|
|
} |
1854
|
|
|
/** |
1855
|
|
|
* set calendar component property attach |
1856
|
|
|
* |
1857
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
1858
|
|
|
* @since 2.5.1 - 2008-11-05 |
1859
|
|
|
* @param string $value |
1860
|
|
|
* @param array $params, optional |
|
|
|
|
1861
|
|
|
* @param integer $index, optional |
|
|
|
|
1862
|
|
|
* @return bool |
1863
|
|
|
*/ |
1864
|
|
|
function setAttendee( $value, $params=FALSE, $index=FALSE ) { |
1865
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
1866
|
|
|
$value = str_replace ( 'MAILTO:', '', $value ); |
1867
|
|
|
$value = str_replace ( 'mailto:', '', $value ); |
1868
|
|
|
$params2 = array(); |
1869
|
|
|
if( is_array($params )) { |
1870
|
|
|
$optarrays = array(); |
1871
|
|
|
foreach( $params as $optparamlabel => $optparamvalue ) { |
1872
|
|
|
$optparamlabel = strtoupper( $optparamlabel ); |
1873
|
|
|
switch( $optparamlabel ) { |
1874
|
|
|
case 'MEMBER': |
1875
|
|
|
case 'DELEGATED-TO': |
1876
|
|
|
case 'DELEGATED-FROM': |
1877
|
|
|
if( is_array( $optparamvalue )) { |
1878
|
|
|
foreach( $optparamvalue as $part ) { |
1879
|
|
|
$part = str_replace( 'MAILTO:', '', $part ); |
1880
|
|
|
$part = str_replace( 'mailto:', '', $part ); |
1881
|
|
View Code Duplication |
if(( '"' == $part{0} ) && ( '"' == $part{strlen($part)-1} )) |
1882
|
|
|
$part = substr( $part, 1, ( strlen($part)-2 )); |
1883
|
|
|
$optarrays[$optparamlabel][] = $part; |
1884
|
|
|
} |
1885
|
|
|
} |
1886
|
|
|
else { |
1887
|
|
|
$part = str_replace( 'MAILTO:', '', $optparamvalue ); |
1888
|
|
|
$part = str_replace( 'mailto:', '', $part ); |
1889
|
|
View Code Duplication |
if(( '"' == $part{0} ) && ( '"' == $part{strlen($part)-1} )) |
1890
|
|
|
$part = substr( $part, 1, ( strlen($part)-2 )); |
1891
|
|
|
$optarrays[$optparamlabel][] = $part; |
1892
|
|
|
} |
1893
|
|
|
break; |
1894
|
|
|
default: |
1895
|
|
|
if( 'SENT-BY' == $optparamlabel ) { |
1896
|
|
|
$optparamvalue = str_replace( 'MAILTO:', '', $optparamvalue ); |
1897
|
|
|
$optparamvalue = str_replace( 'mailto:', '', $optparamvalue ); |
1898
|
|
|
} |
1899
|
|
View Code Duplication |
if(( '"' == substr( $optparamvalue, 0, 1 )) && |
1900
|
|
|
( '"' == substr( $optparamvalue, -1 ))) |
1901
|
|
|
$optparamvalue = substr( $optparamvalue, 1, ( strlen( $optparamvalue ) - 2 )); |
1902
|
|
|
$params2[$optparamlabel] = $optparamvalue; |
1903
|
|
|
break; |
1904
|
|
|
} // end switch( $optparamlabel.. . |
1905
|
|
|
} // end foreach( $optparam.. . |
1906
|
|
|
foreach( $optarrays as $optparamlabel => $optparams ) |
1907
|
|
|
$params2[$optparamlabel] = $optparams; |
1908
|
|
|
} |
1909
|
|
|
// remove defaults |
1910
|
|
|
$this->_existRem( $params2, 'CUTYPE', 'INDIVIDUAL' ); |
1911
|
|
|
$this->_existRem( $params2, 'PARTSTAT', 'NEEDS-ACTION' ); |
1912
|
|
|
$this->_existRem( $params2, 'ROLE', 'REQ-PARTICIPANT' ); |
1913
|
|
|
$this->_existRem( $params2, 'RSVP', 'FALSE' ); |
1914
|
|
|
// check language setting |
1915
|
|
|
if( isset( $params2['CN' ] )) { |
1916
|
|
|
$lang = $this->getConfig( 'language' ); |
1917
|
|
|
if( !isset( $params2['LANGUAGE' ] ) && !empty( $lang )) |
1918
|
|
|
$params2['LANGUAGE' ] = $lang; |
1919
|
|
|
} |
1920
|
|
|
$this->_setMval( $this->attendee, $value, $params2, FALSE, $index ); |
1921
|
|
|
return TRUE; |
1922
|
|
|
} |
1923
|
|
|
/*********************************************************************************/ |
1924
|
|
|
/** |
1925
|
|
|
* Property Name: CATEGORIES |
1926
|
|
|
*/ |
1927
|
|
|
/** |
1928
|
|
|
* creates formatted output for calendar component property categories |
1929
|
|
|
* |
1930
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
1931
|
|
|
* @since 2.4.8 - 2008-10-22 |
1932
|
|
|
* @return string |
1933
|
|
|
*/ |
1934
|
|
View Code Duplication |
function createCategories() { |
1935
|
|
|
if( empty( $this->categories )) return FALSE; |
1936
|
|
|
$output = null; |
1937
|
|
|
foreach( $this->categories as $category ) { |
1938
|
|
|
if( empty( $category['value'] )) { |
1939
|
|
|
if ( $this->getConfig( 'allowEmpty' )) |
1940
|
|
|
$output .= $this->_createElement( 'CATEGORIES' ); |
1941
|
|
|
continue; |
1942
|
|
|
} |
1943
|
|
|
$attributes = $this->_createParams( $category['params'], array( 'LANGUAGE' )); |
1944
|
|
|
if( is_array( $category['value'] )) { |
1945
|
|
|
foreach( $category['value'] as $cix => $categoryPart ) |
1946
|
|
|
$category['value'][$cix] = $this->_strrep( $categoryPart ); |
1947
|
|
|
$content = implode( ',', $category['value'] ); |
1948
|
|
|
} |
1949
|
|
|
else |
1950
|
|
|
$content = $this->_strrep( $category['value'] ); |
1951
|
|
|
$output .= $this->_createElement( 'CATEGORIES', $attributes, $content ); |
1952
|
|
|
} |
1953
|
|
|
return $output; |
1954
|
|
|
} |
1955
|
|
|
/** |
1956
|
|
|
* set calendar component property categories |
1957
|
|
|
* |
1958
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
1959
|
|
|
* @since 2.5.1 - 2008-11-06 |
1960
|
|
|
* @param mixed $value |
1961
|
|
|
* @param array $params, optional |
|
|
|
|
1962
|
|
|
* @param integer $index, optional |
|
|
|
|
1963
|
|
|
* @return bool |
1964
|
|
|
*/ |
1965
|
|
|
function setCategories( $value, $params=FALSE, $index=FALSE ) { |
1966
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
1967
|
|
|
$this->_setMval( $this->categories, $value, $params, FALSE, $index ); |
1968
|
|
|
return TRUE; |
1969
|
|
|
} |
1970
|
|
|
/*********************************************************************************/ |
1971
|
|
|
/** |
1972
|
|
|
* Property Name: CLASS |
1973
|
|
|
*/ |
1974
|
|
|
/** |
1975
|
|
|
* creates formatted output for calendar component property class |
1976
|
|
|
* |
1977
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
1978
|
|
|
* @since 0.9.7 - 2006-11-20 |
1979
|
|
|
* @return string |
1980
|
|
|
*/ |
1981
|
|
|
function createClass() { |
1982
|
|
|
if( empty( $this->class )) return FALSE; |
1983
|
|
|
if( empty( $this->class['value'] )) |
1984
|
|
|
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'CLASS' ) : FALSE; |
1985
|
|
|
$attributes = $this->_createParams( $this->class['params'] ); |
1986
|
|
|
return $this->_createElement( 'CLASS', $attributes, $this->class['value'] ); |
1987
|
|
|
} |
1988
|
|
|
/** |
1989
|
|
|
* set calendar component property class |
1990
|
|
|
* |
1991
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
1992
|
|
|
* @since 2.4.8 - 2008-11-04 |
1993
|
|
|
* @param string $value "PUBLIC" / "PRIVATE" / "CONFIDENTIAL" / iana-token / x-name |
1994
|
|
|
* @param array $params optional |
1995
|
|
|
* @return bool |
1996
|
|
|
*/ |
1997
|
|
|
function setClass( $value, $params=FALSE ) { |
1998
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
1999
|
|
|
$this->class = array( 'value' => $value, 'params' => $this->_setParams( $params )); |
|
|
|
|
2000
|
|
|
return TRUE; |
2001
|
|
|
} |
2002
|
|
|
/*********************************************************************************/ |
2003
|
|
|
/** |
2004
|
|
|
* Property Name: COMMENT |
2005
|
|
|
*/ |
2006
|
|
|
/** |
2007
|
|
|
* creates formatted output for calendar component property comment |
2008
|
|
|
* |
2009
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2010
|
|
|
* @since 2.4.8 - 2008-10-22 |
2011
|
|
|
* @return string |
2012
|
|
|
*/ |
2013
|
|
View Code Duplication |
function createComment() { |
2014
|
|
|
if( empty( $this->comment )) return FALSE; |
2015
|
|
|
$output = null; |
2016
|
|
|
foreach( $this->comment as $commentPart ) { |
2017
|
|
|
if( empty( $commentPart['value'] )) { |
2018
|
|
|
if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'COMMENT' ); |
2019
|
|
|
continue; |
2020
|
|
|
} |
2021
|
|
|
$attributes = $this->_createParams( $commentPart['params'], array( 'ALTREP', 'LANGUAGE' )); |
2022
|
|
|
$content = $this->_strrep( $commentPart['value'] ); |
2023
|
|
|
$output .= $this->_createElement( 'COMMENT', $attributes, $content ); |
2024
|
|
|
} |
2025
|
|
|
return $output; |
2026
|
|
|
} |
2027
|
|
|
/** |
2028
|
|
|
* set calendar component property comment |
2029
|
|
|
* |
2030
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2031
|
|
|
* @since 2.5.1 - 2008-11-06 |
2032
|
|
|
* @param string $value |
2033
|
|
|
* @param array $params, optional |
|
|
|
|
2034
|
|
|
* @param integer $index, optional |
|
|
|
|
2035
|
|
|
* @return bool |
2036
|
|
|
*/ |
2037
|
|
|
function setComment( $value, $params=FALSE, $index=FALSE ) { |
2038
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
2039
|
|
|
$this->_setMval( $this->comment, $value, $params, FALSE, $index ); |
2040
|
|
|
return TRUE; |
2041
|
|
|
} |
2042
|
|
|
/*********************************************************************************/ |
2043
|
|
|
/** |
2044
|
|
|
* Property Name: COMPLETED |
2045
|
|
|
*/ |
2046
|
|
|
/** |
2047
|
|
|
* creates formatted output for calendar component property completed |
2048
|
|
|
* |
2049
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2050
|
|
|
* @since 2.4.8 - 2008-10-22 |
2051
|
|
|
* @return string |
2052
|
|
|
*/ |
2053
|
|
View Code Duplication |
function createCompleted( ) { |
2054
|
|
|
if( empty( $this->completed )) return FALSE; |
2055
|
|
|
if( !isset( $this->completed['value']['year'] ) && |
2056
|
|
|
!isset( $this->completed['value']['month'] ) && |
2057
|
|
|
!isset( $this->completed['value']['day'] ) && |
2058
|
|
|
!isset( $this->completed['value']['hour'] ) && |
2059
|
|
|
!isset( $this->completed['value']['min'] ) && |
2060
|
|
|
!isset( $this->completed['value']['sec'] )) |
2061
|
|
|
if( $this->getConfig( 'allowEmpty' )) |
2062
|
|
|
return $this->_createElement( 'COMPLETED' ); |
2063
|
|
|
else return FALSE; |
2064
|
|
|
$formatted = $this->_format_date_time( $this->completed['value'], 7 ); |
2065
|
|
|
$attributes = $this->_createParams( $this->completed['params'] ); |
2066
|
|
|
return $this->_createElement( 'COMPLETED', $attributes, $formatted ); |
2067
|
|
|
} |
2068
|
|
|
/** |
2069
|
|
|
* set calendar component property completed |
2070
|
|
|
* |
2071
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2072
|
|
|
* @since 2.4.8 - 2008-10-23 |
2073
|
|
|
* @param mixed $year |
2074
|
|
|
* @param mixed $month optional |
2075
|
|
|
* @param int $day optional |
2076
|
|
|
* @param int $hour optional |
2077
|
|
|
* @param int $min optional |
2078
|
|
|
* @param int $sec optional |
2079
|
|
|
* @param array $params optional |
2080
|
|
|
* @return bool |
2081
|
|
|
*/ |
2082
|
|
|
function setCompleted( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) { |
2083
|
|
|
if( empty( $year )) { |
2084
|
|
|
if( $this->getConfig( 'allowEmpty' )) { |
2085
|
|
|
$this->completed = array( 'value' => null, 'params' => $this->_setParams( $params )); |
|
|
|
|
2086
|
|
|
return TRUE; |
2087
|
|
|
} |
2088
|
|
|
else |
2089
|
|
|
return FALSE; |
2090
|
|
|
} |
2091
|
|
|
$this->completed = $this->_setDate2( $year, $month, $day, $hour, $min, $sec, $params ); |
2092
|
|
|
return TRUE; |
2093
|
|
|
} |
2094
|
|
|
/*********************************************************************************/ |
2095
|
|
|
/** |
2096
|
|
|
* Property Name: CONTACT |
2097
|
|
|
*/ |
2098
|
|
|
/** |
2099
|
|
|
* creates formatted output for calendar component property contact |
2100
|
|
|
* |
2101
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2102
|
|
|
* @since 2.4.8 - 2008-10-23 |
2103
|
|
|
* @return string |
2104
|
|
|
*/ |
2105
|
|
View Code Duplication |
function createContact() { |
2106
|
|
|
if( empty( $this->contact )) return FALSE; |
2107
|
|
|
$output = null; |
2108
|
|
|
foreach( $this->contact as $contact ) { |
2109
|
|
|
if( !empty( $contact['value'] )) { |
2110
|
|
|
$attributes = $this->_createParams( $contact['params'], array( 'ALTREP', 'LANGUAGE' )); |
2111
|
|
|
$content = $this->_strrep( $contact['value'] ); |
2112
|
|
|
$output .= $this->_createElement( 'CONTACT', $attributes, $content ); |
2113
|
|
|
} |
2114
|
|
|
elseif( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'CONTACT' ); |
2115
|
|
|
} |
2116
|
|
|
return $output; |
2117
|
|
|
} |
2118
|
|
|
/** |
2119
|
|
|
* set calendar component property contact |
2120
|
|
|
* |
2121
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2122
|
|
|
* @since 2.5.1 - 2008-11-05 |
2123
|
|
|
* @param string $value |
2124
|
|
|
* @param array $params, optional |
|
|
|
|
2125
|
|
|
* @param integer $index, optional |
|
|
|
|
2126
|
|
|
* @return bool |
2127
|
|
|
*/ |
2128
|
|
|
function setContact( $value, $params=FALSE, $index=FALSE ) { |
2129
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
2130
|
|
|
$this->_setMval( $this->contact, $value, $params, FALSE, $index ); |
2131
|
|
|
return TRUE; |
2132
|
|
|
} |
2133
|
|
|
/*********************************************************************************/ |
2134
|
|
|
/** |
2135
|
|
|
* Property Name: CREATED |
2136
|
|
|
*/ |
2137
|
|
|
/** |
2138
|
|
|
* creates formatted output for calendar component property created |
2139
|
|
|
* |
2140
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2141
|
|
|
* @since 2.4.8 - 2008-10-21 |
2142
|
|
|
* @return string |
2143
|
|
|
*/ |
2144
|
|
View Code Duplication |
function createCreated() { |
2145
|
|
|
if( empty( $this->created )) return FALSE; |
2146
|
|
|
$formatted = $this->_format_date_time( $this->created['value'], 7 ); |
2147
|
|
|
$attributes = $this->_createParams( $this->created['params'] ); |
2148
|
|
|
return $this->_createElement( 'CREATED', $attributes, $formatted ); |
2149
|
|
|
} |
2150
|
|
|
/** |
2151
|
|
|
* set calendar component property created |
2152
|
|
|
* |
2153
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2154
|
|
|
* @since 2.4.8 - 2008-10-23 |
2155
|
|
|
* @param mixed $year optional |
2156
|
|
|
* @param mixed $month optional |
2157
|
|
|
* @param int $day optional |
2158
|
|
|
* @param int $hour optional |
2159
|
|
|
* @param int $min optional |
2160
|
|
|
* @param int $sec optional |
2161
|
|
|
* @param mixed $params optional |
2162
|
|
|
* @return bool |
2163
|
|
|
*/ |
2164
|
|
|
function setCreated( $year=FALSE, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) { |
2165
|
|
View Code Duplication |
if( !isset( $year )) { |
2166
|
|
|
$year = date('Ymd\THis', mktime( date( 'H' ), date( 'i' ), date( 's' ) - date( 'Z'), date( 'm' ), date( 'd' ), date( 'Y' ))); |
2167
|
|
|
} |
2168
|
|
|
$this->created = $this->_setDate2( $year, $month, $day, $hour, $min, $sec, $params ); |
2169
|
|
|
return TRUE; |
2170
|
|
|
} |
2171
|
|
|
/*********************************************************************************/ |
2172
|
|
|
/** |
2173
|
|
|
* Property Name: DESCRIPTION |
2174
|
|
|
*/ |
2175
|
|
|
/** |
2176
|
|
|
* creates formatted output for calendar component property description |
2177
|
|
|
* |
2178
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2179
|
|
|
* @since 2.4.8 - 2008-10-22 |
2180
|
|
|
* @return string |
2181
|
|
|
*/ |
2182
|
|
View Code Duplication |
function createDescription() { |
2183
|
|
|
if( empty( $this->description )) return FALSE; |
2184
|
|
|
$output = null; |
2185
|
|
|
foreach( $this->description as $description ) { |
2186
|
|
|
if( !empty( $description['value'] )) { |
2187
|
|
|
$attributes = $this->_createParams( $description['params'], array( 'ALTREP', 'LANGUAGE' )); |
2188
|
|
|
$content = $this->_strrep( $description['value'] ); |
2189
|
|
|
$output .= $this->_createElement( 'DESCRIPTION', $attributes, $content ); |
2190
|
|
|
} |
2191
|
|
|
elseif( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'DESCRIPTION' ); |
2192
|
|
|
} |
2193
|
|
|
return $output; |
2194
|
|
|
} |
2195
|
|
|
/** |
2196
|
|
|
* set calendar component property description |
2197
|
|
|
* |
2198
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2199
|
|
|
* @since 2.5.1 - 2008-11-05 |
2200
|
|
|
* @param string $value |
2201
|
|
|
* @param array $params, optional |
|
|
|
|
2202
|
|
|
* @param integer $index, optional |
|
|
|
|
2203
|
|
|
* @return bool |
2204
|
|
|
*/ |
2205
|
|
|
function setDescription( $value, $params=FALSE, $index=FALSE ) { |
2206
|
|
|
if( empty( $value )) { if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; } |
2207
|
|
|
$this->_setMval( $this->description, $value, $params, FALSE, $index ); |
2208
|
|
|
return TRUE; |
2209
|
|
|
} |
2210
|
|
|
/*********************************************************************************/ |
2211
|
|
|
/** |
2212
|
|
|
* Property Name: DTEND |
2213
|
|
|
*/ |
2214
|
|
|
/** |
2215
|
|
|
* creates formatted output for calendar component property dtend |
2216
|
|
|
* |
2217
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2218
|
|
|
* @since 2.4.8 - 2008-10-21 |
2219
|
|
|
* @return string |
2220
|
|
|
*/ |
2221
|
|
View Code Duplication |
function createDtend() { |
2222
|
|
|
if( empty( $this->dtend )) return FALSE; |
2223
|
|
|
if( !isset( $this->dtend['value']['year'] ) && |
2224
|
|
|
!isset( $this->dtend['value']['month'] ) && |
2225
|
|
|
!isset( $this->dtend['value']['day'] ) && |
2226
|
|
|
!isset( $this->dtend['value']['hour'] ) && |
2227
|
|
|
!isset( $this->dtend['value']['min'] ) && |
2228
|
|
|
!isset( $this->dtend['value']['sec'] )) |
2229
|
|
|
if( $this->getConfig( 'allowEmpty' )) |
2230
|
|
|
return $this->_createElement( 'DTEND' ); |
2231
|
|
|
else return FALSE; |
2232
|
|
|
$formatted = $this->_format_date_time( $this->dtend['value'] ); |
2233
|
|
|
$attributes = $this->_createParams( $this->dtend['params'] ); |
2234
|
|
|
return $this->_createElement( 'DTEND', $attributes, $formatted ); |
2235
|
|
|
} |
2236
|
|
|
/** |
2237
|
|
|
* set calendar component property dtend |
2238
|
|
|
* |
2239
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2240
|
|
|
* @since 2.4.8 - 2008-10-23 |
2241
|
|
|
* @param mixed $year |
2242
|
|
|
* @param mixed $month optional |
2243
|
|
|
* @param int $day optional |
2244
|
|
|
* @param int $hour optional |
2245
|
|
|
* @param int $min optional |
2246
|
|
|
* @param int $sec optional |
2247
|
|
|
* @param string $tz optional |
2248
|
|
|
* @param array params optional |
2249
|
|
|
* @return bool |
2250
|
|
|
*/ |
2251
|
|
View Code Duplication |
function setDtend( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $tz=FALSE, $params=FALSE ) { |
2252
|
|
|
if( empty( $year )) { |
2253
|
|
|
if( $this->getConfig( 'allowEmpty' )) { |
2254
|
|
|
$this->dtend = array( 'value' => null, 'params' => $this->_setParams( $params )); |
2255
|
|
|
return TRUE; |
2256
|
|
|
} |
2257
|
|
|
else |
2258
|
|
|
return FALSE; |
2259
|
|
|
} |
2260
|
|
|
$this->dtend = $this->_setDate( $year, $month, $day, $hour, $min, $sec, $tz, $params ); |
|
|
|
|
2261
|
|
|
return TRUE; |
2262
|
|
|
} |
2263
|
|
|
/*********************************************************************************/ |
2264
|
|
|
/** |
2265
|
|
|
* Property Name: DTSTAMP |
2266
|
|
|
*/ |
2267
|
|
|
/** |
2268
|
|
|
* creates formatted output for calendar component property dtstamp |
2269
|
|
|
* |
2270
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2271
|
|
|
* @since 2.4.4 - 2008-03-07 |
2272
|
|
|
* @return string |
2273
|
|
|
*/ |
2274
|
|
|
function createDtstamp() { |
2275
|
|
|
if( !isset( $this->dtstamp['value']['year'] ) && |
2276
|
|
|
!isset( $this->dtstamp['value']['month'] ) && |
2277
|
|
|
!isset( $this->dtstamp['value']['day'] ) && |
2278
|
|
|
!isset( $this->dtstamp['value']['hour'] ) && |
2279
|
|
|
!isset( $this->dtstamp['value']['min'] ) && |
2280
|
|
|
!isset( $this->dtstamp['value']['sec'] )) |
2281
|
|
|
$this->_makeDtstamp(); |
2282
|
|
|
$formatted = $this->_format_date_time( $this->dtstamp['value'], 7 ); |
2283
|
|
|
$attributes = $this->_createParams( $this->dtstamp['params'] ); |
2284
|
|
|
return $this->_createElement( 'DTSTAMP', $attributes, $formatted ); |
2285
|
|
|
} |
2286
|
|
|
/** |
2287
|
|
|
* computes datestamp for calendar component object instance dtstamp |
2288
|
|
|
* |
2289
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2290
|
|
|
* @since 1.x.x - 2007-05-13 |
2291
|
|
|
* @return void |
2292
|
|
|
*/ |
2293
|
|
|
function _makeDtstamp() { |
2294
|
|
|
$this->dtstamp['value'] = array( 'year' => date( 'Y' ) |
2295
|
|
|
, 'month' => date( 'm' ) |
2296
|
|
|
, 'day' => date( 'd' ) |
2297
|
|
|
, 'hour' => date( 'H' ) |
2298
|
|
|
, 'min' => date( 'i' ) |
2299
|
|
|
, 'sec' => date( 's' ) - date( 'Z' )); |
2300
|
|
|
$this->dtstamp['params'] = null; |
2301
|
|
|
} |
2302
|
|
|
/** |
2303
|
|
|
* set calendar component property dtstamp |
2304
|
|
|
* |
2305
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2306
|
|
|
* @since 2.4.8 - 2008-10-23 |
2307
|
|
|
* @param mixed $year |
2308
|
|
|
* @param mixed $month optional |
2309
|
|
|
* @param int $day optional |
2310
|
|
|
* @param int $hour optional |
2311
|
|
|
* @param int $min optional |
2312
|
|
|
* @param int $sec optional |
2313
|
|
|
* @param array $params optional |
2314
|
|
|
* @return TRUE |
2315
|
|
|
*/ |
2316
|
|
|
function setDtstamp( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) { |
2317
|
|
|
if( empty( $year )) |
2318
|
|
|
$this->_makeDtstamp(); |
2319
|
|
|
else |
2320
|
|
|
$this->dtstamp = $this->_setDate2( $year, $month, $day, $hour, $min, $sec, $params ); |
2321
|
|
|
return TRUE; |
2322
|
|
|
} |
2323
|
|
|
/*********************************************************************************/ |
2324
|
|
|
/** |
2325
|
|
|
* Property Name: DTSTART |
2326
|
|
|
*/ |
2327
|
|
|
/** |
2328
|
|
|
* creates formatted output for calendar component property dtstart |
2329
|
|
|
* |
2330
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2331
|
|
|
* @since 2.4.16 - 2008-10-26 |
2332
|
|
|
* @return string |
2333
|
|
|
*/ |
2334
|
|
|
function createDtstart() { |
2335
|
|
|
if( empty( $this->dtstart )) return FALSE; |
2336
|
|
|
if( !isset( $this->dtstart['value']['year'] ) && |
2337
|
|
|
!isset( $this->dtstart['value']['month'] ) && |
2338
|
|
|
!isset( $this->dtstart['value']['day'] ) && |
2339
|
|
|
!isset( $this->dtstart['value']['hour'] ) && |
2340
|
|
|
!isset( $this->dtstart['value']['min'] ) && |
2341
|
|
|
!isset( $this->dtstart['value']['sec'] )) |
2342
|
|
|
if( $this->getConfig( 'allowEmpty' )) |
2343
|
|
|
return $this->_createElement( 'DTSTART' ); |
2344
|
|
|
else return FALSE; |
2345
|
|
|
if( in_array( $this->objName, array( 'vtimezone', 'standard', 'daylight' ))) |
2346
|
|
|
unset( $this->dtstart['value']['tz'], $this->dtstart['params']['TZID'] ); |
2347
|
|
|
$formatted = $this->_format_date_time( $this->dtstart['value'] ); |
2348
|
|
|
$attributes = $this->_createParams( $this->dtstart['params'] ); |
2349
|
|
|
return $this->_createElement( 'DTSTART', $attributes, $formatted ); |
2350
|
|
|
} |
2351
|
|
|
/** |
2352
|
|
|
* set calendar component property dtstart |
2353
|
|
|
* |
2354
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2355
|
|
|
* @since 2.4.16 - 2008-11-04 |
2356
|
|
|
* @param mixed $year |
2357
|
|
|
* @param mixed $month optional |
2358
|
|
|
* @param int $day optional |
2359
|
|
|
* @param int $hour optional |
2360
|
|
|
* @param int $min optional |
2361
|
|
|
* @param int $sec optional |
2362
|
|
|
* @param string $tz optional |
2363
|
|
|
* @param array $params optional |
2364
|
|
|
* @return bool |
2365
|
|
|
*/ |
2366
|
|
View Code Duplication |
function setDtstart( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $tz=FALSE, $params=FALSE ) { |
2367
|
|
|
if( empty( $year )) { |
2368
|
|
|
if( $this->getConfig( 'allowEmpty' )) { |
2369
|
|
|
$this->dtstart = array( 'value' => null, 'params' => $this->_setParams( $params )); |
|
|
|
|
2370
|
|
|
return TRUE; |
2371
|
|
|
} |
2372
|
|
|
else |
2373
|
|
|
return FALSE; |
2374
|
|
|
} |
2375
|
|
|
$this->dtstart = $this->_setDate( $year, $month, $day, $hour, $min, $sec, $tz, $params, 'dtstart' ); |
|
|
|
|
2376
|
|
|
return TRUE; |
2377
|
|
|
} |
2378
|
|
|
/*********************************************************************************/ |
2379
|
|
|
/** |
2380
|
|
|
* Property Name: DUE |
2381
|
|
|
*/ |
2382
|
|
|
/** |
2383
|
|
|
* creates formatted output for calendar component property due |
2384
|
|
|
* |
2385
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2386
|
|
|
* @since 2.4.8 - 2008-10-22 |
2387
|
|
|
* @return string |
2388
|
|
|
*/ |
2389
|
|
View Code Duplication |
function createDue() { |
2390
|
|
|
if( empty( $this->due )) return FALSE; |
2391
|
|
|
if( !isset( $this->due['value']['year'] ) && |
2392
|
|
|
!isset( $this->due['value']['month'] ) && |
2393
|
|
|
!isset( $this->due['value']['day'] ) && |
2394
|
|
|
!isset( $this->due['value']['hour'] ) && |
2395
|
|
|
!isset( $this->due['value']['min'] ) && |
2396
|
|
|
!isset( $this->due['value']['sec'] )) |
2397
|
|
|
if( $this->getConfig( 'allowEmpty' )) |
2398
|
|
|
return $this->_createElement( 'DUE' ); |
2399
|
|
|
else return FALSE; |
2400
|
|
|
$formatted = $this->_format_date_time( $this->due['value'] ); |
2401
|
|
|
$attributes = $this->_createParams( $this->due['params'] ); |
2402
|
|
|
return $this->_createElement( 'DUE', $attributes, $formatted ); |
2403
|
|
|
} |
2404
|
|
|
/** |
2405
|
|
|
* set calendar component property due |
2406
|
|
|
* |
2407
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2408
|
|
|
* @since 2.4.8 - 2008-11-04 |
2409
|
|
|
* @param mixed $year |
2410
|
|
|
* @param mixed $month optional |
2411
|
|
|
* @param int $day optional |
2412
|
|
|
* @param int $hour optional |
2413
|
|
|
* @param int $min optional |
2414
|
|
|
* @param int $sec optional |
2415
|
|
|
* @param array $params optional |
2416
|
|
|
* @return bool |
2417
|
|
|
*/ |
2418
|
|
View Code Duplication |
function setDue( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $tz=FALSE, $params=FALSE ) { |
2419
|
|
|
if( empty( $year )) { |
2420
|
|
|
if( $this->getConfig( 'allowEmpty' )) { |
2421
|
|
|
$this->due = array( 'value' => null, 'params' => $this->_setParams( $params )); |
|
|
|
|
2422
|
|
|
return TRUE; |
2423
|
|
|
} |
2424
|
|
|
else |
2425
|
|
|
return FALSE; |
2426
|
|
|
} |
2427
|
|
|
$this->due = $this->_setDate( $year, $month, $day, $hour, $min, $sec, $tz, $params ); |
2428
|
|
|
return TRUE; |
2429
|
|
|
} |
2430
|
|
|
/*********************************************************************************/ |
2431
|
|
|
/** |
2432
|
|
|
* Property Name: DURATION |
2433
|
|
|
*/ |
2434
|
|
|
/** |
2435
|
|
|
* creates formatted output for calendar component property duration |
2436
|
|
|
* |
2437
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2438
|
|
|
* @since 2.4.8 - 2008-10-21 |
2439
|
|
|
* @return string |
2440
|
|
|
*/ |
2441
|
|
|
function createDuration() { |
2442
|
|
|
if( empty( $this->duration )) return FALSE; |
2443
|
|
|
if( !isset( $this->duration['value']['week'] ) && |
2444
|
|
|
!isset( $this->duration['value']['day'] ) && |
2445
|
|
|
!isset( $this->duration['value']['hour'] ) && |
2446
|
|
|
!isset( $this->duration['value']['min'] ) && |
2447
|
|
|
!isset( $this->duration['value']['sec'] )) |
2448
|
|
|
if( $this->getConfig( 'allowEmpty' )) |
2449
|
|
|
return $this->_createElement( 'DURATION', array(), null ); |
2450
|
|
|
else return FALSE; |
2451
|
|
|
$attributes = $this->_createParams( $this->duration['params'] ); |
2452
|
|
|
return $this->_createElement( 'DURATION', $attributes, $this->_format_duration( $this->duration['value'] )); |
2453
|
|
|
} |
2454
|
|
|
/** |
2455
|
|
|
* set calendar component property duration |
2456
|
|
|
* |
2457
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2458
|
|
|
* @since 2.4.8 - 2008-11-04 |
2459
|
|
|
* @param mixed $week |
2460
|
|
|
* @param mixed $day optional |
2461
|
|
|
* @param int $hour optional |
2462
|
|
|
* @param int $min optional |
2463
|
|
|
* @param int $sec optional |
2464
|
|
|
* @param array $params optional |
2465
|
|
|
* @return bool |
2466
|
|
|
*/ |
2467
|
|
|
function setDuration( $week, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) { |
2468
|
|
|
if( empty( $week )) if( $this->getConfig( 'allowEmpty' )) $week = null; else return FALSE; |
2469
|
|
|
if( is_array( $week ) && ( 1 <= count( $week ))) |
2470
|
|
|
$this->duration = array( 'value' => $this->_duration_array( $week ), 'params' => $this->_setParams( $day )); |
2471
|
|
|
elseif( is_string( $week ) && ( 3 <= strlen( trim( $week )))) { |
2472
|
|
|
$week = trim( $week ); |
2473
|
|
|
if( in_array( substr( $week, 0, 1 ), array( '+', '-' ))) |
2474
|
|
|
$week = substr( $week, 1 ); |
2475
|
|
|
$this->duration = array( 'value' => $this->_duration_string( $week ), 'params' => $this->_setParams( $day )); |
2476
|
|
|
} |
2477
|
|
|
elseif( empty( $week ) && empty( $day ) && empty( $hour ) && empty( $min ) && empty( $sec )) |
2478
|
|
|
return FALSE; |
2479
|
|
|
else |
2480
|
|
|
$this->duration = array( 'value' => $this->_duration_array( array( $week, $day, $hour, $min, $sec )), 'params' => $this->_setParams( $params )); |
|
|
|
|
2481
|
|
|
return TRUE; |
2482
|
|
|
} |
2483
|
|
|
/*********************************************************************************/ |
2484
|
|
|
/** |
2485
|
|
|
* Property Name: EXDATE |
2486
|
|
|
*/ |
2487
|
|
|
/** |
2488
|
|
|
* creates formatted output for calendar component property exdate |
2489
|
|
|
* |
2490
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2491
|
|
|
* @since 2.4.8 - 2008-10-22 |
2492
|
|
|
* @return string |
2493
|
|
|
*/ |
2494
|
|
|
function createExdate() { |
2495
|
|
|
if( empty( $this->exdate )) return FALSE; |
2496
|
|
|
$output = null; |
2497
|
|
|
foreach( $this->exdate as $ex => $theExdate ) { |
2498
|
|
|
if( empty( $theExdate['value'] )) { |
2499
|
|
|
if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'EXDATE' ); |
2500
|
|
|
continue; |
2501
|
|
|
} |
2502
|
|
|
$content = $attributes = null; |
2503
|
|
|
foreach( $theExdate['value'] as $eix => $exdatePart ) { |
2504
|
|
|
$parno = count( $exdatePart ); |
2505
|
|
|
$formatted = $this->_format_date_time( $exdatePart, $parno ); |
2506
|
|
|
if( isset( $theExdate['params']['TZID'] )) |
2507
|
|
|
$formatted = str_replace( 'Z', '', $formatted); |
2508
|
|
|
if( 0 < $eix ) { |
2509
|
|
|
if( isset( $theExdate['value'][0]['tz'] )) { |
2510
|
|
|
if( ctype_digit( substr( $theExdate['value'][0]['tz'], -4 )) || |
2511
|
|
|
( 'Z' == $theExdate['value'][0]['tz'] )) { |
2512
|
|
|
if( 'Z' != substr( $formatted, -1 )) |
2513
|
|
|
$formatted .= 'Z'; |
2514
|
|
|
} |
2515
|
|
|
else |
2516
|
|
|
$formatted = str_replace( 'Z', '', $formatted ); |
2517
|
|
|
} |
2518
|
|
|
else |
2519
|
|
|
$formatted = str_replace( 'Z', '', $formatted ); |
2520
|
|
|
} |
2521
|
|
|
$content .= ( 0 < $eix ) ? ','.$formatted : $formatted; |
2522
|
|
|
} |
2523
|
|
|
$attributes .= $this->_createParams( $theExdate['params'] ); |
2524
|
|
|
$output .= $this->_createElement( 'EXDATE', $attributes, $content ); |
2525
|
|
|
} |
2526
|
|
|
return $output; |
2527
|
|
|
} |
2528
|
|
|
/** |
2529
|
|
|
* set calendar component property exdate |
2530
|
|
|
* |
2531
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2532
|
|
|
* @since 2.5.1 - 2008-11-05 |
2533
|
|
|
* @param array exdates |
2534
|
|
|
* @param array $params, optional |
|
|
|
|
2535
|
|
|
* @param integer $index, optional |
|
|
|
|
2536
|
|
|
* @return bool |
2537
|
|
|
*/ |
2538
|
|
|
function setExdate( $exdates, $params=FALSE, $index=FALSE ) { |
2539
|
|
View Code Duplication |
if( empty( $exdates )) { |
2540
|
|
|
if( $this->getConfig( 'allowEmpty' )) { |
2541
|
|
|
$this->_setMval( $this->exdate, null, $params, FALSE, $index ); |
2542
|
|
|
return TRUE; |
2543
|
|
|
} |
2544
|
|
|
else |
2545
|
|
|
return FALSE; |
2546
|
|
|
} |
2547
|
|
|
$input = array( 'params' => $this->_setParams( $params, array( 'VALUE' => 'DATE-TIME' ))); |
2548
|
|
|
/* ev. check 1:st date and save ev. timezone **/ |
2549
|
|
|
$this->_chkdatecfg( reset( $exdates ), $parno, $input['params'] ); |
2550
|
|
|
$this->_existRem( $input['params'], 'VALUE', 'DATE-TIME' ); // remove default parameter |
|
|
|
|
2551
|
|
|
foreach( $exdates as $eix => $theExdate ) { |
2552
|
|
|
if( $this->_isArrayTimestampDate( $theExdate )) |
2553
|
|
|
$exdatea = $this->_timestamp2date( $theExdate, $parno ); |
2554
|
|
|
elseif( is_array( $theExdate )) |
2555
|
|
|
$exdatea = $this->_date_time_array( $theExdate, $parno ); |
2556
|
|
|
elseif( 8 <= strlen( trim( $theExdate ))) // ex. 2006-08-03 10:12:18 |
2557
|
|
|
$exdatea = $this->_date_time_string( $theExdate, $parno ); |
2558
|
|
View Code Duplication |
if( 3 == $parno ) |
2559
|
|
|
unset( $exdatea['hour'], $exdatea['min'], $exdatea['sec'], $exdatea['tz'] ); |
2560
|
|
|
elseif( isset( $exdatea['tz'] )) |
2561
|
|
|
$exdatea['tz'] = (string) $exdatea['tz']; |
2562
|
|
View Code Duplication |
if( isset( $input['params']['TZID'] ) || |
2563
|
|
|
( isset( $exdatea['tz'] ) && !$this->_isOffset( $exdatea['tz'] )) || |
2564
|
|
|
( isset( $input['value'][0] ) && ( !isset( $input['value'][0]['tz'] ))) || |
2565
|
|
|
( isset( $input['value'][0]['tz'] ) && !$this->_isOffset( $input['value'][0]['tz'] ))) |
2566
|
|
|
unset( $exdatea['tz'] ); |
2567
|
|
|
$input['value'][] = $exdatea; |
2568
|
|
|
} |
2569
|
|
|
if( 0 >= count( $input['value'] )) |
2570
|
|
|
return FALSE; |
2571
|
|
View Code Duplication |
if( 3 == $parno ) { |
2572
|
|
|
$input['params']['VALUE'] = 'DATE'; |
2573
|
|
|
unset( $input['params']['TZID'] ); |
2574
|
|
|
} |
2575
|
|
|
$this->_setMval( $this->exdate, $input['value'], $input['params'], FALSE, $index ); |
|
|
|
|
2576
|
|
|
return TRUE; |
2577
|
|
|
} |
2578
|
|
|
/*********************************************************************************/ |
2579
|
|
|
/** |
2580
|
|
|
* Property Name: EXRULE |
2581
|
|
|
*/ |
2582
|
|
|
/** |
2583
|
|
|
* creates formatted output for calendar component property exrule |
2584
|
|
|
* |
2585
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2586
|
|
|
* @since 2.4.8 - 2008-10-22 |
2587
|
|
|
* @return string |
2588
|
|
|
*/ |
2589
|
|
|
function createExrule() { |
2590
|
|
|
if( empty( $this->exrule )) return FALSE; |
2591
|
|
|
return $this->_format_recur( 'EXRULE', $this->exrule ); |
2592
|
|
|
} |
2593
|
|
|
/** |
2594
|
|
|
* set calendar component property exdate |
2595
|
|
|
* |
2596
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2597
|
|
|
* @since 2.5.1 - 2008-11-05 |
2598
|
|
|
* @param array $exruleset |
2599
|
|
|
* @param array $params, optional |
|
|
|
|
2600
|
|
|
* @param integer $index, optional |
|
|
|
|
2601
|
|
|
* @return bool |
2602
|
|
|
*/ |
2603
|
|
|
function setExrule( $exruleset, $params=FALSE, $index=FALSE ) { |
2604
|
|
|
if( empty( $exruleset )) if( $this->getConfig( 'allowEmpty' )) $exruleset = null; else return FALSE; |
2605
|
|
|
$this->_setMval( $this->exrule, $this->_setRexrule( $exruleset ), $params, FALSE, $index ); |
|
|
|
|
2606
|
|
|
return TRUE; |
2607
|
|
|
} |
2608
|
|
|
/*********************************************************************************/ |
2609
|
|
|
/** |
2610
|
|
|
* Property Name: FREEBUSY |
2611
|
|
|
*/ |
2612
|
|
|
/** |
2613
|
|
|
* creates formatted output for calendar component property freebusy |
2614
|
|
|
* |
2615
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2616
|
|
|
* @since 2.4.8 - 2008-10-22 |
2617
|
|
|
* @return string |
2618
|
|
|
*/ |
2619
|
|
|
function createFreebusy() { |
2620
|
|
|
if( empty( $this->freebusy )) return FALSE; |
2621
|
|
|
$output = null; |
2622
|
|
|
foreach( $this->freebusy as $freebusyPart ) { |
2623
|
|
|
if( empty( $freebusyPart['value'] )) { |
2624
|
|
|
if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'FREEBUSY' ); |
2625
|
|
|
continue; |
2626
|
|
|
} |
2627
|
|
|
$attributes = $content = null; |
2628
|
|
|
if( isset( $freebusyPart['value']['fbtype'] )) { |
2629
|
|
|
$attributes .= $this->intAttrDelimiter.'FBTYPE='.$freebusyPart['value']['fbtype']; |
2630
|
|
|
unset( $freebusyPart['value']['fbtype'] ); |
2631
|
|
|
$freebusyPart['value'] = array_values( $freebusyPart['value'] ); |
2632
|
|
|
} |
2633
|
|
|
else |
2634
|
|
|
$attributes .= $this->intAttrDelimiter.'FBTYPE=BUSY'; |
2635
|
|
|
$attributes .= $this->_createParams( $freebusyPart['params'] ); |
2636
|
|
|
$fno = 1; |
2637
|
|
|
$cnt = count( $freebusyPart['value']); |
2638
|
|
|
foreach( $freebusyPart['value'] as $periodix => $freebusyPeriod ) { |
2639
|
|
|
$formatted = $this->_format_date_time( $freebusyPeriod[0] ); |
2640
|
|
|
$content .= $formatted; |
2641
|
|
|
$content .= '/'; |
2642
|
|
|
$cnt2 = count( $freebusyPeriod[1]); |
2643
|
|
|
if( array_key_exists( 'year', $freebusyPeriod[1] )) // date-time |
2644
|
|
|
$cnt2 = 7; |
2645
|
|
|
elseif( array_key_exists( 'week', $freebusyPeriod[1] )) // duration |
2646
|
|
|
$cnt2 = 5; |
2647
|
|
|
if(( 7 == $cnt2 ) && // period= -> date-time |
2648
|
|
|
isset( $freebusyPeriod[1]['year'] ) && |
2649
|
|
|
isset( $freebusyPeriod[1]['month'] ) && |
2650
|
|
|
isset( $freebusyPeriod[1]['day'] )) { |
2651
|
|
|
$content .= $this->_format_date_time( $freebusyPeriod[1] ); |
2652
|
|
|
} |
2653
|
|
|
else { // period= -> dur-time |
2654
|
|
|
$content .= $this->_format_duration( $freebusyPeriod[1] ); |
2655
|
|
|
} |
2656
|
|
|
if( $fno < $cnt ) |
2657
|
|
|
$content .= ','; |
2658
|
|
|
$fno++; |
2659
|
|
|
} |
2660
|
|
|
$output .= $this->_createElement( 'FREEBUSY', $attributes, $content ); |
2661
|
|
|
} |
2662
|
|
|
return $output; |
2663
|
|
|
} |
2664
|
|
|
/** |
2665
|
|
|
* set calendar component property freebusy |
2666
|
|
|
* |
2667
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2668
|
|
|
* @since 2.5.1 - 2008-11-05 |
2669
|
|
|
* @param string $fbType |
2670
|
|
|
* @param array $fbValues |
2671
|
|
|
* @param array $params, optional |
|
|
|
|
2672
|
|
|
* @param integer $index, optional |
|
|
|
|
2673
|
|
|
* @return bool |
2674
|
|
|
*/ |
2675
|
|
|
function setFreebusy( $fbType, $fbValues, $params=FALSE, $index=FALSE ) { |
2676
|
|
View Code Duplication |
if( empty( $fbValues )) { |
2677
|
|
|
if( $this->getConfig( 'allowEmpty' )) { |
2678
|
|
|
$this->_setMval( $this->freebusy, null, $params, FALSE, $index ); |
2679
|
|
|
return TRUE; |
2680
|
|
|
} |
2681
|
|
|
else |
2682
|
|
|
return FALSE; |
2683
|
|
|
} |
2684
|
|
|
$fbType = strtoupper( $fbType ); |
2685
|
|
|
if(( !in_array( $fbType, array( 'FREE', 'BUSY', 'BUSY-UNAVAILABLE', 'BUSY-TENTATIVE' ))) && |
2686
|
|
|
( 'X-' != substr( $fbType, 0, 2 ))) |
2687
|
|
|
$fbType = 'BUSY'; |
2688
|
|
|
$input = array( 'fbtype' => $fbType ); |
2689
|
|
|
foreach( $fbValues as $fbPeriod ) { // periods => period |
2690
|
|
|
$freebusyPeriod = array(); |
2691
|
|
|
foreach( $fbPeriod as $fbMember ) { // pairs => singlepart |
2692
|
|
|
$freebusyPairMember = array(); |
2693
|
|
|
if( is_array( $fbMember )) { |
2694
|
|
|
if( $this->_isArrayDate( $fbMember )) { // date-time value |
2695
|
|
|
$freebusyPairMember = $this->_date_time_array( $fbMember, 7 ); |
2696
|
|
|
$freebusyPairMember['tz'] = 'Z'; |
2697
|
|
|
} |
2698
|
|
|
elseif( $this->_isArrayTimestampDate( $fbMember )) { // timestamp value |
2699
|
|
|
$freebusyPairMember = $this->_timestamp2date( $fbMember['timestamp'], 7 ); |
2700
|
|
|
$freebusyPairMember['tz'] = 'Z'; |
2701
|
|
|
} |
2702
|
|
|
else { // array format duration |
2703
|
|
|
$freebusyPairMember = $this->_duration_array( $fbMember ); |
2704
|
|
|
} |
2705
|
|
|
} |
2706
|
|
View Code Duplication |
elseif(( 3 <= strlen( trim( $fbMember ))) && // string format duration |
2707
|
|
|
( in_array( $fbMember{0}, array( 'P', '+', '-' )))) { |
2708
|
|
|
if( 'P' != $fbMember{0} ) |
2709
|
|
|
$fbmember = substr( $fbMember, 1 ); |
2710
|
|
|
$freebusyPairMember = $this->_duration_string( $fbMember ); |
2711
|
|
|
} |
2712
|
|
|
elseif( 8 <= strlen( trim( $fbMember ))) { // text date ex. 2006-08-03 10:12:18 |
2713
|
|
|
$freebusyPairMember = $this->_date_time_string( $fbMember, 7 ); |
2714
|
|
|
$freebusyPairMember['tz'] = 'Z'; |
2715
|
|
|
} |
2716
|
|
|
$freebusyPeriod[] = $freebusyPairMember; |
2717
|
|
|
} |
2718
|
|
|
$input[] = $freebusyPeriod; |
2719
|
|
|
} |
2720
|
|
|
$this->_setMval( $this->freebusy, $input, $params, FALSE, $index ); |
2721
|
|
|
return TRUE; |
2722
|
|
|
} |
2723
|
|
|
/*********************************************************************************/ |
2724
|
|
|
/** |
2725
|
|
|
* Property Name: GEO |
2726
|
|
|
*/ |
2727
|
|
|
/** |
2728
|
|
|
* creates formatted output for calendar component property geo |
2729
|
|
|
* |
2730
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2731
|
|
|
* @since 2.4.8 - 2008-10-21 |
2732
|
|
|
* @return string |
2733
|
|
|
*/ |
2734
|
|
|
function createGeo() { |
2735
|
|
|
if( empty( $this->geo )) return FALSE; |
2736
|
|
|
if( empty( $this->geo['value'] )) |
2737
|
|
|
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'GEO' ) : FALSE; |
2738
|
|
|
$attributes = $this->_createParams( $this->geo['params'] ); |
2739
|
|
|
$content = null; |
2740
|
|
|
$content .= number_format( (float) $this->geo['value']['latitude'], 6, '.', ''); |
2741
|
|
|
$content .= ';'; |
2742
|
|
|
$content .= number_format( (float) $this->geo['value']['longitude'], 6, '.', ''); |
2743
|
|
|
return $this->_createElement( 'GEO', $attributes, $content ); |
2744
|
|
|
} |
2745
|
|
|
/** |
2746
|
|
|
* set calendar component property geo |
2747
|
|
|
* |
2748
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2749
|
|
|
* @since 2.4.8 - 2008-11-04 |
2750
|
|
|
* @param float $latitude |
2751
|
|
|
* @param float $longitude |
2752
|
|
|
* @param array $params optional |
2753
|
|
|
* @return bool |
2754
|
|
|
*/ |
2755
|
|
|
function setGeo( $latitude, $longitude, $params=FALSE ) { |
2756
|
|
|
if( !empty( $latitude ) && !empty( $longitude )) { |
2757
|
|
|
if( !is_array( $this->geo )) $this->geo = array(); |
2758
|
|
|
$this->geo['value']['latitude'] = $latitude; |
2759
|
|
|
$this->geo['value']['longitude'] = $longitude; |
2760
|
|
|
$this->geo['params'] = $this->_setParams( $params ); |
|
|
|
|
2761
|
|
|
} |
2762
|
|
|
elseif( $this->getConfig( 'allowEmpty' )) |
2763
|
|
|
$this->geo = array( 'value' => null, 'params' => $this->_setParams( $params ) ); |
|
|
|
|
2764
|
|
|
else |
2765
|
|
|
return FALSE; |
2766
|
|
|
return TRUE; |
2767
|
|
|
} |
2768
|
|
|
/*********************************************************************************/ |
2769
|
|
|
/** |
2770
|
|
|
* Property Name: LAST-MODIFIED |
2771
|
|
|
*/ |
2772
|
|
|
/** |
2773
|
|
|
* creates formatted output for calendar component property last-modified |
2774
|
|
|
* |
2775
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2776
|
|
|
* @since 2.4.8 - 2008-10-21 |
2777
|
|
|
* @return string |
2778
|
|
|
*/ |
2779
|
|
View Code Duplication |
function createLastModified() { |
2780
|
|
|
if( empty( $this->lastmodified )) return FALSE; |
2781
|
|
|
$attributes = $this->_createParams( $this->lastmodified['params'] ); |
2782
|
|
|
$formatted = $this->_format_date_time( $this->lastmodified['value'], 7 ); |
2783
|
|
|
return $this->_createElement( 'LAST-MODIFIED', $attributes, $formatted ); |
2784
|
|
|
} |
2785
|
|
|
/** |
2786
|
|
|
* set calendar component property completed |
2787
|
|
|
* |
2788
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2789
|
|
|
* @since 2.4.8 - 2008-10-23 |
2790
|
|
|
* @param mixed $year optional |
2791
|
|
|
* @param mixed $month optional |
2792
|
|
|
* @param int $day optional |
2793
|
|
|
* @param int $hour optional |
2794
|
|
|
* @param int $min optional |
2795
|
|
|
* @param int $sec optional |
2796
|
|
|
* @param array $params optional |
2797
|
|
|
* @return boll |
2798
|
|
|
*/ |
2799
|
|
|
function setLastModified( $year=FALSE, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) { |
2800
|
|
View Code Duplication |
if( empty( $year )) |
2801
|
|
|
$year = date('Ymd\THis', mktime( date( 'H' ), date( 'i' ), date( 's' ) - date( 'Z'), date( 'm' ), date( 'd' ), date( 'Y' ))); |
2802
|
|
|
$this->lastmodified = $this->_setDate2( $year, $month, $day, $hour, $min, $sec, $params ); |
2803
|
|
|
return TRUE; |
2804
|
|
|
} |
2805
|
|
|
/*********************************************************************************/ |
2806
|
|
|
/** |
2807
|
|
|
* Property Name: LOCATION |
2808
|
|
|
*/ |
2809
|
|
|
/** |
2810
|
|
|
* creates formatted output for calendar component property location |
2811
|
|
|
* |
2812
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2813
|
|
|
* @since 2.4.8 - 2008-10-22 |
2814
|
|
|
* @return string |
2815
|
|
|
*/ |
2816
|
|
View Code Duplication |
function createLocation() { |
2817
|
|
|
if( empty( $this->location )) return FALSE; |
2818
|
|
|
if( empty( $this->location['value'] )) |
2819
|
|
|
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'LOCATION' ) : FALSE; |
2820
|
|
|
$attributes = $this->_createParams( $this->location['params'], array( 'ALTREP', 'LANGUAGE' )); |
2821
|
|
|
$content = $this->_strrep( $this->location['value'] ); |
2822
|
|
|
return $this->_createElement( 'LOCATION', $attributes, $content ); |
2823
|
|
|
} |
2824
|
|
|
/** |
2825
|
|
|
* set calendar component property location |
2826
|
|
|
' |
2827
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2828
|
|
|
* @since 2.4.8 - 2008-11-04 |
2829
|
|
|
* @param string $value |
2830
|
|
|
* @param array params optional |
2831
|
|
|
* @return bool |
2832
|
|
|
*/ |
2833
|
|
|
function setLocation( $value, $params=FALSE ) { |
2834
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
2835
|
|
|
$this->location = array( 'value' => $value, 'params' => $this->_setParams( $params )); |
2836
|
|
|
return TRUE; |
2837
|
|
|
} |
2838
|
|
|
/*********************************************************************************/ |
2839
|
|
|
/** |
2840
|
|
|
* Property Name: ORGANIZER |
2841
|
|
|
*/ |
2842
|
|
|
/** |
2843
|
|
|
* creates formatted output for calendar component property organizer |
2844
|
|
|
* |
2845
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2846
|
|
|
* @since 2.4.8 - 2008-10-21 |
2847
|
|
|
* @return string |
2848
|
|
|
*/ |
2849
|
|
|
function createOrganizer() { |
2850
|
|
|
if( empty( $this->organizer )) return FALSE; |
2851
|
|
|
if( empty( $this->organizer['value'] )) |
2852
|
|
|
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'ORGANIZER' ) : FALSE; |
2853
|
|
|
$attributes = $this->_createParams( $this->organizer['params'] |
2854
|
|
|
, array( 'CN', 'DIR', 'LANGUAGE', 'SENT-BY' )); |
2855
|
|
|
$content = 'MAILTO:'.$this->organizer['value']; |
2856
|
|
|
return $this->_createElement( 'ORGANIZER', $attributes, $content ); |
2857
|
|
|
} |
2858
|
|
|
/** |
2859
|
|
|
* set calendar component property organizer |
2860
|
|
|
* |
2861
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2862
|
|
|
* @since 2.4.8 - 2008-11-04 |
2863
|
|
|
* @param string $value |
2864
|
|
|
* @param array params optional |
2865
|
|
|
* @return bool |
2866
|
|
|
*/ |
2867
|
|
|
function setOrganizer( $value, $params=FALSE ) { |
2868
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
2869
|
|
|
$value = str_replace ( 'MAILTO:', '', $value ); |
2870
|
|
|
$value = str_replace ( 'mailto:', '', $value ); |
2871
|
|
|
$this->organizer = array( 'value' => $value, 'params' => $this->_setParams( $params )); |
2872
|
|
|
if( isset( $this->organizer['params']['SENT-BY'] )) { |
2873
|
|
|
if( 'MAILTO' == strtoupper( substr( $this->organizer['params']['SENT-BY'], 0, 6 ))) |
2874
|
|
|
$this->organizer['params']['SENT-BY'] = substr( $this->organizer['params']['SENT-BY'], 7 ); |
2875
|
|
|
} |
2876
|
|
|
return TRUE; |
2877
|
|
|
} |
2878
|
|
|
/*********************************************************************************/ |
2879
|
|
|
/** |
2880
|
|
|
* Property Name: PERCENT-COMPLETE |
2881
|
|
|
*/ |
2882
|
|
|
/** |
2883
|
|
|
* creates formatted output for calendar component property percent-complete |
2884
|
|
|
* |
2885
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2886
|
|
|
* @since 2.4.8 - 2008-10-22 |
2887
|
|
|
* @return string |
2888
|
|
|
*/ |
2889
|
|
|
function createPercentComplete() { |
2890
|
|
|
if( empty( $this->percentcomplete )) return FALSE; |
2891
|
|
|
if( empty( $this->percentcomplete['value'] )) |
2892
|
|
|
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'PERCENT-COMPLETE' ) : FALSE; |
2893
|
|
|
$attributes = $this->_createParams( $this->percentcomplete['params'] ); |
2894
|
|
|
return $this->_createElement( 'PERCENT-COMPLETE', $attributes, $this->percentcomplete['value'] ); |
2895
|
|
|
} |
2896
|
|
|
/** |
2897
|
|
|
* set calendar component property percent-complete |
2898
|
|
|
* |
2899
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2900
|
|
|
* @since 2.4.8 - 2008-11-04 |
2901
|
|
|
* @param int $value |
2902
|
|
|
* @param array $params optional |
2903
|
|
|
* @return bool |
2904
|
|
|
*/ |
2905
|
|
|
function setPercentComplete( $value, $params=FALSE ) { |
2906
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
2907
|
|
|
$this->percentcomplete = array( 'value' => $value, 'params' => $this->_setParams( $params )); |
|
|
|
|
2908
|
|
|
return TRUE; |
2909
|
|
|
} |
2910
|
|
|
/*********************************************************************************/ |
2911
|
|
|
/** |
2912
|
|
|
* Property Name: PRIORITY |
2913
|
|
|
*/ |
2914
|
|
|
/** |
2915
|
|
|
* creates formatted output for calendar component property priority |
2916
|
|
|
* |
2917
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2918
|
|
|
* @since 2.4.8 - 2008-10-21 |
2919
|
|
|
* @return string |
2920
|
|
|
*/ |
2921
|
|
|
function createPriority() { |
2922
|
|
|
if( empty( $this->priority )) return FALSE; |
2923
|
|
|
if( empty( $this->priority['value'] )) |
2924
|
|
|
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'PRIORITY' ) : FALSE; |
2925
|
|
|
$attributes = $this->_createParams( $this->priority['params'] ); |
2926
|
|
|
return $this->_createElement( 'PRIORITY', $attributes, $this->priority['value'] ); |
2927
|
|
|
} |
2928
|
|
|
/** |
2929
|
|
|
* set calendar component property priority |
2930
|
|
|
* |
2931
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2932
|
|
|
* @since 2.4.8 - 2008-11-04 |
2933
|
|
|
* @param int $value |
2934
|
|
|
* @param array $params optional |
2935
|
|
|
* @return bool |
2936
|
|
|
*/ |
2937
|
|
|
function setPriority( $value, $params=FALSE ) { |
2938
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
2939
|
|
|
$this->priority = array( 'value' => $value, 'params' => $this->_setParams( $params )); |
|
|
|
|
2940
|
|
|
return TRUE; |
2941
|
|
|
} |
2942
|
|
|
/*********************************************************************************/ |
2943
|
|
|
/** |
2944
|
|
|
* Property Name: RDATE |
2945
|
|
|
*/ |
2946
|
|
|
/** |
2947
|
|
|
* creates formatted output for calendar component property rdate |
2948
|
|
|
* |
2949
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
2950
|
|
|
* @since 2.4.16 - 2008-10-26 |
2951
|
|
|
* @return string |
2952
|
|
|
*/ |
2953
|
|
|
function createRdate() { |
2954
|
|
|
if( empty( $this->rdate )) return FALSE; |
2955
|
|
|
$utctime = ( in_array( $this->objName, array( 'vtimezone', 'standard', 'daylight' ))) ? TRUE : FALSE; |
2956
|
|
|
$output = null; |
2957
|
|
|
if( $utctime ) |
2958
|
|
|
unset( $this->rdate['params']['TZID'] ); |
2959
|
|
|
foreach( $this->rdate as $theRdate ) { |
2960
|
|
|
if( empty( $theRdate['value'] )) { |
2961
|
|
|
if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'RDATE' ); |
2962
|
|
|
continue; |
2963
|
|
|
} |
2964
|
|
|
if( $utctime ) |
2965
|
|
|
unset( $theRdate['params']['TZID'] ); |
2966
|
|
|
$attributes = $this->_createParams( $theRdate['params'] ); |
2967
|
|
|
$cnt = count( $theRdate['value'] ); |
2968
|
|
|
$content = null; |
2969
|
|
|
$rno = 1; |
2970
|
|
|
foreach( $theRdate['value'] as $rpix => $rdatePart ) { |
2971
|
|
|
$contentPart = null; |
2972
|
|
|
if( is_array( $rdatePart ) && |
2973
|
|
|
isset( $theRdate['params']['VALUE'] ) && ( 'PERIOD' == $theRdate['params']['VALUE'] )) { // PERIOD |
2974
|
|
|
if( $utctime ) |
2975
|
|
|
unset( $rdatePart[0]['tz'] ); |
2976
|
|
|
$formatted = $this->_format_date_time( $rdatePart[0]); // PERIOD part 1 |
2977
|
|
View Code Duplication |
if( $utctime || !empty( $theRdate['params']['TZID'] )) |
2978
|
|
|
$formatted = str_replace( 'Z', '', $formatted); |
2979
|
|
View Code Duplication |
if( 0 < $rpix ) { |
2980
|
|
|
if( !empty( $rdatePart[0]['tz'] ) && $this->_isOffset( $rdatePart[0]['tz'] )) { |
2981
|
|
|
if( 'Z' != substr( $formatted, -1 )) $formatted .= 'Z'; |
2982
|
|
|
} |
2983
|
|
|
else |
2984
|
|
|
$formatted = str_replace( 'Z', '', $formatted ); |
2985
|
|
|
} |
2986
|
|
|
$contentPart .= $formatted; |
2987
|
|
|
$contentPart .= '/'; |
2988
|
|
|
$cnt2 = count( $rdatePart[1]); |
2989
|
|
|
if( array_key_exists( 'year', $rdatePart[1] )) { |
2990
|
|
|
if( array_key_exists( 'hour', $rdatePart[1] )) |
2991
|
|
|
$cnt2 = 7; // date-time |
2992
|
|
|
else |
2993
|
|
|
$cnt2 = 3; // date |
2994
|
|
|
} |
2995
|
|
|
elseif( array_key_exists( 'week', $rdatePart[1] )) // duration |
2996
|
|
|
$cnt2 = 5; |
2997
|
|
|
if(( 7 == $cnt2 ) && // period= -> date-time |
2998
|
|
|
isset( $rdatePart[1]['year'] ) && |
2999
|
|
|
isset( $rdatePart[1]['month'] ) && |
3000
|
|
|
isset( $rdatePart[1]['day'] )) { |
3001
|
|
|
if( $utctime ) |
3002
|
|
|
unset( $rdatePart[1]['tz'] ); |
3003
|
|
|
$formatted = $this->_format_date_time( $rdatePart[1] ); // PERIOD part 2 |
3004
|
|
View Code Duplication |
if( $utctime || !empty( $theRdate['params']['TZID'] )) |
3005
|
|
|
$formatted = str_replace( 'Z', '', $formatted); |
3006
|
|
View Code Duplication |
if( !empty( $rdatePart[0]['tz'] ) && $this->_isOffset( $rdatePart[0]['tz'] )) { |
3007
|
|
|
if( 'Z' != substr( $formatted, -1 )) $formatted .= 'Z'; |
3008
|
|
|
} |
3009
|
|
|
else |
3010
|
|
|
$formatted = str_replace( 'Z', '', $formatted ); |
3011
|
|
|
$contentPart .= $formatted; |
3012
|
|
|
} |
3013
|
|
|
else { // period= -> dur-time |
3014
|
|
|
$contentPart .= $this->_format_duration( $rdatePart[1] ); |
3015
|
|
|
} |
3016
|
|
|
} // PERIOD end |
3017
|
|
|
else { // SINGLE date start |
3018
|
|
|
if( $utctime ) |
3019
|
|
|
unset( $rdatePart['tz'] ); |
3020
|
|
|
$formatted = $this->_format_date_time( $rdatePart); |
3021
|
|
View Code Duplication |
if( $utctime || !empty( $theRdate['params']['TZID'] )) |
3022
|
|
|
$formatted = str_replace( 'Z', '', $formatted); |
3023
|
|
|
if( !$utctime && ( 0 < $rpix )) { |
3024
|
|
View Code Duplication |
if( !empty( $theRdate['value'][0]['tz'] ) && $this->_isOffset( $theRdate['value'][0]['tz'] )) { |
3025
|
|
|
if( 'Z' != substr( $formatted, -1 )) |
3026
|
|
|
$formatted .= 'Z'; |
3027
|
|
|
} |
3028
|
|
|
else |
3029
|
|
|
$formatted = str_replace( 'Z', '', $formatted ); |
3030
|
|
|
} |
3031
|
|
|
$contentPart .= $formatted; |
3032
|
|
|
} |
3033
|
|
|
$content .= $contentPart; |
3034
|
|
|
if( $rno < $cnt ) |
3035
|
|
|
$content .= ','; |
3036
|
|
|
$rno++; |
3037
|
|
|
} |
3038
|
|
|
$output .= $this->_createElement( 'RDATE', $attributes, $content ); |
3039
|
|
|
} |
3040
|
|
|
return $output; |
3041
|
|
|
} |
3042
|
|
|
/** |
3043
|
|
|
* set calendar component property rdate |
3044
|
|
|
* |
3045
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3046
|
|
|
* @since 2.5.1 - 2008-11-07 |
3047
|
|
|
* @param array $rdates |
3048
|
|
|
* @param array $params, optional |
|
|
|
|
3049
|
|
|
* @param integer $index, optional |
|
|
|
|
3050
|
|
|
* @return bool |
3051
|
|
|
*/ |
3052
|
|
|
function setRdate( $rdates, $params=FALSE, $index=FALSE ) { |
3053
|
|
View Code Duplication |
if( empty( $rdates )) { |
3054
|
|
|
if( $this->getConfig( 'allowEmpty' )) { |
3055
|
|
|
$this->_setMval( $this->rdate, null, $params, FALSE, $index ); |
3056
|
|
|
return TRUE; |
3057
|
|
|
} |
3058
|
|
|
else |
3059
|
|
|
return FALSE; |
3060
|
|
|
} |
3061
|
|
|
$input = array( 'params' => $this->_setParams( $params, array( 'VALUE' => 'DATE-TIME' ))); |
3062
|
|
|
if( in_array( $this->objName, array( 'vtimezone', 'standard', 'daylight' ))) { |
3063
|
|
|
unset( $input['params']['TZID'] ); |
3064
|
|
|
$input['params']['VALUE'] = 'DATE-TIME'; |
3065
|
|
|
} |
3066
|
|
|
/* check if PERIOD, if not set */ |
3067
|
|
|
if((!isset( $input['params']['VALUE'] ) || !in_array( $input['params']['VALUE'], array( 'DATE', 'PERIOD' ))) && |
3068
|
|
|
isset( $rdates[0] ) && is_array( $rdates[0] ) && ( 2 == count( $rdates[0] )) && |
3069
|
|
|
isset( $rdates[0][0] ) && isset( $rdates[0][1] ) && !isset( $rdates[0]['timestamp'] ) && |
3070
|
|
|
(( is_array( $rdates[0][0] ) && ( isset( $rdates[0][0]['timestamp'] ) || |
3071
|
|
|
$this->_isArrayDate( $rdates[0][0] ))) || |
3072
|
|
|
( is_string( $rdates[0][0] ) && ( 8 <= strlen( trim( $rdates[0][0] ))))) && |
3073
|
|
|
( is_array( $rdates[0][1] ) || ( is_string( $rdates[0][1] ) && ( 3 <= strlen( trim( $rdates[0][1] )))))) |
3074
|
|
|
$input['params']['VALUE'] = 'PERIOD'; |
3075
|
|
|
/* check 1:st date, upd. $parno (opt) and save ev. timezone **/ |
3076
|
|
|
$date = reset( $rdates ); |
3077
|
|
|
if( isset( $input['params']['VALUE'] ) && ( 'PERIOD' == $input['params']['VALUE'] )) // PERIOD |
3078
|
|
|
$date = reset( $date ); |
3079
|
|
|
$this->_chkdatecfg( $date, $parno, $input['params'] ); |
3080
|
|
|
if( in_array( $this->objName, array( 'vtimezone', 'standard', 'daylight' ))) |
3081
|
|
|
unset( $input['params']['TZID'] ); |
3082
|
|
|
$this->_existRem( $input['params'], 'VALUE', 'DATE-TIME' ); // remove default |
|
|
|
|
3083
|
|
|
foreach( $rdates as $rpix => $theRdate ) { |
3084
|
|
|
$inputa = null; |
3085
|
|
|
if( is_array( $theRdate )) { |
3086
|
|
|
if( isset( $input['params']['VALUE'] ) && ( 'PERIOD' == $input['params']['VALUE'] )) { // PERIOD |
3087
|
|
|
foreach( $theRdate as $rix => $rPeriod ) { |
3088
|
|
|
if( is_array( $rPeriod )) { |
3089
|
|
|
if( $this->_isArrayTimestampDate( $rPeriod )) // timestamp |
3090
|
|
|
$inputab = ( isset( $rPeriod['tz'] )) ? $this->_timestamp2date( $rPeriod, $parno ) : $this->_timestamp2date( $rPeriod, 6 ); |
3091
|
|
|
elseif( $this->_isArrayDate( $rPeriod )) |
3092
|
|
|
$inputab = ( 3 < count ( $rPeriod )) ? $this->_date_time_array( $rPeriod, $parno ) : $this->_date_time_array( $rPeriod, 6 ); |
3093
|
|
|
elseif (( 1 == count( $rPeriod )) && ( 8 <= strlen( reset( $rPeriod )))) // text-date |
3094
|
|
|
$inputab = $this->_date_time_string( reset( $rPeriod ), $parno ); |
3095
|
|
|
else // array format duration |
3096
|
|
|
$inputab = $this->_duration_array( $rPeriod ); |
3097
|
|
|
} |
3098
|
|
View Code Duplication |
elseif(( 3 <= strlen( trim( $rPeriod ))) && // string format duration |
3099
|
|
|
( in_array( $rPeriod{0}, array( 'P', '+', '-' )))) { |
3100
|
|
|
if( 'P' != $rPeriod{0} ) |
3101
|
|
|
$rPeriod = substr( $rPeriod, 1 ); |
3102
|
|
|
$inputab = $this->_duration_string( $rPeriod ); |
3103
|
|
|
} |
3104
|
|
|
elseif( 8 <= strlen( trim( $rPeriod ))) // text date ex. 2006-08-03 10:12:18 |
3105
|
|
|
$inputab = $this->_date_time_string( $rPeriod, $parno ); |
3106
|
|
|
if( isset( $input['params']['TZID'] ) || |
3107
|
|
|
( isset( $inputab['tz'] ) && !$this->_isOffset( $inputab['tz'] )) || |
3108
|
|
|
( isset( $inputa[0] ) && ( !isset( $inputa[0]['tz'] ))) || |
3109
|
|
|
( isset( $inputa[0]['tz'] ) && !$this->_isOffset( $inputa[0]['tz'] ))) |
3110
|
|
|
unset( $inputab['tz'] ); |
3111
|
|
|
$inputa[] = $inputab; |
3112
|
|
|
} |
3113
|
|
|
} // PERIOD end |
3114
|
|
|
elseif ( $this->_isArrayTimestampDate( $theRdate )) // timestamp |
3115
|
|
|
$inputa = $this->_timestamp2date( $theRdate, $parno ); |
3116
|
|
|
else // date[-time] |
3117
|
|
|
$inputa = $this->_date_time_array( $theRdate, $parno ); |
3118
|
|
|
} |
3119
|
|
|
elseif( 8 <= strlen( trim( $theRdate ))) // text date ex. 2006-08-03 10:12:18 |
3120
|
|
|
$inputa = $this->_date_time_string( $theRdate, $parno ); |
3121
|
|
|
if( !isset( $input['params']['VALUE'] ) || ( 'PERIOD' != $input['params']['VALUE'] )) { // no PERIOD |
3122
|
|
View Code Duplication |
if( 3 == $parno ) |
3123
|
|
|
unset( $inputa['hour'], $inputa['min'], $inputa['sec'], $inputa['tz'] ); |
3124
|
|
|
elseif( isset( $inputa['tz'] )) |
3125
|
|
|
$inputa['tz'] = (string) $inputa['tz']; |
3126
|
|
View Code Duplication |
if( isset( $input['params']['TZID'] ) || |
3127
|
|
|
( isset( $inputa['tz'] ) && !$this->_isOffset( $inputa['tz'] )) || |
3128
|
|
|
( isset( $input['value'][0] ) && ( !isset( $input['value'][0]['tz'] ))) || |
3129
|
|
|
( isset( $input['value'][0]['tz'] ) && !$this->_isOffset( $input['value'][0]['tz'] ))) |
3130
|
|
|
unset( $inputa['tz'] ); |
3131
|
|
|
} |
3132
|
|
|
$input['value'][] = $inputa; |
3133
|
|
|
} |
3134
|
|
View Code Duplication |
if( 3 == $parno ) { |
3135
|
|
|
$input['params']['VALUE'] = 'DATE'; |
3136
|
|
|
unset( $input['params']['TZID'] ); |
3137
|
|
|
} |
3138
|
|
|
$this->_setMval( $this->rdate, $input['value'], $input['params'], FALSE, $index ); |
|
|
|
|
3139
|
|
|
return TRUE; |
3140
|
|
|
} |
3141
|
|
|
/*********************************************************************************/ |
3142
|
|
|
/** |
3143
|
|
|
* Property Name: RECURRENCE-ID |
3144
|
|
|
*/ |
3145
|
|
|
/** |
3146
|
|
|
* creates formatted output for calendar component property recurrence-id |
3147
|
|
|
* |
3148
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3149
|
|
|
* @since 2.4.8 - 2008-10-21 |
3150
|
|
|
* @return string |
3151
|
|
|
*/ |
3152
|
|
View Code Duplication |
function createRecurrenceid() { |
3153
|
|
|
if( empty( $this->recurrenceid )) return FALSE; |
3154
|
|
|
if( empty( $this->recurrenceid['value'] )) |
3155
|
|
|
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'RECURRENCE-ID' ) : FALSE; |
3156
|
|
|
$formatted = $this->_format_date_time( $this->recurrenceid['value'] ); |
3157
|
|
|
$attributes = $this->_createParams( $this->recurrenceid['params'] ); |
3158
|
|
|
return $this->_createElement( 'RECURRENCE-ID', $attributes, $formatted ); |
3159
|
|
|
} |
3160
|
|
|
/** |
3161
|
|
|
* set calendar component property recurrence-id |
3162
|
|
|
* |
3163
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3164
|
|
|
* @since 2.4.8 - 2008-10-23 |
3165
|
|
|
* @param mixed $year |
3166
|
|
|
* @param mixed $month optional |
3167
|
|
|
* @param int $day optional |
3168
|
|
|
* @param int $hour optional |
3169
|
|
|
* @param int $min optional |
3170
|
|
|
* @param int $sec optional |
3171
|
|
|
* @param array $params optional |
3172
|
|
|
* @return bool |
3173
|
|
|
*/ |
3174
|
|
View Code Duplication |
function setRecurrenceid( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $tz=FALSE, $params=FALSE ) { |
3175
|
|
|
if( empty( $year )) { |
3176
|
|
|
if( $this->getConfig( 'allowEmpty' )) { |
3177
|
|
|
$this->recurrenceid = array( 'value' => null, 'params' => null ); |
3178
|
|
|
return TRUE; |
3179
|
|
|
} |
3180
|
|
|
else |
3181
|
|
|
return FALSE; |
3182
|
|
|
} |
3183
|
|
|
$this->recurrenceid = $this->_setDate( $year, $month, $day, $hour, $min, $sec, $tz, $params ); |
3184
|
|
|
return TRUE; |
3185
|
|
|
} |
3186
|
|
|
/*********************************************************************************/ |
3187
|
|
|
/** |
3188
|
|
|
* Property Name: RELATED-TO |
3189
|
|
|
*/ |
3190
|
|
|
/** |
3191
|
|
|
* creates formatted output for calendar component property related-to |
3192
|
|
|
* |
3193
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3194
|
|
|
* @since 2.4.8 - 2008-10-23 |
3195
|
|
|
* @return string |
3196
|
|
|
*/ |
3197
|
|
|
function createRelatedTo() { |
3198
|
|
|
if( empty( $this->relatedto )) return FALSE; |
3199
|
|
|
$output = null; |
3200
|
|
|
foreach( $this->relatedto as $relation ) { |
3201
|
|
|
if( empty( $relation['value'] )) { |
3202
|
|
|
if( $this->getConfig( 'allowEmpty' )) $output.= $this->_createElement( 'RELATED-TO', $this->_createParams( $relation['params'] )); |
3203
|
|
|
continue; |
3204
|
|
|
} |
3205
|
|
|
$attributes = $this->_createParams( $relation['params'] ); |
3206
|
|
|
$content = ( 'xcal' != $this->format ) ? '<' : ''; |
3207
|
|
|
$content .= $this->_strrep( $relation['value'] ); |
3208
|
|
|
$content .= ( 'xcal' != $this->format ) ? '>' : ''; |
3209
|
|
|
$output .= $this->_createElement( 'RELATED-TO', $attributes, $content ); |
3210
|
|
|
} |
3211
|
|
|
return $output; |
3212
|
|
|
} |
3213
|
|
|
/** |
3214
|
|
|
* set calendar component property related-to |
3215
|
|
|
* |
3216
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3217
|
|
|
* @since 2.5.1 - 2008-11-07 |
3218
|
|
|
* @param float $relid |
|
|
|
|
3219
|
|
|
* @param array $params, optional |
|
|
|
|
3220
|
|
|
* @param index $index, optional |
|
|
|
|
3221
|
|
|
* @return bool |
3222
|
|
|
*/ |
3223
|
|
|
function setRelatedTo( $value, $params=FALSE, $index=FALSE ) { |
3224
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
3225
|
|
View Code Duplication |
if(( '<' == substr( $value, 0, 1 )) && ( '>' == substr( $value, -1 ))) |
3226
|
|
|
$value = substr( $value, 1, ( strlen( $value ) - 2 )); |
3227
|
|
|
$this->_existRem( $params, 'RELTYPE', 'PARENT', TRUE ); // remove default |
3228
|
|
|
$this->_setMval( $this->relatedto, $value, $params, FALSE, $index ); |
3229
|
|
|
return TRUE; |
3230
|
|
|
} |
3231
|
|
|
/*********************************************************************************/ |
3232
|
|
|
/** |
3233
|
|
|
* Property Name: REPEAT |
3234
|
|
|
*/ |
3235
|
|
|
/** |
3236
|
|
|
* creates formatted output for calendar component property repeat |
3237
|
|
|
* |
3238
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3239
|
|
|
* @since 2.4.8 - 2008-10-21 |
3240
|
|
|
* @return string |
3241
|
|
|
*/ |
3242
|
|
|
function createRepeat() { |
3243
|
|
|
if( empty( $this->repeat )) return FALSE; |
3244
|
|
|
if( empty( $this->repeat['value'] )) |
3245
|
|
|
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'REPEAT' ) : FALSE; |
3246
|
|
|
$attributes = $this->_createParams( $this->repeat['params'] ); |
3247
|
|
|
return $this->_createElement( 'REPEAT', $attributes, $this->repeat['value'] ); |
3248
|
|
|
} |
3249
|
|
|
/** |
3250
|
|
|
* set calendar component property transp |
3251
|
|
|
* |
3252
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3253
|
|
|
* @since 2.4.8 - 2008-11-04 |
3254
|
|
|
* @param string $value |
3255
|
|
|
* @param array $params optional |
3256
|
|
|
* @return void |
3257
|
|
|
*/ |
3258
|
|
|
function setRepeat( $value, $params=FALSE ) { |
3259
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
3260
|
|
|
$this->repeat = array( 'value' => $value, 'params' => $this->_setParams( $params )); |
|
|
|
|
3261
|
|
|
return TRUE; |
3262
|
|
|
} |
3263
|
|
|
/*********************************************************************************/ |
3264
|
|
|
/** |
3265
|
|
|
* Property Name: REQUEST-STATUS |
3266
|
|
|
*/ |
3267
|
|
|
/** |
3268
|
|
|
* creates formatted output for calendar component property request-status |
3269
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3270
|
|
|
* @since 2.4.8 - 2008-10-23 |
3271
|
|
|
* @return string |
3272
|
|
|
*/ |
3273
|
|
|
function createRequestStatus() { |
3274
|
|
|
if( empty( $this->requeststatus )) return FALSE; |
3275
|
|
|
$output = null; |
3276
|
|
|
foreach( $this->requeststatus as $rstat ) { |
3277
|
|
|
if( empty( $rstat['value']['statcode'] )) { |
3278
|
|
|
if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'REQUEST-STATUS' ); |
3279
|
|
|
continue; |
3280
|
|
|
} |
3281
|
|
|
$attributes = $this->_createParams( $rstat['params'], array( 'LANGUAGE' )); |
3282
|
|
|
$content = number_format( (float) $rstat['value']['statcode'], 2, '.', ''); |
3283
|
|
|
$content .= ';'.$this->_strrep( $rstat['value']['text'] ); |
3284
|
|
|
if( isset( $rstat['value']['extdata'] )) |
3285
|
|
|
$content .= ';'.$this->_strrep( $rstat['value']['extdata'] ); |
3286
|
|
|
$output .= $this->_createElement( 'REQUEST-STATUS', $attributes, $content ); |
3287
|
|
|
} |
3288
|
|
|
return $output; |
3289
|
|
|
} |
3290
|
|
|
/** |
3291
|
|
|
* set calendar component property request-status |
3292
|
|
|
* |
3293
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3294
|
|
|
* @since 2.5.1 - 2008-11-05 |
3295
|
|
|
* @param float $statcode |
3296
|
|
|
* @param string $text |
3297
|
|
|
* @param string $extdata, optional |
|
|
|
|
3298
|
|
|
* @param array $params, optional |
|
|
|
|
3299
|
|
|
* @param integer $index, optional |
|
|
|
|
3300
|
|
|
* @return bool |
3301
|
|
|
*/ |
3302
|
|
|
function setRequestStatus( $statcode, $text, $extdata=FALSE, $params=FALSE, $index=FALSE ) { |
3303
|
|
|
if( empty( $statcode ) || empty( $text )) if( $this->getConfig( 'allowEmpty' )) $statcode = $text = null; else return FALSE; |
3304
|
|
|
$input = array( 'statcode' => $statcode, 'text' => $text ); |
3305
|
|
|
if( $extdata ) |
3306
|
|
|
$input['extdata'] = $extdata; |
3307
|
|
|
$this->_setMval( $this->requeststatus, $input, $params, FALSE, $index ); |
3308
|
|
|
return TRUE; |
3309
|
|
|
} |
3310
|
|
|
/*********************************************************************************/ |
3311
|
|
|
/** |
3312
|
|
|
* Property Name: RESOURCES |
3313
|
|
|
*/ |
3314
|
|
|
/** |
3315
|
|
|
* creates formatted output for calendar component property resources |
3316
|
|
|
* |
3317
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3318
|
|
|
* @since 2.4.8 - 2008-10-23 |
3319
|
|
|
* @return string |
3320
|
|
|
*/ |
3321
|
|
View Code Duplication |
function createResources() { |
3322
|
|
|
if( empty( $this->resources )) return FALSE; |
3323
|
|
|
$output = null; |
3324
|
|
|
foreach( $this->resources as $resource ) { |
3325
|
|
|
if( empty( $resource['value'] )) { |
3326
|
|
|
if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'RESOURCES' ); |
3327
|
|
|
continue; |
3328
|
|
|
} |
3329
|
|
|
$attributes = $this->_createParams( $resource['params'], array( 'ALTREP', 'LANGUAGE' )); |
3330
|
|
|
if( is_array( $resource['value'] )) { |
3331
|
|
|
foreach( $resource['value'] as $rix => $resourcePart ) |
3332
|
|
|
$resource['value'][$rix] = $this->_strrep( $resourcePart ); |
3333
|
|
|
$content = implode( ',', $resource['value'] ); |
3334
|
|
|
} |
3335
|
|
|
else |
3336
|
|
|
$content = $this->_strrep( $resource['value'] ); |
3337
|
|
|
$output .= $this->_createElement( 'RESOURCES', $attributes, $content ); |
3338
|
|
|
} |
3339
|
|
|
return $output; |
3340
|
|
|
} |
3341
|
|
|
/** |
3342
|
|
|
* set calendar component property recources |
3343
|
|
|
* |
3344
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3345
|
|
|
* @since 2.5.1 - 2008-11-05 |
3346
|
|
|
* @param mixed $value |
3347
|
|
|
* @param array $params, optional |
|
|
|
|
3348
|
|
|
* @param integer $index, optional |
|
|
|
|
3349
|
|
|
* @return bool |
3350
|
|
|
*/ |
3351
|
|
|
function setResources( $value, $params=FALSE, $index=FALSE ) { |
3352
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
3353
|
|
|
$this->_setMval( $this->resources, $value, $params, FALSE, $index ); |
3354
|
|
|
return TRUE; |
3355
|
|
|
} |
3356
|
|
|
/*********************************************************************************/ |
3357
|
|
|
/** |
3358
|
|
|
* Property Name: RRULE |
3359
|
|
|
*/ |
3360
|
|
|
/** |
3361
|
|
|
* creates formatted output for calendar component property rrule |
3362
|
|
|
* |
3363
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3364
|
|
|
* @since 2.4.8 - 2008-10-21 |
3365
|
|
|
* @return string |
3366
|
|
|
*/ |
3367
|
|
|
function createRrule() { |
3368
|
|
|
if( empty( $this->rrule )) return FALSE; |
3369
|
|
|
return $this->_format_recur( 'RRULE', $this->rrule ); |
3370
|
|
|
} |
3371
|
|
|
/** |
3372
|
|
|
* set calendar component property rrule |
3373
|
|
|
* |
3374
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3375
|
|
|
* @since 2.5.1 - 2008-11-05 |
3376
|
|
|
* @param array $rruleset |
3377
|
|
|
* @param array $params, optional |
|
|
|
|
3378
|
|
|
* @param integer $index, optional |
|
|
|
|
3379
|
|
|
* @return void |
3380
|
|
|
*/ |
3381
|
|
|
function setRrule( $rruleset, $params=FALSE, $index=FALSE ) { |
3382
|
|
|
if( empty( $rruleset )) if( $this->getConfig( 'allowEmpty' )) $rruleset = null; else return FALSE; |
3383
|
|
|
$this->_setMval( $this->rrule, $this->_setRexrule( $rruleset ), $params, FALSE, $index ); |
|
|
|
|
3384
|
|
|
return TRUE; |
3385
|
|
|
} |
3386
|
|
|
/*********************************************************************************/ |
3387
|
|
|
/** |
3388
|
|
|
* Property Name: SEQUENCE |
3389
|
|
|
*/ |
3390
|
|
|
/** |
3391
|
|
|
* creates formatted output for calendar component property sequence |
3392
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3393
|
|
|
* @since 0.9.7 - 2006-11-20 |
3394
|
|
|
* @return string |
3395
|
|
|
*/ |
3396
|
|
|
function createSequence() { |
3397
|
|
|
if( empty( $this->sequence )) return FALSE; |
3398
|
|
|
if( empty( $this->sequence['value'] )) |
3399
|
|
|
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'SEQUENCE' ) : FALSE; |
3400
|
|
|
$attributes = $this->_createParams( $this->sequence['params'] ); |
3401
|
|
|
return $this->_createElement( 'SEQUENCE', $attributes, $this->sequence['value'] ); |
3402
|
|
|
} |
3403
|
|
|
/** |
3404
|
|
|
* set calendar component property sequence |
3405
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3406
|
|
|
* @since 2.4.8 - 2008-11-04 |
3407
|
|
|
* @param int $value optional |
3408
|
|
|
* @param array $params optional |
3409
|
|
|
* @return bool |
3410
|
|
|
*/ |
3411
|
|
|
function setSequence( $value=FALSE, $params=FALSE ) { |
3412
|
|
|
if( empty( $value )) |
3413
|
|
|
$value = ( isset( $this->sequence['value'] ) && ( 0 < $this->sequence['value'] )) ? $this->sequence['value'] + 1 : 1; |
3414
|
|
|
$this->sequence = array( 'value' => $value, 'params' => $this->_setParams( $params )); |
|
|
|
|
3415
|
|
|
return TRUE; |
3416
|
|
|
} |
3417
|
|
|
/*********************************************************************************/ |
3418
|
|
|
/** |
3419
|
|
|
* Property Name: STATUS |
3420
|
|
|
*/ |
3421
|
|
|
/** |
3422
|
|
|
* creates formatted output for calendar component property status |
3423
|
|
|
* |
3424
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3425
|
|
|
* @since 2.4.8 - 2008-10-21 |
3426
|
|
|
* @return string |
3427
|
|
|
*/ |
3428
|
|
|
function createStatus() { |
3429
|
|
|
if( empty( $this->status )) return FALSE; |
3430
|
|
|
if( empty( $this->status['value'] )) |
3431
|
|
|
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'STATUS' ) : FALSE; |
3432
|
|
|
$attributes = $this->_createParams( $this->status['params'] ); |
3433
|
|
|
return $this->_createElement( 'STATUS', $attributes, $this->status['value'] ); |
3434
|
|
|
} |
3435
|
|
|
/** |
3436
|
|
|
* set calendar component property status |
3437
|
|
|
* |
3438
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3439
|
|
|
* @since 2.4.8 - 2008-11-04 |
3440
|
|
|
* @param string $value |
3441
|
|
|
* @param mixed $params optional (array or false) |
3442
|
|
|
* @return bool |
3443
|
|
|
*/ |
3444
|
|
|
function setStatus( $value, $params=FALSE ) { |
3445
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
3446
|
|
|
$this->status = array( 'value' => $value, 'params' => $this->_setParams( $params )); |
3447
|
|
|
return TRUE; |
3448
|
|
|
} |
3449
|
|
|
/*********************************************************************************/ |
3450
|
|
|
/** |
3451
|
|
|
* Property Name: SUMMARY |
3452
|
|
|
*/ |
3453
|
|
|
/** |
3454
|
|
|
* creates formatted output for calendar component property summary |
3455
|
|
|
* |
3456
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3457
|
|
|
* @since 2.4.8 - 2008-10-21 |
3458
|
|
|
* @return string |
3459
|
|
|
*/ |
3460
|
|
View Code Duplication |
function createSummary() { |
3461
|
|
|
if( empty( $this->summary )) return FALSE; |
3462
|
|
|
if( empty( $this->summary['value'] )) |
3463
|
|
|
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'SUMMARY' ) : FALSE; |
3464
|
|
|
$attributes = $this->_createParams( $this->summary['params'], array( 'ALTREP', 'LANGUAGE' )); |
3465
|
|
|
$content = $this->_strrep( $this->summary['value'] ); |
3466
|
|
|
return $this->_createElement( 'SUMMARY', $attributes, $content ); |
3467
|
|
|
} |
3468
|
|
|
/** |
3469
|
|
|
* set calendar component property summary |
3470
|
|
|
* |
3471
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3472
|
|
|
* @since 2.4.8 - 2008-11-04 |
3473
|
|
|
* @param string $value |
3474
|
|
|
* @param string $params optional |
3475
|
|
|
* @return bool |
3476
|
|
|
*/ |
3477
|
|
|
function setSummary( $value, $params=FALSE ) { |
3478
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
3479
|
|
|
$this->summary = array( 'value' => $value, 'params' => $this->_setParams( $params )); |
3480
|
|
|
return TRUE; |
3481
|
|
|
} |
3482
|
|
|
/*********************************************************************************/ |
3483
|
|
|
/** |
3484
|
|
|
* Property Name: TRANSP |
3485
|
|
|
*/ |
3486
|
|
|
/** |
3487
|
|
|
* creates formatted output for calendar component property transp |
3488
|
|
|
* |
3489
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3490
|
|
|
* @since 2.4.8 - 2008-10-21 |
3491
|
|
|
* @return string |
3492
|
|
|
*/ |
3493
|
|
|
function createTransp() { |
3494
|
|
|
if( empty( $this->transp )) return FALSE; |
3495
|
|
|
if( empty( $this->transp['value'] )) |
3496
|
|
|
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'TRANSP' ) : FALSE; |
3497
|
|
|
$attributes = $this->_createParams( $this->transp['params'] ); |
3498
|
|
|
return $this->_createElement( 'TRANSP', $attributes, $this->transp['value'] ); |
3499
|
|
|
} |
3500
|
|
|
/** |
3501
|
|
|
* set calendar component property transp |
3502
|
|
|
* |
3503
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3504
|
|
|
* @since 2.4.8 - 2008-11-04 |
3505
|
|
|
* @param string $value |
3506
|
|
|
* @param string $params optional |
3507
|
|
|
* @return bool |
3508
|
|
|
*/ |
3509
|
|
|
function setTransp( $value, $params=FALSE ) { |
3510
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
3511
|
|
|
$this->transp = array( 'value' => $value, 'params' => $this->_setParams( $params )); |
3512
|
|
|
return TRUE; |
3513
|
|
|
} |
3514
|
|
|
/*********************************************************************************/ |
3515
|
|
|
/** |
3516
|
|
|
* Property Name: TRIGGER |
3517
|
|
|
*/ |
3518
|
|
|
/** |
3519
|
|
|
* creates formatted output for calendar component property trigger |
3520
|
|
|
* |
3521
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3522
|
|
|
* @since 2.4.16 - 2008-10-21 |
3523
|
|
|
* @return string |
3524
|
|
|
*/ |
3525
|
|
|
function createTrigger() { |
3526
|
|
|
if( empty( $this->trigger )) return FALSE; |
3527
|
|
|
if( empty( $this->trigger['value'] )) |
3528
|
|
|
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'TRIGGER' ) : FALSE; |
3529
|
|
|
$content = $attributes = null; |
3530
|
|
|
if( isset( $this->trigger['value']['year'] ) && |
3531
|
|
|
isset( $this->trigger['value']['month'] ) && |
3532
|
|
|
isset( $this->trigger['value']['day'] )) |
3533
|
|
|
$content .= $this->_format_date_time( $this->trigger['value'] ); |
3534
|
|
|
else { |
3535
|
|
|
if( TRUE !== $this->trigger['value']['relatedStart'] ) |
3536
|
|
|
$attributes .= $this->intAttrDelimiter.'RELATED=END'; |
3537
|
|
|
if( $this->trigger['value']['before'] ) |
3538
|
|
|
$content .= '-'; |
3539
|
|
|
$content .= $this->_format_duration( $this->trigger['value'] ); |
3540
|
|
|
} |
3541
|
|
|
$attributes .= $this->_createParams( $this->trigger['params'] ); |
3542
|
|
|
return $this->_createElement( 'TRIGGER', $attributes, $content ); |
3543
|
|
|
} |
3544
|
|
|
/** |
3545
|
|
|
* set calendar component property trigger |
3546
|
|
|
* |
3547
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3548
|
|
|
* @since 2.4.16 - 2008-11-04 |
3549
|
|
|
* @param mixed $year |
3550
|
|
|
* @param mixed $month optional |
3551
|
|
|
* @param int $day optional |
3552
|
|
|
* @param int $week optional |
3553
|
|
|
* @param int $hour optional |
3554
|
|
|
* @param int $min optional |
3555
|
|
|
* @param int $sec optional |
3556
|
|
|
* @param bool $relatedStart optional |
3557
|
|
|
* @param bool $before optional |
3558
|
|
|
* @param array $params optional |
3559
|
|
|
* @return bool |
3560
|
|
|
*/ |
3561
|
|
|
function setTrigger( $year, $month=null, $day=null, $week=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $relatedStart=TRUE, $before=TRUE, $params=FALSE ) { |
3562
|
|
|
if( empty( $year ) && empty( $month ) && empty( $day ) && empty( $week ) && empty( $hour ) && empty( $min ) && empty( $sec )) |
3563
|
|
|
if( $this->getConfig( 'allowEmpty' )) { |
3564
|
|
|
$this->trigger = array( 'value' => null, 'params' => $this->_setParams( $params ) ); |
|
|
|
|
3565
|
|
|
return TRUE; |
3566
|
|
|
} |
3567
|
|
|
else |
3568
|
|
|
return FALSE; |
3569
|
|
|
if( $this->_isArrayTimestampDate( $year )) { // timestamp |
3570
|
|
|
$params = $this->_setParams( $month ); |
3571
|
|
|
$date = $this->_timestamp2date( $year, 7 ); |
3572
|
|
|
foreach( $date as $k => $v ) |
3573
|
|
|
$$k = $v; |
3574
|
|
|
} |
3575
|
|
|
elseif( is_array( $year ) && ( is_array( $month ) || empty( $month ))) { |
3576
|
|
|
$params = $this->_setParams( $month ); |
3577
|
|
|
if(!(array_key_exists( 'year', $year ) && // exclude date-time |
3578
|
|
|
array_key_exists( 'month', $year ) && |
3579
|
|
|
array_key_exists( 'day', $year ))) { // so this must be a duration |
3580
|
|
|
if( isset( $params['RELATED'] ) && ( 'END' == $params['RELATED'] )) |
3581
|
|
|
$relatedStart = FALSE; |
3582
|
|
|
else |
3583
|
|
|
$relatedStart = ( array_key_exists( 'relatedStart', $year ) && ( TRUE !== $year['relatedStart'] )) ? FALSE : TRUE; |
3584
|
|
|
$before = ( array_key_exists( 'before', $year ) && ( TRUE !== $year['before'] )) ? FALSE : TRUE; |
3585
|
|
|
} |
3586
|
|
|
$SSYY = ( array_key_exists( 'year', $year )) ? $year['year'] : null; |
3587
|
|
|
$month = ( array_key_exists( 'month', $year )) ? $year['month'] : null; |
3588
|
|
|
$day = ( array_key_exists( 'day', $year )) ? $year['day'] : null; |
3589
|
|
|
$week = ( array_key_exists( 'week', $year )) ? $year['week'] : null; |
3590
|
|
|
$hour = ( array_key_exists( 'hour', $year )) ? $year['hour'] : 0; //null; |
3591
|
|
|
$min = ( array_key_exists( 'min', $year )) ? $year['min'] : 0; //null; |
3592
|
|
|
$sec = ( array_key_exists( 'sec', $year )) ? $year['sec'] : 0; //null; |
3593
|
|
|
$year = $SSYY; |
3594
|
|
|
} |
3595
|
|
|
elseif(is_string( $year ) && ( is_array( $month ) || empty( $month ))) { // duration or date in a string |
3596
|
|
|
$params = $this->_setParams( $month ); |
3597
|
|
|
if( in_array( $year{0}, array( 'P', '+', '-' ))) { // duration |
3598
|
|
|
$relatedStart = ( isset( $params['RELATED'] ) && ( 'END' == $params['RELATED'] )) ? FALSE : TRUE; |
3599
|
|
|
$before = ( '-' == $year{0} ) ? TRUE : FALSE; |
3600
|
|
|
if( 'P' != $year{0} ) |
3601
|
|
|
$year = substr( $year, 1 ); |
3602
|
|
|
$date = $this->_duration_string( $year); |
3603
|
|
|
} |
3604
|
|
|
else // date |
3605
|
|
|
$date = $this->_date_time_string( $year, 7 ); |
3606
|
|
|
unset( $year, $month, $day ); |
3607
|
|
|
foreach( $date as $k => $v ) |
|
|
|
|
3608
|
|
|
$$k = $v; |
3609
|
|
|
} |
3610
|
|
|
else // single values in function input parameters |
3611
|
|
|
$params = $this->_setParams( $params ); |
|
|
|
|
3612
|
|
|
if( !empty( $year ) && !empty( $month ) && !empty( $day )) { // date |
3613
|
|
|
$params['VALUE'] = 'DATE-TIME'; |
3614
|
|
|
$hour = ( $hour ) ? $hour : 0; |
3615
|
|
|
$min = ( $min ) ? $min : 0; |
3616
|
|
|
$sec = ( $sec ) ? $sec : 0; |
3617
|
|
|
$this->trigger = array( 'params' => $params ); |
3618
|
|
|
$this->trigger['value'] = array( 'year' => $year |
3619
|
|
|
, 'month' => $month |
3620
|
|
|
, 'day' => $day |
3621
|
|
|
, 'hour' => $hour |
3622
|
|
|
, 'min' => $min |
3623
|
|
|
, 'sec' => $sec |
3624
|
|
|
, 'tz' => 'Z' ); |
3625
|
|
|
return TRUE; |
3626
|
|
|
} |
3627
|
|
|
elseif(( empty( $year ) && empty( $month )) && // duration |
3628
|
|
|
(!empty( $week ) || !empty( $day ) || !empty( $hour ) || !empty( $min ) || !empty( $sec ))) { |
3629
|
|
|
unset( $params['RELATED'] ); // set at output creation (END only) |
3630
|
|
|
unset( $params['VALUE'] ); // 'DURATION' default |
3631
|
|
|
$this->trigger = array( 'params' => $params ); |
3632
|
|
|
$relatedStart = ( FALSE !== $relatedStart ) ? TRUE : FALSE; |
3633
|
|
|
$before = ( FALSE !== $before ) ? TRUE : FALSE; |
3634
|
|
|
$this->trigger['value'] = array( 'relatedStart' => $relatedStart |
3635
|
|
|
, 'before' => $before ); |
3636
|
|
|
if( !empty( $week )) $this->trigger['value']['week'] = $week; |
3637
|
|
|
if( !empty( $day )) $this->trigger['value']['day'] = $day; |
3638
|
|
|
if( !empty( $hour )) $this->trigger['value']['hour'] = $hour; |
3639
|
|
|
if( !empty( $min )) $this->trigger['value']['min'] = $min; |
3640
|
|
|
if( !empty( $sec )) $this->trigger['value']['sec'] = $sec; |
3641
|
|
|
return TRUE; |
3642
|
|
|
} |
3643
|
|
|
return FALSE; |
3644
|
|
|
} |
3645
|
|
|
/*********************************************************************************/ |
3646
|
|
|
/** |
3647
|
|
|
* Property Name: TZID |
3648
|
|
|
*/ |
3649
|
|
|
/** |
3650
|
|
|
* creates formatted output for calendar component property tzid |
3651
|
|
|
* |
3652
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3653
|
|
|
* @since 2.4.8 - 2008-10-21 |
3654
|
|
|
* @return string |
3655
|
|
|
*/ |
3656
|
|
|
function createTzid() { |
3657
|
|
|
if( empty( $this->tzid )) return FALSE; |
3658
|
|
|
if( empty( $this->tzid['value'] )) |
3659
|
|
|
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'TZID' ) : FALSE; |
3660
|
|
|
$attributes = $this->_createParams( $this->tzid['params'] ); |
3661
|
|
|
return $this->_createElement( 'TZID', $attributes, $this->_strrep( $this->tzid['value'] )); |
3662
|
|
|
} |
3663
|
|
|
/** |
3664
|
|
|
* set calendar component property tzid |
3665
|
|
|
* |
3666
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3667
|
|
|
* @since 2.4.8 - 2008-11-04 |
3668
|
|
|
* @param string $value |
3669
|
|
|
* @param array $params optional |
3670
|
|
|
* @return bool |
3671
|
|
|
*/ |
3672
|
|
|
function setTzid( $value, $params=FALSE ) { |
3673
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
3674
|
|
|
$this->tzid = array( 'value' => $value, 'params' => $this->_setParams( $params )); |
|
|
|
|
3675
|
|
|
return TRUE; |
3676
|
|
|
} |
3677
|
|
|
/*********************************************************************************/ |
3678
|
|
|
/** |
3679
|
|
|
* .. . |
3680
|
|
|
* Property Name: TZNAME |
3681
|
|
|
*/ |
3682
|
|
|
/** |
3683
|
|
|
* creates formatted output for calendar component property tzname |
3684
|
|
|
* |
3685
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3686
|
|
|
* @since 2.4.8 - 2008-10-21 |
3687
|
|
|
* @return string |
3688
|
|
|
*/ |
3689
|
|
View Code Duplication |
function createTzname() { |
3690
|
|
|
if( empty( $this->tzname )) return FALSE; |
3691
|
|
|
$output = null; |
3692
|
|
|
foreach( $this->tzname as $theName ) { |
3693
|
|
|
if( !empty( $theName['value'] )) { |
3694
|
|
|
$attributes = $this->_createParams( $theName['params'], array( 'LANGUAGE' )); |
3695
|
|
|
$output .= $this->_createElement( 'TZNAME', $attributes, $this->_strrep( $theName['value'] )); |
3696
|
|
|
} |
3697
|
|
|
elseif( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'TZNAME' ); |
3698
|
|
|
} |
3699
|
|
|
return $output; |
3700
|
|
|
} |
3701
|
|
|
/** |
3702
|
|
|
* set calendar component property tzname |
3703
|
|
|
* |
3704
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3705
|
|
|
* @since 2.5.1 - 2008-11-05 |
3706
|
|
|
* @param string $value |
3707
|
|
|
* @param string $params, optional |
|
|
|
|
3708
|
|
|
* @param integer $index, optional |
|
|
|
|
3709
|
|
|
* @return bool |
3710
|
|
|
*/ |
3711
|
|
|
function setTzname( $value, $params=FALSE, $index=FALSE ) { |
3712
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
3713
|
|
|
$this->_setMval( $this->tzname, $value, $params, FALSE, $index ); |
3714
|
|
|
return TRUE; |
3715
|
|
|
} |
3716
|
|
|
/*********************************************************************************/ |
3717
|
|
|
/** |
3718
|
|
|
* Property Name: TZOFFSETFROM |
3719
|
|
|
*/ |
3720
|
|
|
/** |
3721
|
|
|
* creates formatted output for calendar component property tzoffsetfrom |
3722
|
|
|
* |
3723
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3724
|
|
|
* @since 2.4.8 - 2008-10-21 |
3725
|
|
|
* @return string |
3726
|
|
|
*/ |
3727
|
|
|
function createTzoffsetfrom() { |
3728
|
|
|
if( empty( $this->tzoffsetfrom )) return FALSE; |
3729
|
|
|
if( empty( $this->tzoffsetfrom['value'] )) |
3730
|
|
|
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'TZOFFSETFROM' ) : FALSE; |
3731
|
|
|
$attributes = $this->_createParams( $this->tzoffsetfrom['params'] ); |
3732
|
|
|
return $this->_createElement( 'TZOFFSETFROM', $attributes, $this->tzoffsetfrom['value'] ); |
3733
|
|
|
} |
3734
|
|
|
/** |
3735
|
|
|
* set calendar component property tzoffsetfrom |
3736
|
|
|
* |
3737
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3738
|
|
|
* @since 2.4.8 - 2008-11-04 |
3739
|
|
|
* @param string $value |
3740
|
|
|
* @param string $params optional |
3741
|
|
|
* @return bool |
3742
|
|
|
*/ |
3743
|
|
|
function setTzoffsetfrom( $value, $params=FALSE ) { |
3744
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
3745
|
|
|
$this->tzoffsetfrom = array( 'value' => $value, 'params' => $this->_setParams( $params )); |
3746
|
|
|
return TRUE; |
3747
|
|
|
} |
3748
|
|
|
/*********************************************************************************/ |
3749
|
|
|
/** |
3750
|
|
|
* Property Name: TZOFFSETTO |
3751
|
|
|
*/ |
3752
|
|
|
/** |
3753
|
|
|
* creates formatted output for calendar component property tzoffsetto |
3754
|
|
|
* |
3755
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3756
|
|
|
* @since 2.4.8 - 2008-10-21 |
3757
|
|
|
* @return string |
3758
|
|
|
*/ |
3759
|
|
|
function createTzoffsetto() { |
3760
|
|
|
if( empty( $this->tzoffsetto )) return FALSE; |
3761
|
|
|
if( empty( $this->tzoffsetto['value'] )) |
3762
|
|
|
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'TZOFFSETTO' ) : FALSE; |
3763
|
|
|
$attributes = $this->_createParams( $this->tzoffsetto['params'] ); |
3764
|
|
|
return $this->_createElement( 'TZOFFSETTO', $attributes, $this->tzoffsetto['value'] ); |
3765
|
|
|
} |
3766
|
|
|
/** |
3767
|
|
|
* set calendar component property tzoffsetto |
3768
|
|
|
* |
3769
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3770
|
|
|
* @since 2.4.8 - 2008-11-04 |
3771
|
|
|
* @param string $value |
3772
|
|
|
* @param string $params optional |
3773
|
|
|
* @return bool |
3774
|
|
|
*/ |
3775
|
|
|
function setTzoffsetto( $value, $params=FALSE ) { |
3776
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
3777
|
|
|
$this->tzoffsetto = array( 'value' => $value, 'params' => $this->_setParams( $params )); |
3778
|
|
|
return TRUE; |
3779
|
|
|
} |
3780
|
|
|
/*********************************************************************************/ |
3781
|
|
|
/** |
3782
|
|
|
* Property Name: TZURL |
3783
|
|
|
*/ |
3784
|
|
|
/** |
3785
|
|
|
* creates formatted output for calendar component property tzurl |
3786
|
|
|
* |
3787
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3788
|
|
|
* @since 2.4.8 - 2008-10-21 |
3789
|
|
|
* @return string |
3790
|
|
|
*/ |
3791
|
|
|
function createTzurl() { |
3792
|
|
|
if( empty( $this->tzurl )) return FALSE; |
3793
|
|
|
if( empty( $this->tzurl['value'] )) |
3794
|
|
|
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'TZURL' ) : FALSE; |
3795
|
|
|
$attributes = $this->_createParams( $this->tzurl['params'] ); |
3796
|
|
|
return $this->_createElement( 'TZURL', $attributes, $this->tzurl['value'] ); |
3797
|
|
|
} |
3798
|
|
|
/** |
3799
|
|
|
* set calendar component property tzurl |
3800
|
|
|
* |
3801
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3802
|
|
|
* @since 2.4.8 - 2008-11-04 |
3803
|
|
|
* @param string $value |
3804
|
|
|
* @param string $params optional |
3805
|
|
|
* @return boll |
3806
|
|
|
*/ |
3807
|
|
|
function setTzurl( $value, $params=FALSE ) { |
3808
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
3809
|
|
|
$this->tzurl = array( 'value' => $value, 'params' => $this->_setParams( $params )); |
3810
|
|
|
return TRUE; |
3811
|
|
|
} |
3812
|
|
|
/*********************************************************************************/ |
3813
|
|
|
/** |
3814
|
|
|
* Property Name: UID |
3815
|
|
|
*/ |
3816
|
|
|
/** |
3817
|
|
|
* creates formatted output for calendar component property uid |
3818
|
|
|
* |
3819
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3820
|
|
|
* @since 0.9.7 - 2006-11-20 |
3821
|
|
|
* @return string |
3822
|
|
|
*/ |
3823
|
|
|
function createUid() { |
3824
|
|
|
if( 0 >= count( $this->uid )) |
3825
|
|
|
$this->_makeuid(); |
3826
|
|
|
$attributes = $this->_createParams( $this->uid['params'] ); |
3827
|
|
|
return $this->_createElement( 'UID', $attributes, $this->uid['value'] ); |
3828
|
|
|
} |
3829
|
|
|
/** |
3830
|
|
|
* create an unique id for this calendar component object instance |
3831
|
|
|
* |
3832
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3833
|
|
|
* @since 2.2.7 - 2007-09-04 |
3834
|
|
|
* @return void |
3835
|
|
|
*/ |
3836
|
|
|
function _makeUid() { |
3837
|
|
|
$date = date('Ymd\THisT'); |
3838
|
|
|
$unique = substr(microtime(), 2, 4); |
3839
|
|
|
$base = 'aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPrRsStTuUvVxXuUvVwWzZ1234567890'; |
3840
|
|
|
$start = 0; |
3841
|
|
|
$end = strlen( $base ) - 1; |
3842
|
|
|
$length = 6; |
3843
|
|
|
$str = null; |
3844
|
|
|
for( $p = 0; $p < $length; $p++ ) |
3845
|
|
|
$unique .= $base{mt_rand( $start, $end )}; |
3846
|
|
|
$this->uid = array( 'params' => null ); |
3847
|
|
|
$this->uid['value'] = $date.'-'.$unique.'@'.$this->getConfig( 'unique_id' ); |
3848
|
|
|
} |
3849
|
|
|
/** |
3850
|
|
|
* set calendar component property uid |
3851
|
|
|
* |
3852
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3853
|
|
|
* @since 2.4.8 - 2008-11-04 |
3854
|
|
|
* @param string $value |
3855
|
|
|
* @param string $params optional |
3856
|
|
|
* @return bool |
3857
|
|
|
*/ |
3858
|
|
|
function setUid( $value, $params=FALSE ) { |
3859
|
|
|
if( empty( $value )) return FALSE; // no allowEmpty check here !!!! |
3860
|
|
|
$this->uid = array( 'value' => $value, 'params' => $this->_setParams( $params )); |
3861
|
|
|
return TRUE; |
3862
|
|
|
} |
3863
|
|
|
/*********************************************************************************/ |
3864
|
|
|
/** |
3865
|
|
|
* Property Name: URL |
3866
|
|
|
*/ |
3867
|
|
|
/** |
3868
|
|
|
* creates formatted output for calendar component property url |
3869
|
|
|
* |
3870
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3871
|
|
|
* @since 2.4.8 - 2008-10-21 |
3872
|
|
|
* @return string |
3873
|
|
|
*/ |
3874
|
|
|
function createUrl() { |
3875
|
|
|
if( empty( $this->url )) return FALSE; |
3876
|
|
|
if( empty( $this->url['value'] )) |
3877
|
|
|
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'URL' ) : FALSE; |
3878
|
|
|
$attributes = $this->_createParams( $this->url['params'] ); |
3879
|
|
|
return $this->_createElement( 'URL', $attributes, $this->url['value'] ); |
3880
|
|
|
} |
3881
|
|
|
/** |
3882
|
|
|
* set calendar component property url |
3883
|
|
|
* |
3884
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3885
|
|
|
* @since 2.4.8 - 2008-11-04 |
3886
|
|
|
* @param string $value |
3887
|
|
|
* @param string $params optional |
3888
|
|
|
* @return bool |
3889
|
|
|
*/ |
3890
|
|
|
function setUrl( $value, $params=FALSE ) { |
3891
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
3892
|
|
|
$this->url = array( 'value' => $value, 'params' => $this->_setParams( $params )); |
3893
|
|
|
return TRUE; |
3894
|
|
|
} |
3895
|
|
|
/*********************************************************************************/ |
3896
|
|
|
/** |
3897
|
|
|
* Property Name: x-prop |
3898
|
|
|
*/ |
3899
|
|
|
/** |
3900
|
|
|
* creates formatted output for calendar component property x-prop |
3901
|
|
|
* |
3902
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3903
|
|
|
* @since 2.4.11 - 2008-10-22 |
3904
|
|
|
* @return string |
3905
|
|
|
*/ |
3906
|
|
|
function createXprop() { |
3907
|
|
|
if( empty( $this->xprop )) return FALSE; |
3908
|
|
|
$output = null; |
3909
|
|
|
foreach( $this->xprop as $label => $xpropPart ) { |
3910
|
|
|
if( empty( $xpropPart['value'] )) { |
3911
|
|
|
if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( $label ); |
3912
|
|
|
continue; |
3913
|
|
|
} |
3914
|
|
|
$attributes = $this->_createParams( $xpropPart['params'], array( 'LANGUAGE' )); |
3915
|
|
|
if( is_array( $xpropPart['value'] )) { |
3916
|
|
|
foreach( $xpropPart['value'] as $pix => $theXpart ) |
3917
|
|
|
$xpropPart['value'][$pix] = $this->_strrep( $theXpart ); |
3918
|
|
|
$xpropPart['value'] = implode( ',', $xpropPart['value'] ); |
3919
|
|
|
} |
3920
|
|
|
else |
3921
|
|
|
$xpropPart['value'] = $this->_strrep( $xpropPart['value'] ); |
3922
|
|
|
$output .= $this->_createElement( $label, $attributes, $xpropPart['value'] ); |
3923
|
|
|
} |
3924
|
|
|
return $output; |
3925
|
|
|
} |
3926
|
|
|
/** |
3927
|
|
|
* set calendar component property x-prop |
3928
|
|
|
* |
3929
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3930
|
|
|
* @since 2.4.11 - 2008-11-04 |
3931
|
|
|
* @param string $label |
3932
|
|
|
* @param mixed $value |
3933
|
|
|
* @param array $params optional |
3934
|
|
|
* @return bool |
3935
|
|
|
*/ |
3936
|
|
View Code Duplication |
function setXprop( $label, $value, $params=FALSE ) { |
3937
|
|
|
if( empty( $label )) return; |
3938
|
|
|
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; |
3939
|
|
|
$xprop = array( 'value' => $value ); |
3940
|
|
|
$toolbox = new calendarComponent(); |
3941
|
|
|
$xprop['params'] = $toolbox->_setParams( $params ); |
|
|
|
|
3942
|
|
|
if( !is_array( $this->xprop )) $this->xprop = array(); |
3943
|
|
|
$this->xprop[strtoupper( $label )] = $xprop; |
3944
|
|
|
return TRUE; |
3945
|
|
|
} |
3946
|
|
|
/*********************************************************************************/ |
3947
|
|
|
/*********************************************************************************/ |
3948
|
|
|
/** |
3949
|
|
|
* create element format parts |
3950
|
|
|
* |
3951
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3952
|
|
|
* @since 2.0.6 - 2006-06-20 |
3953
|
|
|
* @return string |
3954
|
|
|
*/ |
3955
|
|
|
function _createFormat() { |
3956
|
|
|
$objectname = null; |
3957
|
|
|
switch( $this->format ) { |
3958
|
|
|
case 'xcal': |
3959
|
|
|
$objectname = ( isset( $this->timezonetype )) ? |
3960
|
|
|
strtolower( $this->timezonetype ) : strtolower( $this->objName ); |
3961
|
|
|
$this->componentStart1 = $this->elementStart1 = '<'; |
3962
|
|
|
$this->componentStart2 = $this->elementStart2 = '>'; |
3963
|
|
|
$this->componentEnd1 = $this->elementEnd1 = '</'; |
3964
|
|
|
$this->componentEnd2 = $this->elementEnd2 = '>'.$this->nl; |
3965
|
|
|
$this->intAttrDelimiter = '<!-- -->'; |
3966
|
|
|
$this->attributeDelimiter = $this->nl; |
3967
|
|
|
$this->valueInit = null; |
3968
|
|
|
break; |
3969
|
|
|
default: |
3970
|
|
|
$objectname = ( isset( $this->timezonetype )) ? |
3971
|
|
|
strtoupper( $this->timezonetype ) : strtoupper( $this->objName ); |
3972
|
|
|
$this->componentStart1 = 'BEGIN:'; |
3973
|
|
|
$this->componentStart2 = null; |
3974
|
|
|
$this->componentEnd1 = 'END:'; |
3975
|
|
|
$this->componentEnd2 = $this->nl; |
3976
|
|
|
$this->elementStart1 = null; |
3977
|
|
|
$this->elementStart2 = null; |
3978
|
|
|
$this->elementEnd1 = null; |
3979
|
|
|
$this->elementEnd2 = $this->nl; |
3980
|
|
|
$this->intAttrDelimiter = '<!-- -->'; |
3981
|
|
|
$this->attributeDelimiter = ';'; |
3982
|
|
|
$this->valueInit = ':'; |
3983
|
|
|
break; |
3984
|
|
|
} |
3985
|
|
|
return $objectname; |
3986
|
|
|
} |
3987
|
|
|
/** |
3988
|
|
|
* creates formatted output for calendar component property |
3989
|
|
|
* |
3990
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
3991
|
|
|
* @since 2.4.8 - 2008-10-23 |
3992
|
|
|
* @param string $label property name |
3993
|
|
|
* @param string $attributes property attributes |
3994
|
|
|
* @param string $content property content (optional) |
3995
|
|
|
* @return string |
3996
|
|
|
*/ |
3997
|
|
|
function _createElement( $label, $attributes=null, $content=FALSE ) { |
3998
|
|
|
$label = $this->_formatPropertyName( $label ); |
3999
|
|
|
$output = $this->elementStart1.$label; |
4000
|
|
|
$categoriesAttrLang = null; |
4001
|
|
|
$attachInlineBinary = FALSE; |
4002
|
|
|
$attachfmttype = null; |
4003
|
|
|
if( !empty( $attributes )) { |
4004
|
|
|
$attributes = trim( $attributes ); |
4005
|
|
|
if ( 'xcal' == $this->format) { |
4006
|
|
|
$attributes2 = explode( $this->intAttrDelimiter, $attributes ); |
4007
|
|
|
$attributes = null; |
4008
|
|
|
foreach( $attributes2 as $attribute ) { |
4009
|
|
|
$attrKVarr = explode( '=', $attribute ); |
4010
|
|
|
if( empty( $attrKVarr[0] )) |
4011
|
|
|
continue; |
4012
|
|
|
if( !isset( $attrKVarr[1] )) { |
4013
|
|
|
$attrValue = $attrKVarr[0]; |
4014
|
|
|
$attrKey = null; |
4015
|
|
|
} |
4016
|
|
View Code Duplication |
elseif( 2 == count( $attrKVarr)) { |
4017
|
|
|
$attrKey = strtolower( $attrKVarr[0] ); |
4018
|
|
|
$attrValue = $attrKVarr[1]; |
4019
|
|
|
} |
4020
|
|
View Code Duplication |
else { |
4021
|
|
|
$attrKey = strtolower( $attrKVarr[0] ); |
4022
|
|
|
unset( $attrKVarr[0] ); |
4023
|
|
|
$attrValue = implode( '=', $attrKVarr ); |
4024
|
|
|
} |
4025
|
|
|
if(( 'attach' == $label ) && ( in_array( $attrKey, array( 'fmttype', 'encoding', 'value' )))) { |
4026
|
|
|
$attachInlineBinary = TRUE; |
4027
|
|
|
if( 'fmttype' == $attrKey ) |
4028
|
|
|
$attachfmttype = $attrKey.'='.$attrValue; |
4029
|
|
|
continue; |
4030
|
|
|
} |
4031
|
|
|
elseif(( 'categories' == $label ) && ( 'language' == $attrKey )) |
4032
|
|
|
$categoriesAttrLang = $attrKey.'='.$attrValue; |
4033
|
|
|
else { |
4034
|
|
|
$attributes .= ( empty( $attributes )) ? ' ' : $this->attributeDelimiter.' '; |
4035
|
|
|
$attributes .= ( !empty( $attrKey )) ? $attrKey.'=' : null; |
4036
|
|
|
if(( '"' == substr( $attrValue, 0, 1 )) && ( '"' == substr( $attrValue, -1 ))) { |
4037
|
|
|
$attrValue = substr( $attrValue, 1, ( strlen( $attrValue ) - 2 )); |
4038
|
|
|
$attrValue = str_replace( '"', '', $attrValue ); |
4039
|
|
|
} |
4040
|
|
|
$attributes .= '"'.htmlspecialchars( $attrValue ).'"'; |
4041
|
|
|
} |
4042
|
|
|
} |
4043
|
|
|
} |
4044
|
|
|
else { |
4045
|
|
|
$attributes = str_replace( $this->intAttrDelimiter, $this->attributeDelimiter, $attributes ); |
4046
|
|
|
} |
4047
|
|
|
} |
4048
|
|
|
if(((( 'attach' == $label ) && !$attachInlineBinary ) || |
4049
|
|
|
( in_array( $label, array( 'tzurl', 'url' )))) && ( 'xcal' == $this->format)) { |
4050
|
|
|
$pos = strrpos($content, "/"); |
4051
|
|
|
$docname = ( $pos !== false) ? substr( $content, (1 - strlen( $content ) + $pos )) : $content; |
4052
|
|
|
$this->xcaldecl[] = array( 'xmldecl' => 'ENTITY' |
4053
|
|
|
, 'uri' => $docname |
4054
|
|
|
, 'ref' => 'SYSTEM' |
4055
|
|
|
, 'external' => $content |
4056
|
|
|
, 'type' => 'NDATA' |
4057
|
|
|
, 'type2' => 'BINERY' ); |
4058
|
|
|
$attributes .= ( empty( $attributes )) ? ' ' : $this->attributeDelimiter.' '; |
4059
|
|
|
$attributes .= 'uri="'.$docname.'"'; |
4060
|
|
|
$content = null; |
4061
|
|
|
if( 'attach' == $label ) { |
4062
|
|
|
$attributes = str_replace( $this->attributeDelimiter, $this->intAttrDelimiter, $attributes ); |
4063
|
|
|
$content = $this->_createElement( 'extref', $attributes, null ); |
4064
|
|
|
$attributes = null; |
4065
|
|
|
} |
4066
|
|
|
} |
4067
|
|
|
elseif(( 'attach' == $label ) && $attachInlineBinary && ( 'xcal' == $this->format)) { |
4068
|
|
|
$content = $this->nl.$this->_createElement( 'b64bin', $attachfmttype, $content ); // max one attribute |
4069
|
|
|
} |
4070
|
|
|
$output .= $attributes; |
4071
|
|
|
if( !$content ) { |
4072
|
|
|
switch( $this->format ) { |
4073
|
|
|
case 'xcal': |
4074
|
|
|
$output .= ' /'; |
4075
|
|
|
$output .= $this->elementStart2; |
4076
|
|
|
return $output; |
4077
|
|
|
break; |
4078
|
|
|
default: |
4079
|
|
|
$output .= $this->elementStart2.$this->valueInit; |
4080
|
|
|
return $this->_size75( $output ); |
4081
|
|
|
break; |
4082
|
|
|
} |
4083
|
|
|
} |
4084
|
|
|
$output .= $this->elementStart2; |
4085
|
|
|
$output .= $this->valueInit.$content; |
4086
|
|
|
switch( $this->format ) { |
4087
|
|
|
case 'xcal': |
4088
|
|
|
return $output.$this->elementEnd1.$label.$this->elementEnd2; |
4089
|
|
|
break; |
4090
|
|
|
default: |
4091
|
|
|
return $this->_size75( $output ); |
4092
|
|
|
break; |
4093
|
|
|
} |
4094
|
|
|
} |
4095
|
|
|
/** |
4096
|
|
|
* creates formatted output for calendar component property parameters |
4097
|
|
|
* |
4098
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
4099
|
|
|
* @since 0.9.22 - 2007-04-10 |
4100
|
|
|
* @param array $params optional |
4101
|
|
|
* @param array $ctrKeys optional |
4102
|
|
|
* @return string |
4103
|
|
|
*/ |
4104
|
|
|
function _createParams( $params=array(), $ctrKeys=array() ) { |
4105
|
|
|
$attrLANG = $attr1 = $attr2 = null; |
4106
|
|
|
$CNattrKey = ( in_array( 'CN', $ctrKeys )) ? TRUE : FALSE ; |
4107
|
|
|
$LANGattrKey = ( in_array( 'LANGUAGE', $ctrKeys )) ? TRUE : FALSE ; |
4108
|
|
|
$CNattrExist = $LANGattrExist = FALSE; |
4109
|
|
|
if( is_array( $params )) { |
4110
|
|
|
foreach( $params as $paramKey => $paramValue ) { |
4111
|
|
|
if( is_int( $paramKey )) |
4112
|
|
|
$attr2 .= $this->intAttrDelimiter.$paramValue; |
4113
|
|
|
elseif(( 'LANGUAGE' == $paramKey ) && $LANGattrKey ) { |
4114
|
|
|
$attrLANG .= $this->intAttrDelimiter."LANGUAGE=$paramValue"; |
4115
|
|
|
$LANGattrExist = TRUE; |
4116
|
|
|
} |
4117
|
|
|
elseif(( 'CN' == $paramKey ) && $CNattrKey ) { |
4118
|
|
|
$attr1 = $this->intAttrDelimiter.'CN="'.$paramValue.'"'; |
4119
|
|
|
$CNattrExist = TRUE; |
4120
|
|
|
} |
4121
|
|
View Code Duplication |
elseif(( 'ALTREP' == $paramKey ) && in_array( $paramKey, $ctrKeys )) |
4122
|
|
|
$attr2 .= $this->intAttrDelimiter.'ALTREP="'.$paramValue.'"'; |
4123
|
|
View Code Duplication |
elseif(( 'DIR' == $paramKey ) && in_array( $paramKey, $ctrKeys )) |
4124
|
|
|
$attr2 .= $this->intAttrDelimiter.'DIR="'.$paramValue.'"'; |
4125
|
|
View Code Duplication |
elseif(( 'SENT-BY' == $paramKey ) && in_array( $paramKey, $ctrKeys )) |
4126
|
|
|
$attr2 .= $this->intAttrDelimiter.'SENT-BY="MAILTO:'.$paramValue.'"'; |
4127
|
|
|
else |
4128
|
|
|
$attr2 .= $this->intAttrDelimiter."$paramKey=$paramValue"; |
4129
|
|
|
} |
4130
|
|
|
} |
4131
|
|
|
if( !$LANGattrExist ) { |
4132
|
|
|
$lang = $this->getConfig( 'language' ); |
4133
|
|
|
if(( $CNattrExist || $LANGattrKey ) && $lang ) |
4134
|
|
|
$attrLANG .= $this->intAttrDelimiter.'LANGUAGE='.$lang; |
4135
|
|
|
} |
4136
|
|
|
return $attrLANG.$attr1.$attr2; |
4137
|
|
|
} |
4138
|
|
|
/** |
4139
|
|
|
* check a date(-time) for an opt. timezone and if it is a DATE-TIME or DATE |
4140
|
|
|
* |
4141
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
4142
|
|
|
* @since 2.4.16 - 2008-10-25 |
4143
|
|
|
* @param array $date, date to check |
|
|
|
|
4144
|
|
|
* @param int $parno, no of date parts (i.e. year, month.. .) |
|
|
|
|
4145
|
|
|
* @return array $params, property parameters |
4146
|
|
|
*/ |
4147
|
|
|
function _chkdatecfg( $theDate, & $parno, & $params ) { |
4148
|
|
|
if( isset( $params['TZID'] )) |
4149
|
|
|
$parno = 6; |
4150
|
|
|
elseif( isset( $params['VALUE'] ) && ( 'DATE' == $params['VALUE'] )) |
4151
|
|
|
$parno = 3; |
4152
|
|
|
else { |
4153
|
|
|
if( isset( $params['VALUE'] ) && ( 'PERIOD' == $params['VALUE'] )) |
4154
|
|
|
$parno = 7; |
4155
|
|
|
if( is_array( $theDate )) { |
4156
|
|
|
if( isset( $theDate['timestamp'] )) |
4157
|
|
|
$tzid = ( isset( $theDate['tz'] )) ? $theDate['tz'] : null; |
4158
|
|
|
else |
4159
|
|
|
$tzid = ( isset( $theDate['tz'] )) ? $theDate['tz'] : ( 7 == count( $theDate )) ? end( $theDate ) : null; |
4160
|
|
|
if( !empty( $tzid )) { |
4161
|
|
|
$parno = 7; |
4162
|
|
|
if( !$this->_isOffset( $tzid )) |
4163
|
|
|
$params['TZID'] = $tzid; // save only timezone |
4164
|
|
|
} |
4165
|
|
|
elseif( !$parno && ( 3 == count( $theDate )) && |
4166
|
|
|
( isset( $params['VALUE'] ) && ( 'DATE' == $params['VALUE'] ))) |
4167
|
|
|
$parno = 3; |
4168
|
|
|
else |
4169
|
|
|
$parno = 6; |
4170
|
|
|
} |
4171
|
|
|
else { // string |
4172
|
|
|
$date = trim( $theDate ); |
4173
|
|
|
if( 'Z' == substr( $date, -1 )) |
4174
|
|
|
$parno = 7; // UTC DATE-TIME |
4175
|
|
|
elseif((( 8 == strlen( $date ) && ctype_digit( $date )) || ( 11 >= strlen( $date ))) && |
4176
|
|
|
( !isset( $params['VALUE'] ) || !in_array( $params['VALUE'], array( 'DATE-TIME', 'PERIOD' )))) |
4177
|
|
|
$parno = 3; // DATE |
4178
|
|
|
$date = $this->_date_time_string( $date, $parno ); |
4179
|
|
|
if( !empty( $date['tz'] )) { |
4180
|
|
|
$parno = 7; |
4181
|
|
|
if( !$this->_isOffset( $date['tz'] )) |
4182
|
|
|
$params['TZID'] = $date['tz']; // save only timezone |
4183
|
|
|
} |
4184
|
|
|
elseif( empty( $parno )) |
4185
|
|
|
$parno = 6; |
4186
|
|
|
} |
4187
|
|
|
if( isset( $params['TZID'] )) |
4188
|
|
|
$parno = 6; |
4189
|
|
|
} |
4190
|
|
|
} |
4191
|
|
|
/** |
4192
|
|
|
* convert local startdate/enddate (Ymd[His]) to duration |
4193
|
|
|
* |
4194
|
|
|
* uses this component dates if missing input dates |
4195
|
|
|
* |
4196
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
4197
|
|
|
* @since 2.2.11 - 2007-11-03 |
4198
|
|
|
* @param array $startdate, optional |
|
|
|
|
4199
|
|
|
* @param array $duration, optional |
|
|
|
|
4200
|
|
|
* @return array duration |
4201
|
|
|
*/ |
4202
|
|
|
function _date2duration( $startdate=FALSE, $enddate=FALSE ) { |
4203
|
|
|
if( !$startdate || !$enddate ) { |
4204
|
|
|
if( FALSE === ( $startdate = $this->getProperty( 'dtstart' ))) |
4205
|
|
|
return null; |
4206
|
|
|
if( FALSE === ( $enddate = $this->getProperty( 'dtend' ))) // vevent/vfreebusy |
4207
|
|
|
if( FALSE === ( $enddate = $this->getProperty( 'due' ))) // vtodo |
4208
|
|
|
return null; |
4209
|
|
|
} |
4210
|
|
|
if( !$startdate || !$enddate ) |
4211
|
|
|
return null; |
4212
|
|
|
$startWdate = mktime( 0, 0, 0, $startdate['month'], $startdate['day'], $startdate['year'] ); |
4213
|
|
|
$endWdate = mktime( 0, 0, 0, $enddate['month'], $enddate['day'], $enddate['year'] ); |
4214
|
|
|
$wduration = $endWdate - $startWdate; |
4215
|
|
|
$dur = array(); |
4216
|
|
|
$dur['week'] = (int) floor( $wduration / ( 7 * 24 * 60 * 60 )); |
4217
|
|
|
$wduration = $wduration % ( 7 * 24 * 60 * 60 ); |
4218
|
|
|
$dur['day'] = (int) floor( $wduration / ( 24 * 60 * 60 )); |
4219
|
|
|
$wduration = $wduration % ( 24 * 60 * 60 ); |
4220
|
|
|
$dur['hour'] = (int) floor( $wduration / ( 60 * 60 )); |
4221
|
|
|
$wduration = $wduration % ( 60 * 60 ); |
4222
|
|
|
$dur['min'] = (int) floor( $wduration / ( 60 )); |
4223
|
|
|
$dur['sec'] = (int) $wduration % ( 60 ); |
4224
|
|
|
return $dur; |
4225
|
|
|
} |
4226
|
|
|
/** |
4227
|
|
|
* convert date/datetime to timestamp |
4228
|
|
|
* |
4229
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
4230
|
|
|
* @since 2.4.8 - 2008-10-30 |
4231
|
|
|
* @param array $datetime datetime/(date) |
4232
|
|
|
* @param string $tz timezone |
4233
|
|
|
* @return timestamp |
4234
|
|
|
*/ |
4235
|
|
|
function _date2timestamp( $datetime, $tz=null ) { |
4236
|
|
|
$output = null; |
4237
|
|
|
if( !isset( $datetime['hour'] )) $datetime['hour'] = '0'; |
4238
|
|
|
if( !isset( $datetime['min'] )) $datetime['min'] = '0'; |
4239
|
|
|
if( !isset( $datetime['sec'] )) $datetime['sec'] = '0'; |
4240
|
|
|
foreach( $datetime as $dkey => $dvalue ) { |
4241
|
|
|
if( 'tz' != $dkey ) |
4242
|
|
|
$datetime[$dkey] = (integer) $dvalue; |
4243
|
|
|
} |
4244
|
|
|
if( $tz ) |
4245
|
|
|
$datetime['tz'] = $tz; |
4246
|
|
|
$offset = ( isset( $datetime['tz'] ) && ( '' < trim ( $datetime['tz'] ))) ? $this->_tz2offset( $datetime['tz'] ) : 0; |
4247
|
|
|
$output = mktime( $datetime['hour'], $datetime['min'], ($datetime['sec'] + $offset), $datetime['month'], $datetime['day'], $datetime['year'] ); |
4248
|
|
|
return $output; |
4249
|
|
|
} |
4250
|
|
|
/** |
4251
|
|
|
* ensures internal date-time/date format for input date-time/date in array format |
4252
|
|
|
* |
4253
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
4254
|
|
|
* @since 0.3.0 - 2006-08-15 |
4255
|
|
|
* @param array $datetime |
4256
|
|
|
* @param int $parno optional, default FALSE |
4257
|
|
|
* @return array |
4258
|
|
|
*/ |
4259
|
|
|
function _date_time_array( $datetime, $parno=FALSE ) { |
4260
|
|
|
$output = array(); |
4261
|
|
|
foreach( $datetime as $dateKey => $datePart ) { |
4262
|
|
|
switch ( $dateKey ) { |
4263
|
|
|
case '0': |
4264
|
|
|
case 'year': |
4265
|
|
|
$output['year'] = $datePart; |
4266
|
|
|
break; |
4267
|
|
|
case '1': |
4268
|
|
|
case 'month': |
4269
|
|
|
$output['month'] = $datePart; |
4270
|
|
|
break; |
4271
|
|
|
case '2': |
4272
|
|
|
case 'day': |
4273
|
|
|
$output['day'] = $datePart; |
4274
|
|
|
break; |
4275
|
|
|
} |
4276
|
|
|
if( 3 != $parno ) { |
4277
|
|
View Code Duplication |
switch ( $dateKey ) { |
4278
|
|
|
case '0': |
4279
|
|
|
case '1': |
4280
|
|
|
case '2': |
4281
|
|
|
break; |
4282
|
|
|
case '3': |
4283
|
|
|
case 'hour': |
4284
|
|
|
$output['hour'] = $datePart; |
4285
|
|
|
break; |
4286
|
|
|
case '4': |
4287
|
|
|
case 'min': |
4288
|
|
|
$output['min'] = $datePart; |
4289
|
|
|
break; |
4290
|
|
|
case '5': |
4291
|
|
|
case 'sec': |
4292
|
|
|
$output['sec'] = $datePart; |
4293
|
|
|
break; |
4294
|
|
|
case '6': |
4295
|
|
|
case 'tz': |
4296
|
|
|
$output['tz'] = $datePart; |
4297
|
|
|
break; |
4298
|
|
|
} |
4299
|
|
|
} |
4300
|
|
|
} |
4301
|
|
|
if( 3 != $parno ) { |
4302
|
|
|
if( !isset( $output['hour'] )) |
4303
|
|
|
$output['hour'] = 0; |
4304
|
|
|
if( !isset( $output['min'] )) |
4305
|
|
|
$output['min'] = 0; |
4306
|
|
|
if( !isset( $output['sec'] )) |
4307
|
|
|
$output['sec'] = 0; |
4308
|
|
|
} |
4309
|
|
|
return $output; |
4310
|
|
|
} |
4311
|
|
|
/** |
4312
|
|
|
* ensures internal date-time/date format for input date-time/date in string fromat |
4313
|
|
|
* |
4314
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
4315
|
|
|
* @since 2.2.10 - 2007-10-19 |
4316
|
|
|
* @param array $datetime |
4317
|
|
|
* @param int $parno optional, default FALSE |
4318
|
|
|
* @return array |
4319
|
|
|
*/ |
4320
|
|
|
function _date_time_string( $datetime, $parno=FALSE ) { |
4321
|
|
|
$datetime = (string) trim( $datetime ); |
4322
|
|
|
$tz = null; |
4323
|
|
|
$len = strlen( $datetime ) - 1; |
4324
|
|
|
if( 'Z' == substr( $datetime, -1 )) { |
4325
|
|
|
$tz = 'Z'; |
4326
|
|
|
$datetime = trim( substr( $datetime, 0, $len )); |
4327
|
|
|
} |
4328
|
|
|
elseif( ( ctype_digit( substr( $datetime, -2, 2 ))) && // time or date |
4329
|
|
|
( '-' == substr( $datetime, -3, 1 )) || |
4330
|
|
|
( ':' == substr( $datetime, -3, 1 )) || |
4331
|
|
|
( '.' == substr( $datetime, -3, 1 ))) { |
4332
|
|
|
$continue = TRUE; |
4333
|
|
|
} |
4334
|
|
View Code Duplication |
elseif( ( ctype_digit( substr( $datetime, -4, 4 ))) && // 4 pos offset |
4335
|
|
|
( ' +' == substr( $datetime, -6, 2 )) || |
4336
|
|
|
( ' -' == substr( $datetime, -6, 2 ))) { |
4337
|
|
|
$tz = substr( $datetime, -5, 5 ); |
4338
|
|
|
$datetime = substr( $datetime, 0, ($len - 5)); |
4339
|
|
|
} |
4340
|
|
View Code Duplication |
elseif( ( ctype_digit( substr( $datetime, -6, 6 ))) && // 6 pos offset |
4341
|
|
|
( ' +' == substr( $datetime, -8, 2 )) || |
4342
|
|
|
( ' -' == substr( $datetime, -8, 2 ))) { |
4343
|
|
|
$tz = substr( $datetime, -7, 7 ); |
4344
|
|
|
$datetime = substr( $datetime, 0, ($len - 7)); |
4345
|
|
|
} |
4346
|
|
|
elseif( ( 6 < $len ) && ( ctype_digit( substr( $datetime, -6, 6 )))) { |
4347
|
|
|
$continue = TRUE; |
4348
|
|
|
} |
4349
|
|
|
elseif( 'T' == substr( $datetime, -7, 1 )) { |
4350
|
|
|
$continue = TRUE; |
4351
|
|
|
} |
4352
|
|
|
else { |
4353
|
|
|
$cx = $tx = 0; // 19970415T133000 US-Eastern |
4354
|
|
|
for( $cx = -1; $cx > ( 9 - $len ); $cx-- ) { |
4355
|
|
|
if(( ' ' == substr( $datetime, $cx, 1 )) || ctype_digit( substr( $datetime, $cx, 1 ))) |
4356
|
|
|
break; // if exists, tz ends here.. . ? |
4357
|
|
|
elseif( ctype_alpha( substr( $datetime, $cx, 1 )) || |
4358
|
|
|
( in_array( substr( $datetime, $cx, 1 ), array( '-', '/' )))) |
4359
|
|
|
$tx--; // tz length counter |
4360
|
|
|
} |
4361
|
|
|
if( 0 > $tx ) { |
4362
|
|
|
$tz = substr( $datetime, $tx ); |
4363
|
|
|
$datetime = trim( substr( $datetime, 0, $len + $tx + 1 )); |
4364
|
|
|
} |
4365
|
|
|
} |
4366
|
|
|
if( 0 < substr_count( $datetime, '-' )) { |
4367
|
|
|
$datetime = str_replace( '-', '/', $datetime ); |
4368
|
|
|
} |
4369
|
|
|
elseif( ctype_digit( substr( $datetime, 0, 8 )) && |
4370
|
|
|
( 'T' == substr( $datetime, 8, 1 )) && |
4371
|
|
|
ctype_digit( substr( $datetime, 9, 6 ))) { |
4372
|
|
|
$datetime = substr( $datetime, 4, 2 ) |
4373
|
|
|
.'/'.substr( $datetime, 6, 2 ) |
4374
|
|
|
.'/'.substr( $datetime, 0, 4 ) |
4375
|
|
|
.' '.substr( $datetime, 9, 2 ) |
4376
|
|
|
.':'.substr( $datetime, 11, 2 ) |
4377
|
|
|
.':'.substr( $datetime, 13); |
4378
|
|
|
} |
4379
|
|
|
$datestring = date( 'Y-m-d H:i:s', strtotime( $datetime )); |
4380
|
|
|
$tz = trim( $tz ); |
4381
|
|
|
$output = array(); |
4382
|
|
|
$output['year'] = substr( $datestring, 0, 4 ); |
4383
|
|
|
$output['month'] = substr( $datestring, 5, 2 ); |
4384
|
|
|
$output['day'] = substr( $datestring, 8, 2 ); |
4385
|
|
|
if(( 6 == $parno ) || ( 7 == $parno )) { |
4386
|
|
|
$output['hour'] = substr( $datestring, 11, 2 ); |
4387
|
|
|
$output['min'] = substr( $datestring, 14, 2 ); |
4388
|
|
|
$output['sec'] = substr( $datestring, 17, 2 ); |
4389
|
|
|
if( !empty( $tz )) |
4390
|
|
|
$output['tz'] = $tz; |
4391
|
|
|
} |
4392
|
|
|
elseif( 3 != $parno ) { |
4393
|
|
|
if(( '00' < substr( $datestring, 11, 2 )) || |
4394
|
|
|
( '00' < substr( $datestring, 14, 2 )) || |
4395
|
|
|
( '00' < substr( $datestring, 17, 2 ))) { |
4396
|
|
|
$output['hour'] = substr( $datestring, 11, 2 ); |
4397
|
|
|
$output['min'] = substr( $datestring, 14, 2 ); |
4398
|
|
|
$output['sec'] = substr( $datestring, 17, 2 ); |
4399
|
|
|
} |
4400
|
|
|
if( !empty( $tz )) |
4401
|
|
|
$output['tz'] = $tz; |
4402
|
|
|
} |
4403
|
|
|
return $output; |
4404
|
|
|
} |
4405
|
|
|
/** |
4406
|
|
|
* ensures internal duration format for input in array format |
4407
|
|
|
* |
4408
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
4409
|
|
|
* @since 2.1.1 - 2007-06-24 |
4410
|
|
|
* @param array $duration |
4411
|
|
|
* @return array |
4412
|
|
|
*/ |
4413
|
|
|
function _duration_array( $duration ) { |
4414
|
|
|
$output = array(); |
4415
|
|
|
if( is_array( $duration ) && |
4416
|
|
|
( 1 == count( $duration )) && |
4417
|
|
|
isset( $duration['sec'] ) && |
4418
|
|
|
( 60 < $duration['sec'] )) { |
4419
|
|
|
$durseconds = $duration['sec']; |
4420
|
|
|
$output['week'] = floor( $durseconds / ( 60 * 60 * 24 * 7 )); |
4421
|
|
|
$durseconds = $durseconds % ( 60 * 60 * 24 * 7 ); |
4422
|
|
|
$output['day'] = floor( $durseconds / ( 60 * 60 * 24 )); |
4423
|
|
|
$durseconds = $durseconds % ( 60 * 60 * 24 ); |
4424
|
|
|
$output['hour'] = floor( $durseconds / ( 60 * 60 )); |
4425
|
|
|
$durseconds = $durseconds % ( 60 * 60 ); |
4426
|
|
|
$output['min'] = floor( $durseconds / ( 60 )); |
4427
|
|
|
$output['sec'] = ( $durseconds % ( 60 )); |
4428
|
|
|
} |
4429
|
|
|
else { |
4430
|
|
|
foreach( $duration as $durKey => $durValue ) { |
4431
|
|
|
if( empty( $durValue )) continue; |
4432
|
|
View Code Duplication |
switch ( $durKey ) { |
4433
|
|
|
case '0': |
4434
|
|
|
case 'week': |
4435
|
|
|
$output['week'] = $durValue; |
4436
|
|
|
break; |
4437
|
|
|
case '1': |
4438
|
|
|
case 'day': |
4439
|
|
|
$output['day'] = $durValue; |
4440
|
|
|
break; |
4441
|
|
|
case '2': |
4442
|
|
|
case 'hour': |
4443
|
|
|
$output['hour'] = $durValue; |
4444
|
|
|
break; |
4445
|
|
|
case '3': |
4446
|
|
|
case 'min': |
4447
|
|
|
$output['min'] = $durValue; |
4448
|
|
|
break; |
4449
|
|
|
case '4': |
4450
|
|
|
case 'sec': |
4451
|
|
|
$output['sec'] = $durValue; |
4452
|
|
|
break; |
4453
|
|
|
} |
4454
|
|
|
} |
4455
|
|
|
} |
4456
|
|
|
if( isset( $output['week'] ) && ( 0 < $output['week'] )) { |
4457
|
|
|
unset( $output['day'], $output['hour'], $output['min'], $output['sec'] ); |
4458
|
|
|
return $output; |
4459
|
|
|
} |
4460
|
|
|
unset( $output['week'] ); |
4461
|
|
|
if( empty( $output['day'] )) |
4462
|
|
|
unset( $output['day'] ); |
4463
|
|
|
if ( isset( $output['hour'] ) || isset( $output['min'] ) || isset( $output['sec'] )) { |
4464
|
|
|
if( !isset( $output['hour'] )) $output['hour'] = 0; |
4465
|
|
|
if( !isset( $output['min'] )) $output['min'] = 0; |
4466
|
|
|
if( !isset( $output['sec'] )) $output['sec'] = 0; |
4467
|
|
|
if(( 0 == $output['hour'] ) && ( 0 == $output['min'] ) && ( 0 == $output['sec'] )) |
4468
|
|
|
unset( $output['hour'], $output['min'], $output['sec'] ); |
4469
|
|
|
} |
4470
|
|
|
return $output; |
4471
|
|
|
} |
4472
|
|
|
/** |
4473
|
|
|
* convert duration to date in array format based on input or dtstart value |
4474
|
|
|
* |
4475
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
4476
|
|
|
* @since 2.4.8 - 2008-10-30 |
4477
|
|
|
* @param array $startdate, optional |
|
|
|
|
4478
|
|
|
* @param array $duration, optional |
|
|
|
|
4479
|
|
|
* @return array, date format |
|
|
|
|
4480
|
|
|
*/ |
4481
|
|
|
function duration2date( $startdate=FALSE, $duration=FALSE ) { |
4482
|
|
|
if( $startdate && $duration ) { |
4483
|
|
|
$d1 = $startdate; |
4484
|
|
|
$dur = $duration; |
4485
|
|
|
} |
4486
|
|
|
elseif( isset( $this->dtstart['value'] ) && isset( $this->duration['value'] )) { |
4487
|
|
|
$d1 = $this->dtstart['value']; |
4488
|
|
|
$dur = $this->duration['value']; |
4489
|
|
|
} |
4490
|
|
|
else |
4491
|
|
|
return null; |
4492
|
|
|
$dateOnly = ( isset( $d1['hour'] ) || isset( $d1['min'] ) || isset( $d1['sec'] )) ? FALSE : TRUE; |
4493
|
|
|
$d1['hour'] = ( isset( $d1['hour'] )) ? $d1['hour'] : 0; |
4494
|
|
|
$d1['min'] = ( isset( $d1['min'] )) ? $d1['min'] : 0; |
4495
|
|
|
$d1['sec'] = ( isset( $d1['sec'] )) ? $d1['sec'] : 0; |
4496
|
|
|
$dtend = mktime( $d1['hour'], $d1['min'], $d1['sec'], $d1['month'], $d1['day'], $d1['year'] ); |
4497
|
|
View Code Duplication |
if( isset( $dur['week'] )) |
4498
|
|
|
$dtend += ( $dur['week'] * 7 * 24 * 60 * 60 ); |
4499
|
|
View Code Duplication |
if( isset( $dur['day'] )) |
4500
|
|
|
$dtend += ( $dur['day'] * 24 * 60 * 60 ); |
4501
|
|
|
if( isset( $dur['hour'] )) |
4502
|
|
|
$dtend += ( $dur['hour'] * 60 *60 ); |
4503
|
|
|
if( isset( $dur['min'] )) |
4504
|
|
|
$dtend += ( $dur['min'] * 60 ); |
4505
|
|
|
if( isset( $dur['sec'] )) |
4506
|
|
|
$dtend += $dur['sec']; |
4507
|
|
|
$dtend2 = array(); |
4508
|
|
|
$dtend2['year'] = date('Y', $dtend ); |
4509
|
|
|
$dtend2['month'] = date('m', $dtend ); |
4510
|
|
|
$dtend2['day'] = date('d', $dtend ); |
4511
|
|
|
$dtend2['hour'] = date('H', $dtend ); |
4512
|
|
|
$dtend2['min'] = date('i', $dtend ); |
4513
|
|
|
$dtend2['sec'] = date('s', $dtend ); |
4514
|
|
|
if( isset( $d1['tz'] )) |
4515
|
|
|
$dtend2['tz'] = $d1['tz']; |
4516
|
|
|
if( $dateOnly && (( 0 == $dtend2['hour'] ) && ( 0 == $dtend2['min'] ) && ( 0 == $dtend2['sec'] ))) |
4517
|
|
|
unset( $dtend2['hour'], $dtend2['min'], $dtend2['sec'] ); |
4518
|
|
|
return $dtend2; |
4519
|
|
|
} |
4520
|
|
|
/** |
4521
|
|
|
* ensures internal duration format for input in string format |
4522
|
|
|
* |
4523
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
4524
|
|
|
* @since 2.0.5 - 2007-03-14 |
4525
|
|
|
* @param string $duration |
4526
|
|
|
* @return array |
4527
|
|
|
*/ |
4528
|
|
|
function _duration_string( $duration ) { |
4529
|
|
|
$duration = (string) trim( $duration ); |
4530
|
|
|
while( 'P' != strtoupper( substr( $duration, 0, 1 ))) { |
4531
|
|
|
if( 0 < strlen( $duration )) |
4532
|
|
|
$duration = substr( $duration, 1 ); |
4533
|
|
|
else |
4534
|
|
|
return false; // no leading P !?!? |
4535
|
|
|
} |
4536
|
|
|
$duration = substr( $duration, 1 ); // skip P |
4537
|
|
|
$duration = str_replace ( 't', 'T', $duration ); |
4538
|
|
|
$duration = str_replace ( 'T', '', $duration ); |
4539
|
|
|
$output = array(); |
4540
|
|
|
$val = null; |
4541
|
|
|
for( $ix=0; $ix < strlen( $duration ); $ix++ ) { |
4542
|
|
|
switch( strtoupper( $duration{$ix} )) { |
4543
|
|
|
case 'W': |
4544
|
|
|
$output['week'] = $val; |
4545
|
|
|
$val = null; |
4546
|
|
|
break; |
4547
|
|
|
case 'D': |
4548
|
|
|
$output['day'] = $val; |
4549
|
|
|
$val = null; |
4550
|
|
|
break; |
4551
|
|
|
case 'H': |
4552
|
|
|
$output['hour'] = $val; |
4553
|
|
|
$val = null; |
4554
|
|
|
break; |
4555
|
|
|
case 'M': |
4556
|
|
|
$output['min'] = $val; |
4557
|
|
|
$val = null; |
4558
|
|
|
break; |
4559
|
|
|
case 'S': |
4560
|
|
|
$output['sec'] = $val; |
4561
|
|
|
$val = null; |
4562
|
|
|
break; |
4563
|
|
|
default: |
4564
|
|
|
if( !ctype_digit( $duration{$ix} )) |
4565
|
|
|
return false; // unknown duration controll character !?!? |
4566
|
|
|
else |
4567
|
|
|
$val .= $duration{$ix}; |
4568
|
|
|
} |
4569
|
|
|
} |
4570
|
|
|
return $this->_duration_array( $output ); |
4571
|
|
|
} |
4572
|
|
|
/** |
4573
|
|
|
* if not preSet, if exist, remove key with expected value from array and return hit value else return elseValue |
4574
|
|
|
* |
4575
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
4576
|
|
|
* @since 2.4.16 - 2008-11-08 |
4577
|
|
|
* @param array $array |
4578
|
|
|
* @param string $expkey, expected key |
|
|
|
|
4579
|
|
|
* @param string $expval, expected value |
|
|
|
|
4580
|
|
|
* @param int $hitVal optional, return value if found |
4581
|
|
|
* @param int $elseVal optional, return value if not found |
4582
|
|
|
* @param int $preSet optional, return value if already preset |
4583
|
|
|
* @return int |
4584
|
|
|
*/ |
4585
|
|
|
function _existRem( &$array, $expkey, $expval=FALSE, $hitVal=null, $elseVal=null, $preSet=null ) { |
4586
|
|
|
if( $preSet ) |
|
|
|
|
4587
|
|
|
return $preSet; |
4588
|
|
|
if( !is_array( $array ) || ( 0 == count( $array ))) |
4589
|
|
|
return $elseVal; |
4590
|
|
|
foreach( $array as $key => $value ) { |
4591
|
|
|
if( strtoupper( $expkey ) == strtoupper( $key )) { |
4592
|
|
|
if( !$expval || ( strtoupper( $expval ) == strtoupper( $array[$key] ))) { |
4593
|
|
|
unset( $array[$key] ); |
4594
|
|
|
return $hitVal; |
4595
|
|
|
} |
4596
|
|
|
} |
4597
|
|
|
} |
4598
|
|
|
return $elseVal; |
4599
|
|
|
} |
4600
|
|
|
/** |
4601
|
|
|
* creates formatted output for calendar component property data value type date/date-time |
4602
|
|
|
* |
4603
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
4604
|
|
|
* @since 2.4.8 - 2008-10-30 |
4605
|
|
|
* @param array $datetime |
4606
|
|
|
* @param int $parno, optional, default 6 |
|
|
|
|
4607
|
|
|
* @return string |
4608
|
|
|
*/ |
4609
|
|
|
function _format_date_time( $datetime, $parno=6 ) { |
4610
|
|
View Code Duplication |
if( !isset( $datetime['year'] ) && |
4611
|
|
|
!isset( $datetime['month'] ) && |
4612
|
|
|
!isset( $datetime['day'] ) && |
4613
|
|
|
!isset( $datetime['hour'] ) && |
4614
|
|
|
!isset( $datetime['min'] ) && |
4615
|
|
|
!isset( $datetime['sec'] )) |
4616
|
|
|
return ; |
4617
|
|
|
$output = null; |
4618
|
|
|
// if( !isset( $datetime['day'] )) { $o=''; foreach($datetime as $k=>$v) {if(is_array($v)) $v=implode('-',$v);$o.=" $k=>$v";} echo " day SAKNAS : $o <br />\n"; } |
4619
|
|
|
foreach( $datetime as $dkey => $dvalue ) { |
4620
|
|
|
if( 'tz' != $dkey ) |
4621
|
|
|
$datetime[$dkey] = (integer) $dvalue; |
4622
|
|
|
} |
4623
|
|
|
$output = date('Ymd', mktime( 0, 0, 0, $datetime['month'], $datetime['day'], $datetime['year'])); |
4624
|
|
|
if( isset( $datetime['hour'] ) || |
4625
|
|
|
isset( $datetime['min'] ) || |
4626
|
|
|
isset( $datetime['sec'] ) || |
4627
|
|
|
isset( $datetime['tz'] )) { |
4628
|
|
View Code Duplication |
if( isset( $datetime['tz'] ) && |
4629
|
|
|
!isset( $datetime['hour'] )) |
4630
|
|
|
$datetime['hour'] = 0; |
4631
|
|
View Code Duplication |
if( isset( $datetime['hour'] ) && |
4632
|
|
|
!isset( $datetime['min'] )) |
4633
|
|
|
$datetime['min'] = 0; |
4634
|
|
View Code Duplication |
if( isset( $datetime['hour'] ) && |
4635
|
|
|
isset( $datetime['min'] ) && |
4636
|
|
|
!isset( $datetime['sec'] )) |
4637
|
|
|
$datetime['sec'] = 0; |
4638
|
|
|
$date = mktime( $datetime['hour'], $datetime['min'], $datetime['sec'], $datetime['month'], $datetime['day'], $datetime['year']); |
4639
|
|
|
$output .= date('\THis', $date ); |
4640
|
|
|
if( isset( $datetime['tz'] ) && ( '' < trim ( $datetime['tz'] ))) { |
4641
|
|
|
$datetime['tz'] = trim( $datetime['tz'] ); |
4642
|
|
|
if( 'Z' == $datetime['tz'] ) |
4643
|
|
|
$output .= 'Z'; |
4644
|
|
|
$offset = $this->_tz2offset( $datetime['tz'] ); |
4645
|
|
|
if( 0 != $offset ) { |
4646
|
|
|
$date = mktime( $datetime['hour'], $datetime['min'], ($datetime['sec'] + $offset), $datetime['month'], $datetime['day'], $datetime['year']); |
4647
|
|
|
$output = date( 'Ymd\THis\Z', $date ); |
4648
|
|
|
} |
4649
|
|
|
} |
4650
|
|
|
elseif( 7 == $parno ) |
4651
|
|
|
$output .= 'Z'; |
4652
|
|
|
} |
4653
|
|
|
return $output; |
4654
|
|
|
} |
4655
|
|
|
/** |
4656
|
|
|
* creates formatted output for calendar component property data value type duration |
4657
|
|
|
* |
4658
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
4659
|
|
|
* @since 2.4.16 - 2008-10-10 |
4660
|
|
|
* @param array $duration ( week, day, hour, min, sec ) |
4661
|
|
|
* @return string |
4662
|
|
|
*/ |
4663
|
|
|
function _format_duration( $duration ) { |
4664
|
|
View Code Duplication |
if( !isset( $duration['week'] ) && |
4665
|
|
|
!isset( $duration['day'] ) && |
4666
|
|
|
!isset( $duration['hour'] ) && |
4667
|
|
|
!isset( $duration['min'] ) && |
4668
|
|
|
!isset( $duration['sec'] )) |
4669
|
|
|
return; |
4670
|
|
|
$output = 'P'; |
4671
|
|
|
if( isset( $duration['week'] ) && ( 0 < $duration['week'] )) |
4672
|
|
|
$output .= $duration['week'].'W'; |
4673
|
|
|
else { |
4674
|
|
|
if( isset($duration['day'] ) && ( 0 < $duration['day'] )) |
4675
|
|
|
$output .= $duration['day'].'D'; |
4676
|
|
|
if(( isset( $duration['hour']) && ( 0 < $duration['hour'] )) || |
4677
|
|
|
( isset( $duration['min']) && ( 0 < $duration['min'] )) || |
4678
|
|
|
( isset( $duration['sec']) && ( 0 < $duration['sec'] ))) { |
4679
|
|
|
$output .= 'T'; |
4680
|
|
|
$output .= ( isset( $duration['hour']) && ( 0 < $duration['hour'] )) ? $duration['hour'].'H' : '0H'; |
4681
|
|
|
$output .= ( isset( $duration['min']) && ( 0 < $duration['min'] )) ? $duration['min']. 'M' : '0M'; |
4682
|
|
|
$output .= ( isset( $duration['sec']) && ( 0 < $duration['sec'] )) ? $duration['sec']. 'S' : '0S'; |
4683
|
|
|
} |
4684
|
|
|
} |
4685
|
|
|
return $output; |
4686
|
|
|
} |
4687
|
|
|
/** |
4688
|
|
|
* creates formatted output for calendar component property data value type recur |
4689
|
|
|
* |
4690
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
4691
|
|
|
* @since 2.4.8 - 2008-10-22 |
4692
|
|
|
* @param array $recurlabel |
4693
|
|
|
* @param array $recurdata |
4694
|
|
|
* @return string |
4695
|
|
|
*/ |
4696
|
|
|
function _format_recur( $recurlabel, $recurdata ) { |
4697
|
|
|
$output = null; |
4698
|
|
|
foreach( $recurdata as $therule ) { |
4699
|
|
|
if( empty( $therule['value'] )) { |
4700
|
|
|
if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( $recurlabel ); |
4701
|
|
|
continue; |
4702
|
|
|
} |
4703
|
|
|
$attributes = ( isset( $therule['params'] )) ? $this->_createParams( $therule['params'] ) : null; |
4704
|
|
|
$content1 = $content2 = null; |
4705
|
|
|
foreach( $therule['value'] as $rulelabel => $rulevalue ) { |
4706
|
|
|
switch( $rulelabel ) { |
4707
|
|
|
case 'FREQ': |
4708
|
|
|
$content1 .= "FREQ=$rulevalue"; |
4709
|
|
|
break; |
4710
|
|
|
case 'UNTIL': |
4711
|
|
|
$content2 .= ";UNTIL="; |
4712
|
|
|
$content2 .= $this->_format_date_time( $rulevalue ); |
4713
|
|
|
break; |
4714
|
|
|
case 'COUNT': |
4715
|
|
|
case 'INTERVAL': |
4716
|
|
|
case 'WKST': |
4717
|
|
|
$content2 .= ";$rulelabel=$rulevalue"; |
4718
|
|
|
break; |
4719
|
|
|
case 'BYSECOND': |
4720
|
|
|
case 'BYMINUTE': |
4721
|
|
|
case 'BYHOUR': |
4722
|
|
|
case 'BYMONTHDAY': |
4723
|
|
|
case 'BYYEARDAY': |
4724
|
|
|
case 'BYWEEKNO': |
4725
|
|
|
case 'BYMONTH': |
4726
|
|
|
case 'BYSETPOS': |
4727
|
|
|
$content2 .= ";$rulelabel="; |
4728
|
|
|
if (is_array( $rulevalue )) { |
4729
|
|
|
foreach( $rulevalue as $vix => $valuePart ) { |
4730
|
|
|
$content2 .= ( $vix ) ? ',' : null; |
4731
|
|
|
$content2 .= $valuePart; |
4732
|
|
|
} |
4733
|
|
|
} else { |
4734
|
|
|
$content2 .= $rulevalue; |
4735
|
|
|
} |
4736
|
|
|
break; |
4737
|
|
|
case 'BYDAY': |
4738
|
|
|
$content2 .= ";$rulelabel="; |
4739
|
|
|
$bydaycnt = 0; |
4740
|
|
|
foreach( $rulevalue as $vix => $valuePart ) { |
4741
|
|
|
$content21 = $content22 = null; |
4742
|
|
|
if( is_array( $valuePart )) { |
4743
|
|
|
$content2 .= ( $bydaycnt ) ? ',' : null; |
4744
|
|
|
foreach( $valuePart as $vix2 => $valuePart2 ) { |
4745
|
|
|
if( 'DAY' != strtoupper( $vix2 )) |
4746
|
|
|
$content21 .= $valuePart2; |
4747
|
|
|
else |
4748
|
|
|
$content22 .= $valuePart2; |
4749
|
|
|
} |
4750
|
|
|
$content2 .= $content21.$content22; |
4751
|
|
|
$bydaycnt++; |
4752
|
|
|
} |
4753
|
|
|
else { |
4754
|
|
|
$content2 .= ( $bydaycnt ) ? ',' : null; |
4755
|
|
|
if( 'DAY' != strtoupper( $vix )) |
4756
|
|
|
$content21 .= $valuePart; |
4757
|
|
|
else { |
4758
|
|
|
$content22 .= $valuePart; |
4759
|
|
|
$bydaycnt++; |
4760
|
|
|
} |
4761
|
|
|
$content2 .= $content21.$content22; |
4762
|
|
|
} |
4763
|
|
|
} |
4764
|
|
|
break; |
4765
|
|
|
default: |
4766
|
|
|
$content2 .= ";$rulelabel=$rulevalue"; |
4767
|
|
|
break; |
4768
|
|
|
} |
4769
|
|
|
} |
4770
|
|
|
$output .= $this->_createElement( $recurlabel, $attributes, $content1.$content2 ); |
4771
|
|
|
} |
4772
|
|
|
return $output; |
4773
|
|
|
} |
4774
|
|
|
/** |
4775
|
|
|
* create property name case - lower/upper |
4776
|
|
|
* |
4777
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
4778
|
|
|
* @since 0.9.7 - 2006-11-20 |
4779
|
|
|
* @param string $propertyName |
4780
|
|
|
* @return string |
4781
|
|
|
*/ |
4782
|
|
|
function _formatPropertyName( $propertyName ) { |
4783
|
|
|
switch( $this->format ) { |
4784
|
|
|
case 'xcal': |
4785
|
|
|
return strtolower( $propertyName ); |
4786
|
|
|
break; |
4787
|
|
|
default: |
4788
|
|
|
return strtoupper( $propertyName ); |
4789
|
|
|
break; |
4790
|
|
|
} |
4791
|
|
|
} |
4792
|
|
|
/** |
4793
|
|
|
* checks if input array contains a date |
4794
|
|
|
* |
4795
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
4796
|
|
|
* @since 2.4.16 - 2008-10-25 |
4797
|
|
|
* @param array $input |
4798
|
|
|
* @return bool |
4799
|
|
|
*/ |
4800
|
|
|
function _isArrayDate( $input ) { |
4801
|
|
|
if( isset( $input['week'] ) || ( !in_array( count( $input ), array( 3, 6, 7 )))) |
4802
|
|
|
return FALSE; |
4803
|
|
|
if( 7 == count( $input )) |
4804
|
|
|
return TRUE; |
4805
|
|
View Code Duplication |
if( isset( $input['year'] ) && isset( $input['month'] ) && isset( $input['day'] )) |
4806
|
|
|
return checkdate( (int) $input['month'], (int) $input['day'], (int) $input['year'] ); |
4807
|
|
|
if( isset( $input['day'] ) || isset( $input['hour'] ) || isset( $input['min'] ) || isset( $input['sec'] )) |
4808
|
|
|
return FALSE; |
4809
|
|
|
if( in_array( 0, $input )) |
4810
|
|
|
return FALSE; |
4811
|
|
|
if(( 1970 > $input[0] ) || ( 12 < $input[1] ) || ( 31 < $input[2] )) |
4812
|
|
|
return FALSE; |
4813
|
|
View Code Duplication |
if(( isset( $input[0] ) && isset( $input[1] ) && isset( $input[2] )) && |
4814
|
|
|
checkdate( (int) $input[1], (int) $input[2], (int) $input[0] )) |
4815
|
|
|
return TRUE; |
4816
|
|
|
$input = $this->_date_time_string( $input[1].'/'.$input[2].'/'.$input[0], 3 ); // m - d - Y |
4817
|
|
View Code Duplication |
if( isset( $input['year'] ) && isset( $input['month'] ) && isset( $input['day'] )) |
4818
|
|
|
return checkdate( (int) $input['month'], (int) $input['day'], (int) $input['year'] ); |
4819
|
|
|
return FALSE; |
4820
|
|
|
} |
4821
|
|
|
/** |
4822
|
|
|
* checks if input array contains a timestamp date |
4823
|
|
|
* |
4824
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
4825
|
|
|
* @since 2.4.16 - 2008-10-18 |
4826
|
|
|
* @param array $input |
4827
|
|
|
* @return bool |
4828
|
|
|
*/ |
4829
|
|
|
function _isArrayTimestampDate( $input ) { |
4830
|
|
|
return ( is_array( $input ) && isset( $input['timestamp'] )) ? TRUE : FALSE ; |
4831
|
|
|
} |
4832
|
|
|
/** |
4833
|
|
|
* controll if input string contains traling UTC offset |
4834
|
|
|
* |
4835
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
4836
|
|
|
* @since 2.4.16 - 2008-10-19 |
4837
|
|
|
* @param string $input |
4838
|
|
|
* @return bool |
4839
|
|
|
*/ |
4840
|
|
|
function _isOffset( $input ) { |
4841
|
|
|
$input = trim( (string) $input ); |
4842
|
|
|
if( 'Z' == substr( $input, -1 )) |
4843
|
|
|
return TRUE; |
4844
|
|
View Code Duplication |
elseif(( 5 <= strlen( $input )) && |
4845
|
|
|
( in_array( substr( $input, -5, 1 ), array( '+', '-' ))) && |
4846
|
|
|
( '0000' < substr( $input, -4 )) && ( '9999' >= substr( $input, -4 ))) |
4847
|
|
|
return TRUE; |
4848
|
|
View Code Duplication |
elseif(( 7 <= strlen( $input )) && |
4849
|
|
|
( in_array( substr( $input, -7, 1 ), array( '+', '-' ))) && |
4850
|
|
|
( '000000' < substr( $input, -6 )) && ( '999999' >= substr( $input, -6 ))) |
4851
|
|
|
return TRUE; |
4852
|
|
|
return FALSE; |
4853
|
|
|
|
4854
|
|
|
} |
4855
|
|
|
/** |
4856
|
|
|
* check if property not exists within component |
4857
|
|
|
* |
4858
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
4859
|
|
|
* @since 2.5.1 - 2008-10-15 |
4860
|
|
|
* @param string $propName |
4861
|
|
|
* @return bool |
4862
|
|
|
*/ |
4863
|
|
|
function _notExistProp( $propName ) { |
4864
|
|
|
if( empty( $propName )) return FALSE; // when deleting x-prop, an empty propName may be used=allowed |
4865
|
|
|
$propName = strtolower( $propName ); |
4866
|
|
|
if( 'last-modified' == $propName ) { if( !isset( $this->lastmodified )) return TRUE; } |
4867
|
|
|
elseif( 'percent-complete' == $propName ) { if( !isset( $this->percentcomplete )) return TRUE; } |
4868
|
|
|
elseif( 'recurrence-id' == $propName ) { if( !isset( $this->recurrenceid )) return TRUE; } |
4869
|
|
|
elseif( 'related-to' == $propName ) { if( !isset( $this->relatedto )) return TRUE; } |
4870
|
|
|
elseif( 'request-status' == $propName ) { if( !isset( $this->requeststatus )) return TRUE; } |
4871
|
|
|
elseif(( 'x-' != substr($propName,0,2)) && !isset( $this->$propName )) return TRUE; |
4872
|
|
|
return FALSE; |
4873
|
|
|
} |
4874
|
|
|
/** |
4875
|
|
|
* remakes a recur pattern to an array of dates |
4876
|
|
|
* |
4877
|
|
|
* if missing, UNTIL is set 1 year from startdate (emergency break) |
4878
|
|
|
* |
4879
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
4880
|
|
|
* @since 2.4.16 - 2008-10-18 |
4881
|
|
|
* @param array $result, array to update, array([timestamp] => timestamp) |
|
|
|
|
4882
|
|
|
* @param array $recur, pattern for recurrency (only value part, params ignored) |
|
|
|
|
4883
|
|
|
* @param array $wdate, component start date |
|
|
|
|
4884
|
|
|
* @param array $startdate, start date |
|
|
|
|
4885
|
|
|
* @param array $enddate, optional |
|
|
|
|
4886
|
|
|
* @return array of recurrence (start-)dates as index |
4887
|
|
|
* @todo BYHOUR, BYMINUTE, BYSECOND, ev. BYSETPOS due to ambiguity, WEEKLY at year end/start |
4888
|
|
|
*/ |
4889
|
|
|
function _recur2date( & $result, $recur, $wdate, $startdate, $enddate=FALSE ) { |
4890
|
|
|
foreach( $wdate as $k => $v ) if( ctype_digit( $v )) $wdate[$k] = (int) $v; |
4891
|
|
|
$wdatets = $this->_date2timestamp( $wdate ); |
4892
|
|
|
$startdatets = $this->_date2timestamp( $startdate ); |
4893
|
|
|
if( !$enddate ) { |
4894
|
|
|
$enddate = $startdate; |
4895
|
|
|
$enddate['year'] += 1; |
4896
|
|
|
// echo "recur __in_ ".implode('-',$startdate)." period start ".implode('-',$wdate)." period end ".implode('-',$enddate)."<br />\n";print_r($recur);echo "<br />\n";//test### |
4897
|
|
|
} |
4898
|
|
|
$endDatets = $this->_date2timestamp( $enddate ); // fix break |
|
|
|
|
4899
|
|
|
if( !isset( $recur['COUNT'] ) && !isset( $recur['UNTIL'] )) |
4900
|
|
|
$recur['UNTIL'] = $enddate; // create break |
4901
|
|
|
if( isset( $recur['UNTIL'] )) { |
4902
|
|
|
$tdatets = $this->_date2timestamp( $recur['UNTIL'] ); |
4903
|
|
|
if( $endDatets > $tdatets ) { |
4904
|
|
|
$endDatets = $tdatets; // emergency break |
4905
|
|
|
$enddate = $this->_timestamp2date( $endDatets, 6 ); |
4906
|
|
|
} |
4907
|
|
|
else |
4908
|
|
|
$recur['UNTIL'] = $this->_timestamp2date( $endDatets, 6 ); |
4909
|
|
|
} |
4910
|
|
|
if( $wdatets > $endDatets ) { |
4911
|
|
|
//echo "recur out of date ".implode('-',$this->_date_time_string(date('Y-m-d H:i:s',$wdatets),6))."<br />\n";//test |
4912
|
|
|
return array(); // nothing to do.. . |
4913
|
|
|
} |
4914
|
|
|
if( !isset( $recur['FREQ'] )) // "MUST be specified.. ." |
4915
|
|
|
$recur['FREQ'] = 'DAILY'; // ?? |
4916
|
|
|
$wkst = ( isset( $recur['WKST'] ) && ( 'SU' == $recur['WKST'] )) ? 24*60*60 : 0; // ?? |
4917
|
|
|
if( !isset( $recur['INTERVAL'] )) |
4918
|
|
|
$recur['INTERVAL'] = 1; |
4919
|
|
|
$countcnt = ( !isset( $recur['BYSETPOS'] )) ? 1 : 0; // DTSTART counts as the first occurrence |
4920
|
|
|
/* find out how to step up dates and set index for interval count */ |
4921
|
|
|
$step = array(); |
4922
|
|
|
if( 'YEARLY' == $recur['FREQ'] ) |
4923
|
|
|
$step['year'] = 1; |
4924
|
|
|
elseif( 'MONTHLY' == $recur['FREQ'] ) |
4925
|
|
|
$step['month'] = 1; |
4926
|
|
|
elseif( 'WEEKLY' == $recur['FREQ'] ) |
4927
|
|
|
$step['day'] = 7; |
4928
|
|
|
else |
4929
|
|
|
$step['day'] = 1; |
4930
|
|
|
if( isset( $step['year'] ) && isset( $recur['BYMONTH'] )) |
4931
|
|
|
$step = array( 'month' => 1 ); |
4932
|
|
|
if( empty( $step ) && isset( $recur['BYWEEKNO'] )) // ?? |
4933
|
|
|
$step = array( 'day' => 7 ); |
4934
|
|
|
if( isset( $recur['BYYEARDAY'] ) || isset( $recur['BYMONTHDAY'] ) || isset( $recur['BYDAY'] )) |
4935
|
|
|
$step = array( 'day' => 1 ); |
4936
|
|
|
$intervalarr = array(); |
4937
|
|
|
if( 1 < $recur['INTERVAL'] ) { |
4938
|
|
|
$intervalix = $this->_recurIntervalIx( $recur['FREQ'], $wdate, $wkst ); |
4939
|
|
|
$intervalarr = array( $intervalix => 0 ); |
4940
|
|
|
} |
4941
|
|
|
if( isset( $recur['BYSETPOS'] )) { // save start date + weekno |
4942
|
|
|
$bysetposymd1 = $bysetposymd2 = $bysetposw1 = $bysetposw2 = array(); |
4943
|
|
|
$bysetposWold = (int) date( 'W', ( $wdatets + $wkst )); |
4944
|
|
|
$bysetposYold = $wdate['year']; |
4945
|
|
|
$bysetposMold = $wdate['month']; |
4946
|
|
|
$bysetposDold = $wdate['day']; |
4947
|
|
|
if( is_array( $recur['BYSETPOS'] )) { |
4948
|
|
|
foreach( $recur['BYSETPOS'] as $bix => $bval ) |
4949
|
|
|
$recur['BYSETPOS'][$bix] = (int) $bval; |
4950
|
|
|
} |
4951
|
|
|
else |
4952
|
|
|
$recur['BYSETPOS'] = array( (int) $recur['BYSETPOS'] ); |
4953
|
|
|
$this->_stepdate( $enddate, $endDatets, $step); // make sure to count whole last period |
4954
|
|
|
} |
4955
|
|
|
$this->_stepdate( $wdate, $wdatets, $step); |
4956
|
|
|
$year_old = null; |
4957
|
|
|
$daynames = array( 'SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA' ); |
4958
|
|
|
/* MAIN LOOP */ |
4959
|
|
|
// echo "recur start ".implode('-',$wdate)." end ".implode('-',$enddate)."<br />\n";//test |
4960
|
|
|
while( TRUE ) { |
4961
|
|
|
if( isset( $endDatets ) && ( $wdatets > $endDatets )) |
4962
|
|
|
break; |
4963
|
|
|
if( isset( $recur['COUNT'] ) && ( $countcnt >= $recur['COUNT'] )) |
4964
|
|
|
break; |
4965
|
|
|
if( $year_old != $wdate['year'] ) { |
4966
|
|
|
$year_old = $wdate['year']; |
4967
|
|
|
$daycnts = array(); |
4968
|
|
|
$yeardays = $weekno = 0; |
4969
|
|
|
$yeardaycnt = array(); |
4970
|
|
|
for( $m = 1; $m <= 12; $m++ ) { // count up and update up-counters |
4971
|
|
|
$daycnts[$m] = array(); |
4972
|
|
|
$weekdaycnt = array(); |
4973
|
|
|
foreach( $daynames as $dn ) |
4974
|
|
|
$yeardaycnt[$dn] = $weekdaycnt[$dn] = 0; |
4975
|
|
|
$mcnt = date( 't', mktime( 0, 0, 0, $m, 1, $wdate['year'] )); |
4976
|
|
|
for( $d = 1; $d <= $mcnt; $d++ ) { |
4977
|
|
|
$daycnts[$m][$d] = array(); |
4978
|
|
|
if( isset( $recur['BYYEARDAY'] )) { |
4979
|
|
|
$yeardays++; |
4980
|
|
|
$daycnts[$m][$d]['yearcnt_up'] = $yeardays; |
4981
|
|
|
} |
4982
|
|
|
if( isset( $recur['BYDAY'] )) { |
4983
|
|
|
$day = date( 'w', mktime( 0, 0, 0, $m, $d, $wdate['year'] )); |
4984
|
|
|
$day = $daynames[$day]; |
4985
|
|
|
$daycnts[$m][$d]['DAY'] = $day; |
4986
|
|
|
$weekdaycnt[$day]++; |
4987
|
|
|
$daycnts[$m][$d]['monthdayno_up'] = $weekdaycnt[$day]; |
4988
|
|
|
$yeardaycnt[$day]++; |
4989
|
|
|
$daycnts[$m][$d]['yeardayno_up'] = $yeardaycnt[$day]; |
4990
|
|
|
} |
4991
|
|
|
if( isset( $recur['BYWEEKNO'] ) || ( $recur['FREQ'] == 'WEEKLY' )) |
4992
|
|
|
$daycnts[$m][$d]['weekno_up'] =(int)date('W',mktime(0,0,$wkst,$m,$d,$wdate['year'])); |
4993
|
|
|
} |
4994
|
|
|
} |
4995
|
|
|
$daycnt = 0; |
4996
|
|
|
$yeardaycnt = array(); |
4997
|
|
|
if( isset( $recur['BYWEEKNO'] ) || ( $recur['FREQ'] == 'WEEKLY' )) { |
4998
|
|
|
$weekno = null; |
4999
|
|
|
for( $d=31; $d > 25; $d-- ) { // get last weekno for year |
5000
|
|
|
if( !$weekno ) |
5001
|
|
|
$weekno = $daycnts[12][$d]['weekno_up']; |
5002
|
|
|
elseif( $weekno < $daycnts[12][$d]['weekno_up'] ) { |
5003
|
|
|
$weekno = $daycnts[12][$d]['weekno_up']; |
5004
|
|
|
break; |
5005
|
|
|
} |
5006
|
|
|
} |
5007
|
|
|
} |
5008
|
|
|
for( $m = 12; $m > 0; $m-- ) { // count down and update down-counters |
5009
|
|
|
$weekdaycnt = array(); |
5010
|
|
|
foreach( $daynames as $dn ) |
5011
|
|
|
$yeardaycnt[$dn] = $weekdaycnt[$dn] = 0; |
5012
|
|
|
$monthcnt = 0; |
5013
|
|
|
$mcnt = date( 't', mktime( 0, 0, 0, $m, 1, $wdate['year'] )); |
5014
|
|
|
for( $d = $mcnt; $d > 0; $d-- ) { |
5015
|
|
|
if( isset( $recur['BYYEARDAY'] )) { |
5016
|
|
|
$daycnt -= 1; |
5017
|
|
|
$daycnts[$m][$d]['yearcnt_down'] = $daycnt; |
5018
|
|
|
} |
5019
|
|
|
if( isset( $recur['BYMONTHDAY'] )) { |
5020
|
|
|
$monthcnt -= 1; |
5021
|
|
|
$daycnts[$m][$d]['monthcnt_down'] = $monthcnt; |
5022
|
|
|
} |
5023
|
|
|
if( isset( $recur['BYDAY'] )) { |
5024
|
|
|
$day = $daycnts[$m][$d]['DAY']; |
5025
|
|
|
$weekdaycnt[$day] -= 1; |
5026
|
|
|
$daycnts[$m][$d]['monthdayno_down'] = $weekdaycnt[$day]; |
5027
|
|
|
$yeardaycnt[$day] -= 1; |
5028
|
|
|
$daycnts[$m][$d]['yeardayno_down'] = $yeardaycnt[$day]; |
5029
|
|
|
} |
5030
|
|
|
if( isset( $recur['BYWEEKNO'] ) || ( $recur['FREQ'] == 'WEEKLY' )) |
5031
|
|
|
$daycnts[$m][$d]['weekno_down'] = ($daycnts[$m][$d]['weekno_up'] - $weekno - 1); |
5032
|
|
|
} |
5033
|
|
|
} |
5034
|
|
|
} |
5035
|
|
|
/* check interval */ |
5036
|
|
|
if( 1 < $recur['INTERVAL'] ) { |
5037
|
|
|
/* create interval index */ |
5038
|
|
|
$intervalix = $this->_recurIntervalIx( $recur['FREQ'], $wdate, $wkst ); |
5039
|
|
|
/* check interval */ |
5040
|
|
|
$currentKey = array_keys( $intervalarr ); |
5041
|
|
|
$currentKey = end( $currentKey ); // get last index |
5042
|
|
|
if( $currentKey != $intervalix ) |
5043
|
|
|
$intervalarr = array( $intervalix => ( $intervalarr[$currentKey] + 1 )); |
5044
|
|
|
if(( $recur['INTERVAL'] != $intervalarr[$intervalix] ) && |
5045
|
|
|
( 0 != $intervalarr[$intervalix] )) { |
5046
|
|
|
/* step up date */ |
5047
|
|
|
//echo "skip: ".implode('-',$wdate)." ix=$intervalix old=$currentKey interval=".$intervalarr[$intervalix]."<br />\n";//test |
5048
|
|
|
$this->_stepdate( $wdate, $wdatets, $step); |
5049
|
|
|
continue; |
5050
|
|
|
} |
5051
|
|
|
else // continue within the selected interval |
5052
|
|
|
$intervalarr[$intervalix] = 0; |
5053
|
|
|
//echo "cont: ".implode('-',$wdate)." ix=$intervalix old=$currentKey interval=".$intervalarr[$intervalix]."<br />\n";//test |
5054
|
|
|
} |
5055
|
|
|
$updateOK = TRUE; |
5056
|
|
|
if( $updateOK && isset( $recur['BYMONTH'] )) |
5057
|
|
|
$updateOK = $this->_recurBYcntcheck( $recur['BYMONTH'] |
5058
|
|
|
, $wdate['month'] |
5059
|
|
|
,($wdate['month'] - 13)); |
5060
|
|
View Code Duplication |
if( $updateOK && isset( $recur['BYWEEKNO'] )) |
5061
|
|
|
$updateOK = $this->_recurBYcntcheck( $recur['BYWEEKNO'] |
5062
|
|
|
, $daycnts[$wdate['month']][$wdate['day']]['weekno_up'] |
5063
|
|
|
, $daycnts[$wdate['month']][$wdate['day']]['weekno_down'] ); |
5064
|
|
View Code Duplication |
if( $updateOK && isset( $recur['BYYEARDAY'] )) |
5065
|
|
|
$updateOK = $this->_recurBYcntcheck( $recur['BYYEARDAY'] |
5066
|
|
|
, $daycnts[$wdate['month']][$wdate['day']]['yearcnt_up'] |
5067
|
|
|
, $daycnts[$wdate['month']][$wdate['day']]['yearcnt_down'] ); |
5068
|
|
|
if( $updateOK && isset( $recur['BYMONTHDAY'] )) |
5069
|
|
|
$updateOK = $this->_recurBYcntcheck( $recur['BYMONTHDAY'] |
5070
|
|
|
, $wdate['day'] |
5071
|
|
|
, $daycnts[$wdate['month']][$wdate['day']]['monthcnt_down'] ); |
5072
|
|
|
//echo "efter BYMONTHDAY: ".implode('-',$wdate).' status: '; echo ($updateOK) ? 'TRUE' : 'FALSE'; echo "<br />\n";//test### |
5073
|
|
|
if( $updateOK && isset( $recur['BYDAY'] )) { |
5074
|
|
|
$updateOK = FALSE; |
5075
|
|
|
$m = $wdate['month']; |
5076
|
|
|
$d = $wdate['day']; |
5077
|
|
|
if( isset( $recur['BYDAY']['DAY'] )) { // single day, opt with year/month day order no |
5078
|
|
|
$daynoexists = $daynosw = $daynamesw = FALSE; |
5079
|
|
|
if( $recur['BYDAY']['DAY'] == $daycnts[$m][$d]['DAY'] ) |
5080
|
|
|
$daynamesw = TRUE; |
5081
|
|
|
if( isset( $recur['BYDAY'][0] )) { |
5082
|
|
|
$daynoexists = TRUE; |
5083
|
|
View Code Duplication |
if(( isset( $recur['FREQ'] ) && ( $recur['FREQ'] == 'MONTHLY' )) || isset( $recur['BYMONTH'] )) |
5084
|
|
|
$daynosw = $this->_recurBYcntcheck( $recur['BYDAY'][0] |
5085
|
|
|
, $daycnts[$m][$d]['monthdayno_up'] |
5086
|
|
|
, $daycnts[$m][$d]['monthdayno_down'] ); |
5087
|
|
|
elseif( isset( $recur['FREQ'] ) && ( $recur['FREQ'] == 'YEARLY' )) |
5088
|
|
|
$daynosw = $this->_recurBYcntcheck( $recur['BYDAY'][0] |
5089
|
|
|
, $daycnts[$m][$d]['yeardayno_up'] |
5090
|
|
|
, $daycnts[$m][$d]['yeardayno_down'] ); |
5091
|
|
|
} |
5092
|
|
View Code Duplication |
if(( $daynoexists && $daynosw && $daynamesw ) || |
5093
|
|
|
( !$daynoexists && !$daynosw && $daynamesw )) { |
5094
|
|
|
$updateOK = TRUE; |
5095
|
|
|
} |
5096
|
|
|
//echo "daynoexists:$daynoexists daynosw:$daynosw daynamesw:$daynamesw<br />\n"; // test ### |
5097
|
|
|
} |
5098
|
|
|
else { |
5099
|
|
|
foreach( $recur['BYDAY'] as $bydayvalue ) { |
5100
|
|
|
$daynoexists = $daynosw = $daynamesw = FALSE; |
5101
|
|
|
if( isset( $bydayvalue['DAY'] ) && |
5102
|
|
|
( $bydayvalue['DAY'] == $daycnts[$m][$d]['DAY'] )) |
5103
|
|
|
$daynamesw = TRUE; |
5104
|
|
|
if( isset( $bydayvalue[0] )) { |
5105
|
|
|
$daynoexists = TRUE; |
5106
|
|
View Code Duplication |
if(( isset( $recur['FREQ'] ) && ( $recur['FREQ'] == 'MONTHLY' )) || |
5107
|
|
|
isset( $recur['BYMONTH'] )) |
5108
|
|
|
$daynosw = $this->_recurBYcntcheck( $bydayvalue['0'] |
5109
|
|
|
, $daycnts[$m][$d]['monthdayno_up'] |
5110
|
|
|
, $daycnts[$m][$d]['monthdayno_down'] ); |
5111
|
|
|
elseif( isset( $recur['FREQ'] ) && ( $recur['FREQ'] == 'YEARLY' )) |
5112
|
|
|
$daynosw = $this->_recurBYcntcheck( $bydayvalue['0'] |
5113
|
|
|
, $daycnts[$m][$d]['yeardayno_up'] |
5114
|
|
|
, $daycnts[$m][$d]['yeardayno_down'] ); |
5115
|
|
|
} |
5116
|
|
|
//echo "daynoexists:$daynoexists daynosw:$daynosw daynamesw:$daynamesw<br />\n"; // test ### |
5117
|
|
View Code Duplication |
if(( $daynoexists && $daynosw && $daynamesw ) || |
5118
|
|
|
( !$daynoexists && !$daynosw && $daynamesw )) { |
5119
|
|
|
$updateOK = TRUE; |
5120
|
|
|
break; |
5121
|
|
|
} |
5122
|
|
|
} |
5123
|
|
|
} |
5124
|
|
|
} |
5125
|
|
|
//echo "efter BYDAY: ".implode('-',$wdate).' status: '; echo ($updateOK) ? 'TRUE' : 'FALSE'; echo "<br />\n"; // test ### |
5126
|
|
|
/* check BYSETPOS */ |
5127
|
|
|
if( $updateOK ) { |
5128
|
|
|
if( isset( $recur['BYSETPOS'] ) && |
5129
|
|
|
( in_array( $recur['FREQ'], array( 'YEARLY', 'MONTHLY', 'WEEKLY', 'DAILY' )))) { |
5130
|
|
|
if( isset( $recur['WEEKLY'] )) { |
5131
|
|
|
if( $bysetposWold == $daycnts[$wdate['month']][$wdate['day']]['weekno_up'] ) |
5132
|
|
|
$bysetposw1[] = $wdatets; |
5133
|
|
|
else |
5134
|
|
|
$bysetposw2[] = $wdatets; |
5135
|
|
|
} |
5136
|
|
|
else { |
5137
|
|
|
if(( isset( $recur['FREQ'] ) && ( 'YEARLY' == $recur['FREQ'] ) && |
5138
|
|
|
( $bysetposYold == $wdate['year'] )) || |
5139
|
|
|
( isset( $recur['FREQ'] ) && ( 'MONTHLY' == $recur['FREQ'] ) && |
5140
|
|
|
(( $bysetposYold == $wdate['year'] ) && |
5141
|
|
|
( $bysetposMold == $wdate['month'] ))) || |
5142
|
|
|
( isset( $recur['FREQ'] ) && ( 'MONTHLY' == $recur['FREQ'] ) && |
5143
|
|
|
(( $bysetposYold == $wdate['year'] ) && |
5144
|
|
|
( $bysetposMold == $wdate['month']) && |
5145
|
|
|
( $bysetposDold == $wdate['sday'] )))) |
5146
|
|
|
$bysetposymd1[] = $wdatets; |
5147
|
|
|
else |
5148
|
|
|
$bysetposymd2[] = $wdatets; |
5149
|
|
|
} |
5150
|
|
|
} |
5151
|
|
|
else { |
5152
|
|
|
/* update result array if BYSETPOS is set */ |
5153
|
|
|
$countcnt++; |
5154
|
|
|
if( $startdatets <= $wdatets ) { // only output within period |
5155
|
|
|
$result[$wdatets] = TRUE; |
5156
|
|
|
//echo "recur ".implode('-',$this->_date_time_string(date('Y-m-d H:i:s',$wdatets),6))."<br />\n";//test |
5157
|
|
|
} |
5158
|
|
|
//else echo "recur undate ".implode('-',$this->_date_time_string(date('Y-m-d H:i:s',$wdatets),6))." okdatstart ".implode('-',$this->_date_time_string(date('Y-m-d H:i:s',$startdatets),6))."<br />\n";//test |
5159
|
|
|
$updateOK = FALSE; |
5160
|
|
|
} |
5161
|
|
|
} |
5162
|
|
|
/* step up date */ |
5163
|
|
|
$this->_stepdate( $wdate, $wdatets, $step); |
5164
|
|
|
/* check if BYSETPOS is set for updating result array */ |
5165
|
|
|
if( $updateOK && isset( $recur['BYSETPOS'] )) { |
5166
|
|
|
$bysetpos = FALSE; |
5167
|
|
|
if( isset( $recur['FREQ'] ) && ( 'YEARLY' == $recur['FREQ'] ) && |
5168
|
|
|
( $bysetposYold != $wdate['year'] )) { |
5169
|
|
|
$bysetpos = TRUE; |
5170
|
|
|
$bysetposYold = $wdate['year']; |
5171
|
|
|
} |
5172
|
|
|
elseif( isset( $recur['FREQ'] ) && ( 'MONTHLY' == $recur['FREQ'] && |
5173
|
|
|
(( $bysetposYold != $wdate['year'] ) || ( $bysetposMold != $wdate['month'] )))) { |
5174
|
|
|
$bysetpos = TRUE; |
5175
|
|
|
$bysetposYold = $wdate['year']; |
5176
|
|
|
$bysetposMold = $wdate['month']; |
5177
|
|
|
} |
5178
|
|
|
elseif( isset( $recur['FREQ'] ) && ( 'WEEKLY' == $recur['FREQ'] )) { |
5179
|
|
|
$weekno = (int) date( 'W', mktime( 0, 0, $wkst, $wdate['month'], $wdate['day'], $wdate['year'])); |
5180
|
|
|
if( $bysetposWold != $weekno ) { |
5181
|
|
|
$bysetposWold = $weekno; |
5182
|
|
|
$bysetpos = TRUE; |
5183
|
|
|
} |
5184
|
|
|
} |
5185
|
|
|
elseif( isset( $recur['FREQ'] ) && ( 'DAILY' == $recur['FREQ'] ) && |
5186
|
|
|
(( $bysetposYold != $wdate['year'] ) || |
5187
|
|
|
( $bysetposMold != $wdate['month'] ) || |
5188
|
|
|
( $bysetposDold != $wdate['sday'] ))) { |
5189
|
|
|
$bysetpos = TRUE; |
5190
|
|
|
$bysetposYold = $wdate['year']; |
5191
|
|
|
$bysetposMold = $wdate['month']; |
5192
|
|
|
$bysetposDold = $wdate['day']; |
5193
|
|
|
} |
5194
|
|
|
if( $bysetpos ) { |
5195
|
|
|
if( isset( $recur['BYWEEKNO'] )) { |
5196
|
|
|
$bysetposarr1 = & $bysetposw1; |
5197
|
|
|
$bysetposarr2 = & $bysetposw2; |
5198
|
|
|
} |
5199
|
|
|
else { |
5200
|
|
|
$bysetposarr1 = & $bysetposymd1; |
5201
|
|
|
$bysetposarr2 = & $bysetposymd2; |
5202
|
|
|
} |
5203
|
|
|
foreach( $recur['BYSETPOS'] as $ix ) { |
5204
|
|
|
if( 0 > $ix ) // both positive and negative BYSETPOS allowed |
5205
|
|
|
$ix = ( count( $bysetposarr1 ) + $ix + 1); |
5206
|
|
|
$ix--; |
5207
|
|
|
if( isset( $bysetposarr1[$ix] )) { |
5208
|
|
|
if( $startdatets <= $bysetposarr1[$ix] ) { // only output within period |
5209
|
|
|
$result[$bysetposarr1[$ix]] = TRUE; |
5210
|
|
|
//echo "recur ".implode('-',$this->_date_time_string(date('Y-m-d H:i:s',$bysetposarr1[$ix]),6))."<br />\n";//test |
5211
|
|
|
} |
5212
|
|
|
$countcnt++; |
5213
|
|
|
} |
5214
|
|
|
if( isset( $recur['COUNT'] ) && ( $countcnt >= $recur['COUNT'] )) |
5215
|
|
|
break; |
5216
|
|
|
} |
5217
|
|
|
$bysetposarr1 = $bysetposarr2; |
5218
|
|
|
$bysetposarr2 = array(); |
5219
|
|
|
} |
5220
|
|
|
} |
5221
|
|
|
} |
5222
|
|
|
} |
5223
|
|
|
function _recurBYcntcheck( $BYvalue, $upValue, $downValue ) { |
5224
|
|
|
if( is_array( $BYvalue ) && |
5225
|
|
|
( in_array( $upValue, $BYvalue ) || in_array( $downValue, $BYvalue ))) |
5226
|
|
|
return TRUE; |
5227
|
|
|
elseif(( $BYvalue == $upValue ) || ( $BYvalue == $downValue )) |
5228
|
|
|
return TRUE; |
5229
|
|
|
else |
5230
|
|
|
return FALSE; |
5231
|
|
|
} |
5232
|
|
|
function _recurIntervalIx( $freq, $date, $wkst ) { |
5233
|
|
|
/* create interval index */ |
5234
|
|
|
switch( $freq ) { |
5235
|
|
|
case 'YEARLY': |
5236
|
|
|
$intervalix = $date['year']; |
5237
|
|
|
break; |
5238
|
|
|
case 'MONTHLY': |
5239
|
|
|
$intervalix = $date['year'].'-'.$date['month']; |
5240
|
|
|
break; |
5241
|
|
|
case 'WEEKLY': |
5242
|
|
|
$wdatets = $this->_date2timestamp( $date ); |
5243
|
|
|
$intervalix = (int) date( 'W', ( $wdatets + $wkst )); |
5244
|
|
|
break; |
5245
|
|
|
case 'DAILY': |
5246
|
|
|
default: |
5247
|
|
|
$intervalix = $date['year'].'-'.$date['month'].'-'.$date['day']; |
5248
|
|
|
break; |
5249
|
|
|
} |
5250
|
|
|
return $intervalix; |
5251
|
|
|
} |
5252
|
|
|
/** |
5253
|
|
|
* convert input format for exrule and rrule to internal format |
5254
|
|
|
* |
5255
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
5256
|
|
|
* @since 2.4.16 - 2008-10-19 |
5257
|
|
|
* @param array $rexrule |
5258
|
|
|
* @return array |
5259
|
|
|
*/ |
5260
|
|
|
function _setRexrule( $rexrule ) { |
5261
|
|
|
$input = array(); |
5262
|
|
|
if( empty( $rexrule )) |
5263
|
|
|
return $input; |
5264
|
|
|
foreach( $rexrule as $rexrulelabel => $rexrulevalue ) { |
5265
|
|
|
$rexrulelabel = strtoupper( $rexrulelabel ); |
5266
|
|
|
if( 'UNTIL' != $rexrulelabel ) |
5267
|
|
|
$input[$rexrulelabel] = $rexrulevalue; |
5268
|
|
|
else { |
5269
|
|
|
if( $this->_isArrayTimestampDate( $rexrulevalue )) // timestamp date |
5270
|
|
|
$input[$rexrulelabel] = $this->_timestamp2date( $rexrulevalue, 6 ); |
5271
|
|
|
elseif( $this->_isArrayDate( $rexrulevalue )) // date-time |
5272
|
|
|
$input[$rexrulelabel] = $this->_date_time_array( $rexrulevalue, 6 ); |
5273
|
|
|
elseif( 8 <= strlen( trim( $rexrulevalue ))) // ex. 2006-08-03 10:12:18 |
5274
|
|
|
$input[$rexrulelabel] = $this->_date_time_string( $rexrulevalue ); |
5275
|
|
|
if(( 3 < count( $input[$rexrulelabel] )) && !isset( $input[$rexrulelabel]['tz'] )) |
5276
|
|
|
$input[$rexrulelabel]['tz'] = 'Z'; |
5277
|
|
|
} |
5278
|
|
|
} |
5279
|
|
|
return $input; |
5280
|
|
|
} |
5281
|
|
|
/** |
5282
|
|
|
* convert format for input date to internal date with parameters |
5283
|
|
|
* |
5284
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
5285
|
|
|
* @since 2.4.17 - 2008-10-31 |
5286
|
|
|
* @param mixed $year |
5287
|
|
|
* @param mixed $month optional |
5288
|
|
|
* @param int $day optional |
5289
|
|
|
* @param int $hour optional |
5290
|
|
|
* @param int $min optional |
5291
|
|
|
* @param int $sec optional |
5292
|
|
|
* @param array $params optional |
5293
|
|
|
* @param string $caller optional |
5294
|
|
|
* @return array |
5295
|
|
|
*/ |
5296
|
|
|
function _setDate( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $tz=FALSE, $params=FALSE, $caller=null ) { |
5297
|
|
|
$input = $parno = null; |
5298
|
|
|
$localtime = (( 'dtstart' == $caller ) && in_array( $this->objName, array( 'vtimezone', 'standard', 'daylight' ))) ? TRUE : FALSE; |
5299
|
|
|
if( $this->_isArrayDate( $year )) { |
5300
|
|
|
if( $localtime ) unset ( $month['VALUE'], $month['TZID'] ); |
5301
|
|
|
$input['params'] = $this->_setParams( $month, array( 'VALUE' => 'DATE-TIME' )); |
5302
|
|
|
if( isset( $input['params']['TZID'] )) { |
5303
|
|
|
$input['params']['VALUE'] = 'DATE-TIME'; |
5304
|
|
|
unset( $year['tz'] ); |
5305
|
|
|
} |
5306
|
|
|
$hitval = (( !empty( $year['tz'] ) || !empty( $year[6] ))) ? 7 : 6; |
5307
|
|
|
$parno = $this->_existRem( $input['params'], 'VALUE', 'DATE-TIME', $hitval ); |
5308
|
|
|
$parno = $this->_existRem( $input['params'], 'VALUE', 'DATE', 3, count( $year ), $parno ); |
5309
|
|
|
$input['value'] = $this->_date_time_array( $year, $parno ); |
5310
|
|
|
} |
5311
|
|
|
elseif( $this->_isArrayTimestampDate( $year )) { |
5312
|
|
|
if( $localtime ) unset ( $month['VALUE'], $month['TZID'] ); |
5313
|
|
|
$input['params'] = $this->_setParams( $month, array( 'VALUE' => 'DATE-TIME' )); |
5314
|
|
|
if( isset( $input['params']['TZID'] )) { |
5315
|
|
|
$input['params']['VALUE'] = 'DATE-TIME'; |
5316
|
|
|
unset( $year['tz'] ); |
5317
|
|
|
} |
5318
|
|
|
$parno = $this->_existRem( $input['params'], 'VALUE', 'DATE', 3 ); |
5319
|
|
|
$hitval = ( isset( $year['tz'] )) ? 7 : 6; |
5320
|
|
|
$parno = $this->_existRem( $input['params'], 'VALUE', 'DATE-TIME', $hitval, $parno ); |
5321
|
|
|
$input['value'] = $this->_timestamp2date( $year, $parno ); |
5322
|
|
|
} |
5323
|
|
|
elseif( 8 <= strlen( trim( $year ))) { // ex. 2006-08-03 10:12:18 |
5324
|
|
|
if( $localtime ) unset ( $month['VALUE'], $month['TZID'] ); |
5325
|
|
|
$input['params'] = $this->_setParams( $month, array( 'VALUE' => 'DATE-TIME' )); |
5326
|
|
View Code Duplication |
if( isset( $input['params']['TZID'] )) { |
5327
|
|
|
$input['params']['VALUE'] = 'DATE-TIME'; |
5328
|
|
|
$parno = 6; |
5329
|
|
|
} |
5330
|
|
|
$parno = $this->_existRem( $input['params'], 'VALUE', 'DATE-TIME', 7, $parno ); |
5331
|
|
|
$parno = $this->_existRem( $input['params'], 'VALUE', 'DATE', 3, $parno, $parno ); |
5332
|
|
|
$input['value'] = $this->_date_time_string( $year, $parno ); |
5333
|
|
|
} |
5334
|
|
|
else { |
5335
|
|
|
if( is_array( $params )) { |
5336
|
|
|
if( $localtime ) unset ( $params['VALUE'], $params['TZID'] ); |
5337
|
|
|
$input['params'] = $this->_setParams( $params, array( 'VALUE' => 'DATE-TIME' )); |
5338
|
|
|
} |
5339
|
|
|
elseif( is_array( $tz )) { |
5340
|
|
|
$input['params'] = $this->_setParams( $tz, array( 'VALUE' => 'DATE-TIME' )); |
5341
|
|
|
$tz = FALSE; |
5342
|
|
|
} |
5343
|
|
|
elseif( is_array( $hour )) { |
5344
|
|
|
$input['params'] = $this->_setParams( $hour, array( 'VALUE' => 'DATE-TIME' )); |
5345
|
|
|
$hour = $min = $sec = $tz = FALSE; |
5346
|
|
|
} |
5347
|
|
View Code Duplication |
if( isset( $input['params']['TZID'] )) { |
5348
|
|
|
$tz = null; |
5349
|
|
|
$input['params']['VALUE'] = 'DATE-TIME'; |
5350
|
|
|
} |
5351
|
|
|
$parno = $this->_existRem( $input['params'], 'VALUE', 'DATE', 3 ); |
5352
|
|
|
$hitval = ( !empty( $tz )) ? 7 : 6; |
5353
|
|
|
$parno = $this->_existRem( $input['params'], 'VALUE', 'DATE-TIME', $hitval, $parno, $parno ); |
5354
|
|
|
$input['value'] = array( 'year' => $year, 'month' => $month, 'day' => $day ); |
5355
|
|
|
if( 3 != $parno ) { |
5356
|
|
|
$input['value']['hour'] = ( $hour ) ? $hour : '0'; |
5357
|
|
|
$input['value']['min'] = ( $min ) ? $min : '0'; |
5358
|
|
|
$input['value']['sec'] = ( $sec ) ? $sec : '0'; |
5359
|
|
|
if( !empty( $tz )) |
5360
|
|
|
$input['value']['tz'] = $tz; |
5361
|
|
|
} |
5362
|
|
|
} |
5363
|
|
|
if( 3 == $parno ) { |
5364
|
|
|
$input['params']['VALUE'] = 'DATE'; |
5365
|
|
|
unset( $input['value']['tz'] ); |
5366
|
|
|
unset( $input['params']['TZID'] ); |
5367
|
|
|
} |
5368
|
|
|
elseif( isset( $input['params']['TZID'] )) |
5369
|
|
|
unset( $input['value']['tz'] ); |
5370
|
|
|
if( $localtime ) unset( $input['value']['tz'], $input['params']['TZID'] ); |
5371
|
|
View Code Duplication |
if( isset( $input['value']['tz'] )) |
5372
|
|
|
$input['value']['tz'] = (string) $input['value']['tz']; |
5373
|
|
|
if( !empty( $input['value']['tz'] ) && ( 'Z' != $input['value']['tz'] ) && |
5374
|
|
|
( !$this->_isOffset( $input['value']['tz'] ))) |
5375
|
|
|
$input['params']['TZID'] = $input['value']['tz']; |
5376
|
|
|
return $input; |
5377
|
|
|
} |
5378
|
|
|
/** |
5379
|
|
|
* convert format for input date (UTC) to internal date with parameters |
5380
|
|
|
* |
5381
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
5382
|
|
|
* @since 2.4.17 - 2008-10-31 |
5383
|
|
|
* @param mixed $year |
5384
|
|
|
* @param mixed $month optional |
5385
|
|
|
* @param int $day optional |
5386
|
|
|
* @param int $hour optional |
5387
|
|
|
* @param int $min optional |
5388
|
|
|
* @param int $sec optional |
5389
|
|
|
* @param array $params optional |
5390
|
|
|
* @return array |
5391
|
|
|
*/ |
5392
|
|
|
function _setDate2( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) { |
5393
|
|
|
$input = null; |
5394
|
|
|
if( $this->_isArrayDate( $year )) { |
5395
|
|
|
$input['value'] = $this->_date_time_array( $year, 7 ); |
5396
|
|
|
$input['params'] = $this->_setParams( $month, array( 'VALUE' => 'DATE-TIME' ) ); |
5397
|
|
|
} |
5398
|
|
|
elseif( $this->_isArrayTimestampDate( $year )) { |
5399
|
|
|
$input['value'] = $this->_timestamp2date( $year, 7 ); |
5400
|
|
|
$input['params'] = $this->_setParams( $month, array( 'VALUE' => 'DATE-TIME' ) ); |
5401
|
|
|
} |
5402
|
|
|
elseif( 8 <= strlen( trim( $year ))) { // ex. 2006-08-03 10:12:18 |
5403
|
|
|
$input['value'] = $this->_date_time_string( $year, 7 ); |
5404
|
|
|
$input['params'] = $this->_setParams( $month, array( 'VALUE' => 'DATE-TIME' ) ); |
5405
|
|
|
} |
5406
|
|
|
else { |
5407
|
|
|
$input['value'] = array( 'year' => $year |
5408
|
|
|
, 'month' => $month |
5409
|
|
|
, 'day' => $day |
5410
|
|
|
, 'hour' => $hour |
5411
|
|
|
, 'min' => $min |
5412
|
|
|
, 'sec' => $sec ); |
5413
|
|
|
$input['params'] = $this->_setParams( $params, array( 'VALUE' => 'DATE-TIME' )); |
|
|
|
|
5414
|
|
|
} |
5415
|
|
|
$parno = $this->_existRem( $input['params'], 'VALUE', 'DATE-TIME', 7 ); // remove default |
5416
|
|
|
if( !isset( $input['value']['hour'] )) |
5417
|
|
|
$input['value']['hour'] = 0; |
5418
|
|
|
if( !isset( $input['value']['min'] )) |
5419
|
|
|
$input['value']['min'] = 0; |
5420
|
|
|
if( !isset( $input['value']['sec'] )) |
5421
|
|
|
$input['value']['sec'] = 0; |
5422
|
|
|
if( !isset( $input['value']['tz'] ) || !$this->_isOffset( $input['value']['tz'] )) |
5423
|
|
|
$input['value']['tz'] = 'Z'; |
5424
|
|
|
return $input; |
5425
|
|
|
} |
5426
|
|
|
/** |
5427
|
|
|
* check index and set (an indexed) content in multiple value array |
5428
|
|
|
* |
5429
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
5430
|
|
|
* @since 2.5.1 - 2008-11-06 |
5431
|
|
|
* @param array $valArr |
5432
|
|
|
* @param mixed $value |
5433
|
|
|
* @param array $params |
5434
|
|
|
* @param array $defaults |
5435
|
|
|
* @param int $index |
5436
|
|
|
* @return void |
5437
|
|
|
*/ |
5438
|
|
|
function _setMval( & $valArr, $value, $params=FALSE, $defaults=FALSE, $index=FALSE ) { |
5439
|
|
|
if( !is_array( $valArr )) $valArr = array(); |
5440
|
|
|
if( $index ) |
|
|
|
|
5441
|
|
|
$index = $index - 1; |
5442
|
|
|
elseif( 0 < count( $valArr )) { |
5443
|
|
|
$index = end( array_keys( $valArr )); |
|
|
|
|
5444
|
|
|
$index += 1; |
5445
|
|
|
} |
5446
|
|
|
else |
5447
|
|
|
$index = 0; |
5448
|
|
|
$valArr[$index] = array( 'value' => $value, 'params' => $this->_setParams( $params, $defaults )); |
|
|
|
|
5449
|
|
|
ksort( $valArr ); |
5450
|
|
|
} |
5451
|
|
|
/** |
5452
|
|
|
* set input (formatted) parameters- component property attributes |
5453
|
|
|
* |
5454
|
|
|
* default parameters can be set, if missing |
5455
|
|
|
* |
5456
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
5457
|
|
|
* @since 1.x.x - 2007-05-01 |
5458
|
|
|
* @param array $params |
5459
|
|
|
* @param array $defaults |
5460
|
|
|
* @return array |
5461
|
|
|
*/ |
5462
|
|
|
function _setParams( $params, $defaults=FALSE ) { |
5463
|
|
|
if( !is_array( $params)) |
5464
|
|
|
$params = array(); |
5465
|
|
|
$input = array(); |
5466
|
|
|
foreach( $params as $paramKey => $paramValue ) { |
5467
|
|
|
if( is_array( $paramValue )) { |
5468
|
|
|
foreach( $paramValue as $pkey => $pValue ) { |
5469
|
|
View Code Duplication |
if(( '"' == substr( $pValue, 0, 1 )) && ( '"' == substr( $pValue, -1 ))) |
5470
|
|
|
$paramValue[$pkey] = substr( $pValue, 1, ( strlen( $pValue ) - 2 )); |
5471
|
|
|
} |
5472
|
|
|
} |
5473
|
|
View Code Duplication |
elseif(( '"' == substr( $paramValue, 0, 1 )) && ( '"' == substr( $paramValue, -1 ))) |
5474
|
|
|
$paramValue = substr( $paramValue, 1, ( strlen( $paramValue ) - 2 )); |
5475
|
|
|
if( 'VALUE' == strtoupper( $paramKey )) |
5476
|
|
|
$input['VALUE'] = strtoupper( $paramValue ); |
5477
|
|
|
else |
5478
|
|
|
$input[strtoupper( $paramKey )] = $paramValue; |
5479
|
|
|
} |
5480
|
|
|
if( is_array( $defaults )) { |
5481
|
|
|
foreach( $defaults as $paramKey => $paramValue ) { |
5482
|
|
|
if( !isset( $input[$paramKey] )) |
5483
|
|
|
$input[$paramKey] = $paramValue; |
5484
|
|
|
} |
5485
|
|
|
} |
5486
|
|
|
return (0 < count( $input )) ? $input : null; |
5487
|
|
|
} |
5488
|
|
|
/** |
5489
|
|
|
* step date, return updated date, array and timpstamp |
5490
|
|
|
* |
5491
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
5492
|
|
|
* @since 2.4.16 - 2008-10-18 |
5493
|
|
|
* @param array $date, date to step |
|
|
|
|
5494
|
|
|
* @param int $timestamp |
5495
|
|
|
* @param array $step, default array( 'day' => 1 ) |
|
|
|
|
5496
|
|
|
* @return void |
5497
|
|
|
*/ |
5498
|
|
|
function _stepdate( &$date, &$timestamp, $step=array( 'day' => 1 )) { |
5499
|
|
|
foreach( $step as $stepix => $stepvalue ) |
5500
|
|
|
$date[$stepix] += $stepvalue; |
5501
|
|
|
$timestamp = $this->_date2timestamp( $date ); |
5502
|
|
|
$date = $this->_timestamp2date( $timestamp, 6 ); |
5503
|
|
|
foreach( $date as $k => $v ) { |
5504
|
|
|
if( ctype_digit( $v )) |
5505
|
|
|
$date[$k] = (int) $v; |
5506
|
|
|
} |
5507
|
|
|
} |
5508
|
|
|
/** |
5509
|
|
|
* convert timestamp to date array |
5510
|
|
|
* |
5511
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
5512
|
|
|
* @since 2.4.16 - 2008-11-01 |
5513
|
|
|
* @param mixed $timestamp |
5514
|
|
|
* @param int $parno |
5515
|
|
|
* @return array |
5516
|
|
|
*/ |
5517
|
|
|
function _timestamp2date( $timestamp, $parno=6 ) { |
5518
|
|
|
if( is_array( $timestamp )) { |
5519
|
|
|
if(( 7 == $parno ) && !empty( $timestamp['tz'] )) |
5520
|
|
|
$tz = $timestamp['tz']; |
5521
|
|
|
$timestamp = $timestamp['timestamp']; |
5522
|
|
|
} |
5523
|
|
|
$output = array( 'year' => date( 'Y', $timestamp ) |
5524
|
|
|
, 'month' => date( 'm', $timestamp ) |
5525
|
|
|
, 'day' => date( 'd', $timestamp )); |
5526
|
|
|
if( 3 != $parno ) { |
5527
|
|
|
$output['hour'] = date( 'H', $timestamp ); |
5528
|
|
|
$output['min'] = date( 'i', $timestamp ); |
5529
|
|
|
$output['sec'] = date( 's', $timestamp ); |
5530
|
|
|
if( isset( $tz )) |
5531
|
|
|
$output['tz'] = $tz; |
5532
|
|
|
} |
5533
|
|
|
return $output; |
5534
|
|
|
} |
5535
|
|
|
/** |
5536
|
|
|
* convert (numeric) local time offset to seconds correcting localtime to GMT |
5537
|
|
|
* |
5538
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
5539
|
|
|
* @since 2.4.16 - 2008-10-19 |
5540
|
|
|
* @param string $offset |
|
|
|
|
5541
|
|
|
* @return integer |
5542
|
|
|
*/ |
5543
|
|
|
function _tz2offset( $tz ) { |
5544
|
|
|
$tz = trim( (string) $tz ); |
5545
|
|
|
$offset = 0; |
5546
|
|
|
if((( 5 != strlen( $tz )) && ( 7 != strlen( $tz ))) || |
5547
|
|
|
(( '+' != substr( $tz, 0, 1 )) && ( '-' != substr( $tz, 0, 1 ))) || |
5548
|
|
|
(( '0000' >= substr( $tz, 1, 4 )) && ( '9999' < substr( $tz, 1, 4 ))) || |
5549
|
|
|
(( 7 == strlen( $tz )) && ( '00' > substr( $tz, 5, 2 )) && ( '99' < substr( $tz, 5, 2 )))) |
5550
|
|
|
return $offset; |
5551
|
|
|
$hours2sec = (int) substr( $tz, 1, 2 ) * 3600; |
5552
|
|
|
$min2sec = (int) substr( $tz, 3, 2 ) * 60; |
5553
|
|
|
$sec = ( 7 == strlen( $tz )) ? (int) substr( $tz, -2 ) : '00'; |
5554
|
|
|
$offset = $hours2sec + $min2sec + $sec; |
5555
|
|
|
$offset = ('-' == substr( $tz, 0, 1 )) ? $offset : -1 * $offset; |
5556
|
|
|
return $offset; |
5557
|
|
|
} |
5558
|
|
|
/*********************************************************************************/ |
5559
|
|
|
/*********************************************************************************/ |
5560
|
|
|
/** |
5561
|
|
|
* get general component config variables or info about subcomponents |
5562
|
|
|
* |
5563
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
5564
|
|
|
* @since 2.5.1 - 2008-11-02 |
5565
|
|
|
* @param string $config |
5566
|
|
|
* @return value |
5567
|
|
|
*/ |
5568
|
|
|
function getConfig( $config ) { |
5569
|
|
|
switch( strtoupper( $config )) { |
5570
|
|
|
case 'ALLOWEMPTY': |
5571
|
|
|
return $this->allowEmpty; |
5572
|
|
|
break; |
5573
|
|
View Code Duplication |
case 'COMPSINFO': |
5574
|
|
|
unset( $this->compix ); |
5575
|
|
|
$info = array(); |
5576
|
|
|
if( isset( $this->components )) { |
5577
|
|
|
foreach( $this->components as $cix => $component ) { |
5578
|
|
|
if( empty( $component )) continue; |
5579
|
|
|
unset( $component->propix ); |
5580
|
|
|
$info[$cix]['ordno'] = $cix + 1; |
5581
|
|
|
$info[$cix]['type'] = $component->objName; |
5582
|
|
|
$info[$cix]['uid'] = $component->getProperty( 'uid' ); |
5583
|
|
|
$info[$cix]['props'] = $component->getConfig( 'propinfo' ); |
5584
|
|
|
$info[$cix]['sub'] = $component->getConfig( 'compsinfo' ); |
5585
|
|
|
unset( $component->propix ); |
5586
|
|
|
} |
5587
|
|
|
} |
5588
|
|
|
return $info; |
5589
|
|
|
break; |
5590
|
|
|
case 'FORMAT': |
5591
|
|
|
return $this->format; |
5592
|
|
|
break; |
5593
|
|
|
case 'LANGUAGE': |
5594
|
|
|
// get language for calendar component as defined in [RFC 1766] |
5595
|
|
|
return $this->language; |
5596
|
|
|
break; |
5597
|
|
|
case 'NL': |
5598
|
|
|
case 'NEWLINECHAR': |
5599
|
|
|
return $this->nl; |
5600
|
|
|
break; |
5601
|
|
|
case 'PROPINFO': |
5602
|
|
|
$output = array(); |
5603
|
|
|
if( !in_array( $this->objName, array( 'valarm', 'vtimezone', 'standard', 'daylight' ))) { |
5604
|
|
|
if( empty( $this->uid['value'] )) $this->_makeuid(); |
5605
|
|
|
$output['UID'] = 1; |
5606
|
|
|
} |
5607
|
|
|
if( !empty( $this->dtstamp )) $output['DTSTAMP'] = 1; |
5608
|
|
|
if( !empty( $this->summary )) $output['SUMMARY'] = 1; |
5609
|
|
|
if( !empty( $this->description )) $output['DESCRIPTION'] = count( $this->description ); |
5610
|
|
|
if( !empty( $this->dtstart )) $output['DTSTART'] = 1; |
5611
|
|
|
if( !empty( $this->dtend )) $output['DTEND'] = 1; |
5612
|
|
|
if( !empty( $this->due )) $output['DUE'] = 1; |
5613
|
|
|
if( !empty( $this->duration )) $output['DURATION'] = 1; |
5614
|
|
|
if( !empty( $this->rrule )) $output['RRULE'] = count( $this->rrule ); |
5615
|
|
|
if( !empty( $this->rdate )) $output['RDATE'] = count( $this->rdate ); |
5616
|
|
|
if( !empty( $this->exdate )) $output['EXDATE'] = count( $this->exdate ); |
5617
|
|
|
if( !empty( $this->exrule )) $output['EXRULE'] = count( $this->exrule ); |
5618
|
|
|
if( !empty( $this->action )) $output['ACTION'] = 1; |
5619
|
|
|
if( !empty( $this->attach )) $output['ATTACH'] = count( $this->attach ); |
5620
|
|
|
if( !empty( $this->attendee )) $output['ATTENDEE'] = count( $this->attendee ); |
5621
|
|
|
if( !empty( $this->categories )) $output['CATEGORIES'] = count( $this->categories ); |
5622
|
|
|
if( !empty( $this->class )) $output['CLASS'] = 1; |
5623
|
|
|
if( !empty( $this->comment )) $output['COMMENT'] = count( $this->comment ); |
5624
|
|
|
if( !empty( $this->completed )) $output['COMPLETED'] = 1; |
5625
|
|
|
if( !empty( $this->contact )) $output['CONTACT'] = count( $this->contact ); |
5626
|
|
|
if( !empty( $this->created )) $output['CREATED'] = 1; |
5627
|
|
|
if( !empty( $this->freebusy )) $output['FREEBUSY'] = count( $this->freebusy ); |
5628
|
|
|
if( !empty( $this->geo )) $output['GEO'] = 1; |
5629
|
|
|
if( !empty( $this->lastmodified )) $output['LAST-MODIFIED'] = 1; |
5630
|
|
|
if( !empty( $this->location )) $output['LOCATION'] = 1; |
5631
|
|
|
if( !empty( $this->organizer )) $output['ORGANIZER'] = 1; |
5632
|
|
|
if( !empty( $this->percentcomplete )) $output['PERCENT-COMPLETE'] = 1; |
5633
|
|
|
if( !empty( $this->priority )) $output['PRIORITY'] = 1; |
5634
|
|
|
if( !empty( $this->recurrenceid )) $output['RECURRENCE-ID'] = 1; |
5635
|
|
|
if( !empty( $this->relatedto )) $output['RELATED-TO'] = count( $this->relatedto ); |
5636
|
|
|
if( !empty( $this->repeat )) $output['REPEAT'] = 1; |
5637
|
|
|
if( !empty( $this->requeststatus )) $output['REQUEST-STATUS'] = count( $this->requeststatus ); |
5638
|
|
|
if( !empty( $this->resources )) $output['RESOURCES'] = count( $this->resources ); |
5639
|
|
|
if( !empty( $this->sequence )) $output['SEQUENCE'] = 1; |
5640
|
|
|
if( !empty( $this->status )) $output['STATUS'] = 1; |
5641
|
|
|
if( !empty( $this->transp )) $output['TRANSP'] = 1; |
5642
|
|
|
if( !empty( $this->trigger )) $output['TRIGGER'] = 1; |
5643
|
|
|
if( !empty( $this->tzid )) $output['TZID'] = 1; |
5644
|
|
|
if( !empty( $this->tzname )) $output['TZNAME'] = count( $this->tzname ); |
5645
|
|
|
if( !empty( $this->tzoffsetfrom )) $output['TZOFFSETTFROM'] = 1; |
5646
|
|
|
if( !empty( $this->tzoffsetto )) $output['TZOFFSETTO'] = 1; |
5647
|
|
|
if( !empty( $this->tzurl )) $output['TZURL'] = 1; |
5648
|
|
|
if( !empty( $this->url )) $output['URL'] = 1; |
5649
|
|
|
if( !empty( $this->xprop )) $output['X-PROP'] = count( $this->xprop ); |
5650
|
|
|
return $output; |
5651
|
|
|
break; |
5652
|
|
|
case 'UNIQUE_ID': |
5653
|
|
|
if( empty( $this->unique_id )) |
5654
|
|
|
$this->unique_id = ( isset( $_SERVER['SERVER_NAME'] )) ? gethostbyname( $_SERVER['SERVER_NAME'] ) : 'localhost'; |
5655
|
|
|
return $this->unique_id; |
5656
|
|
|
break; |
5657
|
|
|
} |
5658
|
|
|
} |
5659
|
|
|
/** |
5660
|
|
|
* general component config setting |
5661
|
|
|
* |
5662
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
5663
|
|
|
* @since 2.4.8 - 2008-10-24 |
5664
|
|
|
* @param string $config |
5665
|
|
|
* @param string $value |
5666
|
|
|
* @return void |
5667
|
|
|
*/ |
5668
|
|
|
function setConfig( $config, $value ) { |
5669
|
|
|
$res = FALSE; |
5670
|
|
|
switch( strtoupper( $config )) { |
5671
|
|
View Code Duplication |
case 'ALLOWEMPTY': |
5672
|
|
|
$this->allowEmpty = $value; |
5673
|
|
|
$subcfg = array( 'ALLOWEMPTY' => $value ); |
5674
|
|
|
$res = TRUE; |
5675
|
|
|
break; |
5676
|
|
View Code Duplication |
case 'FORMAT': |
5677
|
|
|
$value = trim( $value ); |
5678
|
|
|
$this->format = $value; |
5679
|
|
|
$this->_createFormat(); |
5680
|
|
|
$subcfg = array( 'FORMAT' => $value ); |
5681
|
|
|
$res = TRUE; |
5682
|
|
|
break; |
5683
|
|
View Code Duplication |
case 'LANGUAGE': |
5684
|
|
|
// set language for calendar component as defined in [RFC 1766] |
5685
|
|
|
$value = trim( $value ); |
5686
|
|
|
$this->language = $value; |
5687
|
|
|
$subcfg = array( 'LANGUAGE' => $value ); |
5688
|
|
|
$res = TRUE; |
5689
|
|
|
break; |
5690
|
|
|
case 'NL': |
5691
|
|
View Code Duplication |
case 'NEWLINECHAR': |
5692
|
|
|
$this->nl = $value; |
5693
|
|
|
$subcfg = array( 'NL' => $value ); |
5694
|
|
|
$res = TRUE; |
5695
|
|
|
break; |
5696
|
|
View Code Duplication |
case 'UNIQUE_ID': |
5697
|
|
|
$value = trim( $value ); |
5698
|
|
|
$this->unique_id = $value; |
5699
|
|
|
$subcfg = array( 'UNIQUE_ID' => $value ); |
5700
|
|
|
$res = TRUE; |
5701
|
|
|
break; |
5702
|
|
|
} |
5703
|
|
|
if( !$res ) return FALSE; |
5704
|
|
View Code Duplication |
if( isset( $subcfg ) && !empty( $this->components )) { |
5705
|
|
|
foreach( $subcfg as $cfgkey => $cfgvalue ) { |
5706
|
|
|
foreach( $this->components as $cix => $component ) { |
5707
|
|
|
$res = $component->setConfig( $cfgkey, $cfgvalue ); |
5708
|
|
|
if( !$res ) |
5709
|
|
|
break 2; |
5710
|
|
|
$this->components[$cix] = $component; // PHP4 compliant |
5711
|
|
|
} |
5712
|
|
|
} |
5713
|
|
|
} |
5714
|
|
|
return $res; |
5715
|
|
|
} |
5716
|
|
|
/*********************************************************************************/ |
5717
|
|
|
/** |
5718
|
|
|
* delete component property value |
5719
|
|
|
* |
5720
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
5721
|
|
|
* @since 2.5.1 - 2008-11-14 |
5722
|
|
|
* @param string $propName |
5723
|
|
|
* @param int @propix, optional, if specific property is wanted in case of multiply occurences |
5724
|
|
|
* @return bool, if successfull delete TRUE |
|
|
|
|
5725
|
|
|
*/ |
5726
|
|
|
function deleteProperty( $propName, $propix=FALSE ) { |
5727
|
|
|
if( $this->_notExistProp( $propName )) return FALSE; |
5728
|
|
|
$propName = strtoupper( $propName ); |
5729
|
|
View Code Duplication |
if( in_array( $propName, array( 'ATTACH', 'ATTENDEE', 'CATEGORIES', 'COMMENT', 'CONTACT', 'DESCRIPTION', 'EXDATE', 'EXRULE', |
5730
|
|
|
'FREEBUSY', 'RDATE', 'RELATED-TO', 'RESOURCES', 'RRULE', 'REQUEST-STATUS', 'TZNAME', 'X-PROP' ))) { |
5731
|
|
|
if( !$propix ) |
5732
|
|
|
$propix = ( isset( $this->propdelix[$propName] )) ? $this->propdelix[$propName] + 2 : 1; |
5733
|
|
|
$this->propdelix[$propName] = --$propix; |
5734
|
|
|
} |
5735
|
|
|
$return = FALSE; |
5736
|
|
|
switch( $propName ) { |
5737
|
|
View Code Duplication |
case 'ACTION': |
5738
|
|
|
if( !empty( $this->action )) { |
5739
|
|
|
$this->action = ''; |
5740
|
|
|
$return = TRUE; |
5741
|
|
|
} |
5742
|
|
|
break; |
5743
|
|
|
case 'ATTACH': |
5744
|
|
|
return $this->deletePropertyM( $this->attach, $propix ); |
|
|
|
|
5745
|
|
|
break; |
5746
|
|
|
case 'ATTENDEE': |
5747
|
|
|
return $this->deletePropertyM( $this->attendee, $propix ); |
|
|
|
|
5748
|
|
|
break; |
5749
|
|
|
case 'CATEGORIES': |
5750
|
|
|
return $this->deletePropertyM( $this->categories, $propix ); |
|
|
|
|
5751
|
|
|
break; |
5752
|
|
View Code Duplication |
case 'CLASS': |
5753
|
|
|
if( !empty( $this->class )) { |
5754
|
|
|
$this->class = ''; |
5755
|
|
|
$return = TRUE; |
5756
|
|
|
} |
5757
|
|
|
break; |
5758
|
|
|
case 'COMMENT': |
5759
|
|
|
return $this->deletePropertyM( $this->comment, $propix ); |
|
|
|
|
5760
|
|
|
break; |
5761
|
|
View Code Duplication |
case 'COMPLETED': |
5762
|
|
|
if( !empty( $this->completed )) { |
5763
|
|
|
$this->completed = ''; |
5764
|
|
|
$return = TRUE; |
5765
|
|
|
} |
5766
|
|
|
break; |
5767
|
|
|
case 'CONTACT': |
5768
|
|
|
return $this->deletePropertyM( $this->contact, $propix ); |
|
|
|
|
5769
|
|
|
break; |
5770
|
|
View Code Duplication |
case 'CREATED': |
5771
|
|
|
if( !empty( $this->created )) { |
5772
|
|
|
$this->created = ''; |
5773
|
|
|
$return = TRUE; |
5774
|
|
|
} |
5775
|
|
|
break; |
5776
|
|
|
case 'DESCRIPTION': |
5777
|
|
|
return $this->deletePropertyM( $this->description, $propix ); |
|
|
|
|
5778
|
|
|
break; |
5779
|
|
View Code Duplication |
case 'DTEND': |
5780
|
|
|
if( !empty( $this->dtend )) { |
5781
|
|
|
$this->dtend = ''; |
5782
|
|
|
$return = TRUE; |
5783
|
|
|
} |
5784
|
|
|
break; |
5785
|
|
View Code Duplication |
case 'DTSTAMP': |
5786
|
|
|
if( in_array( $this->objName, array( 'valarm', 'vtimezone', 'standard', 'daylight' ))) |
5787
|
|
|
return FALSE; |
5788
|
|
|
if( !empty( $this->dtstamp )) { |
5789
|
|
|
$this->dtstamp = ''; |
5790
|
|
|
$return = TRUE; |
5791
|
|
|
} |
5792
|
|
|
break; |
5793
|
|
View Code Duplication |
case 'DTSTART': |
5794
|
|
|
if( !empty( $this->dtstart )) { |
5795
|
|
|
$this->dtstart = ''; |
5796
|
|
|
$return = TRUE; |
5797
|
|
|
} |
5798
|
|
|
break; |
5799
|
|
View Code Duplication |
case 'DUE': |
5800
|
|
|
if( !empty( $this->due )) { |
5801
|
|
|
$this->due = ''; |
5802
|
|
|
$return = TRUE; |
5803
|
|
|
} |
5804
|
|
|
break; |
5805
|
|
View Code Duplication |
case 'DURATION': |
5806
|
|
|
if( !empty( $this->duration )) { |
5807
|
|
|
$this->duration = ''; |
5808
|
|
|
$return = TRUE; |
5809
|
|
|
} |
5810
|
|
|
break; |
5811
|
|
|
case 'EXDATE': |
5812
|
|
|
return $this->deletePropertyM( $this->exdate, $propix ); |
|
|
|
|
5813
|
|
|
break; |
5814
|
|
|
case 'EXRULE': |
5815
|
|
|
return $this->deletePropertyM( $this->exrule, $propix ); |
|
|
|
|
5816
|
|
|
break; |
5817
|
|
|
case 'FREEBUSY': |
5818
|
|
|
return $this->deletePropertyM( $this->freebusy, $propix ); |
|
|
|
|
5819
|
|
|
break; |
5820
|
|
View Code Duplication |
case 'GEO': |
5821
|
|
|
if( !empty( $this->geo )) { |
5822
|
|
|
$this->geo = ''; |
5823
|
|
|
$return = TRUE; |
5824
|
|
|
} |
5825
|
|
|
break; |
5826
|
|
|
case 'LAST-MODIFIED': |
5827
|
|
|
if( !empty( $this->lastmodified )) { |
5828
|
|
|
$this->lastmodified = ''; |
5829
|
|
|
$return = TRUE; |
5830
|
|
|
} |
5831
|
|
|
break; |
5832
|
|
View Code Duplication |
case 'LOCATION': |
5833
|
|
|
if( !empty( $this->location )) { |
5834
|
|
|
$this->location = ''; |
5835
|
|
|
$return = TRUE; |
5836
|
|
|
} |
5837
|
|
|
break; |
5838
|
|
View Code Duplication |
case 'ORGANIZER': |
5839
|
|
|
if( !empty( $this->organizer )) { |
5840
|
|
|
$this->organizer = ''; |
5841
|
|
|
$return = TRUE; |
5842
|
|
|
} |
5843
|
|
|
break; |
5844
|
|
|
case 'PERCENT-COMPLETE': |
5845
|
|
|
if( !empty( $this->percentcomplete )) { |
5846
|
|
|
$this->percentcomplete = ''; |
5847
|
|
|
$return = TRUE; |
5848
|
|
|
} |
5849
|
|
|
break; |
5850
|
|
View Code Duplication |
case 'PRIORITY': |
5851
|
|
|
if( !empty( $this->priority )) { |
5852
|
|
|
$this->priority = ''; |
5853
|
|
|
$return = TRUE; |
5854
|
|
|
} |
5855
|
|
|
break; |
5856
|
|
|
case 'RDATE': |
5857
|
|
|
return $this->deletePropertyM( $this->rdate, $propix ); |
|
|
|
|
5858
|
|
|
break; |
5859
|
|
|
case 'RECURRENCE-ID': |
5860
|
|
|
if( !empty( $this->recurrenceid )) { |
5861
|
|
|
$this->recurrenceid = ''; |
5862
|
|
|
$return = TRUE; |
5863
|
|
|
} |
5864
|
|
|
break; |
5865
|
|
|
case 'RELATED-TO': |
5866
|
|
|
return $this->deletePropertyM( $this->relatedto, $propix ); |
|
|
|
|
5867
|
|
|
break; |
5868
|
|
View Code Duplication |
case 'REPEAT': |
5869
|
|
|
if( !empty( $this->repeat )) { |
5870
|
|
|
$this->repeat = ''; |
5871
|
|
|
$return = TRUE; |
5872
|
|
|
} |
5873
|
|
|
break; |
5874
|
|
|
case 'REQUEST-STATUS': |
5875
|
|
|
return $this->deletePropertyM( $this->requeststatus, $propix ); |
|
|
|
|
5876
|
|
|
break; |
5877
|
|
|
case 'RESOURCES': |
5878
|
|
|
return $this->deletePropertyM( $this->resources, $propix ); |
|
|
|
|
5879
|
|
|
break; |
5880
|
|
|
case 'RRULE': |
5881
|
|
|
return $this->deletePropertyM( $this->rrule, $propix ); |
|
|
|
|
5882
|
|
|
break; |
5883
|
|
View Code Duplication |
case 'SEQUENCE': |
5884
|
|
|
if( !empty( $this->sequence )) { |
5885
|
|
|
$this->sequence = ''; |
5886
|
|
|
$return = TRUE; |
5887
|
|
|
} |
5888
|
|
|
break; |
5889
|
|
View Code Duplication |
case 'STATUS': |
5890
|
|
|
if( !empty( $this->status )) { |
5891
|
|
|
$this->status = ''; |
5892
|
|
|
$return = TRUE; |
5893
|
|
|
} |
5894
|
|
|
break; |
5895
|
|
View Code Duplication |
case 'SUMMARY': |
5896
|
|
|
if( !empty( $this->summary )) { |
5897
|
|
|
$this->summary = ''; |
5898
|
|
|
$return = TRUE; |
5899
|
|
|
} |
5900
|
|
|
break; |
5901
|
|
View Code Duplication |
case 'TRANSP': |
5902
|
|
|
if( !empty( $this->transp )) { |
5903
|
|
|
$this->transp = ''; |
5904
|
|
|
$return = TRUE; |
5905
|
|
|
} |
5906
|
|
|
break; |
5907
|
|
View Code Duplication |
case 'TRIGGER': |
5908
|
|
|
if( !empty( $this->trigger )) { |
5909
|
|
|
$this->trigger = ''; |
5910
|
|
|
$return = TRUE; |
5911
|
|
|
} |
5912
|
|
|
break; |
5913
|
|
View Code Duplication |
case 'TZID': |
5914
|
|
|
if( !empty( $this->tzid )) { |
5915
|
|
|
$this->tzid = ''; |
5916
|
|
|
$return = TRUE; |
5917
|
|
|
} |
5918
|
|
|
break; |
5919
|
|
|
case 'TZNAME': |
5920
|
|
|
return $this->deletePropertyM( $this->tzname, $propix ); |
|
|
|
|
5921
|
|
|
break; |
5922
|
|
View Code Duplication |
case 'TZOFFSETFROM': |
5923
|
|
|
if( !empty( $this->tzoffsetfrom )) { |
5924
|
|
|
$this->tzoffsetfrom = ''; |
5925
|
|
|
$return = TRUE; |
5926
|
|
|
} |
5927
|
|
|
break; |
5928
|
|
View Code Duplication |
case 'TZOFFSETTO': |
5929
|
|
|
if( !empty( $this->tzoffsetto )) { |
5930
|
|
|
$this->tzoffsetto = ''; |
5931
|
|
|
$return = TRUE; |
5932
|
|
|
} |
5933
|
|
|
break; |
5934
|
|
View Code Duplication |
case 'TZURL': |
5935
|
|
|
if( !empty( $this->tzurl )) { |
5936
|
|
|
$this->tzurl = ''; |
5937
|
|
|
$return = TRUE; |
5938
|
|
|
} |
5939
|
|
|
break; |
5940
|
|
View Code Duplication |
case 'UID': |
5941
|
|
|
if( in_array( $this->objName, array( 'valarm', 'vtimezone', 'standard', 'daylight' ))) |
5942
|
|
|
return FALSE; |
5943
|
|
|
if( !empty( $this->uid )) { |
5944
|
|
|
$this->uid = ''; |
5945
|
|
|
$return = TRUE; |
5946
|
|
|
} |
5947
|
|
|
break; |
5948
|
|
View Code Duplication |
case 'URL': |
5949
|
|
|
if( !empty( $this->url )) { |
5950
|
|
|
$this->url = ''; |
5951
|
|
|
$return = TRUE; |
5952
|
|
|
} |
5953
|
|
|
break; |
5954
|
|
View Code Duplication |
default: |
5955
|
|
|
$reduced = ''; |
5956
|
|
|
if( $propName != 'X-PROP' ) { |
5957
|
|
|
if( !isset( $this->xprop[$propName] )) return FALSE; |
5958
|
|
|
foreach( $this->xprop as $k => $a ) { |
5959
|
|
|
if(( $k != $propName ) && !empty( $a )) |
5960
|
|
|
$reduced[$k] = $a; |
5961
|
|
|
} |
5962
|
|
|
} |
5963
|
|
|
else { |
5964
|
|
|
if( count( $this->xprop ) <= $propix ) return FALSE; |
5965
|
|
|
$xpropno = 0; |
5966
|
|
|
foreach( $this->xprop as $xpropkey => $xpropvalue ) { |
5967
|
|
|
if( $propix != $xpropno ) |
5968
|
|
|
$reduced[$xpropkey] = $xpropvalue; |
5969
|
|
|
$xpropno++; |
5970
|
|
|
} |
5971
|
|
|
} |
5972
|
|
|
$this->xprop = $reduced; |
5973
|
|
|
return TRUE; |
5974
|
|
|
} |
5975
|
|
|
return $return; |
5976
|
|
|
} |
5977
|
|
|
/*********************************************************************************/ |
5978
|
|
|
/** |
5979
|
|
|
* delete component property value, fixing components with multiple occurencies |
5980
|
|
|
* |
5981
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
5982
|
|
|
* @since 2.4.5 - 2008-11-07 |
5983
|
|
|
* @param array $multiprop, reference to a component property |
|
|
|
|
5984
|
|
|
* @param int @propix, default 0 |
5985
|
|
|
* @return bool TRUE |
5986
|
|
|
*/ |
5987
|
|
|
function deletePropertyM( & $multiprop, $propix=0 ) { |
5988
|
|
|
if( !isset( $multiprop[$propix])) return FALSE; |
5989
|
|
|
unset( $multiprop[$propix] ); |
5990
|
|
|
if( empty( $multiprop )) $multiprop = ''; |
5991
|
|
|
return ( isset( $this->multiprop[$propix] )) ? FALSE : TRUE; |
5992
|
|
|
} |
5993
|
|
|
/** |
5994
|
|
|
* get component property value/params |
5995
|
|
|
* |
5996
|
|
|
* if property has multiply values, consequtive function calls are needed |
5997
|
|
|
* |
5998
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
5999
|
|
|
* @since 2.5.1 - 2008-11-02 |
6000
|
|
|
* @param string $propName, optional |
|
|
|
|
6001
|
|
|
* @param int @propix, optional, if specific property is wanted in case of multiply occurences |
6002
|
|
|
* @param bool $inclParam=FALSE |
|
|
|
|
6003
|
|
|
* @param bool $specform=FALSE |
|
|
|
|
6004
|
|
|
* @return mixed |
6005
|
|
|
*/ |
6006
|
|
|
function getProperty( $propName=FALSE, $propix=FALSE, $inclParam=FALSE, $specform=FALSE ) { |
6007
|
|
|
if( $this->_notExistProp( $propName )) return FALSE; |
6008
|
|
|
$propName = ( $propName ) ? strtoupper( $propName ) : 'X-PROP'; |
6009
|
|
View Code Duplication |
if( in_array( $propName, array( 'ATTACH', 'ATTENDEE', 'CATEGORIES', 'COMMENT', 'CONTACT', 'DESCRIPTION', 'EXDATE', 'EXRULE', |
6010
|
|
|
'FREEBUSY', 'RDATE', 'RELATED-TO', 'RESOURCES', 'RRULE', 'REQUEST-STATUS', 'TZNAME', 'X-PROP' ))) { |
6011
|
|
|
if( !$propix ) |
6012
|
|
|
$propix = ( isset( $this->propix[$propName] )) ? $this->propix[$propName] + 2 : 1; |
6013
|
|
|
$this->propix[$propName] = --$propix; |
6014
|
|
|
} |
6015
|
|
|
switch( $propName ) { |
6016
|
|
View Code Duplication |
case 'ACTION': |
6017
|
|
|
if( !empty( $this->action['value'] )) return ( $inclParam ) ? $this->action : $this->action['value']; |
6018
|
|
|
break; |
6019
|
|
View Code Duplication |
case 'ATTACH': |
6020
|
|
|
if( !isset( $this->attach[$propix] )) return FALSE; |
6021
|
|
|
return ( $inclParam ) ? $this->attach[$propix] : $this->attach[$propix]['value']; |
6022
|
|
|
break; |
6023
|
|
View Code Duplication |
case 'ATTENDEE': |
6024
|
|
|
if( !isset( $this->attendee[$propix] )) return FALSE; |
6025
|
|
|
return ( $inclParam ) ? $this->attendee[$propix] : $this->attendee[$propix]['value']; |
6026
|
|
|
break; |
6027
|
|
View Code Duplication |
case 'CATEGORIES': |
6028
|
|
|
if( !isset( $this->categories[$propix] )) return FALSE; |
6029
|
|
|
return ( $inclParam ) ? $this->categories[$propix] : $this->categories[$propix]['value']; |
6030
|
|
|
break; |
6031
|
|
View Code Duplication |
case 'CLASS': |
6032
|
|
|
if( !empty( $this->class['value'] )) return ( $inclParam ) ? $this->class : $this->class['value']; |
6033
|
|
|
break; |
6034
|
|
View Code Duplication |
case 'COMMENT': |
6035
|
|
|
if( !isset( $this->comment[$propix] )) return FALSE; |
6036
|
|
|
return ( $inclParam ) ? $this->comment[$propix] : $this->comment[$propix]['value']; |
6037
|
|
|
break; |
6038
|
|
View Code Duplication |
case 'COMPLETED': |
6039
|
|
|
if( !empty( $this->completed['value'] )) return ( $inclParam ) ? $this->completed : $this->completed['value']; |
6040
|
|
|
break; |
6041
|
|
View Code Duplication |
case 'CONTACT': |
6042
|
|
|
if( !isset( $this->contact[$propix] )) return FALSE; |
6043
|
|
|
return ( $inclParam ) ? $this->contact[$propix] : $this->contact[$propix]['value']; |
6044
|
|
|
break; |
6045
|
|
View Code Duplication |
case 'CREATED': |
6046
|
|
|
if( !empty( $this->created['value'] )) return ( $inclParam ) ? $this->created : $this->created['value']; |
6047
|
|
|
break; |
6048
|
|
View Code Duplication |
case 'DESCRIPTION': |
6049
|
|
|
if( !isset( $this->description[$propix] )) return FALSE; |
6050
|
|
|
return ( $inclParam ) ? $this->description[$propix] : $this->description[$propix]['value']; |
6051
|
|
|
break; |
6052
|
|
View Code Duplication |
case 'DTEND': |
6053
|
|
|
if( !empty( $this->dtend['value'] )) return ( $inclParam ) ? $this->dtend : $this->dtend['value']; |
6054
|
|
|
break; |
6055
|
|
|
case 'DTSTAMP': |
6056
|
|
|
if( in_array( $this->objName, array( 'valarm', 'vtimezone', 'standard', 'daylight' ))) |
6057
|
|
|
return; |
6058
|
|
|
if( !isset( $this->dtstamp['value'] )) |
6059
|
|
|
$this->_makeDtstamp(); |
6060
|
|
|
return ( $inclParam ) ? $this->dtstamp : $this->dtstamp['value']; |
6061
|
|
|
break; |
6062
|
|
View Code Duplication |
case 'DTSTART': |
6063
|
|
|
if( !empty( $this->dtstart['value'] )) return ( $inclParam ) ? $this->dtstart : $this->dtstart['value']; |
6064
|
|
|
break; |
6065
|
|
View Code Duplication |
case 'DUE': |
6066
|
|
|
if( !empty( $this->due['value'] )) return ( $inclParam ) ? $this->due : $this->due['value']; |
6067
|
|
|
break; |
6068
|
|
|
case 'DURATION': |
6069
|
|
|
if( !isset( $this->duration['value'] )) return FALSE; |
6070
|
|
|
$value = ( $specform ) ? $this->duration2date() : $this->duration['value']; |
6071
|
|
|
return ( $inclParam ) ? array( 'value' => $value, 'params' => $this->duration['params'] ) : $value; |
6072
|
|
|
break; |
6073
|
|
View Code Duplication |
case 'EXDATE': |
6074
|
|
|
if( !isset( $this->exdate[$propix] )) return FALSE; |
6075
|
|
|
return ( $inclParam ) ? $this->exdate[$propix] : $this->exdate[$propix]['value']; |
6076
|
|
|
break; |
6077
|
|
View Code Duplication |
case 'EXRULE': |
6078
|
|
|
if( !isset( $this->exrule[$propix] )) return FALSE; |
6079
|
|
|
return ( $inclParam ) ? $this->exrule[$propix] : $this->exrule[$propix]['value']; |
6080
|
|
|
break; |
6081
|
|
View Code Duplication |
case 'FREEBUSY': |
6082
|
|
|
if( !isset( $this->freebusy[$propix] )) return FALSE; |
6083
|
|
|
return ( $inclParam ) ? $this->freebusy[$propix] : $this->freebusy[$propix]['value']; |
6084
|
|
|
break; |
6085
|
|
View Code Duplication |
case 'GEO': |
6086
|
|
|
if( !empty( $this->geo['value'] )) return ( $inclParam ) ? $this->geo : $this->geo['value']; |
6087
|
|
|
break; |
6088
|
|
|
case 'LAST-MODIFIED': |
6089
|
|
|
if( !empty( $this->lastmodified['value'] )) return ( $inclParam ) ? $this->lastmodified : $this->lastmodified['value']; |
6090
|
|
|
break; |
6091
|
|
View Code Duplication |
case 'LOCATION': |
6092
|
|
|
if( !empty( $this->location['value'] )) return ( $inclParam ) ? $this->location : $this->location['value']; |
6093
|
|
|
break; |
6094
|
|
View Code Duplication |
case 'ORGANIZER': |
6095
|
|
|
if( !empty( $this->organizer['value'] )) return ( $inclParam ) ? $this->organizer : $this->organizer['value']; |
6096
|
|
|
break; |
6097
|
|
|
case 'PERCENT-COMPLETE': |
6098
|
|
|
if( !empty( $this->percentcomplete['value'] )) return ( $inclParam ) ? $this->percentcomplete : $this->percentcomplete['value']; |
6099
|
|
|
break; |
6100
|
|
View Code Duplication |
case 'PRIORITY': |
6101
|
|
|
if( !empty( $this->priority['value'] )) return ( $inclParam ) ? $this->priority : $this->priority['value']; |
6102
|
|
|
break; |
6103
|
|
View Code Duplication |
case 'RDATE': |
6104
|
|
|
if( !isset( $this->rdate[$propix] )) return FALSE; |
6105
|
|
|
return ( $inclParam ) ? $this->rdate[$propix] : $this->rdate[$propix]['value']; |
6106
|
|
|
break; |
6107
|
|
|
case 'RECURRENCE-ID': |
6108
|
|
|
if( !empty( $this->recurrenceid['value'] )) return ( $inclParam ) ? $this->recurrenceid : $this->recurrenceid['value']; |
6109
|
|
|
break; |
6110
|
|
View Code Duplication |
case 'RELATED-TO': |
6111
|
|
|
if( !isset( $this->relatedto[$propix] )) return FALSE; |
6112
|
|
|
return ( $inclParam ) ? $this->relatedto[$propix] : $this->relatedto[$propix]['value']; |
6113
|
|
|
break; |
6114
|
|
View Code Duplication |
case 'REPEAT': |
6115
|
|
|
if( !empty( $this->repeat['value'] )) return ( $inclParam ) ? $this->repeat : $this->repeat['value']; |
6116
|
|
|
break; |
6117
|
|
View Code Duplication |
case 'REQUEST-STATUS': |
6118
|
|
|
if( !isset( $this->requeststatus[$propix] )) return FALSE; |
6119
|
|
|
return ( $inclParam ) ? $this->requeststatus[$propix] : $this->requeststatus[$propix]['value']; |
6120
|
|
|
break; |
6121
|
|
View Code Duplication |
case 'RESOURCES': |
6122
|
|
|
if( !isset( $this->resources[$propix] )) return FALSE; |
6123
|
|
|
return ( $inclParam ) ? $this->resources[$propix] : $this->resources[$propix]['value']; |
6124
|
|
|
break; |
6125
|
|
View Code Duplication |
case 'RRULE': |
6126
|
|
|
if( !isset( $this->rrule[$propix] )) return FALSE; |
6127
|
|
|
return ( $inclParam ) ? $this->rrule[$propix] : $this->rrule[$propix]['value']; |
6128
|
|
|
break; |
6129
|
|
View Code Duplication |
case 'SEQUENCE': |
6130
|
|
|
if( !empty( $this->sequence['value'] )) return ( $inclParam ) ? $this->sequence : $this->sequence['value']; |
6131
|
|
|
break; |
6132
|
|
View Code Duplication |
case 'STATUS': |
6133
|
|
|
if( !empty( $this->status['value'] )) return ( $inclParam ) ? $this->status : $this->status['value']; |
6134
|
|
|
break; |
6135
|
|
View Code Duplication |
case 'SUMMARY': |
6136
|
|
|
if( !empty( $this->summary['value'] )) return ( $inclParam ) ? $this->summary : $this->summary['value']; |
6137
|
|
|
break; |
6138
|
|
View Code Duplication |
case 'TRANSP': |
6139
|
|
|
if( !empty( $this->transp['value'] )) return ( $inclParam ) ? $this->transp : $this->transp['value']; |
6140
|
|
|
break; |
6141
|
|
View Code Duplication |
case 'TRIGGER': |
6142
|
|
|
if( !empty( $this->trigger['value'] )) return ( $inclParam ) ? $this->trigger : $this->trigger['value']; |
6143
|
|
|
break; |
6144
|
|
View Code Duplication |
case 'TZID': |
6145
|
|
|
if( !empty( $this->tzid['value'] )) return ( $inclParam ) ? $this->tzid : $this->tzid['value']; |
6146
|
|
|
break; |
6147
|
|
View Code Duplication |
case 'TZNAME': |
6148
|
|
|
if( !isset( $this->tzname[$propix] )) return FALSE; |
6149
|
|
|
return ( $inclParam ) ? $this->tzname[$propix] : $this->tzname[$propix]['value']; |
6150
|
|
|
break; |
6151
|
|
View Code Duplication |
case 'TZOFFSETFROM': |
6152
|
|
|
if( !empty( $this->tzoffsetfrom['value'] )) return ( $inclParam ) ? $this->tzoffsetfrom : $this->tzoffsetfrom['value']; |
6153
|
|
|
break; |
6154
|
|
View Code Duplication |
case 'TZOFFSETTO': |
6155
|
|
|
if( !empty( $this->tzoffsetto['value'] )) return ( $inclParam ) ? $this->tzoffsetto : $this->tzoffsetto['value']; |
6156
|
|
|
break; |
6157
|
|
View Code Duplication |
case 'TZURL': |
6158
|
|
|
if( !empty( $this->tzurl['value'] )) return ( $inclParam ) ? $this->tzurl : $this->tzurl['value']; |
6159
|
|
|
break; |
6160
|
|
|
case 'UID': |
6161
|
|
|
if( in_array( $this->objName, array( 'valarm', 'vtimezone', 'standard', 'daylight' ))) |
6162
|
|
|
return FALSE; |
6163
|
|
|
if( empty( $this->uid['value'] )) |
6164
|
|
|
$this->_makeuid(); |
6165
|
|
|
return ( $inclParam ) ? $this->uid : $this->uid['value']; |
6166
|
|
|
break; |
6167
|
|
View Code Duplication |
case 'URL': |
6168
|
|
|
if( !empty( $this->url['value'] )) return ( $inclParam ) ? $this->url : $this->url['value']; |
6169
|
|
|
break; |
6170
|
|
View Code Duplication |
default: |
6171
|
|
|
if( $propName != 'X-PROP' ) { |
6172
|
|
|
if( !isset( $this->xprop[$propName] )) return FALSE; |
6173
|
|
|
return ( $inclParam ) ? array( $propName, $this->xprop[$propName] ) |
6174
|
|
|
: array( $propName, $this->xprop[$propName]['value'] ); |
6175
|
|
|
} |
6176
|
|
|
else { |
6177
|
|
|
if( empty( $this->xprop )) return FALSE; |
6178
|
|
|
$xpropno = 0; |
6179
|
|
|
foreach( $this->xprop as $xpropkey => $xpropvalue ) { |
6180
|
|
|
if( $propix == $xpropno ) |
6181
|
|
|
return ( $inclParam ) ? array( $xpropkey, $this->xprop[$xpropkey] ) |
6182
|
|
|
: array( $xpropkey, $this->xprop[$xpropkey]['value'] ); |
6183
|
|
|
else |
6184
|
|
|
$xpropno++; |
6185
|
|
|
} |
6186
|
|
|
return FALSE; // not found ?? |
6187
|
|
|
} |
6188
|
|
|
} |
6189
|
|
|
return FALSE; |
6190
|
|
|
} |
6191
|
|
|
/** |
6192
|
|
|
* general component property setting |
6193
|
|
|
* |
6194
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
6195
|
|
|
* @since 2.5.1 - 2008-11-05 |
6196
|
|
|
* @param mixed $args variable number of function arguments, |
|
|
|
|
6197
|
|
|
* first argument is ALWAYS component name, |
6198
|
|
|
* second ALWAYS component value! |
6199
|
|
|
* @return void |
6200
|
|
|
*/ |
6201
|
|
|
function setProperty() { |
6202
|
|
|
$numargs = func_num_args(); |
6203
|
|
|
if( 1 > $numargs ) return FALSE; |
6204
|
|
|
$arglist = func_get_args(); |
6205
|
|
|
if( $this->_notExistProp( $arglist[0] )) return FALSE; |
6206
|
|
|
if( !$this->getConfig( 'allowEmpty' ) && ( !isset( $arglist[1] ) || empty( $arglist[1] ))) |
6207
|
|
|
return FALSE; |
6208
|
|
|
$arglist[0] = strtoupper( $arglist[0] ); |
6209
|
|
|
for( $argix=$numargs; $argix < 12; $argix++ ) { |
6210
|
|
|
if( !isset( $arglist[$argix] )) |
6211
|
|
|
$arglist[$argix] = null; |
6212
|
|
|
} |
6213
|
|
|
switch( $arglist[0] ) { |
6214
|
|
|
case 'ACTION': |
6215
|
|
|
return $this->setAction( $arglist[1], $arglist[2] ); |
6216
|
|
|
case 'ATTACH': |
6217
|
|
|
return $this->setAttach( $arglist[1], $arglist[2], $arglist[3] ); |
6218
|
|
|
case 'ATTENDEE': |
6219
|
|
|
return $this->setAttendee( $arglist[1], $arglist[2], $arglist[3] ); |
6220
|
|
|
case 'CATEGORIES': |
6221
|
|
|
return $this->setCategories( $arglist[1], $arglist[2], $arglist[3] ); |
6222
|
|
|
case 'CLASS': |
6223
|
|
|
return $this->setClass( $arglist[1], $arglist[2] ); |
6224
|
|
|
case 'COMMENT': |
6225
|
|
|
return $this->setComment( $arglist[1], $arglist[2], $arglist[3] ); |
6226
|
|
|
case 'COMPLETED': |
6227
|
|
|
return $this->setCompleted( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7] ); |
6228
|
|
|
case 'CONTACT': |
6229
|
|
|
return $this->setContact( $arglist[1], $arglist[2], $arglist[3] ); |
6230
|
|
|
case 'CREATED': |
6231
|
|
|
return $this->setCreated( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7] ); |
6232
|
|
|
case 'DESCRIPTION': |
6233
|
|
|
return $this->setDescription( $arglist[1], $arglist[2], $arglist[3] ); |
6234
|
|
|
case 'DTEND': |
6235
|
|
|
return $this->setDtend( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7], $arglist[8] ); |
6236
|
|
|
case 'DTSTAMP': |
6237
|
|
|
return $this->setDtstamp( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7] ); |
6238
|
|
|
case 'DTSTART': |
6239
|
|
|
return $this->setDtstart( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7], $arglist[8] ); |
6240
|
|
|
case 'DUE': |
6241
|
|
|
return $this->setDue( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7], $arglist[8] ); |
6242
|
|
|
case 'DURATION': |
6243
|
|
|
return $this->setDuration( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6] ); |
6244
|
|
|
case 'EXDATE': |
6245
|
|
|
return $this->setExdate( $arglist[1], $arglist[2], $arglist[3] ); |
6246
|
|
|
case 'EXRULE': |
6247
|
|
|
return $this->setExrule( $arglist[1], $arglist[2], $arglist[3] ); |
6248
|
|
|
case 'FREEBUSY': |
6249
|
|
|
return $this->setFreebusy( $arglist[1], $arglist[2], $arglist[3], $arglist[4] ); |
6250
|
|
|
case 'GEO': |
6251
|
|
|
return $this->setGeo( $arglist[1], $arglist[2], $arglist[3] ); |
6252
|
|
|
case 'LAST-MODIFIED': |
6253
|
|
|
return $this->setLastModified( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7] ); |
6254
|
|
|
case 'LOCATION': |
6255
|
|
|
return $this->setLocation( $arglist[1], $arglist[2] ); |
6256
|
|
|
case 'ORGANIZER': |
6257
|
|
|
return $this->setOrganizer( $arglist[1], $arglist[2] ); |
6258
|
|
|
case 'PERCENT-COMPLETE': |
6259
|
|
|
return $this->setPercentComplete( $arglist[1], $arglist[2] ); |
6260
|
|
|
case 'PRIORITY': |
6261
|
|
|
return $this->setPriority( $arglist[1], $arglist[2] ); |
6262
|
|
|
case 'RDATE': |
6263
|
|
|
return $this->setRdate( $arglist[1], $arglist[2], $arglist[3] ); |
6264
|
|
|
case 'RECURRENCE-ID': |
6265
|
|
|
return $this->setRecurrenceid( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7], $arglist[8] ); |
6266
|
|
|
case 'RELATED-TO': |
6267
|
|
|
return $this->setRelatedTo( $arglist[1], $arglist[2], $arglist[3] ); |
6268
|
|
|
case 'REPEAT': |
6269
|
|
|
return $this->setRepeat( $arglist[1], $arglist[2] ); |
6270
|
|
|
case 'REQUEST-STATUS': |
6271
|
|
|
return $this->setRequestStatus( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5] ); |
6272
|
|
|
case 'RESOURCES': |
6273
|
|
|
return $this->setResources( $arglist[1], $arglist[2], $arglist[3] ); |
6274
|
|
|
case 'RRULE': |
6275
|
|
|
return $this->setRrule( $arglist[1], $arglist[2], $arglist[3] ); |
6276
|
|
|
case 'SEQUENCE': |
6277
|
|
|
return $this->setSequence( $arglist[1], $arglist[2] ); |
6278
|
|
|
case 'STATUS': |
6279
|
|
|
return $this->setStatus( $arglist[1], $arglist[2] ); |
6280
|
|
|
case 'SUMMARY': |
6281
|
|
|
return $this->setSummary( $arglist[1], $arglist[2] ); |
6282
|
|
|
case 'TRANSP': |
6283
|
|
|
return $this->setTransp( $arglist[1], $arglist[2] ); |
6284
|
|
|
case 'TRIGGER': |
6285
|
|
|
return $this->setTrigger( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7], $arglist[8], $arglist[9], $arglist[10], $arglist[11] ); |
6286
|
|
|
case 'TZID': |
6287
|
|
|
return $this->setTzid( $arglist[1], $arglist[2] ); |
6288
|
|
|
case 'TZNAME': |
6289
|
|
|
return $this->setTzname( $arglist[1], $arglist[2], $arglist[3] ); |
6290
|
|
|
case 'TZOFFSETFROM': |
6291
|
|
|
return $this->setTzoffsetfrom( $arglist[1], $arglist[2] ); |
6292
|
|
|
case 'TZOFFSETTO': |
6293
|
|
|
return $this->setTzoffsetto( $arglist[1], $arglist[2] ); |
6294
|
|
|
case 'TZURL': |
6295
|
|
|
return $this->setTzurl( $arglist[1], $arglist[2] ); |
6296
|
|
|
case 'UID': |
6297
|
|
|
return $this->setUid( $arglist[1], $arglist[2] ); |
6298
|
|
|
case 'URL': |
6299
|
|
|
return $this->setUrl( $arglist[1], $arglist[2] ); |
6300
|
|
|
default: |
6301
|
|
|
return $this->setXprop( $arglist[0], $arglist[1], $arglist[2] ); |
6302
|
|
|
} |
6303
|
|
|
return FALSE; |
|
|
|
|
6304
|
|
|
} |
6305
|
|
|
/*********************************************************************************/ |
6306
|
|
|
/** |
6307
|
|
|
* parse component unparsed data into properties |
6308
|
|
|
* |
6309
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
6310
|
|
|
* @since 2.5.2 - 2008-10-23 |
6311
|
|
|
* @param mixed $unparsedtext, optional, strict rfc2445 formatted, single property string or array of property strings |
|
|
|
|
6312
|
|
|
* @return bool FALSE if error occurs during parsing |
6313
|
|
|
* |
6314
|
|
|
*/ |
6315
|
|
|
function parse( $unparsedtext=null ) { |
6316
|
|
|
if( $unparsedtext ) { |
6317
|
|
|
$this->unparsed = array(); |
6318
|
|
|
if( is_array( $unparsedtext )) { |
6319
|
|
|
$comp = & $this; |
6320
|
|
|
foreach ( $unparsedtext as $line ) { |
6321
|
|
|
if( 'END:VALARM' == strtoupper( substr( $line, 0, 10 ))) { |
6322
|
|
|
$this->setComponent( $comp ); |
6323
|
|
|
$comp = & $this; |
6324
|
|
|
continue; |
6325
|
|
|
} |
6326
|
|
|
elseif( 'BEGIN:VALARM' == strtoupper( substr( $line, 0, 12 ))) { |
6327
|
|
|
$comp = new valarm(); |
6328
|
|
|
continue; |
6329
|
|
|
} |
6330
|
|
|
else |
6331
|
|
|
$comp->unparsed[] = $line; |
6332
|
|
|
} |
6333
|
|
|
} |
6334
|
|
|
else |
6335
|
|
|
$this->unparsed = array( trim( $unparsedtext )); |
6336
|
|
|
} |
6337
|
|
|
elseif( !isset( $this->unparsed )) |
6338
|
|
|
$this->unparsed = array(); |
6339
|
|
|
/* concatenate property values spread over several lines */ |
6340
|
|
|
$lastix = -1; |
6341
|
|
|
$propnames = array( 'action', 'attach', 'attendee', 'categories', 'comment', 'completed' |
6342
|
|
|
, 'contact', 'class', 'created', 'description', 'dtend', 'dtstart' |
6343
|
|
|
, 'dtstamp', 'due', 'duration', 'exdate', 'exrule', 'freebusy', 'geo' |
6344
|
|
|
, 'last-modified', 'location', 'organizer', 'percent-complete' |
6345
|
|
|
, 'priority', 'rdate', 'recurrence-id', 'related-to', 'repeat' |
6346
|
|
|
, 'request-status', 'resources', 'rrule', 'sequence', 'status' |
6347
|
|
|
, 'summary', 'transp', 'trigger', 'tzid', 'tzname', 'tzoffsetfrom' |
6348
|
|
|
, 'tzoffsetto', 'tzurl', 'uid', 'url', 'x-' ); |
6349
|
|
|
$proprows = array(); |
6350
|
|
View Code Duplication |
foreach( $this->unparsed as $line ) { |
6351
|
|
|
$newProp = FALSE; |
6352
|
|
|
foreach ( $propnames as $propname ) { |
6353
|
|
|
if( $propname == strtolower( substr( $line, 0, strlen( $propname )))) { |
6354
|
|
|
$newProp = TRUE; |
6355
|
|
|
break; |
6356
|
|
|
} |
6357
|
|
|
} |
6358
|
|
|
if( $newProp ) { |
6359
|
|
|
$newProp = FALSE; |
6360
|
|
|
$lastix++; |
6361
|
|
|
$proprows[$lastix] = $line; |
6362
|
|
|
} |
6363
|
|
|
else { |
6364
|
|
|
/* remove line breaks */ |
6365
|
|
|
if(( '\n' == substr( $proprows[$lastix], -2 )) && |
6366
|
|
|
( ' ' == substr( $line, 0, 1 ))) { |
6367
|
|
|
$proprows[$lastix] = substr( $proprows[$lastix], 0, strlen( $proprows[$lastix] ) - 2 ); |
6368
|
|
|
$line = substr( $line, 1 ); |
6369
|
|
|
} |
6370
|
|
|
$proprows[$lastix] .= $line; |
6371
|
|
|
} |
6372
|
|
|
} |
6373
|
|
|
/* parse each property 'line' */ |
6374
|
|
|
foreach( $proprows as $line ) { |
6375
|
|
|
$line = str_replace( "\n ", '', $line ); |
6376
|
|
View Code Duplication |
if( '\n' == substr( $line, -2 )) |
6377
|
|
|
$line = substr( $line, 0, strlen( $line ) - 2 ); |
6378
|
|
|
/* get propname, (problem with x-properties, otherwise in previous loop) */ |
6379
|
|
|
$cix = $propname = null; |
6380
|
|
View Code Duplication |
for( $cix=0; $cix < strlen( $line ); $cix++ ) { |
6381
|
|
|
if( in_array( $line{$cix}, array( ':', ';' ))) |
6382
|
|
|
break; |
6383
|
|
|
else { |
6384
|
|
|
$propname .= $line{$cix}; |
6385
|
|
|
} |
6386
|
|
|
} |
6387
|
|
|
if(( 'x-' == substr( $propname, 0, 2 )) || ( 'X-' == substr( $propname, 0, 2 ))) { |
6388
|
|
|
$propname2 = $propname; |
6389
|
|
|
$propname = 'X-'; |
6390
|
|
|
} |
6391
|
|
|
/* rest of the line is opt.params and value */ |
6392
|
|
|
$line = substr( $line, $cix ); |
6393
|
|
|
/* separate attributes from value */ |
6394
|
|
|
$attr = array(); |
6395
|
|
|
$attrix = -1; |
6396
|
|
|
$strlen = strlen( $line ); |
6397
|
|
View Code Duplication |
for( $cix=0; $cix < $strlen; $cix++ ) { |
6398
|
|
|
if(( ':' == $line{$cix} ) && |
6399
|
|
|
( '://' != substr( $line, $cix, 3 )) && |
6400
|
|
|
( 'mailto:' != strtolower( substr( $line, $cix - 6, 7 )))) { |
6401
|
|
|
$attrEnd = TRUE; |
6402
|
|
|
if(( $cix < ( $strlen - 4 )) && |
6403
|
|
|
ctype_digit( substr( $line, $cix+1, 4 ))) { // an URI with a (4pos) portnr?? |
6404
|
|
|
for( $c2ix = $cix; 3 < $c2ix; $c2ix-- ) { |
6405
|
|
|
if( '://' == substr( $line, $c2ix - 2, 3 )) { |
6406
|
|
|
$attrEnd = FALSE; |
6407
|
|
|
break; // an URI with a portnr!! |
6408
|
|
|
} |
6409
|
|
|
} |
6410
|
|
|
} |
6411
|
|
|
if( $attrEnd) { |
6412
|
|
|
$line = substr( $line, $cix + 1 ); |
6413
|
|
|
break; |
6414
|
|
|
} |
6415
|
|
|
} |
6416
|
|
|
if( ';' == $line{$cix} ) |
6417
|
|
|
$attr[++$attrix] = null; |
6418
|
|
|
else |
6419
|
|
|
$attr[$attrix] .= $line{$cix}; |
6420
|
|
|
} |
6421
|
|
|
/* make attributes in array format */ |
6422
|
|
|
$propattr = array(); |
6423
|
|
View Code Duplication |
foreach( $attr as $attribute ) { |
6424
|
|
|
$attrsplit = explode( '=', $attribute, 2 ); |
6425
|
|
|
if( 1 < count( $attrsplit )) |
6426
|
|
|
$propattr[$attrsplit[0]] = $attrsplit[1]; |
6427
|
|
|
else |
6428
|
|
|
$propattr[] = $attribute; |
6429
|
|
|
} |
6430
|
|
|
/* call setProperty( $propname.. . */ |
6431
|
|
|
switch( $propname ) { |
6432
|
|
|
case 'ATTENDEE': |
6433
|
|
|
foreach( $propattr as $pix => $attr ) { |
6434
|
|
|
$attr2 = explode( ',', $attr ); |
6435
|
|
|
if( 1 < count( $attr2 )) |
6436
|
|
|
$propattr[$pix] = $attr2; |
6437
|
|
|
} |
6438
|
|
|
$this->setProperty( $propname, $line, $propattr ); |
6439
|
|
|
break; |
6440
|
|
|
case 'CATEGORIES': |
6441
|
|
|
case 'RESOURCES': |
6442
|
|
|
if( FALSE !== strpos( $line, ',' )) { |
6443
|
|
|
$content = explode( ',', $line ); |
6444
|
|
|
$clen = count( $content ); |
6445
|
|
View Code Duplication |
for( $cix = 0; $cix < $clen; $cix++ ) { |
6446
|
|
|
if( "\\" == substr($content[$cix], -1)) { |
6447
|
|
|
$content[$cix] .= ','.$content[$cix + 1]; |
6448
|
|
|
unset($content[$cix + 1]); |
6449
|
|
|
$cix++; |
6450
|
|
|
} |
6451
|
|
|
} |
6452
|
|
View Code Duplication |
if( 1 < count( $content )) { |
6453
|
|
|
$content = array_values( $content ); |
6454
|
|
|
foreach( $content as $cix => $contentPart ) |
6455
|
|
|
$content[$cix] = $this->_strunrep( $contentPart ); |
6456
|
|
|
$this->setProperty( $propname, $content, $propattr ); |
6457
|
|
|
break; |
6458
|
|
|
} |
6459
|
|
|
else |
6460
|
|
|
$line = reset( $content ); |
6461
|
|
|
} |
6462
|
|
|
//no break |
6463
|
|
|
case 'X-': |
6464
|
|
|
$propname = ( isset( $propname2 )) ? $propname2 : $propname; |
6465
|
|
|
//no break |
6466
|
|
|
case 'COMMENT': |
6467
|
|
|
case 'CONTACT': |
6468
|
|
|
case 'DESCRIPTION': |
6469
|
|
|
case 'LOCATION': |
6470
|
|
|
case 'SUMMARY': |
6471
|
|
|
if( empty( $line )) |
6472
|
|
|
$propattr = null; |
6473
|
|
|
$this->setProperty( $propname, $this->_strunrep( $line ), $propattr ); |
6474
|
|
|
unset( $propname2 ); |
6475
|
|
|
break; |
6476
|
|
|
case 'REQUEST-STATUS': |
6477
|
|
|
$values = explode( ';', $line, 3 ); |
6478
|
|
|
$values[1] = ( !isset( $values[1] )) ? null : $this->_strunrep( $values[1] ); |
6479
|
|
|
$values[2] = ( !isset( $values[2] )) ? null : $this->_strunrep( $values[2] ); |
6480
|
|
|
$this->setProperty( $propname |
6481
|
|
|
, $values[0] // statcode |
6482
|
|
|
, $values[1] // statdesc |
6483
|
|
|
, $values[2] // extdata |
6484
|
|
|
, $propattr ); |
6485
|
|
|
break; |
6486
|
|
|
case 'FREEBUSY': |
6487
|
|
|
$fbtype = ( isset( $propattr['FBTYPE'] )) ? $propattr['FBTYPE'] : ''; // force setting default, if missing |
6488
|
|
|
unset( $propattr['FBTYPE'] ); |
6489
|
|
|
$values = explode( ',', $line ); |
6490
|
|
View Code Duplication |
foreach( $values as $vix => $value ) { |
6491
|
|
|
$value2 = explode( '/', $value ); |
6492
|
|
|
if( 1 < count( $value2 )) |
6493
|
|
|
$values[$vix] = $value2; |
6494
|
|
|
} |
6495
|
|
|
$this->setProperty( $propname, $fbtype, $values, $propattr ); |
6496
|
|
|
break; |
6497
|
|
|
case 'GEO': |
6498
|
|
|
$value = explode( ';', $line, 2 ); |
6499
|
|
|
if( 2 > count( $value )) |
6500
|
|
|
$value[1] = null; |
6501
|
|
|
$this->setProperty( $propname, $value[0], $value[1], $propattr ); |
6502
|
|
|
break; |
6503
|
|
|
case 'EXDATE': |
6504
|
|
|
$values = ( !empty( $line )) ? explode( ',', $line ) : null; |
6505
|
|
|
$this->setProperty( $propname, $values, $propattr ); |
6506
|
|
|
break; |
6507
|
|
|
case 'RDATE': |
6508
|
|
|
if( empty( $line )) { |
6509
|
|
|
$this->setProperty( $propname, $line, $propattr ); |
6510
|
|
|
break; |
6511
|
|
|
} |
6512
|
|
|
$values = explode( ',', $line ); |
6513
|
|
View Code Duplication |
foreach( $values as $vix => $value ) { |
6514
|
|
|
$value2 = explode( '/', $value ); |
6515
|
|
|
if( 1 < count( $value2 )) |
6516
|
|
|
$values[$vix] = $value2; |
6517
|
|
|
} |
6518
|
|
|
$this->setProperty( $propname, $values, $propattr ); |
6519
|
|
|
break; |
6520
|
|
|
case 'EXRULE': |
6521
|
|
|
case 'RRULE': |
6522
|
|
|
$values = explode( ';', $line ); |
6523
|
|
|
$recur = array(); |
6524
|
|
|
foreach( $values as $value2 ) { |
6525
|
|
|
if( empty( $value2 )) |
6526
|
|
|
continue; // ;-char in ending position ??? |
6527
|
|
|
$value3 = explode( '=', $value2, 2 ); |
6528
|
|
|
$rulelabel = strtoupper( $value3[0] ); |
6529
|
|
|
switch( $rulelabel ) { |
6530
|
|
|
case 'BYDAY': |
6531
|
|
|
$value4 = explode( ',', $value3[1] ); |
6532
|
|
|
if( 1 < count( $value4 )) { |
6533
|
|
|
foreach( $value4 as $v5ix => $value5 ) { |
6534
|
|
|
$value6 = array(); |
6535
|
|
|
$dayno = $dayname = null; |
6536
|
|
|
$value5 = trim( (string) $value5 ); |
6537
|
|
View Code Duplication |
if(( ctype_alpha( substr( $value5, -1 ))) && |
6538
|
|
|
( ctype_alpha( substr( $value5, -2, 1 )))) { |
6539
|
|
|
$dayname = substr( $value5, -2, 2 ); |
6540
|
|
|
if( 2 < strlen( $value5 )) |
6541
|
|
|
$dayno = substr( $value5, 0, ( strlen( $value5 ) - 2 )); |
6542
|
|
|
} |
6543
|
|
|
if( $dayno ) |
6544
|
|
|
$value6[] = $dayno; |
6545
|
|
|
if( $dayname ) |
6546
|
|
|
$value6['DAY'] = $dayname; |
6547
|
|
|
$value4[$v5ix] = $value6; |
6548
|
|
|
} |
6549
|
|
|
} |
6550
|
|
|
else { |
6551
|
|
|
$value4 = array(); |
6552
|
|
|
$dayno = $dayname = null; |
6553
|
|
|
$value5 = trim( (string) $value3[1] ); |
6554
|
|
View Code Duplication |
if(( ctype_alpha( substr( $value5, -1 ))) && |
6555
|
|
|
( ctype_alpha( substr( $value5, -2, 1 )))) { |
6556
|
|
|
$dayname = substr( $value5, -2, 2 ); |
6557
|
|
|
if( 2 < strlen( $value5 )) |
6558
|
|
|
$dayno = substr( $value5, 0, ( strlen( $value5 ) - 2 )); |
6559
|
|
|
} |
6560
|
|
|
if( $dayno ) |
6561
|
|
|
$value4[] = $dayno; |
6562
|
|
|
if( $dayname ) |
6563
|
|
|
$value4['DAY'] = $dayname; |
6564
|
|
|
} |
6565
|
|
|
$recur[$rulelabel] = $value4; |
6566
|
|
|
break; |
6567
|
|
|
default: |
6568
|
|
|
$value4 = explode( ',', $value3[1] ); |
6569
|
|
|
if( 1 < count( $value4 )) |
6570
|
|
|
$value3[1] = $value4; |
6571
|
|
|
$recur[$rulelabel] = $value3[1]; |
6572
|
|
|
break; |
6573
|
|
|
} // end - switch $rulelabel |
6574
|
|
|
} // end - foreach( $values.. . |
6575
|
|
|
$this->setProperty( $propname, $recur, $propattr ); |
6576
|
|
|
break; |
6577
|
|
|
default: |
6578
|
|
|
$this->setProperty( $propname, $line, $propattr ); |
6579
|
|
|
break; |
6580
|
|
|
} // end switch( $propname.. . |
6581
|
|
|
} // end - foreach( $proprows.. . |
6582
|
|
|
unset( $this->unparsed, $proprows ); |
6583
|
|
|
if( isset( $this->components ) && is_array( $this->components ) && ( 0 < count( $this->components ))) { |
6584
|
|
View Code Duplication |
for( $six = 0; $six < count( $this->components ); $six++ ) { |
6585
|
|
|
if( !empty( $this->components[$six]->unparsed )) |
6586
|
|
|
$this->components[$six]->parse(); |
6587
|
|
|
} |
6588
|
|
|
} |
6589
|
|
|
} |
6590
|
|
|
/*********************************************************************************/ |
6591
|
|
|
/*********************************************************************************/ |
6592
|
|
|
/** |
6593
|
|
|
* return a copy of this component |
6594
|
|
|
* |
6595
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
6596
|
|
|
* @since 2.2.16 - 2007-11-07 |
6597
|
|
|
* @return object |
6598
|
|
|
*/ |
6599
|
|
|
function copy() { |
6600
|
|
|
$serialized_contents = serialize($this); |
6601
|
|
|
$copy = unserialize($serialized_contents); |
6602
|
|
|
unset( $copy->propix ); |
6603
|
|
|
return $copy; |
6604
|
|
|
} |
6605
|
|
|
/*********************************************************************************/ |
6606
|
|
|
/*********************************************************************************/ |
6607
|
|
|
/** |
6608
|
|
|
* delete calendar subcomponent from component container |
6609
|
|
|
* |
6610
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
6611
|
|
|
* @since 2.5.1 - 2008-10-15 |
6612
|
|
|
* @param mixed $arg1 ordno / component type / component uid |
6613
|
|
|
* @param mixed $arg2 optional, ordno if arg1 = component type |
6614
|
|
|
* @return void |
6615
|
|
|
*/ |
6616
|
|
View Code Duplication |
function deleteComponent( $arg1, $arg2=FALSE ) { |
6617
|
|
|
if( !isset( $this->components )) return FALSE; |
6618
|
|
|
$argType = $index = null; |
6619
|
|
|
if ( ctype_digit( (string) $arg1 )) { |
6620
|
|
|
$argType = 'INDEX'; |
6621
|
|
|
$index = (int) $arg1 - 1; |
6622
|
|
|
} |
6623
|
|
|
elseif(( strlen( $arg1 ) <= strlen( 'vfreebusy' )) && ( FALSE === strpos( $arg1, '@' ))) { |
6624
|
|
|
$argType = strtolower( $arg1 ); |
6625
|
|
|
$index = ( !empty( $arg2 ) && ctype_digit( (string) $arg2 )) ? (( int ) $arg2 - 1 ) : 0; |
6626
|
|
|
} |
6627
|
|
|
$cix2dC = 0; |
6628
|
|
|
foreach ( $this->components as $cix => $component) { |
6629
|
|
|
if( empty( $component )) continue; |
6630
|
|
|
unset( $component->propix ); |
6631
|
|
|
if(( 'INDEX' == $argType ) && ( $index == $cix )) { |
6632
|
|
|
unset( $this->components[$cix] ); |
6633
|
|
|
return TRUE; |
6634
|
|
|
} |
6635
|
|
|
elseif( $argType == $component->objName ) { |
6636
|
|
|
if( $index == $cix2dC ) { |
6637
|
|
|
unset( $this->components[$cix] ); |
6638
|
|
|
return TRUE; |
6639
|
|
|
} |
6640
|
|
|
$cix2dC++; |
6641
|
|
|
} |
6642
|
|
|
elseif( !$argType && ($arg1 == $component->getProperty( 'uid' ))) { |
6643
|
|
|
unset( $this->components[$cix] ); |
6644
|
|
|
return TRUE; |
6645
|
|
|
} |
6646
|
|
|
} |
6647
|
|
|
return FALSE; |
6648
|
|
|
} |
6649
|
|
|
/** |
6650
|
|
|
* get calendar component subcomponent from component container |
6651
|
|
|
* |
6652
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
6653
|
|
|
* @since 2.5.1 - 2008-10-15 |
6654
|
|
|
* @param mixed $arg1 optional, ordno/component type/ component uid |
6655
|
|
|
* @param mixed $arg2 optional, ordno if arg1 = component type |
6656
|
|
|
* @return object |
6657
|
|
|
*/ |
6658
|
|
View Code Duplication |
function getComponent ( $arg1=FALSE, $arg2=FALSE ) { |
6659
|
|
|
if( !isset( $this->components )) return FALSE; |
6660
|
|
|
$index = $argType = null; |
6661
|
|
|
if ( !$arg1 ) { |
6662
|
|
|
$argType = 'INDEX'; |
6663
|
|
|
$index = $this->compix['INDEX'] = |
6664
|
|
|
( isset( $this->compix['INDEX'] )) ? $this->compix['INDEX'] + 1 : 1; |
6665
|
|
|
} |
6666
|
|
|
elseif ( ctype_digit( (string) $arg1 )) { |
6667
|
|
|
$argType = 'INDEX'; |
6668
|
|
|
$index = (int) $arg1; |
6669
|
|
|
unset( $this->compix ); |
6670
|
|
|
} |
6671
|
|
|
elseif(( strlen( $arg1 ) <= strlen( 'vfreebusy' )) && ( FALSE === strpos( $arg1, '@' ))) { |
6672
|
|
|
unset( $this->compix['INDEX'] ); |
6673
|
|
|
$argType = strtolower( $arg1 ); |
6674
|
|
|
if( !$arg2 ) |
6675
|
|
|
$index = $this->compix[$argType] = |
6676
|
|
|
( isset( $this->compix[$argType] )) ? $this->compix[$argType] + 1 : 1; |
6677
|
|
|
else |
6678
|
|
|
$index = (int) $arg2; |
6679
|
|
|
} |
6680
|
|
|
$index -= 1; |
6681
|
|
|
$ckeys = array_keys( $this->components ); |
6682
|
|
|
if( !empty( $index) && ( $index > end( $ckeys ))) |
6683
|
|
|
return FALSE; |
6684
|
|
|
$cix2gC = 0; |
6685
|
|
|
foreach( $this->components as $cix => $component ) { |
6686
|
|
|
if( empty( $component )) continue; |
6687
|
|
|
unset( $component->propix ); |
6688
|
|
|
if(( 'INDEX' == $argType ) && ( $index == $cix )) |
6689
|
|
|
return $component->copy(); |
6690
|
|
|
elseif( $argType == $component->objName ) { |
6691
|
|
|
if( $index == $cix2gC ) |
6692
|
|
|
return $component->copy(); |
6693
|
|
|
$cix2gC++; |
6694
|
|
|
} |
6695
|
|
|
elseif( !$argType && ( $arg1 == $component->getProperty( 'uid' ))) { |
6696
|
|
|
unset( $component->propix ); |
6697
|
|
|
return $component->copy(); |
6698
|
|
|
} |
6699
|
|
|
} |
6700
|
|
|
/* not found.. . */ |
6701
|
|
|
unset( $this->compix ); |
6702
|
|
|
return false; |
6703
|
|
|
} |
6704
|
|
|
/** |
6705
|
|
|
* add calendar component as subcomponent to container for subcomponents |
6706
|
|
|
* |
6707
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
6708
|
|
|
* @since 1.x.x - 2007-04-24 |
6709
|
|
|
* @param object $component calendar component |
6710
|
|
|
* @return void |
6711
|
|
|
*/ |
6712
|
|
|
function addSubComponent ( $component ) { |
6713
|
|
|
$this->setComponent( $component ); |
6714
|
|
|
} |
6715
|
|
|
/** |
6716
|
|
|
* add calendar component as subcomponent to container for subcomponents |
6717
|
|
|
* |
6718
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
6719
|
|
|
* @since 2.4.13 - 2008-09-24 |
6720
|
|
|
* @param object $component calendar component |
6721
|
|
|
* @param mixed $arg1 optional, ordno/component type/ component uid |
6722
|
|
|
* @param mixed $arg2 optional, ordno if arg1 = component type |
6723
|
|
|
* @return bool |
6724
|
|
|
*/ |
6725
|
|
|
function setComponent( $component, $arg1=FALSE, $arg2=FALSE ) { |
6726
|
|
|
if( !isset( $this->components )) return FALSE; |
6727
|
|
|
if( '' >= $component->getConfig( 'language')) |
6728
|
|
|
$component->setConfig( 'language', $this->getConfig( 'language' )); |
6729
|
|
|
$component->setConfig( 'allowEmpty', $this->getConfig( 'allowEmpty' )); |
6730
|
|
|
$component->setConfig( 'nl', $this->getConfig( 'nl' )); |
6731
|
|
|
$component->setConfig( 'unique_id', $this->getConfig( 'unique_id' )); |
6732
|
|
|
$component->setConfig( 'format', $this->getConfig( 'format' )); |
6733
|
|
View Code Duplication |
if( !in_array( $component->objName, array( 'valarm', 'vtimezone', 'standard', 'daylight' ))) { |
6734
|
|
|
unset( $component->propix ); |
6735
|
|
|
/* make sure dtstamp and uid is set */ |
6736
|
|
|
$dummy = $component->getProperty( 'dtstamp' ); |
6737
|
|
|
$dummy = $component->getProperty( 'uid' ); |
6738
|
|
|
} |
6739
|
|
|
if( !$arg1 ) { |
6740
|
|
|
$this->components[] = $component->copy(); |
6741
|
|
|
return TRUE; |
6742
|
|
|
} |
6743
|
|
|
$argType = $index = null; |
6744
|
|
|
if ( ctype_digit( (string) $arg1 )) { |
6745
|
|
|
$argType = 'INDEX'; |
6746
|
|
|
$index = (int) $arg1 - 1; |
6747
|
|
|
} |
6748
|
|
|
elseif(( strlen( $arg1 ) <= strlen( 'vfreebusy' )) && ( FALSE === strpos( $arg1, '@' ))) { |
6749
|
|
|
$argType = strtolower( $arg1 ); |
6750
|
|
|
$index = ( ctype_digit( (string) $arg2 )) ? ((int) $arg2) - 1 : 0; |
6751
|
|
|
} |
6752
|
|
|
$cix2sC = 0; |
6753
|
|
View Code Duplication |
foreach ( $this->components as $cix => $component2 ) { |
6754
|
|
|
if( empty( $component2 )) continue; |
6755
|
|
|
unset( $component2->propix ); |
6756
|
|
|
if(( 'INDEX' == $argType ) && ( $index == $cix )) { |
6757
|
|
|
$this->components[$cix] = $component->copy(); |
6758
|
|
|
return TRUE; |
6759
|
|
|
} |
6760
|
|
|
elseif( $argType == $component2->objName ) { |
6761
|
|
|
if( $index == $cix2sC ) { |
6762
|
|
|
$this->components[$cix] = $component->copy(); |
6763
|
|
|
return TRUE; |
6764
|
|
|
} |
6765
|
|
|
$cix2sC++; |
6766
|
|
|
} |
6767
|
|
|
elseif( !$argType && ($arg1 == $component2->getProperty( 'uid' ))) { |
6768
|
|
|
$this->components[$cix] = $component->copy(); |
6769
|
|
|
return TRUE; |
6770
|
|
|
} |
6771
|
|
|
} |
6772
|
|
|
/* not found.. . insert anyway.. .*/ |
6773
|
|
|
$this->components[] = $component->copy(); |
6774
|
|
|
return TRUE; |
6775
|
|
|
} |
6776
|
|
|
/** |
6777
|
|
|
* creates formatted output for subcomponents |
6778
|
|
|
* |
6779
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
6780
|
|
|
* @since 2.4.10 - 2008-08-06 |
6781
|
|
|
* @return string |
6782
|
|
|
*/ |
6783
|
|
|
function createSubComponent() { |
6784
|
|
|
$output = null; |
6785
|
|
View Code Duplication |
foreach( $this->components as $component ) { |
6786
|
|
|
if( empty( $component )) continue; |
6787
|
|
|
if( '' >= $component->getConfig( 'language')) |
6788
|
|
|
$component->setConfig( 'language', $this->getConfig( 'language' )); |
6789
|
|
|
$component->setConfig( 'allowEmpty', $this->getConfig( 'allowEmpty' )); |
6790
|
|
|
$component->setConfig( 'nl', $this->getConfig( 'nl' )); |
6791
|
|
|
$component->setConfig( 'unique_id', $this->getConfig( 'unique_id' )); |
6792
|
|
|
$component->setConfig( 'format', $this->getConfig( 'format' )); |
6793
|
|
|
$output .= $component->createComponent( $this->xcaldecl ); |
6794
|
|
|
} |
6795
|
|
|
return $output; |
6796
|
|
|
} |
6797
|
|
|
/********************************************************************************/ |
6798
|
|
|
/** |
6799
|
|
|
* break lines at pos 75 |
6800
|
|
|
* |
6801
|
|
|
* Lines of text SHOULD NOT be longer than 75 octets, excluding the line |
6802
|
|
|
* break. Long content lines SHOULD be split into a multiple line |
6803
|
|
|
* representations using a line "folding" technique. That is, a long |
6804
|
|
|
* line can be split between any two characters by inserting a CRLF |
6805
|
|
|
* immediately followed by a single linear white space character (i.e., |
6806
|
|
|
* SPACE, US-ASCII decimal 32 or HTAB, US-ASCII decimal 9). Any sequence |
6807
|
|
|
* of CRLF followed immediately by a single linear white space character |
6808
|
|
|
* is ignored (i.e., removed) when processing the content type. |
6809
|
|
|
* |
6810
|
|
|
* Edited 2007-08-26 by Anders Litzell, [email protected] to fix bug where |
6811
|
|
|
* the reserved expression "\n" in the arg $string could be broken up by the |
6812
|
|
|
* folding of lines, causing ambiguity in the return string. |
6813
|
|
|
* Fix uses var $breakAtChar=75 and breaks the line at $breakAtChar-1 if need be. |
6814
|
|
|
* |
6815
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
6816
|
|
|
* @since 2.2.8 - 2006-09-03 |
6817
|
|
|
* @param string $value |
|
|
|
|
6818
|
|
|
* @return string |
6819
|
|
|
*/ |
6820
|
|
|
function _size75( $string ) { |
6821
|
|
|
$strlen = strlen( $string ); |
6822
|
|
|
$tmp = $string; |
6823
|
|
|
$string = null; |
6824
|
|
|
while( $strlen > 75 ) { |
6825
|
|
|
$breakAtChar = 75; |
6826
|
|
|
if( substr( $tmp, ( $breakAtChar - 1 ), strlen( '\n' )) == '\n' ) |
6827
|
|
|
$breakAtChar = $breakAtChar - 1; |
6828
|
|
|
$string .= substr( $tmp, 0, $breakAtChar ); |
6829
|
|
|
$string .= $this->nl; |
6830
|
|
|
$tmp = ' '.substr( $tmp, $breakAtChar ); |
6831
|
|
|
$strlen = strlen( $tmp ); |
6832
|
|
|
} // while |
6833
|
|
|
$string .= rtrim( $tmp ); // the rest |
6834
|
|
|
if( $this->nl != substr( $string, ( 0 - strlen( $this->nl )))) |
6835
|
|
|
$string .= $this->nl; |
6836
|
|
|
return $string; |
6837
|
|
|
} |
6838
|
|
|
/** |
6839
|
|
|
* special characters management output |
6840
|
|
|
* |
6841
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
6842
|
|
|
* @since 2.3.3 - 2007-12-20 |
6843
|
|
|
* @param string $string |
6844
|
|
|
* @return string |
6845
|
|
|
*/ |
6846
|
|
|
function _strrep( $string ) { |
6847
|
|
|
switch( $this->format ) { |
6848
|
|
|
case 'xcal': |
6849
|
|
|
$string = str_replace( '\n', $this->nl, $string); |
6850
|
|
|
$string = htmlspecialchars( strip_tags( stripslashes( urldecode ( $string )))); |
6851
|
|
|
break; |
6852
|
|
|
default: |
6853
|
|
|
$pos = 0; |
6854
|
|
|
while( $pos <= strlen( $string )) { |
6855
|
|
|
$pos = strpos( $string, "\\", $pos ); |
6856
|
|
|
if( FALSE === $pos ) |
6857
|
|
|
break; |
6858
|
|
|
if( !in_array( $string{($pos + 1)}, array( 'n', 'N', 'r', ',', ';' ))) { |
6859
|
|
|
$string = substr( $string, 0, $pos )."\\".substr( $string, ( $pos + 1 )); |
6860
|
|
|
$pos += 1; |
6861
|
|
|
} |
6862
|
|
|
$pos += 1; |
6863
|
|
|
} |
6864
|
|
|
if( FALSE !== strpos( $string, '"' )) |
6865
|
|
|
$string = str_replace('"', "'", $string); |
6866
|
|
|
if( FALSE !== strpos( $string, ',' )) |
6867
|
|
|
$string = str_replace(',', '\,', $string); |
6868
|
|
|
if( FALSE !== strpos( $string, ';' )) |
6869
|
|
|
$string = str_replace(';', '\;', $string); |
6870
|
|
|
if( FALSE !== strpos( $string, "\r\n" )) |
6871
|
|
|
$string = str_replace( "\r\n", '\n', $string); |
6872
|
|
|
elseif( FALSE !== strpos( $string, "\r" )) |
6873
|
|
|
$string = str_replace( "\r", '\n', $string); |
6874
|
|
|
if( FALSE !== strpos( $string, '\N' )) |
6875
|
|
|
$string = str_replace( '\N', '\n', $string); |
6876
|
|
|
// if( FALSE !== strpos( $string, $this->nl )) |
6877
|
|
|
$string = str_replace( $this->nl, '\n', $string); |
6878
|
|
|
break; |
6879
|
|
|
} |
6880
|
|
|
return $string; |
6881
|
|
|
} |
6882
|
|
|
/** |
6883
|
|
|
* special characters management input (from iCal file) |
6884
|
|
|
* |
6885
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
6886
|
|
|
* @since 2.3.3 - 2007-11-23 |
6887
|
|
|
* @param string $string |
6888
|
|
|
* @return string |
6889
|
|
|
*/ |
6890
|
|
|
function _strunrep( $string ) { |
6891
|
|
|
$string = str_replace( '\\\\', '\\', $string); |
6892
|
|
|
$string = str_replace( '\,', ',', $string); |
6893
|
|
|
$string = str_replace( '\;', ';', $string); |
6894
|
|
|
// $string = str_replace( '\n', $this->nl, $string); // ?? |
6895
|
|
|
return $string; |
6896
|
|
|
} |
6897
|
|
|
} |
6898
|
|
|
/*********************************************************************************/ |
6899
|
|
|
/*********************************************************************************/ |
6900
|
|
|
/** |
6901
|
|
|
* class for calendar component VEVENT |
6902
|
|
|
* |
6903
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
6904
|
|
|
* @since 2.5.1 - 2008-10-12 |
6905
|
|
|
*/ |
6906
|
|
|
class vevent extends calendarComponent { |
6907
|
|
|
var $attach; |
6908
|
|
|
var $attendee; |
6909
|
|
|
var $categories; |
6910
|
|
|
var $comment; |
6911
|
|
|
var $contact; |
6912
|
|
|
var $class; |
6913
|
|
|
var $created; |
6914
|
|
|
var $description; |
6915
|
|
|
var $dtend; |
6916
|
|
|
var $dtstart; |
6917
|
|
|
var $duration; |
6918
|
|
|
var $exdate; |
6919
|
|
|
var $exrule; |
6920
|
|
|
var $geo; |
6921
|
|
|
var $lastmodified; |
6922
|
|
|
var $location; |
6923
|
|
|
var $organizer; |
6924
|
|
|
var $priority; |
6925
|
|
|
var $rdate; |
6926
|
|
|
var $recurrenceid; |
6927
|
|
|
var $relatedto; |
6928
|
|
|
var $requeststatus; |
6929
|
|
|
var $resources; |
6930
|
|
|
var $rrule; |
6931
|
|
|
var $sequence; |
6932
|
|
|
var $status; |
6933
|
|
|
var $summary; |
6934
|
|
|
var $transp; |
6935
|
|
|
var $url; |
6936
|
|
|
var $xprop; |
6937
|
|
|
// component subcomponents container |
6938
|
|
|
var $components; |
6939
|
|
|
/** |
6940
|
|
|
* constructor for calendar component VEVENT object |
6941
|
|
|
* |
6942
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
6943
|
|
|
* @since 2.5.1 - 2008-10-31 |
6944
|
|
|
* @return void |
|
|
|
|
6945
|
|
|
*/ |
6946
|
|
View Code Duplication |
function __construct() { |
6947
|
|
|
$this->calendarComponent(); |
6948
|
|
|
|
6949
|
|
|
$this->attach = ''; |
6950
|
|
|
$this->attendee = ''; |
6951
|
|
|
$this->categories = ''; |
6952
|
|
|
$this->class = ''; |
6953
|
|
|
$this->comment = ''; |
6954
|
|
|
$this->contact = ''; |
6955
|
|
|
$this->created = ''; |
6956
|
|
|
$this->description = ''; |
6957
|
|
|
$this->dtstart = ''; |
6958
|
|
|
$this->dtend = ''; |
6959
|
|
|
$this->duration = ''; |
6960
|
|
|
$this->exdate = ''; |
6961
|
|
|
$this->exrule = ''; |
6962
|
|
|
$this->geo = ''; |
6963
|
|
|
$this->lastmodified = ''; |
6964
|
|
|
$this->location = ''; |
6965
|
|
|
$this->organizer = ''; |
6966
|
|
|
$this->priority = ''; |
6967
|
|
|
$this->rdate = ''; |
6968
|
|
|
$this->recurrenceid = ''; |
6969
|
|
|
$this->relatedto = ''; |
6970
|
|
|
$this->requeststatus = ''; |
6971
|
|
|
$this->resources = ''; |
6972
|
|
|
$this->rrule = ''; |
6973
|
|
|
$this->sequence = ''; |
6974
|
|
|
$this->status = ''; |
6975
|
|
|
$this->summary = ''; |
6976
|
|
|
$this->transp = ''; |
6977
|
|
|
$this->url = ''; |
6978
|
|
|
$this->xprop = ''; |
6979
|
|
|
|
6980
|
|
|
$this->components = array(); |
6981
|
|
|
|
6982
|
|
|
} |
6983
|
|
|
/** |
6984
|
|
|
* create formatted output for calendar component VEVENT object instance |
6985
|
|
|
* |
6986
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
6987
|
|
|
* @since 2.5.1 - 2008-11-07 |
6988
|
|
|
* @param array $xcaldecl |
6989
|
|
|
* @return string |
6990
|
|
|
*/ |
6991
|
|
View Code Duplication |
function createComponent( &$xcaldecl ) { |
6992
|
|
|
$objectname = $this->_createFormat(); |
6993
|
|
|
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl; |
6994
|
|
|
$component .= $this->createUid(); |
6995
|
|
|
$component .= $this->createDtstamp(); |
6996
|
|
|
$component .= $this->createAttach(); |
6997
|
|
|
$component .= $this->createAttendee(); |
6998
|
|
|
$component .= $this->createCategories(); |
6999
|
|
|
$component .= $this->createComment(); |
7000
|
|
|
$component .= $this->createContact(); |
7001
|
|
|
$component .= $this->createClass(); |
7002
|
|
|
$component .= $this->createCreated(); |
7003
|
|
|
$component .= $this->createDescription(); |
7004
|
|
|
$component .= $this->createDtstart(); |
7005
|
|
|
$component .= $this->createDtend(); |
7006
|
|
|
$component .= $this->createDuration(); |
7007
|
|
|
$component .= $this->createExdate(); |
7008
|
|
|
$component .= $this->createExrule(); |
7009
|
|
|
$component .= $this->createGeo(); |
7010
|
|
|
$component .= $this->createLastModified(); |
7011
|
|
|
$component .= $this->createLocation(); |
7012
|
|
|
$component .= $this->createOrganizer(); |
7013
|
|
|
$component .= $this->createPriority(); |
7014
|
|
|
$component .= $this->createRdate(); |
7015
|
|
|
$component .= $this->createRrule(); |
7016
|
|
|
$component .= $this->createRelatedTo(); |
7017
|
|
|
$component .= $this->createRequestStatus(); |
7018
|
|
|
$component .= $this->createRecurrenceid(); |
7019
|
|
|
$component .= $this->createResources(); |
7020
|
|
|
$component .= $this->createSequence(); |
7021
|
|
|
$component .= $this->createStatus(); |
7022
|
|
|
$component .= $this->createSummary(); |
7023
|
|
|
$component .= $this->createTransp(); |
7024
|
|
|
$component .= $this->createUrl(); |
7025
|
|
|
$component .= $this->createXprop(); |
7026
|
|
|
$component .= $this->createSubComponent(); |
7027
|
|
|
$component .= $this->componentEnd1.$objectname.$this->componentEnd2; |
7028
|
|
|
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) { |
7029
|
|
|
foreach( $this->xcaldecl as $localxcaldecl ) |
7030
|
|
|
$xcaldecl[] = $localxcaldecl; |
7031
|
|
|
} |
7032
|
|
|
return $component; |
7033
|
|
|
} |
7034
|
|
|
} |
7035
|
|
|
/*********************************************************************************/ |
7036
|
|
|
/*********************************************************************************/ |
7037
|
|
|
/** |
7038
|
|
|
* class for calendar component VTODO |
7039
|
|
|
* |
7040
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
7041
|
|
|
* @since 2.5.1 - 2008-10-12 |
7042
|
|
|
*/ |
7043
|
|
|
class vtodo extends calendarComponent { |
7044
|
|
|
var $attach; |
7045
|
|
|
var $attendee; |
7046
|
|
|
var $categories; |
7047
|
|
|
var $comment; |
7048
|
|
|
var $completed; |
7049
|
|
|
var $contact; |
7050
|
|
|
var $class; |
7051
|
|
|
var $created; |
7052
|
|
|
var $description; |
7053
|
|
|
var $dtstart; |
7054
|
|
|
var $due; |
7055
|
|
|
var $duration; |
7056
|
|
|
var $exdate; |
7057
|
|
|
var $exrule; |
7058
|
|
|
var $geo; |
7059
|
|
|
var $lastmodified; |
7060
|
|
|
var $location; |
7061
|
|
|
var $organizer; |
7062
|
|
|
var $percentcomplete; |
7063
|
|
|
var $priority; |
7064
|
|
|
var $rdate; |
7065
|
|
|
var $recurrenceid; |
7066
|
|
|
var $relatedto; |
7067
|
|
|
var $requeststatus; |
7068
|
|
|
var $resources; |
7069
|
|
|
var $rrule; |
7070
|
|
|
var $sequence; |
7071
|
|
|
var $status; |
7072
|
|
|
var $summary; |
7073
|
|
|
var $url; |
7074
|
|
|
var $xprop; |
7075
|
|
|
// component subcomponents container |
7076
|
|
|
var $components; |
7077
|
|
|
/** |
7078
|
|
|
* constructor for calendar component VTODO object |
7079
|
|
|
* |
7080
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
7081
|
|
|
* @since 2.5.1 - 2008-10-31 |
7082
|
|
|
* @return void |
|
|
|
|
7083
|
|
|
*/ |
7084
|
|
View Code Duplication |
function __construct() { |
7085
|
|
|
$this->calendarComponent(); |
7086
|
|
|
|
7087
|
|
|
$this->attach = ''; |
7088
|
|
|
$this->attendee = ''; |
7089
|
|
|
$this->categories = ''; |
7090
|
|
|
$this->class = ''; |
7091
|
|
|
$this->comment = ''; |
7092
|
|
|
$this->completed = ''; |
7093
|
|
|
$this->contact = ''; |
7094
|
|
|
$this->created = ''; |
7095
|
|
|
$this->description = ''; |
7096
|
|
|
$this->dtstart = ''; |
7097
|
|
|
$this->due = ''; |
7098
|
|
|
$this->duration = ''; |
7099
|
|
|
$this->exdate = ''; |
7100
|
|
|
$this->exrule = ''; |
7101
|
|
|
$this->geo = ''; |
7102
|
|
|
$this->lastmodified = ''; |
7103
|
|
|
$this->location = ''; |
7104
|
|
|
$this->organizer = ''; |
7105
|
|
|
$this->percentcomplete = ''; |
7106
|
|
|
$this->priority = ''; |
7107
|
|
|
$this->rdate = ''; |
7108
|
|
|
$this->recurrenceid = ''; |
7109
|
|
|
$this->relatedto = ''; |
7110
|
|
|
$this->requeststatus = ''; |
7111
|
|
|
$this->resources = ''; |
7112
|
|
|
$this->rrule = ''; |
7113
|
|
|
$this->sequence = ''; |
7114
|
|
|
$this->status = ''; |
7115
|
|
|
$this->summary = ''; |
7116
|
|
|
$this->url = ''; |
7117
|
|
|
$this->xprop = ''; |
7118
|
|
|
|
7119
|
|
|
$this->components = array(); |
7120
|
|
|
} |
7121
|
|
|
/** |
7122
|
|
|
* create formatted output for calendar component VTODO object instance |
7123
|
|
|
* |
7124
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
7125
|
|
|
* @since 2.5.1 - 2008-11-07 |
7126
|
|
|
* @param array $xcaldecl |
7127
|
|
|
* @return string |
7128
|
|
|
*/ |
7129
|
|
View Code Duplication |
function createComponent( &$xcaldecl ) { |
7130
|
|
|
$objectname = $this->_createFormat(); |
7131
|
|
|
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl; |
7132
|
|
|
$component .= $this->createUid(); |
7133
|
|
|
$component .= $this->createDtstamp(); |
7134
|
|
|
$component .= $this->createAttach(); |
7135
|
|
|
$component .= $this->createAttendee(); |
7136
|
|
|
$component .= $this->createCategories(); |
7137
|
|
|
$component .= $this->createClass(); |
7138
|
|
|
$component .= $this->createComment(); |
7139
|
|
|
$component .= $this->createCompleted(); |
7140
|
|
|
$component .= $this->createContact(); |
7141
|
|
|
$component .= $this->createCreated(); |
7142
|
|
|
$component .= $this->createDescription(); |
7143
|
|
|
$component .= $this->createDtstart(); |
7144
|
|
|
$component .= $this->createDue(); |
7145
|
|
|
$component .= $this->createDuration(); |
7146
|
|
|
$component .= $this->createExdate(); |
7147
|
|
|
$component .= $this->createExrule(); |
7148
|
|
|
$component .= $this->createGeo(); |
7149
|
|
|
$component .= $this->createLastModified(); |
7150
|
|
|
$component .= $this->createLocation(); |
7151
|
|
|
$component .= $this->createOrganizer(); |
7152
|
|
|
$component .= $this->createPercentComplete(); |
7153
|
|
|
$component .= $this->createPriority(); |
7154
|
|
|
$component .= $this->createRdate(); |
7155
|
|
|
$component .= $this->createRelatedTo(); |
7156
|
|
|
$component .= $this->createRequestStatus(); |
7157
|
|
|
$component .= $this->createRecurrenceid(); |
7158
|
|
|
$component .= $this->createResources(); |
7159
|
|
|
$component .= $this->createRrule(); |
7160
|
|
|
$component .= $this->createSequence(); |
7161
|
|
|
$component .= $this->createStatus(); |
7162
|
|
|
$component .= $this->createSummary(); |
7163
|
|
|
$component .= $this->createUrl(); |
7164
|
|
|
$component .= $this->createXprop(); |
7165
|
|
|
$component .= $this->createSubComponent(); |
7166
|
|
|
$component .= $this->componentEnd1.$objectname.$this->componentEnd2; |
7167
|
|
|
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) { |
7168
|
|
|
foreach( $this->xcaldecl as $localxcaldecl ) |
7169
|
|
|
$xcaldecl[] = $localxcaldecl; |
7170
|
|
|
} |
7171
|
|
|
return $component; |
7172
|
|
|
} |
7173
|
|
|
} |
7174
|
|
|
/*********************************************************************************/ |
7175
|
|
|
/*********************************************************************************/ |
7176
|
|
|
/** |
7177
|
|
|
* class for calendar component VJOURNAL |
7178
|
|
|
* |
7179
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
7180
|
|
|
* @since 2.5.1 - 2008-10-12 |
7181
|
|
|
*/ |
7182
|
|
|
class vjournal extends calendarComponent { |
7183
|
|
|
var $attach; |
7184
|
|
|
var $attendee; |
7185
|
|
|
var $categories; |
7186
|
|
|
var $comment; |
7187
|
|
|
var $contact; |
7188
|
|
|
var $class; |
7189
|
|
|
var $created; |
7190
|
|
|
var $description; |
7191
|
|
|
var $dtstart; |
7192
|
|
|
var $exdate; |
7193
|
|
|
var $exrule; |
7194
|
|
|
var $lastmodified; |
7195
|
|
|
var $organizer; |
7196
|
|
|
var $rdate; |
7197
|
|
|
var $recurrenceid; |
7198
|
|
|
var $relatedto; |
7199
|
|
|
var $requeststatus; |
7200
|
|
|
var $rrule; |
7201
|
|
|
var $sequence; |
7202
|
|
|
var $status; |
7203
|
|
|
var $summary; |
7204
|
|
|
var $url; |
7205
|
|
|
var $xprop; |
7206
|
|
|
/** |
7207
|
|
|
* constructor for calendar component VJOURNAL object |
7208
|
|
|
* |
7209
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
7210
|
|
|
* @since 2.5.1 - 2008-10-31 |
7211
|
|
|
* @return void |
|
|
|
|
7212
|
|
|
*/ |
7213
|
|
|
function __construct() { |
7214
|
|
|
$this->calendarComponent(); |
7215
|
|
|
|
7216
|
|
|
$this->attach = ''; |
7217
|
|
|
$this->attendee = ''; |
7218
|
|
|
$this->categories = ''; |
7219
|
|
|
$this->class = ''; |
7220
|
|
|
$this->comment = ''; |
7221
|
|
|
$this->contact = ''; |
7222
|
|
|
$this->created = ''; |
7223
|
|
|
$this->description = ''; |
7224
|
|
|
$this->dtstart = ''; |
7225
|
|
|
$this->exdate = ''; |
7226
|
|
|
$this->exrule = ''; |
7227
|
|
|
$this->lastmodified = ''; |
7228
|
|
|
$this->organizer = ''; |
7229
|
|
|
$this->rdate = ''; |
7230
|
|
|
$this->recurrenceid = ''; |
7231
|
|
|
$this->relatedto = ''; |
7232
|
|
|
$this->requeststatus = ''; |
7233
|
|
|
$this->rrule = ''; |
7234
|
|
|
$this->sequence = ''; |
7235
|
|
|
$this->status = ''; |
7236
|
|
|
$this->summary = ''; |
7237
|
|
|
$this->url = ''; |
7238
|
|
|
$this->xprop = ''; |
7239
|
|
|
} |
7240
|
|
|
/** |
7241
|
|
|
* create formatted output for calendar component VJOURNAL object instance |
7242
|
|
|
* |
7243
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
7244
|
|
|
* @since 2.5.1 - 2008-10-12 |
7245
|
|
|
* @param array $xcaldecl |
7246
|
|
|
* @return string |
7247
|
|
|
*/ |
7248
|
|
|
function createComponent( &$xcaldecl ) { |
7249
|
|
|
$objectname = $this->_createFormat(); |
7250
|
|
|
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl; |
7251
|
|
|
$component .= $this->createUid(); |
7252
|
|
|
$component .= $this->createDtstamp(); |
7253
|
|
|
$component .= $this->createAttach(); |
7254
|
|
|
$component .= $this->createAttendee(); |
7255
|
|
|
$component .= $this->createCategories(); |
7256
|
|
|
$component .= $this->createClass(); |
7257
|
|
|
$component .= $this->createComment(); |
7258
|
|
|
$component .= $this->createContact(); |
7259
|
|
|
$component .= $this->createCreated(); |
7260
|
|
|
$component .= $this->createDescription(); |
7261
|
|
|
$component .= $this->createDtstart(); |
7262
|
|
|
$component .= $this->createExdate(); |
7263
|
|
|
$component .= $this->createExrule(); |
7264
|
|
|
$component .= $this->createLastModified(); |
7265
|
|
|
$component .= $this->createOrganizer(); |
7266
|
|
|
$component .= $this->createRdate(); |
7267
|
|
|
$component .= $this->createRequestStatus(); |
7268
|
|
|
$component .= $this->createRecurrenceid(); |
7269
|
|
|
$component .= $this->createRelatedTo(); |
7270
|
|
|
$component .= $this->createRrule(); |
7271
|
|
|
$component .= $this->createSequence(); |
7272
|
|
|
$component .= $this->createStatus(); |
7273
|
|
|
$component .= $this->createSummary(); |
7274
|
|
|
$component .= $this->createUrl(); |
7275
|
|
|
$component .= $this->createXprop(); |
7276
|
|
|
$component .= $this->componentEnd1.$objectname.$this->componentEnd2; |
7277
|
|
|
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) { |
7278
|
|
|
foreach( $this->xcaldecl as $localxcaldecl ) |
7279
|
|
|
$xcaldecl[] = $localxcaldecl; |
7280
|
|
|
} |
7281
|
|
|
return $component; |
7282
|
|
|
} |
7283
|
|
|
} |
7284
|
|
|
/*********************************************************************************/ |
7285
|
|
|
/*********************************************************************************/ |
7286
|
|
|
/** |
7287
|
|
|
* class for calendar component VFREEBUSY |
7288
|
|
|
* |
7289
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
7290
|
|
|
* @since 2.5.1 - 2008-10-12 |
7291
|
|
|
*/ |
7292
|
|
|
class vfreebusy extends calendarComponent { |
7293
|
|
|
var $attendee; |
7294
|
|
|
var $comment; |
7295
|
|
|
var $contact; |
7296
|
|
|
var $dtend; |
7297
|
|
|
var $dtstart; |
7298
|
|
|
var $duration; |
7299
|
|
|
var $freebusy; |
7300
|
|
|
var $organizer; |
7301
|
|
|
var $requeststatus; |
7302
|
|
|
var $url; |
7303
|
|
|
var $xprop; |
7304
|
|
|
// component subcomponents container |
7305
|
|
|
var $components; |
7306
|
|
|
/** |
7307
|
|
|
* constructor for calendar component VFREEBUSY object |
7308
|
|
|
* |
7309
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
7310
|
|
|
* @since 2.5.1 - 2008-10-31 |
7311
|
|
|
* @return void |
|
|
|
|
7312
|
|
|
*/ |
7313
|
|
|
function __construct() { |
7314
|
|
|
$this->calendarComponent(); |
7315
|
|
|
|
7316
|
|
|
$this->attendee = ''; |
7317
|
|
|
$this->comment = ''; |
7318
|
|
|
$this->contact = ''; |
7319
|
|
|
$this->dtend = ''; |
7320
|
|
|
$this->dtstart = ''; |
7321
|
|
|
$this->duration = ''; |
7322
|
|
|
$this->freebusy = ''; |
7323
|
|
|
$this->organizer = ''; |
7324
|
|
|
$this->requeststatus = ''; |
7325
|
|
|
$this->url = ''; |
7326
|
|
|
$this->xprop = ''; |
7327
|
|
|
} |
7328
|
|
|
/** |
7329
|
|
|
* create formatted output for calendar component VFREEBUSY object instance |
7330
|
|
|
* |
7331
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
7332
|
|
|
* @since 2.3.1 - 2007-11-19 |
7333
|
|
|
* @param array $xcaldecl |
7334
|
|
|
* @return string |
7335
|
|
|
*/ |
7336
|
|
View Code Duplication |
function createComponent( &$xcaldecl ) { |
7337
|
|
|
$objectname = $this->_createFormat(); |
7338
|
|
|
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl; |
7339
|
|
|
$component .= $this->createUid(); |
7340
|
|
|
$component .= $this->createDtstamp(); |
7341
|
|
|
$component .= $this->createAttendee(); |
7342
|
|
|
$component .= $this->createComment(); |
7343
|
|
|
$component .= $this->createContact(); |
7344
|
|
|
$component .= $this->createDtstart(); |
7345
|
|
|
$component .= $this->createDtend(); |
7346
|
|
|
$component .= $this->createDuration(); |
7347
|
|
|
$component .= $this->createFreebusy(); |
7348
|
|
|
$component .= $this->createOrganizer(); |
7349
|
|
|
$component .= $this->createRequestStatus(); |
7350
|
|
|
$component .= $this->createUrl(); |
7351
|
|
|
$component .= $this->createXprop(); |
7352
|
|
|
$component .= $this->componentEnd1.$objectname.$this->componentEnd2; |
7353
|
|
|
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) { |
7354
|
|
|
foreach( $this->xcaldecl as $localxcaldecl ) |
7355
|
|
|
$xcaldecl[] = $localxcaldecl; |
7356
|
|
|
} |
7357
|
|
|
return $component; |
7358
|
|
|
} |
7359
|
|
|
} |
7360
|
|
|
/*********************************************************************************/ |
7361
|
|
|
/*********************************************************************************/ |
7362
|
|
|
/** |
7363
|
|
|
* class for calendar component VALARM |
7364
|
|
|
* |
7365
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
7366
|
|
|
* @since 2.5.1 - 2008-10-12 |
7367
|
|
|
*/ |
7368
|
|
|
class valarm extends calendarComponent { |
7369
|
|
|
var $action; |
7370
|
|
|
var $attach; |
7371
|
|
|
var $attendee; |
7372
|
|
|
var $description; |
7373
|
|
|
var $duration; |
7374
|
|
|
var $repeat; |
7375
|
|
|
var $summary; |
7376
|
|
|
var $trigger; |
7377
|
|
|
var $xprop; |
7378
|
|
|
/** |
7379
|
|
|
* constructor for calendar component VALARM object |
7380
|
|
|
* |
7381
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
7382
|
|
|
* @since 2.5.1 - 2008-10-31 |
7383
|
|
|
* @return void |
|
|
|
|
7384
|
|
|
*/ |
7385
|
|
|
function __construct() { |
7386
|
|
|
$this->calendarComponent(); |
7387
|
|
|
|
7388
|
|
|
$this->action = ''; |
7389
|
|
|
$this->attach = ''; |
7390
|
|
|
$this->attendee = ''; |
7391
|
|
|
$this->description = ''; |
7392
|
|
|
$this->duration = ''; |
7393
|
|
|
$this->repeat = ''; |
7394
|
|
|
$this->summary = ''; |
7395
|
|
|
$this->trigger = ''; |
7396
|
|
|
$this->xprop = ''; |
7397
|
|
|
} |
7398
|
|
|
/** |
7399
|
|
|
* create formatted output for calendar component VALARM object instance |
7400
|
|
|
* |
7401
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
7402
|
|
|
* @since 2.5.1 - 2008-10-22 |
7403
|
|
|
* @param array $xcaldecl |
7404
|
|
|
* @return string |
7405
|
|
|
*/ |
7406
|
|
|
function createComponent( &$xcaldecl ) { |
7407
|
|
|
$objectname = $this->_createFormat(); |
7408
|
|
|
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl; |
7409
|
|
|
$component .= $this->createAction(); |
7410
|
|
|
$component .= $this->createAttach(); |
7411
|
|
|
$component .= $this->createAttendee(); |
7412
|
|
|
$component .= $this->createDescription(); |
7413
|
|
|
$component .= $this->createDuration(); |
7414
|
|
|
$component .= $this->createRepeat(); |
7415
|
|
|
$component .= $this->createSummary(); |
7416
|
|
|
$component .= $this->createTrigger(); |
7417
|
|
|
$component .= $this->createXprop(); |
7418
|
|
|
$component .= $this->componentEnd1.$objectname.$this->componentEnd2; |
7419
|
|
|
return $component; |
7420
|
|
|
} |
7421
|
|
|
} |
7422
|
|
|
/********************************************************************************** |
7423
|
|
|
/*********************************************************************************/ |
7424
|
|
|
/** |
7425
|
|
|
* class for calendar component VTIMEZONE |
7426
|
|
|
* |
7427
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
7428
|
|
|
* @since 2.5.1 - 2008-10-12 |
7429
|
|
|
*/ |
7430
|
|
|
class vtimezone extends calendarComponent { |
7431
|
|
|
var $timezonetype; |
7432
|
|
|
|
7433
|
|
|
var $comment; |
7434
|
|
|
var $dtstart; |
7435
|
|
|
var $lastmodified; |
7436
|
|
|
var $rdate; |
7437
|
|
|
var $rrule; |
7438
|
|
|
var $tzid; |
7439
|
|
|
var $tzname; |
7440
|
|
|
var $tzoffsetfrom; |
7441
|
|
|
var $tzoffsetto; |
7442
|
|
|
var $tzurl; |
7443
|
|
|
var $xprop; |
7444
|
|
|
// component subcomponents container |
7445
|
|
|
var $components; |
7446
|
|
|
/** |
7447
|
|
|
* constructor for calendar component VTIMEZONE object |
7448
|
|
|
* |
7449
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
7450
|
|
|
* @since 2.5.1 - 2008-10-31 |
7451
|
|
|
* @param string $timezonetype optional, default FALSE ( STANDARD / DAYLIGHT ) |
7452
|
|
|
* @return void |
|
|
|
|
7453
|
|
|
*/ |
7454
|
|
|
function __construct( $timezonetype=FALSE ) { |
7455
|
|
|
if( !$timezonetype ) |
7456
|
|
|
$this->timezonetype = 'VTIMEZONE'; |
7457
|
|
|
else |
7458
|
|
|
$this->timezonetype = strtoupper( $timezonetype ); |
7459
|
|
|
$this->calendarComponent(); |
7460
|
|
|
|
7461
|
|
|
$this->comment = ''; |
7462
|
|
|
$this->dtstart = ''; |
7463
|
|
|
$this->lastmodified = ''; |
7464
|
|
|
$this->rdate = ''; |
7465
|
|
|
$this->rrule = ''; |
7466
|
|
|
$this->tzid = ''; |
7467
|
|
|
$this->tzname = ''; |
7468
|
|
|
$this->tzoffsetfrom = ''; |
7469
|
|
|
$this->tzoffsetto = ''; |
7470
|
|
|
$this->tzurl = ''; |
7471
|
|
|
$this->xprop = ''; |
7472
|
|
|
|
7473
|
|
|
$this->components = array(); |
7474
|
|
|
} |
7475
|
|
|
/** |
7476
|
|
|
* create formatted output for calendar component VTIMEZONE object instance |
7477
|
|
|
* |
7478
|
|
|
* @author Kjell-Inge Gustafsson <[email protected]> |
7479
|
|
|
* @since 2.5.1 - 2008-10-25 |
7480
|
|
|
* @param array $xcaldecl |
7481
|
|
|
* @return string |
7482
|
|
|
*/ |
7483
|
|
View Code Duplication |
function createComponent( &$xcaldecl ) { |
7484
|
|
|
$objectname = $this->_createFormat(); |
7485
|
|
|
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl; |
7486
|
|
|
$component .= $this->createTzid(); |
7487
|
|
|
$component .= $this->createLastModified(); |
7488
|
|
|
$component .= $this->createTzurl(); |
7489
|
|
|
$component .= $this->createDtstart(); |
7490
|
|
|
$component .= $this->createTzoffsetfrom(); |
7491
|
|
|
$component .= $this->createTzoffsetto(); |
7492
|
|
|
$component .= $this->createComment(); |
7493
|
|
|
$component .= $this->createRdate(); |
7494
|
|
|
$component .= $this->createRrule(); |
7495
|
|
|
$component .= $this->createTzname(); |
7496
|
|
|
$component .= $this->createXprop(); |
7497
|
|
|
$component .= $this->createSubComponent(); |
7498
|
|
|
$component .= $this->componentEnd1.$objectname.$this->componentEnd2; |
7499
|
|
|
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) { |
7500
|
|
|
foreach( $this->xcaldecl as $localxcaldecl ) |
7501
|
|
|
$xcaldecl[] = $localxcaldecl; |
7502
|
|
|
} |
7503
|
|
|
return $component; |
7504
|
|
|
} |
7505
|
|
|
} |
7506
|
|
|
?> |
|
|
|
|
Adding a
@return
annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.Please refer to the PHP core documentation on constructors.