Version Description
Download this release
Release Info
Developer | theseed |
Plugin | All-in-One Event Calendar |
Version | 1.2.4 |
Comparing to | |
See all releases |
Code changes from version 1.2.3 to 1.2.4
- all-in-one-event-calendar.php +10 -3
- app/helper/class-ai1ec-importer-helper.php +9 -1
- app/view/calendar.php +1 -1
- language/all-in-one-event-calendar.pot +668 -669
- lib/{iCalUtilityFunctions.class.php → iCalcreator-2.10.23/iCalUtilityFunctions.class.php} +0 -0
- lib/{iCalcreator.class.php → iCalcreator-2.10.23/iCalcreator.class.php} +0 -0
- lib/{lgpl.txt → iCalcreator-2.10.23/lgpl.txt} +0 -0
- lib/{releaseNotes-2.10.23.txt → iCalcreator-2.10.23/releaseNotes-2.10.23.txt} +0 -0
- lib/{summary.html → iCalcreator-2.10.23/summary.html} +0 -0
- lib/{using.html → iCalcreator-2.10.23/using.html} +0 -0
- lib/iCalcreator-2.10/iCalUtilityFunctions.class.php +1505 -0
- lib/iCalcreator-2.10/iCalcreator.class.php +6897 -0
- lib/iCalcreator-2.10/lgpl.txt +504 -0
- lib/iCalcreator-2.10/releaseNotes-2.10.txt +82 -0
- lib/iCalcreator-2.10/summary.html +283 -0
- lib/iCalcreator-2.10/using.html +5683 -0
- readme.txt +4 -1
all-in-one-event-calendar.php
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
* Description: An event calendar system with month, week, agenda views, upcoming events widget, color-coded categories, recurrence, and import/export of .ics feeds.
|
6 |
* Author: The Seed Studio
|
7 |
* Author URI: http://theseednetwork.com/
|
8 |
-
* Version: 1.2.
|
9 |
*/ // NOTE: When updating version number also update first line of app/view/calendar.php
|
10 |
@set_time_limit( 0 );
|
11 |
@ini_set( "memory_limit", "256M" );
|
@@ -146,8 +146,15 @@ define( 'AI1EC_EXPORT_URL', "$tmp&controller=ai1ec_exporter_controller&action=ex
|
|
146 |
// ====================================
|
147 |
// = Include iCal parsers and helpers =
|
148 |
// ====================================
|
149 |
-
|
150 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
151 |
require_once( AI1EC_LIB_PATH . '/SG_iCal.php' );
|
152 |
require_once( AI1EC_LIB_PATH . '/helpers/SG_iCal_Line.php' );
|
153 |
require_once( AI1EC_LIB_PATH . '/helpers/SG_iCal_Duration.php' );
|
5 |
* Description: An event calendar system with month, week, agenda views, upcoming events widget, color-coded categories, recurrence, and import/export of .ics feeds.
|
6 |
* Author: The Seed Studio
|
7 |
* Author URI: http://theseednetwork.com/
|
8 |
+
* Version: 1.2.4
|
9 |
*/ // NOTE: When updating version number also update first line of app/view/calendar.php
|
10 |
@set_time_limit( 0 );
|
11 |
@ini_set( "memory_limit", "256M" );
|
146 |
// ====================================
|
147 |
// = Include iCal parsers and helpers =
|
148 |
// ====================================
|
149 |
+
if( version_compare( PHP_VERSION, '5.3.0' ) >= 0 ) {
|
150 |
+
// Parser that requires PHP v5.3.0 or up
|
151 |
+
require_once( AI1EC_LIB_PATH . '/iCalcreator-2.10.23/iCalcreator.class.php' );
|
152 |
+
require_once( AI1EC_LIB_PATH . '/iCalcreator-2.10.23//iCalUtilityFunctions.class.php' );
|
153 |
+
} else {
|
154 |
+
// Parser that works on PHP versions below 5.3.0
|
155 |
+
require_once( AI1EC_LIB_PATH . '/iCalcreator-2.10/iCalcreator.class.php' );
|
156 |
+
require_once( AI1EC_LIB_PATH . '/iCalcreator-2.10/iCalUtilityFunctions.class.php' );
|
157 |
+
}
|
158 |
require_once( AI1EC_LIB_PATH . '/SG_iCal.php' );
|
159 |
require_once( AI1EC_LIB_PATH . '/helpers/SG_iCal_Line.php' );
|
160 |
require_once( AI1EC_LIB_PATH . '/helpers/SG_iCal_Duration.php' );
|
app/helper/class-ai1ec-importer-helper.php
CHANGED
@@ -90,7 +90,15 @@ class Ai1ec_Importer_Helper {
|
|
90 |
$count = 0;
|
91 |
|
92 |
// include ical parser
|
93 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
|
95 |
// set unique id, required if any component UID is missing
|
96 |
$config = array( 'unique_id' => 'ai1ec' );
|
90 |
$count = 0;
|
91 |
|
92 |
// include ical parser
|
93 |
+
if( version_compare( PHP_VERSION, '5.3.0' ) >= 0 ) {
|
94 |
+
// Parser that requires PHP v5.3.0 or up
|
95 |
+
require_once( AI1EC_LIB_PATH . '/iCalcreator-2.10.23/iCalcreator.class.php' );
|
96 |
+
require_once( AI1EC_LIB_PATH . '/iCalcreator-2.10.23//iCalUtilityFunctions.class.php' );
|
97 |
+
} else {
|
98 |
+
// Parser that works on PHP versions below 5.3.0
|
99 |
+
require_once( AI1EC_LIB_PATH . '/iCalcreator-2.10/iCalcreator.class.php' );
|
100 |
+
require_once( AI1EC_LIB_PATH . '/iCalcreator-2.10/iCalUtilityFunctions.class.php' );
|
101 |
+
}
|
102 |
|
103 |
// set unique id, required if any component UID is missing
|
104 |
$config = array( 'unique_id' => 'ai1ec' );
|
app/view/calendar.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<!-- START All-in-One Event Calendar Plugin - Version 1.2.
|
2 |
<table class="ai1ec-calendar-toolbar">
|
3 |
<tbody>
|
4 |
<tr>
|
1 |
+
<!-- START All-in-One Event Calendar Plugin - Version 1.2.4 -->
|
2 |
<table class="ai1ec-calendar-toolbar">
|
3 |
<tbody>
|
4 |
<tr>
|
language/all-in-one-event-calendar.pot
CHANGED
@@ -2,9 +2,9 @@
|
|
2 |
# This file is distributed under the same license as the All-in-One Event Calendar package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
-
"Project-Id-Version: All-in-One Event Calendar 1.2.
|
6 |
"Report-Msgid-Bugs-To: http://wordpress.org/tag/all-in-one-event-calendar\n"
|
7 |
-
"POT-Creation-Date: 2012-01-
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
@@ -12,1216 +12,1215 @@ msgstr ""
|
|
12 |
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
13 |
"Language-Team: LANGUAGE <LL@li.org>\n"
|
14 |
|
15 |
-
#: app/
|
16 |
-
|
17 |
-
#: app/view/row_weekly.php:3
|
18 |
-
msgid "Every"
|
19 |
msgstr ""
|
20 |
|
21 |
-
#: app/
|
22 |
-
|
23 |
-
|
|
|
24 |
msgstr ""
|
25 |
|
26 |
-
#: app/
|
27 |
-
msgid "
|
28 |
msgstr ""
|
29 |
|
30 |
-
#: app/
|
31 |
-
msgid "
|
32 |
msgstr ""
|
33 |
|
34 |
-
#: app/
|
35 |
-
|
|
|
36 |
msgstr ""
|
37 |
|
38 |
-
#: app/
|
39 |
-
msgid "No"
|
40 |
msgstr ""
|
41 |
|
42 |
-
#: app/
|
43 |
-
msgid "
|
44 |
msgstr ""
|
45 |
|
46 |
-
#: app/
|
47 |
-
|
48 |
-
"
|
49 |
-
"
|
50 |
-
msgstr ""
|
|
|
51 |
|
52 |
-
#: app/
|
53 |
-
|
|
|
54 |
msgstr ""
|
55 |
|
56 |
-
#: app/
|
57 |
-
|
|
|
58 |
msgstr ""
|
59 |
|
60 |
-
#: app/
|
61 |
-
|
|
|
62 |
msgstr ""
|
63 |
|
64 |
-
#: app/
|
65 |
-
msgid "
|
66 |
msgstr ""
|
67 |
|
68 |
-
#: app/
|
69 |
-
msgid "
|
70 |
msgstr ""
|
71 |
|
72 |
-
#: app/
|
73 |
-
msgid ""
|
74 |
-
"The price for this event's first ticket will be taken from the Cost field "
|
75 |
-
"above."
|
76 |
msgstr ""
|
77 |
|
78 |
-
|
79 |
-
|
|
|
|
|
|
|
80 |
msgstr ""
|
81 |
|
82 |
-
#: app/
|
83 |
-
msgid "
|
84 |
msgstr ""
|
85 |
|
86 |
-
#: app/
|
87 |
-
|
|
|
88 |
msgstr ""
|
89 |
|
90 |
-
#: app/
|
91 |
-
msgid "
|
92 |
msgstr ""
|
93 |
|
94 |
-
#: app/
|
95 |
-
msgid "
|
96 |
msgstr ""
|
97 |
|
98 |
-
#: app/
|
99 |
-
msgid "
|
100 |
msgstr ""
|
101 |
|
102 |
-
#: app/
|
103 |
-
msgid "
|
104 |
msgstr ""
|
105 |
|
106 |
-
#: app/
|
107 |
-
|
|
|
108 |
msgstr ""
|
109 |
|
110 |
-
#: app/
|
111 |
-
msgid "
|
112 |
msgstr ""
|
113 |
|
114 |
-
#: app/
|
115 |
-
msgid "
|
116 |
msgstr ""
|
117 |
|
118 |
-
#: app/
|
119 |
-
msgid ""
|
120 |
-
"This post was replicated from another site's <a class=\"ai1ec-ics-icon\" "
|
121 |
-
"href=\"%s\" title=\"iCalendar feed\">calendar feed</a>."
|
122 |
msgstr ""
|
123 |
|
124 |
-
#: app/
|
125 |
-
msgid "
|
126 |
msgstr ""
|
127 |
|
128 |
-
#: app/
|
129 |
-
msgid "
|
130 |
msgstr ""
|
131 |
|
132 |
-
|
133 |
-
|
|
|
134 |
msgstr ""
|
135 |
|
136 |
-
#: app/
|
137 |
-
msgid "Event
|
138 |
msgstr ""
|
139 |
|
140 |
-
#: app/
|
141 |
-
msgid "
|
142 |
msgstr ""
|
143 |
|
144 |
-
#: app/
|
145 |
-
msgid "
|
146 |
msgstr ""
|
147 |
|
148 |
-
#: app/
|
149 |
-
msgid "
|
|
|
|
|
150 |
msgstr ""
|
151 |
|
152 |
-
#.
|
153 |
-
|
154 |
-
|
155 |
-
msgid "The Seed Studio"
|
156 |
msgstr ""
|
157 |
|
158 |
-
#: app/
|
159 |
-
msgid ""
|
160 |
-
"The Seed Studio provides web development and support services for clients "
|
161 |
-
"and web developers."
|
162 |
msgstr ""
|
163 |
|
164 |
-
#: app/
|
165 |
-
|
|
|
166 |
msgstr ""
|
167 |
|
168 |
-
#: app/
|
169 |
-
|
|
|
170 |
msgstr ""
|
171 |
|
172 |
-
#: app/
|
173 |
-
|
|
|
174 |
msgstr ""
|
175 |
|
176 |
-
#: app/
|
177 |
-
|
|
|
178 |
msgstr ""
|
179 |
|
180 |
-
#: app/
|
181 |
-
|
182 |
-
"
|
183 |
-
"this plugin, for your website or for any of your Internet marketing needs "
|
184 |
-
"(we can really help!)."
|
185 |
msgstr ""
|
186 |
|
187 |
-
#: app/
|
188 |
-
|
189 |
-
"
|
190 |
-
"from other WordPress users, visit the plugin's forum."
|
191 |
msgstr ""
|
192 |
|
193 |
-
#: app/
|
194 |
-
|
|
|
195 |
msgstr ""
|
196 |
|
197 |
-
#: app/
|
198 |
-
msgid ""
|
199 |
-
"This plugin is offered free to the Wordpress Community under the GPL3 "
|
200 |
-
"license. All we ask is that you:"
|
201 |
msgstr ""
|
202 |
|
203 |
-
#: app/
|
204 |
-
msgid ""
|
205 |
-
"<a href=\"http://wordpress.org/extend/plugins/all-in-one-event-calendar/\" "
|
206 |
-
"target=\"_blank\">Give it a five-star rating on wordpress.org</a> (if you "
|
207 |
-
"think it deserves it!)"
|
208 |
msgstr ""
|
209 |
|
210 |
-
#: app/
|
211 |
-
msgid "
|
212 |
msgstr ""
|
213 |
|
214 |
-
#: app/
|
215 |
-
msgid "
|
216 |
msgstr ""
|
217 |
|
218 |
-
#: app/
|
219 |
-
msgid "
|
220 |
msgstr ""
|
221 |
|
222 |
-
#: app/
|
223 |
-
msgid "
|
224 |
msgstr ""
|
225 |
|
226 |
-
#: app/
|
227 |
-
|
228 |
-
msgid "Category Color"
|
229 |
msgstr ""
|
230 |
|
231 |
-
#: app/
|
232 |
-
|
233 |
-
msgid "Events in this category will be identified by this color"
|
234 |
msgstr ""
|
235 |
|
236 |
-
#: app/
|
237 |
-
|
238 |
-
msgid "When:"
|
239 |
msgstr ""
|
240 |
|
241 |
-
#: app/
|
242 |
-
msgid "
|
243 |
msgstr ""
|
244 |
|
245 |
-
#: app/
|
246 |
-
msgid "
|
247 |
msgstr ""
|
248 |
|
249 |
-
#: app/
|
250 |
-
|
251 |
-
msgid "Where:"
|
252 |
msgstr ""
|
253 |
|
254 |
-
#: app/
|
255 |
-
msgid "
|
256 |
msgstr ""
|
257 |
|
258 |
-
#: app/
|
259 |
-
msgid "
|
260 |
msgstr ""
|
261 |
|
262 |
-
#: app/
|
263 |
-
msgid "
|
264 |
msgstr ""
|
265 |
|
266 |
-
#: app/
|
267 |
-
#: app/
|
268 |
-
|
|
|
|
|
|
|
269 |
msgstr ""
|
270 |
|
271 |
-
#: app/
|
272 |
-
#: app/
|
273 |
-
|
|
|
|
|
274 |
msgstr ""
|
275 |
|
276 |
-
#: app/
|
277 |
-
#: app/
|
278 |
-
|
|
|
|
|
279 |
msgstr ""
|
280 |
|
281 |
-
#: app/
|
282 |
-
|
|
|
|
|
|
|
283 |
msgstr ""
|
284 |
|
285 |
-
#: app/
|
286 |
-
|
287 |
-
msgid "On"
|
288 |
msgstr ""
|
289 |
|
290 |
-
#: app/
|
291 |
-
msgid "
|
292 |
msgstr ""
|
293 |
|
294 |
-
#: app/
|
295 |
-
msgid "
|
296 |
msgstr ""
|
297 |
|
298 |
-
#: app/
|
299 |
-
msgid "
|
300 |
msgstr ""
|
301 |
|
302 |
-
#: app/
|
303 |
-
msgid "
|
304 |
msgstr ""
|
305 |
|
306 |
-
#: app/
|
307 |
-
|
308 |
-
msgid "(all-day)"
|
309 |
msgstr ""
|
310 |
|
311 |
-
#: app/
|
312 |
-
|
|
|
313 |
msgstr ""
|
314 |
|
315 |
-
#: app/
|
316 |
-
|
|
|
|
|
|
|
317 |
msgstr ""
|
318 |
|
319 |
-
#: app/
|
320 |
-
|
|
|
|
|
321 |
msgstr ""
|
322 |
|
323 |
-
#: app/
|
324 |
-
|
|
|
|
|
|
|
|
|
325 |
msgstr ""
|
326 |
|
327 |
-
#: app/
|
328 |
-
|
|
|
|
|
329 |
msgstr ""
|
330 |
|
331 |
-
#: app/
|
332 |
-
|
|
|
|
|
|
|
333 |
msgstr ""
|
334 |
|
335 |
-
#: app/
|
336 |
-
msgid "
|
337 |
msgstr ""
|
338 |
|
339 |
-
#: app/
|
340 |
-
msgid "
|
341 |
msgstr ""
|
342 |
|
343 |
-
#: app/
|
344 |
-
msgid "
|
345 |
msgstr ""
|
346 |
|
347 |
-
#: app/
|
348 |
-
|
349 |
-
#: app/helper/class-ai1ec-events-helper.php:573
|
350 |
-
#: app/helper/class-ai1ec-events-helper.php:1502
|
351 |
-
#: app/helper/class-ai1ec-settings-helper.php:237
|
352 |
-
msgid "Daily"
|
353 |
msgstr ""
|
354 |
|
355 |
-
#: app/
|
356 |
-
|
357 |
-
#: app/helper/class-ai1ec-events-helper.php:574
|
358 |
-
#: app/helper/class-ai1ec-events-helper.php:1514
|
359 |
-
msgid "Weekly"
|
360 |
msgstr ""
|
361 |
|
362 |
-
#: app/
|
363 |
-
|
364 |
-
#: app/helper/class-ai1ec-events-helper.php:575
|
365 |
-
#: app/helper/class-ai1ec-events-helper.php:1526
|
366 |
-
msgid "Monthly"
|
367 |
msgstr ""
|
368 |
|
369 |
-
#: app/
|
370 |
-
|
371 |
-
#: app/helper/class-ai1ec-events-helper.php:576
|
372 |
-
#: app/helper/class-ai1ec-events-helper.php:1538
|
373 |
-
msgid "Yearly"
|
374 |
msgstr ""
|
375 |
|
376 |
-
#: app/
|
377 |
-
msgid "
|
378 |
msgstr ""
|
379 |
|
380 |
-
#: app/
|
381 |
-
msgid "
|
382 |
msgstr ""
|
383 |
|
384 |
-
#: app/
|
385 |
-
|
386 |
-
msgid "On date"
|
387 |
msgstr ""
|
388 |
|
389 |
-
#: app/
|
390 |
-
msgid "
|
391 |
msgstr ""
|
392 |
|
393 |
-
#: app/
|
394 |
-
|
|
|
395 |
msgstr ""
|
396 |
|
397 |
-
#: app/
|
398 |
-
|
|
|
399 |
msgstr ""
|
400 |
|
401 |
-
#: app/
|
402 |
-
msgid "
|
403 |
msgstr ""
|
404 |
|
405 |
-
#: app/
|
406 |
-
msgid "
|
407 |
msgstr ""
|
408 |
|
409 |
-
#: app/
|
410 |
-
msgid "
|
411 |
msgstr ""
|
412 |
|
413 |
-
#: app/
|
414 |
-
msgid "
|
415 |
msgstr ""
|
416 |
|
417 |
-
#: app/
|
418 |
-
msgid "
|
419 |
msgstr ""
|
420 |
|
421 |
-
#: app/
|
422 |
-
msgid "
|
423 |
msgstr ""
|
424 |
|
425 |
-
#: app/
|
426 |
-
msgid "
|
427 |
msgstr ""
|
428 |
|
429 |
-
#: app/
|
430 |
-
msgid "
|
431 |
msgstr ""
|
432 |
|
433 |
-
#: app/
|
434 |
-
msgid "
|
435 |
msgstr ""
|
436 |
|
437 |
-
#: app/
|
438 |
-
|
439 |
-
msgid "Month"
|
440 |
msgstr ""
|
441 |
|
442 |
-
#: app/
|
443 |
-
|
444 |
-
msgid "
|
445 |
msgstr ""
|
446 |
|
447 |
-
#: app/
|
448 |
-
|
449 |
-
|
450 |
-
msgid "Agenda"
|
451 |
msgstr ""
|
452 |
|
453 |
-
#: app/
|
454 |
-
|
|
|
455 |
msgstr ""
|
456 |
|
457 |
-
#: app/
|
458 |
-
|
|
|
459 |
msgstr ""
|
460 |
|
461 |
-
#: app/
|
462 |
-
msgid "
|
463 |
msgstr ""
|
464 |
|
465 |
-
#: app/
|
466 |
-
msgid "
|
|
|
|
|
467 |
msgstr ""
|
468 |
|
469 |
-
#: app/
|
470 |
-
msgid "
|
471 |
msgstr ""
|
472 |
|
473 |
-
#: app/
|
474 |
-
msgid "
|
475 |
msgstr ""
|
476 |
|
477 |
-
#: app/
|
478 |
-
msgid ""
|
479 |
-
"Subscribe to this calendar using your favourite calendar program (iCal, "
|
480 |
-
"Outlook, etc.)"
|
481 |
msgstr ""
|
482 |
|
483 |
-
#: app/
|
484 |
-
msgid "
|
485 |
msgstr ""
|
486 |
|
487 |
-
#: app/
|
488 |
-
msgid "
|
|
|
|
|
|
|
489 |
msgstr ""
|
490 |
|
491 |
-
#: app/
|
492 |
-
msgid "
|
|
|
|
|
493 |
msgstr ""
|
494 |
|
495 |
-
#: app/
|
496 |
-
msgid "
|
|
|
|
|
497 |
msgstr ""
|
498 |
|
499 |
-
#: app/
|
500 |
-
msgid "
|
|
|
|
|
501 |
msgstr ""
|
502 |
|
503 |
-
#: app/
|
504 |
-
msgid "
|
|
|
|
|
505 |
msgstr ""
|
506 |
|
507 |
-
#: app/
|
508 |
-
|
|
|
509 |
msgstr ""
|
510 |
|
511 |
-
#: app/
|
512 |
-
msgid "
|
513 |
msgstr ""
|
514 |
|
515 |
-
#: app/
|
516 |
-
msgid "
|
517 |
msgstr ""
|
518 |
|
519 |
-
#: app/
|
520 |
-
msgid "Auto-
|
521 |
msgstr ""
|
522 |
|
523 |
-
#: app/
|
524 |
-
msgid "
|
525 |
msgstr ""
|
526 |
|
527 |
-
#: app/view/
|
528 |
-
|
|
|
529 |
msgstr ""
|
530 |
|
531 |
-
#: app/
|
532 |
-
|
|
|
533 |
msgstr ""
|
534 |
|
535 |
-
#: app/
|
536 |
-
msgid "
|
537 |
msgstr ""
|
538 |
|
539 |
-
#: app/
|
540 |
-
msgid "
|
541 |
msgstr ""
|
542 |
|
543 |
-
#: app/
|
544 |
-
msgid "
|
545 |
msgstr ""
|
546 |
|
547 |
-
#: app/
|
548 |
-
msgid "
|
549 |
msgstr ""
|
550 |
|
551 |
-
#: app/
|
552 |
-
msgid "
|
553 |
msgstr ""
|
554 |
|
555 |
-
#: app/
|
556 |
-
msgid "
|
557 |
msgstr ""
|
558 |
|
559 |
-
#: app/
|
560 |
-
msgid "
|
561 |
msgstr ""
|
562 |
|
563 |
-
#: app/view/
|
564 |
-
msgid "
|
565 |
msgstr ""
|
566 |
|
567 |
-
#: app/view/
|
568 |
-
msgid "
|
569 |
msgstr ""
|
570 |
|
571 |
-
#: app/view/
|
572 |
-
msgid "
|
573 |
msgstr ""
|
574 |
|
575 |
-
#: app/view/
|
576 |
-
msgid "
|
577 |
msgstr ""
|
578 |
|
579 |
-
#: app/view/
|
580 |
-
|
|
|
581 |
msgstr ""
|
582 |
|
583 |
-
#: app/view/
|
584 |
-
|
|
|
585 |
msgstr ""
|
586 |
|
587 |
-
#: app/view/
|
588 |
-
msgid "
|
589 |
msgstr ""
|
590 |
|
591 |
#: app/view/feed_row.php:9
|
592 |
msgid "Event category:"
|
593 |
msgstr ""
|
594 |
|
595 |
-
#: app/view/feed_row.php:
|
596 |
-
msgid "
|
597 |
msgstr ""
|
598 |
|
599 |
-
#: app/view/feed_row.php:
|
600 |
-
|
601 |
-
msgid "Update"
|
602 |
msgstr ""
|
603 |
|
604 |
-
#: app/view/
|
605 |
-
|
606 |
-
msgid "Flush 1 event"
|
607 |
-
msgid_plural "Flush %s events"
|
608 |
-
msgstr[0] ""
|
609 |
-
msgstr[1] ""
|
610 |
-
|
611 |
-
#: app/view/box_general_settings.php:1
|
612 |
-
msgid "Viewing Events"
|
613 |
msgstr ""
|
614 |
|
615 |
-
#: app/view/
|
616 |
-
msgid "
|
617 |
msgstr ""
|
618 |
|
619 |
-
#: app/view/
|
620 |
-
msgid "
|
621 |
msgstr ""
|
622 |
|
623 |
-
#: app/view/
|
624 |
-
msgid "
|
625 |
msgstr ""
|
626 |
|
627 |
-
#: app/view/
|
628 |
-
msgid "
|
629 |
msgstr ""
|
630 |
|
631 |
-
#: app/view/
|
632 |
-
msgid ""
|
633 |
-
"Optional. Provide a <a href=\"http://api.jquery.com/category/selectors/\" "
|
634 |
-
"target=\"_blank\">jQuery selector</a> that evaluates to a single DOM "
|
635 |
-
"element. Replaces any existing markup found within target. If left empty, "
|
636 |
-
"calendar is shown in normal page content container."
|
637 |
msgstr ""
|
638 |
|
639 |
-
#: app/view/
|
640 |
-
|
|
|
641 |
msgstr ""
|
642 |
|
643 |
-
#: app/view/
|
644 |
-
msgid "
|
645 |
msgstr ""
|
646 |
|
647 |
-
#: app/view/
|
648 |
-
msgid "
|
649 |
msgstr ""
|
650 |
|
651 |
-
#: app/view/
|
652 |
-
msgid "
|
653 |
msgstr ""
|
654 |
|
655 |
-
#: app/view/
|
656 |
-
msgid "
|
657 |
msgstr ""
|
658 |
|
659 |
-
#: app/view/
|
660 |
-
|
661 |
-
|
662 |
-
"privileged users"
|
663 |
msgstr ""
|
664 |
|
665 |
-
#: app/view/
|
666 |
-
msgid ""
|
667 |
-
"Hide <strong>Subscribe</strong>/<strong>Add to Calendar</strong> buttons in "
|
668 |
-
"calendar and single event views"
|
669 |
msgstr ""
|
670 |
|
671 |
-
#: app/view/
|
672 |
-
msgid "
|
673 |
msgstr ""
|
674 |
|
675 |
-
#: app/view/
|
676 |
-
msgid ""
|
677 |
-
"Use the configured <strong>region</strong> (WordPress locale) to bias the "
|
678 |
-
"address autocomplete function"
|
679 |
msgstr ""
|
680 |
|
681 |
-
#: app/view/
|
682 |
-
msgid "
|
683 |
msgstr ""
|
684 |
|
685 |
-
#: app/view/
|
686 |
-
msgid "
|
687 |
msgstr ""
|
688 |
|
689 |
-
#: app/view/
|
690 |
-
msgid "
|
691 |
msgstr ""
|
692 |
|
693 |
-
#: app/view/
|
694 |
-
msgid "
|
695 |
msgstr ""
|
696 |
|
697 |
-
#: app/view/
|
698 |
-
msgid "
|
699 |
msgstr ""
|
700 |
|
701 |
-
#: app/view/
|
702 |
-
msgid "
|
703 |
msgstr ""
|
704 |
|
705 |
-
#: app/view/
|
706 |
-
|
|
|
707 |
msgstr ""
|
708 |
|
709 |
-
#: app/view/
|
710 |
-
|
|
|
711 |
msgstr ""
|
712 |
|
713 |
-
#: app/
|
714 |
-
|
|
|
|
|
715 |
msgstr ""
|
716 |
|
717 |
-
#: app/
|
718 |
-
|
|
|
719 |
msgstr ""
|
720 |
|
721 |
-
#: app/
|
722 |
-
msgid "
|
723 |
msgstr ""
|
724 |
|
725 |
-
#: app/
|
726 |
-
msgid "
|
727 |
msgstr ""
|
728 |
|
729 |
-
#: app/
|
730 |
-
msgid "
|
731 |
msgstr ""
|
732 |
|
733 |
-
#: app/
|
734 |
-
msgid "
|
735 |
msgstr ""
|
736 |
|
737 |
-
#: app/
|
738 |
-
msgid "
|
739 |
msgstr ""
|
740 |
|
741 |
-
#: app/
|
742 |
-
msgid "
|
|
|
|
|
743 |
msgstr ""
|
744 |
-
|
745 |
-
#: app/
|
746 |
-
msgid "
|
747 |
msgstr ""
|
748 |
|
749 |
-
|
750 |
-
|
751 |
-
msgid "Event restored to revision from %s"
|
752 |
msgstr ""
|
753 |
|
754 |
-
#: app/
|
755 |
-
msgid "
|
756 |
msgstr ""
|
757 |
|
758 |
-
#: app/
|
759 |
-
msgid "
|
760 |
msgstr ""
|
761 |
|
762 |
-
#: app/
|
763 |
-
msgid "
|
764 |
msgstr ""
|
765 |
|
766 |
-
#: app/
|
767 |
msgid ""
|
768 |
-
"
|
769 |
-
"
|
770 |
msgstr ""
|
771 |
|
772 |
-
|
773 |
-
|
774 |
-
msgid "M j, Y @ G:i"
|
775 |
msgstr ""
|
776 |
|
777 |
-
#: app/
|
778 |
-
msgid "
|
779 |
msgstr ""
|
780 |
|
781 |
-
#: app/
|
782 |
-
msgid "
|
783 |
msgstr ""
|
784 |
|
785 |
-
#: app/
|
786 |
-
msgid ""
|
787 |
-
"Imports events created using The Events Calendar plugin into the All-in-One "
|
788 |
-
"Event Calendar"
|
789 |
msgstr ""
|
790 |
|
791 |
-
#: app/
|
792 |
-
|
793 |
-
msgid "Settings"
|
794 |
msgstr ""
|
795 |
|
796 |
-
|
797 |
-
|
798 |
-
#: app/helper/class-ai1ec-calendar-helper.php:717
|
799 |
-
#: app/helper/class-ai1ec-calendar-helper.php:726
|
800 |
-
msgid "Week of %s"
|
801 |
msgstr ""
|
802 |
|
803 |
-
#: app/
|
804 |
-
msgid "
|
805 |
msgstr ""
|
806 |
|
807 |
-
#: app/
|
808 |
-
msgid "
|
809 |
msgstr ""
|
810 |
|
811 |
-
#: app/
|
812 |
-
msgid "
|
813 |
msgstr ""
|
814 |
|
815 |
-
#: app/
|
816 |
-
|
817 |
-
msgid "Invalid ICS feed ID"
|
818 |
msgstr ""
|
819 |
|
820 |
-
#: app/
|
821 |
-
msgid "
|
822 |
msgstr ""
|
823 |
|
824 |
-
#: app/
|
825 |
-
msgid "
|
826 |
msgstr ""
|
827 |
|
828 |
-
|
829 |
-
|
830 |
-
|
|
|
831 |
msgstr ""
|
832 |
|
833 |
-
#: app/
|
834 |
-
|
835 |
-
|
|
|
836 |
msgstr ""
|
837 |
|
838 |
-
#: app/
|
839 |
-
|
840 |
-
msgid "ICS Import Settings"
|
841 |
msgstr ""
|
842 |
|
843 |
-
#: app/
|
844 |
-
msgid "<
|
845 |
msgstr ""
|
846 |
|
847 |
-
#: app/
|
848 |
-
msgid "
|
849 |
msgstr ""
|
850 |
|
851 |
-
#: app/
|
852 |
-
msgid "
|
853 |
msgstr ""
|
854 |
|
855 |
-
#: app/
|
856 |
-
msgid "
|
|
|
|
|
|
|
857 |
msgstr ""
|
858 |
|
859 |
-
#: app/
|
860 |
-
|
861 |
-
|
|
|
862 |
msgstr ""
|
863 |
|
864 |
-
#: app/
|
865 |
-
|
866 |
-
msgid "Every day"
|
867 |
msgstr ""
|
868 |
|
869 |
-
#: app/
|
870 |
-
|
871 |
-
|
|
|
872 |
msgstr ""
|
873 |
|
874 |
-
#: app/
|
875 |
-
|
876 |
-
|
|
|
|
|
877 |
msgstr ""
|
878 |
|
879 |
-
#: app/
|
880 |
-
|
881 |
-
msgid "Every year"
|
882 |
msgstr ""
|
883 |
|
884 |
-
#: app/
|
885 |
-
|
886 |
-
msgid "Custom..."
|
887 |
msgstr ""
|
888 |
|
889 |
-
#: app/
|
890 |
-
msgid "
|
891 |
msgstr ""
|
892 |
|
893 |
-
#: app/
|
894 |
-
msgid "
|
895 |
msgstr ""
|
896 |
|
897 |
-
#: app/
|
898 |
-
msgid "
|
899 |
msgstr ""
|
900 |
|
901 |
-
#: app/
|
902 |
-
msgid "
|
903 |
msgstr ""
|
904 |
|
905 |
-
#: app/
|
906 |
-
msgid "
|
907 |
msgstr ""
|
908 |
|
909 |
-
#: app/
|
910 |
-
msgid "
|
911 |
msgstr ""
|
912 |
|
913 |
-
#: app/
|
914 |
-
msgid "
|
915 |
msgstr ""
|
916 |
|
917 |
-
#: app/
|
918 |
-
msgid "
|
919 |
msgstr ""
|
920 |
|
921 |
-
#: app/
|
922 |
-
msgid "
|
923 |
msgstr ""
|
924 |
|
925 |
-
#: app/
|
926 |
-
msgid "
|
|
|
|
|
|
|
|
|
927 |
msgstr ""
|
928 |
|
929 |
-
#: app/
|
930 |
-
msgid "
|
931 |
msgstr ""
|
932 |
|
933 |
-
#: app/
|
934 |
-
msgid "
|
935 |
msgstr ""
|
936 |
|
937 |
-
#: app/
|
938 |
-
msgid "
|
939 |
msgstr ""
|
940 |
|
941 |
-
#: app/
|
942 |
-
msgid "
|
943 |
msgstr ""
|
944 |
|
945 |
-
#: app/
|
946 |
-
msgid "
|
947 |
msgstr ""
|
948 |
|
949 |
-
#: app/
|
950 |
-
msgid "
|
|
|
|
|
951 |
msgstr ""
|
952 |
|
953 |
-
#: app/
|
954 |
-
msgid "
|
|
|
|
|
955 |
msgstr ""
|
956 |
|
957 |
-
#: app/
|
958 |
-
msgid "
|
959 |
msgstr ""
|
960 |
|
961 |
-
#: app/
|
962 |
-
msgid "
|
|
|
|
|
963 |
msgstr ""
|
964 |
|
965 |
-
#: app/
|
966 |
-
msgid "
|
967 |
msgstr ""
|
968 |
|
969 |
-
#: app/
|
970 |
-
msgid "
|
971 |
msgstr ""
|
972 |
|
973 |
-
#: app/
|
974 |
-
|
975 |
-
#: app/helper/class-ai1ec-events-helper.php:1398
|
976 |
-
msgctxt "Recurrence editor - weekly tab"
|
977 |
-
msgid "on"
|
978 |
msgstr ""
|
979 |
|
980 |
-
#: app/
|
981 |
-
|
982 |
-
#: app/helper/class-ai1ec-events-helper.php:1453
|
983 |
-
msgid "and"
|
984 |
msgstr ""
|
985 |
|
986 |
-
#: app/
|
987 |
-
|
988 |
-
#: app/helper/class-ai1ec-events-helper.php:1424
|
989 |
-
#: app/helper/class-ai1ec-events-helper.php:1435
|
990 |
-
msgctxt "Recurrence editor - monthly tab"
|
991 |
-
msgid "on"
|
992 |
msgstr ""
|
993 |
|
994 |
-
#: app/
|
995 |
-
|
996 |
-
#: app/helper/class-ai1ec-events-helper.php:1424
|
997 |
-
msgid "of the month"
|
998 |
msgstr ""
|
999 |
|
1000 |
-
#: app/
|
1001 |
-
|
1002 |
-
#: app/helper/class-ai1ec-events-helper.php:1463
|
1003 |
-
msgctxt "Recurrence editor - yearly tab"
|
1004 |
-
msgid "on"
|
1005 |
msgstr ""
|
1006 |
|
1007 |
-
#: app/
|
1008 |
-
msgid "
|
|
|
|
|
1009 |
msgstr ""
|
1010 |
|
1011 |
-
#: app/
|
1012 |
-
msgid "
|
1013 |
msgstr ""
|
1014 |
|
1015 |
-
#: app/
|
1016 |
-
msgid "
|
1017 |
msgstr ""
|
1018 |
|
1019 |
-
#: app/
|
1020 |
-
msgid "
|
1021 |
msgstr ""
|
1022 |
|
1023 |
-
#: app/
|
1024 |
-
msgid "
|
1025 |
msgstr ""
|
1026 |
|
1027 |
-
#: app/
|
1028 |
-
msgid "
|
1029 |
msgstr ""
|
1030 |
|
1031 |
-
#: app/
|
1032 |
-
msgid "
|
1033 |
msgstr ""
|
1034 |
|
1035 |
-
#: app/
|
1036 |
-
msgid "
|
1037 |
msgstr ""
|
1038 |
|
1039 |
-
#: app/
|
1040 |
-
msgid "
|
1041 |
msgstr ""
|
1042 |
|
1043 |
-
#: app/
|
1044 |
-
msgid "
|
1045 |
msgstr ""
|
1046 |
|
1047 |
-
#: app/
|
1048 |
-
msgid "
|
1049 |
msgstr ""
|
1050 |
|
1051 |
-
#: app/
|
1052 |
-
|
1053 |
-
msgid "M j"
|
1054 |
msgstr ""
|
1055 |
|
1056 |
-
#: app/
|
1057 |
-
msgid "
|
1058 |
msgstr ""
|
1059 |
|
1060 |
-
#: app/
|
1061 |
-
msgid "
|
1062 |
msgstr ""
|
1063 |
|
1064 |
-
#: app/
|
1065 |
-
msgid "
|
1066 |
msgstr ""
|
1067 |
|
1068 |
-
#: app/
|
1069 |
-
msgid "
|
1070 |
msgstr ""
|
1071 |
|
1072 |
-
#: app/
|
1073 |
-
msgid "
|
1074 |
msgstr ""
|
1075 |
|
1076 |
-
#: app/
|
1077 |
-
|
|
|
1078 |
msgstr ""
|
1079 |
|
1080 |
-
#: app/
|
1081 |
-
msgid "
|
1082 |
msgstr ""
|
1083 |
|
1084 |
-
#: app/
|
1085 |
-
msgid "
|
1086 |
msgstr ""
|
1087 |
|
1088 |
-
#: app/
|
1089 |
-
msgid "
|
1090 |
msgstr ""
|
1091 |
|
1092 |
-
#: app/
|
1093 |
-
msgid "
|
1094 |
msgstr ""
|
1095 |
|
1096 |
-
#: app/
|
1097 |
-
msgid "
|
|
|
|
|
1098 |
msgstr ""
|
1099 |
|
1100 |
-
#: app/
|
1101 |
-
|
1102 |
-
msgid "Events"
|
1103 |
msgstr ""
|
1104 |
|
1105 |
-
#: app/
|
1106 |
-
|
1107 |
-
msgid "Event"
|
1108 |
msgstr ""
|
1109 |
|
1110 |
-
#: app/
|
1111 |
-
msgid "
|
1112 |
msgstr ""
|
1113 |
|
1114 |
-
#: app/
|
1115 |
-
msgid "
|
1116 |
msgstr ""
|
1117 |
|
1118 |
-
#: app/
|
1119 |
-
msgid "
|
1120 |
msgstr ""
|
1121 |
|
1122 |
-
#: app/
|
1123 |
-
msgid "
|
1124 |
msgstr ""
|
1125 |
|
1126 |
-
#: app/
|
1127 |
-
msgid "
|
1128 |
msgstr ""
|
1129 |
|
1130 |
-
#: app/
|
1131 |
-
msgid "
|
1132 |
msgstr ""
|
1133 |
|
1134 |
-
#: app/
|
1135 |
-
msgid "No
|
1136 |
msgstr ""
|
1137 |
|
1138 |
-
#: app/
|
1139 |
-
msgid "
|
1140 |
msgstr ""
|
1141 |
|
1142 |
-
#: app/
|
1143 |
-
msgid "
|
1144 |
msgstr ""
|
1145 |
|
1146 |
-
#: app/
|
1147 |
-
msgid "
|
1148 |
msgstr ""
|
1149 |
|
1150 |
-
#: app/
|
1151 |
-
|
1152 |
-
msgid "Event Categories"
|
1153 |
msgstr ""
|
1154 |
|
1155 |
-
#: app/
|
1156 |
-
|
1157 |
-
msgid "Event Category"
|
1158 |
msgstr ""
|
1159 |
|
1160 |
-
#: app/
|
1161 |
-
|
1162 |
-
msgid "Event Tags"
|
1163 |
msgstr ""
|
1164 |
|
1165 |
-
#: app/
|
1166 |
-
|
1167 |
-
msgid "Event Tag"
|
1168 |
msgstr ""
|
1169 |
|
1170 |
-
#: app/
|
1171 |
-
msgid "
|
1172 |
msgstr ""
|
1173 |
|
1174 |
-
#: app/
|
1175 |
-
msgid ""
|
1176 |
-
"All Events <span class=\"update-plugins count-%d\" title=\"%d Pending Events"
|
1177 |
-
"\"><span class=\"update-count\">%d</span></span>"
|
1178 |
msgstr ""
|
1179 |
|
1180 |
-
#: app/
|
1181 |
-
msgid "
|
1182 |
msgstr ""
|
1183 |
|
1184 |
-
#: app/
|
1185 |
-
msgid "
|
1186 |
msgstr ""
|
1187 |
|
1188 |
-
#: app/
|
1189 |
-
msgid "
|
1190 |
msgstr ""
|
1191 |
|
1192 |
-
#: app/
|
1193 |
-
msgid "
|
1194 |
msgstr ""
|
1195 |
|
1196 |
-
#: app/
|
1197 |
-
msgid ""
|
1198 |
-
"%sTo set up the plugin: %s 1. Select an option in the <strong>Calendar page</"
|
1199 |
-
"strong> dropdown list. %s 2. Select an option in the <strong>Timezone</"
|
1200 |
-
"strong> dropdown list. %s 3. Click <strong>Update Settings</strong>. %s"
|
1201 |
msgstr ""
|
1202 |
|
1203 |
-
#: app/
|
1204 |
-
msgid ""
|
1205 |
-
"To set up the plugin: Select an option in the <strong>Calendar page</strong> "
|
1206 |
-
"dropdown list, the click <strong>Update Settings</strong>."
|
1207 |
msgstr ""
|
1208 |
|
1209 |
-
#: app/
|
1210 |
-
msgid ""
|
1211 |
-
"To set up the plugin: Select an option in the <strong>Timezone</strong> "
|
1212 |
-
"dropdown list, the click <strong>Update Settings</strong>."
|
1213 |
msgstr ""
|
1214 |
|
1215 |
-
#: app/
|
1216 |
-
|
1217 |
-
|
1218 |
-
"here to set it up now »</a>"
|
1219 |
msgstr ""
|
1220 |
|
1221 |
-
#: app/
|
1222 |
-
|
1223 |
-
"
|
1224 |
-
|
|
|
|
|
|
|
1225 |
msgstr ""
|
1226 |
|
1227 |
#. Plugin Name of the plugin/theme
|
2 |
# This file is distributed under the same license as the All-in-One Event Calendar package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
+
"Project-Id-Version: All-in-One Event Calendar 1.2.4\n"
|
6 |
"Report-Msgid-Bugs-To: http://wordpress.org/tag/all-in-one-event-calendar\n"
|
7 |
+
"POT-Creation-Date: 2012-01-19 19:04:49+00:00\n"
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
12 |
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
13 |
"Language-Team: LANGUAGE <LL@li.org>\n"
|
14 |
|
15 |
+
#: app/controller/class-ai1ec-importer-controller.php:91
|
16 |
+
msgid "The Events Calendar → All-in-One Event Calendar"
|
|
|
|
|
17 |
msgstr ""
|
18 |
|
19 |
+
#: app/controller/class-ai1ec-importer-controller.php:92
|
20 |
+
msgid ""
|
21 |
+
"Imports events created using The Events Calendar plugin into the All-in-One "
|
22 |
+
"Event Calendar"
|
23 |
msgstr ""
|
24 |
|
25 |
+
#: app/controller/class-ai1ec-settings-controller.php:82
|
26 |
+
msgid "Settings Updated."
|
27 |
msgstr ""
|
28 |
|
29 |
+
#: app/controller/class-ai1ec-settings-controller.php:173
|
30 |
+
msgid "Flushed %d events"
|
31 |
msgstr ""
|
32 |
|
33 |
+
#: app/controller/class-ai1ec-settings-controller.php:181
|
34 |
+
#: app/controller/class-ai1ec-settings-controller.php:231
|
35 |
+
msgid "Invalid ICS feed ID"
|
36 |
msgstr ""
|
37 |
|
38 |
+
#: app/controller/class-ai1ec-settings-controller.php:216
|
39 |
+
msgid "No events were found"
|
40 |
msgstr ""
|
41 |
|
42 |
+
#: app/controller/class-ai1ec-settings-controller.php:221
|
43 |
+
msgid "Imported %d events"
|
44 |
msgstr ""
|
45 |
|
46 |
+
#: app/controller/class-ai1ec-settings-controller.php:222
|
47 |
+
#: app/view/feed_row.php:22
|
48 |
+
msgid "Flush 1 event"
|
49 |
+
msgid_plural "Flush %s events"
|
50 |
+
msgstr[0] ""
|
51 |
+
msgstr[1] ""
|
52 |
|
53 |
+
#: app/controller/class-ai1ec-settings-controller.php:274
|
54 |
+
msgctxt "meta box"
|
55 |
+
msgid "General Settings"
|
56 |
msgstr ""
|
57 |
|
58 |
+
#: app/controller/class-ai1ec-settings-controller.php:282
|
59 |
+
msgctxt "meta box"
|
60 |
+
msgid "The Seed Studio Support"
|
61 |
msgstr ""
|
62 |
|
63 |
+
#: app/controller/class-ai1ec-settings-controller.php:289
|
64 |
+
msgctxt "meta box"
|
65 |
+
msgid "ICS Import Settings"
|
66 |
msgstr ""
|
67 |
|
68 |
+
#: app/controller/class-ai1ec-settings-controller.php:338
|
69 |
+
msgid "<a href=\"%s\">Settings</a>"
|
70 |
msgstr ""
|
71 |
|
72 |
+
#: app/controller/class-ai1ec-settings-controller.php:352
|
73 |
+
msgid "<a href=\"%s\" target=\"_blank\">Donate</a>"
|
74 |
msgstr ""
|
75 |
|
76 |
+
#: app/controller/class-ai1ec-settings-controller.php:353
|
77 |
+
msgid "<a href=\"%s\" target=\"_blank\">Get Support</a>"
|
|
|
|
|
78 |
msgstr ""
|
79 |
|
80 |
+
#. translators: "%s" represents the week's starting date
|
81 |
+
#: app/controller/class-ai1ec-calendar-controller.php:326
|
82 |
+
#: app/helper/class-ai1ec-calendar-helper.php:717
|
83 |
+
#: app/helper/class-ai1ec-calendar-helper.php:726
|
84 |
+
msgid "Week of %s"
|
85 |
msgstr ""
|
86 |
|
87 |
+
#: app/controller/class-ai1ec-calendar-controller.php:326
|
88 |
+
msgid "F j"
|
89 |
msgstr ""
|
90 |
|
91 |
+
#: app/controller/class-ai1ec-calendar-controller.php:383
|
92 |
+
#: app/helper/class-ai1ec-settings-helper.php:155 app/view/calendar.php:26
|
93 |
+
msgid "Agenda"
|
94 |
msgstr ""
|
95 |
|
96 |
+
#: app/controller/class-ai1ec-events-controller.php:149
|
97 |
+
msgid "This feed is already being imported."
|
98 |
msgstr ""
|
99 |
|
100 |
+
#: app/controller/class-ai1ec-events-controller.php:150
|
101 |
+
msgid "Please enter a valid iCalendar URL."
|
102 |
msgstr ""
|
103 |
|
104 |
+
#: app/controller/class-ai1ec-events-controller.php:285
|
105 |
+
msgid "times"
|
106 |
msgstr ""
|
107 |
|
108 |
+
#: app/controller/class-ai1ec-events-controller.php:334
|
109 |
+
msgid "Publish"
|
110 |
msgstr ""
|
111 |
|
112 |
+
#: app/controller/class-ai1ec-events-controller.php:334
|
113 |
+
#: app/view/feed_row.php:20
|
114 |
+
msgid "Update"
|
115 |
msgstr ""
|
116 |
|
117 |
+
#: app/controller/class-ai1ec-events-controller.php:336
|
118 |
+
msgid "Submit for Review"
|
119 |
msgstr ""
|
120 |
|
121 |
+
#: app/controller/class-ai1ec-events-controller.php:449
|
122 |
+
msgid "Event updated. <a href=\"%s\">View event</a>"
|
123 |
msgstr ""
|
124 |
|
125 |
+
#: app/controller/class-ai1ec-events-controller.php:450
|
126 |
+
msgid "Custom field updated."
|
|
|
|
|
127 |
msgstr ""
|
128 |
|
129 |
+
#: app/controller/class-ai1ec-events-controller.php:451
|
130 |
+
msgid "Custom field deleted."
|
131 |
msgstr ""
|
132 |
|
133 |
+
#: app/controller/class-ai1ec-events-controller.php:452
|
134 |
+
msgid "Event updated."
|
135 |
msgstr ""
|
136 |
|
137 |
+
#. translators: %s: date and time of the revision
|
138 |
+
#: app/controller/class-ai1ec-events-controller.php:454
|
139 |
+
msgid "Event restored to revision from %s"
|
140 |
msgstr ""
|
141 |
|
142 |
+
#: app/controller/class-ai1ec-events-controller.php:455
|
143 |
+
msgid "Event published. <a href=\"%s\">View event</a>"
|
144 |
msgstr ""
|
145 |
|
146 |
+
#: app/controller/class-ai1ec-events-controller.php:456
|
147 |
+
msgid "Event saved."
|
148 |
msgstr ""
|
149 |
|
150 |
+
#: app/controller/class-ai1ec-events-controller.php:457
|
151 |
+
msgid "Event submitted. <a target=\"_blank\" href=\"%s\">Preview event</a>"
|
152 |
msgstr ""
|
153 |
|
154 |
+
#: app/controller/class-ai1ec-events-controller.php:458
|
155 |
+
msgid ""
|
156 |
+
"Event scheduled for: <strong>%1$s</strong>. <a target=\"_blank\" href=\"%2$s"
|
157 |
+
"\">Preview event</a>"
|
158 |
msgstr ""
|
159 |
|
160 |
+
#. translators: Publish box date format, see http:php.net/date
|
161 |
+
#: app/controller/class-ai1ec-events-controller.php:460
|
162 |
+
msgid "M j, Y @ G:i"
|
|
|
163 |
msgstr ""
|
164 |
|
165 |
+
#: app/controller/class-ai1ec-events-controller.php:461
|
166 |
+
msgid "Event draft updated. <a target=\"_blank\" href=\"%s\">Preview event</a>"
|
|
|
|
|
167 |
msgstr ""
|
168 |
|
169 |
+
#: app/controller/class-ai1ec-app-controller.php:354
|
170 |
+
#: app/controller/class-ai1ec-app-controller.php:355
|
171 |
+
msgid "Settings"
|
172 |
msgstr ""
|
173 |
|
174 |
+
#: app/helper/class-ai1ec-events-helper.php:319
|
175 |
+
#: app/helper/class-ai1ec-events-helper.php:341
|
176 |
+
msgid "No repeat"
|
177 |
msgstr ""
|
178 |
|
179 |
+
#: app/helper/class-ai1ec-events-helper.php:320
|
180 |
+
#: app/helper/class-ai1ec-events-helper.php:342
|
181 |
+
msgid "Every day"
|
182 |
msgstr ""
|
183 |
|
184 |
+
#: app/helper/class-ai1ec-events-helper.php:321
|
185 |
+
#: app/helper/class-ai1ec-events-helper.php:343
|
186 |
+
msgid "Every week"
|
187 |
msgstr ""
|
188 |
|
189 |
+
#: app/helper/class-ai1ec-events-helper.php:322
|
190 |
+
#: app/helper/class-ai1ec-events-helper.php:344
|
191 |
+
msgid "Every month"
|
|
|
|
|
192 |
msgstr ""
|
193 |
|
194 |
+
#: app/helper/class-ai1ec-events-helper.php:323
|
195 |
+
#: app/helper/class-ai1ec-events-helper.php:345
|
196 |
+
msgid "Every year"
|
|
|
197 |
msgstr ""
|
198 |
|
199 |
+
#: app/helper/class-ai1ec-events-helper.php:325
|
200 |
+
#: app/helper/class-ai1ec-events-helper.php:347
|
201 |
+
msgid "Custom..."
|
202 |
msgstr ""
|
203 |
|
204 |
+
#: app/helper/class-ai1ec-events-helper.php:468
|
205 |
+
msgid "first"
|
|
|
|
|
206 |
msgstr ""
|
207 |
|
208 |
+
#: app/helper/class-ai1ec-events-helper.php:469
|
209 |
+
msgid "second"
|
|
|
|
|
|
|
210 |
msgstr ""
|
211 |
|
212 |
+
#: app/helper/class-ai1ec-events-helper.php:470
|
213 |
+
msgid "third"
|
214 |
msgstr ""
|
215 |
|
216 |
+
#: app/helper/class-ai1ec-events-helper.php:471
|
217 |
+
msgid "fourth"
|
218 |
msgstr ""
|
219 |
|
220 |
+
#: app/helper/class-ai1ec-events-helper.php:473
|
221 |
+
msgid "last"
|
222 |
msgstr ""
|
223 |
|
224 |
+
#: app/helper/class-ai1ec-events-helper.php:478
|
225 |
+
msgid "Sunday"
|
226 |
msgstr ""
|
227 |
|
228 |
+
#: app/helper/class-ai1ec-events-helper.php:479
|
229 |
+
msgid "Monday"
|
|
|
230 |
msgstr ""
|
231 |
|
232 |
+
#: app/helper/class-ai1ec-events-helper.php:480
|
233 |
+
msgid "Tuesday"
|
|
|
234 |
msgstr ""
|
235 |
|
236 |
+
#: app/helper/class-ai1ec-events-helper.php:481
|
237 |
+
msgid "Wednesday"
|
|
|
238 |
msgstr ""
|
239 |
|
240 |
+
#: app/helper/class-ai1ec-events-helper.php:482
|
241 |
+
msgid "Thursday"
|
242 |
msgstr ""
|
243 |
|
244 |
+
#: app/helper/class-ai1ec-events-helper.php:483
|
245 |
+
msgid "Friday"
|
246 |
msgstr ""
|
247 |
|
248 |
+
#: app/helper/class-ai1ec-events-helper.php:484
|
249 |
+
msgid "Saturday"
|
|
|
250 |
msgstr ""
|
251 |
|
252 |
+
#: app/helper/class-ai1ec-events-helper.php:486
|
253 |
+
msgid "day"
|
254 |
msgstr ""
|
255 |
|
256 |
+
#: app/helper/class-ai1ec-events-helper.php:487
|
257 |
+
msgid "weekday"
|
258 |
msgstr ""
|
259 |
|
260 |
+
#: app/helper/class-ai1ec-events-helper.php:488
|
261 |
+
msgid "weekend day"
|
262 |
msgstr ""
|
263 |
|
264 |
+
#: app/helper/class-ai1ec-events-helper.php:554
|
265 |
+
#: app/helper/class-ai1ec-events-helper.php:573
|
266 |
+
#: app/helper/class-ai1ec-events-helper.php:1502
|
267 |
+
#: app/helper/class-ai1ec-settings-helper.php:237
|
268 |
+
#: app/view/box_time_and_date.php:58
|
269 |
+
msgid "Daily"
|
270 |
msgstr ""
|
271 |
|
272 |
+
#: app/helper/class-ai1ec-events-helper.php:555
|
273 |
+
#: app/helper/class-ai1ec-events-helper.php:574
|
274 |
+
#: app/helper/class-ai1ec-events-helper.php:1514
|
275 |
+
#: app/view/box_time_and_date.php:59
|
276 |
+
msgid "Weekly"
|
277 |
msgstr ""
|
278 |
|
279 |
+
#: app/helper/class-ai1ec-events-helper.php:556
|
280 |
+
#: app/helper/class-ai1ec-events-helper.php:575
|
281 |
+
#: app/helper/class-ai1ec-events-helper.php:1526
|
282 |
+
#: app/view/box_time_and_date.php:60
|
283 |
+
msgid "Monthly"
|
284 |
msgstr ""
|
285 |
|
286 |
+
#: app/helper/class-ai1ec-events-helper.php:557
|
287 |
+
#: app/helper/class-ai1ec-events-helper.php:576
|
288 |
+
#: app/helper/class-ai1ec-events-helper.php:1538
|
289 |
+
#: app/view/box_time_and_date.php:61
|
290 |
+
msgid "Yearly"
|
291 |
msgstr ""
|
292 |
|
293 |
+
#: app/helper/class-ai1ec-events-helper.php:598
|
294 |
+
msgid "day(s)"
|
|
|
295 |
msgstr ""
|
296 |
|
297 |
+
#: app/helper/class-ai1ec-events-helper.php:627
|
298 |
+
msgid "week(s)"
|
299 |
msgstr ""
|
300 |
|
301 |
+
#: app/helper/class-ai1ec-events-helper.php:697
|
302 |
+
msgid "month(s)"
|
303 |
msgstr ""
|
304 |
|
305 |
+
#: app/helper/class-ai1ec-events-helper.php:720
|
306 |
+
msgid "year(s)"
|
307 |
msgstr ""
|
308 |
|
309 |
+
#: app/helper/class-ai1ec-events-helper.php:1300
|
310 |
+
msgid "Never"
|
311 |
msgstr ""
|
312 |
|
313 |
+
#: app/helper/class-ai1ec-events-helper.php:1301
|
314 |
+
msgid "After"
|
|
|
315 |
msgstr ""
|
316 |
|
317 |
+
#: app/helper/class-ai1ec-events-helper.php:1302
|
318 |
+
#: app/view/box_time_and_date.php:84
|
319 |
+
msgid "On date"
|
320 |
msgstr ""
|
321 |
|
322 |
+
#: app/helper/class-ai1ec-events-helper.php:1381
|
323 |
+
#: app/helper/class-ai1ec-events-helper.php:1390
|
324 |
+
#: app/helper/class-ai1ec-events-helper.php:1398
|
325 |
+
msgctxt "Recurrence editor - weekly tab"
|
326 |
+
msgid "on"
|
327 |
msgstr ""
|
328 |
|
329 |
+
#: app/helper/class-ai1ec-events-helper.php:1386
|
330 |
+
#: app/helper/class-ai1ec-events-helper.php:1415
|
331 |
+
#: app/helper/class-ai1ec-events-helper.php:1453
|
332 |
+
msgid "and"
|
333 |
msgstr ""
|
334 |
|
335 |
+
#: app/helper/class-ai1ec-events-helper.php:1411
|
336 |
+
#: app/helper/class-ai1ec-events-helper.php:1418
|
337 |
+
#: app/helper/class-ai1ec-events-helper.php:1424
|
338 |
+
#: app/helper/class-ai1ec-events-helper.php:1435
|
339 |
+
msgctxt "Recurrence editor - monthly tab"
|
340 |
+
msgid "on"
|
341 |
msgstr ""
|
342 |
|
343 |
+
#: app/helper/class-ai1ec-events-helper.php:1411
|
344 |
+
#: app/helper/class-ai1ec-events-helper.php:1418
|
345 |
+
#: app/helper/class-ai1ec-events-helper.php:1424
|
346 |
+
msgid "of the month"
|
347 |
msgstr ""
|
348 |
|
349 |
+
#: app/helper/class-ai1ec-events-helper.php:1448
|
350 |
+
#: app/helper/class-ai1ec-events-helper.php:1456
|
351 |
+
#: app/helper/class-ai1ec-events-helper.php:1463
|
352 |
+
msgctxt "Recurrence editor - yearly tab"
|
353 |
+
msgid "on"
|
354 |
msgstr ""
|
355 |
|
356 |
+
#: app/helper/class-ai1ec-events-helper.php:1505
|
357 |
+
msgid "Every other day"
|
358 |
msgstr ""
|
359 |
|
360 |
+
#: app/helper/class-ai1ec-events-helper.php:1507
|
361 |
+
msgid "Every %d days"
|
362 |
msgstr ""
|
363 |
|
364 |
+
#: app/helper/class-ai1ec-events-helper.php:1517
|
365 |
+
msgid "Every other week"
|
366 |
msgstr ""
|
367 |
|
368 |
+
#: app/helper/class-ai1ec-events-helper.php:1519
|
369 |
+
msgid "Every %d weeks"
|
|
|
|
|
|
|
|
|
370 |
msgstr ""
|
371 |
|
372 |
+
#: app/helper/class-ai1ec-events-helper.php:1529
|
373 |
+
msgid "Every other month"
|
|
|
|
|
|
|
374 |
msgstr ""
|
375 |
|
376 |
+
#: app/helper/class-ai1ec-events-helper.php:1531
|
377 |
+
msgid "Every %d months"
|
|
|
|
|
|
|
378 |
msgstr ""
|
379 |
|
380 |
+
#: app/helper/class-ai1ec-events-helper.php:1541
|
381 |
+
msgid "Every other year"
|
|
|
|
|
|
|
382 |
msgstr ""
|
383 |
|
384 |
+
#: app/helper/class-ai1ec-events-helper.php:1543
|
385 |
+
msgid "Every %d years"
|
386 |
msgstr ""
|
387 |
|
388 |
+
#: app/helper/class-ai1ec-events-helper.php:1563
|
389 |
+
msgid "until %s"
|
390 |
msgstr ""
|
391 |
|
392 |
+
#: app/helper/class-ai1ec-events-helper.php:1566
|
393 |
+
msgid "for %d occurrences"
|
|
|
394 |
msgstr ""
|
395 |
|
396 |
+
#: app/helper/class-ai1ec-events-helper.php:1568
|
397 |
+
msgid "forever"
|
398 |
msgstr ""
|
399 |
|
400 |
+
#: app/helper/class-ai1ec-app-helper.php:147
|
401 |
+
msgctxt "Custom post type name"
|
402 |
+
msgid "Events"
|
403 |
msgstr ""
|
404 |
|
405 |
+
#: app/helper/class-ai1ec-app-helper.php:148
|
406 |
+
msgctxt "Custom post type name (singular)"
|
407 |
+
msgid "Event"
|
408 |
msgstr ""
|
409 |
|
410 |
+
#: app/helper/class-ai1ec-app-helper.php:149
|
411 |
+
msgid "Add New"
|
412 |
msgstr ""
|
413 |
|
414 |
+
#: app/helper/class-ai1ec-app-helper.php:150
|
415 |
+
msgid "Add New Event"
|
416 |
msgstr ""
|
417 |
|
418 |
+
#: app/helper/class-ai1ec-app-helper.php:151
|
419 |
+
msgid "Edit Event"
|
420 |
msgstr ""
|
421 |
|
422 |
+
#: app/helper/class-ai1ec-app-helper.php:152
|
423 |
+
msgid "New Event"
|
424 |
msgstr ""
|
425 |
|
426 |
+
#: app/helper/class-ai1ec-app-helper.php:153
|
427 |
+
msgid "View Event"
|
428 |
msgstr ""
|
429 |
|
430 |
+
#: app/helper/class-ai1ec-app-helper.php:154
|
431 |
+
msgid "Search Events"
|
432 |
msgstr ""
|
433 |
|
434 |
+
#: app/helper/class-ai1ec-app-helper.php:155
|
435 |
+
msgid "No Events found"
|
436 |
msgstr ""
|
437 |
|
438 |
+
#: app/helper/class-ai1ec-app-helper.php:156
|
439 |
+
msgid "No Events found in Trash"
|
440 |
msgstr ""
|
441 |
|
442 |
+
#: app/helper/class-ai1ec-app-helper.php:157
|
443 |
+
msgid "Parent Event"
|
444 |
msgstr ""
|
445 |
|
446 |
+
#: app/helper/class-ai1ec-app-helper.php:158
|
447 |
+
msgid "Events"
|
|
|
448 |
msgstr ""
|
449 |
|
450 |
+
#: app/helper/class-ai1ec-app-helper.php:205
|
451 |
+
msgctxt "Event categories taxonomy"
|
452 |
+
msgid "Event Categories"
|
453 |
msgstr ""
|
454 |
|
455 |
+
#: app/helper/class-ai1ec-app-helper.php:206
|
456 |
+
msgctxt "Event categories taxonomy (singular)"
|
457 |
+
msgid "Event Category"
|
|
|
458 |
msgstr ""
|
459 |
|
460 |
+
#: app/helper/class-ai1ec-app-helper.php:213
|
461 |
+
msgctxt "Event tags taxonomy"
|
462 |
+
msgid "Event Tags"
|
463 |
msgstr ""
|
464 |
|
465 |
+
#: app/helper/class-ai1ec-app-helper.php:214
|
466 |
+
msgctxt "Event tags taxonomy (singular)"
|
467 |
+
msgid "Event Tag"
|
468 |
msgstr ""
|
469 |
|
470 |
+
#: app/helper/class-ai1ec-app-helper.php:281
|
471 |
+
msgid "Show All "
|
472 |
msgstr ""
|
473 |
|
474 |
+
#: app/helper/class-ai1ec-app-helper.php:313
|
475 |
+
msgid ""
|
476 |
+
"All Events <span class=\"update-plugins count-%d\" title=\"%d Pending Events"
|
477 |
+
"\"><span class=\"update-count\">%d</span></span>"
|
478 |
msgstr ""
|
479 |
|
480 |
+
#: app/helper/class-ai1ec-app-helper.php:319
|
481 |
+
msgid "All Events"
|
482 |
msgstr ""
|
483 |
|
484 |
+
#: app/helper/class-ai1ec-app-helper.php:395
|
485 |
+
msgid "Event Details"
|
486 |
msgstr ""
|
487 |
|
488 |
+
#: app/helper/class-ai1ec-app-helper.php:428
|
489 |
+
msgid "Post Date"
|
|
|
|
|
490 |
msgstr ""
|
491 |
|
492 |
+
#: app/helper/class-ai1ec-app-helper.php:429
|
493 |
+
msgid "Event date/time"
|
494 |
msgstr ""
|
495 |
|
496 |
+
#: app/helper/class-ai1ec-app-helper.php:653
|
497 |
+
msgid ""
|
498 |
+
"%sTo set up the plugin: %s 1. Select an option in the <strong>Calendar page</"
|
499 |
+
"strong> dropdown list. %s 2. Select an option in the <strong>Timezone</"
|
500 |
+
"strong> dropdown list. %s 3. Click <strong>Update Settings</strong>. %s"
|
501 |
msgstr ""
|
502 |
|
503 |
+
#: app/helper/class-ai1ec-app-helper.php:655
|
504 |
+
msgid ""
|
505 |
+
"To set up the plugin: Select an option in the <strong>Calendar page</strong> "
|
506 |
+
"dropdown list, the click <strong>Update Settings</strong>."
|
507 |
msgstr ""
|
508 |
|
509 |
+
#: app/helper/class-ai1ec-app-helper.php:657
|
510 |
+
msgid ""
|
511 |
+
"To set up the plugin: Select an option in the <strong>Timezone</strong> "
|
512 |
+
"dropdown list, the click <strong>Update Settings</strong>."
|
513 |
msgstr ""
|
514 |
|
515 |
+
#: app/helper/class-ai1ec-app-helper.php:661
|
516 |
+
msgid ""
|
517 |
+
"The plugin is installed, but has not been configured. <a href=\"%s\">Click "
|
518 |
+
"here to set it up now »</a>"
|
519 |
msgstr ""
|
520 |
|
521 |
+
#: app/helper/class-ai1ec-app-helper.php:667
|
522 |
+
msgid ""
|
523 |
+
"The plugin is installed, but has not been configured. Please log in as a "
|
524 |
+
"WordPress Administrator to set it up."
|
525 |
msgstr ""
|
526 |
|
527 |
+
#: app/helper/class-ai1ec-calendar-helper.php:718
|
528 |
+
#: app/helper/class-ai1ec-calendar-helper.php:727
|
529 |
+
msgid "M j"
|
530 |
msgstr ""
|
531 |
|
532 |
+
#: app/helper/class-ai1ec-calendar-helper.php:759
|
533 |
+
msgid "« Previous Events"
|
534 |
msgstr ""
|
535 |
|
536 |
+
#: app/helper/class-ai1ec-calendar-helper.php:766
|
537 |
+
msgid "Next Events »"
|
538 |
msgstr ""
|
539 |
|
540 |
+
#: app/helper/class-ai1ec-settings-helper.php:85
|
541 |
+
msgid "- Auto-Create New Page -"
|
542 |
msgstr ""
|
543 |
|
544 |
+
#: app/helper/class-ai1ec-settings-helper.php:107
|
545 |
+
msgid "View \"%s\" »"
|
546 |
msgstr ""
|
547 |
|
548 |
+
#: app/helper/class-ai1ec-settings-helper.php:149 app/view/calendar.php:11
|
549 |
+
#: app/view/calendar.php:12 app/view/calendar.php:25
|
550 |
+
msgid "Month"
|
551 |
msgstr ""
|
552 |
|
553 |
+
#: app/helper/class-ai1ec-settings-helper.php:152 app/view/calendar.php:18
|
554 |
+
#: app/view/calendar.php:19
|
555 |
+
msgid "Week"
|
556 |
msgstr ""
|
557 |
|
558 |
+
#: app/helper/class-ai1ec-settings-helper.php:204
|
559 |
+
msgid "Default (d/m/y)"
|
560 |
msgstr ""
|
561 |
|
562 |
+
#: app/helper/class-ai1ec-settings-helper.php:207
|
563 |
+
msgid "US (m/d/y)"
|
564 |
msgstr ""
|
565 |
|
566 |
+
#: app/helper/class-ai1ec-settings-helper.php:210
|
567 |
+
msgid "ISO 8601 (y-m-d)"
|
568 |
msgstr ""
|
569 |
|
570 |
+
#: app/helper/class-ai1ec-settings-helper.php:213
|
571 |
+
msgid "Dotted (m.d.y)"
|
572 |
msgstr ""
|
573 |
|
574 |
+
#: app/helper/class-ai1ec-settings-helper.php:231
|
575 |
+
msgid "Hourly"
|
576 |
msgstr ""
|
577 |
|
578 |
+
#: app/helper/class-ai1ec-settings-helper.php:234
|
579 |
+
msgid "Twice Daily"
|
580 |
msgstr ""
|
581 |
|
582 |
+
#: app/helper/class-ai1ec-settings-helper.php:321
|
583 |
+
msgid "Calendar"
|
584 |
msgstr ""
|
585 |
|
586 |
+
#: app/view/settings.php:5
|
587 |
+
msgid "All-in-one Event Calendar"
|
588 |
msgstr ""
|
589 |
|
590 |
+
#: app/view/settings.php:16
|
591 |
+
msgid "Update Settings"
|
592 |
msgstr ""
|
593 |
|
594 |
+
#: app/view/box_event_cost.php:1
|
595 |
+
msgid "Event cost"
|
596 |
msgstr ""
|
597 |
|
598 |
+
#: app/view/box_event_cost.php:7
|
599 |
+
msgid "Cost"
|
600 |
msgstr ""
|
601 |
|
602 |
+
#: app/view/event-excerpt.php:2 app/view/event-single.php:5
|
603 |
+
#: app/view/event-multi.php:4
|
604 |
+
msgid "When:"
|
605 |
msgstr ""
|
606 |
|
607 |
+
#: app/view/event-excerpt.php:4 app/view/event-single.php:20
|
608 |
+
#: app/view/event-multi.php:20
|
609 |
+
msgid "Where:"
|
610 |
msgstr ""
|
611 |
|
612 |
+
#: app/view/feed_row.php:3 app/view/box_ics_import_settings.php:8
|
613 |
+
msgid "iCalendar/.ics Feed URL:"
|
614 |
msgstr ""
|
615 |
|
616 |
#: app/view/feed_row.php:9
|
617 |
msgid "Event category:"
|
618 |
msgstr ""
|
619 |
|
620 |
+
#: app/view/feed_row.php:15 app/view/box_ics_import_settings.php:18
|
621 |
+
msgid "Tag with"
|
622 |
msgstr ""
|
623 |
|
624 |
+
#: app/view/feed_row.php:19
|
625 |
+
msgid "× Delete"
|
|
|
626 |
msgstr ""
|
627 |
|
628 |
+
#: app/view/event-map.php:2
|
629 |
+
msgid "Click to view map"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
630 |
msgstr ""
|
631 |
|
632 |
+
#: app/view/event-map.php:9
|
633 |
+
msgid "View Full-Size Map »"
|
634 |
msgstr ""
|
635 |
|
636 |
+
#: app/view/box_event_location.php:1
|
637 |
+
msgid "Event location details"
|
638 |
msgstr ""
|
639 |
|
640 |
+
#: app/view/box_event_location.php:7
|
641 |
+
msgid "Venue name:"
|
642 |
msgstr ""
|
643 |
|
644 |
+
#: app/view/box_event_location.php:17
|
645 |
+
msgid "Address:"
|
646 |
msgstr ""
|
647 |
|
648 |
+
#: app/view/box_event_location.php:27
|
649 |
+
msgid "Show Google Map:"
|
|
|
|
|
|
|
|
|
650 |
msgstr ""
|
651 |
|
652 |
+
#: app/view/class-ai1ec-agenda-widget.php:18
|
653 |
+
#: app/view/class-ai1ec-agenda-widget.php:39
|
654 |
+
msgid "Upcoming Events"
|
655 |
msgstr ""
|
656 |
|
657 |
+
#: app/view/class-ai1ec-agenda-widget.php:20
|
658 |
+
msgid "All-in-One Event Calendar: Lists upcoming events in Agenda view"
|
659 |
msgstr ""
|
660 |
|
661 |
+
#: app/view/month.php:4 app/view/agenda.php:12 app/view/week.php:4
|
662 |
+
msgid "Today"
|
663 |
msgstr ""
|
664 |
|
665 |
+
#: app/view/month.php:50 app/view/week.php:55 app/view/week.php:127
|
666 |
+
msgid "Summary:"
|
667 |
msgstr ""
|
668 |
|
669 |
+
#: app/view/month.php:53 app/view/week.php:58 app/view/week.php:130
|
670 |
+
msgid "click anywhere for details"
|
671 |
msgstr ""
|
672 |
|
673 |
+
#: app/view/month.php:68 app/view/agenda.php:59 app/view/agenda.php:109
|
674 |
+
#: app/view/week.php:69
|
675 |
+
msgid "(all-day)"
|
|
|
676 |
msgstr ""
|
677 |
|
678 |
+
#: app/view/import.php:6
|
679 |
+
msgid "Successfully imported events:"
|
|
|
|
|
680 |
msgstr ""
|
681 |
|
682 |
+
#: app/view/event-single.php:8
|
683 |
+
msgid "Back to Calendar »"
|
684 |
msgstr ""
|
685 |
|
686 |
+
#: app/view/event-single.php:15 app/view/event-multi.php:14
|
687 |
+
msgid "Repeats:"
|
|
|
|
|
688 |
msgstr ""
|
689 |
|
690 |
+
#: app/view/event-single.php:27
|
691 |
+
msgid "Add this event to your favourite calendar program (iCal, Outlook, etc.)"
|
692 |
msgstr ""
|
693 |
|
694 |
+
#: app/view/event-single.php:28
|
695 |
+
msgid "✔ Add to Calendar"
|
696 |
msgstr ""
|
697 |
|
698 |
+
#: app/view/event-single.php:31
|
699 |
+
msgid "Add this event to your Google Calendar"
|
700 |
msgstr ""
|
701 |
|
702 |
+
#: app/view/event-single.php:33
|
703 |
+
msgid "Add to Google Calendar"
|
704 |
msgstr ""
|
705 |
|
706 |
+
#: app/view/event-single.php:40 app/view/event-multi.php:33
|
707 |
+
msgid "Cost:"
|
708 |
msgstr ""
|
709 |
|
710 |
+
#: app/view/event-single.php:46 app/view/event-multi.php:39
|
711 |
+
msgid "Contact:"
|
712 |
msgstr ""
|
713 |
|
714 |
+
#: app/view/event-single.php:52 app/view/event-multi.php:45
|
715 |
+
#: app/view/agenda.php:81
|
716 |
+
msgid "Categories:"
|
717 |
msgstr ""
|
718 |
|
719 |
+
#: app/view/event-single.php:59 app/view/event-multi.php:51
|
720 |
+
#: app/view/agenda.php:87
|
721 |
+
msgid "Tags:"
|
722 |
msgstr ""
|
723 |
|
724 |
+
#: app/view/row_weekly.php:3 app/view/row_monthly.php:3
|
725 |
+
#: app/view/row_monthly.php:22 app/view/row_yearly.php:3
|
726 |
+
#: app/view/row_daily.php:3
|
727 |
+
msgid "Every"
|
728 |
msgstr ""
|
729 |
|
730 |
+
#: app/view/row_weekly.php:6
|
731 |
+
msgctxt "Recurrence editor - weekly tab"
|
732 |
+
msgid "On"
|
733 |
msgstr ""
|
734 |
|
735 |
+
#: app/view/box_eventbrite.php:1
|
736 |
+
msgid "Eventbrite Ticketing"
|
737 |
msgstr ""
|
738 |
|
739 |
+
#: app/view/box_eventbrite.php:7
|
740 |
+
msgid "Register this event with Eventbrite.com?"
|
741 |
msgstr ""
|
742 |
|
743 |
+
#: app/view/box_eventbrite.php:12
|
744 |
+
msgid "Yes"
|
745 |
msgstr ""
|
746 |
|
747 |
+
#: app/view/box_eventbrite.php:14
|
748 |
+
msgid "No"
|
749 |
msgstr ""
|
750 |
|
751 |
+
#: app/view/box_eventbrite.php:22
|
752 |
+
msgid "Set up your first ticket"
|
753 |
msgstr ""
|
754 |
|
755 |
+
#: app/view/box_eventbrite.php:24
|
756 |
+
msgid ""
|
757 |
+
"To create multiple tickets per event, submit this form, then follow the link "
|
758 |
+
"to Eventbrite."
|
759 |
msgstr ""
|
760 |
+
|
761 |
+
#: app/view/box_eventbrite.php:32
|
762 |
+
msgid "Name"
|
763 |
msgstr ""
|
764 |
|
765 |
+
#: app/view/box_eventbrite.php:42
|
766 |
+
msgid "Description"
|
|
|
767 |
msgstr ""
|
768 |
|
769 |
+
#: app/view/box_eventbrite.php:53
|
770 |
+
msgid "Type"
|
771 |
msgstr ""
|
772 |
|
773 |
+
#: app/view/box_eventbrite.php:58
|
774 |
+
msgid "Set Price"
|
775 |
msgstr ""
|
776 |
|
777 |
+
#: app/view/box_eventbrite.php:60
|
778 |
+
msgid "Donation Based"
|
779 |
msgstr ""
|
780 |
|
781 |
+
#: app/view/box_eventbrite.php:68
|
782 |
msgid ""
|
783 |
+
"The price for this event's first ticket will be taken from the Cost field "
|
784 |
+
"above."
|
785 |
msgstr ""
|
786 |
|
787 |
+
#: app/view/box_eventbrite.php:75
|
788 |
+
msgid "Quantity"
|
|
|
789 |
msgstr ""
|
790 |
|
791 |
+
#: app/view/box_eventbrite.php:85
|
792 |
+
msgid "Include Fee in Price"
|
793 |
msgstr ""
|
794 |
|
795 |
+
#: app/view/box_eventbrite.php:90
|
796 |
+
msgid "Add Service Fee on top of price"
|
797 |
msgstr ""
|
798 |
|
799 |
+
#: app/view/box_eventbrite.php:92
|
800 |
+
msgid "Include Service fee in price"
|
|
|
|
|
801 |
msgstr ""
|
802 |
|
803 |
+
#: app/view/box_eventbrite.php:98
|
804 |
+
msgid "Payment Options"
|
|
|
805 |
msgstr ""
|
806 |
|
807 |
+
#: app/view/box_eventbrite.php:103
|
808 |
+
msgid "Paypal"
|
|
|
|
|
|
|
809 |
msgstr ""
|
810 |
|
811 |
+
#: app/view/box_eventbrite.php:105
|
812 |
+
msgid "Google Checkout"
|
813 |
msgstr ""
|
814 |
|
815 |
+
#: app/view/box_eventbrite.php:107
|
816 |
+
msgid "Check"
|
817 |
msgstr ""
|
818 |
|
819 |
+
#: app/view/box_eventbrite.php:109
|
820 |
+
msgid "Cash"
|
821 |
msgstr ""
|
822 |
|
823 |
+
#: app/view/box_eventbrite.php:111
|
824 |
+
msgid "Send an Invoice"
|
|
|
825 |
msgstr ""
|
826 |
|
827 |
+
#: app/view/row_monthly.php:9
|
828 |
+
msgid "On day of the month"
|
829 |
msgstr ""
|
830 |
|
831 |
+
#: app/view/row_monthly.php:13
|
832 |
+
msgid "On day of the week"
|
833 |
msgstr ""
|
834 |
|
835 |
+
#. #-#-#-#-# plugin.pot (All-in-One Event Calendar 1.2.4) #-#-#-#-#
|
836 |
+
#. Author of the plugin/theme
|
837 |
+
#: app/view/box_the_seed_studio.php:4
|
838 |
+
msgid "The Seed Studio"
|
839 |
msgstr ""
|
840 |
|
841 |
+
#: app/view/box_the_seed_studio.php:7
|
842 |
+
msgid ""
|
843 |
+
"The Seed Studio provides web development and support services for clients "
|
844 |
+
"and web developers."
|
845 |
msgstr ""
|
846 |
|
847 |
+
#: app/view/box_the_seed_studio.php:14
|
848 |
+
msgid "Follow @theseednet"
|
|
|
849 |
msgstr ""
|
850 |
|
851 |
+
#: app/view/box_the_seed_studio.php:20
|
852 |
+
msgid "Get Support<span> from one of our experienced pros</span>"
|
853 |
msgstr ""
|
854 |
|
855 |
+
#: app/view/box_the_seed_studio.php:23
|
856 |
+
msgid "Support"
|
857 |
msgstr ""
|
858 |
|
859 |
+
#: app/view/box_the_seed_studio.php:25
|
860 |
+
msgid "View plugin documentation"
|
861 |
msgstr ""
|
862 |
|
863 |
+
#: app/view/box_the_seed_studio.php:28
|
864 |
+
msgid ""
|
865 |
+
"You can also hire The Seed for support on a contract or per-hour basis for "
|
866 |
+
"this plugin, for your website or for any of your Internet marketing needs "
|
867 |
+
"(we can really help!)."
|
868 |
msgstr ""
|
869 |
|
870 |
+
#: app/view/box_the_seed_studio.php:31
|
871 |
+
msgid ""
|
872 |
+
"Plugin users: The Seed gives support priority to clients. For free support "
|
873 |
+
"from other WordPress users, visit the plugin's forum."
|
874 |
msgstr ""
|
875 |
|
876 |
+
#: app/view/box_the_seed_studio.php:34
|
877 |
+
msgid "Vote and Share"
|
|
|
878 |
msgstr ""
|
879 |
|
880 |
+
#: app/view/box_the_seed_studio.php:36
|
881 |
+
msgid ""
|
882 |
+
"This plugin is offered free to the Wordpress Community under the GPL3 "
|
883 |
+
"license. All we ask is that you:"
|
884 |
msgstr ""
|
885 |
|
886 |
+
#: app/view/box_the_seed_studio.php:38
|
887 |
+
msgid ""
|
888 |
+
"<a href=\"http://wordpress.org/extend/plugins/all-in-one-event-calendar/\" "
|
889 |
+
"target=\"_blank\">Give it a five-star rating on wordpress.org</a> (if you "
|
890 |
+
"think it deserves it!)"
|
891 |
msgstr ""
|
892 |
|
893 |
+
#: app/view/box_the_seed_studio.php:39
|
894 |
+
msgid "Link to the plugin page on our website"
|
|
|
895 |
msgstr ""
|
896 |
|
897 |
+
#: app/view/box_the_seed_studio.php:40
|
898 |
+
msgid "Become a Fan on Facebook"
|
|
|
899 |
msgstr ""
|
900 |
|
901 |
+
#: app/view/box_the_seed_studio.php:41
|
902 |
+
msgid "Follow us on Twitter"
|
903 |
msgstr ""
|
904 |
|
905 |
+
#: app/view/box_the_seed_studio.php:46
|
906 |
+
msgid "Latest from the Seed Network"
|
907 |
msgstr ""
|
908 |
|
909 |
+
#: app/view/event-multi.php:7
|
910 |
+
msgid "View in Calendar »"
|
911 |
msgstr ""
|
912 |
|
913 |
+
#: app/view/event-multi.php:24
|
914 |
+
msgid "View Map »"
|
915 |
msgstr ""
|
916 |
|
917 |
+
#: app/view/box_general_settings.php:1
|
918 |
+
msgid "Viewing Events"
|
919 |
msgstr ""
|
920 |
|
921 |
+
#: app/view/box_general_settings.php:3
|
922 |
+
msgid "Calendar page:"
|
923 |
msgstr ""
|
924 |
|
925 |
+
#: app/view/box_general_settings.php:7
|
926 |
+
msgid "Default calendar view:"
|
927 |
msgstr ""
|
928 |
|
929 |
+
#: app/view/box_general_settings.php:12
|
930 |
+
msgid "Timezone:"
|
931 |
msgstr ""
|
932 |
|
933 |
+
#: app/view/box_general_settings.php:17
|
934 |
+
msgid "Contain calendar in this DOM element:"
|
935 |
msgstr ""
|
936 |
|
937 |
+
#: app/view/box_general_settings.php:19
|
938 |
+
msgid ""
|
939 |
+
"Optional. Provide a <a href=\"http://api.jquery.com/category/selectors/\" "
|
940 |
+
"target=\"_blank\">jQuery selector</a> that evaluates to a single DOM "
|
941 |
+
"element. Replaces any existing markup found within target. If left empty, "
|
942 |
+
"calendar is shown in normal page content container."
|
943 |
msgstr ""
|
944 |
|
945 |
+
#: app/view/box_general_settings.php:21
|
946 |
+
msgid "Week starts on"
|
947 |
msgstr ""
|
948 |
|
949 |
+
#: app/view/box_general_settings.php:25
|
950 |
+
msgid "Agenda pages show at most"
|
951 |
msgstr ""
|
952 |
|
953 |
+
#: app/view/box_general_settings.php:26
|
954 |
+
msgid "events"
|
955 |
msgstr ""
|
956 |
|
957 |
+
#: app/view/box_general_settings.php:31
|
958 |
+
msgid "Keep all events <strong>expanded</strong> in the agenda view"
|
959 |
msgstr ""
|
960 |
|
961 |
+
#: app/view/box_general_settings.php:37
|
962 |
+
msgid "<strong>Exclude</strong> events from search results"
|
963 |
msgstr ""
|
964 |
|
965 |
+
#: app/view/box_general_settings.php:43
|
966 |
+
msgid ""
|
967 |
+
"Show <strong>Post Your Event</strong> button above the calendar to "
|
968 |
+
"privileged users"
|
969 |
msgstr ""
|
970 |
|
971 |
+
#: app/view/box_general_settings.php:49
|
972 |
+
msgid ""
|
973 |
+
"Hide <strong>Subscribe</strong>/<strong>Add to Calendar</strong> buttons in "
|
974 |
+
"calendar and single event views"
|
975 |
msgstr ""
|
976 |
|
977 |
+
#: app/view/box_general_settings.php:55
|
978 |
+
msgid "Hide <strong>Google Maps</strong> until clicked"
|
979 |
msgstr ""
|
980 |
|
981 |
+
#: app/view/box_general_settings.php:61
|
982 |
+
msgid ""
|
983 |
+
"Use the configured <strong>region</strong> (WordPress locale) to bias the "
|
984 |
+
"address autocomplete function"
|
985 |
msgstr ""
|
986 |
|
987 |
+
#: app/view/box_general_settings.php:67
|
988 |
+
msgid "Include <strong>event categories</strong> in post category lists"
|
989 |
msgstr ""
|
990 |
|
991 |
+
#: app/view/box_general_settings.php:71
|
992 |
+
msgid "Adding/Editing Events"
|
993 |
msgstr ""
|
994 |
|
995 |
+
#: app/view/box_general_settings.php:73
|
996 |
+
msgid "Input dates in this format:"
|
|
|
|
|
|
|
997 |
msgstr ""
|
998 |
|
999 |
+
#: app/view/box_general_settings.php:79
|
1000 |
+
msgid "Use <strong>24h time</strong> in time pickers"
|
|
|
|
|
1001 |
msgstr ""
|
1002 |
|
1003 |
+
#: app/view/box_general_settings.php:85
|
1004 |
+
msgid "Display <strong>Publish</strong> at bottom of Edit Event form"
|
|
|
|
|
|
|
|
|
1005 |
msgstr ""
|
1006 |
|
1007 |
+
#: app/view/agenda-widget.php:11
|
1008 |
+
msgid "There are no upcoming events."
|
|
|
|
|
1009 |
msgstr ""
|
1010 |
|
1011 |
+
#: app/view/agenda-widget.php:59
|
1012 |
+
msgid "View Calendar »"
|
|
|
|
|
|
|
1013 |
msgstr ""
|
1014 |
|
1015 |
+
#: app/view/agenda-widget.php:67 app/view/calendar.php:110
|
1016 |
+
msgid ""
|
1017 |
+
"Subscribe to this calendar using your favourite calendar program (iCal, "
|
1018 |
+
"Outlook, etc.)"
|
1019 |
msgstr ""
|
1020 |
|
1021 |
+
#: app/view/agenda-widget.php:68 app/view/calendar.php:111
|
1022 |
+
msgid "✔ Subscribe"
|
1023 |
msgstr ""
|
1024 |
|
1025 |
+
#: app/view/agenda-widget.php:72 app/view/calendar.php:116
|
1026 |
+
msgid "Subscribe to this calendar in your Google Calendar"
|
1027 |
msgstr ""
|
1028 |
|
1029 |
+
#: app/view/agenda-widget.php:74
|
1030 |
+
msgid "Add to Google"
|
1031 |
msgstr ""
|
1032 |
|
1033 |
+
#: app/view/box_event_contact.php:1
|
1034 |
+
msgid "Organizer contact info"
|
1035 |
msgstr ""
|
1036 |
|
1037 |
+
#: app/view/box_event_contact.php:7
|
1038 |
+
msgid "Contact name:"
|
1039 |
msgstr ""
|
1040 |
|
1041 |
+
#: app/view/box_event_contact.php:17
|
1042 |
+
msgid "Phone:"
|
1043 |
msgstr ""
|
1044 |
|
1045 |
+
#: app/view/box_event_contact.php:27
|
1046 |
+
msgid "E-mail:"
|
1047 |
msgstr ""
|
1048 |
|
1049 |
+
#: app/view/admin_notices.php:2
|
1050 |
+
msgid "All-in-One Event Calendar Notice:"
|
1051 |
msgstr ""
|
1052 |
|
1053 |
+
#: app/view/calendar.php:35
|
1054 |
+
msgid "+ Post Your Event"
|
1055 |
msgstr ""
|
1056 |
|
1057 |
+
#: app/view/calendar.php:44
|
1058 |
+
msgid "Clear Filters"
|
1059 |
msgstr ""
|
1060 |
|
1061 |
+
#: app/view/calendar.php:44
|
1062 |
+
msgid "✘"
|
|
|
1063 |
msgstr ""
|
1064 |
|
1065 |
+
#: app/view/calendar.php:45
|
1066 |
+
msgid "Filter:"
|
1067 |
msgstr ""
|
1068 |
|
1069 |
+
#: app/view/calendar.php:50
|
1070 |
+
msgid "Categories ▾"
|
1071 |
msgstr ""
|
1072 |
|
1073 |
+
#: app/view/calendar.php:72
|
1074 |
+
msgid "Tags ▾"
|
1075 |
msgstr ""
|
1076 |
|
1077 |
+
#: app/view/calendar.php:112
|
1078 |
+
msgid "to this filtered calendar"
|
1079 |
msgstr ""
|
1080 |
|
1081 |
+
#: app/view/calendar.php:118
|
1082 |
+
msgid "Subscribe in Google Calendar"
|
1083 |
msgstr ""
|
1084 |
|
1085 |
+
#: app/view/row_yearly.php:7
|
1086 |
+
msgctxt "Recurrence editor - yearly tab"
|
1087 |
+
msgid "In"
|
1088 |
msgstr ""
|
1089 |
|
1090 |
+
#: app/view/agenda.php:5
|
1091 |
+
msgid "+ Expand All"
|
1092 |
msgstr ""
|
1093 |
|
1094 |
+
#: app/view/agenda.php:8
|
1095 |
+
msgid "− Collapse All"
|
1096 |
msgstr ""
|
1097 |
|
1098 |
+
#: app/view/agenda.php:29
|
1099 |
+
msgid "There are no upcoming events to display at this time."
|
1100 |
msgstr ""
|
1101 |
|
1102 |
+
#: app/view/agenda.php:77
|
1103 |
+
msgid "Read more »"
|
1104 |
msgstr ""
|
1105 |
|
1106 |
+
#: app/view/event-single-footer.php:4
|
1107 |
+
msgid ""
|
1108 |
+
"This post was replicated from another site's <a class=\"ai1ec-ics-icon\" "
|
1109 |
+
"href=\"%s\" title=\"iCalendar feed\">calendar feed</a>."
|
1110 |
msgstr ""
|
1111 |
|
1112 |
+
#: app/view/event-single-footer.php:8
|
1113 |
+
msgid "View original post »"
|
|
|
1114 |
msgstr ""
|
1115 |
|
1116 |
+
#: app/view/agenda-widget-form.php:2
|
1117 |
+
msgid "Title:"
|
|
|
1118 |
msgstr ""
|
1119 |
|
1120 |
+
#: app/view/agenda-widget-form.php:6
|
1121 |
+
msgid "Number of events to show:"
|
1122 |
msgstr ""
|
1123 |
|
1124 |
+
#: app/view/agenda-widget-form.php:14
|
1125 |
+
msgid "Events with these <strong>Categories</strong>"
|
1126 |
msgstr ""
|
1127 |
|
1128 |
+
#: app/view/agenda-widget-form.php:23
|
1129 |
+
msgid "No categories found."
|
1130 |
msgstr ""
|
1131 |
|
1132 |
+
#: app/view/agenda-widget-form.php:30
|
1133 |
+
msgid "<strong>Or</strong> events with these <strong>Tags</strong>"
|
1134 |
msgstr ""
|
1135 |
|
1136 |
+
#: app/view/agenda-widget-form.php:39
|
1137 |
+
msgid "No tags found."
|
1138 |
msgstr ""
|
1139 |
|
1140 |
+
#: app/view/agenda-widget-form.php:46
|
1141 |
+
msgid "<strong>Or</strong> any of these <strong>Events</strong>"
|
1142 |
msgstr ""
|
1143 |
|
1144 |
+
#: app/view/agenda-widget-form.php:55
|
1145 |
+
msgid "No events found."
|
1146 |
msgstr ""
|
1147 |
|
1148 |
+
#: app/view/agenda-widget-form.php:62
|
1149 |
+
msgid "Show <strong>View Calendar</strong> button"
|
1150 |
msgstr ""
|
1151 |
|
1152 |
+
#: app/view/agenda-widget-form.php:65
|
1153 |
+
msgid "Show <strong>Subscribe</strong> buttons"
|
1154 |
msgstr ""
|
1155 |
|
1156 |
+
#: app/view/agenda-widget-form.php:68
|
1157 |
+
msgid "Hide this widget on calendar page"
|
1158 |
msgstr ""
|
1159 |
|
1160 |
+
#: app/view/box_time_and_date.php:2
|
1161 |
+
msgid "Event date and time"
|
|
|
1162 |
msgstr ""
|
1163 |
|
1164 |
+
#: app/view/box_time_and_date.php:8
|
1165 |
+
msgid "All-day event"
|
|
|
1166 |
msgstr ""
|
1167 |
|
1168 |
+
#: app/view/box_time_and_date.php:18
|
1169 |
+
msgid "Start date / time"
|
|
|
1170 |
msgstr ""
|
1171 |
|
1172 |
+
#: app/view/box_time_and_date.php:31
|
1173 |
+
msgid "End date / time"
|
|
|
1174 |
msgstr ""
|
1175 |
|
1176 |
+
#: app/view/box_time_and_date.php:46
|
1177 |
+
msgid "Repeat"
|
1178 |
msgstr ""
|
1179 |
|
1180 |
+
#: app/view/box_time_and_date.php:70
|
1181 |
+
msgid "End"
|
|
|
|
|
1182 |
msgstr ""
|
1183 |
|
1184 |
+
#: app/view/box_time_and_date.php:77
|
1185 |
+
msgid "Ending after"
|
1186 |
msgstr ""
|
1187 |
|
1188 |
+
#: app/view/box_time_and_date.php:92
|
1189 |
+
msgid "Apply"
|
1190 |
msgstr ""
|
1191 |
|
1192 |
+
#: app/view/box_time_and_date.php:93
|
1193 |
+
msgid "Cancel"
|
1194 |
msgstr ""
|
1195 |
|
1196 |
+
#: app/view/box_ics_import_settings.php:2
|
1197 |
+
msgid "Auto-refresh"
|
1198 |
msgstr ""
|
1199 |
|
1200 |
+
#: app/view/box_ics_import_settings.php:12
|
1201 |
+
msgid "Event category"
|
|
|
|
|
|
|
1202 |
msgstr ""
|
1203 |
|
1204 |
+
#: app/view/box_ics_import_settings.php:22
|
1205 |
+
msgid "+ Add new subscription"
|
|
|
|
|
1206 |
msgstr ""
|
1207 |
|
1208 |
+
#: app/view/week.php:33
|
1209 |
+
msgid "All-day"
|
|
|
|
|
1210 |
msgstr ""
|
1211 |
|
1212 |
+
#: app/view/event_categories-color_picker.php:5
|
1213 |
+
#: app/view/event_categories-color_picker.php:19
|
1214 |
+
msgid "Category Color"
|
|
|
1215 |
msgstr ""
|
1216 |
|
1217 |
+
#: app/view/event_categories-color_picker.php:13
|
1218 |
+
#: app/view/event_categories-color_picker.php:25
|
1219 |
+
msgid "Events in this category will be identified by this color"
|
1220 |
+
msgstr ""
|
1221 |
+
|
1222 |
+
#: app/model/class-ai1ec-event.php:486
|
1223 |
+
msgid " (all-day)"
|
1224 |
msgstr ""
|
1225 |
|
1226 |
#. Plugin Name of the plugin/theme
|
lib/{iCalUtilityFunctions.class.php → iCalcreator-2.10.23/iCalUtilityFunctions.class.php}
RENAMED
File without changes
|
lib/{iCalcreator.class.php → iCalcreator-2.10.23/iCalcreator.class.php}
RENAMED
File without changes
|
lib/{lgpl.txt → iCalcreator-2.10.23/lgpl.txt}
RENAMED
File without changes
|
lib/{releaseNotes-2.10.23.txt → iCalcreator-2.10.23/releaseNotes-2.10.23.txt}
RENAMED
File without changes
|
lib/{summary.html → iCalcreator-2.10.23/summary.html}
RENAMED
File without changes
|
lib/{using.html → iCalcreator-2.10.23/using.html}
RENAMED
File without changes
|
lib/iCalcreator-2.10/iCalUtilityFunctions.class.php
ADDED
@@ -0,0 +1,1505 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* iCalcreator class v2.10
|
4 |
+
* copyright (c) 2007-2011 Kjell-Inge Gustafsson kigkonsult
|
5 |
+
* www.kigkonsult.se/iCalcreator/index.php
|
6 |
+
* ical@kigkonsult.se
|
7 |
+
*
|
8 |
+
* This library is free software; you can redistribute it and/or
|
9 |
+
* modify it under the terms of the GNU Lesser General Public
|
10 |
+
* License as published by the Free Software Foundation; either
|
11 |
+
* version 2.1 of the License, or (at your option) any later version.
|
12 |
+
*
|
13 |
+
* This library is distributed in the hope that it will be useful,
|
14 |
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15 |
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
16 |
+
* Lesser General Public License for more details.
|
17 |
+
*
|
18 |
+
* You should have received a copy of the GNU Lesser General Public
|
19 |
+
* License along with this library; if not, write to the Free Software
|
20 |
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
21 |
+
*/
|
22 |
+
/**
|
23 |
+
* moving all utility (static) functions to a utility class
|
24 |
+
*
|
25 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
26 |
+
* @since 2.6.22 - 2010-09-25
|
27 |
+
*
|
28 |
+
*/
|
29 |
+
class iCalUtilityFunctions {
|
30 |
+
// Store the single instance of iCalUtilityFunctions
|
31 |
+
private static $m_pInstance;
|
32 |
+
|
33 |
+
// Private constructor to limit object instantiation to within the class
|
34 |
+
private function __construct() {
|
35 |
+
$m_pInstance = FALSE;
|
36 |
+
}
|
37 |
+
|
38 |
+
// Getter method for creating/returning the single instance of this class
|
39 |
+
public static function getInstance() {
|
40 |
+
if (!self::$m_pInstance)
|
41 |
+
self::$m_pInstance = new iCalUtilityFunctions();
|
42 |
+
|
43 |
+
return self::$m_pInstance;
|
44 |
+
}
|
45 |
+
/**
|
46 |
+
* check a date(-time) for an opt. timezone and if it is a DATE-TIME or DATE
|
47 |
+
*
|
48 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
49 |
+
* @since 2.4.16 - 2008-10-25
|
50 |
+
* @param array $date, date to check
|
51 |
+
* @param int $parno, no of date parts (i.e. year, month.. .)
|
52 |
+
* @return array $params, property parameters
|
53 |
+
*/
|
54 |
+
public static function _chkdatecfg( $theDate, & $parno, & $params ) {
|
55 |
+
if( isset( $params['TZID'] ))
|
56 |
+
$parno = 6;
|
57 |
+
elseif( isset( $params['VALUE'] ) && ( 'DATE' == $params['VALUE'] ))
|
58 |
+
$parno = 3;
|
59 |
+
else {
|
60 |
+
if( isset( $params['VALUE'] ) && ( 'PERIOD' == $params['VALUE'] ))
|
61 |
+
$parno = 7;
|
62 |
+
if( is_array( $theDate )) {
|
63 |
+
if( isset( $theDate['timestamp'] ))
|
64 |
+
$tzid = ( isset( $theDate['tz'] )) ? $theDate['tz'] : null;
|
65 |
+
else
|
66 |
+
$tzid = ( isset( $theDate['tz'] )) ? $theDate['tz'] : ( 7 == count( $theDate )) ? end( $theDate ) : null;
|
67 |
+
if( !empty( $tzid )) {
|
68 |
+
$parno = 7;
|
69 |
+
if( !iCalUtilityFunctions::_isOffset( $tzid ))
|
70 |
+
$params['TZID'] = $tzid; // save only timezone
|
71 |
+
}
|
72 |
+
elseif( !$parno && ( 3 == count( $theDate )) &&
|
73 |
+
( isset( $params['VALUE'] ) && ( 'DATE' == $params['VALUE'] )))
|
74 |
+
$parno = 3;
|
75 |
+
else
|
76 |
+
$parno = 6;
|
77 |
+
}
|
78 |
+
else { // string
|
79 |
+
$date = trim( $theDate );
|
80 |
+
if( 'Z' == substr( $date, -1 ))
|
81 |
+
$parno = 7; // UTC DATE-TIME
|
82 |
+
elseif((( 8 == strlen( $date ) && ctype_digit( $date )) || ( 11 >= strlen( $date ))) &&
|
83 |
+
( !isset( $params['VALUE'] ) || !in_array( $params['VALUE'], array( 'DATE-TIME', 'PERIOD' ))))
|
84 |
+
$parno = 3; // DATE
|
85 |
+
$date = iCalUtilityFunctions::_date_time_string( $date, $parno );
|
86 |
+
if( !empty( $date['tz'] )) {
|
87 |
+
$parno = 7;
|
88 |
+
if( !iCalUtilityFunctions::_isOffset( $date['tz'] ))
|
89 |
+
$params['TZID'] = $date['tz']; // save only timezone
|
90 |
+
}
|
91 |
+
elseif( empty( $parno ))
|
92 |
+
$parno = 6;
|
93 |
+
}
|
94 |
+
if( isset( $params['TZID'] ))
|
95 |
+
$parno = 6;
|
96 |
+
}
|
97 |
+
}
|
98 |
+
/**
|
99 |
+
* create (very simple) timezone and standard/daylight components
|
100 |
+
*
|
101 |
+
* Result when 'Europe/Stockholm' is used as timezone:
|
102 |
+
*
|
103 |
+
* BEGIN:VTIMEZONE
|
104 |
+
* TZID:Europe/Stockholm
|
105 |
+
* BEGIN:STANDARD
|
106 |
+
* DTSTART:20101031T020000
|
107 |
+
* TZOFFSETFROM:+0200
|
108 |
+
* TZOFFSETTO:+0100
|
109 |
+
* RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
|
110 |
+
* TZNAME:CET
|
111 |
+
* END:STANDARD
|
112 |
+
* BEGIN:DAYLIGHT
|
113 |
+
* DTSTART:20100328T030000
|
114 |
+
* TZOFFSETFROM:+0100
|
115 |
+
* TZOFFSETTO:+0200
|
116 |
+
* RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
|
117 |
+
* TZNAME:CEST
|
118 |
+
* END:DAYLIGHT
|
119 |
+
* END:VTIMEZONE
|
120 |
+
*
|
121 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
122 |
+
* @since 2.9.2 - 2011-05-30
|
123 |
+
* @param object $calendar, reference to an iCalcreator calendar instance
|
124 |
+
* @param string $timezone, a PHP5 (DateTimeZone) valid timezone
|
125 |
+
* @param array $xProp, *[x-propName => x-propValue], optional
|
126 |
+
* @return bool
|
127 |
+
*/
|
128 |
+
public static function createTimezone( & $calendar, $timezone, $xProp=array() ) {
|
129 |
+
if( !class_exists( 'DateTimeZone' ))
|
130 |
+
return FALSE;
|
131 |
+
if( empty( $timezone ))
|
132 |
+
return FALSE;
|
133 |
+
try {
|
134 |
+
$dtz = new DateTimeZone( $timezone );
|
135 |
+
$transitions = $dtz->getTransitions();
|
136 |
+
$stdDTSTART = $stdTZOFFSETTO = $stdTZOFFSETFROM = $stdTZNAME = $dlghtDTSTART = $dlghtTZOFFSETTO = $dlghtTZOFFSETFROM = $dlghtTZNAME = FALSE;
|
137 |
+
foreach( $transitions as $trans ) {
|
138 |
+
if( substr( $trans['time'], 0, 4 ) > ( date( 'Y' ) - 1 ))
|
139 |
+
break;
|
140 |
+
if( $trans['isdst'] !== TRUE ) {
|
141 |
+
$stdDTSTART = $trans['time'];
|
142 |
+
$stdTZOFFSETTO = $dlghtTZOFFSETFROM = iCalUtilityFunctions::offsetSec2His( $trans['offset'] );
|
143 |
+
$stdTZNAME = $trans['abbr'];
|
144 |
+
}
|
145 |
+
else {
|
146 |
+
$dlghtDTSTART = $trans['time'];
|
147 |
+
$dlghtTZOFFSETTO = $stdTZOFFSETFROM = iCalUtilityFunctions::offsetSec2His( $trans['offset'] );
|
148 |
+
$dlghtTZNAME = $trans['abbr'];
|
149 |
+
}
|
150 |
+
}
|
151 |
+
if( $stdDTSTART && $stdTZOFFSETTO && $stdTZOFFSETFROM && $stdTZNAME && $dlghtDTSTART && $dlghtTZOFFSETTO && $dlghtTZOFFSETFROM && $dlghtTZNAME ) {
|
152 |
+
$tz = & $calendar->newComponent( 'vtimezone' );
|
153 |
+
$tz->setproperty( 'tzid', $timezone );
|
154 |
+
if( !empty( $xProp )) {
|
155 |
+
foreach( $xProp as $xPropName => $xPropValue )
|
156 |
+
if( 'x-' == strtolower( substr( $xPropName, 0, 2 )))
|
157 |
+
$tz->setproperty( $xPropName, $xPropValue );
|
158 |
+
}
|
159 |
+
$std = & $tz->newComponent( 'standard' );
|
160 |
+
$std->setProperty( 'dtstart', $stdDTSTART );
|
161 |
+
$std->setProperty( 'tzname', $stdTZNAME );
|
162 |
+
$std->setProperty( 'tzoffsetto', $stdTZOFFSETTO );
|
163 |
+
$std->setProperty( 'tzoffsetfrom', $stdTZOFFSETFROM );
|
164 |
+
$std->setProperty( 'RRULE', array( 'FREQ' => 'YEARLY', 'BYDAY' => array( '-1', 'DAY' => 'SU' ), 'BYMONTH' => 10 ));
|
165 |
+
$dlght = & $tz->newComponent( 'daylight' );
|
166 |
+
$dlght->setProperty( 'dtstart', $dlghtDTSTART );
|
167 |
+
$dlght->setProperty( 'tzname', $dlghtTZNAME );
|
168 |
+
$dlght->setProperty( 'tzoffsetto', $dlghtTZOFFSETTO );
|
169 |
+
$dlght->setProperty( 'tzoffsetfrom', $dlghtTZOFFSETFROM );
|
170 |
+
$dlght->setProperty( 'RRULE', array( 'FREQ' => 'YEARLY', 'BYDAY' => array( '-1', 'DAY' => 'SU' ), 'BYMONTH' => 3 ));
|
171 |
+
}
|
172 |
+
}
|
173 |
+
catch( Exception $e ) {
|
174 |
+
return FALSE;
|
175 |
+
}
|
176 |
+
return TRUE;
|
177 |
+
}
|
178 |
+
/**
|
179 |
+
* convert date/datetime to timestamp
|
180 |
+
*
|
181 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
182 |
+
* @since 2.4.8 - 2008-10-30
|
183 |
+
* @param array $datetime datetime/(date)
|
184 |
+
* @param string $tz timezone
|
185 |
+
* @return timestamp
|
186 |
+
*/
|
187 |
+
public static function _date2timestamp( $datetime, $tz=null ) {
|
188 |
+
$output = null;
|
189 |
+
if( !isset( $datetime['hour'] )) $datetime['hour'] = '0';
|
190 |
+
if( !isset( $datetime['min'] )) $datetime['min'] = '0';
|
191 |
+
if( !isset( $datetime['sec'] )) $datetime['sec'] = '0';
|
192 |
+
foreach( $datetime as $dkey => $dvalue ) {
|
193 |
+
if( 'tz' != $dkey )
|
194 |
+
$datetime[$dkey] = (integer) $dvalue;
|
195 |
+
}
|
196 |
+
if( $tz )
|
197 |
+
$datetime['tz'] = $tz;
|
198 |
+
$offset = ( isset( $datetime['tz'] ) && ( '' < trim ( $datetime['tz'] ))) ? iCalUtilityFunctions::_tz2offset( $datetime['tz'] ) : 0;
|
199 |
+
$output = mktime( $datetime['hour'], $datetime['min'], ($datetime['sec'] + $offset), $datetime['month'], $datetime['day'], $datetime['year'] );
|
200 |
+
return $output;
|
201 |
+
}
|
202 |
+
/**
|
203 |
+
* ensures internal date-time/date format for input date-time/date in array format
|
204 |
+
*
|
205 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
206 |
+
* @since 0.3.0 - 2006-08-15
|
207 |
+
* @param array $datetime
|
208 |
+
* @param int $parno optional, default FALSE
|
209 |
+
* @return array
|
210 |
+
*/
|
211 |
+
public static function _date_time_array( $datetime, $parno=FALSE ) {
|
212 |
+
$output = array();
|
213 |
+
foreach( $datetime as $dateKey => $datePart ) {
|
214 |
+
switch ( $dateKey ) {
|
215 |
+
case '0': case 'year': $output['year'] = $datePart; break;
|
216 |
+
case '1': case 'month': $output['month'] = $datePart; break;
|
217 |
+
case '2': case 'day': $output['day'] = $datePart; break;
|
218 |
+
}
|
219 |
+
if( 3 != $parno ) {
|
220 |
+
switch ( $dateKey ) {
|
221 |
+
case '0':
|
222 |
+
case '1':
|
223 |
+
case '2': break;
|
224 |
+
case '3': case 'hour': $output['hour'] = $datePart; break;
|
225 |
+
case '4': case 'min' : $output['min'] = $datePart; break;
|
226 |
+
case '5': case 'sec' : $output['sec'] = $datePart; break;
|
227 |
+
case '6': case 'tz' : $output['tz'] = $datePart; break;
|
228 |
+
}
|
229 |
+
}
|
230 |
+
}
|
231 |
+
if( 3 != $parno ) {
|
232 |
+
if( !isset( $output['hour'] ))
|
233 |
+
$output['hour'] = 0;
|
234 |
+
if( !isset( $output['min'] ))
|
235 |
+
$output['min'] = 0;
|
236 |
+
if( !isset( $output['sec'] ))
|
237 |
+
$output['sec'] = 0;
|
238 |
+
}
|
239 |
+
return $output;
|
240 |
+
}
|
241 |
+
/**
|
242 |
+
* ensures internal date-time/date format for input date-time/date in string fromat
|
243 |
+
*
|
244 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
245 |
+
* @since 2.6.35 - 2010-12-03
|
246 |
+
* @param array $datetime
|
247 |
+
* @param int $parno optional, default FALSE
|
248 |
+
* @return array
|
249 |
+
*/
|
250 |
+
public static function _date_time_string( $datetime, $parno=FALSE ) {
|
251 |
+
$datetime = (string) trim( $datetime );
|
252 |
+
$tz = null;
|
253 |
+
$len = strlen( $datetime ) - 1;
|
254 |
+
if( 'Z' == substr( $datetime, -1 )) {
|
255 |
+
$tz = 'Z';
|
256 |
+
$datetime = trim( substr( $datetime, 0, $len ));
|
257 |
+
}
|
258 |
+
elseif( ( ctype_digit( substr( $datetime, -2, 2 ))) && // time or date
|
259 |
+
( '-' == substr( $datetime, -3, 1 )) ||
|
260 |
+
( ':' == substr( $datetime, -3, 1 )) ||
|
261 |
+
( '.' == substr( $datetime, -3, 1 ))) {
|
262 |
+
$continue = TRUE;
|
263 |
+
}
|
264 |
+
elseif( ( ctype_digit( substr( $datetime, -4, 4 ))) && // 4 pos offset
|
265 |
+
( ' +' == substr( $datetime, -6, 2 )) ||
|
266 |
+
( ' -' == substr( $datetime, -6, 2 ))) {
|
267 |
+
$tz = substr( $datetime, -5, 5 );
|
268 |
+
$datetime = substr( $datetime, 0, ($len - 5));
|
269 |
+
}
|
270 |
+
elseif( ( ctype_digit( substr( $datetime, -6, 6 ))) && // 6 pos offset
|
271 |
+
( ' +' == substr( $datetime, -8, 2 )) ||
|
272 |
+
( ' -' == substr( $datetime, -8, 2 ))) {
|
273 |
+
$tz = substr( $datetime, -7, 7 );
|
274 |
+
$datetime = substr( $datetime, 0, ($len - 7));
|
275 |
+
}
|
276 |
+
elseif( ( 6 < $len ) && ( ctype_digit( substr( $datetime, -6, 6 )))) {
|
277 |
+
$continue = TRUE;
|
278 |
+
}
|
279 |
+
elseif( 'T' == substr( $datetime, -7, 1 )) {
|
280 |
+
$continue = TRUE;
|
281 |
+
}
|
282 |
+
else {
|
283 |
+
$cx = $tx = 0; // 19970415T133000 US-Eastern
|
284 |
+
for( $cx = -1; $cx > ( 9 - $len ); $cx-- ) {
|
285 |
+
$char = substr( $datetime, $cx, 1 );
|
286 |
+
if(( ' ' == $char) || ctype_digit( $char))
|
287 |
+
break; // if exists, tz ends here.. . ?
|
288 |
+
else
|
289 |
+
$tx--; // tz length counter
|
290 |
+
}
|
291 |
+
if( 0 > $tx ) {
|
292 |
+
$tz = substr( $datetime, $tx );
|
293 |
+
$datetime = trim( substr( $datetime, 0, $len + $tx + 1 ));
|
294 |
+
}
|
295 |
+
}
|
296 |
+
if( 0 < substr_count( $datetime, '-' )) {
|
297 |
+
$datetime = str_replace( '-', '/', $datetime );
|
298 |
+
}
|
299 |
+
elseif( ctype_digit( substr( $datetime, 0, 8 )) &&
|
300 |
+
( 'T' == substr( $datetime, 8, 1 )) &&
|
301 |
+
ctype_digit( substr( $datetime, 9, 6 ))) {
|
302 |
+
$datetime = substr( $datetime, 4, 2 )
|
303 |
+
.'/'.substr( $datetime, 6, 2 )
|
304 |
+
.'/'.substr( $datetime, 0, 4 )
|
305 |
+
.' '.substr( $datetime, 9, 2 )
|
306 |
+
.':'.substr( $datetime, 11, 2 )
|
307 |
+
.':'.substr( $datetime, 13);
|
308 |
+
}
|
309 |
+
$datestring = date( 'Y-m-d H:i:s', strtotime( $datetime ));
|
310 |
+
$tz = trim( $tz );
|
311 |
+
$output = array();
|
312 |
+
$output['year'] = substr( $datestring, 0, 4 );
|
313 |
+
$output['month'] = substr( $datestring, 5, 2 );
|
314 |
+
$output['day'] = substr( $datestring, 8, 2 );
|
315 |
+
if(( 6 == $parno ) || ( 7 == $parno ) || ( !$parno && ( 'Z' == $tz ))) {
|
316 |
+
$output['hour'] = substr( $datestring, 11, 2 );
|
317 |
+
$output['min'] = substr( $datestring, 14, 2 );
|
318 |
+
$output['sec'] = substr( $datestring, 17, 2 );
|
319 |
+
if( !empty( $tz ))
|
320 |
+
$output['tz'] = $tz;
|
321 |
+
}
|
322 |
+
elseif( 3 != $parno ) {
|
323 |
+
if(( '00' < substr( $datestring, 11, 2 )) ||
|
324 |
+
( '00' < substr( $datestring, 14, 2 )) ||
|
325 |
+
( '00' < substr( $datestring, 17, 2 ))) {
|
326 |
+
$output['hour'] = substr( $datestring, 11, 2 );
|
327 |
+
$output['min'] = substr( $datestring, 14, 2 );
|
328 |
+
$output['sec'] = substr( $datestring, 17, 2 );
|
329 |
+
}
|
330 |
+
if( !empty( $tz ))
|
331 |
+
$output['tz'] = $tz;
|
332 |
+
}
|
333 |
+
return $output;
|
334 |
+
}
|
335 |
+
/**
|
336 |
+
* convert local startdate/enddate (Ymd[His]) to duration array
|
337 |
+
*
|
338 |
+
* uses this component dates if missing input dates
|
339 |
+
*
|
340 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
341 |
+
* @since 2.6.11 - 2010-10-21
|
342 |
+
* @param array $startdate
|
343 |
+
* @param array $duration
|
344 |
+
* @return array duration
|
345 |
+
*/
|
346 |
+
function _date2duration( $startdate, $enddate ) {
|
347 |
+
$startWdate = mktime( 0, 0, 0, $startdate['month'], $startdate['day'], $startdate['year'] );
|
348 |
+
$endWdate = mktime( 0, 0, 0, $enddate['month'], $enddate['day'], $enddate['year'] );
|
349 |
+
$wduration = $endWdate - $startWdate;
|
350 |
+
$dur = array();
|
351 |
+
$dur['week'] = (int) floor( $wduration / ( 7 * 24 * 60 * 60 ));
|
352 |
+
$wduration = $wduration % ( 7 * 24 * 60 * 60 );
|
353 |
+
$dur['day'] = (int) floor( $wduration / ( 24 * 60 * 60 ));
|
354 |
+
$wduration = $wduration % ( 24 * 60 * 60 );
|
355 |
+
$dur['hour'] = (int) floor( $wduration / ( 60 * 60 ));
|
356 |
+
$wduration = $wduration % ( 60 * 60 );
|
357 |
+
$dur['min'] = (int) floor( $wduration / ( 60 ));
|
358 |
+
$dur['sec'] = (int) $wduration % ( 60 );
|
359 |
+
return $dur;
|
360 |
+
}
|
361 |
+
/**
|
362 |
+
* ensures internal duration format for input in array format
|
363 |
+
*
|
364 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
365 |
+
* @since 2.1.1 - 2007-06-24
|
366 |
+
* @param array $duration
|
367 |
+
* @return array
|
368 |
+
*/
|
369 |
+
public static function _duration_array( $duration ) {
|
370 |
+
$output = array();
|
371 |
+
if( is_array( $duration ) &&
|
372 |
+
( 1 == count( $duration )) &&
|
373 |
+
isset( $duration['sec'] ) &&
|
374 |
+
( 60 < $duration['sec'] )) {
|
375 |
+
$durseconds = $duration['sec'];
|
376 |
+
$output['week'] = floor( $durseconds / ( 60 * 60 * 24 * 7 ));
|
377 |
+
$durseconds = $durseconds % ( 60 * 60 * 24 * 7 );
|
378 |
+
$output['day'] = floor( $durseconds / ( 60 * 60 * 24 ));
|
379 |
+
$durseconds = $durseconds % ( 60 * 60 * 24 );
|
380 |
+
$output['hour'] = floor( $durseconds / ( 60 * 60 ));
|
381 |
+
$durseconds = $durseconds % ( 60 * 60 );
|
382 |
+
$output['min'] = floor( $durseconds / ( 60 ));
|
383 |
+
$output['sec'] = ( $durseconds % ( 60 ));
|
384 |
+
}
|
385 |
+
else {
|
386 |
+
foreach( $duration as $durKey => $durValue ) {
|
387 |
+
if( empty( $durValue )) continue;
|
388 |
+
switch ( $durKey ) {
|
389 |
+
case '0': case 'week': $output['week'] = $durValue; break;
|
390 |
+
case '1': case 'day': $output['day'] = $durValue; break;
|
391 |
+
case '2': case 'hour': $output['hour'] = $durValue; break;
|
392 |
+
case '3': case 'min': $output['min'] = $durValue; break;
|
393 |
+
case '4': case 'sec': $output['sec'] = $durValue; break;
|
394 |
+
}
|
395 |
+
}
|
396 |
+
}
|
397 |
+
if( isset( $output['week'] ) && ( 0 < $output['week'] )) {
|
398 |
+
unset( $output['day'], $output['hour'], $output['min'], $output['sec'] );
|
399 |
+
return $output;
|
400 |
+
}
|
401 |
+
unset( $output['week'] );
|
402 |
+
if( empty( $output['day'] ))
|
403 |
+
unset( $output['day'] );
|
404 |
+
if ( isset( $output['hour'] ) || isset( $output['min'] ) || isset( $output['sec'] )) {
|
405 |
+
if( !isset( $output['hour'] )) $output['hour'] = 0;
|
406 |
+
if( !isset( $output['min'] )) $output['min'] = 0;
|
407 |
+
if( !isset( $output['sec'] )) $output['sec'] = 0;
|
408 |
+
if(( 0 == $output['hour'] ) && ( 0 == $output['min'] ) && ( 0 == $output['sec'] ))
|
409 |
+
unset( $output['hour'], $output['min'], $output['sec'] );
|
410 |
+
}
|
411 |
+
return $output;
|
412 |
+
}
|
413 |
+
/**
|
414 |
+
* ensures internal duration format for input in string format
|
415 |
+
*
|
416 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
417 |
+
* @since 2.0.5 - 2007-03-14
|
418 |
+
* @param string $duration
|
419 |
+
* @return array
|
420 |
+
*/
|
421 |
+
public static function _duration_string( $duration ) {
|
422 |
+
$duration = (string) trim( $duration );
|
423 |
+
while( 'P' != strtoupper( substr( $duration, 0, 1 ))) {
|
424 |
+
if( 0 < strlen( $duration ))
|
425 |
+
$duration = substr( $duration, 1 );
|
426 |
+
else
|
427 |
+
return false; // no leading P !?!?
|
428 |
+
}
|
429 |
+
$duration = substr( $duration, 1 ); // skip P
|
430 |
+
$duration = str_replace ( 't', 'T', $duration );
|
431 |
+
$duration = str_replace ( 'T', '', $duration );
|
432 |
+
$output = array();
|
433 |
+
$val = null;
|
434 |
+
for( $ix=0; $ix < strlen( $duration ); $ix++ ) {
|
435 |
+
switch( strtoupper( substr( $duration, $ix, 1 ))) {
|
436 |
+
case 'W':
|
437 |
+
$output['week'] = $val;
|
438 |
+
$val = null;
|
439 |
+
break;
|
440 |
+
case 'D':
|
441 |
+
$output['day'] = $val;
|
442 |
+
$val = null;
|
443 |
+
break;
|
444 |
+
case 'H':
|
445 |
+
$output['hour'] = $val;
|
446 |
+
$val = null;
|
447 |
+
break;
|
448 |
+
case 'M':
|
449 |
+
$output['min'] = $val;
|
450 |
+
$val = null;
|
451 |
+
break;
|
452 |
+
case 'S':
|
453 |
+
$output['sec'] = $val;
|
454 |
+
$val = null;
|
455 |
+
break;
|
456 |
+
default:
|
457 |
+
if( !ctype_digit( substr( $duration, $ix, 1 )))
|
458 |
+
return false; // unknown duration control character !?!?
|
459 |
+
else
|
460 |
+
$val .= substr( $duration, $ix, 1 );
|
461 |
+
}
|
462 |
+
}
|
463 |
+
return iCalUtilityFunctions::_duration_array( $output );
|
464 |
+
}
|
465 |
+
/**
|
466 |
+
* convert duration to date in array format
|
467 |
+
*
|
468 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
469 |
+
* @since 2.8.7 - 2011-03-03
|
470 |
+
* @param array $startdate
|
471 |
+
* @param array $duration
|
472 |
+
* @return array, date format
|
473 |
+
*/
|
474 |
+
function _duration2date( $startdate=null, $duration=null ) {
|
475 |
+
if( empty( $startdate )) return FALSE;
|
476 |
+
if( empty( $duration )) return FALSE;
|
477 |
+
$dateOnly = ( isset( $startdate['hour'] ) || isset( $startdate['min'] ) || isset( $startdate['sec'] )) ? FALSE : TRUE;
|
478 |
+
$startdate['hour'] = ( isset( $startdate['hour'] )) ? $startdate['hour'] : 0;
|
479 |
+
$startdate['min'] = ( isset( $startdate['min'] )) ? $startdate['min'] : 0;
|
480 |
+
$startdate['sec'] = ( isset( $startdate['sec'] )) ? $startdate['sec'] : 0;
|
481 |
+
$dtend = 0;
|
482 |
+
if( isset( $duration['week'] ))
|
483 |
+
$dtend += ( $duration['week'] * 7 * 24 * 60 * 60 );
|
484 |
+
if( isset( $duration['day'] ))
|
485 |
+
$dtend += ( $duration['day'] * 24 * 60 * 60 );
|
486 |
+
if( isset( $duration['hour'] ))
|
487 |
+
$dtend += ( $duration['hour'] * 60 *60 );
|
488 |
+
if( isset( $duration['min'] ))
|
489 |
+
$dtend += ( $duration['min'] * 60 );
|
490 |
+
if( isset( $duration['sec'] ))
|
491 |
+
$dtend += $duration['sec'];
|
492 |
+
$dtend = mktime( $startdate['hour'], $startdate['min'], ( $startdate['sec'] + $dtend ), $startdate['month'], $startdate['day'], $startdate['year'] );
|
493 |
+
$dtend2 = array();
|
494 |
+
$dtend2['year'] = date('Y', $dtend );
|
495 |
+
$dtend2['month'] = date('m', $dtend );
|
496 |
+
$dtend2['day'] = date('d', $dtend );
|
497 |
+
$dtend2['hour'] = date('H', $dtend );
|
498 |
+
$dtend2['min'] = date('i', $dtend );
|
499 |
+
$dtend2['sec'] = date('s', $dtend );
|
500 |
+
if( isset( $startdate['tz'] ))
|
501 |
+
$dtend2['tz'] = $startdate['tz'];
|
502 |
+
if( $dateOnly && (( 0 == $dtend2['hour'] ) && ( 0 == $dtend2['min'] ) && ( 0 == $dtend2['sec'] )))
|
503 |
+
unset( $dtend2['hour'], $dtend2['min'], $dtend2['sec'] );
|
504 |
+
return $dtend2;
|
505 |
+
}
|
506 |
+
/**
|
507 |
+
* if not preSet, if exist, remove key with expected value from array and return hit value else return elseValue
|
508 |
+
*
|
509 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
510 |
+
* @since 2.4.16 - 2008-11-08
|
511 |
+
* @param array $array
|
512 |
+
* @param string $expkey, expected key
|
513 |
+
* @param string $expval, expected value
|
514 |
+
* @param int $hitVal optional, return value if found
|
515 |
+
* @param int $elseVal optional, return value if not found
|
516 |
+
* @param int $preSet optional, return value if already preset
|
517 |
+
* @return int
|
518 |
+
*/
|
519 |
+
public static function _existRem( &$array, $expkey, $expval=FALSE, $hitVal=null, $elseVal=null, $preSet=null ) {
|
520 |
+
if( $preSet )
|
521 |
+
return $preSet;
|
522 |
+
if( !is_array( $array ) || ( 0 == count( $array )))
|
523 |
+
return $elseVal;
|
524 |
+
foreach( $array as $key => $value ) {
|
525 |
+
if( strtoupper( $expkey ) == strtoupper( $key )) {
|
526 |
+
if( !$expval || ( strtoupper( $expval ) == strtoupper( $array[$key] ))) {
|
527 |
+
unset( $array[$key] );
|
528 |
+
return $hitVal;
|
529 |
+
}
|
530 |
+
}
|
531 |
+
}
|
532 |
+
return $elseVal;
|
533 |
+
}
|
534 |
+
/**
|
535 |
+
* creates formatted output for calendar component property data value type date/date-time
|
536 |
+
*
|
537 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
538 |
+
* @since 2.4.8 - 2008-10-30
|
539 |
+
* @param array $datetime
|
540 |
+
* @param int $parno, optional, default 6
|
541 |
+
* @return string
|
542 |
+
*/
|
543 |
+
public static function _format_date_time( $datetime, $parno=6 ) {
|
544 |
+
if( !isset( $datetime['year'] ) &&
|
545 |
+
!isset( $datetime['month'] ) &&
|
546 |
+
!isset( $datetime['day'] ) &&
|
547 |
+
!isset( $datetime['hour'] ) &&
|
548 |
+
!isset( $datetime['min'] ) &&
|
549 |
+
!isset( $datetime['sec'] ))
|
550 |
+
return ;
|
551 |
+
$output = null;
|
552 |
+
// 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"; }
|
553 |
+
foreach( $datetime as $dkey => & $dvalue )
|
554 |
+
if( 'tz' != $dkey ) $dvalue = (integer) $dvalue;
|
555 |
+
$output = date('Ymd', mktime( 0, 0, 0, $datetime['month'], $datetime['day'], $datetime['year']));
|
556 |
+
if( isset( $datetime['hour'] ) ||
|
557 |
+
isset( $datetime['min'] ) ||
|
558 |
+
isset( $datetime['sec'] ) ||
|
559 |
+
isset( $datetime['tz'] )) {
|
560 |
+
if( isset( $datetime['tz'] ) &&
|
561 |
+
!isset( $datetime['hour'] ))
|
562 |
+
$datetime['hour'] = 0;
|
563 |
+
if( isset( $datetime['hour'] ) &&
|
564 |
+
!isset( $datetime['min'] ))
|
565 |
+
$datetime['min'] = 0;
|
566 |
+
if( isset( $datetime['hour'] ) &&
|
567 |
+
isset( $datetime['min'] ) &&
|
568 |
+
!isset( $datetime['sec'] ))
|
569 |
+
$datetime['sec'] = 0;
|
570 |
+
$date = mktime( $datetime['hour'], $datetime['min'], $datetime['sec'], $datetime['month'], $datetime['day'], $datetime['year']);
|
571 |
+
$output .= date('\THis', $date );
|
572 |
+
if( isset( $datetime['tz'] ) && ( '' < trim ( $datetime['tz'] ))) {
|
573 |
+
$datetime['tz'] = trim( $datetime['tz'] );
|
574 |
+
if( 'Z' == $datetime['tz'] )
|
575 |
+
$output .= 'Z';
|
576 |
+
$offset = iCalUtilityFunctions::_tz2offset( $datetime['tz'] );
|
577 |
+
if( 0 != $offset ) {
|
578 |
+
$date = mktime( $datetime['hour'], $datetime['min'], ($datetime['sec'] + $offset), $datetime['month'], $datetime['day'], $datetime['year']);
|
579 |
+
$output = date( 'Ymd\THis\Z', $date );
|
580 |
+
}
|
581 |
+
}
|
582 |
+
elseif( 7 == $parno )
|
583 |
+
$output .= 'Z';
|
584 |
+
}
|
585 |
+
return $output;
|
586 |
+
}
|
587 |
+
/**
|
588 |
+
* creates formatted output for calendar component property data value type duration
|
589 |
+
*
|
590 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
591 |
+
* @since 2.9.9 - 2011-06-17
|
592 |
+
* @param array $duration ( week, day, hour, min, sec )
|
593 |
+
* @return string
|
594 |
+
*/
|
595 |
+
public static function _format_duration( $duration ) {
|
596 |
+
if( isset( $duration['week'] ) ||
|
597 |
+
isset( $duration['day'] ) ||
|
598 |
+
isset( $duration['hour'] ) ||
|
599 |
+
isset( $duration['min'] ) ||
|
600 |
+
isset( $duration['sec'] ))
|
601 |
+
$ok = TRUE;
|
602 |
+
else
|
603 |
+
return;
|
604 |
+
if( isset( $duration['week'] ) && ( 0 < $duration['week'] ))
|
605 |
+
return 'P'.$duration['week'].'W';
|
606 |
+
$output = 'P';
|
607 |
+
if( isset($duration['day'] ) && ( 0 < $duration['day'] ))
|
608 |
+
$output .= $duration['day'].'D';
|
609 |
+
if(( isset( $duration['hour']) && ( 0 < $duration['hour'] )) ||
|
610 |
+
( isset( $duration['min']) && ( 0 < $duration['min'] )) ||
|
611 |
+
( isset( $duration['sec']) && ( 0 < $duration['sec'] )))
|
612 |
+
$output .= 'T';
|
613 |
+
$output .= ( isset( $duration['hour']) && ( 0 < $duration['hour'] )) ? $duration['hour'].'H' : '';
|
614 |
+
$output .= ( isset( $duration['min']) && ( 0 < $duration['min'] )) ? $duration['min']. 'M' : '';
|
615 |
+
$output .= ( isset( $duration['sec']) && ( 0 < $duration['sec'] )) ? $duration['sec']. 'S' : '';
|
616 |
+
if( 'P' == $output )
|
617 |
+
$output = 'PT0S';
|
618 |
+
return $output;
|
619 |
+
}
|
620 |
+
/**
|
621 |
+
* checks if input array contains a date
|
622 |
+
*
|
623 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
624 |
+
* @since 2.4.16 - 2008-10-25
|
625 |
+
* @param array $input
|
626 |
+
* @return bool
|
627 |
+
*/
|
628 |
+
public static function _isArrayDate( $input ) {
|
629 |
+
if( isset( $input['week'] ) || ( !in_array( count( $input ), array( 3, 6, 7 ))))
|
630 |
+
return FALSE;
|
631 |
+
if( 7 == count( $input ))
|
632 |
+
return TRUE;
|
633 |
+
if( isset( $input['year'] ) && isset( $input['month'] ) && isset( $input['day'] ))
|
634 |
+
return checkdate( (int) $input['month'], (int) $input['day'], (int) $input['year'] );
|
635 |
+
if( isset( $input['day'] ) || isset( $input['hour'] ) || isset( $input['min'] ) || isset( $input['sec'] ))
|
636 |
+
return FALSE;
|
637 |
+
if( in_array( 0, $input ))
|
638 |
+
return FALSE;
|
639 |
+
if(( 1970 > $input[0] ) || ( 12 < $input[1] ) || ( 31 < $input[2] ))
|
640 |
+
return FALSE;
|
641 |
+
if(( isset( $input[0] ) && isset( $input[1] ) && isset( $input[2] )) &&
|
642 |
+
checkdate( (int) $input[1], (int) $input[2], (int) $input[0] ))
|
643 |
+
return TRUE;
|
644 |
+
$input = iCalUtilityFunctions::_date_time_string( $input[1].'/'.$input[2].'/'.$input[0], 3 ); // m - d - Y
|
645 |
+
if( isset( $input['year'] ) && isset( $input['month'] ) && isset( $input['day'] ))
|
646 |
+
return checkdate( (int) $input['month'], (int) $input['day'], (int) $input['year'] );
|
647 |
+
return FALSE;
|
648 |
+
}
|
649 |
+
/**
|
650 |
+
* checks if input array contains a timestamp date
|
651 |
+
*
|
652 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
653 |
+
* @since 2.4.16 - 2008-10-18
|
654 |
+
* @param array $input
|
655 |
+
* @return bool
|
656 |
+
*/
|
657 |
+
public static function _isArrayTimestampDate( $input ) {
|
658 |
+
return ( is_array( $input ) && isset( $input['timestamp'] )) ? TRUE : FALSE ;
|
659 |
+
}
|
660 |
+
/**
|
661 |
+
* controll if input string contains trailing UTC offset
|
662 |
+
*
|
663 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
664 |
+
* @since 2.4.16 - 2008-10-19
|
665 |
+
* @param string $input
|
666 |
+
* @return bool
|
667 |
+
*/
|
668 |
+
public static function _isOffset( $input ) {
|
669 |
+
$input = trim( (string) $input );
|
670 |
+
if( 'Z' == substr( $input, -1 ))
|
671 |
+
return TRUE;
|
672 |
+
elseif(( 5 <= strlen( $input )) &&
|
673 |
+
( in_array( substr( $input, -5, 1 ), array( '+', '-' ))) &&
|
674 |
+
( '0000' < substr( $input, -4 )) && ( '9999' >= substr( $input, -4 )))
|
675 |
+
return TRUE;
|
676 |
+
elseif(( 7 <= strlen( $input )) &&
|
677 |
+
( in_array( substr( $input, -7, 1 ), array( '+', '-' ))) &&
|
678 |
+
( '000000' < substr( $input, -6 )) && ( '999999' >= substr( $input, -6 )))
|
679 |
+
return TRUE;
|
680 |
+
return FALSE;
|
681 |
+
|
682 |
+
}
|
683 |
+
/**
|
684 |
+
* transform offset in seconds to [-/+]hhmm[ss]
|
685 |
+
*
|
686 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
687 |
+
* @since 2011-05-02
|
688 |
+
* @param string $seconds
|
689 |
+
* @return string
|
690 |
+
*/
|
691 |
+
public static function offsetSec2His( $seconds ) {
|
692 |
+
if( '-' == substr( $seconds, 0, 1 )) {
|
693 |
+
$prefix = '-';
|
694 |
+
$seconds = substr( $seconds, 1 );
|
695 |
+
}
|
696 |
+
elseif( '+' == substr( $seconds, 0, 1 )) {
|
697 |
+
$prefix = '+';
|
698 |
+
$seconds = substr( $seconds, 1 );
|
699 |
+
}
|
700 |
+
else
|
701 |
+
$prefix = '+';
|
702 |
+
$output = '';
|
703 |
+
$hour = (int) floor( $seconds / 3600 );
|
704 |
+
if( 10 > $hour )
|
705 |
+
$hour = '0'.$hour;
|
706 |
+
$seconds = $seconds % 3600;
|
707 |
+
$min = (int) floor( $seconds / 60 );
|
708 |
+
if( 10 > $min )
|
709 |
+
$min = '0'.$min;
|
710 |
+
$output = $hour.$min;
|
711 |
+
$seconds = $seconds % 60;
|
712 |
+
if( 0 < $seconds) {
|
713 |
+
if( 9 < $seconds)
|
714 |
+
$output .= $seconds;
|
715 |
+
else
|
716 |
+
$output .= '0'.$seconds;
|
717 |
+
}
|
718 |
+
return $prefix.$output;
|
719 |
+
}
|
720 |
+
/**
|
721 |
+
* remakes a recur pattern to an array of dates
|
722 |
+
*
|
723 |
+
* if missing, UNTIL is set 1 year from startdate (emergency break)
|
724 |
+
*
|
725 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
726 |
+
* @since 2.9.10 - 2011-07-07
|
727 |
+
* @param array $result, array to update, array([timestamp] => timestamp)
|
728 |
+
* @param array $recur, pattern for recurrency (only value part, params ignored)
|
729 |
+
* @param array $wdate, component start date
|
730 |
+
* @param array $startdate, start date
|
731 |
+
* @param array $enddate, optional
|
732 |
+
* @return array of recurrence (start-)dates as index
|
733 |
+
* @todo BYHOUR, BYMINUTE, BYSECOND, ev. BYSETPOS due to ambiguity, WEEKLY at year end/start
|
734 |
+
*/
|
735 |
+
public static function _recur2date( & $result, $recur, $wdate, $startdate, $enddate=FALSE ) {
|
736 |
+
foreach( $wdate as $k => $v ) if( ctype_digit( $v )) $wdate[$k] = (int) $v;
|
737 |
+
$wdateStart = $wdate;
|
738 |
+
$wdatets = iCalUtilityFunctions::_date2timestamp( $wdate );
|
739 |
+
$startdatets = iCalUtilityFunctions::_date2timestamp( $startdate );
|
740 |
+
if( !$enddate ) {
|
741 |
+
$enddate = $startdate;
|
742 |
+
$enddate['year'] += 1;
|
743 |
+
}
|
744 |
+
// echo "recur __in_ comp start ".implode('-',$wdate)." period start ".implode('-',$startdate)." period end ".implode('-',$enddate)."<br />\n";print_r($recur);echo "<br />\n";//test###
|
745 |
+
$endDatets = iCalUtilityFunctions::_date2timestamp( $enddate ); // fix break
|
746 |
+
if( !isset( $recur['COUNT'] ) && !isset( $recur['UNTIL'] ))
|
747 |
+
$recur['UNTIL'] = $enddate; // create break
|
748 |
+
if( isset( $recur['UNTIL'] )) {
|
749 |
+
$tdatets = iCalUtilityFunctions::_date2timestamp( $recur['UNTIL'] );
|
750 |
+
if( $endDatets > $tdatets ) {
|
751 |
+
$endDatets = $tdatets; // emergency break
|
752 |
+
$enddate = iCalUtilityFunctions::_timestamp2date( $endDatets, 6 );
|
753 |
+
}
|
754 |
+
else
|
755 |
+
$recur['UNTIL'] = iCalUtilityFunctions::_timestamp2date( $endDatets, 6 );
|
756 |
+
}
|
757 |
+
if( $wdatets > $endDatets ) {
|
758 |
+
// echo "recur out of date ".implode('-',iCalUtilityFunctions::_date_time_string(date('Y-m-d H:i:s',$wdatets),6))."<br />\n";//test
|
759 |
+
return array(); // nothing to do.. .
|
760 |
+
}
|
761 |
+
if( !isset( $recur['FREQ'] )) // "MUST be specified.. ."
|
762 |
+
$recur['FREQ'] = 'DAILY'; // ??
|
763 |
+
$wkst = ( isset( $recur['WKST'] ) && ( 'SU' == $recur['WKST'] )) ? 24*60*60 : 0; // ??
|
764 |
+
$weekStart = (int) date( 'W', ( $wdatets + $wkst ));
|
765 |
+
if( !isset( $recur['INTERVAL'] ))
|
766 |
+
$recur['INTERVAL'] = 1;
|
767 |
+
$countcnt = ( !isset( $recur['BYSETPOS'] )) ? 1 : 0; // DTSTART counts as the first occurrence
|
768 |
+
/* find out how to step up dates and set index for interval count */
|
769 |
+
$step = array();
|
770 |
+
if( 'YEARLY' == $recur['FREQ'] )
|
771 |
+
$step['year'] = 1;
|
772 |
+
elseif( 'MONTHLY' == $recur['FREQ'] )
|
773 |
+
$step['month'] = 1;
|
774 |
+
elseif( 'WEEKLY' == $recur['FREQ'] )
|
775 |
+
$step['day'] = 7;
|
776 |
+
else
|
777 |
+
$step['day'] = 1;
|
778 |
+
if( isset( $step['year'] ) && isset( $recur['BYMONTH'] ))
|
779 |
+
$step = array( 'month' => 1 );
|
780 |
+
if( empty( $step ) && isset( $recur['BYWEEKNO'] )) // ??
|
781 |
+
$step = array( 'day' => 7 );
|
782 |
+
if( isset( $recur['BYYEARDAY'] ) || isset( $recur['BYMONTHDAY'] ) || isset( $recur['BYDAY'] ))
|
783 |
+
$step = array( 'day' => 1 );
|
784 |
+
$intervalarr = array();
|
785 |
+
if( 1 < $recur['INTERVAL'] ) {
|
786 |
+
$intervalix = iCalUtilityFunctions::_recurIntervalIx( $recur['FREQ'], $wdate, $wkst );
|
787 |
+
$intervalarr = array( $intervalix => 0 );
|
788 |
+
}
|
789 |
+
if( isset( $recur['BYSETPOS'] )) { // save start date + weekno
|
790 |
+
$bysetposymd1 = $bysetposymd2 = $bysetposw1 = $bysetposw2 = array();
|
791 |
+
// echo "bysetposXold_start=$bysetposYold $bysetposMold $bysetposDold<br />\n"; // test ###
|
792 |
+
if( is_array( $recur['BYSETPOS'] )) {
|
793 |
+
foreach( $recur['BYSETPOS'] as $bix => $bval )
|
794 |
+
$recur['BYSETPOS'][$bix] = (int) $bval;
|
795 |
+
}
|
796 |
+
else
|
797 |
+
$recur['BYSETPOS'] = array( (int) $recur['BYSETPOS'] );
|
798 |
+
if( 'YEARLY' == $recur['FREQ'] ) {
|
799 |
+
$wdate['month'] = $wdate['day'] = 1; // start from beginning of year
|
800 |
+
$wdatets = iCalUtilityFunctions::_date2timestamp( $wdate );
|
801 |
+
iCalUtilityFunctions::_stepdate( $enddate, $endDatets, array( 'year' => 1 )); // make sure to count whole last year
|
802 |
+
}
|
803 |
+
elseif( 'MONTHLY' == $recur['FREQ'] ) {
|
804 |
+
$wdate['day'] = 1; // start from beginning of month
|
805 |
+
$wdatets = iCalUtilityFunctions::_date2timestamp( $wdate );
|
806 |
+
iCalUtilityFunctions::_stepdate( $enddate, $endDatets, array( 'month' => 1 )); // make sure to count whole last month
|
807 |
+
}
|
808 |
+
else
|
809 |
+
iCalUtilityFunctions::_stepdate( $enddate, $endDatets, $step); // make sure to count whole last period
|
810 |
+
// echo "BYSETPOS endDat++ =".implode('-',$enddate).' step='.var_export($step,TRUE)."<br />\n";//test###
|
811 |
+
$bysetposWold = (int) date( 'W', ( $wdatets + $wkst ));
|
812 |
+
$bysetposYold = $wdate['year'];
|
813 |
+
$bysetposMold = $wdate['month'];
|
814 |
+
$bysetposDold = $wdate['day'];
|
815 |
+
}
|
816 |
+
else
|
817 |
+
iCalUtilityFunctions::_stepdate( $wdate, $wdatets, $step);
|
818 |
+
$year_old = null;
|
819 |
+
$daynames = array( 'SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA' );
|
820 |
+
/* MAIN LOOP */
|
821 |
+
// echo "recur start ".implode('-',$wdate)." end ".implode('-',$enddate)."<br />\n";//test
|
822 |
+
while( TRUE ) {
|
823 |
+
if( isset( $endDatets ) && ( $wdatets > $endDatets ))
|
824 |
+
break;
|
825 |
+
if( isset( $recur['COUNT'] ) && ( $countcnt >= $recur['COUNT'] ))
|
826 |
+
break;
|
827 |
+
if( $year_old != $wdate['year'] ) {
|
828 |
+
$year_old = $wdate['year'];
|
829 |
+
$daycnts = array();
|
830 |
+
$yeardays = $weekno = 0;
|
831 |
+
$yeardaycnt = array();
|
832 |
+
for( $m = 1; $m <= 12; $m++ ) { // count up and update up-counters
|
833 |
+
$daycnts[$m] = array();
|
834 |
+
$weekdaycnt = array();
|
835 |
+
foreach( $daynames as $dn )
|
836 |
+
$yeardaycnt[$dn] = $weekdaycnt[$dn] = 0;
|
837 |
+
$mcnt = date( 't', mktime( 0, 0, 0, $m, 1, $wdate['year'] ));
|
838 |
+
for( $d = 1; $d <= $mcnt; $d++ ) {
|
839 |
+
$daycnts[$m][$d] = array();
|
840 |
+
if( isset( $recur['BYYEARDAY'] )) {
|
841 |
+
$yeardays++;
|
842 |
+
$daycnts[$m][$d]['yearcnt_up'] = $yeardays;
|
843 |
+
}
|
844 |
+
if( isset( $recur['BYDAY'] )) {
|
845 |
+
$day = date( 'w', mktime( 0, 0, 0, $m, $d, $wdate['year'] ));
|
846 |
+
$day = $daynames[$day];
|
847 |
+
$daycnts[$m][$d]['DAY'] = $day;
|
848 |
+
$weekdaycnt[$day]++;
|
849 |
+
$daycnts[$m][$d]['monthdayno_up'] = $weekdaycnt[$day];
|
850 |
+
$yeardaycnt[$day]++;
|
851 |
+
$daycnts[$m][$d]['yeardayno_up'] = $yeardaycnt[$day];
|
852 |
+
}
|
853 |
+
if( isset( $recur['BYWEEKNO'] ) || ( $recur['FREQ'] == 'WEEKLY' ))
|
854 |
+
$daycnts[$m][$d]['weekno_up'] =(int)date('W',mktime(0,0,$wkst,$m,$d,$wdate['year']));
|
855 |
+
}
|
856 |
+
}
|
857 |
+
$daycnt = 0;
|
858 |
+
$yeardaycnt = array();
|
859 |
+
if( isset( $recur['BYWEEKNO'] ) || ( $recur['FREQ'] == 'WEEKLY' )) {
|
860 |
+
$weekno = null;
|
861 |
+
for( $d=31; $d > 25; $d-- ) { // get last weekno for year
|
862 |
+
if( !$weekno )
|
863 |
+
$weekno = $daycnts[12][$d]['weekno_up'];
|
864 |
+
elseif( $weekno < $daycnts[12][$d]['weekno_up'] ) {
|
865 |
+
$weekno = $daycnts[12][$d]['weekno_up'];
|
866 |
+
break;
|
867 |
+
}
|
868 |
+
}
|
869 |
+
}
|
870 |
+
for( $m = 12; $m > 0; $m-- ) { // count down and update down-counters
|
871 |
+
$weekdaycnt = array();
|
872 |
+
foreach( $daynames as $dn )
|
873 |
+
$yeardaycnt[$dn] = $weekdaycnt[$dn] = 0;
|
874 |
+
$monthcnt = 0;
|
875 |
+
$mcnt = date( 't', mktime( 0, 0, 0, $m, 1, $wdate['year'] ));
|
876 |
+
for( $d = $mcnt; $d > 0; $d-- ) {
|
877 |
+
if( isset( $recur['BYYEARDAY'] )) {
|
878 |
+
$daycnt -= 1;
|
879 |
+
$daycnts[$m][$d]['yearcnt_down'] = $daycnt;
|
880 |
+
}
|
881 |
+
if( isset( $recur['BYMONTHDAY'] )) {
|
882 |
+
$monthcnt -= 1;
|
883 |
+
$daycnts[$m][$d]['monthcnt_down'] = $monthcnt;
|
884 |
+
}
|
885 |
+
if( isset( $recur['BYDAY'] )) {
|
886 |
+
$day = $daycnts[$m][$d]['DAY'];
|
887 |
+
$weekdaycnt[$day] -= 1;
|
888 |
+
$daycnts[$m][$d]['monthdayno_down'] = $weekdaycnt[$day];
|
889 |
+
$yeardaycnt[$day] -= 1;
|
890 |
+
$daycnts[$m][$d]['yeardayno_down'] = $yeardaycnt[$day];
|
891 |
+
}
|
892 |
+
if( isset( $recur['BYWEEKNO'] ) || ( $recur['FREQ'] == 'WEEKLY' ))
|
893 |
+
$daycnts[$m][$d]['weekno_down'] = ($daycnts[$m][$d]['weekno_up'] - $weekno - 1);
|
894 |
+
}
|
895 |
+
}
|
896 |
+
}
|
897 |
+
/* check interval */
|
898 |
+
if( 1 < $recur['INTERVAL'] ) {
|
899 |
+
/* create interval index */
|
900 |
+
$intervalix = iCalUtilityFunctions::_recurIntervalIx( $recur['FREQ'], $wdate, $wkst );
|
901 |
+
/* check interval */
|
902 |
+
$currentKey = array_keys( $intervalarr );
|
903 |
+
$currentKey = end( $currentKey ); // get last index
|
904 |
+
if( $currentKey != $intervalix )
|
905 |
+
$intervalarr = array( $intervalix => ( $intervalarr[$currentKey] + 1 ));
|
906 |
+
if(( $recur['INTERVAL'] != $intervalarr[$intervalix] ) &&
|
907 |
+
( 0 != $intervalarr[$intervalix] )) {
|
908 |
+
/* step up date */
|
909 |
+
// echo "skip: ".implode('-',$wdate)." ix=$intervalix old=$currentKey interval=".$intervalarr[$intervalix]."<br />\n";//test
|
910 |
+
iCalUtilityFunctions::_stepdate( $wdate, $wdatets, $step);
|
911 |
+
continue;
|
912 |
+
}
|
913 |
+
else // continue within the selected interval
|
914 |
+
$intervalarr[$intervalix] = 0;
|
915 |
+
// echo "cont: ".implode('-',$wdate)." ix=$intervalix old=$currentKey interval=".$intervalarr[$intervalix]."<br />\n";//test
|
916 |
+
}
|
917 |
+
$updateOK = TRUE;
|
918 |
+
if( $updateOK && isset( $recur['BYMONTH'] ))
|
919 |
+
$updateOK = iCalUtilityFunctions::_recurBYcntcheck( $recur['BYMONTH']
|
920 |
+
, $wdate['month']
|
921 |
+
,($wdate['month'] - 13));
|
922 |
+
if( $updateOK && isset( $recur['BYWEEKNO'] ))
|
923 |
+
$updateOK = iCalUtilityFunctions::_recurBYcntcheck( $recur['BYWEEKNO']
|
924 |
+
, $daycnts[$wdate['month']][$wdate['day']]['weekno_up']
|
925 |
+
, $daycnts[$wdate['month']][$wdate['day']]['weekno_down'] );
|
926 |
+
if( $updateOK && isset( $recur['BYYEARDAY'] ))
|
927 |
+
$updateOK = iCalUtilityFunctions::_recurBYcntcheck( $recur['BYYEARDAY']
|
928 |
+
, $daycnts[$wdate['month']][$wdate['day']]['yearcnt_up']
|
929 |
+
, $daycnts[$wdate['month']][$wdate['day']]['yearcnt_down'] );
|
930 |
+
if( $updateOK && isset( $recur['BYMONTHDAY'] ))
|
931 |
+
$updateOK = iCalUtilityFunctions::_recurBYcntcheck( $recur['BYMONTHDAY']
|
932 |
+
, $wdate['day']
|
933 |
+
, $daycnts[$wdate['month']][$wdate['day']]['monthcnt_down'] );
|
934 |
+
// echo "efter BYMONTHDAY: ".implode('-',$wdate).' status: '; echo ($updateOK) ? 'TRUE' : 'FALSE'; echo "<br />\n";//test###
|
935 |
+
if( $updateOK && isset( $recur['BYDAY'] )) {
|
936 |
+
$updateOK = FALSE;
|
937 |
+
$m = $wdate['month'];
|
938 |
+
$d = $wdate['day'];
|
939 |
+
if( isset( $recur['BYDAY']['DAY'] )) { // single day, opt with year/month day order no
|
940 |
+
$daynoexists = $daynosw = $daynamesw = FALSE;
|
941 |
+
if( $recur['BYDAY']['DAY'] == $daycnts[$m][$d]['DAY'] )
|
942 |
+
$daynamesw = TRUE;
|
943 |
+
if( isset( $recur['BYDAY'][0] )) {
|
944 |
+
$daynoexists = TRUE;
|
945 |
+
if(( isset( $recur['FREQ'] ) && ( $recur['FREQ'] == 'MONTHLY' )) || isset( $recur['BYMONTH'] ))
|
946 |
+
$daynosw = iCalUtilityFunctions::_recurBYcntcheck( $recur['BYDAY'][0]
|
947 |
+
, $daycnts[$m][$d]['monthdayno_up']
|
948 |
+
, $daycnts[$m][$d]['monthdayno_down'] );
|
949 |
+
elseif( isset( $recur['FREQ'] ) && ( $recur['FREQ'] == 'YEARLY' ))
|
950 |
+
$daynosw = iCalUtilityFunctions::_recurBYcntcheck( $recur['BYDAY'][0]
|
951 |
+
, $daycnts[$m][$d]['yeardayno_up']
|
952 |
+
, $daycnts[$m][$d]['yeardayno_down'] );
|
953 |
+
}
|
954 |
+
if(( $daynoexists && $daynosw && $daynamesw ) ||
|
955 |
+
( !$daynoexists && !$daynosw && $daynamesw )) {
|
956 |
+
$updateOK = TRUE;
|
957 |
+
}
|
958 |
+
// echo "daynoexists:$daynoexists daynosw:$daynosw daynamesw:$daynamesw<br />\n"; // test ###
|
959 |
+
}
|
960 |
+
else {
|
961 |
+
foreach( $recur['BYDAY'] as $bydayvalue ) {
|
962 |
+
$daynoexists = $daynosw = $daynamesw = FALSE;
|
963 |
+
if( isset( $bydayvalue['DAY'] ) &&
|
964 |
+
( $bydayvalue['DAY'] == $daycnts[$m][$d]['DAY'] ))
|
965 |
+
$daynamesw = TRUE;
|
966 |
+
if( isset( $bydayvalue[0] )) {
|
967 |
+
$daynoexists = TRUE;
|
968 |
+
if(( isset( $recur['FREQ'] ) && ( $recur['FREQ'] == 'MONTHLY' )) ||
|
969 |
+
isset( $recur['BYMONTH'] ))
|
970 |
+
$daynosw = iCalUtilityFunctions::_recurBYcntcheck( $bydayvalue['0']
|
971 |
+
, $daycnts[$m][$d]['monthdayno_up']
|
972 |
+
, $daycnts[$m][$d]['monthdayno_down'] );
|
973 |
+
elseif( isset( $recur['FREQ'] ) && ( $recur['FREQ'] == 'YEARLY' ))
|
974 |
+
$daynosw = iCalUtilityFunctions::_recurBYcntcheck( $bydayvalue['0']
|
975 |
+
, $daycnts[$m][$d]['yeardayno_up']
|
976 |
+
, $daycnts[$m][$d]['yeardayno_down'] );
|
977 |
+
}
|
978 |
+
// echo "daynoexists:$daynoexists daynosw:$daynosw daynamesw:$daynamesw<br />\n"; // test ###
|
979 |
+
if(( $daynoexists && $daynosw && $daynamesw ) ||
|
980 |
+
( !$daynoexists && !$daynosw && $daynamesw )) {
|
981 |
+
$updateOK = TRUE;
|
982 |
+
break;
|
983 |
+
}
|
984 |
+
}
|
985 |
+
}
|
986 |
+
}
|
987 |
+
// echo "efter BYDAY: ".implode('-',$wdate).' status: '; echo ($updateOK) ? 'TRUE' : 'FALSE'; echo "<br />\n"; // test ###
|
988 |
+
/* check BYSETPOS */
|
989 |
+
if( $updateOK ) {
|
990 |
+
if( isset( $recur['BYSETPOS'] ) &&
|
991 |
+
( in_array( $recur['FREQ'], array( 'YEARLY', 'MONTHLY', 'WEEKLY', 'DAILY' )))) {
|
992 |
+
if( isset( $recur['WEEKLY'] )) {
|
993 |
+
if( $bysetposWold == $daycnts[$wdate['month']][$wdate['day']]['weekno_up'] )
|
994 |
+
$bysetposw1[] = $wdatets;
|
995 |
+
else
|
996 |
+
$bysetposw2[] = $wdatets;
|
997 |
+
}
|
998 |
+
else {
|
999 |
+
if(( isset( $recur['FREQ'] ) && ( 'YEARLY' == $recur['FREQ'] ) &&
|
1000 |
+
( $bysetposYold == $wdate['year'] )) ||
|
1001 |
+
( isset( $recur['FREQ'] ) && ( 'MONTHLY' == $recur['FREQ'] ) &&
|
1002 |
+
(( $bysetposYold == $wdate['year'] ) &&
|
1003 |
+
( $bysetposMold == $wdate['month'] ))) ||
|
1004 |
+
( isset( $recur['FREQ'] ) && ( 'DAILY' == $recur['FREQ'] ) &&
|
1005 |
+
(( $bysetposYold == $wdate['year'] ) &&
|
1006 |
+
( $bysetposMold == $wdate['month']) &&
|
1007 |
+
( $bysetposDold == $wdate['day'] )))) {
|
1008 |
+
// echo "bysetposymd1[]=".implode('-',iCalUtilityFunctions::_date_time_string(date('Y-m-d H:i:s',$wdatets),6))."<br />\n";//test
|
1009 |
+
$bysetposymd1[] = $wdatets;
|
1010 |
+
}
|
1011 |
+
else {
|
1012 |
+
// echo "bysetposymd2[]=".implode('-',iCalUtilityFunctions::_date_time_string(date('Y-m-d H:i:s',$wdatets),6))."<br />\n";//test
|
1013 |
+
$bysetposymd2[] = $wdatets;
|
1014 |
+
}
|
1015 |
+
}
|
1016 |
+
}
|
1017 |
+
else {
|
1018 |
+
/* update result array if BYSETPOS is set */
|
1019 |
+
$countcnt++;
|
1020 |
+
if( $startdatets <= $wdatets ) { // only output within period
|
1021 |
+
$result[$wdatets] = TRUE;
|
1022 |
+
// echo "recur ".implode('-',iCalUtilityFunctions::_date_time_string(date('Y-m-d H:i:s',$wdatets),6))."<br />\n";//test
|
1023 |
+
}
|
1024 |
+
// echo "recur undate ".implode('-',iCalUtilityFunctions::_date_time_string(date('Y-m-d H:i:s',$wdatets),6))." okdatstart ".implode('-',iCalUtilityFunctions::_date_time_string(date('Y-m-d H:i:s',$startdatets),6))."<br />\n";//test
|
1025 |
+
$updateOK = FALSE;
|
1026 |
+
}
|
1027 |
+
}
|
1028 |
+
/* step up date */
|
1029 |
+
iCalUtilityFunctions::_stepdate( $wdate, $wdatets, $step);
|
1030 |
+
/* check if BYSETPOS is set for updating result array */
|
1031 |
+
if( $updateOK && isset( $recur['BYSETPOS'] )) {
|
1032 |
+
$bysetpos = FALSE;
|
1033 |
+
if( isset( $recur['FREQ'] ) && ( 'YEARLY' == $recur['FREQ'] ) &&
|
1034 |
+
( $bysetposYold != $wdate['year'] )) {
|
1035 |
+
$bysetpos = TRUE;
|
1036 |
+
$bysetposYold = $wdate['year'];
|
1037 |
+
}
|
1038 |
+
elseif( isset( $recur['FREQ'] ) && ( 'MONTHLY' == $recur['FREQ'] &&
|
1039 |
+
(( $bysetposYold != $wdate['year'] ) || ( $bysetposMold != $wdate['month'] )))) {
|
1040 |
+
$bysetpos = TRUE;
|
1041 |
+
$bysetposYold = $wdate['year'];
|
1042 |
+
$bysetposMold = $wdate['month'];
|
1043 |
+
}
|
1044 |
+
elseif( isset( $recur['FREQ'] ) && ( 'WEEKLY' == $recur['FREQ'] )) {
|
1045 |
+
$weekno = (int) date( 'W', mktime( 0, 0, $wkst, $wdate['month'], $wdate['day'], $wdate['year']));
|
1046 |
+
if( $bysetposWold != $weekno ) {
|
1047 |
+
$bysetposWold = $weekno;
|
1048 |
+
$bysetpos = TRUE;
|
1049 |
+
}
|
1050 |
+
}
|
1051 |
+
elseif( isset( $recur['FREQ'] ) && ( 'DAILY' == $recur['FREQ'] ) &&
|
1052 |
+
(( $bysetposYold != $wdate['year'] ) ||
|
1053 |
+
( $bysetposMold != $wdate['month'] ) ||
|
1054 |
+
( $bysetposDold != $wdate['day'] ))) {
|
1055 |
+
$bysetpos = TRUE;
|
1056 |
+
$bysetposYold = $wdate['year'];
|
1057 |
+
$bysetposMold = $wdate['month'];
|
1058 |
+
$bysetposDold = $wdate['day'];
|
1059 |
+
}
|
1060 |
+
if( $bysetpos ) {
|
1061 |
+
if( isset( $recur['BYWEEKNO'] )) {
|
1062 |
+
$bysetposarr1 = & $bysetposw1;
|
1063 |
+
$bysetposarr2 = & $bysetposw2;
|
1064 |
+
}
|
1065 |
+
else {
|
1066 |
+
$bysetposarr1 = & $bysetposymd1;
|
1067 |
+
$bysetposarr2 = & $bysetposymd2;
|
1068 |
+
}
|
1069 |
+
// echo 'test före out startYMD (weekno)='.$wdateStart['year'].':'.$wdateStart['month'].':'.$wdateStart['day']." ($weekStart) "; // test ###
|
1070 |
+
foreach( $recur['BYSETPOS'] as $ix ) {
|
1071 |
+
if( 0 > $ix ) // both positive and negative BYSETPOS allowed
|
1072 |
+
$ix = ( count( $bysetposarr1 ) + $ix + 1);
|
1073 |
+
$ix--;
|
1074 |
+
if( isset( $bysetposarr1[$ix] )) {
|
1075 |
+
if( $startdatets <= $bysetposarr1[$ix] ) { // only output within period
|
1076 |
+
// $testdate = iCalUtilityFunctions::_timestamp2date( $bysetposarr1[$ix], 6 ); // test ###
|
1077 |
+
// $testweekno = (int) date( 'W', mktime( 0, 0, $wkst, $testdate['month'], $testdate['day'], $testdate['year'] )); // test ###
|
1078 |
+
// echo " testYMD (weekno)=".$testdate['year'].':'.$testdate['month'].':'.$testdate['day']." ($testweekno)"; // test ###
|
1079 |
+
$result[$bysetposarr1[$ix]] = TRUE;
|
1080 |
+
// echo " recur ".implode('-',iCalUtilityFunctions::_date_time_string(date('Y-m-d H:i:s',$bysetposarr1[$ix]),6)); // test ###
|
1081 |
+
}
|
1082 |
+
$countcnt++;
|
1083 |
+
}
|
1084 |
+
if( isset( $recur['COUNT'] ) && ( $countcnt >= $recur['COUNT'] ))
|
1085 |
+
break;
|
1086 |
+
}
|
1087 |
+
// echo "<br />\n"; // test ###
|
1088 |
+
$bysetposarr1 = $bysetposarr2;
|
1089 |
+
$bysetposarr2 = array();
|
1090 |
+
}
|
1091 |
+
}
|
1092 |
+
}
|
1093 |
+
}
|
1094 |
+
public static function _recurBYcntcheck( $BYvalue, $upValue, $downValue ) {
|
1095 |
+
if( is_array( $BYvalue ) &&
|
1096 |
+
( in_array( $upValue, $BYvalue ) || in_array( $downValue, $BYvalue )))
|
1097 |
+
return TRUE;
|
1098 |
+
elseif(( $BYvalue == $upValue ) || ( $BYvalue == $downValue ))
|
1099 |
+
return TRUE;
|
1100 |
+
else
|
1101 |
+
return FALSE;
|
1102 |
+
}
|
1103 |
+
public static function _recurIntervalIx( $freq, $date, $wkst ) {
|
1104 |
+
/* create interval index */
|
1105 |
+
switch( $freq ) {
|
1106 |
+
case 'YEARLY':
|
1107 |
+
$intervalix = $date['year'];
|
1108 |
+
break;
|
1109 |
+
case 'MONTHLY':
|
1110 |
+
$intervalix = $date['year'].'-'.$date['month'];
|
1111 |
+
break;
|
1112 |
+
case 'WEEKLY':
|
1113 |
+
$wdatets = iCalUtilityFunctions::_date2timestamp( $date );
|
1114 |
+
$intervalix = (int) date( 'W', ( $wdatets + $wkst ));
|
1115 |
+
break;
|
1116 |
+
case 'DAILY':
|
1117 |
+
default:
|
1118 |
+
$intervalix = $date['year'].'-'.$date['month'].'-'.$date['day'];
|
1119 |
+
break;
|
1120 |
+
}
|
1121 |
+
return $intervalix;
|
1122 |
+
}
|
1123 |
+
/**
|
1124 |
+
* convert input format for exrule and rrule to internal format
|
1125 |
+
*
|
1126 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
1127 |
+
* @since 2.9.10 - 2011-07-07
|
1128 |
+
* @param array $rexrule
|
1129 |
+
* @return array
|
1130 |
+
*/
|
1131 |
+
public static function _setRexrule( $rexrule ) {
|
1132 |
+
$input = array();
|
1133 |
+
if( empty( $rexrule ))
|
1134 |
+
return $input;
|
1135 |
+
foreach( $rexrule as $rexrulelabel => $rexrulevalue ) {
|
1136 |
+
$rexrulelabel = strtoupper( $rexrulelabel );
|
1137 |
+
if( 'UNTIL' != $rexrulelabel )
|
1138 |
+
$input[$rexrulelabel] = $rexrulevalue;
|
1139 |
+
else {
|
1140 |
+
if( iCalUtilityFunctions::_isArrayTimestampDate( $rexrulevalue )) // timestamp date
|
1141 |
+
$input[$rexrulelabel] = iCalUtilityFunctions::_timestamp2date( $rexrulevalue, 6 );
|
1142 |
+
elseif( iCalUtilityFunctions::_isArrayDate( $rexrulevalue )) // date-time
|
1143 |
+
$input[$rexrulelabel] = iCalUtilityFunctions::_date_time_array( $rexrulevalue, 6 );
|
1144 |
+
elseif( 8 <= strlen( trim( $rexrulevalue ))) // ex. 2006-08-03 10:12:18
|
1145 |
+
$input[$rexrulelabel] = iCalUtilityFunctions::_date_time_string( $rexrulevalue );
|
1146 |
+
if(( 3 < count( $input[$rexrulelabel] )) && !isset( $input[$rexrulelabel]['tz'] ))
|
1147 |
+
$input[$rexrulelabel]['tz'] = 'Z';
|
1148 |
+
}
|
1149 |
+
}
|
1150 |
+
/* set recurrence rule specification in rfc2445 order */
|
1151 |
+
$input2 = array();
|
1152 |
+
if( isset( $input['FREQ'] ))
|
1153 |
+
$input2['FREQ'] = $input['FREQ'];
|
1154 |
+
if( isset( $input['UNTIL'] ))
|
1155 |
+
$input2['UNTIL'] = $input['UNTIL'];
|
1156 |
+
elseif( isset( $input['COUNT'] ))
|
1157 |
+
$input2['COUNT'] = $input['COUNT'];
|
1158 |
+
if( isset( $input['INTERVAL'] ))
|
1159 |
+
$input2['INTERVAL'] = $input['INTERVAL'];
|
1160 |
+
if( isset( $input['BYSECOND'] ))
|
1161 |
+
$input2['BYSECOND'] = $input['BYSECOND'];
|
1162 |
+
if( isset( $input['BYMINUTE'] ))
|
1163 |
+
$input2['BYMINUTE'] = $input['BYMINUTE'];
|
1164 |
+
if( isset( $input['BYHOUR'] ))
|
1165 |
+
$input2['BYHOUR'] = $input['BYHOUR'];
|
1166 |
+
if( isset( $input['BYDAY'] )) {
|
1167 |
+
if( !is_array( $input['BYDAY'] )) // ensure upper case.. .
|
1168 |
+
$input2['BYDAY'] = strtoupper( $input['BYDAY'] );
|
1169 |
+
else {
|
1170 |
+
foreach( $input['BYDAY'] as $BYDAYx => $BYDAYv ) {
|
1171 |
+
if( 'DAY' == strtoupper( $BYDAYx ))
|
1172 |
+
$input2['BYDAY']['DAY'] = strtoupper( $BYDAYv );
|
1173 |
+
elseif( !is_array( $BYDAYv )) {
|
1174 |
+
$input2['BYDAY'][$BYDAYx] = $BYDAYv;
|
1175 |
+
}
|
1176 |
+
else {
|
1177 |
+
foreach( $BYDAYv as $BYDAYx2 => $BYDAYv2 ) {
|
1178 |
+
if( 'DAY' == strtoupper( $BYDAYx2 ))
|
1179 |
+
$input2['BYDAY'][$BYDAYx]['DAY'] = strtoupper( $BYDAYv2 );
|
1180 |
+
else
|
1181 |
+
$input2['BYDAY'][$BYDAYx][$BYDAYx2] = $BYDAYv2;
|
1182 |
+
}
|
1183 |
+
}
|
1184 |
+
}
|
1185 |
+
}
|
1186 |
+
}
|
1187 |
+
if( isset( $input['BYMONTHDAY'] ))
|
1188 |
+
$input2['BYMONTHDAY'] = $input['BYMONTHDAY'];
|
1189 |
+
if( isset( $input['BYYEARDAY'] ))
|
1190 |
+
$input2['BYYEARDAY'] = $input['BYYEARDAY'];
|
1191 |
+
if( isset( $input['BYWEEKNO'] ))
|
1192 |
+
$input2['BYWEEKNO'] = $input['BYWEEKNO'];
|
1193 |
+
if( isset( $input['BYMONTH'] ))
|
1194 |
+
$input2['BYMONTH'] = $input['BYMONTH'];
|
1195 |
+
if( isset( $input['BYSETPOS'] ))
|
1196 |
+
$input2['BYSETPOS'] = $input['BYSETPOS'];
|
1197 |
+
if( isset( $input['WKST'] ))
|
1198 |
+
$input2['WKST'] = $input['WKST'];
|
1199 |
+
return $input2;
|
1200 |
+
}
|
1201 |
+
/**
|
1202 |
+
* convert format for input date to internal date with parameters
|
1203 |
+
*
|
1204 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
1205 |
+
* @since 2.9.6 - 2011-05-14
|
1206 |
+
* @param mixed $year
|
1207 |
+
* @param mixed $month optional
|
1208 |
+
* @param int $day optional
|
1209 |
+
* @param int $hour optional
|
1210 |
+
* @param int $min optional
|
1211 |
+
* @param int $sec optional
|
1212 |
+
* @param string $tz optional
|
1213 |
+
* @param array $params optional
|
1214 |
+
* @param string $caller optional
|
1215 |
+
* @param string $objName optional
|
1216 |
+
* @param string $tzid optional
|
1217 |
+
* @return array
|
1218 |
+
*/
|
1219 |
+
public static function _setDate( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $tz=FALSE, $params=FALSE, $caller=null, $objName=null, $tzid=FALSE ) {
|
1220 |
+
$input = $parno = null;
|
1221 |
+
$localtime = (( 'dtstart' == $caller ) && in_array( $objName, array( 'vtimezone', 'standard', 'daylight' ))) ? TRUE : FALSE;
|
1222 |
+
if( iCalUtilityFunctions::_isArrayDate( $year )) {
|
1223 |
+
if( $localtime ) unset ( $month['VALUE'], $month['TZID'] );
|
1224 |
+
$input['params'] = iCalUtilityFunctions::_setParams( $month, array( 'VALUE' => 'DATE-TIME' ));
|
1225 |
+
if( isset( $input['params']['TZID'] )) {
|
1226 |
+
$input['params']['VALUE'] = 'DATE-TIME';
|
1227 |
+
unset( $year['tz'] );
|
1228 |
+
}
|
1229 |
+
$hitval = (( !empty( $year['tz'] ) || !empty( $year[6] ))) ? 7 : 6;
|
1230 |
+
$parno = iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE-TIME', $hitval );
|
1231 |
+
$parno = iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE', 3, count( $year ), $parno );
|
1232 |
+
$input['value'] = iCalUtilityFunctions::_date_time_array( $year, $parno );
|
1233 |
+
}
|
1234 |
+
elseif( iCalUtilityFunctions::_isArrayTimestampDate( $year )) {
|
1235 |
+
if( $localtime ) unset ( $month['VALUE'], $month['TZID'] );
|
1236 |
+
$input['params'] = iCalUtilityFunctions::_setParams( $month, array( 'VALUE' => 'DATE-TIME' ));
|
1237 |
+
if( isset( $input['params']['TZID'] )) {
|
1238 |
+
$input['params']['VALUE'] = 'DATE-TIME';
|
1239 |
+
unset( $year['tz'] );
|
1240 |
+
}
|
1241 |
+
$parno = iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE', 3 );
|
1242 |
+
$hitval = ( isset( $year['tz'] )) ? 7 : 6;
|
1243 |
+
$parno = iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE-TIME', $hitval, $parno );
|
1244 |
+
$input['value'] = iCalUtilityFunctions::_timestamp2date( $year, $parno );
|
1245 |
+
}
|
1246 |
+
elseif( 8 <= strlen( trim( $year ))) { // ex. 2006-08-03 10:12:18
|
1247 |
+
if( $localtime ) unset ( $month['VALUE'], $month['TZID'] );
|
1248 |
+
$input['params'] = iCalUtilityFunctions::_setParams( $month, array( 'VALUE' => 'DATE-TIME' ));
|
1249 |
+
if( isset( $input['params']['TZID'] )) {
|
1250 |
+
$input['params']['VALUE'] = 'DATE-TIME';
|
1251 |
+
$parno = 6;
|
1252 |
+
}
|
1253 |
+
$parno = iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE-TIME', 7, $parno );
|
1254 |
+
$parno = iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE', 3, $parno, $parno );
|
1255 |
+
$input['value'] = iCalUtilityFunctions::_date_time_string( $year, $parno );
|
1256 |
+
}
|
1257 |
+
else {
|
1258 |
+
if( is_array( $params )) {
|
1259 |
+
if( $localtime ) unset ( $params['VALUE'], $params['TZID'] );
|
1260 |
+
$input['params'] = iCalUtilityFunctions::_setParams( $params, array( 'VALUE' => 'DATE-TIME' ));
|
1261 |
+
}
|
1262 |
+
elseif( is_array( $tz )) {
|
1263 |
+
$input['params'] = iCalUtilityFunctions::_setParams( $tz, array( 'VALUE' => 'DATE-TIME' ));
|
1264 |
+
$tz = FALSE;
|
1265 |
+
}
|
1266 |
+
elseif( is_array( $hour )) {
|
1267 |
+
$input['params'] = iCalUtilityFunctions::_setParams( $hour, array( 'VALUE' => 'DATE-TIME' ));
|
1268 |
+
$hour = $min = $sec = $tz = FALSE;
|
1269 |
+
}
|
1270 |
+
if( isset( $input['params']['TZID'] )) {
|
1271 |
+
$tz = null;
|
1272 |
+
$input['params']['VALUE'] = 'DATE-TIME';
|
1273 |
+
}
|
1274 |
+
$parno = iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE', 3 );
|
1275 |
+
$hitval = ( !empty( $tz )) ? 7 : 6;
|
1276 |
+
$parno = iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE-TIME', $hitval, $parno, $parno );
|
1277 |
+
$input['value'] = array( 'year' => $year, 'month' => $month, 'day' => $day );
|
1278 |
+
if( 3 != $parno ) {
|
1279 |
+
$input['value']['hour'] = ( $hour ) ? $hour : '0';
|
1280 |
+
$input['value']['min'] = ( $min ) ? $min : '0';
|
1281 |
+
$input['value']['sec'] = ( $sec ) ? $sec : '0';
|
1282 |
+
if( !empty( $tz ))
|
1283 |
+
$input['value']['tz'] = $tz;
|
1284 |
+
}
|
1285 |
+
}
|
1286 |
+
if( 3 == $parno ) {
|
1287 |
+
$input['params']['VALUE'] = 'DATE';
|
1288 |
+
unset( $input['value']['tz'] );
|
1289 |
+
unset( $input['params']['TZID'] );
|
1290 |
+
}
|
1291 |
+
elseif( isset( $input['params']['TZID'] ))
|
1292 |
+
unset( $input['value']['tz'] );
|
1293 |
+
if( $localtime )
|
1294 |
+
unset( $input['value']['tz'], $input['params']['TZID'] );
|
1295 |
+
elseif(( !isset( $input['params']['VALUE'] ) || ( $input['params']['VALUE'] != 'DATE' )) && !isset( $input['params']['TZID'] ) && $tzid )
|
1296 |
+
$input['params']['TZID'] = $tzid;
|
1297 |
+
if( isset( $input['value']['tz'] ))
|
1298 |
+
$input['value']['tz'] = (string) $input['value']['tz'];
|
1299 |
+
if( !empty( $input['value']['tz'] ) && ( 'Z' != $input['value']['tz'] ) &&
|
1300 |
+
( !iCalUtilityFunctions::_isOffset( $input['value']['tz'] )))
|
1301 |
+
$input['params']['TZID'] = $input['value']['tz'];
|
1302 |
+
return $input;
|
1303 |
+
}
|
1304 |
+
/**
|
1305 |
+
* convert format for input date (UTC) to internal date with parameters
|
1306 |
+
*
|
1307 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
1308 |
+
* @since 2.4.17 - 2008-10-31
|
1309 |
+
* @param mixed $year
|
1310 |
+
* @param mixed $month optional
|
1311 |
+
* @param int $day optional
|
1312 |
+
* @param int $hour optional
|
1313 |
+
* @param int $min optional
|
1314 |
+
* @param int $sec optional
|
1315 |
+
* @param array $params optional
|
1316 |
+
* @return array
|
1317 |
+
*/
|
1318 |
+
public static function _setDate2( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) {
|
1319 |
+
$input = null;
|
1320 |
+
if( iCalUtilityFunctions::_isArrayDate( $year )) {
|
1321 |
+
$input['value'] = iCalUtilityFunctions::_date_time_array( $year, 7 );
|
1322 |
+
$input['params'] = iCalUtilityFunctions::_setParams( $month, array( 'VALUE' => 'DATE-TIME' ) );
|
1323 |
+
}
|
1324 |
+
elseif( iCalUtilityFunctions::_isArrayTimestampDate( $year )) {
|
1325 |
+
$input['value'] = iCalUtilityFunctions::_timestamp2date( $year, 7 );
|
1326 |
+
$input['params'] = iCalUtilityFunctions::_setParams( $month, array( 'VALUE' => 'DATE-TIME' ) );
|
1327 |
+
}
|
1328 |
+
elseif( 8 <= strlen( trim( $year ))) { // ex. 2006-08-03 10:12:18
|
1329 |
+
$input['value'] = iCalUtilityFunctions::_date_time_string( $year, 7 );
|
1330 |
+
$input['params'] = iCalUtilityFunctions::_setParams( $month, array( 'VALUE' => 'DATE-TIME' ) );
|
1331 |
+
}
|
1332 |
+
else {
|
1333 |
+
$input['value'] = array( 'year' => $year
|
1334 |
+
, 'month' => $month
|
1335 |
+
, 'day' => $day
|
1336 |
+
, 'hour' => $hour
|
1337 |
+
, 'min' => $min
|
1338 |
+
, 'sec' => $sec );
|
1339 |
+
$input['params'] = iCalUtilityFunctions::_setParams( $params, array( 'VALUE' => 'DATE-TIME' ));
|
1340 |
+
}
|
1341 |
+
$parno = iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE-TIME', 7 ); // remove default
|
1342 |
+
if( !isset( $input['value']['hour'] ))
|
1343 |
+
$input['value']['hour'] = 0;
|
1344 |
+
if( !isset( $input['value']['min'] ))
|
1345 |
+
$input['value']['min'] = 0;
|
1346 |
+
if( !isset( $input['value']['sec'] ))
|
1347 |
+
$input['value']['sec'] = 0;
|
1348 |
+
if( !isset( $input['value']['tz'] ) || !iCalUtilityFunctions::_isOffset( $input['value']['tz'] ))
|
1349 |
+
$input['value']['tz'] = 'Z';
|
1350 |
+
return $input;
|
1351 |
+
}
|
1352 |
+
/**
|
1353 |
+
* check index and set (an indexed) content in multiple value array
|
1354 |
+
*
|
1355 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
1356 |
+
* @since 2.6.12 - 2011-01-03
|
1357 |
+
* @param array $valArr
|
1358 |
+
* @param mixed $value
|
1359 |
+
* @param array $params
|
1360 |
+
* @param array $defaults
|
1361 |
+
* @param int $index
|
1362 |
+
* @return void
|
1363 |
+
*/
|
1364 |
+
public static function _setMval( & $valArr, $value, $params=FALSE, $defaults=FALSE, $index=FALSE ) {
|
1365 |
+
if( !is_array( $valArr )) $valArr = array();
|
1366 |
+
if( $index )
|
1367 |
+
$index = $index - 1;
|
1368 |
+
elseif( 0 < count( $valArr )) {
|
1369 |
+
$keys = array_keys( $valArr );
|
1370 |
+
$index = end( $keys ) + 1;
|
1371 |
+
}
|
1372 |
+
else
|
1373 |
+
$index = 0;
|
1374 |
+
$valArr[$index] = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params, $defaults ));
|
1375 |
+
ksort( $valArr );
|
1376 |
+
}
|
1377 |
+
/**
|
1378 |
+
* set input (formatted) parameters- component property attributes
|
1379 |
+
*
|
1380 |
+
* default parameters can be set, if missing
|
1381 |
+
*
|
1382 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
1383 |
+
* @since 1.x.x - 2007-05-01
|
1384 |
+
* @param array $params
|
1385 |
+
* @param array $defaults
|
1386 |
+
* @return array
|
1387 |
+
*/
|
1388 |
+
public static function _setParams( $params, $defaults=FALSE ) {
|
1389 |
+
if( !is_array( $params))
|
1390 |
+
$params = array();
|
1391 |
+
$input = array();
|
1392 |
+
foreach( $params as $paramKey => $paramValue ) {
|
1393 |
+
if( is_array( $paramValue )) {
|
1394 |
+
foreach( $paramValue as $pkey => $pValue ) {
|
1395 |
+
if(( '"' == substr( $pValue, 0, 1 )) && ( '"' == substr( $pValue, -1 )))
|
1396 |
+
$paramValue[$pkey] = substr( $pValue, 1, ( strlen( $pValue ) - 2 ));
|
1397 |
+
}
|
1398 |
+
}
|
1399 |
+
elseif(( '"' == substr( $paramValue, 0, 1 )) && ( '"' == substr( $paramValue, -1 )))
|
1400 |
+
$paramValue = substr( $paramValue, 1, ( strlen( $paramValue ) - 2 ));
|
1401 |
+
if( 'VALUE' == strtoupper( $paramKey ))
|
1402 |
+
$input['VALUE'] = strtoupper( $paramValue );
|
1403 |
+
else
|
1404 |
+
$input[strtoupper( $paramKey )] = $paramValue;
|
1405 |
+
}
|
1406 |
+
if( is_array( $defaults )) {
|
1407 |
+
foreach( $defaults as $paramKey => $paramValue ) {
|
1408 |
+
if( !isset( $input[$paramKey] ))
|
1409 |
+
$input[$paramKey] = $paramValue;
|
1410 |
+
}
|
1411 |
+
}
|
1412 |
+
return (0 < count( $input )) ? $input : null;
|
1413 |
+
}
|
1414 |
+
/**
|
1415 |
+
* step date, return updated date, array and timpstamp
|
1416 |
+
*
|
1417 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
1418 |
+
* @since 2.4.16 - 2008-10-18
|
1419 |
+
* @param array $date, date to step
|
1420 |
+
* @param int $timestamp
|
1421 |
+
* @param array $step, default array( 'day' => 1 )
|
1422 |
+
* @return void
|
1423 |
+
*/
|
1424 |
+
public static function _stepdate( &$date, &$timestamp, $step=array( 'day' => 1 )) {
|
1425 |
+
foreach( $step as $stepix => $stepvalue )
|
1426 |
+
$date[$stepix] += $stepvalue;
|
1427 |
+
$timestamp = iCalUtilityFunctions::_date2timestamp( $date );
|
1428 |
+
$date = iCalUtilityFunctions::_timestamp2date( $timestamp, 6 );
|
1429 |
+
foreach( $date as $k => $v ) {
|
1430 |
+
if( ctype_digit( $v ))
|
1431 |
+
$date[$k] = (int) $v;
|
1432 |
+
}
|
1433 |
+
}
|
1434 |
+
/**
|
1435 |
+
* convert timestamp to date array
|
1436 |
+
*
|
1437 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
1438 |
+
* @since 2.4.16 - 2008-11-01
|
1439 |
+
* @param mixed $timestamp
|
1440 |
+
* @param int $parno
|
1441 |
+
* @return array
|
1442 |
+
*/
|
1443 |
+
public static function _timestamp2date( $timestamp, $parno=6 ) {
|
1444 |
+
if( is_array( $timestamp )) {
|
1445 |
+
if(( 7 == $parno ) && !empty( $timestamp['tz'] ))
|
1446 |
+
$tz = $timestamp['tz'];
|
1447 |
+
$timestamp = $timestamp['timestamp'];
|
1448 |
+
}
|
1449 |
+
$output = array( 'year' => date( 'Y', $timestamp )
|
1450 |
+
, 'month' => date( 'm', $timestamp )
|
1451 |
+
, 'day' => date( 'd', $timestamp ));
|
1452 |
+
if( 3 != $parno ) {
|
1453 |
+
$output['hour'] = date( 'H', $timestamp );
|
1454 |
+
$output['min'] = date( 'i', $timestamp );
|
1455 |
+
$output['sec'] = date( 's', $timestamp );
|
1456 |
+
if( isset( $tz ))
|
1457 |
+
$output['tz'] = $tz;
|
1458 |
+
}
|
1459 |
+
return $output;
|
1460 |
+
}
|
1461 |
+
/**
|
1462 |
+
* convert timestamp to duration in array format
|
1463 |
+
*
|
1464 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
1465 |
+
* @since 2.6.23 - 2010-10-23
|
1466 |
+
* @param int $timestamp
|
1467 |
+
* @return array, duration format
|
1468 |
+
*/
|
1469 |
+
function _timestamp2duration( $timestamp ) {
|
1470 |
+
$dur = array();
|
1471 |
+
$dur['week'] = (int) floor( $timestamp / ( 7 * 24 * 60 * 60 ));
|
1472 |
+
$timestamp = $timestamp % ( 7 * 24 * 60 * 60 );
|
1473 |
+
$dur['day'] = (int) floor( $timestamp / ( 24 * 60 * 60 ));
|
1474 |
+
$timestamp = $timestamp % ( 24 * 60 * 60 );
|
1475 |
+
$dur['hour'] = (int) floor( $timestamp / ( 60 * 60 ));
|
1476 |
+
$timestamp = $timestamp % ( 60 * 60 );
|
1477 |
+
$dur['min'] = (int) floor( $timestamp / ( 60 ));
|
1478 |
+
$dur['sec'] = (int) $timestamp % ( 60 );
|
1479 |
+
return $dur;
|
1480 |
+
}
|
1481 |
+
/**
|
1482 |
+
* convert (numeric) local time offset to seconds correcting localtime to GMT
|
1483 |
+
*
|
1484 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
1485 |
+
* @since 2.4.16 - 2008-10-19
|
1486 |
+
* @param string $offset
|
1487 |
+
* @return integer
|
1488 |
+
*/
|
1489 |
+
public static function _tz2offset( $tz ) {
|
1490 |
+
$tz = trim( (string) $tz );
|
1491 |
+
$offset = 0;
|
1492 |
+
if((( 5 != strlen( $tz )) && ( 7 != strlen( $tz ))) ||
|
1493 |
+
(( '+' != substr( $tz, 0, 1 )) && ( '-' != substr( $tz, 0, 1 ))) ||
|
1494 |
+
(( '0000' >= substr( $tz, 1, 4 )) && ( '9999' < substr( $tz, 1, 4 ))) ||
|
1495 |
+
(( 7 == strlen( $tz )) && ( '00' > substr( $tz, 5, 2 )) && ( '99' < substr( $tz, 5, 2 ))))
|
1496 |
+
return $offset;
|
1497 |
+
$hours2sec = (int) substr( $tz, 1, 2 ) * 3600;
|
1498 |
+
$min2sec = (int) substr( $tz, 3, 2 ) * 60;
|
1499 |
+
$sec = ( 7 == strlen( $tz )) ? (int) substr( $tz, -2 ) : '00';
|
1500 |
+
$offset = $hours2sec + $min2sec + $sec;
|
1501 |
+
$offset = ('-' == substr( $tz, 0, 1 )) ? $offset : -1 * $offset;
|
1502 |
+
return $offset;
|
1503 |
+
}
|
1504 |
+
}
|
1505 |
+
?>
|
lib/iCalcreator-2.10/iCalcreator.class.php
ADDED
@@ -0,0 +1,6897 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*********************************************************************************/
|
3 |
+
/**
|
4 |
+
* iCalcreator class v2.10
|
5 |
+
* copyright (c) 2007-2011 Kjell-Inge Gustafsson kigkonsult
|
6 |
+
* www.kigkonsult.se/iCalcreator/index.php
|
7 |
+
* ical@kigkonsult.se
|
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 |
+
/*********************************************************************************/
|
47 |
+
/* only for phpversion 5.1 and later, */
|
48 |
+
/* date management, default timezone setting */
|
49 |
+
/* since 2.6.36 - 2010-12-31 */
|
50 |
+
if( substr( phpversion(), 0, 3) >= '5.1' )
|
51 |
+
// && ( 'UTC' == date_default_timezone_get()))
|
52 |
+
date_default_timezone_set( 'Europe/Stockholm' );
|
53 |
+
/*********************************************************************************/
|
54 |
+
/* since 2.6.22 - 2010-09-25, do NOT remove!! */
|
55 |
+
require_once ( 'iCalUtilityFunctions.class.php' );
|
56 |
+
/*********************************************************************************/
|
57 |
+
/* version, do NOT remove!! */
|
58 |
+
define( 'ICALCREATOR_VERSION', 'iCalcreator 2.10' );
|
59 |
+
/*********************************************************************************/
|
60 |
+
/*********************************************************************************/
|
61 |
+
/**
|
62 |
+
* vcalendar class
|
63 |
+
*
|
64 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
65 |
+
* @since 2.9.6 - 2011-05-14
|
66 |
+
*/
|
67 |
+
class vcalendar {
|
68 |
+
// calendar property variables
|
69 |
+
var $calscale;
|
70 |
+
var $method;
|
71 |
+
var $prodid;
|
72 |
+
var $version;
|
73 |
+
var $xprop;
|
74 |
+
// container for calendar components
|
75 |
+
var $components;
|
76 |
+
// component config variables
|
77 |
+
var $allowEmpty;
|
78 |
+
var $unique_id;
|
79 |
+
var $language;
|
80 |
+
var $directory;
|
81 |
+
var $filename;
|
82 |
+
var $url;
|
83 |
+
var $delimiter;
|
84 |
+
var $nl;
|
85 |
+
var $format;
|
86 |
+
var $dtzid;
|
87 |
+
// component internal variables
|
88 |
+
var $attributeDelimiter;
|
89 |
+
var $valueInit;
|
90 |
+
// component xCal declaration container
|
91 |
+
var $xcaldecl;
|
92 |
+
/**
|
93 |
+
* constructor for calendar object
|
94 |
+
*
|
95 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
96 |
+
* @since 2.9.6 - 2011-05-14
|
97 |
+
* @param array $config
|
98 |
+
* @return void
|
99 |
+
*/
|
100 |
+
function vcalendar ( $config = array()) {
|
101 |
+
$this->_makeVersion();
|
102 |
+
$this->calscale = null;
|
103 |
+
$this->method = null;
|
104 |
+
$this->_makeUnique_id();
|
105 |
+
$this->prodid = null;
|
106 |
+
$this->xprop = array();
|
107 |
+
$this->language = null;
|
108 |
+
$this->directory = null;
|
109 |
+
$this->filename = null;
|
110 |
+
$this->url = null;
|
111 |
+
$this->dtzid = null;
|
112 |
+
/**
|
113 |
+
* language = <Text identifying a language, as defined in [RFC 1766]>
|
114 |
+
*/
|
115 |
+
if( defined( 'ICAL_LANG' ) && !isset( $config['language'] ))
|
116 |
+
$config['language'] = ICAL_LANG;
|
117 |
+
if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE;
|
118 |
+
if( !isset( $config['nl'] )) $config['nl'] = "\r\n";
|
119 |
+
if( !isset( $config['format'] )) $config['format'] = 'iCal';
|
120 |
+
if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR;
|
121 |
+
$this->setConfig( $config );
|
122 |
+
|
123 |
+
$this->xcaldecl = array();
|
124 |
+
$this->components = array();
|
125 |
+
}
|
126 |
+
/*********************************************************************************/
|
127 |
+
/**
|
128 |
+
* Property Name: CALSCALE
|
129 |
+
*/
|
130 |
+
/**
|
131 |
+
* creates formatted output for calendar property calscale
|
132 |
+
*
|
133 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
134 |
+
* @since 2.4.8 - 2008-10-21
|
135 |
+
* @return string
|
136 |
+
*/
|
137 |
+
function createCalscale() {
|
138 |
+
if( empty( $this->calscale )) return FALSE;
|
139 |
+
switch( $this->format ) {
|
140 |
+
case 'xcal':
|
141 |
+
return ' calscale="'.$this->calscale.'"'.$this->nl;
|
142 |
+
break;
|
143 |
+
default:
|
144 |
+
return 'CALSCALE:'.$this->calscale.$this->nl;
|
145 |
+
break;
|
146 |
+
}
|
147 |
+
}
|
148 |
+
/**
|
149 |
+
* set calendar property calscale
|
150 |
+
*
|
151 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
152 |
+
* @since 2.4.8 - 2008-10-21
|
153 |
+
* @param string $value
|
154 |
+
* @return void
|
155 |
+
*/
|
156 |
+
function setCalscale( $value ) {
|
157 |
+
if( empty( $value )) return FALSE;
|
158 |
+
$this->calscale = $value;
|
159 |
+
}
|
160 |
+
/*********************************************************************************/
|
161 |
+
/**
|
162 |
+
* Property Name: METHOD
|
163 |
+
*/
|
164 |
+
/**
|
165 |
+
* creates formatted output for calendar property method
|
166 |
+
*
|
167 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
168 |
+
* @since 0.9.7 - 2006-11-20
|
169 |
+
* @return string
|
170 |
+
*/
|
171 |
+
function createMethod() {
|
172 |
+
if( empty( $this->method )) return FALSE;
|
173 |
+
switch( $this->format ) {
|
174 |
+
case 'xcal':
|
175 |
+
return ' method="'.$this->method.'"'.$this->nl;
|
176 |
+
break;
|
177 |
+
default:
|
178 |
+
return 'METHOD:'.$this->method.$this->nl;
|
179 |
+
break;
|
180 |
+
}
|
181 |
+
}
|
182 |
+
/**
|
183 |
+
* set calendar property method
|
184 |
+
*
|
185 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
186 |
+
* @since 2.4.8 - 2008-20-23
|
187 |
+
* @param string $value
|
188 |
+
* @return bool
|
189 |
+
*/
|
190 |
+
function setMethod( $value ) {
|
191 |
+
if( empty( $value )) return FALSE;
|
192 |
+
$this->method = $value;
|
193 |
+
return TRUE;
|
194 |
+
}
|
195 |
+
/*********************************************************************************/
|
196 |
+
/**
|
197 |
+
* Property Name: PRODID
|
198 |
+
*
|
199 |
+
* The identifier is RECOMMENDED to be the identical syntax to the
|
200 |
+
* [RFC 822] addr-spec. A good method to assure uniqueness is to put the
|
201 |
+
* domain name or a domain literal IP address of the host on which.. .
|
202 |
+
*/
|
203 |
+
/**
|
204 |
+
* creates formatted output for calendar property prodid
|
205 |
+
*
|
206 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
207 |
+
* @since 0.9.7 - 2006-11-20
|
208 |
+
* @return string
|
209 |
+
*/
|
210 |
+
function createProdid() {
|
211 |
+
if( !isset( $this->prodid ))
|
212 |
+
$this->_makeProdid();
|
213 |
+
switch( $this->format ) {
|
214 |
+
case 'xcal':
|
215 |
+
return ' prodid="'.$this->prodid.'"'.$this->nl;
|
216 |
+
break;
|
217 |
+
default:
|
218 |
+
return 'PRODID:'.$this->prodid.$this->nl;
|
219 |
+
break;
|
220 |
+
}
|
221 |
+
}
|
222 |
+
/**
|
223 |
+
* make default value for calendar prodid
|
224 |
+
*
|
225 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
226 |
+
* @since 2.6.8 - 2009-12-30
|
227 |
+
* @return void
|
228 |
+
*/
|
229 |
+
function _makeProdid() {
|
230 |
+
$this->prodid = '-//'.$this->unique_id.'//NONSGML kigkonsult.se '.ICALCREATOR_VERSION.'//'.strtoupper( $this->language );
|
231 |
+
}
|
232 |
+
/**
|
233 |
+
* Conformance: The property MUST be specified once in an iCalendar object.
|
234 |
+
* Description: The vendor of the implementation SHOULD assure that this
|
235 |
+
* is a globally unique identifier; using some technique such as an FPI
|
236 |
+
* value, as defined in [ISO 9070].
|
237 |
+
*/
|
238 |
+
/**
|
239 |
+
* make default unique_id for calendar prodid
|
240 |
+
*
|
241 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
242 |
+
* @since 0.3.0 - 2006-08-10
|
243 |
+
* @return void
|
244 |
+
*/
|
245 |
+
function _makeUnique_id() {
|
246 |
+
$this->unique_id = ( isset( $_SERVER['SERVER_NAME'] )) ? gethostbyname( $_SERVER['SERVER_NAME'] ) : 'localhost';
|
247 |
+
}
|
248 |
+
/*********************************************************************************/
|
249 |
+
/**
|
250 |
+
* Property Name: VERSION
|
251 |
+
*
|
252 |
+
* Description: A value of "2.0" corresponds to this memo.
|
253 |
+
*/
|
254 |
+
/**
|
255 |
+
* creates formatted output for calendar property version
|
256 |
+
|
257 |
+
*
|
258 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
259 |
+
* @since 0.9.7 - 2006-11-20
|
260 |
+
* @return string
|
261 |
+
*/
|
262 |
+
function createVersion() {
|
263 |
+
if( empty( $this->version ))
|
264 |
+
$this->_makeVersion();
|
265 |
+
switch( $this->format ) {
|
266 |
+
case 'xcal':
|
267 |
+
return ' version="'.$this->version.'"'.$this->nl;
|
268 |
+
break;
|
269 |
+
default:
|
270 |
+
return 'VERSION:'.$this->version.$this->nl;
|
271 |
+
break;
|
272 |
+
}
|
273 |
+
}
|
274 |
+
/**
|
275 |
+
* set default calendar version
|
276 |
+
*
|
277 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
278 |
+
* @since 0.3.0 - 2006-08-10
|
279 |
+
* @return void
|
280 |
+
*/
|
281 |
+
function _makeVersion() {
|
282 |
+
$this->version = '2.0';
|
283 |
+
}
|
284 |
+
/**
|
285 |
+
* set calendar version
|
286 |
+
*
|
287 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
288 |
+
* @since 2.4.8 - 2008-10-23
|
289 |
+
* @param string $value
|
290 |
+
* @return void
|
291 |
+
*/
|
292 |
+
function setVersion( $value ) {
|
293 |
+
if( empty( $value )) return FALSE;
|
294 |
+
$this->version = $value;
|
295 |
+
return TRUE;
|
296 |
+
}
|
297 |
+
/*********************************************************************************/
|
298 |
+
/**
|
299 |
+
* Property Name: x-prop
|
300 |
+
*/
|
301 |
+
/**
|
302 |
+
* creates formatted output for calendar property x-prop, iCal format only
|
303 |
+
*
|
304 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
305 |
+
* @since 2.9.3 - 2011-05-14
|
306 |
+
* @return string
|
307 |
+
*/
|
308 |
+
function createXprop() {
|
309 |
+
if( 'xcal' == $this->format )
|
310 |
+
return false;
|
311 |
+
if( empty( $this->xprop ) || !is_array( $this->xprop )) return FALSE;
|
312 |
+
$output = null;
|
313 |
+
$toolbox = new calendarComponent();
|
314 |
+
$toolbox->setConfig( $this->getConfig());
|
315 |
+
foreach( $this->xprop as $label => $xpropPart ) {
|
316 |
+
if( !isset($xpropPart['value']) || ( empty( $xpropPart['value'] ) && !is_numeric( $xpropPart['value'] ))) {
|
317 |
+
$output .= $toolbox->_createElement( $label );
|
318 |
+
continue;
|
319 |
+
}
|
320 |
+
$attributes = $toolbox->_createParams( $xpropPart['params'], array( 'LANGUAGE' ));
|
321 |
+
if( is_array( $xpropPart['value'] )) {
|
322 |
+
foreach( $xpropPart['value'] as $pix => $theXpart )
|
323 |
+
$xpropPart['value'][$pix] = $toolbox->_strrep( $theXpart );
|
324 |
+
$xpropPart['value'] = implode( ',', $xpropPart['value'] );
|
325 |
+
}
|
326 |
+
else
|
327 |
+
$xpropPart['value'] = $toolbox->_strrep( $xpropPart['value'] );
|
328 |
+
$output .= $toolbox->_createElement( $label, $attributes, $xpropPart['value'] );
|
329 |
+
}
|
330 |
+
return $output;
|
331 |
+
}
|
332 |
+
/**
|
333 |
+
* set calendar property x-prop
|
334 |
+
*
|
335 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
336 |
+
* @since 2.9.3 - 2011-05-14
|
337 |
+
* @param string $label
|
338 |
+
* @param string $value
|
339 |
+
* @param array $params optional
|
340 |
+
* @return bool
|
341 |
+
*/
|
342 |
+
function setXprop( $label, $value, $params=FALSE ) {
|
343 |
+
if( empty( $label )) return FALSE;
|
344 |
+
if( empty( $value ) && !is_numeric( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
345 |
+
$xprop = array( 'value' => $value );
|
346 |
+
$xprop['params'] = iCalUtilityFunctions::_setParams( $params );
|
347 |
+
if( !is_array( $this->xprop )) $this->xprop = array();
|
348 |
+
$this->xprop[strtoupper( $label )] = $xprop;
|
349 |
+
return TRUE;
|
350 |
+
}
|
351 |
+
/*********************************************************************************/
|
352 |
+
/**
|
353 |
+
* delete calendar property value
|
354 |
+
*
|
355 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
356 |
+
* @since 2.8.8 - 2011-03-15
|
357 |
+
* @param mixed $propName, bool FALSE => X-property
|
358 |
+
* @param int $propix, optional, if specific property is wanted in case of multiply occurences
|
359 |
+
* @return bool, if successfull delete
|
360 |
+
*/
|
361 |
+
function deleteProperty( $propName=FALSE, $propix=FALSE ) {
|
362 |
+
$propName = ( $propName ) ? strtoupper( $propName ) : 'X-PROP';
|
363 |
+
if( !$propix )
|
364 |
+
$propix = ( isset( $this->propdelix[$propName] ) && ( 'X-PROP' != $propName )) ? $this->propdelix[$propName] + 2 : 1;
|
365 |
+
$this->propdelix[$propName] = --$propix;
|
366 |
+
$return = FALSE;
|
367 |
+
switch( $propName ) {
|
368 |
+
case 'CALSCALE':
|
369 |
+
if( isset( $this->calscale )) {
|
370 |
+
$this->calscale = null;
|
371 |
+
$return = TRUE;
|
372 |
+
}
|
373 |
+
break;
|
374 |
+
case 'METHOD':
|
375 |
+
if( isset( $this->method )) {
|
376 |
+
$this->method = null;
|
377 |
+
$return = TRUE;
|
378 |
+
}
|
379 |
+
break;
|
380 |
+
default:
|
381 |
+
$reduced = array();
|
382 |
+
if( $propName != 'X-PROP' ) {
|
383 |
+
if( !isset( $this->xprop[$propName] )) { unset( $this->propdelix[$propName] ); return FALSE; }
|
384 |
+
foreach( $this->xprop as $k => $a ) {
|
385 |
+
if(( $k != $propName ) && !empty( $a ))
|
386 |
+
$reduced[$k] = $a;
|
387 |
+
}
|
388 |
+
}
|
389 |
+
else {
|
390 |
+
if( count( $this->xprop ) <= $propix ) return FALSE;
|
391 |
+
$xpropno = 0;
|
392 |
+
foreach( $this->xprop as $xpropkey => $xpropvalue ) {
|
393 |
+
if( $propix != $xpropno )
|
394 |
+
$reduced[$xpropkey] = $xpropvalue;
|
395 |
+
$xpropno++;
|
396 |
+
}
|
397 |
+
}
|
398 |
+
$this->xprop = $reduced;
|
399 |
+
if( empty( $this->xprop )) {
|
400 |
+
unset( $this->propdelix[$propName] );
|
401 |
+
return FALSE;
|
402 |
+
}
|
403 |
+
return TRUE;
|
404 |
+
}
|
405 |
+
return $return;
|
406 |
+
}
|
407 |
+
/**
|
408 |
+
* get calendar property value/params
|
409 |
+
*
|
410 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
411 |
+
* @since 2.8.8 - 2011-04-16
|
412 |
+
* @param string $propName, optional
|
413 |
+
* @param int $propix, optional, if specific property is wanted in case of multiply occurences
|
414 |
+
* @param bool $inclParam=FALSE
|
415 |
+
* @return mixed
|
416 |
+
*/
|
417 |
+
function getProperty( $propName=FALSE, $propix=FALSE, $inclParam=FALSE ) {
|
418 |
+
$propName = ( $propName ) ? strtoupper( $propName ) : 'X-PROP';
|
419 |
+
if( 'X-PROP' == $propName ) {
|
420 |
+
if( !$propix )
|
421 |
+
$propix = ( isset( $this->propix[$propName] )) ? $this->propix[$propName] + 2 : 1;
|
422 |
+
$this->propix[$propName] = --$propix;
|
423 |
+
}
|
424 |
+
switch( $propName ) {
|
425 |
+
case 'ATTENDEE':
|
426 |
+
case 'CATEGORIES':
|
427 |
+
case 'DTSTART':
|
428 |
+
case 'LOCATION':
|
429 |
+
case 'ORGANIZER':
|
430 |
+
case 'PRIORITY':
|
431 |
+
case 'RESOURCES':
|
432 |
+
case 'STATUS':
|
433 |
+
case 'SUMMARY':
|
434 |
+
case 'RECURRENCE-ID-UID':
|
435 |
+
case 'R-UID':
|
436 |
+
case 'UID':
|
437 |
+
$output = array();
|
438 |
+
foreach ( $this->components as $cix => $component) {
|
439 |
+
if( !in_array( $component->objName, array('vevent', 'vtodo', 'vjournal', 'vfreebusy' )))
|
440 |
+
continue;
|
441 |
+
if(( 'ATTENDEE' == $propName ) || ( 'CATEGORIES' == $propName ) || ( 'RESOURCES' == $propName )) {
|
442 |
+
$component->_getProperties( $propName, $output );
|
443 |
+
continue;
|
444 |
+
}
|
445 |
+
elseif(( 3 < strlen( $propName )) && ( 'UID' == substr( $propName, -3 ))) {
|
446 |
+
if( FALSE !== ( $content = $component->getProperty( 'RECURRENCE-ID' )))
|
447 |
+
$content = $component->getProperty( 'UID' );
|
448 |
+
}
|
449 |
+
elseif( FALSE === ( $content = $component->getProperty( $propName )))
|
450 |
+
continue;
|
451 |
+
if( FALSE === $content )
|
452 |
+
continue;
|
453 |
+
elseif( is_array( $content )) {
|
454 |
+
if( isset( $content['year'] )) {
|
455 |
+
$key = sprintf( '%04d%02d%02d', $content['year'], $content['month'], $content['day'] );
|
456 |
+
if( !isset( $output[$key] ))
|
457 |
+
$output[$key] = 1;
|
458 |
+
else
|
459 |
+
$output[$key] += 1;
|
460 |
+
}
|
461 |
+
else {
|
462 |
+
foreach( $content as $partValue => $partCount ) {
|
463 |
+
if( !isset( $output[$partValue] ))
|
464 |
+
$output[$partValue] = $partCount;
|
465 |
+
else
|
466 |
+
$output[$partValue] += $partCount;
|
467 |
+
}
|
468 |
+
}
|
469 |
+
} // end elseif( is_array( $content )) {
|
470 |
+
elseif( !isset( $output[$content] ))
|
471 |
+
$output[$content] = 1;
|
472 |
+
else
|
473 |
+
$output[$content] += 1;
|
474 |
+
} // end foreach ( $this->components as $cix => $component)
|
475 |
+
if( !empty( $output ))
|
476 |
+
ksort( $output );
|
477 |
+
return $output;
|
478 |
+
break;
|
479 |
+
|
480 |
+
case 'CALSCALE':
|
481 |
+
return ( !empty( $this->calscale )) ? $this->calscale : FALSE;
|
482 |
+
break;
|
483 |
+
case 'METHOD':
|
484 |
+
return ( !empty( $this->method )) ? $this->method : FALSE;
|
485 |
+
break;
|
486 |
+
case 'PRODID':
|
487 |
+
if( empty( $this->prodid ))
|
488 |
+
$this->_makeProdid();
|
489 |
+
return $this->prodid;
|
490 |
+
break;
|
491 |
+
case 'VERSION':
|
492 |
+
return ( !empty( $this->version )) ? $this->version : FALSE;
|
493 |
+
break;
|
494 |
+
default:
|
495 |
+
if( $propName != 'X-PROP' ) {
|
496 |
+
if( !isset( $this->xprop[$propName] )) return FALSE;
|
497 |
+
return ( $inclParam ) ? array( $propName, $this->xprop[$propName] )
|
498 |
+
: array( $propName, $this->xprop[$propName]['value'] );
|
499 |
+
}
|
500 |
+
else {
|
501 |
+
if( empty( $this->xprop )) return FALSE;
|
502 |
+
$xpropno = 0;
|
503 |
+
foreach( $this->xprop as $xpropkey => $xpropvalue ) {
|
504 |
+
if( $propix == $xpropno )
|
505 |
+
return ( $inclParam ) ? array( $xpropkey, $this->xprop[$xpropkey] )
|
506 |
+
: array( $xpropkey, $this->xprop[$xpropkey]['value'] );
|
507 |
+
else
|
508 |
+
$xpropno++;
|
509 |
+
}
|
510 |
+
unset( $this->propix[$propName] );
|
511 |
+
return FALSE; // not found ??
|
512 |
+
}
|
513 |
+
}
|
514 |
+
return FALSE;
|
515 |
+
}
|
516 |
+
/**
|
517 |
+
* general vcalendar property setting
|
518 |
+
*
|
519 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
520 |
+
* @since 2.2.13 - 2007-11-04
|
521 |
+
* @param mixed $args variable number of function arguments,
|
522 |
+
* first argument is ALWAYS component name,
|
523 |
+
* second ALWAYS component value!
|
524 |
+
* @return bool
|
525 |
+
*/
|
526 |
+
function setProperty () {
|
527 |
+
$numargs = func_num_args();
|
528 |
+
if( 1 > $numargs )
|
529 |
+
return FALSE;
|
530 |
+
$arglist = func_get_args();
|
531 |
+
$arglist[0] = strtoupper( $arglist[0] );
|
532 |
+
switch( $arglist[0] ) {
|
533 |
+
case 'CALSCALE':
|
534 |
+
return $this->setCalscale( $arglist[1] );
|
535 |
+
case 'METHOD':
|
536 |
+
return $this->setMethod( $arglist[1] );
|
537 |
+
case 'VERSION':
|
538 |
+
return $this->setVersion( $arglist[1] );
|
539 |
+
default:
|
540 |
+
if( !isset( $arglist[1] )) $arglist[1] = null;
|
541 |
+
if( !isset( $arglist[2] )) $arglist[2] = null;
|
542 |
+
return $this->setXprop( $arglist[0], $arglist[1], $arglist[2] );
|
543 |
+
}
|
544 |
+
return FALSE;
|
545 |
+
}
|
546 |
+
/*********************************************************************************/
|
547 |
+
/**
|
548 |
+
* get vcalendar config values or * calendar components
|
549 |
+
*
|
550 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
551 |
+
* @since 2.9.6 - 2011-05-14
|
552 |
+
* @param mixed $config
|
553 |
+
* @return value
|
554 |
+
*/
|
555 |
+
function getConfig( $config = FALSE ) {
|
556 |
+
if( !$config ) {
|
557 |
+
$return = array();
|
558 |
+
$return['ALLOWEMPTY'] = $this->getConfig( 'ALLOWEMPTY' );
|
559 |
+
$return['DELIMITER'] = $this->getConfig( 'DELIMITER' );
|
560 |
+
$return['DIRECTORY'] = $this->getConfig( 'DIRECTORY' );
|
561 |
+
$return['FILENAME'] = $this->getConfig( 'FILENAME' );
|
562 |
+
$return['DIRFILE'] = $this->getConfig( 'DIRFILE' );
|
563 |
+
$return['FILESIZE'] = $this->getConfig( 'FILESIZE' );
|
564 |
+
$return['FORMAT'] = $this->getConfig( 'FORMAT' );
|
565 |
+
if( FALSE !== ( $lang = $this->getConfig( 'LANGUAGE' )))
|
566 |
+
$return['LANGUAGE'] = $lang;
|
567 |
+
$return['NEWLINECHAR'] = $this->getConfig( 'NEWLINECHAR' );
|
568 |
+
$return['UNIQUE_ID'] = $this->getConfig( 'UNIQUE_ID' );
|
569 |
+
if( FALSE !== ( $url = $this->getConfig( 'URL' )))
|
570 |
+
$return['URL'] = $url;
|
571 |
+
$return['TZID'] = $this->getConfig( 'TZID' );
|
572 |
+
return $return;
|
573 |
+
}
|
574 |
+
switch( strtoupper( $config )) {
|
575 |
+
case 'ALLOWEMPTY':
|
576 |
+
return $this->allowEmpty;
|
577 |
+
break;
|
578 |
+
case 'COMPSINFO':
|
579 |
+
unset( $this->compix );
|
580 |
+
$info = array();
|
581 |
+
foreach( $this->components as $cix => $component ) {
|
582 |
+
if( empty( $component )) continue;
|
583 |
+
$info[$cix]['ordno'] = $cix + 1;
|
584 |
+
$info[$cix]['type'] = $component->objName;
|
585 |
+
$info[$cix]['uid'] = $component->getProperty( 'uid' );
|
586 |
+
$info[$cix]['props'] = $component->getConfig( 'propinfo' );
|
587 |
+
$info[$cix]['sub'] = $component->getConfig( 'compsinfo' );
|
588 |
+
}
|
589 |
+
return $info;
|
590 |
+
break;
|
591 |
+
case 'DELIMITER':
|
592 |
+
return $this->delimiter;
|
593 |
+
break;
|
594 |
+
case 'DIRECTORY':
|
595 |
+
if( empty( $this->directory ))
|
596 |
+
$this->directory = '.';
|
597 |
+
return $this->directory;
|
598 |
+
break;
|
599 |
+
case 'DIRFILE':
|
600 |
+
return $this->getConfig( 'directory' ).$this->getConfig( 'delimiter' ).$this->getConfig( 'filename' );
|
601 |
+
break;
|
602 |
+
case 'FILEINFO':
|
603 |
+
return array( $this->getConfig( 'directory' )
|
604 |
+
, $this->getConfig( 'filename' )
|
605 |
+
, $this->getConfig( 'filesize' ));
|
606 |
+
break;
|
607 |
+
case 'FILENAME':
|
608 |
+
if( empty( $this->filename )) {
|
609 |
+
if( 'xcal' == $this->format )
|
610 |
+
$this->filename = date( 'YmdHis' ).'.xml'; // recommended xcs.. .
|
611 |
+
else
|
612 |
+
$this->filename = date( 'YmdHis' ).'.ics';
|
613 |
+
}
|
614 |
+
return $this->filename;
|
615 |
+
break;
|
616 |
+
case 'FILESIZE':
|
617 |
+
$size = 0;
|
618 |
+
if( empty( $this->url )) {
|
619 |
+
$dirfile = $this->getConfig( 'dirfile' );
|
620 |
+
if( !is_file( $dirfile ) || ( FALSE === ( $size = filesize( $dirfile ))))
|
621 |
+
$size = 0;
|
622 |
+
clearstatcache();
|
623 |
+
}
|
624 |
+
return $size;
|
625 |
+
break;
|
626 |
+
case 'FORMAT':
|
627 |
+
return ( $this->format == 'xcal' ) ? 'xCal' : 'iCal';
|
628 |
+
break;
|
629 |
+
case 'LANGUAGE':
|
630 |
+
/* get language for calendar component as defined in [RFC 1766] */
|
631 |
+
return $this->language;
|
632 |
+
break;
|
633 |
+
case 'NL':
|
634 |
+
case 'NEWLINECHAR':
|
635 |
+
return $this->nl;
|
636 |
+
break;
|
637 |
+
case 'TZID':
|
638 |
+
return $this->dtzid;
|
639 |
+
break;
|
640 |
+
case 'UNIQUE_ID':
|
641 |
+
return $this->unique_id;
|
642 |
+
break;
|
643 |
+
case 'URL':
|
644 |
+
if( !empty( $this->url ))
|
645 |
+
return $this->url;
|
646 |
+
else
|
647 |
+
return FALSE;
|
648 |
+
break;
|
649 |
+
}
|
650 |
+
}
|
651 |
+
/**
|
652 |
+
* general vcalendar config setting
|
653 |
+
*
|
654 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
655 |
+
* @since 2.9.6 - 2011-05-14
|
656 |
+
* @param mixed $config
|
657 |
+
* @param string $value
|
658 |
+
* @return void
|
659 |
+
*/
|
660 |
+
function setConfig( $config, $value = FALSE) {
|
661 |
+
if( is_array( $config )) {
|
662 |
+
foreach( $config as $cKey => $cValue ) {
|
663 |
+
if( FALSE === $this->setConfig( $cKey, $cValue ))
|
664 |
+
return FALSE;
|
665 |
+
}
|
666 |
+
return TRUE;
|
667 |
+
}
|
668 |
+
$res = FALSE;
|
669 |
+
switch( strtoupper( $config )) {
|
670 |
+
case 'ALLOWEMPTY':
|
671 |
+
$this->allowEmpty = $value;
|
672 |
+
$subcfg = array( 'ALLOWEMPTY' => $value );
|
673 |
+
$res = TRUE;
|
674 |
+
break;
|
675 |
+
case 'DELIMITER':
|
676 |
+
$this->delimiter = $value;
|
677 |
+
return TRUE;
|
678 |
+
break;
|
679 |
+
case 'DIRECTORY':
|
680 |
+
$value = trim( $value );
|
681 |
+
$del = $this->getConfig('delimiter');
|
682 |
+
if( $del == substr( $value, ( 0 - strlen( $del ))))
|
683 |
+
$value = substr( $value, 0, ( strlen( $value ) - strlen( $del )));
|
684 |
+
if( is_dir( $value )) {
|
685 |
+
/* local directory */
|
686 |
+
clearstatcache();
|
687 |
+
$this->directory = $value;
|
688 |
+
$this->url = null;
|
689 |
+
return TRUE;
|
690 |
+
}
|
691 |
+
else
|
692 |
+
return FALSE;
|
693 |
+
break;
|
694 |
+
case 'FILENAME':
|
695 |
+
$value = trim( $value );
|
696 |
+
if( !empty( $this->url )) {
|
697 |
+
/* remote directory+file -> URL */
|
698 |
+
$this->filename = $value;
|
699 |
+
return TRUE;
|
700 |
+
}
|
701 |
+
$dirfile = $this->getConfig( 'directory' ).$this->getConfig( 'delimiter' ).$value;
|
702 |
+
if( file_exists( $dirfile )) {
|
703 |
+
/* local file exists */
|
704 |
+
if( is_readable( $dirfile ) || is_writable( $dirfile )) {
|
705 |
+
clearstatcache();
|
706 |
+
$this->filename = $value;
|
707 |
+
return TRUE;
|
708 |
+
}
|
709 |
+
else
|
710 |
+
return FALSE;
|
711 |
+
}
|
712 |
+
elseif( is_readable($this->getConfig( 'directory' ) ) || is_writable( $this->getConfig( 'directory' ) )) {
|
713 |
+
/* read- or writable directory */
|
714 |
+
$this->filename = $value;
|
715 |
+
return TRUE;
|
716 |
+
}
|
717 |
+
else
|
718 |
+
return FALSE;
|
719 |
+
break;
|
720 |
+
case 'FORMAT':
|
721 |
+
$value = trim( strtolower( $value ));
|
722 |
+
if( 'xcal' == $value ) {
|
723 |
+
$this->format = 'xcal';
|
724 |
+
$this->attributeDelimiter = $this->nl;
|
725 |
+
$this->valueInit = null;
|
726 |
+
}
|
727 |
+
else {
|
728 |
+
$this->format = null;
|
729 |
+
$this->attributeDelimiter = ';';
|
730 |
+
$this->valueInit = ':';
|
731 |
+
}
|
732 |
+
$subcfg = array( 'FORMAT' => $value );
|
733 |
+
$res = TRUE;
|
734 |
+
break;
|
735 |
+
case 'LANGUAGE':
|
736 |
+
// set language for calendar component as defined in [RFC 1766]
|
737 |
+
$value = trim( $value );
|
738 |
+
$this->language = $value;
|
739 |
+
$subcfg = array( 'LANGUAGE' => $value );
|
740 |
+
$res = TRUE;
|
741 |
+
break;
|
742 |
+
case 'NL':
|
743 |
+
case 'NEWLINECHAR':
|
744 |
+
$this->nl = $value;
|
745 |
+
$subcfg = array( 'NL' => $value );
|
746 |
+
$res = TRUE;
|
747 |
+
break;
|
748 |
+
case 'TZID':
|
749 |
+
$this->dtzid = $value;
|
750 |
+
$subcfg = array( 'TZID' => $value );
|
751 |
+
$res = TRUE;
|
752 |
+
break;
|
753 |
+
case 'UNIQUE_ID':
|
754 |
+
$value = trim( $value );
|
755 |
+
$this->unique_id = $value;
|
756 |
+
$subcfg = array( 'UNIQUE_ID' => $value );
|
757 |
+
$res = TRUE;
|
758 |
+
break;
|
759 |
+
case 'URL':
|
760 |
+
/* remote file - URL */
|
761 |
+
$value = trim( $value );
|
762 |
+
$value = str_replace( 'HTTP://', 'http://', $value );
|
763 |
+
$value = str_replace( 'WEBCAL://', 'http://', $value );
|
764 |
+
$value = str_replace( 'webcal://', 'http://', $value );
|
765 |
+
$this->url = $value;
|
766 |
+
$this->directory = null;
|
767 |
+
$parts = pathinfo( $value );
|
768 |
+
return $this->setConfig( 'filename', $parts['basename'] );
|
769 |
+
break;
|
770 |
+
default: // any unvalid config key.. .
|
771 |
+
return TRUE;
|
772 |
+
}
|
773 |
+
if( !$res ) return FALSE;
|
774 |
+
if( isset( $subcfg ) && !empty( $this->components )) {
|
775 |
+
foreach( $subcfg as $cfgkey => $cfgvalue ) {
|
776 |
+
foreach( $this->components as $cix => $component ) {
|
777 |
+
$res = $component->setConfig( $cfgkey, $cfgvalue, TRUE );
|
778 |
+
if( !$res )
|
779 |
+
break 2;
|
780 |
+
$this->components[$cix] = $component->copy(); // PHP4 compliant
|
781 |
+
}
|
782 |
+
}
|
783 |
+
}
|
784 |
+
return $res;
|
785 |
+
}
|
786 |
+
/*********************************************************************************/
|
787 |
+
/**
|
788 |
+
* add calendar component to container
|
789 |
+
*
|
790 |
+
* alias to setComponent
|
791 |
+
*
|
792 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
793 |
+
* @since 1.x.x - 2007-04-24
|
794 |
+
* @param object $component calendar component
|
795 |
+
* @return void
|
796 |
+
*/
|
797 |
+
function addComponent( $component ) {
|
798 |
+
$this->setComponent( $component );
|
799 |
+
}
|
800 |
+
/**
|
801 |
+
* delete calendar component from container
|
802 |
+
*
|
803 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
804 |
+
* @since 2.8.8 - 2011-03-15
|
805 |
+
* @param mixed $arg1 ordno / component type / component uid
|
806 |
+
* @param mixed $arg2 optional, ordno if arg1 = component type
|
807 |
+
* @return void
|
808 |
+
*/
|
809 |
+
function deleteComponent( $arg1, $arg2=FALSE ) {
|
810 |
+
$argType = $index = null;
|
811 |
+
if ( ctype_digit( (string) $arg1 )) {
|
812 |
+
$argType = 'INDEX';
|
813 |
+
$index = (int) $arg1 - 1;
|
814 |
+
}
|
815 |
+
elseif(( strlen( $arg1 ) <= strlen( 'vfreebusy' )) && ( FALSE === strpos( $arg1, '@' ))) {
|
816 |
+
$argType = strtolower( $arg1 );
|
817 |
+
$index = ( !empty( $arg2 ) && ctype_digit( (string) $arg2 )) ? (( int ) $arg2 - 1 ) : 0;
|
818 |
+
}
|
819 |
+
$cix1dC = 0;
|
820 |
+
foreach ( $this->components as $cix => $component) {
|
821 |
+
if( empty( $component )) continue;
|
822 |
+
if(( 'INDEX' == $argType ) && ( $index == $cix )) {
|
823 |
+
unset( $this->components[$cix] );
|
824 |
+
return TRUE;
|
825 |
+
}
|
826 |
+
elseif( $argType == $component->objName ) {
|
827 |
+
if( $index == $cix1dC ) {
|
828 |
+
unset( $this->components[$cix] );
|
829 |
+
return TRUE;
|
830 |
+
}
|
831 |
+
$cix1dC++;
|
832 |
+
}
|
833 |
+
elseif( !$argType && ($arg1 == $component->getProperty( 'uid' ))) {
|
834 |
+
unset( $this->components[$cix] );
|
835 |
+
return TRUE;
|
836 |
+
}
|
837 |
+
}
|
838 |
+
return FALSE;
|
839 |
+
}
|
840 |
+
/**
|
841 |
+
* get calendar component from container
|
842 |
+
*
|
843 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
844 |
+
* @since 2.9.1 - 2011-04-16
|
845 |
+
* @param mixed $arg1 optional, ordno/component type/ component uid
|
846 |
+
* @param mixed $arg2 optional, ordno if arg1 = component type
|
847 |
+
* @return object
|
848 |
+
*/
|
849 |
+
function getComponent( $arg1=FALSE, $arg2=FALSE ) {
|
850 |
+
$index = $argType = null;
|
851 |
+
if ( !$arg1 ) { // first or next in component chain
|
852 |
+
$argType = 'INDEX';
|
853 |
+
$index = $this->compix['INDEX'] = ( isset( $this->compix['INDEX'] )) ? $this->compix['INDEX'] + 1 : 1;
|
854 |
+
}
|
855 |
+
elseif ( ctype_digit( (string) $arg1 )) { // specific component in chain
|
856 |
+
$argType = 'INDEX';
|
857 |
+
$index = (int) $arg1;
|
858 |
+
unset( $this->compix );
|
859 |
+
}
|
860 |
+
elseif( is_array( $arg1 )) { // array( *[propertyName => propertyValue] )
|
861 |
+
$arg2 = implode( '-', array_keys( $arg1 ));
|
862 |
+
$index = $this->compix[$arg2] = ( isset( $this->compix[$arg2] )) ? $this->compix[$arg2] + 1 : 1;
|
863 |
+
$dateProps = array( 'DTSTART', 'DTEND', 'DUE', 'CREATED', 'COMPLETED', 'DTSTAMP', 'LAST-MODIFIED', 'RECURRENCE-ID' );
|
864 |
+
$otherProps = array( 'ATTENDEE', 'CATEGORIES', 'LOCATION', 'ORGANIZER', 'PRIORITY', 'RESOURCES', 'STATUS', 'SUMMARY', 'UID' );
|
865 |
+
}
|
866 |
+
elseif(( strlen( $arg1 ) <= strlen( 'vfreebusy' )) && ( FALSE === strpos( $arg1, '@' ))) { // object class name
|
867 |
+
unset( $this->compix['INDEX'] );
|
868 |
+
$argType = strtolower( $arg1 );
|
869 |
+
if( !$arg2 )
|
870 |
+
$index = $this->compix[$argType] = ( isset( $this->compix[$argType] )) ? $this->compix[$argType] + 1 : 1;
|
871 |
+
elseif( isset( $arg2 ) && ctype_digit( (string) $arg2 ))
|
872 |
+
$index = (int) $arg2;
|
873 |
+
}
|
874 |
+
elseif(( strlen( $arg1 ) > strlen( 'vfreebusy' )) && ( FALSE !== strpos( $arg1, '@' ))) { // UID as 1st argument
|
875 |
+
if( !$arg2 )
|
876 |
+
$index = $this->compix[$arg1] = ( isset( $this->compix[$arg1] )) ? $this->compix[$arg1] + 1 : 1;
|
877 |
+
elseif( isset( $arg2 ) && ctype_digit( (string) $arg2 ))
|
878 |
+
$index = (int) $arg2;
|
879 |
+
}
|
880 |
+
if( isset( $index ))
|
881 |
+
$index -= 1;
|
882 |
+
$ckeys = array_keys( $this->components );
|
883 |
+
if( !empty( $index) && ( $index > end( $ckeys )))
|
884 |
+
return FALSE;
|
885 |
+
$cix1gC = 0;
|
886 |
+
foreach ( $this->components as $cix => $component) {
|
887 |
+
if( empty( $component )) continue;
|
888 |
+
if(( 'INDEX' == $argType ) && ( $index == $cix ))
|
889 |
+
return $component->copy();
|
890 |
+
elseif( $argType == $component->objName ) {
|
891 |
+
if( $index == $cix1gC )
|
892 |
+
return $component->copy();
|
893 |
+
$cix1gC++;
|
894 |
+
}
|
895 |
+
elseif( is_array( $arg1 )) { // array( *[propertyName => propertyValue] )
|
896 |
+
$hit = FALSE;
|
897 |
+
foreach( $arg1 as $pName => $pValue ) {
|
898 |
+
$pName = strtoupper( $pName );
|
899 |
+
if( !in_array( $pName, $dateProps ) && !in_array( $pName, $otherProps ))
|
900 |
+
continue;
|
901 |
+
if(( 'ATTENDEE' == $pName ) || ( 'CATEGORIES' == $pName ) || ( 'RESOURCES' == $pName )) { // multiple ocurrence may occur
|
902 |
+
$propValues = array();
|
903 |
+
$component->_getProperties( $pName, $propValues );
|
904 |
+
$propValues = array_keys( $propValues );
|
905 |
+
$hit = ( in_array( $pValue, $propValues )) ? TRUE : FALSE;
|
906 |
+
continue;
|
907 |
+
} // end if(( 'CATEGORIES' == $propName ) || ( 'RESOURCES' == $propName )) { // multiple ocurrence may occur
|
908 |
+
if( FALSE === ( $value = $component->getProperty( $pName ))) { // single ocurrency
|
909 |
+
$hit = FALSE; // missing property
|
910 |
+
continue;
|
911 |
+
}
|
912 |
+
if( 'SUMMARY' == $pName ) { // exists within (any case)
|
913 |
+
$hit = ( FALSE !== stripos( $d, $pValue )) ? TRUE : FALSE;
|
914 |
+
continue;
|
915 |
+
}
|
916 |
+
if( in_array( strtoupper( $pName ), $dateProps )) {
|
917 |
+
$valuedate = sprintf( '%04d%02d%02d', $value['year'], $value['month'], $value['day'] );
|
918 |
+
if( 8 < strlen( $pValue )) {
|
919 |
+
if( isset( $value['hour'] )) {
|
920 |
+
if( 'T' == substr( $pValue, 8, 1 ))
|
921 |
+
$pValue = str_replace( 'T', '', $pValue );
|
922 |
+
$valuedate .= sprintf( '%02d%02d%02d', $value['hour'], $value['min'], $value['sec'] );
|
923 |
+
}
|
924 |
+
else
|
925 |
+
$pValue = substr( $pValue, 0, 8 );
|
926 |
+
}
|
927 |
+
$hit = ( $pValue == $valuedate ) ? TRUE : FALSE;
|
928 |
+
continue;
|
929 |
+
}
|
930 |
+
elseif( !is_array( $value ))
|
931 |
+
$value = array( $value );
|
932 |
+
foreach( $value as $part ) {
|
933 |
+
$part = ( FALSE !== strpos( $part, ',' )) ? explode( ',', $part ) : array( $part );
|
934 |
+
foreach( $part as $subPart ) {
|
935 |
+
if( $pValue == $subPart ) {
|
936 |
+
$hit = TRUE;
|
937 |
+
continue 2;
|
938 |
+
}
|
939 |
+
}
|
940 |
+
}
|
941 |
+
$hit = FALSE; // no hit in property
|
942 |
+
} // end foreach( $arg1 as $pName => $pValue )
|
943 |
+
if( $hit ) {
|
944 |
+
if( $index == $cix1gC )
|
945 |
+
return $component->copy();
|
946 |
+
$cix1gC++;
|
947 |
+
}
|
948 |
+
} // end elseif( is_array( $arg1 )) { // array( *[propertyName => propertyValue] )
|
949 |
+
elseif( !$argType && ($arg1 == $component->getProperty( 'uid' ))) { // UID
|
950 |
+
if( $index == $cix1gC )
|
951 |
+
return $component->copy();
|
952 |
+
$cix1gC++;
|
953 |
+
}
|
954 |
+
} // end foreach ( $this->components.. .
|
955 |
+
/* not found.. . */
|
956 |
+
unset( $this->compix );
|
957 |
+
return FALSE;
|
958 |
+
}
|
959 |
+
/**
|
960 |
+
* create new calendar component, already included within calendar
|
961 |
+
*
|
962 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
963 |
+
* @since 2.6.33 - 2011-01-03
|
964 |
+
* @param string $compType component type
|
965 |
+
* @return object (reference)
|
966 |
+
*/
|
967 |
+
function & newComponent( $compType ) {
|
968 |
+
$config = $this->getConfig();
|
969 |
+
$keys = array_keys( $this->components );
|
970 |
+
$ix = end( $keys) + 1;
|
971 |
+
switch( strtoupper( $compType )) {
|
972 |
+
case 'EVENT':
|
973 |
+
case 'VEVENT':
|
974 |
+
$this->components[$ix] = new vevent( $config );
|
975 |
+
break;
|
976 |
+
case 'TODO':
|
977 |
+
case 'VTODO':
|
978 |
+
$this->components[$ix] = new vtodo( $config );
|
979 |
+
break;
|
980 |
+
case 'JOURNAL':
|
981 |
+
case 'VJOURNAL':
|
982 |
+
$this->components[$ix] = new vjournal( $config );
|
983 |
+
break;
|
984 |
+
case 'FREEBUSY':
|
985 |
+
case 'VFREEBUSY':
|
986 |
+
$this->components[$ix] = new vfreebusy( $config );
|
987 |
+
break;
|
988 |
+
case 'TIMEZONE':
|
989 |
+
case 'VTIMEZONE':
|
990 |
+
array_unshift( $this->components, new vtimezone( $config ));
|
991 |
+
$ix = 0;
|
992 |
+
break;
|
993 |
+
default:
|
994 |
+
return FALSE;
|
995 |
+
}
|
996 |
+
return $this->components[$ix];
|
997 |
+
}
|
998 |
+
/**
|
999 |
+
* select components from calendar on date or selectOption basis
|
1000 |
+
*
|
1001 |
+
* Ensure DTSTART is set for every component.
|
1002 |
+
* No date controls occurs.
|
1003 |
+
*
|
1004 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
1005 |
+
* @since 2.9.7 - 2011-06-04
|
1006 |
+
* @param mixed $startY optional, start Year, default current Year ALT. array selecOptions
|
1007 |
+
* @param int $startM optional, start Month, default current Month
|
1008 |
+
* @param int $startD optional, start Day, default current Day
|
1009 |
+
* @param int $endY optional, end Year, default $startY
|
1010 |
+
* @param int $endY optional, end Month, default $startM
|
1011 |
+
* @param int $endY optional, end Day, default $startD
|
1012 |
+
* @param mixed $cType optional, calendar component type(-s), default FALSE=all else string/array type(-s)
|
1013 |
+
* @param bool $flat optional, FALSE (default) => output : array[Year][Month][Day][]
|
1014 |
+
* TRUE => output : array[] (ignores split)
|
1015 |
+
* @param bool $any optional, TRUE (default) - select component that take place within period
|
1016 |
+
* FALSE - only components that starts within period
|
1017 |
+
* @param bool $split optional, TRUE (default) - one component copy every day it take place during the
|
1018 |
+
* period (implies flat=FALSE)
|
1019 |
+
* FALSE - one occurance of component only in output array
|
1020 |
+
* @return array or FALSE
|
1021 |
+
*/
|
1022 |
+
function selectComponents( $startY=FALSE, $startM=FALSE, $startD=FALSE, $endY=FALSE, $endM=FALSE, $endD=FALSE, $cType=FALSE, $flat=FALSE, $any=TRUE, $split=TRUE ) {
|
1023 |
+
/* check if empty calendar */
|
1024 |
+
if( 0 >= count( $this->components )) return FALSE;
|
1025 |
+
if( is_array( $startY ))
|
1026 |
+
return $this->selectComponents2( $startY );
|
1027 |
+
/* check default dates */
|
1028 |
+
if( !$startY ) $startY = date( 'Y' );
|
1029 |
+
if( !$startM ) $startM = date( 'm' );
|
1030 |
+
if( !$startD ) $startD = date( 'd' );
|
1031 |
+
$startDate = mktime( 0, 0, 0, $startM, $startD, $startY );
|
1032 |
+
if( !$endY ) $endY = $startY;
|
1033 |
+
if( !$endM ) $endM = $startM;
|
1034 |
+
if( !$endD ) $endD = $startD;
|
1035 |
+
$endDate = mktime( 23, 59, 59, $endM, $endD, $endY );
|
1036 |
+
//echo 'selectComp arg='.date( 'Y-m-d H:i:s', $startDate).' -- '.date( 'Y-m-d H:i:s', $endDate)."<br />\n"; $tcnt = 0;// test ###
|
1037 |
+
/* check component types */
|
1038 |
+
$validTypes = array('vevent', 'vtodo', 'vjournal', 'vfreebusy' );
|
1039 |
+
if( is_array( $cType )) {
|
1040 |
+
foreach( $cType as $cix => $theType ) {
|
1041 |
+
$cType[$cix] = $theType = strtolower( $theType );
|
1042 |
+
if( !in_array( $theType, $validTypes ))
|
1043 |
+
$cType[$cix] = 'vevent';
|
1044 |
+
}
|
1045 |
+
$cType = array_unique( $cType );
|
1046 |
+
}
|
1047 |
+
elseif( !empty( $cType )) {
|
1048 |
+
$cType = strtolower( $cType );
|
1049 |
+
if( !in_array( $cType, $validTypes ))
|
1050 |
+
$cType = array( 'vevent' );
|
1051 |
+
else
|
1052 |
+
$cType = array( $cType );
|
1053 |
+
}
|
1054 |
+
else
|
1055 |
+
$cType = $validTypes;
|
1056 |
+
if( 0 >= count( $cType ))
|
1057 |
+
$cType = $validTypes;
|
1058 |
+
if(( TRUE === $flat ) && ( TRUE === $split )) // invalid combination
|
1059 |
+
$split = FALSE;
|
1060 |
+
/* iterate components */
|
1061 |
+
$result = array();
|
1062 |
+
foreach ( $this->components as $cix => $component ) {
|
1063 |
+
if( empty( $component )) continue;
|
1064 |
+
unset( $start );
|
1065 |
+
/* deselect unvalid type components */
|
1066 |
+
if( !in_array( $component->objName, $cType )) continue;
|
1067 |
+
$start = $component->getProperty( 'dtstart' );
|
1068 |
+
/* select due when dtstart is missing */
|
1069 |
+
if( empty( $start ) && ( $component->objName == 'vtodo' ) && ( FALSE === ( $start = $component->getProperty( 'due' ))))
|
1070 |
+
continue;
|
1071 |
+
$dtendExist = $dueExist = $durationExist = $endAllDayEvent = FALSE;
|
1072 |
+
unset( $end, $startWdate, $endWdate, $rdurWsecs, $rdur, $exdatelist, $workstart, $workend, $endDateFormat ); // clean up
|
1073 |
+
$startWdate = iCalUtilityFunctions::_date2timestamp( $start );
|
1074 |
+
$startDateFormat = ( isset( $start['hour'] )) ? 'Y-m-d H:i:s' : 'Y-m-d';
|
1075 |
+
/* get end date from dtend/due/duration properties */
|
1076 |
+
$end = $component->getProperty( 'dtend' );
|
1077 |
+
if( !empty( $end )) {
|
1078 |
+
$dtendExist = TRUE;
|
1079 |
+
$endDateFormat = ( isset( $end['hour'] )) ? 'Y-m-d H:i:s' : 'Y-m-d';
|
1080 |
+
}
|
1081 |
+
if( empty( $end ) && ( $component->objName == 'vtodo' )) {
|
1082 |
+
$end = $component->getProperty( 'due' );
|
1083 |
+
if( !empty( $end )) {
|
1084 |
+
$dueExist = TRUE;
|
1085 |
+
$endDateFormat = ( isset( $end['hour'] )) ? 'Y-m-d H:i:s' : 'Y-m-d';
|
1086 |
+
}
|
1087 |
+
}
|
1088 |
+
if( !empty( $end ) && !isset( $end['hour'] )) {
|
1089 |
+
/* a DTEND without time part regards an event that ends the day before,
|
1090 |
+
for an all-day event DTSTART=20071201 DTEND=20071202 (taking place 20071201!!! */
|
1091 |
+
$endAllDayEvent = TRUE;
|
1092 |
+
$endWdate = mktime( 23, 59, 59, $end['month'], ($end['day'] - 1), $end['year'] );
|
1093 |
+
$end['year'] = date( 'Y', $endWdate );
|
1094 |
+
$end['month'] = date( 'm', $endWdate );
|
1095 |
+
$end['day'] = date( 'd', $endWdate );
|
1096 |
+
$end['hour'] = 23;
|
1097 |
+
$end['min'] = $end['sec'] = 59;
|
1098 |
+
}
|
1099 |
+
if( empty( $end )) {
|
1100 |
+
$end = $component->getProperty( 'duration', FALSE, FALSE, TRUE );// in dtend (array) format
|
1101 |
+
if( !empty( $end ))
|
1102 |
+
$durationExist = TRUE;
|
1103 |
+
$endDateFormat = ( isset( $start['hour'] )) ? 'Y-m-d H:i:s' : 'Y-m-d';
|
1104 |
+
// if( !empty($end)) echo 'selectComp 4 start='.implode('-',$start).' end='.implode('-',$end)."<br />\n"; // test ###
|
1105 |
+
}
|
1106 |
+
if( empty( $end )) { // assume one day duration if missing end date
|
1107 |
+
$end = array( 'year' => $start['year'], 'month' => $start['month'], 'day' => $start['day'], 'hour' => 23, 'min' => 59, 'sec' => 59 );
|
1108 |
+
}
|
1109 |
+
// if( isset($end)) echo 'selectComp 5 start='.implode('-',$start).' end='.implode('-',$end)."<br />\n"; // test ###
|
1110 |
+
$endWdate = iCalUtilityFunctions::_date2timestamp( $end );
|
1111 |
+
if( $endWdate < $startWdate ) { // MUST be after start date!!
|
1112 |
+
$end = array( 'year' => $start['year'], 'month' => $start['month'], 'day' => $start['day'], 'hour' => 23, 'min' => 59, 'sec' => 59 );
|
1113 |
+
$endWdate = iCalUtilityFunctions::_date2timestamp( $end );
|
1114 |
+
}
|
1115 |
+
$rdurWsecs = $endWdate - $startWdate; // compute component duration in seconds
|
1116 |
+
/* make a list of optional exclude dates for component occurence from exrule and exdate */
|
1117 |
+
$exdatelist = array();
|
1118 |
+
$workstart = iCalUtilityFunctions::_timestamp2date(( $startDate - $rdurWsecs ), 6);
|
1119 |
+
$workend = iCalUtilityFunctions::_timestamp2date(( $endDate + $rdurWsecs ), 6);
|
1120 |
+
while( FALSE !== ( $exrule = $component->getProperty( 'exrule' ))) // check exrule
|
1121 |
+
iCalUtilityFunctions::_recur2date( $exdatelist, $exrule, $start, $workstart, $workend );
|
1122 |
+
while( FALSE !== ( $exdate = $component->getProperty( 'exdate' ))) { // check exdate
|
1123 |
+
foreach( $exdate as $theExdate ) {
|
1124 |
+
$exWdate = iCalUtilityFunctions::_date2timestamp( $theExdate );
|
1125 |
+
$exWdate = mktime( 0, 0, 0, date( 'm', $exWdate ), date( 'd', $exWdate ), date( 'Y', $exWdate ) ); // on a day-basis !!!
|
1126 |
+
if((( $startDate - $rdurWsecs ) <= $exWdate ) && ( $endDate >= $exWdate ))
|
1127 |
+
$exdatelist[$exWdate] = TRUE;
|
1128 |
+
}
|
1129 |
+
}
|
1130 |
+
/* if 'any' components, check repeating components, removing all excluding dates */
|
1131 |
+
if( TRUE === $any ) {
|
1132 |
+
/* make a list of optional repeating dates for component occurence, rrule, rdate */
|
1133 |
+
$recurlist = array();
|
1134 |
+
while( FALSE !== ( $rrule = $component->getProperty( 'rrule' ))) // check rrule
|
1135 |
+
iCalUtilityFunctions::_recur2date( $recurlist, $rrule, $start, $workstart, $workend );
|
1136 |
+
foreach( $recurlist as $recurkey => $recurvalue ) // key=match date as timestamp
|
1137 |
+
$recurlist[$recurkey] = $rdurWsecs; // add duration in seconds
|
1138 |
+
while( FALSE !== ( $rdate = $component->getProperty( 'rdate' ))) { // check rdate
|
1139 |
+
foreach( $rdate as $theRdate ) {
|
1140 |
+
if( is_array( $theRdate ) && ( 2 == count( $theRdate )) && // all days within PERIOD
|
1141 |
+
array_key_exists( '0', $theRdate ) && array_key_exists( '1', $theRdate )) {
|
1142 |
+
$rstart = iCalUtilityFunctions::_date2timestamp( $theRdate[0] );
|
1143 |
+
if(( $rstart < ( $startDate - $rdurWsecs )) || ( $rstart > $endDate ))
|
1144 |
+
continue;
|
1145 |
+
if( isset( $theRdate[1]['year'] )) // date-date period
|
1146 |
+
$rend = iCalUtilityFunctions::_date2timestamp( $theRdate[1] );
|
1147 |
+
else { // date-duration period
|
1148 |
+
$rend = iCalUtilityFunctions::_duration2date( $theRdate[0], $theRdate[1] );
|
1149 |
+
$rend = iCalUtilityFunctions::_date2timestamp( $rend );
|
1150 |
+
}
|
1151 |
+
while( $rstart < $rend ) {
|
1152 |
+
$recurlist[$rstart] = $rdurWsecs; // set start date for recurrence instance + rdate duration in seconds
|
1153 |
+
$rstart = mktime( date( 'H', $rstart ), date( 'i', $rstart ), date( 's', $rstart ), date( 'm', $rstart ), date( 'd', $rstart ) + 1, date( 'Y', $rstart ) ); // step one day
|
1154 |
+
}
|
1155 |
+
} // PERIOD end
|
1156 |
+
else { // single date
|
1157 |
+
$theRdate = iCalUtilityFunctions::_date2timestamp( $theRdate );
|
1158 |
+
if((( $startDate - $rdurWsecs ) <= $theRdate ) && ( $endDate >= $theRdate ))
|
1159 |
+
$recurlist[$theRdate] = $rdurWsecs; // set start date for recurrence instance + event duration in seconds
|
1160 |
+
}
|
1161 |
+
}
|
1162 |
+
}
|
1163 |
+
if( 0 < count( $recurlist )) {
|
1164 |
+
ksort( $recurlist );
|
1165 |
+
$xRecurrence = 1;
|
1166 |
+
foreach( $recurlist as $recurkey => $durvalue ) {
|
1167 |
+
// echo "recurKey=".date( 'Y-m-d H:i:s', $recurkey ).' dur='.iCalUtilityFunctions::offsetSec2His( $durvalue )."<br />\n"; // test ###;
|
1168 |
+
if((( $startDate - $rdurWsecs ) > $recurkey ) || ( $endDate < $recurkey )) // not within period
|
1169 |
+
continue;
|
1170 |
+
$checkDate = mktime( 0, 0, 0, date( 'm', $recurkey ), date( 'd', $recurkey ), date( 'Y', $recurkey ) ); // on a day-basis !!!
|
1171 |
+
if( isset( $exdatelist[$checkDate] )) // check excluded dates
|
1172 |
+
continue;
|
1173 |
+
if( $startWdate >= $recurkey ) // exclude component start date
|
1174 |
+
continue;
|
1175 |
+
$component2 = $component->copy();
|
1176 |
+
$rstart = $recurkey;
|
1177 |
+
$rend = $recurkey + $durvalue;
|
1178 |
+
/* add repeating components within valid dates to output array, only start date set */
|
1179 |
+
if( $flat ) {
|
1180 |
+
$datestring = date( $startDateFormat, $recurkey );
|
1181 |
+
if( isset( $start['tz'] ))
|
1182 |
+
$datestring .= ' '.$start['tz'];
|
1183 |
+
// echo "X-CURRENT-DTSTART 0 =$datestring tcnt =".++$tcnt."<br />";$component2->setProperty( 'X-CNT', $tcnt ); // test ###
|
1184 |
+
$component2->setProperty( 'X-CURRENT-DTSTART', $datestring );
|
1185 |
+
if( $dtendExist || $dueExist || $durationExist ) {
|
1186 |
+
$datestring = date( $endDateFormat, $recurkey + $durvalue ); // fixa korrekt sluttid
|
1187 |
+
if( isset( $end['tz'] ))
|
1188 |
+
$datestring .= ' '.$end['tz'];
|
1189 |
+
$propName = ( !$dueExist ) ? 'X-CURRENT-DTEND' : 'X-CURRENT-DUE';
|
1190 |
+
$component2->setProperty( $propName, $datestring );
|
1191 |
+
} // end if( $dtendExist || $dueExist || $durationExist )
|
1192 |
+
$component2->setProperty( 'X-RECURRENCE', ++$xRecurrence );
|
1193 |
+
$result[$component2->getProperty( 'UID' )] = $component2->copy(); // copy to output
|
1194 |
+
}
|
1195 |
+
/* add repeating components within valid dates to output array, one each day */
|
1196 |
+
elseif( $split ) {
|
1197 |
+
if( $rend > $endDate )
|
1198 |
+
$rend = $endDate;
|
1199 |
+
$startYMD = date( 'Ymd', $rstart );
|
1200 |
+
$endYMD = date( 'Ymd', $rend );
|
1201 |
+
// echo "splitStart=".date( 'Y-m-d H:i:s', $rstart ).' end='.date( 'Y-m-d H:i:s', $rend )."<br />\n"; // test ###;
|
1202 |
+
while( $rstart <= $rend ) { // iterate.. .
|
1203 |
+
$checkDate = mktime( 0, 0, 0, date( 'm', $rstart ), date( 'd', $rstart ), date( 'Y', $rstart ) ); // on a day-basis !!!
|
1204 |
+
if( isset( $exdatelist[$checkDate] )) // exclude any recurrence START date, found in exdatelist
|
1205 |
+
break;
|
1206 |
+
// echo "checking date after startdate=".date( 'Y-m-d H:i:s', $rstart ).' mot '.date( 'Y-m-d H:i:s', $startDate )."<br />"; // test ###;
|
1207 |
+
if( $rstart >= $startDate ) { // date after dtstart
|
1208 |
+
if( date( 'Ymd', $rstart ) > $startYMD ) // date after dtstart
|
1209 |
+
$datestring = date( $startDateFormat, $checkDate );
|
1210 |
+
else
|
1211 |
+
$datestring = date( $startDateFormat, $rstart );
|
1212 |
+
if( isset( $start['tz'] ))
|
1213 |
+
$datestring .= ' '.$start['tz'];
|
1214 |
+
//echo "X-CURRENT-DTSTART 1 = $datestring xRecurrence=$xRecurrence tcnt =".++$tcnt."<br />";$component2->setProperty( 'X-CNT', $tcnt ); // test ###
|
1215 |
+
$component2->setProperty( 'X-CURRENT-DTSTART', $datestring );
|
1216 |
+
if( $dtendExist || $dueExist || $durationExist ) {
|
1217 |
+
if( date( 'Ymd', $rstart ) < $endYMD ) // not the last day
|
1218 |
+
$tend = mktime( 23, 59, 59, date( 'm', $rstart ), date( 'd', $rstart ), date( 'Y', $rstart ));
|
1219 |
+
else
|
1220 |
+
$tend = mktime( date( 'H', $endWdate ), date( 'i', $endWdate ), date( 's', $endWdate ), date( 'm', $rstart ), date( 'd', $rstart ), date( 'Y', $rstart ) ); // on a day-basis !!!
|
1221 |
+
$datestring = date( $endDateFormat, $tend );
|
1222 |
+
if( isset( $end['tz'] ))
|
1223 |
+
$datestring .= ' '.$end['tz'];
|
1224 |
+
$propName = ( !$dueExist ) ? 'X-CURRENT-DTEND' : 'X-CURRENT-DUE';
|
1225 |
+
$component2->setProperty( $propName, $datestring );
|
1226 |
+
} // end if( $dtendExist || $dueExist || $durationExist )
|
1227 |
+
$component2->setProperty( 'X-RECURRENCE', $xRecurrence );
|
1228 |
+
$wd = getdate( $rstart );
|
1229 |
+
$result[$wd['year']][$wd['mon']][$wd['mday']][$component2->getProperty( 'UID' )] = $component2->copy(); // copy to output
|
1230 |
+
} // end if( $checkDate > $startYMD ) { // date after dtstart
|
1231 |
+
$rstart = mktime( date( 'H', $rstart ), date( 'i', $rstart ), date( 's', $rstart ), date( 'm', $rstart ), date( 'd', $rstart ) + 1, date( 'Y', $rstart ) ); // step one day
|
1232 |
+
} // end while( $rstart <= $rend )
|
1233 |
+
$xRecurrence += 1;
|
1234 |
+
} // end elseif( $split )
|
1235 |
+
elseif( $rstart >= $startDate ) { // date within period //* flat=FALSE && split=FALSE *//
|
1236 |
+
$checkDate = mktime( 0, 0, 0, date( 'm', $rstart ), date( 'd', $rstart ), date( 'Y', $rstart ) ); // on a day-basis !!!
|
1237 |
+
if( !isset( $exdatelist[$checkDate] )) { // exclude any recurrence START date, found in exdatelist
|
1238 |
+
$xRecurrence += 1;
|
1239 |
+
$datestring = date( $startDateFormat, $rstart );
|
1240 |
+
if( isset( $start['tz'] ))
|
1241 |
+
$datestring .= ' '.$start['tz'];
|
1242 |
+
//echo "X-CURRENT-DTSTART 2 = $datestring xRecurrence=$xRecurrence tcnt =".++$tcnt."<br />";$component2->setProperty( 'X-CNT', $tcnt ); // test ###
|
1243 |
+
$component2->setProperty( 'X-CURRENT-DTSTART', $datestring );
|
1244 |
+
if( $dtendExist || $dueExist || $durationExist ) {
|
1245 |
+
$rstart += $rdurWsecs;
|
1246 |
+
if( date( 'Ymd', $rstart ) < date( 'Ymd', $endWdate ))
|
1247 |
+
$tend = mktime( 23, 59, 59, date( 'm', $rstart ), date( 'd', $rstart ), date( 'Y', $rstart ));
|
1248 |
+
else
|
1249 |
+
$tend = mktime( date( 'H', $endWdate ), date( 'i', $endWdate ), date( 's', $endWdate ), date( 'm', $rstart ), date( 'd', $rstart ), date( 'Y', $rstart ) ); // on a day-basis !!!
|
1250 |
+
$datestring = date( $endDateFormat, $tend );
|
1251 |
+
if( isset( $end['tz'] ))
|
1252 |
+
$datestring .= ' '.$end['tz'];
|
1253 |
+
$propName = ( !$dueExist ) ? 'X-CURRENT-DTEND' : 'X-CURRENT-DUE';
|
1254 |
+
$component2->setProperty( $propName, $datestring );
|
1255 |
+
} // end if( $dtendExist || $dueExist || $durationExist )
|
1256 |
+
$component2->setProperty( 'X-RECURRENCE', $xRecurrence );
|
1257 |
+
$wd = getdate( $rstart );
|
1258 |
+
$result[$wd['year']][$wd['mon']][$wd['mday']][$component2->getProperty( 'UID' )] = $component2->copy(); // copy to output
|
1259 |
+
} // end if( !isset( $exdatelist[$checkDate] ))
|
1260 |
+
} // end elseif( $rstart >= $startDate )
|
1261 |
+
} // end foreach( $recurlist as $recurkey => $durvalue )
|
1262 |
+
} // end if( 0 < count( $recurlist ))
|
1263 |
+
/* deselect components with startdate/enddate not within period */
|
1264 |
+
if(( $endWdate < $startDate ) || ( $startWdate > $endDate ))
|
1265 |
+
continue;
|
1266 |
+
} // end if( TRUE === $any )
|
1267 |
+
/* deselect components with startdate not within period */
|
1268 |
+
elseif(( $startWdate < $startDate ) || ( $startWdate > $endDate ))
|
1269 |
+
continue;
|
1270 |
+
/* add the selected component (WITHIN valid dates) to output array */
|
1271 |
+
if( $flat )
|
1272 |
+
$result[$component->getProperty( 'UID' )] = $component->copy(); // copy to output;
|
1273 |
+
elseif( $split ) { // split the original component
|
1274 |
+
if( $endWdate > $endDate )
|
1275 |
+
$endWdate = $endDate; // use period end date
|
1276 |
+
$rstart = $startWdate;
|
1277 |
+
if( $rstart < $startDate )
|
1278 |
+
$rstart = $startDate; // use period start date
|
1279 |
+
$checkDate = mktime( 0, 0, 0, date( 'm', $rstart ), date( 'd', $rstart ), date( 'Y', $rstart ) ); // on a day-basis !!!
|
1280 |
+
if( !isset( $exdatelist[$checkDate] )) { // exclude any recurrence START date, found in exdatelist
|
1281 |
+
foreach( array( 'X-CURRENT-DTSTART','X-CURRENT-DTEND','X-CURRENT-DUE','X-RECURRENCE' ) as $propName )
|
1282 |
+
$component->deleteProperty( $propName ); // remove any x-props, if set
|
1283 |
+
while( $rstart <= $endWdate ) { // iterate
|
1284 |
+
if( $rstart > $startWdate ) { // if NOT startdate, set X-properties
|
1285 |
+
$datestring = date( $startDateFormat, mktime( 0, 0, 0, date( 'm', $rstart ), date( 'd', $rstart ), date( 'Y', $rstart )));
|
1286 |
+
if( isset( $start['tz'] ))
|
1287 |
+
$datestring .= ' '.$start['tz'];
|
1288 |
+
// echo "X-CURRENT-DTSTART 3 = $datestring xRecurrence=$xRecurrence tcnt =".++$tcnt."<br />";$component->setProperty( 'X-CNT', $tcnt ); // test ###
|
1289 |
+
$component->setProperty( 'X-CURRENT-DTSTART', $datestring );
|
1290 |
+
if( $dtendExist || $dueExist || $durationExist ) {
|
1291 |
+
if( date( 'Ymd', $rstart ) < date( 'Ymd', $endWdate ))
|
1292 |
+
$tend = mktime( 0, 0, 0, date( 'm', $rstart ), date( 'd', $rstart ), date( 'Y', $rstart ));
|
1293 |
+
else
|
1294 |
+
$tend = mktime( date( 'H', $endWdate ), date( 'i', $endWdate ), date( 's', $endWdate ), date( 'm', $rstart ), date( 'd', $rstart ), date( 'Y', $rstart ) ); // on a day-basis !!!
|
1295 |
+
$datestring = date( $endDateFormat, $tend );
|
1296 |
+
if( isset( $end['tz'] ))
|
1297 |
+
$datestring .= ' '.$end['tz'];
|
1298 |
+
$propName = ( !$dueExist ) ? 'X-CURRENT-DTEND' : 'X-CURRENT-DUE';
|
1299 |
+
$component->setProperty( $propName, $datestring );
|
1300 |
+
} // end if( $dtendExist || $dueExist || $durationExist )
|
1301 |
+
} // end if( $rstart > $startWdate )
|
1302 |
+
$wd = getdate( $rstart );
|
1303 |
+
$result[$wd['year']][$wd['mon']][$wd['mday']][$component->getProperty( 'UID' )] = $component->copy(); // copy to output
|
1304 |
+
$rstart = mktime( date( 'H', $rstart ), date( 'i', $rstart ), date( 's', $rstart ), date( 'm', $rstart ), date( 'd', $rstart ) + 1, date( 'Y', $rstart ) ); // step one day
|
1305 |
+
} // end while( $rstart <= $endWdate )
|
1306 |
+
} // end if( !isset( $exdatelist[$checkDate] ))
|
1307 |
+
} // end if( $split ) - else use component date
|
1308 |
+
elseif( $startWdate >= $startDate ) { // within period
|
1309 |
+
$checkDate = mktime( 0, 0, 0, date( 'm', $startWdate ), date( 'd', $startWdate ), date( 'Y', $startWdate ) ); // on a day-basis !!!
|
1310 |
+
if( !isset( $exdatelist[$checkDate] )) { // exclude any recurrence START date, found in exdatelist
|
1311 |
+
foreach( array( 'X-CURRENT-DTSTART','X-CURRENT-DTEND','X-CURRENT-DUE','X-RECURRENCE' ) as $propName )
|
1312 |
+
$component->deleteProperty( $propName ); // remove any x-props, if set
|
1313 |
+
$wd = getdate( $startWdate );
|
1314 |
+
$result[$wd['year']][$wd['mon']][$wd['mday']][$component->getProperty( 'UID' )] = $component->copy(); // copy to output
|
1315 |
+
}
|
1316 |
+
}
|
1317 |
+
} // end foreach ( $this->components as $cix => $component )
|
1318 |
+
if( 0 >= count( $result )) return FALSE;
|
1319 |
+
elseif( !$flat ) {
|
1320 |
+
foreach( $result as $y => $yeararr ) {
|
1321 |
+
foreach( $yeararr as $m => $montharr ) {
|
1322 |
+
foreach( $montharr as $d => $dayarr )
|
1323 |
+
$result[$y][$m][$d] = array_values( $dayarr ); // skip tricky UID-index
|
1324 |
+
ksort( $result[$y][$m] );
|
1325 |
+
}
|
1326 |
+
ksort( $result[$y] );
|
1327 |
+
}
|
1328 |
+
ksort( $result );
|
1329 |
+
} // end elseif( !$flat )
|
1330 |
+
return $result;
|
1331 |
+
}
|
1332 |
+
/**
|
1333 |
+
* select components from calendar on based on Categories, Location, Resources and/or Summary
|
1334 |
+
*
|
1335 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
1336 |
+
* @since 2.8.8 - 2011-05-03
|
1337 |
+
* @param array $selectOptions, (string) key => (mixed) value, (key=propertyName)
|
1338 |
+
* @return array
|
1339 |
+
*/
|
1340 |
+
function selectComponents2( $selectOptions ) {
|
1341 |
+
$output = array();
|
1342 |
+
$allowedProperties = array( 'ATTENDEE', 'CATEGORIES', 'LOCATION', 'ORGANIZER', 'RESOURCES', 'PRIORITY', 'STATUS', 'SUMMARY', 'UID' );
|
1343 |
+
foreach( $this->components as $cix => $component3 ) {
|
1344 |
+
if( !in_array( $component3->objName, array('vevent', 'vtodo', 'vjournal', 'vfreebusy' )))
|
1345 |
+
continue;
|
1346 |
+
$uid = $component3->getProperty( 'UID' );
|
1347 |
+
foreach( $selectOptions as $propName => $pvalue ) {
|
1348 |
+
$propName = strtoupper( $propName );
|
1349 |
+
if( !in_array( $propName, $allowedProperties ))
|
1350 |
+
continue;
|
1351 |
+
if( !is_array( $pvalue ))
|
1352 |
+
$pvalue = array( $pvalue );
|
1353 |
+
if(( 'UID' == $propName ) && in_array( $uid, $pvalue )) {
|
1354 |
+
$output[] = $component3->copy();
|
1355 |
+
continue;
|
1356 |
+
}
|
1357 |
+
elseif(( 'ATTENDEE' == $propName ) || ( 'CATEGORIES' == $propName ) || ( 'RESOURCES' == $propName )) {
|
1358 |
+
$propValues = array();
|
1359 |
+
$component3->_getProperties( $propName, $propValues );
|
1360 |
+
$propValues = array_keys( $propValues );
|
1361 |
+
foreach( $pvalue as $theValue ) {
|
1362 |
+
if( in_array( $theValue, $propValues ) && !isset( $output[$uid] )) {
|
1363 |
+
$output[$uid] = $component3->copy();
|
1364 |
+
break;
|
1365 |
+
}
|
1366 |
+
}
|
1367 |
+
continue;
|
1368 |
+
} // end elseif(( 'ATTENDEE' == $propName ) || ( 'CATEGORIES' == $propName ) || ( 'RESOURCES' == $propName ))
|
1369 |
+
elseif( FALSE === ( $d = $component3->getProperty( $propName ))) // single ocurrence
|
1370 |
+
continue;
|
1371 |
+
if( is_array( $d )) {
|
1372 |
+
foreach( $d as $part ) {
|
1373 |
+
if( in_array( $part, $pvalue ) && !isset( $output[$uid] ))
|
1374 |
+
$output[$uid] = $component3->copy();
|
1375 |
+
}
|
1376 |
+
}
|
1377 |
+
elseif(( 'SUMMARY' == $propName ) && !isset( $output[$uid] )) {
|
1378 |
+
foreach( $pvalue as $pval ) {
|
1379 |
+
if( FALSE !== stripos( $d, $pval )) {
|
1380 |
+
$output[$uid] = $component3->copy();
|
1381 |
+
break;
|
1382 |
+
}
|
1383 |
+
}
|
1384 |
+
}
|
1385 |
+
elseif( in_array( $d, $pvalue ) && !isset( $output[$uid] ))
|
1386 |
+
$output[$uid] = $component3->copy();
|
1387 |
+
} // end foreach( $selectOptions as $propName => $pvalue ) {
|
1388 |
+
} // end foreach( $this->components as $cix => $component3 ) {
|
1389 |
+
if( !empty( $output )) {
|
1390 |
+
ksort( $output );
|
1391 |
+
$output = array_values( $output );
|
1392 |
+
}
|
1393 |
+
return $output;
|
1394 |
+
}
|
1395 |
+
/**
|
1396 |
+
* add calendar component to container
|
1397 |
+
*
|
1398 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
1399 |
+
* @since 2.8.8 - 2011-03-15
|
1400 |
+
* @param object $component calendar component
|
1401 |
+
* @param mixed $arg1 optional, ordno/component type/ component uid
|
1402 |
+
* @param mixed $arg2 optional, ordno if arg1 = component type
|
1403 |
+
* @return void
|
1404 |
+
*/
|
1405 |
+
function setComponent( $component, $arg1=FALSE, $arg2=FALSE ) {
|
1406 |
+
$component->setConfig( $this->getConfig(), FALSE, TRUE );
|
1407 |
+
if( !in_array( $component->objName, array( 'valarm', 'vtimezone' ))) {
|
1408 |
+
/* make sure dtstamp and uid is set */
|
1409 |
+
$dummy1 = $component->getProperty( 'dtstamp' );
|
1410 |
+
$dummy2 = $component->getProperty( 'uid' );
|
1411 |
+
}
|
1412 |
+
if( !$arg1 ) { // plain insert, last in chain
|
1413 |
+
$this->components[] = $component->copy();
|
1414 |
+
return TRUE;
|
1415 |
+
}
|
1416 |
+
$argType = $index = null;
|
1417 |
+
if ( ctype_digit( (string) $arg1 )) { // index insert/replace
|
1418 |
+
$argType = 'INDEX';
|
1419 |
+
$index = (int) $arg1 - 1;
|
1420 |
+
}
|
1421 |
+
elseif( in_array( strtolower( $arg1 ), array( 'vevent', 'vtodo', 'vjournal', 'vfreebusy', 'valarm', 'vtimezone' ))) {
|
1422 |
+
$argType = strtolower( $arg1 );
|
1423 |
+
$index = ( ctype_digit( (string) $arg2 )) ? ((int) $arg2) - 1 : 0;
|
1424 |
+
}
|
1425 |
+
// else if arg1 is set, arg1 must be an UID
|
1426 |
+
$cix1sC = 0;
|
1427 |
+
foreach ( $this->components as $cix => $component2) {
|
1428 |
+
if( empty( $component2 )) continue;
|
1429 |
+
if(( 'INDEX' == $argType ) && ( $index == $cix )) { // index insert/replace
|
1430 |
+
$this->components[$cix] = $component->copy();
|
1431 |
+
return TRUE;
|
1432 |
+
}
|
1433 |
+
elseif( $argType == $component2->objName ) { // component Type index insert/replace
|
1434 |
+
if( $index == $cix1sC ) {
|
1435 |
+
$this->components[$cix] = $component->copy();
|
1436 |
+
return TRUE;
|
1437 |
+
}
|
1438 |
+
$cix1sC++;
|
1439 |
+
}
|
1440 |
+
elseif( !$argType && ( $arg1 == $component2->getProperty( 'uid' ))) { // UID insert/replace
|
1441 |
+
$this->components[$cix] = $component->copy();
|
1442 |
+
return TRUE;
|
1443 |
+
}
|
1444 |
+
}
|
1445 |
+
/* arg1=index and not found.. . insert at index .. .*/
|
1446 |
+
if( 'INDEX' == $argType ) {
|
1447 |
+
$this->components[$index] = $component->copy();
|
1448 |
+
ksort( $this->components, SORT_NUMERIC );
|
1449 |
+
}
|
1450 |
+
else /* not found.. . insert last in chain anyway .. .*/
|
1451 |
+
$this->components[] = $component->copy();
|
1452 |
+
return TRUE;
|
1453 |
+
}
|
1454 |
+
/**
|
1455 |
+
* sort iCal compoments
|
1456 |
+
*
|
1457 |
+
* ascending sort on properties (if exist) x-current-dtstart, dtstart,
|
1458 |
+
* x-current-dtend, dtend, x-current-due, due, duration, created, dtstamp, uid
|
1459 |
+
* if no arguments, otherwise sorting on argument CATEGORIES, LOCATION, SUMMARY or RESOURCES
|
1460 |
+
*
|
1461 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
1462 |
+
* @since 2.8.4 - 2011-06-02
|
1463 |
+
* @param string $sortArg, optional
|
1464 |
+
* @return void
|
1465 |
+
*
|
1466 |
+
*/
|
1467 |
+
function sort( $sortArg=FALSE ) {
|
1468 |
+
if( is_array( $this->components )) {
|
1469 |
+
if( $sortArg ) {
|
1470 |
+
$sortArg = strtoupper( $sortArg );
|
1471 |
+
if( !in_array( $sortArg, array( 'ATTENDEE', 'CATEGORIES', 'DTSTAMP', 'LOCATION', 'ORGANIZER', 'RESOURCES', 'PRIORITY', 'STATUS', 'SUMMARY' )))
|
1472 |
+
$sortArg = FALSE;
|
1473 |
+
}
|
1474 |
+
/* set sort parameters for each component */
|
1475 |
+
foreach( $this->components as $cix => & $c ) {
|
1476 |
+
$c->srtk = array( '0', '0', '0', '0' );
|
1477 |
+
if( 'vtimezone' == $c->objName ) {
|
1478 |
+
if( FALSE === ( $c->srtk[0] = $c->getProperty( 'tzid' )))
|
1479 |
+
$c->srtk[0] = 0;
|
1480 |
+
continue;
|
1481 |
+
}
|
1482 |
+
elseif( $sortArg ) {
|
1483 |
+
if(( 'ATTENDEE' == $sortArg ) || ( 'CATEGORIES' == $sortArg ) || ( 'RESOURCES' == $sortArg )) {
|
1484 |
+
$propValues = array();
|
1485 |
+
$c->_getProperties( $sortArg, $propValues );
|
1486 |
+
$c->srtk[0] = reset( array_keys( $propValues ));
|
1487 |
+
}
|
1488 |
+
elseif( FALSE !== ( $d = $c->getProperty( $sortArg )))
|
1489 |
+
$c->srtk[0] = $d;
|
1490 |
+
continue;
|
1491 |
+
}
|
1492 |
+
if( FALSE !== ( $d = $c->getProperty( 'X-CURRENT-DTSTART' )))
|
1493 |
+
$c->srtk[0] = iCalUtilityFunctions::_date_time_string( $d[1] );
|
1494 |
+
elseif( FALSE === ( $c->srtk[0] = $c->getProperty( 'dtstart' )))
|
1495 |
+
$c->srtk[1] = 0; // sortkey 0 : dtstart
|
1496 |
+
if( FALSE !== ( $d = $c->getProperty( 'X-CURRENT-DTEND' )))
|
1497 |
+
$c->srtk[1] = iCalUtilityFunctions::_date_time_string( $d[1] ); // sortkey 1 : dtend/due(/dtstart+duration)
|
1498 |
+
elseif( FALSE === ( $c->srtk[1] = $c->getProperty( 'dtend' ))) {
|
1499 |
+
if( FALSE !== ( $d = $c->getProperty( 'X-CURRENT-DUE' )))
|
1500 |
+
$c->srtk[1] = iCalUtilityFunctions::_date_time_string( $d[1] );
|
1501 |
+
elseif( FALSE === ( $c->srtk[1] = $c->getProperty( 'due' )))
|
1502 |
+
if( FALSE === ( $c->srtk[1] = $c->getProperty( 'duration', FALSE, FALSE, TRUE )))
|
1503 |
+
$c->srtk[1] = 0;
|
1504 |
+
}
|
1505 |
+
if( FALSE === ( $c->srtk[2] = $c->getProperty( 'created' ))) // sortkey 2 : created/dtstamp
|
1506 |
+
if( FALSE === ( $c->srtk[2] = $c->getProperty( 'dtstamp' )))
|
1507 |
+
$c->srtk[2] = 0;
|
1508 |
+
if( FALSE === ( $c->srtk[3] = $c->getProperty( 'uid' ))) // sortkey 3 : uid
|
1509 |
+
$c->srtk[3] = 0;
|
1510 |
+
} // end foreach( $this->components as & $c
|
1511 |
+
/* sort */
|
1512 |
+
usort( $this->components, array( $this, '_cmpfcn' ));
|
1513 |
+
}
|
1514 |
+
}
|
1515 |
+
function _cmpfcn( $a, $b ) {
|
1516 |
+
if( empty( $a )) return -1;
|
1517 |
+
if( empty( $b )) return 1;
|
1518 |
+
if( 'vtimezone' == $a->objName ) {
|
1519 |
+
if( 'vtimezone' != $b->objName ) return -1;
|
1520 |
+
elseif( $a->srtk[0] <= $b->srtk[0] ) return -1;
|
1521 |
+
else return 1;
|
1522 |
+
}
|
1523 |
+
elseif( 'vtimezone' == $b->objName ) return 1;
|
1524 |
+
$sortkeys = array( 'year', 'month', 'day', 'hour', 'min', 'sec' );
|
1525 |
+
for( $k = 0; $k < 4 ; $k++ ) {
|
1526 |
+
if( empty( $a->srtk[$k] )) return -1;
|
1527 |
+
elseif( empty( $b->srtk[$k] )) return 1;
|
1528 |
+
if( is_array( $a->srtk[$k] )) {
|
1529 |
+
if( is_array( $b->srtk[$k] )) {
|
1530 |
+
foreach( $sortkeys as $key ) {
|
1531 |
+
if ( empty( $a->srtk[$k][$key] )) return -1;
|
1532 |
+
elseif( empty( $b->srtk[$k][$key] )) return 1;
|
1533 |
+
if ( $a->srtk[$k][$key] == $b->srtk[$k][$key])
|
1534 |
+
continue;
|
1535 |
+
if (( (int) $a->srtk[$k][$key] ) < ((int) $b->srtk[$k][$key] ))
|
1536 |
+
return -1;
|
1537 |
+
elseif(( (int) $a->srtk[$k][$key] ) > ((int) $b->srtk[$k][$key] ))
|
1538 |
+
return 1;
|
1539 |
+
}
|
1540 |
+
}
|
1541 |
+
else return -1;
|
1542 |
+
}
|
1543 |
+
elseif( is_array( $b->srtk[$k] )) return 1;
|
1544 |
+
elseif( $a->srtk[$k] < $b->srtk[$k] ) return -1;
|
1545 |
+
elseif( $a->srtk[$k] > $b->srtk[$k] ) return 1;
|
1546 |
+
}
|
1547 |
+
return 0;
|
1548 |
+
}
|
1549 |
+
/**
|
1550 |
+
* parse iCal text/file into vcalendar, components, properties and parameters
|
1551 |
+
*
|
1552 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
1553 |
+
* @since 2.8.2 - 2011-05-21
|
1554 |
+
* @param mixed $unparsedtext, optional, strict rfc2445 formatted, single property string or array of property strings
|
1555 |
+
* @return bool FALSE if error occurs during parsing
|
1556 |
+
*
|
1557 |
+
*/
|
1558 |
+
function parse( $unparsedtext=FALSE ) {
|
1559 |
+
$nl = $this->getConfig( 'nl' );
|
1560 |
+
if(( FALSE === $unparsedtext ) || empty( $unparsedtext )) {
|
1561 |
+
/* directory+filename is set previously via setConfig directory+filename or url */
|
1562 |
+
if( FALSE === ( $filename = $this->getConfig( 'url' )))
|
1563 |
+
$filename = $this->getConfig( 'dirfile' );
|
1564 |
+
/* READ FILE */
|
1565 |
+
if( FALSE === ( $rows = file_get_contents( $filename )))
|
1566 |
+
return FALSE; /* err 1 */
|
1567 |
+
}
|
1568 |
+
elseif( is_array( $unparsedtext ))
|
1569 |
+
$rows = implode( '\n'.$nl, $unparsedtext );
|
1570 |
+
else
|
1571 |
+
$rows = & $unparsedtext;
|
1572 |
+
/* identify BEGIN:VCALENDAR, MUST be first row */
|
1573 |
+
if( 'BEGIN:VCALENDAR' != strtoupper( substr( $rows, 0, 15 )))
|
1574 |
+
return FALSE; /* err 8 */
|
1575 |
+
/* fix line folding */
|
1576 |
+
$eolchars = array( "\r\n", "\n\r", "\n", "\r" ); // check all line endings
|
1577 |
+
$EOLmark = FALSE;
|
1578 |
+
foreach( $eolchars as $eolchar ) {
|
1579 |
+
if( !$EOLmark && ( FALSE !== strpos( $rows, $eolchar ))) {
|
1580 |
+
$rows = str_replace( $eolchar." ", '', $rows );
|
1581 |
+
$rows = str_replace( $eolchar."\t", '', $rows );
|
1582 |
+
if( $eolchar != $nl )
|
1583 |
+
$rows = str_replace( $eolchar, $nl, $rows );
|
1584 |
+
$EOLmark = TRUE;
|
1585 |
+
}
|
1586 |
+
}
|
1587 |
+
$tmp = explode( $nl, $rows );
|
1588 |
+
$rows = array();
|
1589 |
+
foreach( $tmp as $tmpr )
|
1590 |
+
if( !empty( $tmpr ))
|
1591 |
+
$rows[] = $tmpr;
|
1592 |
+
/* skip trailing empty lines */
|
1593 |
+
$lix = count( $rows ) - 1;
|
1594 |
+
while( empty( $rows[$lix] ) && ( 0 < $lix ))
|
1595 |
+
$lix -= 1;
|
1596 |
+
/* identify ending END:VCALENDAR row, MUST be last row */
|
1597 |
+
if( 'END:VCALENDAR' != strtoupper( substr( $rows[$lix], 0, 13 )))
|
1598 |
+
return FALSE; /* err 9 */
|
1599 |
+
if( 3 > count( $rows ))
|
1600 |
+
return FALSE; /* err 10 */
|
1601 |
+
$comp = & $this;
|
1602 |
+
$calsync = 0;
|
1603 |
+
/* identify components and update unparsed data within component */
|
1604 |
+
$config = $this->getConfig();
|
1605 |
+
foreach( $rows as $line ) {
|
1606 |
+
if( '' == trim( $line ))
|
1607 |
+
continue;
|
1608 |
+
if( 'BEGIN:VCALENDAR' == strtoupper( substr( $line, 0, 15 ))) {
|
1609 |
+
$calsync++;
|
1610 |
+
continue;
|
1611 |
+
}
|
1612 |
+
elseif( 'END:VCALENDAR' == strtoupper( substr( $line, 0, 13 ))) {
|
1613 |
+
$calsync--;
|
1614 |
+
break;
|
1615 |
+
}
|
1616 |
+
elseif( 1 != $calsync )
|
1617 |
+
return FALSE; /* err 20 */
|
1618 |
+
elseif( in_array( strtoupper( substr( $line, 0, 6 )), array( 'END:VE', 'END:VF', 'END:VJ', 'END:VT' ))) {
|
1619 |
+
$this->components[] = $comp->copy();
|
1620 |
+
continue;
|
1621 |
+
}
|
1622 |
+
|
1623 |
+
if( 'BEGIN:VEVENT' == strtoupper( substr( $line, 0, 12 )))
|
1624 |
+
$comp = new vevent( $config );
|
1625 |
+
elseif( 'BEGIN:VFREEBUSY' == strtoupper( substr( $line, 0, 15 )))
|
1626 |
+
$comp = new vfreebusy( $config );
|
1627 |
+
elseif( 'BEGIN:VJOURNAL' == strtoupper( substr( $line, 0, 14 )))
|
1628 |
+
$comp = new vjournal( $config );
|
1629 |
+
elseif( 'BEGIN:VTODO' == strtoupper( substr( $line, 0, 11 )))
|
1630 |
+
$comp = new vtodo( $config );
|
1631 |
+
elseif( 'BEGIN:VTIMEZONE' == strtoupper( substr( $line, 0, 15 )))
|
1632 |
+
$comp = new vtimezone( $config );
|
1633 |
+
else /* update component with unparsed data */
|
1634 |
+
$comp->unparsed[] = $line;
|
1635 |
+
} // end - foreach( rows.. .
|
1636 |
+
unset( $config );
|
1637 |
+
/* parse data for calendar (this) object */
|
1638 |
+
if( isset( $this->unparsed ) && is_array( $this->unparsed ) && ( 0 < count( $this->unparsed ))) {
|
1639 |
+
/* concatenate property values spread over several lines */
|
1640 |
+
$lastix = -1;
|
1641 |
+
$propnames = array( 'calscale','method','prodid','version','x-' );
|
1642 |
+
$proprows = array();
|
1643 |
+
foreach( $this->unparsed as $line ) {
|
1644 |
+
if( '' == trim( $line ))
|
1645 |
+
continue;
|
1646 |
+
$newProp = FALSE;
|
1647 |
+
foreach ( $propnames as $propname ) {
|
1648 |
+
if( $propname == strtolower( substr( $line, 0, strlen( $propname )))) {
|
1649 |
+
$newProp = TRUE;
|
1650 |
+
break;
|
1651 |
+
}
|
1652 |
+
}
|
1653 |
+
if( $newProp ) {
|
1654 |
+
$newProp = FALSE;
|
1655 |
+
$lastix++;
|
1656 |
+
$proprows[$lastix] = $line;
|
1657 |
+
}
|
1658 |
+
else
|
1659 |
+
$proprows[$lastix] .= '!"#¤%&/()=?'.$line;
|
1660 |
+
}
|
1661 |
+
foreach( $proprows as $line ) {
|
1662 |
+
$line = str_replace( '!"#¤%&/()=? ', '', $line );
|
1663 |
+
$line = str_replace( '!"#¤%&/()=?', '', $line );
|
1664 |
+
if( '\n' == substr( $line, -2 ))
|
1665 |
+
$line = substr( $line, 0, strlen( $line ) - 2 );
|
1666 |
+
/* get property name */
|
1667 |
+
$cix = $propname = null;
|
1668 |
+
for( $cix=0, $clen = strlen( $line ); $cix < $clen; $cix++ ) {
|
1669 |
+
if( in_array( $line[$cix], array( ':', ';' )))
|
1670 |
+
break;
|
1671 |
+
else
|
1672 |
+
$propname .= $line[$cix];
|
1673 |
+
}
|
1674 |
+
/* ignore version/prodid properties */
|
1675 |
+
if( in_array( strtoupper( $propname ), array( 'VERSION', 'PRODID' )))
|
1676 |
+
continue;
|
1677 |
+
$line = substr( $line, $cix);
|
1678 |
+
/* separate attributes from value */
|
1679 |
+
$attr = array();
|
1680 |
+
$attrix = -1;
|
1681 |
+
$strlen = strlen( $line );
|
1682 |
+
for( $cix=0; $cix < $strlen; $cix++ ) {
|
1683 |
+
if(( ':' == $line[$cix] ) &&
|
1684 |
+
( '://' != substr( $line, $cix, 3 )) &&
|
1685 |
+
( !in_array( strtolower( substr( $line, $cix - 3, 4 )), array( 'fax:', 'cid:', 'sms:', 'tel:', 'urn:' ))) &&
|
1686 |
+
( !in_array( strtolower( substr( $line, $cix - 4, 5 )), array( 'crid:', 'news:', 'pres:' ))) &&
|
1687 |
+
( 'mailto:' != strtolower( substr( $line, $cix - 6, 7 )))) {
|
1688 |
+
$attrEnd = TRUE;
|
1689 |
+
if(( $cix < ( $strlen - 4 )) &&
|
1690 |
+
ctype_digit( substr( $line, $cix+1, 4 ))) { // an URI with a (4pos) portnr??
|
1691 |
+
for( $c2ix = $cix; 3 < $c2ix; $c2ix-- ) {
|
1692 |
+
if( '://' == substr( $line, $c2ix - 2, 3 )) {
|
1693 |
+
$attrEnd = FALSE;
|
1694 |
+
break; // an URI with a portnr!!
|
1695 |
+
}
|
1696 |
+
}
|
1697 |
+
}
|
1698 |
+
if( $attrEnd) {
|
1699 |
+
$line = substr( $line, $cix + 1 );
|
1700 |
+
break;
|
1701 |
+
}
|
1702 |
+
}
|
1703 |
+
if( ';' == $line[$cix] )
|
1704 |
+
$attr[++$attrix] = null;
|
1705 |
+
else
|
1706 |
+
$attr[$attrix] .= $line[$cix];
|
1707 |
+
}
|
1708 |
+
|
1709 |
+
/* make attributes in array format */
|
1710 |
+
$propattr = array();
|
1711 |
+
foreach( $attr as $attribute ) {
|
1712 |
+
$attrsplit = explode( '=', $attribute, 2 );
|
1713 |
+
if( 1 < count( $attrsplit ))
|
1714 |
+
$propattr[$attrsplit[0]] = $attrsplit[1];
|
1715 |
+
else
|
1716 |
+
$propattr[] = $attribute;
|
1717 |
+
}
|
1718 |
+
/* update Property */
|
1719 |
+
if( FALSE !== strpos( $line, ',' )) {
|
1720 |
+
$content = explode( ',', $line );
|
1721 |
+
$clen = count( $content );
|
1722 |
+
for( $cix = 0; $cix < $clen; $cix++ ) {
|
1723 |
+
if( "\\" == substr( $content[$cix], -1 )) {
|
1724 |
+
$content[$cix] .= ','.$content[$cix + 1];
|
1725 |
+
unset( $content[$cix + 1] );
|
1726 |
+
$cix++;
|
1727 |
+
}
|
1728 |
+
}
|
1729 |
+
if( 1 < count( $content )) {
|
1730 |
+
foreach( $content as $cix => $contentPart )
|
1731 |
+
$content[$cix] = calendarComponent::_strunrep( $contentPart );
|
1732 |
+
$this->setProperty( $propname, $content, $propattr );
|
1733 |
+
continue;
|
1734 |
+
}
|
1735 |
+
else
|
1736 |
+
$line = reset( $content );
|
1737 |
+
$line = calendarComponent::_strunrep( $line );
|
1738 |
+
}
|
1739 |
+
$this->setProperty( $propname, trim( $line ), $propattr );
|
1740 |
+
} // end - foreach( $this->unparsed.. .
|
1741 |
+
} // end - if( is_array( $this->unparsed.. .
|
1742 |
+
unset( $unparsedtext, $rows, $this->unparsed, $proprows );
|
1743 |
+
/* parse Components */
|
1744 |
+
if( is_array( $this->components ) && ( 0 < count( $this->components ))) {
|
1745 |
+
$ckeys = array_keys( $this->components );
|
1746 |
+
foreach( $ckeys as $ckey ) {
|
1747 |
+
if( !empty( $this->components[$ckey] ) && !empty( $this->components[$ckey]->unparsed )) {
|
1748 |
+
$this->components[$ckey]->parse();
|
1749 |
+
}
|
1750 |
+
}
|
1751 |
+
}
|
1752 |
+
else
|
1753 |
+
return FALSE; /* err 91 or something.. . */
|
1754 |
+
return TRUE;
|
1755 |
+
}
|
1756 |
+
/*********************************************************************************/
|
1757 |
+
/**
|
1758 |
+
* creates formatted output for calendar object instance
|
1759 |
+
*
|
1760 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
1761 |
+
* @since 2.8.1 - 2011-03-12
|
1762 |
+
* @return string
|
1763 |
+
*/
|
1764 |
+
function createCalendar() {
|
1765 |
+
$calendarInit1 = $calendarInit2 = $calendarxCaldecl = $calendarStart = $calendar = null;
|
1766 |
+
switch( $this->format ) {
|
1767 |
+
case 'xcal':
|
1768 |
+
$calendarInit1 = '<?xml version="1.0" encoding="UTF-8"?>'.$this->nl.
|
1769 |
+
'<!DOCTYPE iCalendar PUBLIC "-//IETF//DTD XCAL/iCalendar XML//EN"'.$this->nl.
|
1770 |
+
'"http://www.ietf.org/internet-drafts/draft-ietf-calsch-many-xcal-01.txt"';
|
1771 |
+
$calendarInit2 = '>'.$this->nl;
|
1772 |
+
$calendarStart = '<vcalendar';
|
1773 |
+
break;
|
1774 |
+
default:
|
1775 |
+
$calendarStart = 'BEGIN:VCALENDAR'.$this->nl;
|
1776 |
+
break;
|
1777 |
+
}
|
1778 |
+
$calendarStart .= $this->createVersion();
|
1779 |
+
$calendarStart .= $this->createProdid();
|
1780 |
+
$calendarStart .= $this->createCalscale();
|
1781 |
+
$calendarStart .= $this->createMethod();
|
1782 |
+
switch( $this->format ) {
|
1783 |
+
case 'xcal':
|
1784 |
+
$nlstrlen = strlen( $this->nl );
|
1785 |
+
if( $this->nl == substr( $calendarStart, ( 0 - $nlstrlen )))
|
1786 |
+
$calendarStart = substr( $calendarStart, 0, ( strlen( $calendarStart ) - $nlstrlen ));
|
1787 |
+
$calendarStart .= '>'.$this->nl;
|
1788 |
+
break;
|
1789 |
+
default:
|
1790 |
+
break;
|
1791 |
+
}
|
1792 |
+
$calendar .= $this->createXprop();
|
1793 |
+
foreach( $this->components as $component ) {
|
1794 |
+
if( empty( $component )) continue;
|
1795 |
+
$component->setConfig( $this->getConfig(), FALSE, TRUE );
|
1796 |
+
$calendar .= $component->createComponent( $this->xcaldecl );
|
1797 |
+
}
|
1798 |
+
if(( 0 < count( $this->xcaldecl )) && ( 'xcal' == $this->format )) { // xCal only
|
1799 |
+
$calendarInit1 .= $this->nl.'['.$this->nl;
|
1800 |
+
$old_xcaldecl = array();
|
1801 |
+
foreach( $this->xcaldecl as $declix => $declPart ) {
|
1802 |
+
if(( 0 < count( $old_xcaldecl)) &&
|
1803 |
+
( in_array( $declPart['uri'], $old_xcaldecl['uri'] )) &&
|
1804 |
+
( in_array( $declPart['external'], $old_xcaldecl['external'] )))
|
1805 |
+
continue; // no duplicate uri and ext. references
|
1806 |
+
$calendarxCaldecl .= '<!';
|
1807 |
+
foreach( $declPart as $declKey => $declValue ) {
|
1808 |
+
switch( $declKey ) { // index
|
1809 |
+
case 'xmldecl': // no 1
|
1810 |
+
$calendarxCaldecl .= $declValue.' ';
|
1811 |
+
break;
|
1812 |
+
case 'uri': // no 2
|
1813 |
+
$calendarxCaldecl .= $declValue.' ';
|
1814 |
+
$old_xcaldecl['uri'][] = $declValue;
|
1815 |
+
break;
|
1816 |
+
case 'ref': // no 3
|
1817 |
+
$calendarxCaldecl .= $declValue.' ';
|
1818 |
+
break;
|
1819 |
+
case 'external': // no 4
|
1820 |
+
$calendarxCaldecl .= '"'.$declValue.'" ';
|
1821 |
+
$old_xcaldecl['external'][] = $declValue;
|
1822 |
+
break;
|
1823 |
+
case 'type': // no 5
|
1824 |
+
$calendarxCaldecl .= $declValue.' ';
|
1825 |
+
break;
|
1826 |
+
case 'type2': // no 6
|
1827 |
+
$calendarxCaldecl .= $declValue;
|
1828 |
+
break;
|
1829 |
+
}
|
1830 |
+
}
|
1831 |
+
$calendarxCaldecl .= '>'.$this->nl;
|
1832 |
+
}
|
1833 |
+
$calendarInit2 = ']'.$calendarInit2;
|
1834 |
+
}
|
1835 |
+
switch( $this->format ) {
|
1836 |
+
case 'xcal':
|
1837 |
+
$calendar .= '</vcalendar>'.$this->nl;
|
1838 |
+
break;
|
1839 |
+
default:
|
1840 |
+
$calendar .= 'END:VCALENDAR'.$this->nl;
|
1841 |
+
break;
|
1842 |
+
}
|
1843 |
+
return $calendarInit1.$calendarxCaldecl.$calendarInit2.$calendarStart.$calendar;
|
1844 |
+
}
|
1845 |
+
/**
|
1846 |
+
* a HTTP redirect header is sent with created, updated and/or parsed calendar
|
1847 |
+
*
|
1848 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
1849 |
+
* @since 2.9.12 - 2011-07-13
|
1850 |
+
* @param bool $utf8Encode
|
1851 |
+
* @param bool $gzip
|
1852 |
+
* @return redirect
|
1853 |
+
*/
|
1854 |
+
function returnCalendar( $utf8Encode=FALSE, $gzip=FALSE ) {
|
1855 |
+
$filename = $this->getConfig( 'filename' );
|
1856 |
+
$output = $this->createCalendar();
|
1857 |
+
if( $utf8Encode )
|
1858 |
+
$output = utf8_encode( $output );
|
1859 |
+
if( $gzip ) {
|
1860 |
+
$output = gzencode( $output, 9 );
|
1861 |
+
header( 'Content-Encoding: gzip');
|
1862 |
+
header( 'Vary: *');
|
1863 |
+
}
|
1864 |
+
$filesize = strlen( $output );
|
1865 |
+
if( 'xcal' == $this->format )
|
1866 |
+
header( 'Content-Type: application/calendar+xml; charset=utf-8' );
|
1867 |
+
else
|
1868 |
+
header( 'Content-Type: text/calendar; charset=utf-8' );
|
1869 |
+
header( 'Content-Length: '.$filesize );
|
1870 |
+
header( 'Content-Disposition: attachment; filename="'.$filename.'"' );
|
1871 |
+
header( 'Cache-Control: max-age=10' );
|
1872 |
+
echo $output;
|
1873 |
+
die();
|
1874 |
+
}
|
1875 |
+
/**
|
1876 |
+
* save content in a file
|
1877 |
+
*
|
1878 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
1879 |
+
* @since 2.2.12 - 2007-12-30
|
1880 |
+
* @param string $directory optional
|
1881 |
+
* @param string $filename optional
|
1882 |
+
* @param string $delimiter optional
|
1883 |
+
* @return bool
|
1884 |
+
*/
|
1885 |
+
function saveCalendar( $directory=FALSE, $filename=FALSE, $delimiter=FALSE ) {
|
1886 |
+
if( $directory )
|
1887 |
+
$this->setConfig( 'directory', $directory );
|
1888 |
+
if( $filename )
|
1889 |
+
$this->setConfig( 'filename', $filename );
|
1890 |
+
if( $delimiter && ($delimiter != DIRECTORY_SEPARATOR ))
|
1891 |
+
$this->setConfig( 'delimiter', $delimiter );
|
1892 |
+
if( FALSE === ( $dirfile = $this->getConfig( 'url' )))
|
1893 |
+
$dirfile = $this->getConfig( 'dirfile' );
|
1894 |
+
$iCalFile = @fopen( $dirfile, 'w' );
|
1895 |
+
if( $iCalFile ) {
|
1896 |
+
if( FALSE === fwrite( $iCalFile, $this->createCalendar() ))
|
1897 |
+
return FALSE;
|
1898 |
+
fclose( $iCalFile );
|
1899 |
+
return TRUE;
|
1900 |
+
}
|
1901 |
+
else
|
1902 |
+
return FALSE;
|
1903 |
+
}
|
1904 |
+
/**
|
1905 |
+
* if recent version of calendar file exists (default one hour), an HTTP redirect header is sent
|
1906 |
+
* else FALSE is returned
|
1907 |
+
*
|
1908 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
1909 |
+
* @since 2.2.12 - 2007-10-28
|
1910 |
+
* @param string $directory optional alt. int timeout
|
1911 |
+
* @param string $filename optional
|
1912 |
+
* @param string $delimiter optional
|
1913 |
+
* @param int timeout optional, default 3600 sec
|
1914 |
+
* @return redirect/FALSE
|
1915 |
+
*/
|
1916 |
+
function useCachedCalendar( $directory=FALSE, $filename=FALSE, $delimiter=FALSE, $timeout=3600) {
|
1917 |
+
if ( $directory && ctype_digit( (string) $directory ) && !$filename ) {
|
1918 |
+
$timeout = (int) $directory;
|
1919 |
+
$directory = FALSE;
|
1920 |
+
}
|
1921 |
+
if( $directory )
|
1922 |
+
$this->setConfig( 'directory', $directory );
|
1923 |
+
if( $filename )
|
1924 |
+
$this->setConfig( 'filename', $filename );
|
1925 |
+
if( $delimiter && ( $delimiter != DIRECTORY_SEPARATOR ))
|
1926 |
+
$this->setConfig( 'delimiter', $delimiter );
|
1927 |
+
$filesize = $this->getConfig( 'filesize' );
|
1928 |
+
if( 0 >= $filesize )
|
1929 |
+
return FALSE;
|
1930 |
+
$dirfile = $this->getConfig( 'dirfile' );
|
1931 |
+
if( time() - filemtime( $dirfile ) < $timeout) {
|
1932 |
+
clearstatcache();
|
1933 |
+
$dirfile = $this->getConfig( 'dirfile' );
|
1934 |
+
$filename = $this->getConfig( 'filename' );
|
1935 |
+
// if( headers_sent( $filename, $linenum ))
|
1936 |
+
// die( "Headers already sent in $filename on line $linenum\n" );
|
1937 |
+
if( 'xcal' == $this->format )
|
1938 |
+
header( 'Content-Type: application/calendar+xml; charset=utf-8' );
|
1939 |
+
else
|
1940 |
+
header( 'Content-Type: text/calendar; charset=utf-8' );
|
1941 |
+
header( 'Content-Length: '.$filesize );
|
1942 |
+
header( 'Content-Disposition: attachment; filename="'.$filename.'"' );
|
1943 |
+
header( 'Cache-Control: max-age=10' );
|
1944 |
+
$fp = @fopen( $dirfile, 'r' );
|
1945 |
+
if( $fp ) {
|
1946 |
+
fpassthru( $fp );
|
1947 |
+
fclose( $fp );
|
1948 |
+
}
|
1949 |
+
die();
|
1950 |
+
}
|
1951 |
+
else
|
1952 |
+
return FALSE;
|
1953 |
+
}
|
1954 |
+
}
|
1955 |
+
/*********************************************************************************/
|
1956 |
+
/*********************************************************************************/
|
1957 |
+
/**
|
1958 |
+
* abstract class for calendar components
|
1959 |
+
*
|
1960 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
1961 |
+
* @since 2.9.6 - 2011-05-14
|
1962 |
+
*/
|
1963 |
+
class calendarComponent {
|
1964 |
+
// component property variables
|
1965 |
+
var $uid;
|
1966 |
+
var $dtstamp;
|
1967 |
+
|
1968 |
+
// component config variables
|
1969 |
+
var $allowEmpty;
|
1970 |
+
var $language;
|
1971 |
+
var $nl;
|
1972 |
+
var $unique_id;
|
1973 |
+
var $format;
|
1974 |
+
var $objName; // created automatically at instance creation
|
1975 |
+
var $dtzid; // default (local) timezone
|
1976 |
+
// component internal variables
|
1977 |
+
var $componentStart1;
|
1978 |
+
var $componentStart2;
|
1979 |
+
var $componentEnd1;
|
1980 |
+
var $componentEnd2;
|
1981 |
+
var $elementStart1;
|
1982 |
+
var $elementStart2;
|
1983 |
+
var $elementEnd1;
|
1984 |
+
var $elementEnd2;
|
1985 |
+
var $intAttrDelimiter;
|
1986 |
+
var $attributeDelimiter;
|
1987 |
+
var $valueInit;
|
1988 |
+
// component xCal declaration container
|
1989 |
+
var $xcaldecl;
|
1990 |
+
/**
|
1991 |
+
* constructor for calendar component object
|
1992 |
+
*
|
1993 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
1994 |
+
* @since 2.9.6 - 2011-05-17
|
1995 |
+
*/
|
1996 |
+
function calendarComponent() {
|
1997 |
+
$this->objName = ( isset( $this->timezonetype )) ?
|
1998 |
+
strtolower( $this->timezonetype ) : get_class ( $this );
|
1999 |
+
$this->uid = array();
|
2000 |
+
$this->dtstamp = array();
|
2001 |
+
|
2002 |
+
$this->language = null;
|
2003 |
+
$this->nl = null;
|
2004 |
+
$this->unique_id = null;
|
2005 |
+
$this->format = null;
|
2006 |
+
$this->dtzid = null;
|
2007 |
+
$this->allowEmpty = TRUE;
|
2008 |
+
$this->xcaldecl = array();
|
2009 |
+
|
2010 |
+
$this->_createFormat();
|
2011 |
+
$this->_makeDtstamp();
|
2012 |
+
}
|
2013 |
+
/*********************************************************************************/
|
2014 |
+
/**
|
2015 |
+
* Property Name: ACTION
|
2016 |
+
*/
|
2017 |
+
/**
|
2018 |
+
* creates formatted output for calendar component property action
|
2019 |
+
*
|
2020 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2021 |
+
* @since 2.4.8 - 2008-10-22
|
2022 |
+
* @return string
|
2023 |
+
*/
|
2024 |
+
function createAction() {
|
2025 |
+
if( empty( $this->action )) return FALSE;
|
2026 |
+
if( empty( $this->action['value'] ))
|
2027 |
+
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'ACTION' ) : FALSE;
|
2028 |
+
$attributes = $this->_createParams( $this->action['params'] );
|
2029 |
+
return $this->_createElement( 'ACTION', $attributes, $this->action['value'] );
|
2030 |
+
}
|
2031 |
+
/**
|
2032 |
+
* set calendar component property action
|
2033 |
+
*
|
2034 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2035 |
+
* @since 2.4.8 - 2008-11-04
|
2036 |
+
* @param string $value "AUDIO" / "DISPLAY" / "EMAIL" / "PROCEDURE"
|
2037 |
+
* @param mixed $params
|
2038 |
+
* @return bool
|
2039 |
+
*/
|
2040 |
+
function setAction( $value, $params=FALSE ) {
|
2041 |
+
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
2042 |
+
$this->action = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params ));
|
2043 |
+
return TRUE;
|
2044 |
+
}
|
2045 |
+
/*********************************************************************************/
|
2046 |
+
/**
|
2047 |
+
* Property Name: ATTACH
|
2048 |
+
*/
|
2049 |
+
/**
|
2050 |
+
* creates formatted output for calendar component property attach
|
2051 |
+
*
|
2052 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2053 |
+
* @since 0.9.7 - 2006-11-23
|
2054 |
+
* @return string
|
2055 |
+
*/
|
2056 |
+
function createAttach() {
|
2057 |
+
if( empty( $this->attach )) return FALSE;
|
2058 |
+
$output = null;
|
2059 |
+
foreach( $this->attach as $attachPart ) {
|
2060 |
+
if(! empty( $attachPart['value'] )) {
|
2061 |
+
$attributes = $this->_createParams( $attachPart['params'] );
|
2062 |
+
$output .= $this->_createElement( 'ATTACH', $attributes, $attachPart['value'] );
|
2063 |
+
}
|
2064 |
+
elseif( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'ATTACH' );
|
2065 |
+
}
|
2066 |
+
return $output;
|
2067 |
+
}
|
2068 |
+
/**
|
2069 |
+
* set calendar component property attach
|
2070 |
+
*
|
2071 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2072 |
+
* @since 2.5.1 - 2008-11-06
|
2073 |
+
* @param string $value
|
2074 |
+
* @param array $params, optional
|
2075 |
+
* @param integer $index, optional
|
2076 |
+
* @return bool
|
2077 |
+
*/
|
2078 |
+
function setAttach( $value, $params=FALSE, $index=FALSE ) {
|
2079 |
+
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
2080 |
+
iCalUtilityFunctions::_setMval( $this->attach, $value, $params, FALSE, $index );
|
2081 |
+
return TRUE;
|
2082 |
+
}
|
2083 |
+
/*********************************************************************************/
|
2084 |
+
/**
|
2085 |
+
* Property Name: ATTENDEE
|
2086 |
+
*/
|
2087 |
+
/**
|
2088 |
+
* creates formatted output for calendar component property attendee
|
2089 |
+
*
|
2090 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2091 |
+
* @since 2.9.8 - 2011-05-30
|
2092 |
+
* @return string
|
2093 |
+
*/
|
2094 |
+
function createAttendee() {
|
2095 |
+
if( empty( $this->attendee )) return FALSE;
|
2096 |
+
$output = null;
|
2097 |
+
foreach( $this->attendee as $attendeePart ) { // start foreach 1
|
2098 |
+
if( empty( $attendeePart['value'] )) {
|
2099 |
+
if( $this->getConfig( 'allowEmpty' ))
|
2100 |
+
$output .= $this->_createElement( 'ATTENDEE' );
|
2101 |
+
continue;
|
2102 |
+
}
|
2103 |
+
$attendee1 = $attendee2 = null;
|
2104 |
+
foreach( $attendeePart as $paramlabel => $paramvalue ) { // start foreach 2
|
2105 |
+
if( 'value' == $paramlabel )
|
2106 |
+
$attendee2 .= $paramvalue;
|
2107 |
+
elseif(( 'params' == $paramlabel ) && ( is_array( $paramvalue ))) { // start elseif
|
2108 |
+
// set attenddee parameters in rfc2445 order
|
2109 |
+
if( isset( $paramvalue['CUTYPE'] ))
|
2110 |
+
$attendee1 .= $this->intAttrDelimiter.'CUTYPE='.$paramvalue['CUTYPE'];
|
2111 |
+
if( isset( $paramvalue['MEMBER'] )) {
|
2112 |
+
$attendee1 .= $this->intAttrDelimiter.'MEMBER=';
|
2113 |
+
foreach( $paramvalue['MEMBER'] as $cix => $opv )
|
2114 |
+
$attendee1 .= ( $cix ) ? ', "'.$opv.'"' : '"'.$opv.'"' ;
|
2115 |
+
}
|
2116 |
+
if( isset( $paramvalue['ROLE'] ))
|
2117 |
+
$attendee1 .= $this->intAttrDelimiter.'ROLE='.$paramvalue['ROLE'];
|
2118 |
+
if( isset( $paramvalue['PARTSTAT'] ))
|
2119 |
+
$attendee1 .= $this->intAttrDelimiter.'PARTSTAT='.$paramvalue['PARTSTAT'];
|
2120 |
+
if( isset( $paramvalue['RSVP'] ))
|
2121 |
+
$attendee1 .= $this->intAttrDelimiter.'RSVP='.$paramvalue['RSVP'];
|
2122 |
+
if( isset( $paramvalue['DELEGATED-TO'] )) {
|
2123 |
+
$attendee1 .= $this->intAttrDelimiter.'DELEGATED-TO=';
|
2124 |
+
foreach( $paramvalue['DELEGATED-TO'] as $cix => $opv )
|
2125 |
+
$attendee1 .= ( $cix ) ? ', "'.$opv.'"' : '"'.$opv.'"' ;
|
2126 |
+
}
|
2127 |
+
if( isset( $paramvalue['DELEGATED-FROM'] )) {
|
2128 |
+
$attendee1 .= $this->intAttrDelimiter.'DELEGATED-FROM=';
|
2129 |
+
foreach( $paramvalue['DELEGATED-FROM'] as $cix => $opv )
|
2130 |
+
$attendee1 .= ( $cix ) ? ', "'.$opv.'"' : '"'.$opv.'"' ;
|
2131 |
+
}
|
2132 |
+
if( isset( $paramvalue['SENT-BY'] ))
|
2133 |
+
$attendee1 .= $this->intAttrDelimiter.'SENT-BY="'.$paramvalue['SENT-BY'].'"';
|
2134 |
+
if( isset( $paramvalue['CN'] ))
|
2135 |
+
$attendee1 .= $this->intAttrDelimiter.'CN="'.$paramvalue['CN'].'"';
|
2136 |
+
if( isset( $paramvalue['DIR'] ))
|
2137 |
+
$attendee1 .= $this->intAttrDelimiter.'DIR="'.$paramvalue['DIR'].'"';
|
2138 |
+
if( isset( $paramvalue['LANGUAGE'] ))
|
2139 |
+
$attendee1 .= $this->intAttrDelimiter.'LANGUAGE='.$paramvalue['LANGUAGE'];
|
2140 |
+
$xparams = array();
|
2141 |
+
foreach( $paramvalue as $optparamlabel => $optparamvalue ) { // start foreach 3
|
2142 |
+
if( ctype_digit( (string) $optparamlabel )) {
|
2143 |
+
$xparams[] = $optparamvalue;
|
2144 |
+
continue;
|
2145 |
+
}
|
2146 |
+
if( !in_array( $optparamlabel, array( 'CUTYPE', 'MEMBER', 'ROLE', 'PARTSTAT', 'RSVP', 'DELEGATED-TO', 'DELEGATED-FROM', 'SENT-BY', 'CN', 'DIR', 'LANGUAGE' )))
|
2147 |
+
$xparams[$optparamlabel] = $optparamvalue;
|
2148 |
+
} // end foreach 3
|
2149 |
+
ksort( $xparams, SORT_STRING );
|
2150 |
+
foreach( $xparams as $paramKey => $paramValue ) {
|
2151 |
+
if( ctype_digit( (string) $paramKey ))
|
2152 |
+
$attendee1 .= $this->intAttrDelimiter.$paramValue;
|
2153 |
+
else
|
2154 |
+
$attendee1 .= $this->intAttrDelimiter."$paramKey=$paramValue";
|
2155 |
+
} // end foreach 3
|
2156 |
+
} // end elseif(( 'params' == $paramlabel ) && ( is_array( $paramvalue )))
|
2157 |
+
} // end foreach 2
|
2158 |
+
$output .= $this->_createElement( 'ATTENDEE', $attendee1, $attendee2 );
|
2159 |
+
} // end foreach 1
|
2160 |
+
return $output;
|
2161 |
+
}
|
2162 |
+
/**
|
2163 |
+
* set calendar component property attach
|
2164 |
+
*
|
2165 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2166 |
+
* @since 2.6.34 - 2010-12-18
|
2167 |
+
* @param string $value
|
2168 |
+
* @param array $params, optional
|
2169 |
+
* @param integer $index, optional
|
2170 |
+
* @return bool
|
2171 |
+
*/
|
2172 |
+
function setAttendee( $value, $params=FALSE, $index=FALSE ) {
|
2173 |
+
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
2174 |
+
// ftp://, http://, mailto:, file://, gopher://, news:, nntp://, telnet://, wais://, prospero:// may exist.. . also in params
|
2175 |
+
if( FALSE !== ( $pos = strpos( substr( $value, 0, 9 ), ':' )))
|
2176 |
+
$value = strtoupper( substr( $value, 0, $pos )).substr( $value, $pos );
|
2177 |
+
elseif( !empty( $value ))
|
2178 |
+
$value = 'MAILTO:'.$value;
|
2179 |
+
$params2 = array();
|
2180 |
+
if( is_array($params )) {
|
2181 |
+
$optarrays = array();
|
2182 |
+
foreach( $params as $optparamlabel => $optparamvalue ) {
|
2183 |
+
$optparamlabel = strtoupper( $optparamlabel );
|
2184 |
+
switch( $optparamlabel ) {
|
2185 |
+
case 'MEMBER':
|
2186 |
+
case 'DELEGATED-TO':
|
2187 |
+
case 'DELEGATED-FROM':
|
2188 |
+
if( !is_array( $optparamvalue ))
|
2189 |
+
$optparamvalue = array( $optparamvalue );
|
2190 |
+
foreach( $optparamvalue as $part ) {
|
2191 |
+
$part = trim( $part );
|
2192 |
+
if(( '"' == substr( $part, 0, 1 )) &&
|
2193 |
+
( '"' == substr( $part, -1 )))
|
2194 |
+
$part = substr( $part, 1, ( strlen( $part ) - 2 ));
|
2195 |
+
if( 'mailto:' != strtolower( substr( $part, 0, 7 )))
|
2196 |
+
$part = "MAILTO:$part";
|
2197 |
+
else
|
2198 |
+
$part = 'MAILTO:'.substr( $part, 7 );
|
2199 |
+
$optarrays[$optparamlabel][] = $part;
|
2200 |
+
}
|
2201 |
+
break;
|
2202 |
+
default:
|
2203 |
+
if(( '"' == substr( $optparamvalue, 0, 1 )) &&
|
2204 |
+
( '"' == substr( $optparamvalue, -1 )))
|
2205 |
+
$optparamvalue = substr( $optparamvalue, 1, ( strlen( $optparamvalue ) - 2 ));
|
2206 |
+
if( 'SENT-BY' == $optparamlabel ) {
|
2207 |
+
if( 'mailto:' != strtolower( substr( $optparamvalue, 0, 7 )))
|
2208 |
+
$optparamvalue = "MAILTO:$optparamvalue";
|
2209 |
+
else
|
2210 |
+
$optparamvalue = 'MAILTO:'.substr( $optparamvalue, 7 );
|
2211 |
+
}
|
2212 |
+
$params2[$optparamlabel] = $optparamvalue;
|
2213 |
+
break;
|
2214 |
+
} // end switch( $optparamlabel.. .
|
2215 |
+
} // end foreach( $optparam.. .
|
2216 |
+
foreach( $optarrays as $optparamlabel => $optparams )
|
2217 |
+
$params2[$optparamlabel] = $optparams;
|
2218 |
+
}
|
2219 |
+
// remove defaults
|
2220 |
+
iCalUtilityFunctions::_existRem( $params2, 'CUTYPE', 'INDIVIDUAL' );
|
2221 |
+
iCalUtilityFunctions::_existRem( $params2, 'PARTSTAT', 'NEEDS-ACTION' );
|
2222 |
+
iCalUtilityFunctions::_existRem( $params2, 'ROLE', 'REQ-PARTICIPANT' );
|
2223 |
+
iCalUtilityFunctions::_existRem( $params2, 'RSVP', 'FALSE' );
|
2224 |
+
// check language setting
|
2225 |
+
if( isset( $params2['CN' ] )) {
|
2226 |
+
$lang = $this->getConfig( 'language' );
|
2227 |
+
if( !isset( $params2['LANGUAGE' ] ) && !empty( $lang ))
|
2228 |
+
$params2['LANGUAGE' ] = $lang;
|
2229 |
+
}
|
2230 |
+
iCalUtilityFunctions::_setMval( $this->attendee, $value, $params2, FALSE, $index );
|
2231 |
+
return TRUE;
|
2232 |
+
}
|
2233 |
+
/*********************************************************************************/
|
2234 |
+
/**
|
2235 |
+
* Property Name: CATEGORIES
|
2236 |
+
*/
|
2237 |
+
/**
|
2238 |
+
* creates formatted output for calendar component property categories
|
2239 |
+
*
|
2240 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2241 |
+
* @since 2.4.8 - 2008-10-22
|
2242 |
+
* @return string
|
2243 |
+
*/
|
2244 |
+
function createCategories() {
|
2245 |
+
if( empty( $this->categories )) return FALSE;
|
2246 |
+
$output = null;
|
2247 |
+
foreach( $this->categories as $category ) {
|
2248 |
+
if( empty( $category['value'] )) {
|
2249 |
+
if ( $this->getConfig( 'allowEmpty' ))
|
2250 |
+
$output .= $this->_createElement( 'CATEGORIES' );
|
2251 |
+
continue;
|
2252 |
+
}
|
2253 |
+
$attributes = $this->_createParams( $category['params'], array( 'LANGUAGE' ));
|
2254 |
+
if( is_array( $category['value'] )) {
|
2255 |
+
foreach( $category['value'] as $cix => $categoryPart )
|
2256 |
+
$category['value'][$cix] = $this->_strrep( $categoryPart );
|
2257 |
+
$content = implode( ',', $category['value'] );
|
2258 |
+
}
|
2259 |
+
else
|
2260 |
+
$content = $this->_strrep( $category['value'] );
|
2261 |
+
$output .= $this->_createElement( 'CATEGORIES', $attributes, $content );
|
2262 |
+
}
|
2263 |
+
return $output;
|
2264 |
+
}
|
2265 |
+
/**
|
2266 |
+
* set calendar component property categories
|
2267 |
+
*
|
2268 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2269 |
+
* @since 2.5.1 - 2008-11-06
|
2270 |
+
* @param mixed $value
|
2271 |
+
* @param array $params, optional
|
2272 |
+
* @param integer $index, optional
|
2273 |
+
* @return bool
|
2274 |
+
*/
|
2275 |
+
function setCategories( $value, $params=FALSE, $index=FALSE ) {
|
2276 |
+
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
2277 |
+
iCalUtilityFunctions::_setMval( $this->categories, $value, $params, FALSE, $index );
|
2278 |
+
return TRUE;
|
2279 |
+
}
|
2280 |
+
/*********************************************************************************/
|
2281 |
+
/**
|
2282 |
+
* Property Name: CLASS
|
2283 |
+
*/
|
2284 |
+
/**
|
2285 |
+
* creates formatted output for calendar component property class
|
2286 |
+
*
|
2287 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2288 |
+
* @since 0.9.7 - 2006-11-20
|
2289 |
+
* @return string
|
2290 |
+
*/
|
2291 |
+
function createClass() {
|
2292 |
+
if( empty( $this->class )) return FALSE;
|
2293 |
+
if( empty( $this->class['value'] ))
|
2294 |
+
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'CLASS' ) : FALSE;
|
2295 |
+
$attributes = $this->_createParams( $this->class['params'] );
|
2296 |
+
return $this->_createElement( 'CLASS', $attributes, $this->class['value'] );
|
2297 |
+
}
|
2298 |
+
/**
|
2299 |
+
* set calendar component property class
|
2300 |
+
*
|
2301 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2302 |
+
* @since 2.4.8 - 2008-11-04
|
2303 |
+
* @param string $value "PUBLIC" / "PRIVATE" / "CONFIDENTIAL" / iana-token / x-name
|
2304 |
+
* @param array $params optional
|
2305 |
+
* @return bool
|
2306 |
+
*/
|
2307 |
+
function setClass( $value, $params=FALSE ) {
|
2308 |
+
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
2309 |
+
$this->class = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params ));
|
2310 |
+
return TRUE;
|
2311 |
+
}
|
2312 |
+
/*********************************************************************************/
|
2313 |
+
/**
|
2314 |
+
* Property Name: COMMENT
|
2315 |
+
*/
|
2316 |
+
/**
|
2317 |
+
* creates formatted output for calendar component property comment
|
2318 |
+
*
|
2319 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2320 |
+
* @since 2.4.8 - 2008-10-22
|
2321 |
+
* @return string
|
2322 |
+
*/
|
2323 |
+
function createComment() {
|
2324 |
+
if( empty( $this->comment )) return FALSE;
|
2325 |
+
$output = null;
|
2326 |
+
foreach( $this->comment as $commentPart ) {
|
2327 |
+
if( empty( $commentPart['value'] )) {
|
2328 |
+
if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'COMMENT' );
|
2329 |
+
continue;
|
2330 |
+
}
|
2331 |
+
$attributes = $this->_createParams( $commentPart['params'], array( 'ALTREP', 'LANGUAGE' ));
|
2332 |
+
$content = $this->_strrep( $commentPart['value'] );
|
2333 |
+
$output .= $this->_createElement( 'COMMENT', $attributes, $content );
|
2334 |
+
}
|
2335 |
+
return $output;
|
2336 |
+
}
|
2337 |
+
/**
|
2338 |
+
* set calendar component property comment
|
2339 |
+
*
|
2340 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2341 |
+
* @since 2.5.1 - 2008-11-06
|
2342 |
+
* @param string $value
|
2343 |
+
* @param array $params, optional
|
2344 |
+
* @param integer $index, optional
|
2345 |
+
* @return bool
|
2346 |
+
*/
|
2347 |
+
function setComment( $value, $params=FALSE, $index=FALSE ) {
|
2348 |
+
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
2349 |
+
iCalUtilityFunctions::_setMval( $this->comment, $value, $params, FALSE, $index );
|
2350 |
+
return TRUE;
|
2351 |
+
}
|
2352 |
+
/*********************************************************************************/
|
2353 |
+
/**
|
2354 |
+
* Property Name: COMPLETED
|
2355 |
+
*/
|
2356 |
+
/**
|
2357 |
+
* creates formatted output for calendar component property completed
|
2358 |
+
*
|
2359 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2360 |
+
* @since 2.4.8 - 2008-10-22
|
2361 |
+
* @return string
|
2362 |
+
*/
|
2363 |
+
function createCompleted( ) {
|
2364 |
+
if( empty( $this->completed )) return FALSE;
|
2365 |
+
if( !isset( $this->completed['value']['year'] ) &&
|
2366 |
+
!isset( $this->completed['value']['month'] ) &&
|
2367 |
+
!isset( $this->completed['value']['day'] ) &&
|
2368 |
+
!isset( $this->completed['value']['hour'] ) &&
|
2369 |
+
!isset( $this->completed['value']['min'] ) &&
|
2370 |
+
!isset( $this->completed['value']['sec'] ))
|
2371 |
+
if( $this->getConfig( 'allowEmpty' ))
|
2372 |
+
return $this->_createElement( 'COMPLETED' );
|
2373 |
+
else return FALSE;
|
2374 |
+
$formatted = iCalUtilityFunctions::_format_date_time( $this->completed['value'], 7 );
|
2375 |
+
$attributes = $this->_createParams( $this->completed['params'] );
|
2376 |
+
return $this->_createElement( 'COMPLETED', $attributes, $formatted );
|
2377 |
+
}
|
2378 |
+
/**
|
2379 |
+
* set calendar component property completed
|
2380 |
+
*
|
2381 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2382 |
+
* @since 2.4.8 - 2008-10-23
|
2383 |
+
* @param mixed $year
|
2384 |
+
* @param mixed $month optional
|
2385 |
+
* @param int $day optional
|
2386 |
+
* @param int $hour optional
|
2387 |
+
* @param int $min optional
|
2388 |
+
* @param int $sec optional
|
2389 |
+
* @param array $params optional
|
2390 |
+
* @return bool
|
2391 |
+
*/
|
2392 |
+
function setCompleted( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) {
|
2393 |
+
if( empty( $year )) {
|
2394 |
+
if( $this->getConfig( 'allowEmpty' )) {
|
2395 |
+
$this->completed = array( 'value' => null, 'params' => iCalUtilityFunctions::_setParams( $params ));
|
2396 |
+
return TRUE;
|
2397 |
+
}
|
2398 |
+
else
|
2399 |
+
return FALSE;
|
2400 |
+
}
|
2401 |
+
$this->completed = iCalUtilityFunctions::_setDate2( $year, $month, $day, $hour, $min, $sec, $params );
|
2402 |
+
return TRUE;
|
2403 |
+
}
|
2404 |
+
/*********************************************************************************/
|
2405 |
+
/**
|
2406 |
+
* Property Name: CONTACT
|
2407 |
+
*/
|
2408 |
+
/**
|
2409 |
+
* creates formatted output for calendar component property contact
|
2410 |
+
*
|
2411 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2412 |
+
* @since 2.4.8 - 2008-10-23
|
2413 |
+
* @return string
|
2414 |
+
*/
|
2415 |
+
function createContact() {
|
2416 |
+
if( empty( $this->contact )) return FALSE;
|
2417 |
+
$output = null;
|
2418 |
+
foreach( $this->contact as $contact ) {
|
2419 |
+
if( !empty( $contact['value'] )) {
|
2420 |
+
$attributes = $this->_createParams( $contact['params'], array( 'ALTREP', 'LANGUAGE' ));
|
2421 |
+
$content = $this->_strrep( $contact['value'] );
|
2422 |
+
$output .= $this->_createElement( 'CONTACT', $attributes, $content );
|
2423 |
+
}
|
2424 |
+
elseif( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'CONTACT' );
|
2425 |
+
}
|
2426 |
+
return $output;
|
2427 |
+
}
|
2428 |
+
/**
|
2429 |
+
* set calendar component property contact
|
2430 |
+
*
|
2431 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2432 |
+
* @since 2.5.1 - 2008-11-05
|
2433 |
+
* @param string $value
|
2434 |
+
* @param array $params, optional
|
2435 |
+
* @param integer $index, optional
|
2436 |
+
* @return bool
|
2437 |
+
*/
|
2438 |
+
function setContact( $value, $params=FALSE, $index=FALSE ) {
|
2439 |
+
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
2440 |
+
iCalUtilityFunctions::_setMval( $this->contact, $value, $params, FALSE, $index );
|
2441 |
+
return TRUE;
|
2442 |
+
}
|
2443 |
+
/*********************************************************************************/
|
2444 |
+
/**
|
2445 |
+
* Property Name: CREATED
|
2446 |
+
*/
|
2447 |
+
/**
|
2448 |
+
* creates formatted output for calendar component property created
|
2449 |
+
*
|
2450 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2451 |
+
* @since 2.4.8 - 2008-10-21
|
2452 |
+
* @return string
|
2453 |
+
*/
|
2454 |
+
function createCreated() {
|
2455 |
+
if( empty( $this->created )) return FALSE;
|
2456 |
+
$formatted = iCalUtilityFunctions::_format_date_time( $this->created['value'], 7 );
|
2457 |
+
$attributes = $this->_createParams( $this->created['params'] );
|
2458 |
+
return $this->_createElement( 'CREATED', $attributes, $formatted );
|
2459 |
+
}
|
2460 |
+
/**
|
2461 |
+
* set calendar component property created
|
2462 |
+
*
|
2463 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2464 |
+
* @since 2.4.8 - 2008-10-23
|
2465 |
+
* @param mixed $year optional
|
2466 |
+
* @param mixed $month optional
|
2467 |
+
* @param int $day optional
|
2468 |
+
* @param int $hour optional
|
2469 |
+
* @param int $min optional
|
2470 |
+
* @param int $sec optional
|
2471 |
+
* @param mixed $params optional
|
2472 |
+
* @return bool
|
2473 |
+
*/
|
2474 |
+
function setCreated( $year=FALSE, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) {
|
2475 |
+
if( !isset( $year )) {
|
2476 |
+
$year = date('Ymd\THis', mktime( date( 'H' ), date( 'i' ), date( 's' ) - date( 'Z'), date( 'm' ), date( 'd' ), date( 'Y' )));
|
2477 |
+
}
|
2478 |
+
$this->created = iCalUtilityFunctions::_setDate2( $year, $month, $day, $hour, $min, $sec, $params );
|
2479 |
+
return TRUE;
|
2480 |
+
}
|
2481 |
+
/*********************************************************************************/
|
2482 |
+
/**
|
2483 |
+
* Property Name: DESCRIPTION
|
2484 |
+
*/
|
2485 |
+
/**
|
2486 |
+
* creates formatted output for calendar component property description
|
2487 |
+
*
|
2488 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2489 |
+
* @since 2.4.8 - 2008-10-22
|
2490 |
+
* @return string
|
2491 |
+
*/
|
2492 |
+
function createDescription() {
|
2493 |
+
if( empty( $this->description )) return FALSE;
|
2494 |
+
$output = null;
|
2495 |
+
foreach( $this->description as $description ) {
|
2496 |
+
if( !empty( $description['value'] )) {
|
2497 |
+
$attributes = $this->_createParams( $description['params'], array( 'ALTREP', 'LANGUAGE' ));
|
2498 |
+
$content = $this->_strrep( $description['value'] );
|
2499 |
+
$output .= $this->_createElement( 'DESCRIPTION', $attributes, $content );
|
2500 |
+
}
|
2501 |
+
elseif( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'DESCRIPTION' );
|
2502 |
+
}
|
2503 |
+
return $output;
|
2504 |
+
}
|
2505 |
+
/**
|
2506 |
+
* set calendar component property description
|
2507 |
+
*
|
2508 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2509 |
+
* @since 2.6.24 - 2010-11-06
|
2510 |
+
* @param string $value
|
2511 |
+
* @param array $params, optional
|
2512 |
+
* @param integer $index, optional
|
2513 |
+
* @return bool
|
2514 |
+
*/
|
2515 |
+
function setDescription( $value, $params=FALSE, $index=FALSE ) {
|
2516 |
+
if( empty( $value )) { if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE; }
|
2517 |
+
if( 'vjournal' != $this->objName )
|
2518 |
+
$index = 1;
|
2519 |
+
iCalUtilityFunctions::_setMval( $this->description, $value, $params, FALSE, $index );
|
2520 |
+
return TRUE;
|
2521 |
+
}
|
2522 |
+
/*********************************************************************************/
|
2523 |
+
/**
|
2524 |
+
* Property Name: DTEND
|
2525 |
+
*/
|
2526 |
+
/**
|
2527 |
+
* creates formatted output for calendar component property dtend
|
2528 |
+
*
|
2529 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2530 |
+
* @since 2.9.6 - 2011-05-14
|
2531 |
+
* @return string
|
2532 |
+
*/
|
2533 |
+
function createDtend() {
|
2534 |
+
if( empty( $this->dtend )) return FALSE;
|
2535 |
+
if( !isset( $this->dtend['value']['year'] ) &&
|
2536 |
+
!isset( $this->dtend['value']['month'] ) &&
|
2537 |
+
!isset( $this->dtend['value']['day'] ) &&
|
2538 |
+
!isset( $this->dtend['value']['hour'] ) &&
|
2539 |
+
!isset( $this->dtend['value']['min'] ) &&
|
2540 |
+
!isset( $this->dtend['value']['sec'] ))
|
2541 |
+
if( $this->getConfig( 'allowEmpty' ))
|
2542 |
+
return $this->_createElement( 'DTEND' );
|
2543 |
+
else return FALSE;
|
2544 |
+
$formatted = iCalUtilityFunctions::_format_date_time( $this->dtend['value'] );
|
2545 |
+
if(( FALSE !== ( $tzid = $this->getConfig( 'TZID' ))) &&
|
2546 |
+
( !isset( $this->dtend['params']['VALUE'] ) || ( $this->dtend['params']['VALUE'] != 'DATE' )) &&
|
2547 |
+
!isset( $this->dtend['params']['TZID'] ))
|
2548 |
+
$this->dtend['params']['TZID'] = $tzid;
|
2549 |
+
$attributes = $this->_createParams( $this->dtend['params'] );
|
2550 |
+
return $this->_createElement( 'DTEND', $attributes, $formatted );
|
2551 |
+
}
|
2552 |
+
/**
|
2553 |
+
* set calendar component property dtend
|
2554 |
+
*
|
2555 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2556 |
+
* @since 2.9.6 - 2011-05-14
|
2557 |
+
* @param mixed $year
|
2558 |
+
* @param mixed $month optional
|
2559 |
+
* @param int $day optional
|
2560 |
+
* @param int $hour optional
|
2561 |
+
* @param int $min optional
|
2562 |
+
* @param int $sec optional
|
2563 |
+
* @param string $tz optional
|
2564 |
+
* @param array params optional
|
2565 |
+
* @return bool
|
2566 |
+
*/
|
2567 |
+
function setDtend( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $tz=FALSE, $params=FALSE ) {
|
2568 |
+
if( empty( $year )) {
|
2569 |
+
if( $this->getConfig( 'allowEmpty' )) {
|
2570 |
+
$this->dtend = array( 'value' => null, 'params' => iCalUtilityFunctions::_setParams( $params ));
|
2571 |
+
return TRUE;
|
2572 |
+
}
|
2573 |
+
else
|
2574 |
+
return FALSE;
|
2575 |
+
}
|
2576 |
+
$this->dtend = iCalUtilityFunctions::_setDate( $year, $month, $day, $hour, $min, $sec, $tz, $params, null, null, $this->getConfig( 'TZID' ));
|
2577 |
+
return TRUE;
|
2578 |
+
}
|
2579 |
+
/*********************************************************************************/
|
2580 |
+
/**
|
2581 |
+
* Property Name: DTSTAMP
|
2582 |
+
*/
|
2583 |
+
/**
|
2584 |
+
* creates formatted output for calendar component property dtstamp
|
2585 |
+
*
|
2586 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2587 |
+
* @since 2.4.4 - 2008-03-07
|
2588 |
+
* @return string
|
2589 |
+
*/
|
2590 |
+
function createDtstamp() {
|
2591 |
+
if( !isset( $this->dtstamp['value']['year'] ) &&
|
2592 |
+
!isset( $this->dtstamp['value']['month'] ) &&
|
2593 |
+
!isset( $this->dtstamp['value']['day'] ) &&
|
2594 |
+
!isset( $this->dtstamp['value']['hour'] ) &&
|
2595 |
+
!isset( $this->dtstamp['value']['min'] ) &&
|
2596 |
+
!isset( $this->dtstamp['value']['sec'] ))
|
2597 |
+
$this->_makeDtstamp();
|
2598 |
+
$formatted = iCalUtilityFunctions::_format_date_time( $this->dtstamp['value'], 7 );
|
2599 |
+
$attributes = $this->_createParams( $this->dtstamp['params'] );
|
2600 |
+
return $this->_createElement( 'DTSTAMP', $attributes, $formatted );
|
2601 |
+
}
|
2602 |
+
/**
|
2603 |
+
* computes datestamp for calendar component object instance dtstamp
|
2604 |
+
*
|
2605 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2606 |
+
* @since 2.6.25 - 2010-11-09
|
2607 |
+
* @return void
|
2608 |
+
*/
|
2609 |
+
function _makeDtstamp() {
|
2610 |
+
$d = mktime( date('H'), date('m'), (date('s') - date( 'Z' )), date('m'), date('d'), date('Y'));
|
2611 |
+
$this->dtstamp['value'] = array( 'year' => date( 'Y', $d )
|
2612 |
+
, 'month' => date( 'm', $d )
|
2613 |
+
, 'day' => date( 'd', $d )
|
2614 |
+
, 'hour' => date( 'H', $d )
|
2615 |
+
, 'min' => date( 'i', $d )
|
2616 |
+
, 'sec' => date( 's', $d ));
|
2617 |
+
$this->dtstamp['params'] = null;
|
2618 |
+
}
|
2619 |
+
/**
|
2620 |
+
* set calendar component property dtstamp
|
2621 |
+
*
|
2622 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2623 |
+
* @since 2.4.8 - 2008-10-23
|
2624 |
+
* @param mixed $year
|
2625 |
+
* @param mixed $month optional
|
2626 |
+
* @param int $day optional
|
2627 |
+
* @param int $hour optional
|
2628 |
+
* @param int $min optional
|
2629 |
+
* @param int $sec optional
|
2630 |
+
* @param array $params optional
|
2631 |
+
* @return TRUE
|
2632 |
+
*/
|
2633 |
+
function setDtstamp( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) {
|
2634 |
+
if( empty( $year ))
|
2635 |
+
$this->_makeDtstamp();
|
2636 |
+
else
|
2637 |
+
$this->dtstamp = iCalUtilityFunctions::_setDate2( $year, $month, $day, $hour, $min, $sec, $params );
|
2638 |
+
return TRUE;
|
2639 |
+
}
|
2640 |
+
/*********************************************************************************/
|
2641 |
+
/**
|
2642 |
+
* Property Name: DTSTART
|
2643 |
+
*/
|
2644 |
+
/**
|
2645 |
+
* creates formatted output for calendar component property dtstart
|
2646 |
+
*
|
2647 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2648 |
+
* @since 2.9.6 - 2011-05-15
|
2649 |
+
* @return string
|
2650 |
+
*/
|
2651 |
+
function createDtstart() {
|
2652 |
+
if( empty( $this->dtstart )) return FALSE;
|
2653 |
+
if( !isset( $this->dtstart['value']['year'] ) &&
|
2654 |
+
!isset( $this->dtstart['value']['month'] ) &&
|
2655 |
+
!isset( $this->dtstart['value']['day'] ) &&
|
2656 |
+
!isset( $this->dtstart['value']['hour'] ) &&
|
2657 |
+
!isset( $this->dtstart['value']['min'] ) &&
|
2658 |
+
!isset( $this->dtstart['value']['sec'] )) {
|
2659 |
+
if( $this->getConfig( 'allowEmpty' ))
|
2660 |
+
return $this->_createElement( 'DTSTART' );
|
2661 |
+
else return FALSE;
|
2662 |
+
}
|
2663 |
+
if( in_array( $this->objName, array( 'vtimezone', 'standard', 'daylight' )))
|
2664 |
+
unset( $this->dtstart['value']['tz'], $this->dtstart['params']['TZID'] );
|
2665 |
+
elseif(( FALSE !== ( $tzid = $this->getConfig( 'TZID' ))) &&
|
2666 |
+
( !isset( $this->dtstart['params']['VALUE'] ) || ( $this->dtstart['params']['VALUE'] != 'DATE' )) &&
|
2667 |
+
!isset( $this->dtstart['params']['TZID'] ))
|
2668 |
+
$this->dtstart['params']['TZID'] = $tzid;
|
2669 |
+
$formatted = iCalUtilityFunctions::_format_date_time( $this->dtstart['value'] );
|
2670 |
+
$attributes = $this->_createParams( $this->dtstart['params'] );
|
2671 |
+
return $this->_createElement( 'DTSTART', $attributes, $formatted );
|
2672 |
+
}
|
2673 |
+
/**
|
2674 |
+
* set calendar component property dtstart
|
2675 |
+
*
|
2676 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2677 |
+
* @since 2.6.22 - 2010-09-22
|
2678 |
+
* @param mixed $year
|
2679 |
+
* @param mixed $month optional
|
2680 |
+
* @param int $day optional
|
2681 |
+
* @param int $hour optional
|
2682 |
+
* @param int $min optional
|
2683 |
+
* @param int $sec optional
|
2684 |
+
* @param string $tz optional
|
2685 |
+
* @param array $params optional
|
2686 |
+
* @return bool
|
2687 |
+
*/
|
2688 |
+
function setDtstart( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $tz=FALSE, $params=FALSE ) {
|
2689 |
+
if( empty( $year )) {
|
2690 |
+
if( $this->getConfig( 'allowEmpty' )) {
|
2691 |
+
$this->dtstart = array( 'value' => null, 'params' => iCalUtilityFunctions::_setParams( $params ));
|
2692 |
+
return TRUE;
|
2693 |
+
}
|
2694 |
+
else
|
2695 |
+
return FALSE;
|
2696 |
+
}
|
2697 |
+
$this->dtstart = iCalUtilityFunctions::_setDate( $year, $month, $day, $hour, $min, $sec, $tz, $params, 'dtstart', $this->objName, $this->getConfig( 'TZID' ));
|
2698 |
+
return TRUE;
|
2699 |
+
}
|
2700 |
+
/*********************************************************************************/
|
2701 |
+
/**
|
2702 |
+
* Property Name: DUE
|
2703 |
+
*/
|
2704 |
+
/**
|
2705 |
+
* creates formatted output for calendar component property due
|
2706 |
+
*
|
2707 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2708 |
+
* @since 2.4.8 - 2008-10-22
|
2709 |
+
* @return string
|
2710 |
+
*/
|
2711 |
+
function createDue() {
|
2712 |
+
if( empty( $this->due )) return FALSE;
|
2713 |
+
if( !isset( $this->due['value']['year'] ) &&
|
2714 |
+
!isset( $this->due['value']['month'] ) &&
|
2715 |
+
!isset( $this->due['value']['day'] ) &&
|
2716 |
+
!isset( $this->due['value']['hour'] ) &&
|
2717 |
+
!isset( $this->due['value']['min'] ) &&
|
2718 |
+
!isset( $this->due['value']['sec'] )) {
|
2719 |
+
if( $this->getConfig( 'allowEmpty' ))
|
2720 |
+
return $this->_createElement( 'DUE' );
|
2721 |
+
else
|
2722 |
+
return FALSE;
|
2723 |
+
}
|
2724 |
+
$formatted = iCalUtilityFunctions::_format_date_time( $this->due['value'] );
|
2725 |
+
if(( FALSE !== ( $tzid = $this->getConfig( 'TZID' ))) &&
|
2726 |
+
( !isset( $this->due['params']['VALUE'] ) || ( $this->due['params']['VALUE'] != 'DATE' )) &&
|
2727 |
+
!isset( $this->due['params']['TZID'] ))
|
2728 |
+
$this->due['params']['TZID'] = $tzid;
|
2729 |
+
$attributes = $this->_createParams( $this->due['params'] );
|
2730 |
+
return $this->_createElement( 'DUE', $attributes, $formatted );
|
2731 |
+
}
|
2732 |
+
/**
|
2733 |
+
* set calendar component property due
|
2734 |
+
*
|
2735 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2736 |
+
* @since 2.4.8 - 2008-11-04
|
2737 |
+
* @param mixed $year
|
2738 |
+
* @param mixed $month optional
|
2739 |
+
* @param int $day optional
|
2740 |
+
* @param int $hour optional
|
2741 |
+
* @param int $min optional
|
2742 |
+
* @param int $sec optional
|
2743 |
+
* @param array $params optional
|
2744 |
+
* @return bool
|
2745 |
+
*/
|
2746 |
+
function setDue( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $tz=FALSE, $params=FALSE ) {
|
2747 |
+
if( empty( $year )) {
|
2748 |
+
if( $this->getConfig( 'allowEmpty' )) {
|
2749 |
+
$this->due = array( 'value' => null, 'params' => iCalUtilityFunctions::_setParams( $params ));
|
2750 |
+
return TRUE;
|
2751 |
+
}
|
2752 |
+
else
|
2753 |
+
return FALSE;
|
2754 |
+
}
|
2755 |
+
$this->due = iCalUtilityFunctions::_setDate( $year, $month, $day, $hour, $min, $sec, $tz, $params, null, null, $this->getConfig( 'TZID' ));
|
2756 |
+
return TRUE;
|
2757 |
+
}
|
2758 |
+
/*********************************************************************************/
|
2759 |
+
/**
|
2760 |
+
* Property Name: DURATION
|
2761 |
+
*/
|
2762 |
+
/**
|
2763 |
+
* creates formatted output for calendar component property duration
|
2764 |
+
*
|
2765 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2766 |
+
* @since 2.4.8 - 2008-10-21
|
2767 |
+
* @return string
|
2768 |
+
*/
|
2769 |
+
function createDuration() {
|
2770 |
+
if( empty( $this->duration )) return FALSE;
|
2771 |
+
if( !isset( $this->duration['value']['week'] ) &&
|
2772 |
+
!isset( $this->duration['value']['day'] ) &&
|
2773 |
+
!isset( $this->duration['value']['hour'] ) &&
|
2774 |
+
!isset( $this->duration['value']['min'] ) &&
|
2775 |
+
!isset( $this->duration['value']['sec'] ))
|
2776 |
+
if( $this->getConfig( 'allowEmpty' ))
|
2777 |
+
return $this->_createElement( 'DURATION', array(), null );
|
2778 |
+
else return FALSE;
|
2779 |
+
$attributes = $this->_createParams( $this->duration['params'] );
|
2780 |
+
return $this->_createElement( 'DURATION', $attributes, iCalUtilityFunctions::_format_duration( $this->duration['value'] ));
|
2781 |
+
}
|
2782 |
+
/**
|
2783 |
+
* set calendar component property duration
|
2784 |
+
*
|
2785 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2786 |
+
* @since 2.4.8 - 2008-11-04
|
2787 |
+
* @param mixed $week
|
2788 |
+
* @param mixed $day optional
|
2789 |
+
* @param int $hour optional
|
2790 |
+
* @param int $min optional
|
2791 |
+
* @param int $sec optional
|
2792 |
+
* @param array $params optional
|
2793 |
+
* @return bool
|
2794 |
+
*/
|
2795 |
+
function setDuration( $week, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) {
|
2796 |
+
if( empty( $week )) if( $this->getConfig( 'allowEmpty' )) $week = null; else return FALSE;
|
2797 |
+
if( is_array( $week ) && ( 1 <= count( $week )))
|
2798 |
+
$this->duration = array( 'value' => iCalUtilityFunctions::_duration_array( $week ), 'params' => iCalUtilityFunctions::_setParams( $day ));
|
2799 |
+
elseif( is_string( $week ) && ( 3 <= strlen( trim( $week )))) {
|
2800 |
+
$week = trim( $week );
|
2801 |
+
if( in_array( substr( $week, 0, 1 ), array( '+', '-' )))
|
2802 |
+
$week = substr( $week, 1 );
|
2803 |
+
$this->duration = array( 'value' => iCalUtilityFunctions::_duration_string( $week ), 'params' => iCalUtilityFunctions::_setParams( $day ));
|
2804 |
+
}
|
2805 |
+
elseif( empty( $week ) && empty( $day ) && empty( $hour ) && empty( $min ) && empty( $sec ))
|
2806 |
+
return FALSE;
|
2807 |
+
else
|
2808 |
+
$this->duration = array( 'value' => iCalUtilityFunctions::_duration_array( array( $week, $day, $hour, $min, $sec )), 'params' => iCalUtilityFunctions::_setParams( $params ));
|
2809 |
+
return TRUE;
|
2810 |
+
}
|
2811 |
+
/*********************************************************************************/
|
2812 |
+
/**
|
2813 |
+
* Property Name: EXDATE
|
2814 |
+
*/
|
2815 |
+
/**
|
2816 |
+
* creates formatted output for calendar component property exdate
|
2817 |
+
*
|
2818 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2819 |
+
* @since 2.4.8 - 2008-10-22
|
2820 |
+
* @return string
|
2821 |
+
*/
|
2822 |
+
function createExdate() {
|
2823 |
+
if( empty( $this->exdate )) return FALSE;
|
2824 |
+
$output = null;
|
2825 |
+
foreach( $this->exdate as $ex => $theExdate ) {
|
2826 |
+
if( empty( $theExdate['value'] )) {
|
2827 |
+
if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'EXDATE' );
|
2828 |
+
continue;
|
2829 |
+
}
|
2830 |
+
$content = $attributes = null;
|
2831 |
+
foreach( $theExdate['value'] as $eix => $exdatePart ) {
|
2832 |
+
$parno = count( $exdatePart );
|
2833 |
+
$formatted = iCalUtilityFunctions::_format_date_time( $exdatePart, $parno );
|
2834 |
+
if( isset( $theExdate['params']['TZID'] ))
|
2835 |
+
$formatted = str_replace( 'Z', '', $formatted);
|
2836 |
+
if( 0 < $eix ) {
|
2837 |
+
if( isset( $theExdate['value'][0]['tz'] )) {
|
2838 |
+
if( ctype_digit( substr( $theExdate['value'][0]['tz'], -4 )) ||
|
2839 |
+
( 'Z' == $theExdate['value'][0]['tz'] )) {
|
2840 |
+
if( 'Z' != substr( $formatted, -1 ))
|
2841 |
+
$formatted .= 'Z';
|
2842 |
+
}
|
2843 |
+
else
|
2844 |
+
$formatted = str_replace( 'Z', '', $formatted );
|
2845 |
+
}
|
2846 |
+
else
|
2847 |
+
$formatted = str_replace( 'Z', '', $formatted );
|
2848 |
+
}
|
2849 |
+
$content .= ( 0 < $eix ) ? ','.$formatted : $formatted;
|
2850 |
+
}
|
2851 |
+
$attributes .= $this->_createParams( $theExdate['params'] );
|
2852 |
+
$output .= $this->_createElement( 'EXDATE', $attributes, $content );
|
2853 |
+
}
|
2854 |
+
return $output;
|
2855 |
+
}
|
2856 |
+
/**
|
2857 |
+
* set calendar component property exdate
|
2858 |
+
*
|
2859 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2860 |
+
* @since 2.5.1 - 2008-11-05
|
2861 |
+
* @param array exdates
|
2862 |
+
* @param array $params, optional
|
2863 |
+
* @param integer $index, optional
|
2864 |
+
* @return bool
|
2865 |
+
*/
|
2866 |
+
function setExdate( $exdates, $params=FALSE, $index=FALSE ) {
|
2867 |
+
if( empty( $exdates )) {
|
2868 |
+
if( $this->getConfig( 'allowEmpty' )) {
|
2869 |
+
iCalUtilityFunctions::_setMval( $this->exdate, null, $params, FALSE, $index );
|
2870 |
+
return TRUE;
|
2871 |
+
}
|
2872 |
+
else
|
2873 |
+
return FALSE;
|
2874 |
+
}
|
2875 |
+
$input = array( 'params' => iCalUtilityFunctions::_setParams( $params, array( 'VALUE' => 'DATE-TIME' )));
|
2876 |
+
/* ev. check 1:st date and save ev. timezone **/
|
2877 |
+
iCalUtilityFunctions::_chkdatecfg( reset( $exdates ), $parno, $input['params'] );
|
2878 |
+
iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE-TIME' ); // remove default parameter
|
2879 |
+
foreach( $exdates as $eix => $theExdate ) {
|
2880 |
+
if( iCalUtilityFunctions::_isArrayTimestampDate( $theExdate ))
|
2881 |
+
$exdatea = iCalUtilityFunctions::_timestamp2date( $theExdate, $parno );
|
2882 |
+
elseif( is_array( $theExdate ))
|
2883 |
+
$exdatea = iCalUtilityFunctions::_date_time_array( $theExdate, $parno );
|
2884 |
+
elseif( 8 <= strlen( trim( $theExdate ))) // ex. 2006-08-03 10:12:18
|
2885 |
+
$exdatea = iCalUtilityFunctions::_date_time_string( $theExdate, $parno );
|
2886 |
+
if( 3 == $parno )
|
2887 |
+
unset( $exdatea['hour'], $exdatea['min'], $exdatea['sec'], $exdatea['tz'] );
|
2888 |
+
elseif( isset( $exdatea['tz'] ))
|
2889 |
+
$exdatea['tz'] = (string) $exdatea['tz'];
|
2890 |
+
if( isset( $input['params']['TZID'] ) ||
|
2891 |
+
( isset( $exdatea['tz'] ) && !iCalUtilityFunctions::_isOffset( $exdatea['tz'] )) ||
|
2892 |
+
( isset( $input['value'][0] ) && ( !isset( $input['value'][0]['tz'] ))) ||
|
2893 |
+
( isset( $input['value'][0]['tz'] ) && !iCalUtilityFunctions::_isOffset( $input['value'][0]['tz'] )))
|
2894 |
+
unset( $exdatea['tz'] );
|
2895 |
+
$input['value'][] = $exdatea;
|
2896 |
+
}
|
2897 |
+
if( 0 >= count( $input['value'] ))
|
2898 |
+
return FALSE;
|
2899 |
+
if( 3 == $parno ) {
|
2900 |
+
$input['params']['VALUE'] = 'DATE';
|
2901 |
+
unset( $input['params']['TZID'] );
|
2902 |
+
}
|
2903 |
+
iCalUtilityFunctions::_setMval( $this->exdate, $input['value'], $input['params'], FALSE, $index );
|
2904 |
+
return TRUE;
|
2905 |
+
}
|
2906 |
+
/*********************************************************************************/
|
2907 |
+
/**
|
2908 |
+
* Property Name: EXRULE
|
2909 |
+
*/
|
2910 |
+
/**
|
2911 |
+
* creates formatted output for calendar component property exrule
|
2912 |
+
*
|
2913 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2914 |
+
* @since 2.4.8 - 2008-10-22
|
2915 |
+
* @return string
|
2916 |
+
*/
|
2917 |
+
function createExrule() {
|
2918 |
+
if( empty( $this->exrule )) return FALSE;
|
2919 |
+
return $this->_format_recur( 'EXRULE', $this->exrule );
|
2920 |
+
}
|
2921 |
+
/**
|
2922 |
+
* set calendar component property exdate
|
2923 |
+
*
|
2924 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2925 |
+
* @since 2.5.1 - 2008-11-05
|
2926 |
+
* @param array $exruleset
|
2927 |
+
* @param array $params, optional
|
2928 |
+
* @param integer $index, optional
|
2929 |
+
* @return bool
|
2930 |
+
*/
|
2931 |
+
function setExrule( $exruleset, $params=FALSE, $index=FALSE ) {
|
2932 |
+
if( empty( $exruleset )) if( $this->getConfig( 'allowEmpty' )) $exruleset = null; else return FALSE;
|
2933 |
+
iCalUtilityFunctions::_setMval( $this->exrule, iCalUtilityFunctions::_setRexrule( $exruleset ), $params, FALSE, $index );
|
2934 |
+
return TRUE;
|
2935 |
+
}
|
2936 |
+
/*********************************************************************************/
|
2937 |
+
/**
|
2938 |
+
* Property Name: FREEBUSY
|
2939 |
+
*/
|
2940 |
+
/**
|
2941 |
+
* creates formatted output for calendar component property freebusy
|
2942 |
+
*
|
2943 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2944 |
+
* @since 2.4.8 - 2008-10-22
|
2945 |
+
* @return string
|
2946 |
+
*/
|
2947 |
+
function createFreebusy() {
|
2948 |
+
if( empty( $this->freebusy )) return FALSE;
|
2949 |
+
$output = null;
|
2950 |
+
foreach( $this->freebusy as $freebusyPart ) {
|
2951 |
+
if( empty( $freebusyPart['value'] )) {
|
2952 |
+
if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'FREEBUSY' );
|
2953 |
+
continue;
|
2954 |
+
}
|
2955 |
+
$attributes = $content = null;
|
2956 |
+
if( isset( $freebusyPart['value']['fbtype'] )) {
|
2957 |
+
$attributes .= $this->intAttrDelimiter.'FBTYPE='.$freebusyPart['value']['fbtype'];
|
2958 |
+
unset( $freebusyPart['value']['fbtype'] );
|
2959 |
+
$freebusyPart['value'] = array_values( $freebusyPart['value'] );
|
2960 |
+
}
|
2961 |
+
else
|
2962 |
+
$attributes .= $this->intAttrDelimiter.'FBTYPE=BUSY';
|
2963 |
+
$attributes .= $this->_createParams( $freebusyPart['params'] );
|
2964 |
+
$fno = 1;
|
2965 |
+
$cnt = count( $freebusyPart['value']);
|
2966 |
+
foreach( $freebusyPart['value'] as $periodix => $freebusyPeriod ) {
|
2967 |
+
$formatted = iCalUtilityFunctions::_format_date_time( $freebusyPeriod[0] );
|
2968 |
+
$content .= $formatted;
|
2969 |
+
$content .= '/';
|
2970 |
+
$cnt2 = count( $freebusyPeriod[1]);
|
2971 |
+
if( array_key_exists( 'year', $freebusyPeriod[1] )) // date-time
|
2972 |
+
$cnt2 = 7;
|
2973 |
+
elseif( array_key_exists( 'week', $freebusyPeriod[1] )) // duration
|
2974 |
+
$cnt2 = 5;
|
2975 |
+
if(( 7 == $cnt2 ) && // period= -> date-time
|
2976 |
+
isset( $freebusyPeriod[1]['year'] ) &&
|
2977 |
+
isset( $freebusyPeriod[1]['month'] ) &&
|
2978 |
+
isset( $freebusyPeriod[1]['day'] )) {
|
2979 |
+
$content .= iCalUtilityFunctions::_format_date_time( $freebusyPeriod[1] );
|
2980 |
+
}
|
2981 |
+
else { // period= -> dur-time
|
2982 |
+
$content .= iCalUtilityFunctions::_format_duration( $freebusyPeriod[1] );
|
2983 |
+
}
|
2984 |
+
if( $fno < $cnt )
|
2985 |
+
$content .= ',';
|
2986 |
+
$fno++;
|
2987 |
+
}
|
2988 |
+
$output .= $this->_createElement( 'FREEBUSY', $attributes, $content );
|
2989 |
+
}
|
2990 |
+
return $output;
|
2991 |
+
}
|
2992 |
+
/**
|
2993 |
+
* set calendar component property freebusy
|
2994 |
+
*
|
2995 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
2996 |
+
* @since 2.8.10 - 2011-03-24
|
2997 |
+
* @param string $fbType
|
2998 |
+
* @param array $fbValues
|
2999 |
+
* @param array $params, optional
|
3000 |
+
* @param integer $index, optional
|
3001 |
+
* @return bool
|
3002 |
+
*/
|
3003 |
+
function setFreebusy( $fbType, $fbValues, $params=FALSE, $index=FALSE ) {
|
3004 |
+
if( empty( $fbValues )) {
|
3005 |
+
if( $this->getConfig( 'allowEmpty' )) {
|
3006 |
+
iCalUtilityFunctions::_setMval( $this->freebusy, null, $params, FALSE, $index );
|
3007 |
+
return TRUE;
|
3008 |
+
}
|
3009 |
+
else
|
3010 |
+
return FALSE;
|
3011 |
+
}
|
3012 |
+
$fbType = strtoupper( $fbType );
|
3013 |
+
if(( !in_array( $fbType, array( 'FREE', 'BUSY', 'BUSY-UNAVAILABLE', 'BUSY-TENTATIVE' ))) &&
|
3014 |
+
( 'X-' != substr( $fbType, 0, 2 )))
|
3015 |
+
$fbType = 'BUSY';
|
3016 |
+
$input = array( 'fbtype' => $fbType );
|
3017 |
+
foreach( $fbValues as $fbPeriod ) { // periods => period
|
3018 |
+
if( empty( $fbPeriod ))
|
3019 |
+
continue;
|
3020 |
+
$freebusyPeriod = array();
|
3021 |
+
foreach( $fbPeriod as $fbMember ) { // pairs => singlepart
|
3022 |
+
$freebusyPairMember = array();
|
3023 |
+
if( is_array( $fbMember )) {
|
3024 |
+
if( iCalUtilityFunctions::_isArrayDate( $fbMember )) { // date-time value
|
3025 |
+
$freebusyPairMember = iCalUtilityFunctions::_date_time_array( $fbMember, 7 );
|
3026 |
+
$freebusyPairMember['tz'] = 'Z';
|
3027 |
+
}
|
3028 |
+
elseif( iCalUtilityFunctions::_isArrayTimestampDate( $fbMember )) { // timestamp value
|
3029 |
+
$freebusyPairMember = iCalUtilityFunctions::_timestamp2date( $fbMember['timestamp'], 7 );
|
3030 |
+
$freebusyPairMember['tz'] = 'Z';
|
3031 |
+
}
|
3032 |
+
else { // array format duration
|
3033 |
+
$freebusyPairMember = iCalUtilityFunctions::_duration_array( $fbMember );
|
3034 |
+
}
|
3035 |
+
}
|
3036 |
+
elseif(( 3 <= strlen( trim( $fbMember ))) && // string format duration
|
3037 |
+
( in_array( $fbMember{0}, array( 'P', '+', '-' )))) {
|
3038 |
+
if( 'P' != $fbMember{0} )
|
3039 |
+
$fbmember = substr( $fbMember, 1 );
|
3040 |
+
$freebusyPairMember = iCalUtilityFunctions::_duration_string( $fbMember );
|
3041 |
+
}
|
3042 |
+
elseif( 8 <= strlen( trim( $fbMember ))) { // text date ex. 2006-08-03 10:12:18
|
3043 |
+
$freebusyPairMember = iCalUtilityFunctions::_date_time_string( $fbMember, 7 );
|
3044 |
+
$freebusyPairMember['tz'] = 'Z';
|
3045 |
+
}
|
3046 |
+
$freebusyPeriod[] = $freebusyPairMember;
|
3047 |
+
}
|
3048 |
+
$input[] = $freebusyPeriod;
|
3049 |
+
}
|
3050 |
+
iCalUtilityFunctions::_setMval( $this->freebusy, $input, $params, FALSE, $index );
|
3051 |
+
return TRUE;
|
3052 |
+
}
|
3053 |
+
/*********************************************************************************/
|
3054 |
+
/**
|
3055 |
+
* Property Name: GEO
|
3056 |
+
*/
|
3057 |
+
/**
|
3058 |
+
* creates formatted output for calendar component property geo
|
3059 |
+
*
|
3060 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3061 |
+
* @since 2.4.8 - 2008-10-21
|
3062 |
+
* @return string
|
3063 |
+
*/
|
3064 |
+
function createGeo() {
|
3065 |
+
if( empty( $this->geo )) return FALSE;
|
3066 |
+
if( empty( $this->geo['value'] ))
|
3067 |
+
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'GEO' ) : FALSE;
|
3068 |
+
$attributes = $this->_createParams( $this->geo['params'] );
|
3069 |
+
$content = null;
|
3070 |
+
$content .= number_format( (float) $this->geo['value']['latitude'], 6, '.', '');
|
3071 |
+
$content .= ';';
|
3072 |
+
$content .= number_format( (float) $this->geo['value']['longitude'], 6, '.', '');
|
3073 |
+
return $this->_createElement( 'GEO', $attributes, $content );
|
3074 |
+
}
|
3075 |
+
/**
|
3076 |
+
* set calendar component property geo
|
3077 |
+
*
|
3078 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3079 |
+
* @since 2.4.8 - 2008-11-04
|
3080 |
+
* @param float $latitude
|
3081 |
+
* @param float $longitude
|
3082 |
+
* @param array $params optional
|
3083 |
+
* @return bool
|
3084 |
+
*/
|
3085 |
+
function setGeo( $latitude, $longitude, $params=FALSE ) {
|
3086 |
+
if( !empty( $latitude ) && !empty( $longitude )) {
|
3087 |
+
if( !is_array( $this->geo )) $this->geo = array();
|
3088 |
+
$this->geo['value']['latitude'] = $latitude;
|
3089 |
+
$this->geo['value']['longitude'] = $longitude;
|
3090 |
+
$this->geo['params'] = iCalUtilityFunctions::_setParams( $params );
|
3091 |
+
}
|
3092 |
+
elseif( $this->getConfig( 'allowEmpty' ))
|
3093 |
+
$this->geo = array( 'value' => null, 'params' => iCalUtilityFunctions::_setParams( $params ) );
|
3094 |
+
else
|
3095 |
+
return FALSE;
|
3096 |
+
return TRUE;
|
3097 |
+
}
|
3098 |
+
/*********************************************************************************/
|
3099 |
+
/**
|
3100 |
+
* Property Name: LAST-MODIFIED
|
3101 |
+
*/
|
3102 |
+
/**
|
3103 |
+
* creates formatted output for calendar component property last-modified
|
3104 |
+
*
|
3105 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3106 |
+
* @since 2.4.8 - 2008-10-21
|
3107 |
+
* @return string
|
3108 |
+
*/
|
3109 |
+
function createLastModified() {
|
3110 |
+
if( empty( $this->lastmodified )) return FALSE;
|
3111 |
+
$attributes = $this->_createParams( $this->lastmodified['params'] );
|
3112 |
+
$formatted = iCalUtilityFunctions::_format_date_time( $this->lastmodified['value'], 7 );
|
3113 |
+
return $this->_createElement( 'LAST-MODIFIED', $attributes, $formatted );
|
3114 |
+
}
|
3115 |
+
/**
|
3116 |
+
* set calendar component property completed
|
3117 |
+
*
|
3118 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3119 |
+
* @since 2.4.8 - 2008-10-23
|
3120 |
+
* @param mixed $year optional
|
3121 |
+
* @param mixed $month optional
|
3122 |
+
* @param int $day optional
|
3123 |
+
* @param int $hour optional
|
3124 |
+
* @param int $min optional
|
3125 |
+
* @param int $sec optional
|
3126 |
+
* @param array $params optional
|
3127 |
+
* @return boll
|
3128 |
+
*/
|
3129 |
+
function setLastModified( $year=FALSE, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) {
|
3130 |
+
if( empty( $year ))
|
3131 |
+
$year = date('Ymd\THis', mktime( date( 'H' ), date( 'i' ), date( 's' ) - date( 'Z'), date( 'm' ), date( 'd' ), date( 'Y' )));
|
3132 |
+
$this->lastmodified = iCalUtilityFunctions::_setDate2( $year, $month, $day, $hour, $min, $sec, $params );
|
3133 |
+
return TRUE;
|
3134 |
+
}
|
3135 |
+
/*********************************************************************************/
|
3136 |
+
/**
|
3137 |
+
* Property Name: LOCATION
|
3138 |
+
*/
|
3139 |
+
/**
|
3140 |
+
* creates formatted output for calendar component property location
|
3141 |
+
*
|
3142 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3143 |
+
* @since 2.4.8 - 2008-10-22
|
3144 |
+
* @return string
|
3145 |
+
*/
|
3146 |
+
function createLocation() {
|
3147 |
+
if( empty( $this->location )) return FALSE;
|
3148 |
+
if( empty( $this->location['value'] ))
|
3149 |
+
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'LOCATION' ) : FALSE;
|
3150 |
+
$attributes = $this->_createParams( $this->location['params'], array( 'ALTREP', 'LANGUAGE' ));
|
3151 |
+
$content = $this->_strrep( $this->location['value'] );
|
3152 |
+
return $this->_createElement( 'LOCATION', $attributes, $content );
|
3153 |
+
}
|
3154 |
+
/**
|
3155 |
+
* set calendar component property location
|
3156 |
+
'
|
3157 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3158 |
+
* @since 2.4.8 - 2008-11-04
|
3159 |
+
* @param string $value
|
3160 |
+
* @param array params optional
|
3161 |
+
* @return bool
|
3162 |
+
*/
|
3163 |
+
function setLocation( $value, $params=FALSE ) {
|
3164 |
+
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
3165 |
+
$this->location = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params ));
|
3166 |
+
return TRUE;
|
3167 |
+
}
|
3168 |
+
/*********************************************************************************/
|
3169 |
+
/**
|
3170 |
+
* Property Name: ORGANIZER
|
3171 |
+
*/
|
3172 |
+
/**
|
3173 |
+
* creates formatted output for calendar component property organizer
|
3174 |
+
*
|
3175 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3176 |
+
* @since 2.6.33 - 2010-12-17
|
3177 |
+
* @return string
|
3178 |
+
*/
|
3179 |
+
function createOrganizer() {
|
3180 |
+
if( empty( $this->organizer )) return FALSE;
|
3181 |
+
if( empty( $this->organizer['value'] ))
|
3182 |
+
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'ORGANIZER' ) : FALSE;
|
3183 |
+
$attributes = $this->_createParams( $this->organizer['params']
|
3184 |
+
, array( 'CN', 'DIR', 'SENT-BY', 'LANGUAGE' ));
|
3185 |
+
return $this->_createElement( 'ORGANIZER', $attributes, $this->organizer['value'] );
|
3186 |
+
}
|
3187 |
+
/**
|
3188 |
+
* set calendar component property organizer
|
3189 |
+
*
|
3190 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3191 |
+
* @since 2.6.27 - 2010-11-29
|
3192 |
+
* @param string $value
|
3193 |
+
* @param array params optional
|
3194 |
+
* @return bool
|
3195 |
+
*/
|
3196 |
+
function setOrganizer( $value, $params=FALSE ) {
|
3197 |
+
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
3198 |
+
if( FALSE === ( $pos = strpos( substr( $value, 0, 9 ), ':' )))
|
3199 |
+
$value = 'MAILTO:'.$value;
|
3200 |
+
else
|
3201 |
+
$value = strtolower( substr( $value, 0, $pos )).substr( $value, $pos );
|
3202 |
+
$value = str_replace( 'mailto:', 'MAILTO:', $value );
|
3203 |
+
$this->organizer = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params ));
|
3204 |
+
if( isset( $this->organizer['params']['SENT-BY'] )){
|
3205 |
+
if( 'mailto:' !== strtolower( substr( $this->organizer['params']['SENT-BY'], 0, 7 )))
|
3206 |
+
$this->organizer['params']['SENT-BY'] = 'MAILTO:'.$this->organizer['params']['SENT-BY'];
|
3207 |
+
else
|
3208 |
+
$this->organizer['params']['SENT-BY'] = 'MAILTO:'.substr( $this->organizer['params']['SENT-BY'], 7 );
|
3209 |
+
}
|
3210 |
+
return TRUE;
|
3211 |
+
}
|
3212 |
+
/*********************************************************************************/
|
3213 |
+
/**
|
3214 |
+
* Property Name: PERCENT-COMPLETE
|
3215 |
+
*/
|
3216 |
+
/**
|
3217 |
+
* creates formatted output for calendar component property percent-complete
|
3218 |
+
*
|
3219 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3220 |
+
* @since 2.9.3 - 2011-05-14
|
3221 |
+
* @return string
|
3222 |
+
*/
|
3223 |
+
function createPercentComplete() {
|
3224 |
+
if( !isset($this->percentcomplete) || ( empty( $this->percentcomplete ) && !is_numeric( $this->percentcomplete ))) return FALSE;
|
3225 |
+
if( !isset( $this->percentcomplete['value'] ) || ( empty( $this->percentcomplete['value'] ) && !is_numeric( $this->percentcomplete['value'] )))
|
3226 |
+
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'PERCENT-COMPLETE' ) : FALSE;
|
3227 |
+
$attributes = $this->_createParams( $this->percentcomplete['params'] );
|
3228 |
+
return $this->_createElement( 'PERCENT-COMPLETE', $attributes, $this->percentcomplete['value'] );
|
3229 |
+
}
|
3230 |
+
/**
|
3231 |
+
* set calendar component property percent-complete
|
3232 |
+
*
|
3233 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3234 |
+
* @since 2.9.3 - 2011-05-14
|
3235 |
+
* @param int $value
|
3236 |
+
* @param array $params optional
|
3237 |
+
* @return bool
|
3238 |
+
*/
|
3239 |
+
function setPercentComplete( $value, $params=FALSE ) {
|
3240 |
+
if( empty( $value ) && !is_numeric( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
3241 |
+
$this->percentcomplete = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params ));
|
3242 |
+
return TRUE;
|
3243 |
+
}
|
3244 |
+
/*********************************************************************************/
|
3245 |
+
/**
|
3246 |
+
* Property Name: PRIORITY
|
3247 |
+
*/
|
3248 |
+
/**
|
3249 |
+
* creates formatted output for calendar component property priority
|
3250 |
+
*
|
3251 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3252 |
+
* @since 2.9.3 - 2011-05-14
|
3253 |
+
* @return string
|
3254 |
+
*/
|
3255 |
+
function createPriority() {
|
3256 |
+
if( !isset($this->priority) || ( empty( $this->priority ) && !is_numeric( $this->priority ))) return FALSE;
|
3257 |
+
if( !isset( $this->priority['value'] ) || ( empty( $this->priority['value'] ) && !is_numeric( $this->priority['value'] )))
|
3258 |
+
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'PRIORITY' ) : FALSE;
|
3259 |
+
$attributes = $this->_createParams( $this->priority['params'] );
|
3260 |
+
return $this->_createElement( 'PRIORITY', $attributes, $this->priority['value'] );
|
3261 |
+
}
|
3262 |
+
/**
|
3263 |
+
* set calendar component property priority
|
3264 |
+
*
|
3265 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3266 |
+
* @since 2.9.3 - 2011-05-14
|
3267 |
+
* @param int $value
|
3268 |
+
* @param array $params optional
|
3269 |
+
* @return bool
|
3270 |
+
*/
|
3271 |
+
function setPriority( $value, $params=FALSE ) {
|
3272 |
+
if( empty( $value ) && !is_numeric( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
3273 |
+
$this->priority = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params ));
|
3274 |
+
return TRUE;
|
3275 |
+
}
|
3276 |
+
/*********************************************************************************/
|
3277 |
+
/**
|
3278 |
+
* Property Name: RDATE
|
3279 |
+
*/
|
3280 |
+
/**
|
3281 |
+
* creates formatted output for calendar component property rdate
|
3282 |
+
*
|
3283 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3284 |
+
* @since 2.4.16 - 2008-10-26
|
3285 |
+
* @return string
|
3286 |
+
*/
|
3287 |
+
function createRdate() {
|
3288 |
+
if( empty( $this->rdate )) return FALSE;
|
3289 |
+
$utctime = ( in_array( $this->objName, array( 'vtimezone', 'standard', 'daylight' ))) ? TRUE : FALSE;
|
3290 |
+
$output = null;
|
3291 |
+
if( $utctime )
|
3292 |
+
unset( $this->rdate['params']['TZID'] );
|
3293 |
+
foreach( $this->rdate as $theRdate ) {
|
3294 |
+
if( empty( $theRdate['value'] )) {
|
3295 |
+
if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'RDATE' );
|
3296 |
+
continue;
|
3297 |
+
}
|
3298 |
+
if( $utctime )
|
3299 |
+
unset( $theRdate['params']['TZID'] );
|
3300 |
+
$attributes = $this->_createParams( $theRdate['params'] );
|
3301 |
+
$cnt = count( $theRdate['value'] );
|
3302 |
+
$content = null;
|
3303 |
+
$rno = 1;
|
3304 |
+
foreach( $theRdate['value'] as $rpix => $rdatePart ) {
|
3305 |
+
$contentPart = null;
|
3306 |
+
if( is_array( $rdatePart ) &&
|
3307 |
+
isset( $theRdate['params']['VALUE'] ) && ( 'PERIOD' == $theRdate['params']['VALUE'] )) { // PERIOD
|
3308 |
+
if( $utctime )
|
3309 |
+
unset( $rdatePart[0]['tz'] );
|
3310 |
+
$formatted = iCalUtilityFunctions::_format_date_time( $rdatePart[0]); // PERIOD part 1
|
3311 |
+
if( $utctime || !empty( $theRdate['params']['TZID'] ))
|
3312 |
+
$formatted = str_replace( 'Z', '', $formatted);
|
3313 |
+
if( 0 < $rpix ) {
|
3314 |
+
if( !empty( $rdatePart[0]['tz'] ) && iCalUtilityFunctions::_isOffset( $rdatePart[0]['tz'] )) {
|
3315 |
+
if( 'Z' != substr( $formatted, -1 )) $formatted .= 'Z';
|
3316 |
+
}
|
3317 |
+
else
|
3318 |
+
$formatted = str_replace( 'Z', '', $formatted );
|
3319 |
+
}
|
3320 |
+
$contentPart .= $formatted;
|
3321 |
+
$contentPart .= '/';
|
3322 |
+
$cnt2 = count( $rdatePart[1]);
|
3323 |
+
if( array_key_exists( 'year', $rdatePart[1] )) {
|
3324 |
+
if( array_key_exists( 'hour', $rdatePart[1] ))
|
3325 |
+
$cnt2 = 7; // date-time
|
3326 |
+
else
|
3327 |
+
$cnt2 = 3; // date
|
3328 |
+
}
|
3329 |
+
elseif( array_key_exists( 'week', $rdatePart[1] )) // duration
|
3330 |
+
$cnt2 = 5;
|
3331 |
+
if(( 7 == $cnt2 ) && // period= -> date-time
|
3332 |
+
isset( $rdatePart[1]['year'] ) &&
|
3333 |
+
isset( $rdatePart[1]['month'] ) &&
|
3334 |
+
isset( $rdatePart[1]['day'] )) {
|
3335 |
+
if( $utctime )
|
3336 |
+
unset( $rdatePart[1]['tz'] );
|
3337 |
+
$formatted = iCalUtilityFunctions::_format_date_time( $rdatePart[1] ); // PERIOD part 2
|
3338 |
+
if( $utctime || !empty( $theRdate['params']['TZID'] ))
|
3339 |
+
$formatted = str_replace( 'Z', '', $formatted);
|
3340 |
+
if( !empty( $rdatePart[0]['tz'] ) && iCalUtilityFunctions::_isOffset( $rdatePart[0]['tz'] )) {
|
3341 |
+
if( 'Z' != substr( $formatted, -1 )) $formatted .= 'Z';
|
3342 |
+
}
|
3343 |
+
else
|
3344 |
+
$formatted = str_replace( 'Z', '', $formatted );
|
3345 |
+
$contentPart .= $formatted;
|
3346 |
+
}
|
3347 |
+
else { // period= -> dur-time
|
3348 |
+
$contentPart .= iCalUtilityFunctions::_format_duration( $rdatePart[1] );
|
3349 |
+
}
|
3350 |
+
} // PERIOD end
|
3351 |
+
else { // SINGLE date start
|
3352 |
+
if( $utctime )
|
3353 |
+
unset( $rdatePart['tz'] );
|
3354 |
+
$formatted = iCalUtilityFunctions::_format_date_time( $rdatePart);
|
3355 |
+
if( $utctime || !empty( $theRdate['params']['TZID'] ))
|
3356 |
+
$formatted = str_replace( 'Z', '', $formatted);
|
3357 |
+
if( !$utctime && ( 0 < $rpix )) {
|
3358 |
+
if( !empty( $theRdate['value'][0]['tz'] ) && iCalUtilityFunctions::_isOffset( $theRdate['value'][0]['tz'] )) {
|
3359 |
+
if( 'Z' != substr( $formatted, -1 ))
|
3360 |
+
$formatted .= 'Z';
|
3361 |
+
}
|
3362 |
+
else
|
3363 |
+
$formatted = str_replace( 'Z', '', $formatted );
|
3364 |
+
}
|
3365 |
+
$contentPart .= $formatted;
|
3366 |
+
}
|
3367 |
+
$content .= $contentPart;
|
3368 |
+
if( $rno < $cnt )
|
3369 |
+
$content .= ',';
|
3370 |
+
$rno++;
|
3371 |
+
}
|
3372 |
+
$output .= $this->_createElement( 'RDATE', $attributes, $content );
|
3373 |
+
}
|
3374 |
+
return $output;
|
3375 |
+
}
|
3376 |
+
/**
|
3377 |
+
* set calendar component property rdate
|
3378 |
+
*
|
3379 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3380 |
+
* @since 2.5.1 - 2008-11-07
|
3381 |
+
* @param array $rdates
|
3382 |
+
* @param array $params, optional
|
3383 |
+
* @param integer $index, optional
|
3384 |
+
* @return bool
|
3385 |
+
*/
|
3386 |
+
function setRdate( $rdates, $params=FALSE, $index=FALSE ) {
|
3387 |
+
if( empty( $rdates )) {
|
3388 |
+
if( $this->getConfig( 'allowEmpty' )) {
|
3389 |
+
iCalUtilityFunctions::_setMval( $this->rdate, null, $params, FALSE, $index );
|
3390 |
+
return TRUE;
|
3391 |
+
}
|
3392 |
+
else
|
3393 |
+
return FALSE;
|
3394 |
+
}
|
3395 |
+
$input = array( 'params' => iCalUtilityFunctions::_setParams( $params, array( 'VALUE' => 'DATE-TIME' )));
|
3396 |
+
if( in_array( $this->objName, array( 'vtimezone', 'standard', 'daylight' ))) {
|
3397 |
+
unset( $input['params']['TZID'] );
|
3398 |
+
$input['params']['VALUE'] = 'DATE-TIME';
|
3399 |
+
}
|
3400 |
+
/* check if PERIOD, if not set */
|
3401 |
+
if((!isset( $input['params']['VALUE'] ) || !in_array( $input['params']['VALUE'], array( 'DATE', 'PERIOD' ))) &&
|
3402 |
+
isset( $rdates[0] ) && is_array( $rdates[0] ) && ( 2 == count( $rdates[0] )) &&
|
3403 |
+
isset( $rdates[0][0] ) && isset( $rdates[0][1] ) && !isset( $rdates[0]['timestamp'] ) &&
|
3404 |
+
(( is_array( $rdates[0][0] ) && ( isset( $rdates[0][0]['timestamp'] ) ||
|
3405 |
+
iCalUtilityFunctions::_isArrayDate( $rdates[0][0] ))) ||
|
3406 |
+
( is_string( $rdates[0][0] ) && ( 8 <= strlen( trim( $rdates[0][0] ))))) &&
|
3407 |
+
( is_array( $rdates[0][1] ) || ( is_string( $rdates[0][1] ) && ( 3 <= strlen( trim( $rdates[0][1] ))))))
|
3408 |
+
$input['params']['VALUE'] = 'PERIOD';
|
3409 |
+
/* check 1:st date, upd. $parno (opt) and save ev. timezone **/
|
3410 |
+
$date = reset( $rdates );
|
3411 |
+
if( isset( $input['params']['VALUE'] ) && ( 'PERIOD' == $input['params']['VALUE'] )) // PERIOD
|
3412 |
+
$date = reset( $date );
|
3413 |
+
iCalUtilityFunctions::_chkdatecfg( $date, $parno, $input['params'] );
|
3414 |
+
if( in_array( $this->objName, array( 'vtimezone', 'standard', 'daylight' )))
|
3415 |
+
unset( $input['params']['TZID'] );
|
3416 |
+
iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE-TIME' ); // remove default
|
3417 |
+
foreach( $rdates as $rpix => $theRdate ) {
|
3418 |
+
$inputa = null;
|
3419 |
+
if( is_array( $theRdate )) {
|
3420 |
+
if( isset( $input['params']['VALUE'] ) && ( 'PERIOD' == $input['params']['VALUE'] )) { // PERIOD
|
3421 |
+
foreach( $theRdate as $rix => $rPeriod ) {
|
3422 |
+
if( is_array( $rPeriod )) {
|
3423 |
+
if( iCalUtilityFunctions::_isArrayTimestampDate( $rPeriod )) // timestamp
|
3424 |
+
$inputab = ( isset( $rPeriod['tz'] )) ? iCalUtilityFunctions::_timestamp2date( $rPeriod, $parno ) : iCalUtilityFunctions::_timestamp2date( $rPeriod, 6 );
|
3425 |
+
elseif( iCalUtilityFunctions::_isArrayDate( $rPeriod ))
|
3426 |
+
$inputab = ( 3 < count ( $rPeriod )) ? iCalUtilityFunctions::_date_time_array( $rPeriod, $parno ) : iCalUtilityFunctions::_date_time_array( $rPeriod, 6 );
|
3427 |
+
elseif (( 1 == count( $rPeriod )) && ( 8 <= strlen( reset( $rPeriod )))) // text-date
|
3428 |
+
$inputab = iCalUtilityFunctions::_date_time_string( reset( $rPeriod ), $parno );
|
3429 |
+
else // array format duration
|
3430 |
+
$inputab = iCalUtilityFunctions::_duration_array( $rPeriod );
|
3431 |
+
}
|
3432 |
+
elseif(( 3 <= strlen( trim( $rPeriod ))) && // string format duration
|
3433 |
+
( in_array( $rPeriod[0], array( 'P', '+', '-' )))) {
|
3434 |
+
if( 'P' != $rPeriod[0] )
|
3435 |
+
$rPeriod = substr( $rPeriod, 1 );
|
3436 |
+
$inputab = iCalUtilityFunctions::_duration_string( $rPeriod );
|
3437 |
+
}
|
3438 |
+
elseif( 8 <= strlen( trim( $rPeriod ))) // text date ex. 2006-08-03 10:12:18
|
3439 |
+
$inputab = iCalUtilityFunctions::_date_time_string( $rPeriod, $parno );
|
3440 |
+
if( isset( $input['params']['TZID'] ) ||
|
3441 |
+
( isset( $inputab['tz'] ) && !iCalUtilityFunctions::_isOffset( $inputab['tz'] )) ||
|
3442 |
+
( isset( $inputa[0] ) && ( !isset( $inputa[0]['tz'] ))) ||
|
3443 |
+
( isset( $inputa[0]['tz'] ) && !iCalUtilityFunctions::_isOffset( $inputa[0]['tz'] )))
|
3444 |
+
unset( $inputab['tz'] );
|
3445 |
+
$inputa[] = $inputab;
|
3446 |
+
}
|
3447 |
+
} // PERIOD end
|
3448 |
+
elseif ( iCalUtilityFunctions::_isArrayTimestampDate( $theRdate )) // timestamp
|
3449 |
+
$inputa = iCalUtilityFunctions::_timestamp2date( $theRdate, $parno );
|
3450 |
+
else // date[-time]
|
3451 |
+
$inputa = iCalUtilityFunctions::_date_time_array( $theRdate, $parno );
|
3452 |
+
}
|
3453 |
+
elseif( 8 <= strlen( trim( $theRdate ))) // text date ex. 2006-08-03 10:12:18
|
3454 |
+
$inputa = iCalUtilityFunctions::_date_time_string( $theRdate, $parno );
|
3455 |
+
if( !isset( $input['params']['VALUE'] ) || ( 'PERIOD' != $input['params']['VALUE'] )) { // no PERIOD
|
3456 |
+
if( 3 == $parno )
|
3457 |
+
unset( $inputa['hour'], $inputa['min'], $inputa['sec'], $inputa['tz'] );
|
3458 |
+
elseif( isset( $inputa['tz'] ))
|
3459 |
+
$inputa['tz'] = (string) $inputa['tz'];
|
3460 |
+
if( isset( $input['params']['TZID'] ) ||
|
3461 |
+
( isset( $inputa['tz'] ) && !iCalUtilityFunctions::_isOffset( $inputa['tz'] )) ||
|
3462 |
+
( isset( $input['value'][0] ) && ( !isset( $input['value'][0]['tz'] ))) ||
|
3463 |
+
( isset( $input['value'][0]['tz'] ) && !iCalUtilityFunctions::_isOffset( $input['value'][0]['tz'] )))
|
3464 |
+
unset( $inputa['tz'] );
|
3465 |
+
}
|
3466 |
+
$input['value'][] = $inputa;
|
3467 |
+
}
|
3468 |
+
if( 3 == $parno ) {
|
3469 |
+
$input['params']['VALUE'] = 'DATE';
|
3470 |
+
unset( $input['params']['TZID'] );
|
3471 |
+
}
|
3472 |
+
iCalUtilityFunctions::_setMval( $this->rdate, $input['value'], $input['params'], FALSE, $index );
|
3473 |
+
return TRUE;
|
3474 |
+
}
|
3475 |
+
/*********************************************************************************/
|
3476 |
+
/**
|
3477 |
+
* Property Name: RECURRENCE-ID
|
3478 |
+
*/
|
3479 |
+
/**
|
3480 |
+
* creates formatted output for calendar component property recurrence-id
|
3481 |
+
*
|
3482 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3483 |
+
* @since 2.9.6 - 2011-05-15
|
3484 |
+
* @return string
|
3485 |
+
*/
|
3486 |
+
function createRecurrenceid() {
|
3487 |
+
if( empty( $this->recurrenceid )) return FALSE;
|
3488 |
+
if( empty( $this->recurrenceid['value'] ))
|
3489 |
+
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'RECURRENCE-ID' ) : FALSE;
|
3490 |
+
$formatted = iCalUtilityFunctions::_format_date_time( $this->recurrenceid['value'] );
|
3491 |
+
if(( FALSE !== ( $tzid = $this->getConfig( 'TZID' ))) &&
|
3492 |
+
( !isset( $this->recurrenceid['params']['VALUE'] ) || ( $this->recurrenceid['params']['VALUE'] != 'DATE' )) &&
|
3493 |
+
!isset( $this->recurrenceid['params']['TZID'] ))
|
3494 |
+
$this->recurrenceid['params']['TZID'] = $tzid;
|
3495 |
+
$attributes = $this->_createParams( $this->recurrenceid['params'] );
|
3496 |
+
return $this->_createElement( 'RECURRENCE-ID', $attributes, $formatted );
|
3497 |
+
}
|
3498 |
+
/**
|
3499 |
+
* set calendar component property recurrence-id
|
3500 |
+
*
|
3501 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3502 |
+
* @since 2.9.6 - 2011-05-15
|
3503 |
+
* @param mixed $year
|
3504 |
+
* @param mixed $month optional
|
3505 |
+
* @param int $day optional
|
3506 |
+
* @param int $hour optional
|
3507 |
+
* @param int $min optional
|
3508 |
+
* @param int $sec optional
|
3509 |
+
* @param array $params optional
|
3510 |
+
* @return bool
|
3511 |
+
*/
|
3512 |
+
function setRecurrenceid( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $tz=FALSE, $params=FALSE ) {
|
3513 |
+
if( empty( $year )) {
|
3514 |
+
if( $this->getConfig( 'allowEmpty' )) {
|
3515 |
+
$this->recurrenceid = array( 'value' => null, 'params' => null );
|
3516 |
+
return TRUE;
|
3517 |
+
}
|
3518 |
+
else
|
3519 |
+
return FALSE;
|
3520 |
+
}
|
3521 |
+
$this->recurrenceid = iCalUtilityFunctions::_setDate( $year, $month, $day, $hour, $min, $sec, $tz, $params, null, null, $this->getConfig( 'TZID' ));
|
3522 |
+
return TRUE;
|
3523 |
+
}
|
3524 |
+
/*********************************************************************************/
|
3525 |
+
/**
|
3526 |
+
* Property Name: RELATED-TO
|
3527 |
+
*/
|
3528 |
+
/**
|
3529 |
+
* creates formatted output for calendar component property related-to
|
3530 |
+
*
|
3531 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3532 |
+
* @since 2.4.8 - 2008-10-23
|
3533 |
+
* @return string
|
3534 |
+
*/
|
3535 |
+
function createRelatedTo() {
|
3536 |
+
if( empty( $this->relatedto )) return FALSE;
|
3537 |
+
$output = null;
|
3538 |
+
foreach( $this->relatedto as $relation ) {
|
3539 |
+
if( empty( $relation['value'] )) {
|
3540 |
+
if( $this->getConfig( 'allowEmpty' )) $output.= $this->_createElement( 'RELATED-TO', $this->_createParams( $relation['params'] ));
|
3541 |
+
continue;
|
3542 |
+
}
|
3543 |
+
$attributes = $this->_createParams( $relation['params'] );
|
3544 |
+
$content = ( 'xcal' != $this->format ) ? '<' : '';
|
3545 |
+
$content .= $this->_strrep( $relation['value'] );
|
3546 |
+
$content .= ( 'xcal' != $this->format ) ? '>' : '';
|
3547 |
+
$output .= $this->_createElement( 'RELATED-TO', $attributes, $content );
|
3548 |
+
}
|
3549 |
+
return $output;
|
3550 |
+
}
|
3551 |
+
/**
|
3552 |
+
* set calendar component property related-to
|
3553 |
+
*
|
3554 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3555 |
+
* @since 2.5.1 - 2008-11-07
|
3556 |
+
* @param float $relid
|
3557 |
+
* @param array $params, optional
|
3558 |
+
* @param index $index, optional
|
3559 |
+
* @return bool
|
3560 |
+
*/
|
3561 |
+
function setRelatedTo( $value, $params=FALSE, $index=FALSE ) {
|
3562 |
+
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
3563 |
+
if(( '<' == substr( $value, 0, 1 )) && ( '>' == substr( $value, -1 )))
|
3564 |
+
$value = substr( $value, 1, ( strlen( $value ) - 2 ));
|
3565 |
+
iCalUtilityFunctions::_existRem( $params, 'RELTYPE', 'PARENT', TRUE ); // remove default
|
3566 |
+
iCalUtilityFunctions::_setMval( $this->relatedto, $value, $params, FALSE, $index );
|
3567 |
+
return TRUE;
|
3568 |
+
}
|
3569 |
+
/*********************************************************************************/
|
3570 |
+
/**
|
3571 |
+
* Property Name: REPEAT
|
3572 |
+
*/
|
3573 |
+
/**
|
3574 |
+
* creates formatted output for calendar component property repeat
|
3575 |
+
*
|
3576 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3577 |
+
* @since 2.9.3 - 2011-05-14
|
3578 |
+
* @return string
|
3579 |
+
*/
|
3580 |
+
function createRepeat() {
|
3581 |
+
if( !isset( $this->repeat ) || ( empty( $this->repeat ) && !is_numeric( $this->repeat ))) return FALSE;
|
3582 |
+
if( !isset( $this->repeat['value']) || ( empty( $this->repeat['value'] ) && !is_numeric( $this->repeat['value'] )))
|
3583 |
+
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'REPEAT' ) : FALSE;
|
3584 |
+
$attributes = $this->_createParams( $this->repeat['params'] );
|
3585 |
+
return $this->_createElement( 'REPEAT', $attributes, $this->repeat['value'] );
|
3586 |
+
}
|
3587 |
+
/**
|
3588 |
+
* set calendar component property transp
|
3589 |
+
*
|
3590 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3591 |
+
* @since 2.9.3 - 2011-05-14
|
3592 |
+
* @param string $value
|
3593 |
+
* @param array $params optional
|
3594 |
+
* @return void
|
3595 |
+
*/
|
3596 |
+
function setRepeat( $value, $params=FALSE ) {
|
3597 |
+
if( empty( $value ) && !is_numeric( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
3598 |
+
$this->repeat = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params ));
|
3599 |
+
return TRUE;
|
3600 |
+
}
|
3601 |
+
/*********************************************************************************/
|
3602 |
+
/**
|
3603 |
+
* Property Name: REQUEST-STATUS
|
3604 |
+
*/
|
3605 |
+
/**
|
3606 |
+
* creates formatted output for calendar component property request-status
|
3607 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3608 |
+
* @since 2.4.8 - 2008-10-23
|
3609 |
+
* @return string
|
3610 |
+
*/
|
3611 |
+
function createRequestStatus() {
|
3612 |
+
if( empty( $this->requeststatus )) return FALSE;
|
3613 |
+
$output = null;
|
3614 |
+
foreach( $this->requeststatus as $rstat ) {
|
3615 |
+
if( empty( $rstat['value']['statcode'] )) {
|
3616 |
+
if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'REQUEST-STATUS' );
|
3617 |
+
continue;
|
3618 |
+
}
|
3619 |
+
$attributes = $this->_createParams( $rstat['params'], array( 'LANGUAGE' ));
|
3620 |
+
$content = number_format( (float) $rstat['value']['statcode'], 2, '.', '');
|
3621 |
+
$content .= ';'.$this->_strrep( $rstat['value']['text'] );
|
3622 |
+
if( isset( $rstat['value']['extdata'] ))
|
3623 |
+
$content .= ';'.$this->_strrep( $rstat['value']['extdata'] );
|
3624 |
+
$output .= $this->_createElement( 'REQUEST-STATUS', $attributes, $content );
|
3625 |
+
}
|
3626 |
+
return $output;
|
3627 |
+
}
|
3628 |
+
/**
|
3629 |
+
* set calendar component property request-status
|
3630 |
+
*
|
3631 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3632 |
+
* @since 2.5.1 - 2008-11-05
|
3633 |
+
* @param float $statcode
|
3634 |
+
* @param string $text
|
3635 |
+
* @param string $extdata, optional
|
3636 |
+
* @param array $params, optional
|
3637 |
+
* @param integer $index, optional
|
3638 |
+
* @return bool
|
3639 |
+
*/
|
3640 |
+
function setRequestStatus( $statcode, $text, $extdata=FALSE, $params=FALSE, $index=FALSE ) {
|
3641 |
+
if( empty( $statcode ) || empty( $text )) if( $this->getConfig( 'allowEmpty' )) $statcode = $text = null; else return FALSE;
|
3642 |
+
$input = array( 'statcode' => $statcode, 'text' => $text );
|
3643 |
+
if( $extdata )
|
3644 |
+
$input['extdata'] = $extdata;
|
3645 |
+
iCalUtilityFunctions::_setMval( $this->requeststatus, $input, $params, FALSE, $index );
|
3646 |
+
return TRUE;
|
3647 |
+
}
|
3648 |
+
/*********************************************************************************/
|
3649 |
+
/**
|
3650 |
+
* Property Name: RESOURCES
|
3651 |
+
*/
|
3652 |
+
/**
|
3653 |
+
* creates formatted output for calendar component property resources
|
3654 |
+
*
|
3655 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3656 |
+
* @since 2.4.8 - 2008-10-23
|
3657 |
+
* @return string
|
3658 |
+
*/
|
3659 |
+
function createResources() {
|
3660 |
+
if( empty( $this->resources )) return FALSE;
|
3661 |
+
$output = null;
|
3662 |
+
foreach( $this->resources as $resource ) {
|
3663 |
+
if( empty( $resource['value'] )) {
|
3664 |
+
if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'RESOURCES' );
|
3665 |
+
continue;
|
3666 |
+
}
|
3667 |
+
$attributes = $this->_createParams( $resource['params'], array( 'ALTREP', 'LANGUAGE' ));
|
3668 |
+
if( is_array( $resource['value'] )) {
|
3669 |
+
foreach( $resource['value'] as $rix => $resourcePart )
|
3670 |
+
$resource['value'][$rix] = $this->_strrep( $resourcePart );
|
3671 |
+
$content = implode( ',', $resource['value'] );
|
3672 |
+
}
|
3673 |
+
else
|
3674 |
+
$content = $this->_strrep( $resource['value'] );
|
3675 |
+
$output .= $this->_createElement( 'RESOURCES', $attributes, $content );
|
3676 |
+
}
|
3677 |
+
return $output;
|
3678 |
+
}
|
3679 |
+
/**
|
3680 |
+
* set calendar component property recources
|
3681 |
+
*
|
3682 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3683 |
+
* @since 2.5.1 - 2008-11-05
|
3684 |
+
* @param mixed $value
|
3685 |
+
* @param array $params, optional
|
3686 |
+
* @param integer $index, optional
|
3687 |
+
* @return bool
|
3688 |
+
*/
|
3689 |
+
function setResources( $value, $params=FALSE, $index=FALSE ) {
|
3690 |
+
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
3691 |
+
iCalUtilityFunctions::_setMval( $this->resources, $value, $params, FALSE, $index );
|
3692 |
+
return TRUE;
|
3693 |
+
}
|
3694 |
+
/*********************************************************************************/
|
3695 |
+
/**
|
3696 |
+
* Property Name: RRULE
|
3697 |
+
*/
|
3698 |
+
/**
|
3699 |
+
* creates formatted output for calendar component property rrule
|
3700 |
+
*
|
3701 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3702 |
+
* @since 2.4.8 - 2008-10-21
|
3703 |
+
* @return string
|
3704 |
+
*/
|
3705 |
+
function createRrule() {
|
3706 |
+
if( empty( $this->rrule )) return FALSE;
|
3707 |
+
return $this->_format_recur( 'RRULE', $this->rrule );
|
3708 |
+
}
|
3709 |
+
/**
|
3710 |
+
* set calendar component property rrule
|
3711 |
+
*
|
3712 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3713 |
+
* @since 2.5.1 - 2008-11-05
|
3714 |
+
* @param array $rruleset
|
3715 |
+
* @param array $params, optional
|
3716 |
+
* @param integer $index, optional
|
3717 |
+
* @return void
|
3718 |
+
*/
|
3719 |
+
function setRrule( $rruleset, $params=FALSE, $index=FALSE ) {
|
3720 |
+
if( empty( $rruleset )) if( $this->getConfig( 'allowEmpty' )) $rruleset = null; else return FALSE;
|
3721 |
+
iCalUtilityFunctions::_setMval( $this->rrule, iCalUtilityFunctions::_setRexrule( $rruleset ), $params, FALSE, $index );
|
3722 |
+
return TRUE;
|
3723 |
+
}
|
3724 |
+
/*********************************************************************************/
|
3725 |
+
/**
|
3726 |
+
* Property Name: SEQUENCE
|
3727 |
+
*/
|
3728 |
+
/**
|
3729 |
+
* creates formatted output for calendar component property sequence
|
3730 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3731 |
+
* @since 2.9.3 - 2011-05-14
|
3732 |
+
* @return string
|
3733 |
+
*/
|
3734 |
+
function createSequence() {
|
3735 |
+
if( !isset( $this->sequence ) || ( empty( $this->sequence ) && !is_numeric( $this->sequence ))) return FALSE;
|
3736 |
+
if(( !isset($this->sequence['value'] ) || ( empty( $this->sequence['value'] ) && !is_numeric( $this->sequence['value'] ))) &&
|
3737 |
+
( '0' != $this->sequence['value'] ))
|
3738 |
+
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'SEQUENCE' ) : FALSE;
|
3739 |
+
$attributes = $this->_createParams( $this->sequence['params'] );
|
3740 |
+
return $this->_createElement( 'SEQUENCE', $attributes, $this->sequence['value'] );
|
3741 |
+
}
|
3742 |
+
/**
|
3743 |
+
* set calendar component property sequence
|
3744 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3745 |
+
* @since 2.9.3 - 2011-05-14
|
3746 |
+
* @param int $value optional
|
3747 |
+
* @param array $params optional
|
3748 |
+
* @return bool
|
3749 |
+
*/
|
3750 |
+
function setSequence( $value=FALSE, $params=FALSE ) {
|
3751 |
+
if(( empty( $value ) && !is_numeric( $value )) && ( '0' != $value ))
|
3752 |
+
$value = ( isset( $this->sequence['value'] ) && ( 0 < $this->sequence['value'] )) ? $this->sequence['value'] + 1 : 1;
|
3753 |
+
$this->sequence = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params ));
|
3754 |
+
return TRUE;
|
3755 |
+
}
|
3756 |
+
/*********************************************************************************/
|
3757 |
+
/**
|
3758 |
+
* Property Name: STATUS
|
3759 |
+
*/
|
3760 |
+
/**
|
3761 |
+
* creates formatted output for calendar component property status
|
3762 |
+
*
|
3763 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3764 |
+
* @since 2.4.8 - 2008-10-21
|
3765 |
+
* @return string
|
3766 |
+
*/
|
3767 |
+
function createStatus() {
|
3768 |
+
if( empty( $this->status )) return FALSE;
|
3769 |
+
if( empty( $this->status['value'] ))
|
3770 |
+
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'STATUS' ) : FALSE;
|
3771 |
+
$attributes = $this->_createParams( $this->status['params'] );
|
3772 |
+
return $this->_createElement( 'STATUS', $attributes, $this->status['value'] );
|
3773 |
+
}
|
3774 |
+
/**
|
3775 |
+
* set calendar component property status
|
3776 |
+
*
|
3777 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3778 |
+
* @since 2.4.8 - 2008-11-04
|
3779 |
+
* @param string $value
|
3780 |
+
* @param array $params optional
|
3781 |
+
* @return bool
|
3782 |
+
*/
|
3783 |
+
function setStatus( $value, $params=FALSE ) {
|
3784 |
+
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
3785 |
+
$this->status = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params ));
|
3786 |
+
return TRUE;
|
3787 |
+
}
|
3788 |
+
/*********************************************************************************/
|
3789 |
+
/**
|
3790 |
+
* Property Name: SUMMARY
|
3791 |
+
*/
|
3792 |
+
/**
|
3793 |
+
* creates formatted output for calendar component property summary
|
3794 |
+
*
|
3795 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3796 |
+
* @since 2.4.8 - 2008-10-21
|
3797 |
+
* @return string
|
3798 |
+
*/
|
3799 |
+
function createSummary() {
|
3800 |
+
if( empty( $this->summary )) return FALSE;
|
3801 |
+
if( empty( $this->summary['value'] ))
|
3802 |
+
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'SUMMARY' ) : FALSE;
|
3803 |
+
$attributes = $this->_createParams( $this->summary['params'], array( 'ALTREP', 'LANGUAGE' ));
|
3804 |
+
$content = $this->_strrep( $this->summary['value'] );
|
3805 |
+
return $this->_createElement( 'SUMMARY', $attributes, $content );
|
3806 |
+
}
|
3807 |
+
/**
|
3808 |
+
* set calendar component property summary
|
3809 |
+
*
|
3810 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3811 |
+
* @since 2.4.8 - 2008-11-04
|
3812 |
+
* @param string $value
|
3813 |
+
* @param string $params optional
|
3814 |
+
* @return bool
|
3815 |
+
*/
|
3816 |
+
function setSummary( $value, $params=FALSE ) {
|
3817 |
+
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
3818 |
+
$this->summary = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params ));
|
3819 |
+
return TRUE;
|
3820 |
+
}
|
3821 |
+
/*********************************************************************************/
|
3822 |
+
/**
|
3823 |
+
* Property Name: TRANSP
|
3824 |
+
*/
|
3825 |
+
/**
|
3826 |
+
* creates formatted output for calendar component property transp
|
3827 |
+
*
|
3828 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3829 |
+
* @since 2.4.8 - 2008-10-21
|
3830 |
+
* @return string
|
3831 |
+
*/
|
3832 |
+
function createTransp() {
|
3833 |
+
if( empty( $this->transp )) return FALSE;
|
3834 |
+
if( empty( $this->transp['value'] ))
|
3835 |
+
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'TRANSP' ) : FALSE;
|
3836 |
+
$attributes = $this->_createParams( $this->transp['params'] );
|
3837 |
+
return $this->_createElement( 'TRANSP', $attributes, $this->transp['value'] );
|
3838 |
+
}
|
3839 |
+
/**
|
3840 |
+
* set calendar component property transp
|
3841 |
+
*
|
3842 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3843 |
+
* @since 2.4.8 - 2008-11-04
|
3844 |
+
* @param string $value
|
3845 |
+
* @param string $params optional
|
3846 |
+
* @return bool
|
3847 |
+
*/
|
3848 |
+
function setTransp( $value, $params=FALSE ) {
|
3849 |
+
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
3850 |
+
$this->transp = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params ));
|
3851 |
+
return TRUE;
|
3852 |
+
}
|
3853 |
+
/*********************************************************************************/
|
3854 |
+
/**
|
3855 |
+
* Property Name: TRIGGER
|
3856 |
+
*/
|
3857 |
+
/**
|
3858 |
+
* creates formatted output for calendar component property trigger
|
3859 |
+
*
|
3860 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3861 |
+
* @since 2.4.16 - 2008-10-21
|
3862 |
+
* @return string
|
3863 |
+
*/
|
3864 |
+
function createTrigger() {
|
3865 |
+
if( empty( $this->trigger )) return FALSE;
|
3866 |
+
if( empty( $this->trigger['value'] ))
|
3867 |
+
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'TRIGGER' ) : FALSE;
|
3868 |
+
$content = $attributes = null;
|
3869 |
+
if( isset( $this->trigger['value']['year'] ) &&
|
3870 |
+
isset( $this->trigger['value']['month'] ) &&
|
3871 |
+
isset( $this->trigger['value']['day'] ))
|
3872 |
+
$content .= iCalUtilityFunctions::_format_date_time( $this->trigger['value'] );
|
3873 |
+
else {
|
3874 |
+
if( TRUE !== $this->trigger['value']['relatedStart'] )
|
3875 |
+
$attributes .= $this->intAttrDelimiter.'RELATED=END';
|
3876 |
+
if( $this->trigger['value']['before'] )
|
3877 |
+
$content .= '-';
|
3878 |
+
$content .= iCalUtilityFunctions::_format_duration( $this->trigger['value'] );
|
3879 |
+
}
|
3880 |
+
$attributes .= $this->_createParams( $this->trigger['params'] );
|
3881 |
+
return $this->_createElement( 'TRIGGER', $attributes, $content );
|
3882 |
+
}
|
3883 |
+
/**
|
3884 |
+
* set calendar component property trigger
|
3885 |
+
*
|
3886 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
3887 |
+
* @since 2.9.9 - 2011-06-17
|
3888 |
+
* @param mixed $year
|
3889 |
+
* @param mixed $month optional
|
3890 |
+
* @param int $day optional
|
3891 |
+
* @param int $week optional
|
3892 |
+
* @param int $hour optional
|
3893 |
+
* @param int $min optional
|
3894 |
+
* @param int $sec optional
|
3895 |
+
* @param bool $relatedStart optional
|
3896 |
+
* @param bool $before optional
|
3897 |
+
* @param array $params optional
|
3898 |
+
* @return bool
|
3899 |
+
*/
|
3900 |
+
function setTrigger( $year, $month=null, $day=null, $week=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $relatedStart=TRUE, $before=TRUE, $params=FALSE ) {
|
3901 |
+
if( empty( $year ) && empty( $month ) && empty( $day ) && empty( $week ) && empty( $hour ) && empty( $min ) && empty( $sec ))
|
3902 |
+
if( $this->getConfig( 'allowEmpty' )) {
|
3903 |
+
$this->trigger = array( 'value' => null, 'params' => iCalUtilityFunctions::_setParams( $params ) );
|
3904 |
+
return TRUE;
|
3905 |
+
}
|
3906 |
+
else
|
3907 |
+
return FALSE;
|
3908 |
+
if( iCalUtilityFunctions::_isArrayTimestampDate( $year )) { // timestamp
|
3909 |
+
$params = iCalUtilityFunctions::_setParams( $month );
|
3910 |
+
$date = iCalUtilityFunctions::_timestamp2date( $year, 7 );
|
3911 |
+
foreach( $date as $k => $v )
|
3912 |
+
$$k = $v;
|
3913 |
+
}
|
3914 |
+
elseif( is_array( $year ) && ( is_array( $month ) || empty( $month ))) {
|
3915 |
+
$params = iCalUtilityFunctions::_setParams( $month );
|
3916 |
+
if(!(array_key_exists( 'year', $year ) && // exclude date-time
|
3917 |
+
array_key_exists( 'month', $year ) &&
|
3918 |
+
array_key_exists( 'day', $year ))) { // when this must be a duration
|
3919 |
+
if( isset( $params['RELATED'] ) && ( 'END' == strtoupper( $params['RELATED'] )))
|
3920 |
+
$relatedStart = FALSE;
|
3921 |
+
else
|
3922 |
+
$relatedStart = ( array_key_exists( 'relatedStart', $year ) && ( TRUE !== $year['relatedStart'] )) ? FALSE : TRUE;
|
3923 |
+
$before = ( array_key_exists( 'before', $year ) && ( TRUE !== $year['before'] )) ? FALSE : TRUE;
|
3924 |
+
}
|
3925 |
+
$SSYY = ( array_key_exists( 'year', $year )) ? $year['year'] : null;
|
3926 |
+
$month = ( array_key_exists( 'month', $year )) ? $year['month'] : null;
|
3927 |
+
$day = ( array_key_exists( 'day', $year )) ? $year['day'] : null;
|
3928 |
+
$week = ( array_key_exists( 'week', $year )) ? $year['week'] : null;
|
3929 |
+
$hour = ( array_key_exists( 'hour', $year )) ? $year['hour'] : 0; //null;
|
3930 |
+
$min = ( array_key_exists( 'min', $year )) ? $year['min'] : 0; //null;
|
3931 |
+
$sec = ( array_key_exists( 'sec', $year )) ? $year['sec'] : 0; //null;
|
3932 |
+
$year = $SSYY;
|
3933 |
+
}
|
3934 |
+
elseif(is_string( $year ) && ( is_array( $month ) || empty( $month ))) { // duration or date in a string
|
3935 |
+
$params = iCalUtilityFunctions::_setParams( $month );
|
3936 |
+
if( in_array( $year[0], array( 'P', '+', '-' ))) { // duration
|
3937 |
+
$relatedStart = ( isset( $params['RELATED'] ) && ( 'END' == strtoupper( $params['RELATED'] ))) ? FALSE : TRUE;
|
3938 |
+
$before = ( '-' == $year[0] ) ? TRUE : FALSE;
|
3939 |
+
if( 'P' != $year[0] )
|
3940 |
+
$year = substr( $year, 1 );
|
3941 |
+
$date = iCalUtilityFunctions::_duration_string( $year);
|
3942 |
+
}
|
3943 |
+
else // date
|
3944 |
+
$date = iCalUtilityFunctions::_date_time_string( $year, 7 );
|
3945 |
+
unset( $year, $month, $day );
|
3946 |
+
if( empty( $date ))
|
3947 |
+
$sec = 0;
|
3948 |
+
else
|
3949 |
+
foreach( $date as $k => $v )
|
3950 |
+
$$k = $v;
|
3951 |
+
}
|
3952 |
+
else // single values in function input parameters
|
3953 |
+
$params = iCalUtilityFunctions::_setParams( $params );
|
3954 |
+
if( !empty( $year ) && !empty( $month ) && !empty( $day )) { // date
|
3955 |
+
$params['VALUE'] = 'DATE-TIME';
|
3956 |
+
$hour = ( $hour ) ? $hour : 0;
|
3957 |
+
$min = ( $min ) ? $min : 0;
|
3958 |
+
$sec = ( $sec ) ? $sec : 0;
|
3959 |
+
$this->trigger = array( 'params' => $params );
|
3960 |
+
$this->trigger['value'] = array( 'year' => $year
|
3961 |
+
, 'month' => $month
|
3962 |
+
, 'day' => $day
|
3963 |
+
, 'hour' => $hour
|
3964 |
+
, 'min' => $min
|
3965 |
+
, 'sec' => $sec
|
3966 |
+
, 'tz' => 'Z' );
|
3967 |
+
return TRUE;
|
3968 |
+
}
|
3969 |
+
elseif(( empty( $year ) && empty( $month )) && // duration
|
3970 |
+
(( !empty( $week ) || ( 0 == $week )) ||
|
3971 |
+
( !empty( $day ) || ( 0 == $day )) ||
|
3972 |
+
( !empty( $hour ) || ( 0 == $hour )) ||
|
3973 |
+
( !empty( $min ) || ( 0 == $min )) ||
|
3974 |
+
( !empty( $sec ) || ( 0 == $sec )))) {
|
3975 |
+
unset( $params['RELATED'] ); // set at output creation (END only)
|
3976 |
+
unset( $params['VALUE'] ); // 'DURATION' default
|
3977 |
+
$this->trigger = array( 'params' => $params );
|
3978 |
+
$this->trigger['value'] = array();
|
3979 |
+
if( !empty( $week )) $this->trigger['value']['week'] = $week;
|
3980 |
+
if( !empty( $day )) $this->trigger['value']['day'] = $day;
|
3981 |
+
if( !empty( $hour )) $this->trigger['value']['hour'] = $hour;
|
3982 |
+
if( !empty( $min )) $this->trigger['value']['min'] = $min;
|
3983 |
+
if( !empty( $sec )) $this->trigger['value']['sec'] = $sec;
|
3984 |
+
if( empty( $this->trigger['value'] )) {
|
3985 |
+
$this->trigger['value']['sec'] = 0;
|
3986 |
+
$before = FALSE;
|
3987 |
+
}
|
3988 |
+
$relatedStart = ( FALSE !== $relatedStart ) ? TRUE : FALSE;
|
3989 |
+
$before = ( FALSE !== $before ) ? TRUE : FALSE;
|
3990 |
+
$this->trigger['value']['relatedStart'] = $relatedStart;
|
3991 |
+
$this->trigger['value']['before'] = $before;
|
3992 |
+
return TRUE;
|
3993 |
+
}
|
3994 |
+
return FALSE;
|
3995 |
+
}
|
3996 |
+
/*********************************************************************************/
|
3997 |
+
/**
|
3998 |
+
* Property Name: TZID
|
3999 |
+
*/
|
4000 |
+
/**
|
4001 |
+
* creates formatted output for calendar component property tzid
|
4002 |
+
*
|
4003 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4004 |
+
* @since 2.4.8 - 2008-10-21
|
4005 |
+
* @return string
|
4006 |
+
*/
|
4007 |
+
function createTzid() {
|
4008 |
+
if( empty( $this->tzid )) return FALSE;
|
4009 |
+
if( empty( $this->tzid['value'] ))
|
4010 |
+
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'TZID' ) : FALSE;
|
4011 |
+
$attributes = $this->_createParams( $this->tzid['params'] );
|
4012 |
+
return $this->_createElement( 'TZID', $attributes, $this->_strrep( $this->tzid['value'] ));
|
4013 |
+
}
|
4014 |
+
/**
|
4015 |
+
* set calendar component property tzid
|
4016 |
+
*
|
4017 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4018 |
+
* @since 2.4.8 - 2008-11-04
|
4019 |
+
* @param string $value
|
4020 |
+
* @param array $params optional
|
4021 |
+
* @return bool
|
4022 |
+
*/
|
4023 |
+
function setTzid( $value, $params=FALSE ) {
|
4024 |
+
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
4025 |
+
$this->tzid = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params ));
|
4026 |
+
return TRUE;
|
4027 |
+
}
|
4028 |
+
/*********************************************************************************/
|
4029 |
+
/**
|
4030 |
+
* .. .
|
4031 |
+
* Property Name: TZNAME
|
4032 |
+
*/
|
4033 |
+
/**
|
4034 |
+
* creates formatted output for calendar component property tzname
|
4035 |
+
*
|
4036 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4037 |
+
* @since 2.4.8 - 2008-10-21
|
4038 |
+
* @return string
|
4039 |
+
*/
|
4040 |
+
function createTzname() {
|
4041 |
+
if( empty( $this->tzname )) return FALSE;
|
4042 |
+
$output = null;
|
4043 |
+
foreach( $this->tzname as $theName ) {
|
4044 |
+
if( !empty( $theName['value'] )) {
|
4045 |
+
$attributes = $this->_createParams( $theName['params'], array( 'LANGUAGE' ));
|
4046 |
+
$output .= $this->_createElement( 'TZNAME', $attributes, $this->_strrep( $theName['value'] ));
|
4047 |
+
}
|
4048 |
+
elseif( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'TZNAME' );
|
4049 |
+
}
|
4050 |
+
return $output;
|
4051 |
+
}
|
4052 |
+
/**
|
4053 |
+
* set calendar component property tzname
|
4054 |
+
*
|
4055 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4056 |
+
* @since 2.5.1 - 2008-11-05
|
4057 |
+
* @param string $value
|
4058 |
+
* @param string $params, optional
|
4059 |
+
* @param integer $index, optional
|
4060 |
+
* @return bool
|
4061 |
+
*/
|
4062 |
+
function setTzname( $value, $params=FALSE, $index=FALSE ) {
|
4063 |
+
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
4064 |
+
iCalUtilityFunctions::_setMval( $this->tzname, $value, $params, FALSE, $index );
|
4065 |
+
return TRUE;
|
4066 |
+
}
|
4067 |
+
/*********************************************************************************/
|
4068 |
+
/**
|
4069 |
+
* Property Name: TZOFFSETFROM
|
4070 |
+
*/
|
4071 |
+
/**
|
4072 |
+
* creates formatted output for calendar component property tzoffsetfrom
|
4073 |
+
*
|
4074 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4075 |
+
* @since 2.4.8 - 2008-10-21
|
4076 |
+
* @return string
|
4077 |
+
*/
|
4078 |
+
function createTzoffsetfrom() {
|
4079 |
+
if( empty( $this->tzoffsetfrom )) return FALSE;
|
4080 |
+
if( empty( $this->tzoffsetfrom['value'] ))
|
4081 |
+
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'TZOFFSETFROM' ) : FALSE;
|
4082 |
+
$attributes = $this->_createParams( $this->tzoffsetfrom['params'] );
|
4083 |
+
return $this->_createElement( 'TZOFFSETFROM', $attributes, $this->tzoffsetfrom['value'] );
|
4084 |
+
}
|
4085 |
+
/**
|
4086 |
+
* set calendar component property tzoffsetfrom
|
4087 |
+
*
|
4088 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4089 |
+
* @since 2.4.8 - 2008-11-04
|
4090 |
+
* @param string $value
|
4091 |
+
* @param string $params optional
|
4092 |
+
* @return bool
|
4093 |
+
*/
|
4094 |
+
function setTzoffsetfrom( $value, $params=FALSE ) {
|
4095 |
+
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
4096 |
+
$this->tzoffsetfrom = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params ));
|
4097 |
+
return TRUE;
|
4098 |
+
}
|
4099 |
+
/*********************************************************************************/
|
4100 |
+
/**
|
4101 |
+
* Property Name: TZOFFSETTO
|
4102 |
+
*/
|
4103 |
+
/**
|
4104 |
+
* creates formatted output for calendar component property tzoffsetto
|
4105 |
+
*
|
4106 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4107 |
+
* @since 2.4.8 - 2008-10-21
|
4108 |
+
* @return string
|
4109 |
+
*/
|
4110 |
+
function createTzoffsetto() {
|
4111 |
+
if( empty( $this->tzoffsetto )) return FALSE;
|
4112 |
+
if( empty( $this->tzoffsetto['value'] ))
|
4113 |
+
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'TZOFFSETTO' ) : FALSE;
|
4114 |
+
$attributes = $this->_createParams( $this->tzoffsetto['params'] );
|
4115 |
+
return $this->_createElement( 'TZOFFSETTO', $attributes, $this->tzoffsetto['value'] );
|
4116 |
+
}
|
4117 |
+
/**
|
4118 |
+
* set calendar component property tzoffsetto
|
4119 |
+
*
|
4120 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4121 |
+
* @since 2.4.8 - 2008-11-04
|
4122 |
+
* @param string $value
|
4123 |
+
* @param string $params optional
|
4124 |
+
* @return bool
|
4125 |
+
*/
|
4126 |
+
function setTzoffsetto( $value, $params=FALSE ) {
|
4127 |
+
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
4128 |
+
$this->tzoffsetto = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params ));
|
4129 |
+
return TRUE;
|
4130 |
+
}
|
4131 |
+
/*********************************************************************************/
|
4132 |
+
/**
|
4133 |
+
* Property Name: TZURL
|
4134 |
+
*/
|
4135 |
+
/**
|
4136 |
+
* creates formatted output for calendar component property tzurl
|
4137 |
+
*
|
4138 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4139 |
+
* @since 2.4.8 - 2008-10-21
|
4140 |
+
* @return string
|
4141 |
+
*/
|
4142 |
+
function createTzurl() {
|
4143 |
+
if( empty( $this->tzurl )) return FALSE;
|
4144 |
+
if( empty( $this->tzurl['value'] ))
|
4145 |
+
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'TZURL' ) : FALSE;
|
4146 |
+
$attributes = $this->_createParams( $this->tzurl['params'] );
|
4147 |
+
return $this->_createElement( 'TZURL', $attributes, $this->tzurl['value'] );
|
4148 |
+
}
|
4149 |
+
/**
|
4150 |
+
* set calendar component property tzurl
|
4151 |
+
*
|
4152 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4153 |
+
* @since 2.4.8 - 2008-11-04
|
4154 |
+
* @param string $value
|
4155 |
+
* @param string $params optional
|
4156 |
+
* @return boll
|
4157 |
+
*/
|
4158 |
+
function setTzurl( $value, $params=FALSE ) {
|
4159 |
+
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
4160 |
+
$this->tzurl = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params ));
|
4161 |
+
return TRUE;
|
4162 |
+
}
|
4163 |
+
/*********************************************************************************/
|
4164 |
+
/**
|
4165 |
+
* Property Name: UID
|
4166 |
+
*/
|
4167 |
+
/**
|
4168 |
+
* creates formatted output for calendar component property uid
|
4169 |
+
*
|
4170 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4171 |
+
* @since 0.9.7 - 2006-11-20
|
4172 |
+
* @return string
|
4173 |
+
*/
|
4174 |
+
function createUid() {
|
4175 |
+
if( 0 >= count( $this->uid ))
|
4176 |
+
$this->_makeuid();
|
4177 |
+
$attributes = $this->_createParams( $this->uid['params'] );
|
4178 |
+
return $this->_createElement( 'UID', $attributes, $this->uid['value'] );
|
4179 |
+
}
|
4180 |
+
/**
|
4181 |
+
* create an unique id for this calendar component object instance
|
4182 |
+
*
|
4183 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4184 |
+
* @since 2.2.7 - 2007-09-04
|
4185 |
+
* @return void
|
4186 |
+
*/
|
4187 |
+
function _makeUid() {
|
4188 |
+
$date = date('Ymd\THisT');
|
4189 |
+
$unique = substr(microtime(), 2, 4);
|
4190 |
+
$base = 'aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPrRsStTuUvVxXuUvVwWzZ1234567890';
|
4191 |
+
$start = 0;
|
4192 |
+
$end = strlen( $base ) - 1;
|
4193 |
+
$length = 6;
|
4194 |
+
$str = null;
|
4195 |
+
for( $p = 0; $p < $length; $p++ )
|
4196 |
+
$unique .= $base{mt_rand( $start, $end )};
|
4197 |
+
$this->uid = array( 'params' => null );
|
4198 |
+
$this->uid['value'] = $date.'-'.$unique.'@'.$this->getConfig( 'unique_id' );
|
4199 |
+
}
|
4200 |
+
/**
|
4201 |
+
* set calendar component property uid
|
4202 |
+
*
|
4203 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4204 |
+
* @since 2.4.8 - 2008-11-04
|
4205 |
+
* @param string $value
|
4206 |
+
* @param string $params optional
|
4207 |
+
* @return bool
|
4208 |
+
*/
|
4209 |
+
function setUid( $value, $params=FALSE ) {
|
4210 |
+
if( empty( $value )) return FALSE; // no allowEmpty check here !!!!
|
4211 |
+
$this->uid = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params ));
|
4212 |
+
return TRUE;
|
4213 |
+
}
|
4214 |
+
/*********************************************************************************/
|
4215 |
+
/**
|
4216 |
+
* Property Name: URL
|
4217 |
+
*/
|
4218 |
+
/**
|
4219 |
+
* creates formatted output for calendar component property url
|
4220 |
+
*
|
4221 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4222 |
+
* @since 2.4.8 - 2008-10-21
|
4223 |
+
* @return string
|
4224 |
+
*/
|
4225 |
+
function createUrl() {
|
4226 |
+
if( empty( $this->url )) return FALSE;
|
4227 |
+
if( empty( $this->url['value'] ))
|
4228 |
+
return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'URL' ) : FALSE;
|
4229 |
+
$attributes = $this->_createParams( $this->url['params'] );
|
4230 |
+
return $this->_createElement( 'URL', $attributes, $this->url['value'] );
|
4231 |
+
}
|
4232 |
+
/**
|
4233 |
+
* set calendar component property url
|
4234 |
+
*
|
4235 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4236 |
+
* @since 2.4.8 - 2008-11-04
|
4237 |
+
* @param string $value
|
4238 |
+
* @param string $params optional
|
4239 |
+
* @return bool
|
4240 |
+
*/
|
4241 |
+
function setUrl( $value, $params=FALSE ) {
|
4242 |
+
if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
4243 |
+
$this->url = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params ));
|
4244 |
+
return TRUE;
|
4245 |
+
}
|
4246 |
+
/*********************************************************************************/
|
4247 |
+
/**
|
4248 |
+
* Property Name: x-prop
|
4249 |
+
*/
|
4250 |
+
/**
|
4251 |
+
* creates formatted output for calendar component property x-prop
|
4252 |
+
*
|
4253 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4254 |
+
* @since 2.9.3 - 2011-05-14
|
4255 |
+
* @return string
|
4256 |
+
*/
|
4257 |
+
function createXprop() {
|
4258 |
+
if( empty( $this->xprop )) return FALSE;
|
4259 |
+
$output = null;
|
4260 |
+
foreach( $this->xprop as $label => $xpropPart ) {
|
4261 |
+
if( !isset($xpropPart['value']) || ( empty( $xpropPart['value'] ) && !is_numeric( $xpropPart['value'] ))) {
|
4262 |
+
if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( $label );
|
4263 |
+
continue;
|
4264 |
+
}
|
4265 |
+
$attributes = $this->_createParams( $xpropPart['params'], array( 'LANGUAGE' ));
|
4266 |
+
if( is_array( $xpropPart['value'] )) {
|
4267 |
+
foreach( $xpropPart['value'] as $pix => $theXpart )
|
4268 |
+
$xpropPart['value'][$pix] = $this->_strrep( $theXpart );
|
4269 |
+
$xpropPart['value'] = implode( ',', $xpropPart['value'] );
|
4270 |
+
}
|
4271 |
+
else
|
4272 |
+
$xpropPart['value'] = $this->_strrep( $xpropPart['value'] );
|
4273 |
+
$output .= $this->_createElement( $label, $attributes, $xpropPart['value'] );
|
4274 |
+
}
|
4275 |
+
return $output;
|
4276 |
+
}
|
4277 |
+
/**
|
4278 |
+
* set calendar component property x-prop
|
4279 |
+
*
|
4280 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4281 |
+
* @since 2.9.3 - 2011-05-14
|
4282 |
+
* @param string $label
|
4283 |
+
* @param mixed $value
|
4284 |
+
* @param array $params optional
|
4285 |
+
* @return bool
|
4286 |
+
*/
|
4287 |
+
function setXprop( $label, $value, $params=FALSE ) {
|
4288 |
+
if( empty( $label )) return;
|
4289 |
+
if( empty( $value ) && !is_numeric( $value )) if( $this->getConfig( 'allowEmpty' )) $value = null; else return FALSE;
|
4290 |
+
$xprop = array( 'value' => $value );
|
4291 |
+
$xprop['params'] = iCalUtilityFunctions::_setParams( $params );
|
4292 |
+
if( !is_array( $this->xprop )) $this->xprop = array();
|
4293 |
+
$this->xprop[strtoupper( $label )] = $xprop;
|
4294 |
+
return TRUE;
|
4295 |
+
}
|
4296 |
+
/*********************************************************************************/
|
4297 |
+
/*********************************************************************************/
|
4298 |
+
/**
|
4299 |
+
* create element format parts
|
4300 |
+
*
|
4301 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4302 |
+
* @since 2.0.6 - 2006-06-20
|
4303 |
+
* @return string
|
4304 |
+
*/
|
4305 |
+
function _createFormat() {
|
4306 |
+
$objectname = null;
|
4307 |
+
switch( $this->format ) {
|
4308 |
+
case 'xcal':
|
4309 |
+
$objectname = ( isset( $this->timezonetype )) ?
|
4310 |
+
strtolower( $this->timezonetype ) : strtolower( $this->objName );
|
4311 |
+
$this->componentStart1 = $this->elementStart1 = '<';
|
4312 |
+
$this->componentStart2 = $this->elementStart2 = '>';
|
4313 |
+
$this->componentEnd1 = $this->elementEnd1 = '</';
|
4314 |
+
$this->componentEnd2 = $this->elementEnd2 = '>'.$this->nl;
|
4315 |
+
$this->intAttrDelimiter = '<!-- -->';
|
4316 |
+
$this->attributeDelimiter = $this->nl;
|
4317 |
+
$this->valueInit = null;
|
4318 |
+
break;
|
4319 |
+
default:
|
4320 |
+
$objectname = ( isset( $this->timezonetype )) ?
|
4321 |
+
strtoupper( $this->timezonetype ) : strtoupper( $this->objName );
|
4322 |
+
$this->componentStart1 = 'BEGIN:';
|
4323 |
+
$this->componentStart2 = null;
|
4324 |
+
$this->componentEnd1 = 'END:';
|
4325 |
+
$this->componentEnd2 = $this->nl;
|
4326 |
+
$this->elementStart1 = null;
|
4327 |
+
$this->elementStart2 = null;
|
4328 |
+
$this->elementEnd1 = null;
|
4329 |
+
$this->elementEnd2 = $this->nl;
|
4330 |
+
$this->intAttrDelimiter = '<!-- -->';
|
4331 |
+
$this->attributeDelimiter = ';';
|
4332 |
+
$this->valueInit = ':';
|
4333 |
+
break;
|
4334 |
+
}
|
4335 |
+
return $objectname;
|
4336 |
+
}
|
4337 |
+
/**
|
4338 |
+
* creates formatted output for calendar component property
|
4339 |
+
*
|
4340 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4341 |
+
* @since 2.6.22 - 2010-12-06
|
4342 |
+
* @param string $label property name
|
4343 |
+
* @param string $attributes property attributes
|
4344 |
+
* @param string $content property content (optional)
|
4345 |
+
* @return string
|
4346 |
+
*/
|
4347 |
+
function _createElement( $label, $attributes=null, $content=FALSE ) {
|
4348 |
+
switch( $this->format ) {
|
4349 |
+
case 'xcal':
|
4350 |
+
$label = strtolower( $label );
|
4351 |
+
break;
|
4352 |
+
default:
|
4353 |
+
$label = strtoupper( $label );
|
4354 |
+
break;
|
4355 |
+
}
|
4356 |
+
$output = $this->elementStart1.$label;
|
4357 |
+
$categoriesAttrLang = null;
|
4358 |
+
$attachInlineBinary = FALSE;
|
4359 |
+
$attachfmttype = null;
|
4360 |
+
if( !empty( $attributes )) {
|
4361 |
+
$attributes = trim( $attributes );
|
4362 |
+
if ( 'xcal' == $this->format) {
|
4363 |
+
$attributes2 = explode( $this->intAttrDelimiter, $attributes );
|
4364 |
+
$attributes = null;
|
4365 |
+
foreach( $attributes2 as $attribute ) {
|
4366 |
+
$attrKVarr = explode( '=', $attribute );
|
4367 |
+
if( empty( $attrKVarr[0] ))
|
4368 |
+
continue;
|
4369 |
+
if( !isset( $attrKVarr[1] )) {
|
4370 |
+
$attrValue = $attrKVarr[0];
|
4371 |
+
$attrKey = null;
|
4372 |
+
}
|
4373 |
+
elseif( 2 == count( $attrKVarr)) {
|
4374 |
+
$attrKey = strtolower( $attrKVarr[0] );
|
4375 |
+
$attrValue = $attrKVarr[1];
|
4376 |
+
}
|
4377 |
+
else {
|
4378 |
+
$attrKey = strtolower( $attrKVarr[0] );
|
4379 |
+
unset( $attrKVarr[0] );
|
4380 |
+
$attrValue = implode( '=', $attrKVarr );
|
4381 |
+
}
|
4382 |
+
if(( 'attach' == $label ) && ( in_array( $attrKey, array( 'fmttype', 'encoding', 'value' )))) {
|
4383 |
+
$attachInlineBinary = TRUE;
|
4384 |
+
if( 'fmttype' == $attrKey )
|
4385 |
+
$attachfmttype = $attrKey.'='.$attrValue;
|
4386 |
+
continue;
|
4387 |
+
}
|
4388 |
+
elseif(( 'categories' == $label ) && ( 'language' == $attrKey ))
|
4389 |
+
$categoriesAttrLang = $attrKey.'='.$attrValue;
|
4390 |
+
else {
|
4391 |
+
$attributes .= ( empty( $attributes )) ? ' ' : $this->attributeDelimiter.' ';
|
4392 |
+
$attributes .= ( !empty( $attrKey )) ? $attrKey.'=' : null;
|
4393 |
+
if(( '"' == substr( $attrValue, 0, 1 )) && ( '"' == substr( $attrValue, -1 ))) {
|
4394 |
+
$attrValue = substr( $attrValue, 1, ( strlen( $attrValue ) - 2 ));
|
4395 |
+
$attrValue = str_replace( '"', '', $attrValue );
|
4396 |
+
}
|
4397 |
+
$attributes .= '"'.htmlspecialchars( $attrValue ).'"';
|
4398 |
+
}
|
4399 |
+
}
|
4400 |
+
}
|
4401 |
+
else {
|
4402 |
+
$attributes = str_replace( $this->intAttrDelimiter, $this->attributeDelimiter, $attributes );
|
4403 |
+
}
|
4404 |
+
}
|
4405 |
+
if(((( 'attach' == $label ) && !$attachInlineBinary ) ||
|
4406 |
+
( in_array( $label, array( 'tzurl', 'url' )))) && ( 'xcal' == $this->format)) {
|
4407 |
+
$pos = strrpos($content, "/");
|
4408 |
+
$docname = ( $pos !== false) ? substr( $content, (1 - strlen( $content ) + $pos )) : $content;
|
4409 |
+
$this->xcaldecl[] = array( 'xmldecl' => 'ENTITY'
|
4410 |
+
, 'uri' => $docname
|
4411 |
+
, 'ref' => 'SYSTEM'
|
4412 |
+
, 'external' => $content
|
4413 |
+
, 'type' => 'NDATA'
|
4414 |
+
, 'type2' => 'BINERY' );
|
4415 |
+
$attributes .= ( empty( $attributes )) ? ' ' : $this->attributeDelimiter.' ';
|
4416 |
+
$attributes .= 'uri="'.$docname.'"';
|
4417 |
+
$content = null;
|
4418 |
+
if( 'attach' == $label ) {
|
4419 |
+
$attributes = str_replace( $this->attributeDelimiter, $this->intAttrDelimiter, $attributes );
|
4420 |
+
$content = $this->_createElement( 'extref', $attributes, null );
|
4421 |
+
$attributes = null;
|
4422 |
+
}
|
4423 |
+
}
|
4424 |
+
elseif(( 'attach' == $label ) && $attachInlineBinary && ( 'xcal' == $this->format)) {
|
4425 |
+
$content = $this->nl.$this->_createElement( 'b64bin', $attachfmttype, $content ); // max one attribute
|
4426 |
+
}
|
4427 |
+
$output .= $attributes;
|
4428 |
+
if( !$content && ( '0' != $content )) {
|
4429 |
+
switch( $this->format ) {
|
4430 |
+
case 'xcal':
|
4431 |
+
$output .= ' /';
|
4432 |
+
$output .= $this->elementStart2;
|
4433 |
+
return $output;
|
4434 |
+
break;
|
4435 |
+
default:
|
4436 |
+
$output .= $this->elementStart2.$this->valueInit;
|
4437 |
+
return $this->_size75( $output );
|
4438 |
+
break;
|
4439 |
+
}
|
4440 |
+
}
|
4441 |
+
$output .= $this->elementStart2;
|
4442 |
+
$output .= $this->valueInit.$content;
|
4443 |
+
switch( $this->format ) {
|
4444 |
+
case 'xcal':
|
4445 |
+
return $output.$this->elementEnd1.$label.$this->elementEnd2;
|
4446 |
+
break;
|
4447 |
+
default:
|
4448 |
+
return $this->_size75( $output );
|
4449 |
+
break;
|
4450 |
+
}
|
4451 |
+
}
|
4452 |
+
/**
|
4453 |
+
* creates formatted output for calendar component property parameters
|
4454 |
+
*
|
4455 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4456 |
+
* @since 2.6.33 - 2010-12-18
|
4457 |
+
* @param array $params optional
|
4458 |
+
* @param array $ctrKeys optional
|
4459 |
+
* @return string
|
4460 |
+
*/
|
4461 |
+
function _createParams( $params=array(), $ctrKeys=array() ) {
|
4462 |
+
if( !is_array( $params ) || empty( $params ))
|
4463 |
+
$params = array();
|
4464 |
+
$attrLANG = $attr1 = $attr2 = $lang = null;
|
4465 |
+
$CNattrKey = ( in_array( 'CN', $ctrKeys )) ? TRUE : FALSE ;
|
4466 |
+
$LANGattrKey = ( in_array( 'LANGUAGE', $ctrKeys )) ? TRUE : FALSE ;
|
4467 |
+
$CNattrExist = $LANGattrExist = FALSE;
|
4468 |
+
$xparams = array();
|
4469 |
+
foreach( $params as $paramKey => $paramValue ) {
|
4470 |
+
if( ctype_digit( (string) $paramKey )) {
|
4471 |
+
$xparams[] = $paramValue;
|
4472 |
+
continue;
|
4473 |
+
}
|
4474 |
+
$paramKey = strtoupper( $paramKey );
|
4475 |
+
if( !in_array( $paramKey, array( 'ALTREP', 'CN', 'DIR', 'ENCODING', 'FMTTYPE', 'LANGUAGE', 'RANGE', 'RELTYPE', 'SENT-BY', 'TZID', 'VALUE' )))
|
4476 |
+
$xparams[$paramKey] = $paramValue;
|
4477 |
+
else
|
4478 |
+
$params[$paramKey] = $paramValue;
|
4479 |
+
}
|
4480 |
+
ksort( $xparams, SORT_STRING );
|
4481 |
+
foreach( $xparams as $paramKey => $paramValue ) {
|
4482 |
+
if( ctype_digit( (string) $paramKey ))
|
4483 |
+
$attr2 .= $this->intAttrDelimiter.$paramValue;
|
4484 |
+
else
|
4485 |
+
$attr2 .= $this->intAttrDelimiter."$paramKey=$paramValue";
|
4486 |
+
}
|
4487 |
+
if( isset( $params['FMTTYPE'] ) && !in_array( 'FMTTYPE', $ctrKeys )) {
|
4488 |
+
$attr1 .= $this->intAttrDelimiter.'FMTTYPE='.$params['FMTTYPE'].$attr2;
|
4489 |
+
$attr2 = null;
|
4490 |
+
}
|
4491 |
+
if( isset( $params['ENCODING'] ) && !in_array( 'ENCODING', $ctrKeys )) {
|
4492 |
+
if( !empty( $attr2 )) {
|
4493 |
+
$attr1 .= $attr2;
|
4494 |
+
$attr2 = null;
|
4495 |
+
}
|
4496 |
+
$attr1 .= $this->intAttrDelimiter.'ENCODING='.$params['ENCODING'];
|
4497 |
+
}
|
4498 |
+
if( isset( $params['VALUE'] ) && !in_array( 'VALUE', $ctrKeys ))
|
4499 |
+
$attr1 .= $this->intAttrDelimiter.'VALUE='.$params['VALUE'];
|
4500 |
+
if( isset( $params['TZID'] ) && !in_array( 'TZID', $ctrKeys ))
|
4501 |
+
$attr1 .= $this->intAttrDelimiter.'TZID='.$params['TZID'];
|
4502 |
+
if( isset( $params['RANGE'] ) && !in_array( 'RANGE', $ctrKeys ))
|
4503 |
+
$attr1 .= $this->intAttrDelimiter.'RANGE='.$params['RANGE'];
|
4504 |
+
if( isset( $params['RELTYPE'] ) && !in_array( 'RELTYPE', $ctrKeys ))
|
4505 |
+
$attr1 .= $this->intAttrDelimiter.'RELTYPE='.$params['RELTYPE'];
|
4506 |
+
if( isset( $params['CN'] ) && $CNattrKey ) {
|
4507 |
+
$attr1 = $this->intAttrDelimiter.'CN="'.$params['CN'].'"';
|
4508 |
+
$CNattrExist = TRUE;
|
4509 |
+
}
|
4510 |
+
if( isset( $params['DIR'] ) && in_array( 'DIR', $ctrKeys ))
|
4511 |
+
$attr1 .= $this->intAttrDelimiter.'DIR="'.$params['DIR'].'"';
|
4512 |
+
if( isset( $params['SENT-BY'] ) && in_array( 'SENT-BY', $ctrKeys ))
|
4513 |
+
$attr1 .= $this->intAttrDelimiter.'SENT-BY="'.$params['SENT-BY'].'"';
|
4514 |
+
if( isset( $params['ALTREP'] ) && in_array( 'ALTREP', $ctrKeys ))
|
4515 |
+
$attr1 .= $this->intAttrDelimiter.'ALTREP="'.$params['ALTREP'].'"';
|
4516 |
+
if( isset( $params['LANGUAGE'] ) && $LANGattrKey ) {
|
4517 |
+
$attrLANG .= $this->intAttrDelimiter.'LANGUAGE='.$params['LANGUAGE'];
|
4518 |
+
$LANGattrExist = TRUE;
|
4519 |
+
}
|
4520 |
+
if( !$LANGattrExist ) {
|
4521 |
+
$lang = $this->getConfig( 'language' );
|
4522 |
+
if(( $CNattrExist || $LANGattrKey ) && $lang )
|
4523 |
+
$attrLANG .= $this->intAttrDelimiter.'LANGUAGE='.$lang;
|
4524 |
+
}
|
4525 |
+
return $attr1.$attrLANG.$attr2;
|
4526 |
+
}
|
4527 |
+
/**
|
4528 |
+
* creates formatted output for calendar component property data value type recur
|
4529 |
+
*
|
4530 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4531 |
+
* @since 2.4.8 - 2008-10-22
|
4532 |
+
* @param array $recurlabel
|
4533 |
+
* @param array $recurdata
|
4534 |
+
* @return string
|
4535 |
+
*/
|
4536 |
+
function _format_recur( $recurlabel, $recurdata ) {
|
4537 |
+
$output = null;
|
4538 |
+
foreach( $recurdata as $therule ) {
|
4539 |
+
if( empty( $therule['value'] )) {
|
4540 |
+
if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( $recurlabel );
|
4541 |
+
continue;
|
4542 |
+
}
|
4543 |
+
$attributes = ( isset( $therule['params'] )) ? $this->_createParams( $therule['params'] ) : null;
|
4544 |
+
$content1 = $content2 = null;
|
4545 |
+
foreach( $therule['value'] as $rulelabel => $rulevalue ) {
|
4546 |
+
switch( $rulelabel ) {
|
4547 |
+
case 'FREQ': {
|
4548 |
+
$content1 .= "FREQ=$rulevalue";
|
4549 |
+
break;
|
4550 |
+
}
|
4551 |
+
case 'UNTIL': {
|
4552 |
+
$content2 .= ";UNTIL=";
|
4553 |
+
$content2 .= iCalUtilityFunctions::_format_date_time( $rulevalue );
|
4554 |
+
break;
|
4555 |
+
}
|
4556 |
+
case 'COUNT':
|
4557 |
+
case 'INTERVAL':
|
4558 |
+
case 'WKST': {
|
4559 |
+
$content2 .= ";$rulelabel=$rulevalue";
|
4560 |
+
break;
|
4561 |
+
}
|
4562 |
+
case 'BYSECOND':
|
4563 |
+
case 'BYMINUTE':
|
4564 |
+
case 'BYHOUR':
|
4565 |
+
case 'BYMONTHDAY':
|
4566 |
+
case 'BYYEARDAY':
|
4567 |
+
case 'BYWEEKNO':
|
4568 |
+
case 'BYMONTH':
|
4569 |
+
case 'BYSETPOS': {
|
4570 |
+
$content2 .= ";$rulelabel=";
|
4571 |
+
if( is_array( $rulevalue )) {
|
4572 |
+
foreach( $rulevalue as $vix => $valuePart ) {
|
4573 |
+
$content2 .= ( $vix ) ? ',' : null;
|
4574 |
+
$content2 .= $valuePart;
|
4575 |
+
}
|
4576 |
+
}
|
4577 |
+
else
|
4578 |
+
$content2 .= $rulevalue;
|
4579 |
+
break;
|
4580 |
+
}
|
4581 |
+
case 'BYDAY': {
|
4582 |
+
$content2 .= ";$rulelabel=";
|
4583 |
+
$bydaycnt = 0;
|
4584 |
+
foreach( $rulevalue as $vix => $valuePart ) {
|
4585 |
+
$content21 = $content22 = null;
|
4586 |
+
if( is_array( $valuePart )) {
|
4587 |
+
$content2 .= ( $bydaycnt ) ? ',' : null;
|
4588 |
+
foreach( $valuePart as $vix2 => $valuePart2 ) {
|
4589 |
+
if( 'DAY' != strtoupper( $vix2 ))
|
4590 |
+
$content21 .= $valuePart2;
|
4591 |
+
else
|
4592 |
+
$content22 .= $valuePart2;
|
4593 |
+
}
|
4594 |
+
$content2 .= $content21.$content22;
|
4595 |
+
$bydaycnt++;
|
4596 |
+
}
|
4597 |
+
else {
|
4598 |
+
$content2 .= ( $bydaycnt ) ? ',' : null;
|
4599 |
+
if( 'DAY' != strtoupper( $vix ))
|
4600 |
+
$content21 .= $valuePart;
|
4601 |
+
else {
|
4602 |
+
$content22 .= $valuePart;
|
4603 |
+
$bydaycnt++;
|
4604 |
+
}
|
4605 |
+
$content2 .= $content21.$content22;
|
4606 |
+
}
|
4607 |
+
}
|
4608 |
+
break;
|
4609 |
+
}
|
4610 |
+
default: {
|
4611 |
+
$content2 .= ";$rulelabel=$rulevalue";
|
4612 |
+
break;
|
4613 |
+
}
|
4614 |
+
}
|
4615 |
+
}
|
4616 |
+
$output .= $this->_createElement( $recurlabel, $attributes, $content1.$content2 );
|
4617 |
+
}
|
4618 |
+
return $output;
|
4619 |
+
}
|
4620 |
+
/**
|
4621 |
+
* check if property not exists within component
|
4622 |
+
*
|
4623 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4624 |
+
* @since 2.5.1 - 2008-10-15
|
4625 |
+
* @param string $propName
|
4626 |
+
* @return bool
|
4627 |
+
*/
|
4628 |
+
function _notExistProp( $propName ) {
|
4629 |
+
if( empty( $propName )) return FALSE; // when deleting x-prop, an empty propName may be used=allowed
|
4630 |
+
$propName = strtolower( $propName );
|
4631 |
+
if( 'last-modified' == $propName ) { if( !isset( $this->lastmodified )) return TRUE; }
|
4632 |
+
elseif( 'percent-complete' == $propName ) { if( !isset( $this->percentcomplete )) return TRUE; }
|
4633 |
+
elseif( 'recurrence-id' == $propName ) { if( !isset( $this->recurrenceid )) return TRUE; }
|
4634 |
+
elseif( 'related-to' == $propName ) { if( !isset( $this->relatedto )) return TRUE; }
|
4635 |
+
elseif( 'request-status' == $propName ) { if( !isset( $this->requeststatus )) return TRUE; }
|
4636 |
+
elseif(( 'x-' != substr($propName,0,2)) && !isset( $this->$propName )) return TRUE;
|
4637 |
+
return FALSE;
|
4638 |
+
}
|
4639 |
+
/*********************************************************************************/
|
4640 |
+
/*********************************************************************************/
|
4641 |
+
/**
|
4642 |
+
* get general component config variables or info about subcomponents
|
4643 |
+
*
|
4644 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4645 |
+
* @since 2.9.6 - 2011-05-14
|
4646 |
+
* @param mixed $config
|
4647 |
+
* @return value
|
4648 |
+
*/
|
4649 |
+
function getConfig( $config = FALSE) {
|
4650 |
+
if( !$config ) {
|
4651 |
+
$return = array();
|
4652 |
+
$return['ALLOWEMPTY'] = $this->getConfig( 'ALLOWEMPTY' );
|
4653 |
+
$return['FORMAT'] = $this->getConfig( 'FORMAT' );
|
4654 |
+
if( FALSE !== ( $lang = $this->getConfig( 'LANGUAGE' )))
|
4655 |
+
$return['LANGUAGE'] = $lang;
|
4656 |
+
$return['NEWLINECHAR'] = $this->getConfig( 'NEWLINECHAR' );
|
4657 |
+
$return['TZTD'] = $this->getConfig( 'TZID' );
|
4658 |
+
$return['UNIQUE_ID'] = $this->getConfig( 'UNIQUE_ID' );
|
4659 |
+
return $return;
|
4660 |
+
}
|
4661 |
+
switch( strtoupper( $config )) {
|
4662 |
+
case 'ALLOWEMPTY':
|
4663 |
+
return $this->allowEmpty;
|
4664 |
+
break;
|
4665 |
+
case 'COMPSINFO':
|
4666 |
+
unset( $this->compix );
|
4667 |
+
$info = array();
|
4668 |
+
if( isset( $this->components )) {
|
4669 |
+
foreach( $this->components as $cix => $component ) {
|
4670 |
+
if( empty( $component )) continue;
|
4671 |
+
$info[$cix]['ordno'] = $cix + 1;
|
4672 |
+
$info[$cix]['type'] = $component->objName;
|
4673 |
+
$info[$cix]['uid'] = $component->getProperty( 'uid' );
|
4674 |
+
$info[$cix]['props'] = $component->getConfig( 'propinfo' );
|
4675 |
+
$info[$cix]['sub'] = $component->getConfig( 'compsinfo' );
|
4676 |
+
}
|
4677 |
+
}
|
4678 |
+
return $info;
|
4679 |
+
break;
|
4680 |
+
case 'FORMAT':
|
4681 |
+
return $this->format;
|
4682 |
+
break;
|
4683 |
+
case 'LANGUAGE':
|
4684 |
+
// get language for calendar component as defined in [RFC 1766]
|
4685 |
+
return $this->language;
|
4686 |
+
break;
|
4687 |
+
case 'NL':
|
4688 |
+
case 'NEWLINECHAR':
|
4689 |
+
return $this->nl;
|
4690 |
+
break;
|
4691 |
+
case 'PROPINFO':
|
4692 |
+
$output = array();
|
4693 |
+
if( !in_array( $this->objName, array( 'valarm', 'vtimezone', 'standard', 'daylight' ))) {
|
4694 |
+
if( empty( $this->uid['value'] )) $this->_makeuid();
|
4695 |
+
$output['UID'] = 1;
|
4696 |
+
}
|
4697 |
+
if( !empty( $this->dtstamp )) $output['DTSTAMP'] = 1;
|
4698 |
+
if( !empty( $this->summary )) $output['SUMMARY'] = 1;
|
4699 |
+
if( !empty( $this->description )) $output['DESCRIPTION'] = count( $this->description );
|
4700 |
+
if( !empty( $this->dtstart )) $output['DTSTART'] = 1;
|
4701 |
+
if( !empty( $this->dtend )) $output['DTEND'] = 1;
|
4702 |
+
if( !empty( $this->due )) $output['DUE'] = 1;
|
4703 |
+
if( !empty( $this->duration )) $output['DURATION'] = 1;
|
4704 |
+
if( !empty( $this->rrule )) $output['RRULE'] = count( $this->rrule );
|
4705 |
+
if( !empty( $this->rdate )) $output['RDATE'] = count( $this->rdate );
|
4706 |
+
if( !empty( $this->exdate )) $output['EXDATE'] = count( $this->exdate );
|
4707 |
+
if( !empty( $this->exrule )) $output['EXRULE'] = count( $this->exrule );
|
4708 |
+
if( !empty( $this->action )) $output['ACTION'] = 1;
|
4709 |
+
if( !empty( $this->attach )) $output['ATTACH'] = count( $this->attach );
|
4710 |
+
if( !empty( $this->attendee )) $output['ATTENDEE'] = count( $this->attendee );
|
4711 |
+
if( !empty( $this->categories )) $output['CATEGORIES'] = count( $this->categories );
|
4712 |
+
if( !empty( $this->class )) $output['CLASS'] = 1;
|
4713 |
+
if( !empty( $this->comment )) $output['COMMENT'] = count( $this->comment );
|
4714 |
+
if( !empty( $this->completed )) $output['COMPLETED'] = 1;
|
4715 |
+
if( !empty( $this->contact )) $output['CONTACT'] = count( $this->contact );
|
4716 |
+
if( !empty( $this->created )) $output['CREATED'] = 1;
|
4717 |
+
if( !empty( $this->freebusy )) $output['FREEBUSY'] = count( $this->freebusy );
|
4718 |
+
if( !empty( $this->geo )) $output['GEO'] = 1;
|
4719 |
+
if( !empty( $this->lastmodified )) $output['LAST-MODIFIED'] = 1;
|
4720 |
+
if( !empty( $this->location )) $output['LOCATION'] = 1;
|
4721 |
+
if( !empty( $this->organizer )) $output['ORGANIZER'] = 1;
|
4722 |
+
if( !empty( $this->percentcomplete )) $output['PERCENT-COMPLETE'] = 1;
|
4723 |
+
if( !empty( $this->priority )) $output['PRIORITY'] = 1;
|
4724 |
+
if( !empty( $this->recurrenceid )) $output['RECURRENCE-ID'] = 1;
|
4725 |
+
if( !empty( $this->relatedto )) $output['RELATED-TO'] = count( $this->relatedto );
|
4726 |
+
if( !empty( $this->repeat )) $output['REPEAT'] = 1;
|
4727 |
+
if( !empty( $this->requeststatus )) $output['REQUEST-STATUS'] = count( $this->requeststatus );
|
4728 |
+
if( !empty( $this->resources )) $output['RESOURCES'] = count( $this->resources );
|
4729 |
+
if( !empty( $this->sequence )) $output['SEQUENCE'] = 1;
|
4730 |
+
if( !empty( $this->sequence )) $output['SEQUENCE'] = 1;
|
4731 |
+
if( !empty( $this->status )) $output['STATUS'] = 1;
|
4732 |
+
if( !empty( $this->transp )) $output['TRANSP'] = 1;
|
4733 |
+
if( !empty( $this->trigger )) $output['TRIGGER'] = 1;
|
4734 |
+
if( !empty( $this->tzid )) $output['TZID'] = 1;
|
4735 |
+
if( !empty( $this->tzname )) $output['TZNAME'] = count( $this->tzname );
|
4736 |
+
if( !empty( $this->tzoffsetfrom )) $output['TZOFFSETFROM'] = 1;
|
4737 |
+
if( !empty( $this->tzoffsetto )) $output['TZOFFSETTO'] = 1;
|
4738 |
+
if( !empty( $this->tzurl )) $output['TZURL'] = 1;
|
4739 |
+
if( !empty( $this->url )) $output['URL'] = 1;
|
4740 |
+
if( !empty( $this->xprop )) $output['X-PROP'] = count( $this->xprop );
|
4741 |
+
return $output;
|
4742 |
+
break;
|
4743 |
+
case 'TZID':
|
4744 |
+
return $this->dtzid;
|
4745 |
+
break;
|
4746 |
+
case 'UNIQUE_ID':
|
4747 |
+
if( empty( $this->unique_id ))
|
4748 |
+
$this->unique_id = ( isset( $_SERVER['SERVER_NAME'] )) ? gethostbyname( $_SERVER['SERVER_NAME'] ) : 'localhost';
|
4749 |
+
return $this->unique_id;
|
4750 |
+
break;
|
4751 |
+
}
|
4752 |
+
}
|
4753 |
+
/**
|
4754 |
+
* general component config setting
|
4755 |
+
*
|
4756 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4757 |
+
* @since 2.9.6 - 2011-05-14
|
4758 |
+
* @param mixed $config
|
4759 |
+
* @param string $value
|
4760 |
+
* @param bool $softUpdate
|
4761 |
+
* @return void
|
4762 |
+
*/
|
4763 |
+
function setConfig( $config, $value = FALSE, $softUpdate = FALSE ) {
|
4764 |
+
if( is_array( $config )) {
|
4765 |
+
foreach( $config as $cKey => $cValue ) {
|
4766 |
+
if( FALSE === $this->setConfig( $cKey, $cValue, $softUpdate ))
|
4767 |
+
return FALSE;
|
4768 |
+
}
|
4769 |
+
return TRUE;
|
4770 |
+
}
|
4771 |
+
$res = FALSE;
|
4772 |
+
switch( strtoupper( $config )) {
|
4773 |
+
case 'ALLOWEMPTY':
|
4774 |
+
$this->allowEmpty = $value;
|
4775 |
+
$subcfg = array( 'ALLOWEMPTY' => $value );
|
4776 |
+
$res = TRUE;
|
4777 |
+
break;
|
4778 |
+
case 'FORMAT':
|
4779 |
+
$value = trim( strtolower( $value ));
|
4780 |
+
$this->format = $value;
|
4781 |
+
$this->_createFormat();
|
4782 |
+
$subcfg = array( 'FORMAT' => $value );
|
4783 |
+
$res = TRUE;
|
4784 |
+
break;
|
4785 |
+
case 'LANGUAGE':
|
4786 |
+
// set language for calendar component as defined in [RFC 1766]
|
4787 |
+
$value = trim( $value );
|
4788 |
+
if( empty( $this->language ) || !$softUpdate )
|
4789 |
+
$this->language = $value;
|
4790 |
+
$subcfg = array( 'LANGUAGE' => $value );
|
4791 |
+
$res = TRUE;
|
4792 |
+
break;
|
4793 |
+
case 'NL':
|
4794 |
+
case 'NEWLINECHAR':
|
4795 |
+
$this->nl = $value;
|
4796 |
+
$subcfg = array( 'NL' => $value );
|
4797 |
+
$res = TRUE;
|
4798 |
+
break;
|
4799 |
+
case 'TZID':
|
4800 |
+
$this->dtzid = $value;
|
4801 |
+
$subcfg = array( 'TZID' => $value );
|
4802 |
+
$res = TRUE;
|
4803 |
+
break;
|
4804 |
+
case 'UNIQUE_ID':
|
4805 |
+
$value = trim( $value );
|
4806 |
+
$this->unique_id = $value;
|
4807 |
+
$subcfg = array( 'UNIQUE_ID' => $value );
|
4808 |
+
$res = TRUE;
|
4809 |
+
break;
|
4810 |
+
default: // any unvalid config key.. .
|
4811 |
+
return TRUE;
|
4812 |
+
}
|
4813 |
+
if( !$res ) return FALSE;
|
4814 |
+
if( isset( $subcfg ) && !empty( $this->components )) {
|
4815 |
+
foreach( $subcfg as $cfgkey => $cfgvalue ) {
|
4816 |
+
foreach( $this->components as $cix => $component ) {
|
4817 |
+
$res = $component->setConfig( $cfgkey, $cfgvalue, $softUpdate );
|
4818 |
+
if( !$res )
|
4819 |
+
break 2;
|
4820 |
+
$this->components[$cix] = $component->copy(); // PHP4 compliant
|
4821 |
+
}
|
4822 |
+
}
|
4823 |
+
}
|
4824 |
+
return $res;
|
4825 |
+
}
|
4826 |
+
/*********************************************************************************/
|
4827 |
+
/**
|
4828 |
+
* delete component property value
|
4829 |
+
*
|
4830 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
4831 |
+
* @since 2.8.8 - 2011-03-15
|
4832 |
+
* @param mixed $propName, bool FALSE => X-property
|
4833 |
+
* @param int $propix, optional, if specific property is wanted in case of multiply occurences
|
4834 |
+
* @return bool, if successfull delete TRUE
|
4835 |
+
*/
|
4836 |
+
function deleteProperty( $propName=FALSE, $propix=FALSE ) {
|
4837 |
+
if( $this->_notExistProp( $propName )) return FALSE;
|
4838 |
+
$propName = strtoupper( $propName );
|
4839 |
+
if( in_array( $propName, array( 'ATTACH', 'ATTENDEE', 'CATEGORIES', 'COMMENT', 'CONTACT', 'DESCRIPTION', 'EXDATE', 'EXRULE',
|
4840 |
+
'FREEBUSY', 'RDATE', 'RELATED-TO', 'RESOURCES', 'RRULE', 'REQUEST-STATUS', 'TZNAME', 'X-PROP' ))) {
|
4841 |
+
if( !$propix )
|
4842 |
+
$propix = ( isset( $this->propdelix[$propName] ) && ( 'X-PROP' != $propName )) ? $this->propdelix[$propName] + 2 : 1;
|
4843 |
+
$this->propdelix[$propName] = --$propix;
|
4844 |
+
}
|
4845 |
+
$return = FALSE;
|
4846 |
+
switch( $propName ) {
|
4847 |
+
case 'ACTION':
|
4848 |
+
if( !empty( $this->action )) {
|
4849 |
+
$this->action = '';
|
4850 |
+
$return = TRUE;
|
4851 |
+
}
|
4852 |
+
break;
|
4853 |
+
case 'ATTACH':
|
4854 |
+
return $this->deletePropertyM( $this->attach, $this->propdelix[$propName] );
|
4855 |
+
break;
|
4856 |
+
case 'ATTENDEE':
|
4857 |
+
return $this->deletePropertyM( $this->attendee, $this->propdelix[$propName] );
|
4858 |
+
break;
|
4859 |
+
case 'CATEGORIES':
|
4860 |
+
return $this->deletePropertyM( $this->categories, $this->propdelix[$propName] );
|
4861 |
+
break;
|
4862 |
+
case 'CLASS':
|
4863 |
+
if( !empty( $this->class )) {
|
4864 |
+
$this->class = '';
|
4865 |
+
$return = TRUE;
|
4866 |
+
}
|
4867 |
+
break;
|
4868 |
+
case 'COMMENT':
|
4869 |
+
return $this->deletePropertyM( $this->comment, $this->propdelix[$propName] );
|
4870 |
+
break;
|
4871 |
+
case 'COMPLETED':
|
4872 |
+
if( !empty( $this->completed )) {
|
4873 |
+
$this->completed = '';
|
4874 |
+
$return = TRUE;
|
4875 |
+
}
|
4876 |
+
break;
|
4877 |
+
case 'CONTACT':
|
4878 |
+
return $this->deletePropertyM( $this->contact, $this->propdelix[$propName] );
|
4879 |
+
break;
|
4880 |
+
case 'CREATED':
|
4881 |
+
if( !empty( $this->created )) {
|
4882 |
+
$this->created = '';
|
4883 |
+
$return = TRUE;
|
4884 |
+
}
|
4885 |
+
break;
|
4886 |
+
case 'DESCRIPTION':
|
4887 |
+
return $this->deletePropertyM( $this->description, $this->propdelix[$propName] );
|
4888 |
+
break;
|
4889 |
+
case 'DTEND':
|
4890 |
+
if( !empty( $this->dtend )) {
|
4891 |
+
$this->dtend = '';
|
4892 |
+
$return = TRUE;
|
4893 |
+
}
|
4894 |
+
break;
|
4895 |
+
case 'DTSTAMP':
|
4896 |
+
if( in_array( $this->objName, array( 'valarm', 'vtimezone', 'standard', 'daylight' )))
|
4897 |
+
return FALSE;
|
4898 |
+
if( !empty( $this->dtstamp )) {
|
4899 |
+
$this->dtstamp = '';
|
4900 |
+
$return = TRUE;
|
4901 |
+
}
|
4902 |
+
break;
|
4903 |
+
case 'DTSTART':
|
4904 |
+
if( !empty( $this->dtstart )) {
|
4905 |
+
$this->dtstart = '';
|
4906 |
+
$return = TRUE;
|
4907 |
+
}
|
4908 |
+
break;
|
4909 |
+
case 'DUE':
|
4910 |
+
if( !empty( $this->due )) {
|
4911 |
+
$this->due = '';
|
4912 |
+
$return = TRUE;
|
4913 |
+
}
|
4914 |
+
break;
|
4915 |
+
case 'DURATION':
|
4916 |
+
if( !empty( $this->duration )) {
|
4917 |
+
$this->duration = '';
|
4918 |
+
$return = TRUE;
|
4919 |
+
}
|
4920 |
+
break;
|
4921 |
+
case 'EXDATE':
|
4922 |
+
return $this->deletePropertyM( $this->exdate, $this->propdelix[$propName] );
|
4923 |
+
break;
|
4924 |
+
case 'EXRULE':
|
4925 |
+
return $this->deletePropertyM( $this->exrule, $this->propdelix[$propName] );
|
4926 |
+
break;
|
4927 |
+
case 'FREEBUSY':
|
4928 |
+
return $this->deletePropertyM( $this->freebusy, $this->propdelix[$propName] );
|
4929 |
+
break;
|
4930 |
+
case 'GEO':
|
4931 |
+
if( !empty( $this->geo )) {
|
4932 |
+
$this->geo = '';
|
4933 |
+
$return = TRUE;
|
4934 |
+
}
|
4935 |
+
break;
|
4936 |
+
case 'LAST-MODIFIED':
|
4937 |
+
if( !empty( $this->lastmodified )) {
|
4938 |
+
$this->lastmodified = '';
|
4939 |
+
$return = TRUE;
|
4940 |
+
}
|
4941 |
+
break;
|
4942 |
+
case 'LOCATION':
|
4943 |
+
if( !empty( $this->location )) {
|
4944 |
+
$this->location = '';
|
4945 |
+
$return = TRUE;
|
4946 |
+
}
|
4947 |
+
break;
|
4948 |
+
case 'ORGANIZER':
|
4949 |
+
if( !empty( $this->organizer )) {
|
4950 |
+
$this->organizer = '';
|
4951 |
+
$return = TRUE;
|
4952 |
+
}
|
4953 |
+
break;
|
4954 |
+
case 'PERCENT-COMPLETE':
|
4955 |
+
if( !empty( $this->percentcomplete )) {
|
4956 |
+
$this->percentcomplete = '';
|
4957 |
+
$return = TRUE;
|
4958 |
+
}
|
4959 |
+
break;
|
4960 |
+
case 'PRIORITY':
|
4961 |
+
if( !empty( $this->priority )) {
|
4962 |
+
$this->priority = '';
|
4963 |
+
$return = TRUE;
|
4964 |
+
}
|
4965 |
+
break;
|
4966 |
+
case 'RDATE':
|
4967 |
+
return $this->deletePropertyM( $this->rdate, $this->propdelix[$propName] );
|
4968 |
+
break;
|
4969 |
+
case 'RECURRENCE-ID':
|
4970 |
+
if( !empty( $this->recurrenceid )) {
|
4971 |
+
$this->recurrenceid = '';
|
4972 |
+
$return = TRUE;
|
4973 |
+
}
|
4974 |
+
break;
|
4975 |
+
case 'RELATED-TO':
|
4976 |
+
return $this->deletePropertyM( $this->relatedto, $this->propdelix[$propName] );
|
4977 |
+
break;
|
4978 |
+
case 'REPEAT':
|
4979 |
+
if( !empty( $this->repeat )) {
|
4980 |
+
$this->repeat = '';
|
4981 |
+
$return = TRUE;
|
4982 |
+
}
|
4983 |
+
break;
|
4984 |
+
case 'REQUEST-STATUS':
|
4985 |
+
return $this->deletePropertyM( $this->requeststatus, $this->propdelix[$propName] );
|
4986 |
+
break;
|
4987 |
+
case 'RESOURCES':
|
4988 |
+
return $this->deletePropertyM( $this->resources, $this->propdelix[$propName] );
|
4989 |
+
break;
|
4990 |
+
case 'RRULE':
|
4991 |
+
return $this->deletePropertyM( $this->rrule, $this->propdelix[$propName] );
|
4992 |
+
break;
|
4993 |
+
case 'SEQUENCE':
|
4994 |
+
if( !empty( $this->sequence )) {
|
4995 |
+
$this->sequence = '';
|
4996 |
+
$return = TRUE;
|
4997 |
+
}
|
4998 |
+
break;
|
4999 |
+
case 'STATUS':
|
5000 |
+
if( !empty( $this->status )) {
|
5001 |
+
$this->status = '';
|
5002 |
+
$return = TRUE;
|
5003 |
+
}
|
5004 |
+
break;
|
5005 |
+
case 'SUMMARY':
|
5006 |
+
if( !empty( $this->summary )) {
|
5007 |
+
$this->summary = '';
|
5008 |
+
$return = TRUE;
|
5009 |
+
}
|
5010 |
+
break;
|
5011 |
+
case 'TRANSP':
|
5012 |
+
if( !empty( $this->transp )) {
|
5013 |
+
$this->transp = '';
|
5014 |
+
$return = TRUE;
|
5015 |
+
}
|
5016 |
+
break;
|
5017 |
+
case 'TRIGGER':
|
5018 |
+
if( !empty( $this->trigger )) {
|
5019 |
+
$this->trigger = '';
|
5020 |
+
$return = TRUE;
|
5021 |
+
}
|
5022 |
+
break;
|
5023 |
+
case 'TZID':
|
5024 |
+
if( !empty( $this->tzid )) {
|
5025 |
+
$this->tzid = '';
|
5026 |
+
$return = TRUE;
|
5027 |
+
}
|
5028 |
+
break;
|
5029 |
+
case 'TZNAME':
|
5030 |
+
return $this->deletePropertyM( $this->tzname, $this->propdelix[$propName] );
|
5031 |
+
break;
|
5032 |
+
case 'TZOFFSETFROM':
|
5033 |
+
if( !empty( $this->tzoffsetfrom )) {
|
5034 |
+
$this->tzoffsetfrom = '';
|
5035 |
+
$return = TRUE;
|
5036 |
+
}
|
5037 |
+
break;
|
5038 |
+
case 'TZOFFSETTO':
|
5039 |
+
if( !empty( $this->tzoffsetto )) {
|
5040 |
+
$this->tzoffsetto = '';
|
5041 |
+
$return = TRUE;
|
5042 |
+
}
|
5043 |
+
break;
|
5044 |
+
case 'TZURL':
|
5045 |
+
if( !empty( $this->tzurl )) {
|
5046 |
+
$this->tzurl = '';
|
5047 |
+
$return = TRUE;
|
5048 |
+
}
|
5049 |
+
break;
|
5050 |
+
case 'UID':
|
5051 |
+
if( in_array( $this->objName, array( 'valarm', 'vtimezone', 'standard', 'daylight' )))
|
5052 |
+
return FALSE;
|
5053 |
+
if( !empty( $this->uid )) {
|
5054 |
+
$this->uid = '';
|
5055 |
+
$return = TRUE;
|
5056 |
+
}
|
5057 |
+
break;
|
5058 |
+
case 'URL':
|
5059 |
+
if( !empty( $this->url )) {
|
5060 |
+
$this->url = '';
|
5061 |
+
$return = TRUE;
|
5062 |
+
}
|
5063 |
+
break;
|
5064 |
+
default:
|
5065 |
+
$reduced = '';
|
5066 |
+
if( $propName != 'X-PROP' ) {
|
5067 |
+
if( !isset( $this->xprop[$propName] )) return FALSE;
|
5068 |
+
foreach( $this->xprop as $k => $a ) {
|
5069 |
+
if(( $k != $propName ) && !empty( $a ))
|
5070 |
+
$reduced[$k] = $a;
|
5071 |
+
}
|
5072 |
+
}
|
5073 |
+
else {
|
5074 |
+
if( count( $this->xprop ) <= $propix ) { unset( $this->propdelix[$propName] ); return FALSE; }
|
5075 |
+
$xpropno = 0;
|
5076 |
+
foreach( $this->xprop as $xpropkey => $xpropvalue ) {
|
5077 |
+
if( $propix != $xpropno )
|
5078 |
+
$reduced[$xpropkey] = $xpropvalue;
|
5079 |
+
$xpropno++;
|
5080 |
+
}
|
5081 |
+
}
|
5082 |
+
$this->xprop = $reduced;
|
5083 |
+
if( empty( $this->xprop )) {
|
5084 |
+
unset( $this->propdelix[$propName] );
|
5085 |
+
return FALSE;
|
5086 |
+
}
|
5087 |
+
return TRUE;
|
5088 |
+
}
|
5089 |
+
return $return;
|
5090 |
+
}
|
5091 |
+
/*********************************************************************************/
|
5092 |
+
/**
|
5093 |
+
* delete component property value, fixing components with multiple occurencies
|
5094 |
+
*
|
5095 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
5096 |
+
* @since 2.8.8 - 2011-03-15
|
5097 |
+
* @param array $multiprop, reference to a component property
|
5098 |
+
* @param int $propix, reference to removal counter
|
5099 |
+
* @return bool TRUE
|
5100 |
+
*/
|
5101 |
+
function deletePropertyM( & $multiprop, & $propix ) {
|
5102 |
+
if( isset( $multiprop[$propix] ))
|
5103 |
+
unset( $multiprop[$propix] );
|
5104 |
+
if( empty( $multiprop )) {
|
5105 |
+
$multiprop = '';
|
5106 |
+
unset( $propix );
|
5107 |
+
return FALSE;
|
5108 |
+
}
|
5109 |
+
else
|
5110 |
+
return TRUE;
|
5111 |
+
}
|
5112 |
+
/**
|
5113 |
+
* get component property value/params
|
5114 |
+
*
|
5115 |
+
* if property has multiply values, consequtive function calls are needed
|
5116 |
+
*
|
5117 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
5118 |
+
* @since 2.9.3 - 2011-05-18
|
5119 |
+
* @param string $propName, optional
|
5120 |
+
* @param int @propix, optional, if specific property is wanted in case of multiply occurences
|
5121 |
+
* @param bool $inclParam=FALSE
|
5122 |
+
* @param bool $specform=FALSE
|
5123 |
+
* @return mixed
|
5124 |
+
*/
|
5125 |
+
function getProperty( $propName=FALSE, $propix=FALSE, $inclParam=FALSE, $specform=FALSE ) {
|
5126 |
+
if( $this->_notExistProp( $propName )) return FALSE;
|
5127 |
+
$propName = ( $propName ) ? strtoupper( $propName ) : 'X-PROP';
|
5128 |
+
if( in_array( $propName, array( 'ATTACH', 'ATTENDEE', 'CATEGORIES', 'COMMENT', 'CONTACT', 'DESCRIPTION', 'EXDATE', 'EXRULE',
|
5129 |
+
'FREEBUSY', 'RDATE', 'RELATED-TO', 'RESOURCES', 'RRULE', 'REQUEST-STATUS', 'TZNAME', 'X-PROP' ))) {
|
5130 |
+
if( !$propix )
|
5131 |
+
$propix = ( isset( $this->propix[$propName] )) ? $this->propix[$propName] + 2 : 1;
|
5132 |
+
$this->propix[$propName] = --$propix;
|
5133 |
+
}
|
5134 |
+
switch( $propName ) {
|
5135 |
+
case 'ACTION':
|
5136 |
+
if( !empty( $this->action['value'] )) return ( $inclParam ) ? $this->action : $this->action['value'];
|
5137 |
+
break;
|
5138 |
+
case 'ATTACH':
|
5139 |
+
while( is_array( $this->attach ) && !isset( $this->attach[$propix] ) && ( 0 < count( $this->attach )) && ( $propix < end( array_keys( $this->attach ))))
|
5140 |
+
$propix++;
|
5141 |
+
if( !isset( $this->attach[$propix] )) { unset( $this->propix[$propName] ); return FALSE; }
|
5142 |
+
return ( $inclParam ) ? $this->attach[$propix] : $this->attach[$propix]['value'];
|
5143 |
+
break;
|
5144 |
+
case 'ATTENDEE':
|
5145 |
+
while( is_array( $this->attendee ) && !isset( $this->attendee[$propix] ) && ( 0 < count( $this->attendee )) && ( $propix < end( array_keys( $this->attendee ))))
|
5146 |
+
$propix++;
|
5147 |
+
if( !isset( $this->attendee[$propix] )) { unset( $this->propix[$propName] ); return FALSE; }
|
5148 |
+
return ( $inclParam ) ? $this->attendee[$propix] : $this->attendee[$propix]['value'];
|
5149 |
+
break;
|
5150 |
+
case 'CATEGORIES':
|
5151 |
+
while( is_array( $this->categories ) && !isset( $this->categories[$propix] ) && ( 0 < count( $this->categories )) && ( $propix < end( array_keys( $this->categories ))))
|
5152 |
+
$propix++;
|
5153 |
+
if( !isset( $this->categories[$propix] )) { unset( $this->propix[$propName] ); return FALSE; }
|
5154 |
+
return ( $inclParam ) ? $this->categories[$propix] : $this->categories[$propix]['value'];
|
5155 |
+
break;
|
5156 |
+
case 'CLASS':
|
5157 |
+
if( !empty( $this->class['value'] )) return ( $inclParam ) ? $this->class : $this->class['value'];
|
5158 |
+
break;
|
5159 |
+
case 'COMMENT':
|
5160 |
+
while( is_array( $this->comment ) && !isset( $this->comment[$propix] ) && ( 0 < count( $this->comment )) && ( $propix < end( array_keys( $this->comment ))))
|
5161 |
+
$propix++;
|
5162 |
+
if( !isset( $this->comment[$propix] )) { unset( $this->propix[$propName] ); return FALSE; }
|
5163 |
+
return ( $inclParam ) ? $this->comment[$propix] : $this->comment[$propix]['value'];
|
5164 |
+
break;
|
5165 |
+
case 'COMPLETED':
|
5166 |
+
if( !empty( $this->completed['value'] )) return ( $inclParam ) ? $this->completed : $this->completed['value'];
|
5167 |
+
break;
|
5168 |
+
case 'CONTACT':
|
5169 |
+
while( is_array( $this->contact ) && !isset( $this->contact[$propix] ) && ( 0 < count( $this->contact )) && ( $propix < end( array_keys( $this->contact ))))
|
5170 |
+
$propix++;
|
5171 |
+
if( !isset( $this->contact[$propix] )) { unset( $this->propix[$propName] ); return FALSE; }
|
5172 |
+
return ( $inclParam ) ? $this->contact[$propix] : $this->contact[$propix]['value'];
|
5173 |
+
break;
|
5174 |
+
case 'CREATED':
|
5175 |
+
if( !empty( $this->created['value'] )) return ( $inclParam ) ? $this->created : $this->created['value'];
|
5176 |
+
break;
|
5177 |
+
case 'DESCRIPTION':
|
5178 |
+
while( is_array( $this->description ) && !isset( $this->description[$propix] ) && ( 0 < count( $this->description )) && ( $propix < end( array_keys( $this->description ))))
|
5179 |
+
$propix++;
|
5180 |
+
if( !isset( $this->description[$propix] )) { unset( $this->propix[$propName] ); return FALSE; }
|
5181 |
+
return ( $inclParam ) ? $this->description[$propix] : $this->description[$propix]['value'];
|
5182 |
+
break;
|
5183 |
+
case 'DTEND':
|
5184 |
+
if( !empty( $this->dtend['value'] )) return ( $inclParam ) ? $this->dtend : $this->dtend['value'];
|
5185 |
+
break;
|
5186 |
+
case 'DTSTAMP':
|
5187 |
+
if( in_array( $this->objName, array( 'valarm', 'vtimezone', 'standard', 'daylight' )))
|
5188 |
+
return;
|
5189 |
+
if( !isset( $this->dtstamp['value'] ))
|
5190 |
+
$this->_makeDtstamp();
|
5191 |
+
return ( $inclParam ) ? $this->dtstamp : $this->dtstamp['value'];
|
5192 |
+
break;
|
5193 |
+
case 'DTSTART':
|
5194 |
+
if( !empty( $this->dtstart['value'] )) return ( $inclParam ) ? $this->dtstart : $this->dtstart['value'];
|
5195 |
+
break;
|
5196 |
+
case 'DUE':
|
5197 |
+
if( !empty( $this->due['value'] )) return ( $inclParam ) ? $this->due : $this->due['value'];
|
5198 |
+
break;
|
5199 |
+
case 'DURATION':
|
5200 |
+
if( !isset( $this->duration['value'] )) return FALSE;
|
5201 |
+
$value = ( $specform && isset( $this->dtstart['value'] ) && isset( $this->duration['value'] )) ? iCalUtilityFunctions::_duration2date( $this->dtstart['value'], $this->duration['value'] ) : $this->duration['value'];
|
5202 |
+
return ( $inclParam ) ? array( 'value' => $value, 'params' => $this->duration['params'] ) : $value;
|
5203 |
+
break;
|
5204 |
+
case 'EXDATE':
|
5205 |
+
while( is_array( $this->exdate ) && !isset( $this->exdate[$propix] ) && ( 0 < count( $this->exdate )) && ( $propix < end( array_keys( $this->exdate ))))
|
5206 |
+
$propix++;
|
5207 |
+
if( !isset( $this->exdate[$propix] )) { unset( $this->propix[$propName] ); return FALSE; }
|
5208 |
+
return ( $inclParam ) ? $this->exdate[$propix] : $this->exdate[$propix]['value'];
|
5209 |
+
break;
|
5210 |
+
case 'EXRULE':
|
5211 |
+
while( is_array( $this->exrule ) && !isset( $this->exrule[$propix] ) && ( 0 < count( $this->exrule )) && ( $propix < end( array_keys( $this->exrule ))))
|
5212 |
+
$propix++;
|
5213 |
+
if( !isset( $this->exrule[$propix] )) { unset( $this->propix[$propName] ); return FALSE; }
|
5214 |
+
return ( $inclParam ) ? $this->exrule[$propix] : $this->exrule[$propix]['value'];
|
5215 |
+
break;
|
5216 |
+
case 'FREEBUSY':
|
5217 |
+
while( is_array( $this->freebusy ) && !isset( $this->freebusy[$propix] ) && ( 0 < count( $this->freebusy )) && ( $propix < end( array_keys( $this->freebusy ))))
|
5218 |
+
$propix++;
|
5219 |
+
if( !isset( $this->freebusy[$propix] )) { unset( $this->propix[$propName] ); return FALSE; }
|
5220 |
+
return ( $inclParam ) ? $this->freebusy[$propix] : $this->freebusy[$propix]['value'];
|
5221 |
+
break;
|
5222 |
+
case 'GEO':
|
5223 |
+
if( !empty( $this->geo['value'] )) return ( $inclParam ) ? $this->geo : $this->geo['value'];
|
5224 |
+
break;
|
5225 |
+
case 'LAST-MODIFIED':
|
5226 |
+
if( !empty( $this->lastmodified['value'] )) return ( $inclParam ) ? $this->lastmodified : $this->lastmodified['value'];
|
5227 |
+
break;
|
5228 |
+
case 'LOCATION':
|
5229 |
+
if( !empty( $this->location['value'] )) return ( $inclParam ) ? $this->location : $this->location['value'];
|
5230 |
+
break;
|
5231 |
+
case 'ORGANIZER':
|
5232 |
+
if( !empty( $this->organizer['value'] )) return ( $inclParam ) ? $this->organizer : $this->organizer['value'];
|
5233 |
+
break;
|
5234 |
+
case 'PERCENT-COMPLETE':
|
5235 |
+
if( !empty( $this->percentcomplete['value'] ) || ( isset( $this->percentcomplete['value'] ) && ( '0' == $this->percentcomplete['value'] ))) return ( $inclParam ) ? $this->percentcomplete : $this->percentcomplete['value'];
|
5236 |
+
break;
|
5237 |
+
case 'PRIORITY':
|
5238 |
+
if( !empty( $this->priority['value'] ) || ( isset( $this->priority['value'] ) && ('0' == $this->priority['value'] ))) return ( $inclParam ) ? $this->priority : $this->priority['value'];
|
5239 |
+
break;
|
5240 |
+
case 'RDATE':
|
5241 |
+
while( is_array( $this->rdate ) && !isset( $this->rdate[$propix] ) && ( 0 < count( $this->rdate )) && ( $propix < end( array_keys( $this->rdate ))))
|
5242 |
+
$propix++;
|
5243 |
+
if( !isset( $this->rdate[$propix] )) { unset( $this->propix[$propName] ); return FALSE; }
|
5244 |
+
return ( $inclParam ) ? $this->rdate[$propix] : $this->rdate[$propix]['value'];
|
5245 |
+
break;
|
5246 |
+
case 'RECURRENCE-ID':
|
5247 |
+
if( !empty( $this->recurrenceid['value'] )) return ( $inclParam ) ? $this->recurrenceid : $this->recurrenceid['value'];
|
5248 |
+
break;
|
5249 |
+
case 'RELATED-TO':
|
5250 |
+
while( is_array( $this->relatedto ) && !isset( $this->relatedto[$propix] ) && ( 0 < count( $this->relatedto )) && ( $propix < end( array_keys( $this->relatedto ))))
|
5251 |
+
$propix++;
|
5252 |
+
if( !isset( $this->relatedto[$propix] )) { unset( $this->propix[$propName] ); return FALSE; }
|
5253 |
+
return ( $inclParam ) ? $this->relatedto[$propix] : $this->relatedto[$propix]['value'];
|
5254 |
+
break;
|
5255 |
+
case 'REPEAT':
|
5256 |
+
if( !empty( $this->repeat['value'] ) || ( isset( $this->repeat['value'] ) && ( '0' == $this->repeat['value'] ))) return ( $inclParam ) ? $this->repeat : $this->repeat['value'];
|
5257 |
+
break;
|
5258 |
+
case 'REQUEST-STATUS':
|
5259 |
+
while( is_array( $this->requeststatus ) && !isset( $this->requeststatus[$propix] ) && ( 0 < count( $this->requeststatus )) && ( $propix < end( array_keys( $this->requeststatus ))))
|
5260 |
+
$propix++;
|
5261 |
+
if( !isset( $this->requeststatus[$propix] )) { unset( $this->propix[$propName] ); return FALSE; }
|
5262 |
+
return ( $inclParam ) ? $this->requeststatus[$propix] : $this->requeststatus[$propix]['value'];
|
5263 |
+
break;
|
5264 |
+
case 'RESOURCES':
|
5265 |
+
while( is_array( $this->resources ) && !isset( $this->resources[$propix] ) && ( 0 < count( $this->resources )) && ( $propix < end( array_keys( $this->resources ))))
|
5266 |
+
$propix++;
|
5267 |
+
if( !isset( $this->resources[$propix] )) { unset( $this->propix[$propName] ); return FALSE; }
|
5268 |
+
return ( $inclParam ) ? $this->resources[$propix] : $this->resources[$propix]['value'];
|
5269 |
+
break;
|
5270 |
+
case 'RRULE':
|
5271 |
+
while( is_array( $this->rrule ) && !isset( $this->rrule[$propix] ) && ( 0 < count( $this->rrule )) && ( $propix < end( array_keys( $this->rrule ))))
|
5272 |
+
$propix++;
|
5273 |
+
if( !isset( $this->rrule[$propix] )) { unset( $this->propix[$propName] ); return FALSE; }
|
5274 |
+
return ( $inclParam ) ? $this->rrule[$propix] : $this->rrule[$propix]['value'];
|
5275 |
+
break;
|
5276 |
+
case 'SEQUENCE':
|
5277 |
+
if( isset( $this->sequence['value'] ) && ( isset( $this->sequence['value'] ) && ( '0' <= $this->sequence['value'] ))) return ( $inclParam ) ? $this->sequence : $this->sequence['value'];
|
5278 |
+
break;
|
5279 |
+
case 'STATUS':
|
5280 |
+
if( !empty( $this->status['value'] )) return ( $inclParam ) ? $this->status : $this->status['value'];
|
5281 |
+
break;
|
5282 |
+
case 'SUMMARY':
|
5283 |
+
if( !empty( $this->summary['value'] )) return ( $inclParam ) ? $this->summary : $this->summary['value'];
|
5284 |
+
break;
|
5285 |
+
case 'TRANSP':
|
5286 |
+
if( !empty( $this->transp['value'] )) return ( $inclParam ) ? $this->transp : $this->transp['value'];
|
5287 |
+
break;
|
5288 |
+
case 'TRIGGER':
|
5289 |
+
if( !empty( $this->trigger['value'] )) return ( $inclParam ) ? $this->trigger : $this->trigger['value'];
|
5290 |
+
break;
|
5291 |
+
case 'TZID':
|
5292 |
+
if( !empty( $this->tzid['value'] )) return ( $inclParam ) ? $this->tzid : $this->tzid['value'];
|
5293 |
+
break;
|
5294 |
+
case 'TZNAME':
|
5295 |
+
while( is_array( $this->tzname ) && !isset( $this->tzname[$propix] ) && ( 0 < count( $this->tzname )) && ( $propix < end( array_keys( $this->tzname ))))
|
5296 |
+
$propix++;
|
5297 |
+
if( !isset( $this->tzname[$propix] )) { unset( $this->propix[$propName] ); return FALSE; }
|
5298 |
+
return ( $inclParam ) ? $this->tzname[$propix] : $this->tzname[$propix]['value'];
|
5299 |
+
break;
|
5300 |
+
case 'TZOFFSETFROM':
|
5301 |
+
if( !empty( $this->tzoffsetfrom['value'] )) return ( $inclParam ) ? $this->tzoffsetfrom : $this->tzoffsetfrom['value'];
|
5302 |
+
break;
|
5303 |
+
case 'TZOFFSETTO':
|
5304 |
+
if( !empty( $this->tzoffsetto['value'] )) return ( $inclParam ) ? $this->tzoffsetto : $this->tzoffsetto['value'];
|
5305 |
+
break;
|
5306 |
+
case 'TZURL':
|
5307 |
+
if( !empty( $this->tzurl['value'] )) return ( $inclParam ) ? $this->tzurl : $this->tzurl['value'];
|
5308 |
+
break;
|
5309 |
+
case 'UID':
|
5310 |
+
if( in_array( $this->objName, array( 'valarm', 'vtimezone', 'standard', 'daylight' )))
|
5311 |
+
return FALSE;
|
5312 |
+
if( empty( $this->uid['value'] ))
|
5313 |
+
$this->_makeuid();
|
5314 |
+
return ( $inclParam ) ? $this->uid : $this->uid['value'];
|
5315 |
+
break;
|
5316 |
+
case 'URL':
|
5317 |
+
if( !empty( $this->url['value'] )) return ( $inclParam ) ? $this->url : $this->url['value'];
|
5318 |
+
break;
|
5319 |
+
default:
|
5320 |
+
if( $propName != 'X-PROP' ) {
|
5321 |
+
if( !isset( $this->xprop[$propName] )) return FALSE;
|
5322 |
+
return ( $inclParam ) ? array( $propName, $this->xprop[$propName] )
|
5323 |
+
: array( $propName, $this->xprop[$propName]['value'] );
|
5324 |
+
}
|
5325 |
+
else {
|
5326 |
+
if( empty( $this->xprop )) return FALSE;
|
5327 |
+
$xpropno = 0;
|
5328 |
+
foreach( $this->xprop as $xpropkey => $xpropvalue ) {
|
5329 |
+
if( $propix == $xpropno )
|
5330 |
+
return ( $inclParam ) ? array( $xpropkey, $this->xprop[$xpropkey] )
|
5331 |
+
: array( $xpropkey, $this->xprop[$xpropkey]['value'] );
|
5332 |
+
else
|
5333 |
+
$xpropno++;
|
5334 |
+
}
|
5335 |
+
return FALSE; // not found ??
|
5336 |
+
}
|
5337 |
+
}
|
5338 |
+
return FALSE;
|
5339 |
+
}
|
5340 |
+
/**
|
5341 |
+
* returns calendar property unique values for 'CATEGORIES', 'RESOURCES' or 'ATTENDEE' and each number of ocurrence
|
5342 |
+
*
|
5343 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
5344 |
+
* @since 2.8.8 - 2011-04-13
|
5345 |
+
* @param string $propName
|
5346 |
+
* @param array $output, incremented result array
|
5347 |
+
*/
|
5348 |
+
function _getProperties( $propName, & $output ) {
|
5349 |
+
if( !in_array( strtoupper( $propName ), array( 'ATTENDEE', 'CATEGORIES', 'RESOURCES' )))
|
5350 |
+
return output;
|
5351 |
+
while( FALSE !== ( $content = $this->getProperty( $propName ))) {
|
5352 |
+
if( is_array( $content )) {
|
5353 |
+
foreach( $content as $part ) {
|
5354 |
+
if( FALSE !== strpos( $part, ',' )) {
|
5355 |
+
$part = explode( ',', $part );
|
5356 |
+
foreach( $part as $thePart ) {
|
5357 |
+
$thePart = trim( $thePart );
|
5358 |
+
if( !empty( $thePart )) {
|
5359 |
+
if( !isset( $output[$thePart] ))
|
5360 |
+
$output[$thePart] = 1;
|
5361 |
+
else
|
5362 |
+
$output[$thePart] += 1;
|
5363 |
+
}
|
5364 |
+
}
|
5365 |
+
}
|
5366 |
+
else {
|
5367 |
+
$part = trim( $part );
|
5368 |
+
if( !isset( $output[$part] ))
|
5369 |
+
$output[$part] = 1;
|
5370 |
+
else
|
5371 |
+
$output[$part] += 1;
|
5372 |
+
}
|
5373 |
+
}
|
5374 |
+
}
|
5375 |
+
elseif( FALSE !== strpos( $content, ',' )) {
|
5376 |
+
$content = explode( ',', $content );
|
5377 |
+
foreach( $content as $thePart ) {
|
5378 |
+
$thePart = trim( $thePart );
|
5379 |
+
if( !empty( $thePart )) {
|
5380 |
+
if( !isset( $output[$thePart] ))
|
5381 |
+
$output[$thePart] = 1;
|
5382 |
+
else
|
5383 |
+
$output[$thePart] += 1;
|
5384 |
+
}
|
5385 |
+
}
|
5386 |
+
}
|
5387 |
+
else {
|
5388 |
+
$content = trim( $content );
|
5389 |
+
if( !empty( $content )) {
|
5390 |
+
if( !isset( $output[$content] ))
|
5391 |
+
$output[$content] = 1;
|
5392 |
+
else
|
5393 |
+
$output[$content] += 1;
|
5394 |
+
}
|
5395 |
+
}
|
5396 |
+
}
|
5397 |
+
ksort( $output );
|
5398 |
+
return $output;
|
5399 |
+
}
|
5400 |
+
/**
|
5401 |
+
* general component property setting
|
5402 |
+
*
|
5403 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
5404 |
+
* @since 2.5.1 - 2008-11-05
|
5405 |
+
* @param mixed $args variable number of function arguments,
|
5406 |
+
* first argument is ALWAYS component name,
|
5407 |
+
* second ALWAYS component value!
|
5408 |
+
* @return void
|
5409 |
+
*/
|
5410 |
+
function setProperty() {
|
5411 |
+
$numargs = func_num_args();
|
5412 |
+
if( 1 > $numargs ) return FALSE;
|
5413 |
+
$arglist = func_get_args();
|
5414 |
+
if( $this->_notExistProp( $arglist[0] )) return FALSE;
|
5415 |
+
if( !$this->getConfig( 'allowEmpty' ) && ( !isset( $arglist[1] ) || empty( $arglist[1] )))
|
5416 |
+
return FALSE;
|
5417 |
+
$arglist[0] = strtoupper( $arglist[0] );
|
5418 |
+
for( $argix=$numargs; $argix < 12; $argix++ ) {
|
5419 |
+
if( !isset( $arglist[$argix] ))
|
5420 |
+
$arglist[$argix] = null;
|
5421 |
+
}
|
5422 |
+
switch( $arglist[0] ) {
|
5423 |
+
case 'ACTION':
|
5424 |
+
return $this->setAction( $arglist[1], $arglist[2] );
|
5425 |
+
case 'ATTACH':
|
5426 |
+
return $this->setAttach( $arglist[1], $arglist[2], $arglist[3] );
|
5427 |
+
case 'ATTENDEE':
|
5428 |
+
return $this->setAttendee( $arglist[1], $arglist[2], $arglist[3] );
|
5429 |
+
case 'CATEGORIES':
|
5430 |
+
return $this->setCategories( $arglist[1], $arglist[2], $arglist[3] );
|
5431 |
+
case 'CLASS':
|
5432 |
+
return $this->setClass( $arglist[1], $arglist[2] );
|
5433 |
+
case 'COMMENT':
|
5434 |
+
return $this->setComment( $arglist[1], $arglist[2], $arglist[3] );
|
5435 |
+
case 'COMPLETED':
|
5436 |
+
return $this->setCompleted( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7] );
|
5437 |
+
case 'CONTACT':
|
5438 |
+
return $this->setContact( $arglist[1], $arglist[2], $arglist[3] );
|
5439 |
+
case 'CREATED':
|
5440 |
+
return $this->setCreated( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7] );
|
5441 |
+
case 'DESCRIPTION':
|
5442 |
+
return $this->setDescription( $arglist[1], $arglist[2], $arglist[3] );
|
5443 |
+
case 'DTEND':
|
5444 |
+
return $this->setDtend( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7], $arglist[8] );
|
5445 |
+
case 'DTSTAMP':
|
5446 |
+
return $this->setDtstamp( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7] );
|
5447 |
+
case 'DTSTART':
|
5448 |
+
return $this->setDtstart( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7], $arglist[8] );
|
5449 |
+
case 'DUE':
|
5450 |
+
return $this->setDue( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7], $arglist[8] );
|
5451 |
+
case 'DURATION':
|
5452 |
+
return $this->setDuration( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6] );
|
5453 |
+
case 'EXDATE':
|
5454 |
+
return $this->setExdate( $arglist[1], $arglist[2], $arglist[3] );
|
5455 |
+
case 'EXRULE':
|
5456 |
+
return $this->setExrule( $arglist[1], $arglist[2], $arglist[3] );
|
5457 |
+
case 'FREEBUSY':
|
5458 |
+
return $this->setFreebusy( $arglist[1], $arglist[2], $arglist[3], $arglist[4] );
|
5459 |
+
case 'GEO':
|
5460 |
+
return $this->setGeo( $arglist[1], $arglist[2], $arglist[3] );
|
5461 |
+
case 'LAST-MODIFIED':
|
5462 |
+
return $this->setLastModified( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7] );
|
5463 |
+
case 'LOCATION':
|
5464 |
+
return $this->setLocation( $arglist[1], $arglist[2] );
|
5465 |
+
case 'ORGANIZER':
|
5466 |
+
return $this->setOrganizer( $arglist[1], $arglist[2] );
|
5467 |
+
case 'PERCENT-COMPLETE':
|
5468 |
+
return $this->setPercentComplete( $arglist[1], $arglist[2] );
|
5469 |
+
case 'PRIORITY':
|
5470 |
+
return $this->setPriority( $arglist[1], $arglist[2] );
|
5471 |
+
case 'RDATE':
|
5472 |
+
return $this->setRdate( $arglist[1], $arglist[2], $arglist[3] );
|
5473 |
+
case 'RECURRENCE-ID':
|
5474 |
+
return $this->setRecurrenceid( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7], $arglist[8] );
|
5475 |
+
case 'RELATED-TO':
|
5476 |
+
return $this->setRelatedTo( $arglist[1], $arglist[2], $arglist[3] );
|
5477 |
+
case 'REPEAT':
|
5478 |
+
return $this->setRepeat( $arglist[1], $arglist[2] );
|
5479 |
+
case 'REQUEST-STATUS':
|
5480 |
+
return $this->setRequestStatus( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5] );
|
5481 |
+
case 'RESOURCES':
|
5482 |
+
return $this->setResources( $arglist[1], $arglist[2], $arglist[3] );
|
5483 |
+
case 'RRULE':
|
5484 |
+
return $this->setRrule( $arglist[1], $arglist[2], $arglist[3] );
|
5485 |
+
case 'SEQUENCE':
|
5486 |
+
return $this->setSequence( $arglist[1], $arglist[2] );
|
5487 |
+
case 'STATUS':
|
5488 |
+
return $this->setStatus( $arglist[1], $arglist[2] );
|
5489 |
+
case 'SUMMARY':
|
5490 |
+
return $this->setSummary( $arglist[1], $arglist[2] );
|
5491 |
+
case 'TRANSP':
|
5492 |
+
return $this->setTransp( $arglist[1], $arglist[2] );
|
5493 |
+
case 'TRIGGER':
|
5494 |
+
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] );
|
5495 |
+
case 'TZID':
|
5496 |
+
return $this->setTzid( $arglist[1], $arglist[2] );
|
5497 |
+
case 'TZNAME':
|
5498 |
+
return $this->setTzname( $arglist[1], $arglist[2], $arglist[3] );
|
5499 |
+
case 'TZOFFSETFROM':
|
5500 |
+
return $this->setTzoffsetfrom( $arglist[1], $arglist[2] );
|
5501 |
+
case 'TZOFFSETTO':
|
5502 |
+
return $this->setTzoffsetto( $arglist[1], $arglist[2] );
|
5503 |
+
case 'TZURL':
|
5504 |
+
return $this->setTzurl( $arglist[1], $arglist[2] );
|
5505 |
+
case 'UID':
|
5506 |
+
return $this->setUid( $arglist[1], $arglist[2] );
|
5507 |
+
case 'URL':
|
5508 |
+
return $this->setUrl( $arglist[1], $arglist[2] );
|
5509 |
+
default:
|
5510 |
+
return $this->setXprop( $arglist[0], $arglist[1], $arglist[2] );
|
5511 |
+
}
|
5512 |
+
return FALSE;
|
5513 |
+
}
|
5514 |
+
/*********************************************************************************/
|
5515 |
+
/**
|
5516 |
+
* parse component unparsed data into properties
|
5517 |
+
*
|
5518 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
5519 |
+
* @since 2.8.2 - 2011-05-21
|
5520 |
+
* @param mixed $unparsedtext, optional, strict rfc2445 formatted, single property string or array of strings
|
5521 |
+
* @return bool FALSE if error occurs during parsing
|
5522 |
+
*
|
5523 |
+
*/
|
5524 |
+
function parse( $unparsedtext=null ) {
|
5525 |
+
if( !empty( $unparsedtext )) {
|
5526 |
+
$nl = $this->getConfig( 'nl' );
|
5527 |
+
if( is_array( $unparsedtext ))
|
5528 |
+
$unparsedtext = implode( '\n'.$nl, $unparsedtext );
|
5529 |
+
/* fix line folding */
|
5530 |
+
$eolchars = array( "\r\n", "\n\r", "\n", "\r" ); // check all line endings
|
5531 |
+
$EOLmark = FALSE;
|
5532 |
+
foreach( $eolchars as $eolchar ) {
|
5533 |
+
if( !$EOLmark && ( FALSE !== strpos( $unparsedtext, $eolchar ))) {
|
5534 |
+
$unparsedtext = str_replace( $eolchar." ", '', $unparsedtext );
|
5535 |
+
$unparsedtext = str_replace( $eolchar."\t", '', $unparsedtext );
|
5536 |
+
if( $eolchar != $nl )
|
5537 |
+
$unparsedtext = str_replace( $eolchar, $nl, $unparsedtext );
|
5538 |
+
$EOLmark = TRUE;
|
5539 |
+
}
|
5540 |
+
}
|
5541 |
+
$tmp = explode( $nl, $unparsedtext );
|
5542 |
+
$unparsedtext = array();
|
5543 |
+
foreach( $tmp as $tmpr )
|
5544 |
+
if( !empty( $tmpr ))
|
5545 |
+
$unparsedtext[] = $tmpr;
|
5546 |
+
}
|
5547 |
+
elseif( !isset( $this->unparsed ))
|
5548 |
+
$unparsedtext = array();
|
5549 |
+
else
|
5550 |
+
$unparsedtext = $this->unparsed;
|
5551 |
+
$this->unparsed = array();
|
5552 |
+
$comp = & $this;
|
5553 |
+
$config = $this->getConfig();
|
5554 |
+
foreach ( $unparsedtext as $line ) {
|
5555 |
+
// echo $comp->objName.": $line<br />"; // test ###
|
5556 |
+
if( in_array( strtoupper( substr( $line, 0, 6 )), array( 'END:VA', 'END:ST', 'END:DA' )))
|
5557 |
+
$this->components[] = $comp->copy();
|
5558 |
+
elseif( 'END:' == strtoupper( substr( $line, 0, 4 )))
|
5559 |
+
break;
|
5560 |
+
elseif( 'BEGIN:VALARM' == strtoupper( substr( $line, 0, 12 )))
|
5561 |
+
$comp = new valarm( $config);
|
5562 |
+
elseif( 'BEGIN:STANDARD' == strtoupper( substr( $line, 0, 14 )))
|
5563 |
+
$comp = new vtimezone( 'standard', $config );
|
5564 |
+
elseif( 'BEGIN:DAYLIGHT' == strtoupper( substr( $line, 0, 14 )))
|
5565 |
+
$comp = new vtimezone( 'daylight', $config );
|
5566 |
+
elseif( 'BEGIN:' == strtoupper( substr( $line, 0, 6 )))
|
5567 |
+
continue;
|
5568 |
+
else {
|
5569 |
+
$comp->unparsed[] = $line;
|
5570 |
+
// echo $comp->objName.": $line<br />\n"; // test ###
|
5571 |
+
}
|
5572 |
+
}
|
5573 |
+
unset( $config );
|
5574 |
+
// echo $this->objName.'<br />'.var_export( $this->unparsed, TRUE )."<br />\n"; // test ###
|
5575 |
+
/* concatenate property values spread over several lines */
|
5576 |
+
$lastix = -1;
|
5577 |
+
$propnames = array( 'action', 'attach', 'attendee', 'categories', 'comment', 'completed'
|
5578 |
+
, 'contact', 'class', 'created', 'description', 'dtend', 'dtstart'
|
5579 |
+
, 'dtstamp', 'due', 'duration', 'exdate', 'exrule', 'freebusy', 'geo'
|
5580 |
+
, 'last-modified', 'location', 'organizer', 'percent-complete'
|
5581 |
+
, 'priority', 'rdate', 'recurrence-id', 'related-to', 'repeat'
|
5582 |
+
, 'request-status', 'resources', 'rrule', 'sequence', 'status'
|
5583 |
+
, 'summary', 'transp', 'trigger', 'tzid', 'tzname', 'tzoffsetfrom'
|
5584 |
+
, 'tzoffsetto', 'tzurl', 'uid', 'url', 'x-' );
|
5585 |
+
$proprows = array();
|
5586 |
+
foreach( $this->unparsed as $line ) {
|
5587 |
+
$newProp = FALSE;
|
5588 |
+
foreach ( $propnames as $propname ) {
|
5589 |
+
if( $propname == strtolower( substr( $line, 0, strlen( $propname )))) {
|
5590 |
+
$newProp = TRUE;
|
5591 |
+
break;
|
5592 |
+
}
|
5593 |
+
}
|
5594 |
+
if( $newProp ) {
|
5595 |
+
if( -1 < $lastix )
|
5596 |
+
$proprows[$lastix] = $proprows[$lastix];
|
5597 |
+
$newProp = FALSE;
|
5598 |
+
$lastix++;
|
5599 |
+
$proprows[$lastix] = $line;
|
5600 |
+
}
|
5601 |
+
else
|
5602 |
+
$proprows[$lastix] .= '!"#¤%&/()=?'.$line;
|
5603 |
+
}
|
5604 |
+
/* parse each property 'line' */
|
5605 |
+
foreach( $proprows as $line ) {
|
5606 |
+
$line = str_replace( '!"#¤%&/()=? ', '', $line );
|
5607 |
+
$line = str_replace( '!"#¤%&/()=?', '', $line );
|
5608 |
+
if( '\n' == substr( $line, -2 ))
|
5609 |
+
$line = substr( $line, 0, strlen( $line ) - 2 );
|
5610 |
+
/* get propname, (problem with x-properties, otherwise in previous loop) */
|
5611 |
+
$cix = $propname = null;
|
5612 |
+
for( $cix=0, $clen = strlen( $line ); $cix < $clen; $cix++ ) {
|
5613 |
+
if( in_array( $line[$cix], array( ':', ';' )))
|
5614 |
+
break;
|
5615 |
+
else {
|
5616 |
+
$propname .= $line[$cix];
|
5617 |
+
}
|
5618 |
+
}
|
5619 |
+
if(( 'x-' == substr( $propname, 0, 2 )) || ( 'X-' == substr( $propname, 0, 2 ))) {
|
5620 |
+
$propname2 = $propname;
|
5621 |
+
$propname = 'X-';
|
5622 |
+
}
|
5623 |
+
/* rest of the line is opt.params and value */
|
5624 |
+
$line = substr( $line, $cix );
|
5625 |
+
/* separate attributes from value */
|
5626 |
+
$attr = array();
|
5627 |
+
$attrix = -1;
|
5628 |
+
$clen = strlen( $line );
|
5629 |
+
for( $cix=0; $cix < $clen; $cix++ ) {
|
5630 |
+
if(( ':' == $line[$cix] ) &&
|
5631 |
+
( '://' != substr( $line, $cix, 3 )) &&
|
5632 |
+
( !in_array( strtolower( substr( $line, $cix - 3, 4 )), array( 'fax:', 'cid:', 'sms:', 'tel:', 'urn:' ))) &&
|
5633 |
+
( !in_array( strtolower( substr( $line, $cix - 4, 5 )), array( 'crid:', 'news:', 'pres:' ))) &&
|
5634 |
+
( 'mailto:' != strtolower( substr( $line, $cix - 6, 7 )))) {
|
5635 |
+
$attrEnd = TRUE;
|
5636 |
+
if(( $cix < ( $clen - 4 )) &&
|
5637 |
+
ctype_digit( substr( $line, $cix+1, 4 ))) { // an URI with a (4pos) portnr??
|
5638 |
+
for( $c2ix = $cix; 3 < $c2ix; $c2ix-- ) {
|
5639 |
+
if( '://' == substr( $line, $c2ix - 2, 3 )) {
|
5640 |
+
$attrEnd = FALSE;
|
5641 |
+
break; // an URI with a portnr!!
|
5642 |
+
}
|
5643 |
+
}
|
5644 |
+
}
|
5645 |
+
if( $attrEnd) {
|
5646 |
+
$line = substr( $line, $cix + 1 );
|
5647 |
+
break;
|
5648 |
+
}
|
5649 |
+
}
|
5650 |
+
if( ';' == $line[$cix] )
|
5651 |
+
$attr[++$attrix] = null;
|
5652 |
+
else
|
5653 |
+
$attr[$attrix] .= $line[$cix];
|
5654 |
+
}
|
5655 |
+
/* make attributes in array format */
|
5656 |
+
$propattr = array();
|
5657 |
+
foreach( $attr as $attribute ) {
|
5658 |
+
$attrsplit = explode( '=', $attribute, 2 );
|
5659 |
+
if( 1 < count( $attrsplit ))
|
5660 |
+
$propattr[$attrsplit[0]] = $attrsplit[1];
|
5661 |
+
else
|
5662 |
+
$propattr[] = $attribute;
|
5663 |
+
}
|
5664 |
+
/* call setProperty( $propname.. . */
|
5665 |
+
switch( strtoupper( $propname )) {
|
5666 |
+
case 'ATTENDEE':
|
5667 |
+
foreach( $propattr as $pix => $attr ) {
|
5668 |
+
$attr2 = explode( ',', $attr );
|
5669 |
+
if( 1 < count( $attr2 ))
|
5670 |
+
$propattr[$pix] = $attr2;
|
5671 |
+
}
|
5672 |
+
$this->setProperty( $propname, $line, $propattr );
|
5673 |
+
break;
|
5674 |
+
case 'CATEGORIES':
|
5675 |
+
case 'RESOURCES':
|
5676 |
+
if( FALSE !== strpos( $line, ',' )) {
|
5677 |
+
$content = explode( ',', $line );
|
5678 |
+
$clen = count( $content );
|
5679 |
+
for( $cix = 0; $cix < $clen; $cix++ ) {
|
5680 |
+
if( "\\" == substr($content[$cix], -1)) {
|
5681 |
+
$content[$cix] .= ','.$content[$cix + 1];
|
5682 |
+
unset($content[$cix + 1]);
|
5683 |
+
$cix++;
|
5684 |
+
}
|
5685 |
+
}
|
5686 |
+
if( 1 < count( $content )) {
|
5687 |
+
$content = array_values( $content );
|
5688 |
+
foreach( $content as $cix => $contentPart )
|
5689 |
+
$content[$cix] = calendarComponent::_strunrep( $contentPart );
|
5690 |
+
$this->setProperty( $propname, $content, $propattr );
|
5691 |
+
break;
|
5692 |
+
}
|
5693 |
+
else
|
5694 |
+
$line = reset( $content );
|
5695 |
+
}
|
5696 |
+
case 'X-':
|
5697 |
+
$propname = ( isset( $propname2 )) ? $propname2 : $propname;
|
5698 |
+
case 'COMMENT':
|
5699 |
+
case 'CONTACT':
|
5700 |
+
case 'DESCRIPTION':
|
5701 |
+
case 'LOCATION':
|
5702 |
+
case 'SUMMARY':
|
5703 |
+
if( empty( $line ))
|
5704 |
+
$propattr = null;
|
5705 |
+
$this->setProperty( $propname, calendarComponent::_strunrep( $line ), $propattr );
|
5706 |
+
unset( $propname2 );
|
5707 |
+
break;
|
5708 |
+
case 'REQUEST-STATUS':
|
5709 |
+
$values = explode( ';', $line, 3 );
|
5710 |
+
$values[1] = ( !isset( $values[1] )) ? null : calendarComponent::_strunrep( $values[1] );
|
5711 |
+
$values[2] = ( !isset( $values[2] )) ? null : calendarComponent::_strunrep( $values[2] );
|
5712 |
+
$this->setProperty( $propname
|
5713 |
+
, $values[0] // statcode
|
5714 |
+
, $values[1] // statdesc
|
5715 |
+
, $values[2] // extdata
|
5716 |
+
, $propattr );
|
5717 |
+
break;
|
5718 |
+
case 'FREEBUSY':
|
5719 |
+
$fbtype = ( isset( $propattr['FBTYPE'] )) ? $propattr['FBTYPE'] : ''; // force setting default, if missing
|
5720 |
+
unset( $propattr['FBTYPE'] );
|
5721 |
+
$values = explode( ',', $line );
|
5722 |
+
foreach( $values as $vix => $value ) {
|
5723 |
+
$value2 = explode( '/', $value );
|
5724 |
+
if( 1 < count( $value2 ))
|
5725 |
+
$values[$vix] = $value2;
|
5726 |
+
}
|
5727 |
+
$this->setProperty( $propname, $fbtype, $values, $propattr );
|
5728 |
+
break;
|
5729 |
+
case 'GEO':
|
5730 |
+
$value = explode( ';', $line, 2 );
|
5731 |
+
if( 2 > count( $value ))
|
5732 |
+
$value[1] = null;
|
5733 |
+
$this->setProperty( $propname, $value[0], $value[1], $propattr );
|
5734 |
+
break;
|
5735 |
+
case 'EXDATE':
|
5736 |
+
$values = ( !empty( $line )) ? explode( ',', $line ) : null;
|
5737 |
+
$this->setProperty( $propname, $values, $propattr );
|
5738 |
+
break;
|
5739 |
+
case 'RDATE':
|
5740 |
+
if( empty( $line )) {
|
5741 |
+
$this->setProperty( $propname, $line, $propattr );
|
5742 |
+
break;
|
5743 |
+
}
|
5744 |
+
$values = explode( ',', $line );
|
5745 |
+
foreach( $values as $vix => $value ) {
|
5746 |
+
$value2 = explode( '/', $value );
|
5747 |
+
if( 1 < count( $value2 ))
|
5748 |
+
$values[$vix] = $value2;
|
5749 |
+
}
|
5750 |
+
$this->setProperty( $propname, $values, $propattr );
|
5751 |
+
break;
|
5752 |
+
case 'EXRULE':
|
5753 |
+
case 'RRULE':
|
5754 |
+
$values = explode( ';', $line );
|
5755 |
+
$recur = array();
|
5756 |
+
foreach( $values as $value2 ) {
|
5757 |
+
if( empty( $value2 ))
|
5758 |
+
continue; // ;-char in ending position ???
|
5759 |
+
$value3 = explode( '=', $value2, 2 );
|
5760 |
+
$rulelabel = strtoupper( $value3[0] );
|
5761 |
+
switch( $rulelabel ) {
|
5762 |
+
case 'BYDAY': {
|
5763 |
+
$value4 = explode( ',', $value3[1] );
|
5764 |
+
if( 1 < count( $value4 )) {
|
5765 |
+
foreach( $value4 as $v5ix => $value5 ) {
|
5766 |
+
$value6 = array();
|
5767 |
+
$dayno = $dayname = null;
|
5768 |
+
$value5 = trim( (string) $value5 );
|
5769 |
+
if(( ctype_alpha( substr( $value5, -1 ))) &&
|
5770 |
+
( ctype_alpha( substr( $value5, -2, 1 )))) {
|
5771 |
+
$dayname = substr( $value5, -2, 2 );
|
5772 |
+
if( 2 < strlen( $value5 ))
|
5773 |
+
$dayno = substr( $value5, 0, ( strlen( $value5 ) - 2 ));
|
5774 |
+
}
|
5775 |
+
if( $dayno )
|
5776 |
+
$value6[] = $dayno;
|
5777 |
+
if( $dayname )
|
5778 |
+
$value6['DAY'] = $dayname;
|
5779 |
+
$value4[$v5ix] = $value6;
|
5780 |
+
}
|
5781 |
+
}
|
5782 |
+
else {
|
5783 |
+
$value4 = array();
|
5784 |
+
$dayno = $dayname = null;
|
5785 |
+
$value5 = trim( (string) $value3[1] );
|
5786 |
+
if(( ctype_alpha( substr( $value5, -1 ))) &&
|
5787 |
+
( ctype_alpha( substr( $value5, -2, 1 )))) {
|
5788 |
+
$dayname = substr( $value5, -2, 2 );
|
5789 |
+
if( 2 < strlen( $value5 ))
|
5790 |
+
$dayno = substr( $value5, 0, ( strlen( $value5 ) - 2 ));
|
5791 |
+
}
|
5792 |
+
if( $dayno )
|
5793 |
+
$value4[] = $dayno;
|
5794 |
+
if( $dayname )
|
5795 |
+
$value4['DAY'] = $dayname;
|
5796 |
+
}
|
5797 |
+
$recur[$rulelabel] = $value4;
|
5798 |
+
break;
|
5799 |
+
}
|
5800 |
+
default: {
|
5801 |
+
$value4 = explode( ',', $value3[1] );
|
5802 |
+
if( 1 < count( $value4 ))
|
5803 |
+
$value3[1] = $value4;
|
5804 |
+
$recur[$rulelabel] = $value3[1];
|
5805 |
+
break;
|
5806 |
+
}
|
5807 |
+
} // end - switch $rulelabel
|
5808 |
+
} // end - foreach( $values.. .
|
5809 |
+
$this->setProperty( $propname, $recur, $propattr );
|
5810 |
+
break;
|
5811 |
+
case 'ACTION':
|
5812 |
+
case 'CLASSIFICATION':
|
5813 |
+
case 'STATUS':
|
5814 |
+
case 'TRANSP':
|
5815 |
+
case 'UID':
|
5816 |
+
case 'TZID':
|
5817 |
+
case 'RELATED-TO':
|
5818 |
+
case 'TZNAME':
|
5819 |
+
$line = calendarComponent::_strunrep( $line );
|
5820 |
+
default:
|
5821 |
+
$this->setProperty( $propname, $line, $propattr );
|
5822 |
+
break;
|
5823 |
+
} // end switch( $propname.. .
|
5824 |
+
} // end - foreach( $proprows.. .
|
5825 |
+
unset( $unparsedtext, $this->unparsed, $proprows );
|
5826 |
+
if( isset( $this->components ) && is_array( $this->components ) && ( 0 < count( $this->components ))) {
|
5827 |
+
$ckeys = array_keys( $this->components );
|
5828 |
+
foreach( $ckeys as $ckey ) {
|
5829 |
+
if( !empty( $this->components[$ckey] ) && !empty( $this->components[$ckey]->unparsed )) {
|
5830 |
+
$this->components[$ckey]->parse();
|
5831 |
+
}
|
5832 |
+
}
|
5833 |
+
}
|
5834 |
+
return TRUE;
|
5835 |
+
}
|
5836 |
+
/*********************************************************************************/
|
5837 |
+
/*********************************************************************************/
|
5838 |
+
/**
|
5839 |
+
* return a copy of this component
|
5840 |
+
*
|
5841 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
5842 |
+
* @since 2.8.8 - 2011-03-15
|
5843 |
+
* @return object
|
5844 |
+
*/
|
5845 |
+
function copy() {
|
5846 |
+
$serialized_contents = serialize( $this );
|
5847 |
+
$copy = unserialize( $serialized_contents );
|
5848 |
+
return $copy;
|
5849 |
+
}
|
5850 |
+
/*********************************************************************************/
|
5851 |
+
/*********************************************************************************/
|
5852 |
+
/**
|
5853 |
+
* delete calendar subcomponent from component container
|
5854 |
+
*
|
5855 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
5856 |
+
* @since 2.8.8 - 2011-03-15
|
5857 |
+
* @param mixed $arg1 ordno / component type / component uid
|
5858 |
+
* @param mixed $arg2 optional, ordno if arg1 = component type
|
5859 |
+
* @return void
|
5860 |
+
*/
|
5861 |
+
function deleteComponent( $arg1, $arg2=FALSE ) {
|
5862 |
+
if( !isset( $this->components )) return FALSE;
|
5863 |
+
$argType = $index = null;
|
5864 |
+
if ( ctype_digit( (string) $arg1 )) {
|
5865 |
+
$argType = 'INDEX';
|
5866 |
+
$index = (int) $arg1 - 1;
|
5867 |
+
}
|
5868 |
+
elseif(( strlen( $arg1 ) <= strlen( 'vfreebusy' )) && ( FALSE === strpos( $arg1, '@' ))) {
|
5869 |
+
$argType = strtolower( $arg1 );
|
5870 |
+
$index = ( !empty( $arg2 ) && ctype_digit( (string) $arg2 )) ? (( int ) $arg2 - 1 ) : 0;
|
5871 |
+
}
|
5872 |
+
$cix2dC = 0;
|
5873 |
+
foreach ( $this->components as $cix => $component) {
|
5874 |
+
if( empty( $component )) continue;
|
5875 |
+
if(( 'INDEX' == $argType ) && ( $index == $cix )) {
|
5876 |
+
unset( $this->components[$cix] );
|
5877 |
+
return TRUE;
|
5878 |
+
}
|
5879 |
+
elseif( $argType == $component->objName ) {
|
5880 |
+
if( $index == $cix2dC ) {
|
5881 |
+
unset( $this->components[$cix] );
|
5882 |
+
return TRUE;
|
5883 |
+
}
|
5884 |
+
$cix2dC++;
|
5885 |
+
}
|
5886 |
+
elseif( !$argType && ($arg1 == $component->getProperty( 'uid' ))) {
|
5887 |
+
unset( $this->components[$cix] );
|
5888 |
+
return TRUE;
|
5889 |
+
}
|
5890 |
+
}
|
5891 |
+
return FALSE;
|
5892 |
+
}
|
5893 |
+
/**
|
5894 |
+
* get calendar component subcomponent from component container
|
5895 |
+
*
|
5896 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
5897 |
+
* @since 2.8.8 - 2011-03-15
|
5898 |
+
* @param mixed $arg1 optional, ordno/component type/ component uid
|
5899 |
+
* @param mixed $arg2 optional, ordno if arg1 = component type
|
5900 |
+
* @return object
|
5901 |
+
*/
|
5902 |
+
function getComponent ( $arg1=FALSE, $arg2=FALSE ) {
|
5903 |
+
if( !isset( $this->components )) return FALSE;
|
5904 |
+
$index = $argType = null;
|
5905 |
+
if ( !$arg1 ) {
|
5906 |
+
$argType = 'INDEX';
|
5907 |
+
$index = $this->compix['INDEX'] =
|
5908 |
+
( isset( $this->compix['INDEX'] )) ? $this->compix['INDEX'] + 1 : 1;
|
5909 |
+
}
|
5910 |
+
elseif ( ctype_digit( (string) $arg1 )) {
|
5911 |
+
$argType = 'INDEX';
|
5912 |
+
$index = (int) $arg1;
|
5913 |
+
unset( $this->compix );
|
5914 |
+
}
|
5915 |
+
elseif(( strlen( $arg1 ) <= strlen( 'vfreebusy' )) && ( FALSE === strpos( $arg1, '@' ))) {
|
5916 |
+
unset( $this->compix['INDEX'] );
|
5917 |
+
$argType = strtolower( $arg1 );
|
5918 |
+
if( !$arg2 )
|
5919 |
+
$index = $this->compix[$argType] = ( isset( $this->compix[$argType] )) ? $this->compix[$argType] + 1 : 1;
|
5920 |
+
else
|
5921 |
+
$index = (int) $arg2;
|
5922 |
+
}
|
5923 |
+
$index -= 1;
|
5924 |
+
$ckeys = array_keys( $this->components );
|
5925 |
+
if( !empty( $index) && ( $index > end( $ckeys )))
|
5926 |
+
return FALSE;
|
5927 |
+
$cix2gC = 0;
|
5928 |
+
foreach( $this->components as $cix => $component ) {
|
5929 |
+
if( empty( $component )) continue;
|
5930 |
+
if(( 'INDEX' == $argType ) && ( $index == $cix ))
|
5931 |
+
return $component->copy();
|
5932 |
+
elseif( $argType == $component->objName ) {
|
5933 |
+
if( $index == $cix2gC )
|
5934 |
+
return $component->copy();
|
5935 |
+
$cix2gC++;
|
5936 |
+
}
|
5937 |
+
elseif( !$argType && ( $arg1 == $component->getProperty( 'uid' )))
|
5938 |
+
return $component->copy();
|
5939 |
+
}
|
5940 |
+
/* not found.. . */
|
5941 |
+
unset( $this->compix );
|
5942 |
+
return false;
|
5943 |
+
}
|
5944 |
+
/**
|
5945 |
+
* add calendar component as subcomponent to container for subcomponents
|
5946 |
+
*
|
5947 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
5948 |
+
* @since 1.x.x - 2007-04-24
|
5949 |
+
* @param object $component calendar component
|
5950 |
+
* @return void
|
5951 |
+
*/
|
5952 |
+
function addSubComponent ( $component ) {
|
5953 |
+
$this->setComponent( $component );
|
5954 |
+
}
|
5955 |
+
/**
|
5956 |
+
* create new calendar component subcomponent, already included within component
|
5957 |
+
*
|
5958 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
5959 |
+
* @since 2.6.33 - 2011-01-03
|
5960 |
+
* @param string $compType subcomponent type
|
5961 |
+
* @return object (reference)
|
5962 |
+
*/
|
5963 |
+
function & newComponent( $compType ) {
|
5964 |
+
$config = $this->getConfig();
|
5965 |
+
$keys = array_keys( $this->components );
|
5966 |
+
$ix = end( $keys) + 1;
|
5967 |
+
switch( strtoupper( $compType )) {
|
5968 |
+
case 'ALARM':
|
5969 |
+
case 'VALARM':
|
5970 |
+
$this->components[$ix] = new valarm( $config );
|
5971 |
+
break;
|
5972 |
+
case 'STANDARD':
|
5973 |
+
array_unshift( $this->components, new vtimezone( 'STANDARD', $config ));
|
5974 |
+
$ix = 0;
|
5975 |
+
break;
|
5976 |
+
case 'DAYLIGHT':
|
5977 |
+
$this->components[$ix] = new vtimezone( 'DAYLIGHT', $config );
|
5978 |
+
break;
|
5979 |
+
default:
|
5980 |
+
return FALSE;
|
5981 |
+
}
|
5982 |
+
return $this->components[$ix];
|
5983 |
+
}
|
5984 |
+
/**
|
5985 |
+
* add calendar component as subcomponent to container for subcomponents
|
5986 |
+
*
|
5987 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
5988 |
+
* @since 2.8.8 - 2011-03-15
|
5989 |
+
* @param object $component calendar component
|
5990 |
+
* @param mixed $arg1 optional, ordno/component type/ component uid
|
5991 |
+
* @param mixed $arg2 optional, ordno if arg1 = component type
|
5992 |
+
* @return bool
|
5993 |
+
*/
|
5994 |
+
function setComponent( $component, $arg1=FALSE, $arg2=FALSE ) {
|
5995 |
+
if( !isset( $this->components )) return FALSE;
|
5996 |
+
$component->setConfig( $this->getConfig(), FALSE, TRUE );
|
5997 |
+
if( !in_array( $component->objName, array( 'valarm', 'vtimezone', 'standard', 'daylight' ))) {
|
5998 |
+
/* make sure dtstamp and uid is set */
|
5999 |
+
$dummy = $component->getProperty( 'dtstamp' );
|
6000 |
+
$dummy = $component->getProperty( 'uid' );
|
6001 |
+
}
|
6002 |
+
if( !$arg1 ) { // plain insert, last in chain
|
6003 |
+
$this->components[] = $component->copy();
|
6004 |
+
return TRUE;
|
6005 |
+
}
|
6006 |
+
$argType = $index = null;
|
6007 |
+
if ( ctype_digit( (string) $arg1 )) { // index insert/replace
|
6008 |
+
$argType = 'INDEX';
|
6009 |
+
$index = (int) $arg1 - 1;
|
6010 |
+
}
|
6011 |
+
elseif( in_array( strtolower( $arg1 ), array( 'vevent', 'vtodo', 'vjournal', 'vfreebusy', 'valarm', 'vtimezone' ))) {
|
6012 |
+
$argType = strtolower( $arg1 );
|
6013 |
+
$index = ( ctype_digit( (string) $arg2 )) ? ((int) $arg2) - 1 : 0;
|
6014 |
+
}
|
6015 |
+
// else if arg1 is set, arg1 must be an UID
|
6016 |
+
$cix2sC = 0;
|
6017 |
+
foreach ( $this->components as $cix => $component2 ) {
|
6018 |
+
if( empty( $component2 )) continue;
|
6019 |
+
if(( 'INDEX' == $argType ) && ( $index == $cix )) { // index insert/replace
|
6020 |
+
$this->components[$cix] = $component->copy();
|
6021 |
+
return TRUE;
|
6022 |
+
}
|
6023 |
+
elseif( $argType == $component2->objName ) { // component Type index insert/replace
|
6024 |
+
if( $index == $cix2sC ) {
|
6025 |
+
$this->components[$cix] = $component->copy();
|
6026 |
+
return TRUE;
|
6027 |
+
}
|
6028 |
+
$cix2sC++;
|
6029 |
+
}
|
6030 |
+
elseif( !$argType && ( $arg1 == $component2->getProperty( 'uid' ))) { // UID insert/replace
|
6031 |
+
$this->components[$cix] = $component->copy();
|
6032 |
+
return TRUE;
|
6033 |
+
}
|
6034 |
+
}
|
6035 |
+
/* arg1=index and not found.. . insert at index .. .*/
|
6036 |
+
if( 'INDEX' == $argType ) {
|
6037 |
+
$this->components[$index] = $component->copy();
|
6038 |
+
ksort( $this->components, SORT_NUMERIC );
|
6039 |
+
}
|
6040 |
+
else /* not found.. . insert last in chain anyway .. .*/
|
6041 |
+
$this->components[] = $component->copy();
|
6042 |
+
return TRUE;
|
6043 |
+
}
|
6044 |
+
/**
|
6045 |
+
* creates formatted output for subcomponents
|
6046 |
+
*
|
6047 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6048 |
+
* @since 2.6.27 - 2010-12-12
|
6049 |
+
* @return string
|
6050 |
+
*/
|
6051 |
+
function createSubComponent() {
|
6052 |
+
$output = null;
|
6053 |
+
foreach( $this->components as $component ) {
|
6054 |
+
if( empty( $component )) continue;
|
6055 |
+
$component->setConfig( $this->getConfig(), FALSE, TRUE );
|
6056 |
+
$output .= $component->createComponent( $this->xcaldecl );
|
6057 |
+
}
|
6058 |
+
return $output;
|
6059 |
+
}
|
6060 |
+
/********************************************************************************/
|
6061 |
+
/**
|
6062 |
+
* break lines at pos 75
|
6063 |
+
*
|
6064 |
+
* Lines of text SHOULD NOT be longer than 75 octets, excluding the line
|
6065 |
+
* break. Long content lines SHOULD be split into a multiple line
|
6066 |
+
* representations using a line "folding" technique. That is, a long
|
6067 |
+
* line can be split between any two characters by inserting a CRLF
|
6068 |
+
* immediately followed by a single linear white space character (i.e.,
|
6069 |
+
* SPACE, US-ASCII decimal 32 or HTAB, US-ASCII decimal 9). Any sequence
|
6070 |
+
* of CRLF followed immediately by a single linear white space character
|
6071 |
+
* is ignored (i.e., removed) when processing the content type.
|
6072 |
+
*
|
6073 |
+
* Edited 2007-08-26 by Anders Litzell, anders@litzell.se to fix bug where
|
6074 |
+
* the reserved expression "\n" in the arg $string could be broken up by the
|
6075 |
+
* folding of lines, causing ambiguity in the return string.
|
6076 |
+
* Fix uses var $breakAtChar=75 and breaks the line at $breakAtChar-1 if need be.
|
6077 |
+
*
|
6078 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6079 |
+
* @since 2.6.13 - 2010-12-06
|
6080 |
+
* @param string $value
|
6081 |
+
* @return string
|
6082 |
+
*/
|
6083 |
+
function _size75( $string ) {
|
6084 |
+
$tmp = $string;
|
6085 |
+
$string = null;
|
6086 |
+
/* if PHP is config with mb_string.. . */
|
6087 |
+
if( defined( MB_OVERLOAD_STRING )) {
|
6088 |
+
$strlen = mb_strlen( $tmp );
|
6089 |
+
while( $strlen > 75 ) {
|
6090 |
+
$breakAtChar = 75;
|
6091 |
+
if( substr( $tmp, ( $breakAtChar - 1 ), strlen( '\n' )) == '\n' )
|
6092 |
+
$breakAtChar = $breakAtChar - 1;
|
6093 |
+
$string .= mb_substr( $tmp, 0, $breakAtChar );
|
6094 |
+
if( '\n' == substr( $string, ( 0 - strlen( '\n' ))))
|
6095 |
+
$string = substr( $string, 0, ( strlen( $string ) - strlen( '\n' )));
|
6096 |
+
if( $this->nl != mb_substr( $string, ( 0 - strlen( $this->nl ))))
|
6097 |
+
$string .= $this->nl;
|
6098 |
+
$tmp = ' '.mb_substr( $tmp, $breakAtChar );
|
6099 |
+
$strlen = mb_strlen( $tmp );
|
6100 |
+
} // end while
|
6101 |
+
if( 0 < $strlen ) {
|
6102 |
+
$string .= $tmp; // the rest
|
6103 |
+
if( '\n' == substr( $string, ( 0 - strlen( '\n' ))))
|
6104 |
+
$string = substr( $string, 0, ( strlen( $string ) - strlen( '\n' )));
|
6105 |
+
if( $this->nl != mb_substr( $string, ( 0 - strlen( $this->nl ))))
|
6106 |
+
$string .= $this->nl;
|
6107 |
+
}
|
6108 |
+
return $string;
|
6109 |
+
}
|
6110 |
+
/* if PHP is not config with mb_string.. . */
|
6111 |
+
$eolcharlen = strlen( '\n' );
|
6112 |
+
while( TRUE ) {
|
6113 |
+
$bytecnt = strlen( $tmp );
|
6114 |
+
$charCnt = $ix = 0;
|
6115 |
+
for( $ix = 0; $ix < $bytecnt; $ix++ ) {
|
6116 |
+
if(( 73 < $charCnt ) && ( '\n' == substr( $tmp, $ix, $eolcharlen ))) {
|
6117 |
+
$ix += $eolcharlen;
|
6118 |
+
break; // break when '\n' and eol
|
6119 |
+
}
|
6120 |
+
elseif( 74 < $charCnt )
|
6121 |
+
break; // always break for-loop here
|
6122 |
+
else {
|
6123 |
+
$byte = ord( $tmp[$ix] );
|
6124 |
+
if ($byte <= 127) { // add a one byte character
|
6125 |
+
$string .= substr( $tmp, $ix, 1 );
|
6126 |
+
$charCnt += 1;
|
6127 |
+
}
|
6128 |
+
else if ($byte >= 194 && $byte <= 223) { // start byte in two byte character
|
6129 |
+
$string .= substr( $tmp, $ix, 2 ); // add a two bytes character
|
6130 |
+
$charCnt += 1;
|
6131 |
+
}
|
6132 |
+
else if ($byte >= 224 && $byte <= 239) { // start byte in three bytes character
|
6133 |
+
$string .= substr( $tmp, $ix, 3 ); // add a three bytes character
|
6134 |
+
$charCnt += 1;
|
6135 |
+
}
|
6136 |
+
else if ($byte >= 240 && $byte <= 244) { // start byte in four bytes character
|
6137 |
+
$string .= substr( $tmp, $ix, 4 ); // add a four bytes character
|
6138 |
+
$charCnt += 1;
|
6139 |
+
}
|
6140 |
+
}
|
6141 |
+
} // end for
|
6142 |
+
if( '\n' == substr( $string, ( 0 - strlen( '\n' ))))
|
6143 |
+
$string = substr( $string, 0, ( strlen( $string ) - strlen( '\n' )));
|
6144 |
+
if( $this->nl != substr( $string, ( 0 - strlen( $this->nl ))))
|
6145 |
+
$string .= $this->nl;
|
6146 |
+
$tmp = substr( $tmp, $ix );
|
6147 |
+
if( empty( $tmp ))
|
6148 |
+
break; // while-loop breakes here
|
6149 |
+
else
|
6150 |
+
$tmp = ' '.$tmp;
|
6151 |
+
} // end while
|
6152 |
+
if( !empty( $tmp )) {
|
6153 |
+
if( '\n' == substr( $string, ( 0 - strlen( '\n' ))))
|
6154 |
+
$string = substr( $string, 0, ( strlen( $string ) - strlen( '\n' ))).$this->nl;
|
6155 |
+
if( $this->nl != substr( $string, ( 0 - strlen( $this->nl ))))
|
6156 |
+
$string .= $this->nl;
|
6157 |
+
}
|
6158 |
+
return $string;
|
6159 |
+
}
|
6160 |
+
/**
|
6161 |
+
* special characters management output
|
6162 |
+
*
|
6163 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6164 |
+
* @since 2.6.15 - 2010-09-24
|
6165 |
+
* @param string $string
|
6166 |
+
* @return string
|
6167 |
+
*/
|
6168 |
+
function _strrep( $string ) {
|
6169 |
+
switch( $this->format ) {
|
6170 |
+
case 'xcal':
|
6171 |
+
$string = str_replace( '\n', $this->nl, $string);
|
6172 |
+
$string = htmlspecialchars( strip_tags( stripslashes( urldecode ( $string ))));
|
6173 |
+
break;
|
6174 |
+
default:
|
6175 |
+
$pos = 0;
|
6176 |
+
$specChars = array( 'n', 'N', 'r', ',', ';' );
|
6177 |
+
while( $pos <= strlen( $string )) {
|
6178 |
+
$pos = strpos( $string, "\\", $pos );
|
6179 |
+
if( FALSE === $pos )
|
6180 |
+
break;
|
6181 |
+
if( !in_array( substr( $string, $pos, 1 ), $specChars )) {
|
6182 |
+
$string = substr( $string, 0, $pos )."\\".substr( $string, ( $pos + 1 ));
|
6183 |
+
$pos += 1;
|
6184 |
+
}
|
6185 |
+
$pos += 1;
|
6186 |
+
}
|
6187 |
+
if( FALSE !== strpos( $string, '"' ))
|
6188 |
+
$string = str_replace('"', "'", $string);
|
6189 |
+
if( FALSE !== strpos( $string, ',' ))
|
6190 |
+
$string = str_replace(',', '\,', $string);
|
6191 |
+
if( FALSE !== strpos( $string, ';' ))
|
6192 |
+
$string = str_replace(';', '\;', $string);
|
6193 |
+
|
6194 |
+
if( FALSE !== strpos( $string, "\r\n" ))
|
6195 |
+
$string = str_replace( "\r\n", '\n', $string);
|
6196 |
+
elseif( FALSE !== strpos( $string, "\r" ))
|
6197 |
+
$string = str_replace( "\r", '\n', $string);
|
6198 |
+
|
6199 |
+
elseif( FALSE !== strpos( $string, "\n" ))
|
6200 |
+
$string = str_replace( "\n", '\n', $string);
|
6201 |
+
|
6202 |
+
if( FALSE !== strpos( $string, '\N' ))
|
6203 |
+
$string = str_replace( '\N', '\n', $string);
|
6204 |
+
// if( FALSE !== strpos( $string, $this->nl ))
|
6205 |
+
$string = str_replace( $this->nl, '\n', $string);
|
6206 |
+
break;
|
6207 |
+
}
|
6208 |
+
return $string;
|
6209 |
+
}
|
6210 |
+
/**
|
6211 |
+
* special characters management input (from iCal file)
|
6212 |
+
*
|
6213 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6214 |
+
* @since 2.6.22 - 2010-10-17
|
6215 |
+
* @param string $string
|
6216 |
+
* @return string
|
6217 |
+
*/
|
6218 |
+
static function _strunrep( $string ) {
|
6219 |
+
$string = str_replace( '\\\\', '\\', $string);
|
6220 |
+
$string = str_replace( '\,', ',', $string);
|
6221 |
+
$string = str_replace( '\;', ';', $string);
|
6222 |
+
// $string = str_replace( '\n', $this->nl, $string); // ??
|
6223 |
+
return $string;
|
6224 |
+
}
|
6225 |
+
}
|
6226 |
+
/*********************************************************************************/
|
6227 |
+
/*********************************************************************************/
|
6228 |
+
/**
|
6229 |
+
* class for calendar component VEVENT
|
6230 |
+
*
|
6231 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6232 |
+
* @since 2.5.1 - 2008-10-12
|
6233 |
+
*/
|
6234 |
+
class vevent extends calendarComponent {
|
6235 |
+
var $attach;
|
6236 |
+
var $attendee;
|
6237 |
+
var $categories;
|
6238 |
+
var $comment;
|
6239 |
+
var $contact;
|
6240 |
+
var $class;
|
6241 |
+
var $created;
|
6242 |
+
var $description;
|
6243 |
+
var $dtend;
|
6244 |
+
var $dtstart;
|
6245 |
+
var $duration;
|
6246 |
+
var $exdate;
|
6247 |
+
var $exrule;
|
6248 |
+
var $geo;
|
6249 |
+
var $lastmodified;
|
6250 |
+
var $location;
|
6251 |
+
var $organizer;
|
6252 |
+
var $priority;
|
6253 |
+
var $rdate;
|
6254 |
+
var $recurrenceid;
|
6255 |
+
var $relatedto;
|
6256 |
+
var $requeststatus;
|
6257 |
+
var $resources;
|
6258 |
+
var $rrule;
|
6259 |
+
var $sequence;
|
6260 |
+
var $status;
|
6261 |
+
var $summary;
|
6262 |
+
var $transp;
|
6263 |
+
var $url;
|
6264 |
+
var $xprop;
|
6265 |
+
// component subcomponents container
|
6266 |
+
var $components;
|
6267 |
+
/**
|
6268 |
+
* constructor for calendar component VEVENT object
|
6269 |
+
*
|
6270 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6271 |
+
* @since 2.8.2 - 2011-05-01
|
6272 |
+
* @param array $config
|
6273 |
+
* @return void
|
6274 |
+
*/
|
6275 |
+
function vevent( $config = array()) {
|
6276 |
+
$this->calendarComponent();
|
6277 |
+
|
6278 |
+
$this->attach = '';
|
6279 |
+
$this->attendee = '';
|
6280 |
+
$this->categories = '';
|
6281 |
+
$this->class = '';
|
6282 |
+
$this->comment = '';
|
6283 |
+
$this->contact = '';
|
6284 |
+
$this->created = '';
|
6285 |
+
$this->description = '';
|
6286 |
+
$this->dtstart = '';
|
6287 |
+
$this->dtend = '';
|
6288 |
+
$this->duration = '';
|
6289 |
+
$this->exdate = '';
|
6290 |
+
$this->exrule = '';
|
6291 |
+
$this->geo = '';
|
6292 |
+
$this->lastmodified = '';
|
6293 |
+
$this->location = '';
|
6294 |
+
$this->organizer = '';
|
6295 |
+
$this->priority = '';
|
6296 |
+
$this->rdate = '';
|
6297 |
+
$this->recurrenceid = '';
|
6298 |
+
$this->relatedto = '';
|
6299 |
+
$this->requeststatus = '';
|
6300 |
+
$this->resources = '';
|
6301 |
+
$this->rrule = '';
|
6302 |
+
$this->sequence = '';
|
6303 |
+
$this->status = '';
|
6304 |
+
$this->summary = '';
|
6305 |
+
$this->transp = '';
|
6306 |
+
$this->url = '';
|
6307 |
+
$this->xprop = '';
|
6308 |
+
|
6309 |
+
$this->components = array();
|
6310 |
+
|
6311 |
+
if( defined( 'ICAL_LANG' ) && !isset( $config['language'] ))
|
6312 |
+
$config['language'] = ICAL_LANG;
|
6313 |
+
if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE;
|
6314 |
+
if( !isset( $config['nl'] )) $config['nl'] = "\r\n";
|
6315 |
+
if( !isset( $config['format'] )) $config['format'] = 'iCal';
|
6316 |
+
if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR;
|
6317 |
+
$this->setConfig( $config );
|
6318 |
+
|
6319 |
+
}
|
6320 |
+
/**
|
6321 |
+
* create formatted output for calendar component VEVENT object instance
|
6322 |
+
*
|
6323 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6324 |
+
* @since 2.5.1 - 2008-11-07
|
6325 |
+
* @param array $xcaldecl
|
6326 |
+
* @return string
|
6327 |
+
*/
|
6328 |
+
function createComponent( &$xcaldecl ) {
|
6329 |
+
$objectname = $this->_createFormat();
|
6330 |
+
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl;
|
6331 |
+
$component .= $this->createUid();
|
6332 |
+
$component .= $this->createDtstamp();
|
6333 |
+
$component .= $this->createAttach();
|
6334 |
+
$component .= $this->createAttendee();
|
6335 |
+
$component .= $this->createCategories();
|
6336 |
+
$component .= $this->createComment();
|
6337 |
+
$component .= $this->createContact();
|
6338 |
+
$component .= $this->createClass();
|
6339 |
+
$component .= $this->createCreated();
|
6340 |
+
$component .= $this->createDescription();
|
6341 |
+
$component .= $this->createDtstart();
|
6342 |
+
$component .= $this->createDtend();
|
6343 |
+
$component .= $this->createDuration();
|
6344 |
+
$component .= $this->createExdate();
|
6345 |
+
$component .= $this->createExrule();
|
6346 |
+
$component .= $this->createGeo();
|
6347 |
+
$component .= $this->createLastModified();
|
6348 |
+
$component .= $this->createLocation();
|
6349 |
+
$component .= $this->createOrganizer();
|
6350 |
+
$component .= $this->createPriority();
|
6351 |
+
$component .= $this->createRdate();
|
6352 |
+
$component .= $this->createRrule();
|
6353 |
+
$component .= $this->createRelatedTo();
|
6354 |
+
$component .= $this->createRequestStatus();
|
6355 |
+
$component .= $this->createRecurrenceid();
|
6356 |
+
$component .= $this->createResources();
|
6357 |
+
$component .= $this->createSequence();
|
6358 |
+
$component .= $this->createStatus();
|
6359 |
+
$component .= $this->createSummary();
|
6360 |
+
$component .= $this->createTransp();
|
6361 |
+
$component .= $this->createUrl();
|
6362 |
+
$component .= $this->createXprop();
|
6363 |
+
$component .= $this->createSubComponent();
|
6364 |
+
$component .= $this->componentEnd1.$objectname.$this->componentEnd2;
|
6365 |
+
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) {
|
6366 |
+
foreach( $this->xcaldecl as $localxcaldecl )
|
6367 |
+
$xcaldecl[] = $localxcaldecl;
|
6368 |
+
}
|
6369 |
+
return $component;
|
6370 |
+
}
|
6371 |
+
}
|
6372 |
+
/*********************************************************************************/
|
6373 |
+
/*********************************************************************************/
|
6374 |
+
/**
|
6375 |
+
* class for calendar component VTODO
|
6376 |
+
*
|
6377 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6378 |
+
* @since 2.5.1 - 2008-10-12
|
6379 |
+
*/
|
6380 |
+
class vtodo extends calendarComponent {
|
6381 |
+
var $attach;
|
6382 |
+
var $attendee;
|
6383 |
+
var $categories;
|
6384 |
+
var $comment;
|
6385 |
+
var $completed;
|
6386 |
+
var $contact;
|
6387 |
+
var $class;
|
6388 |
+
var $created;
|
6389 |
+
var $description;
|
6390 |
+
var $dtstart;
|
6391 |
+
var $due;
|
6392 |
+
var $duration;
|
6393 |
+
var $exdate;
|
6394 |
+
var $exrule;
|
6395 |
+
var $geo;
|
6396 |
+
var $lastmodified;
|
6397 |
+
var $location;
|
6398 |
+
var $organizer;
|
6399 |
+
var $percentcomplete;
|
6400 |
+
var $priority;
|
6401 |
+
var $rdate;
|
6402 |
+
var $recurrenceid;
|
6403 |
+
var $relatedto;
|
6404 |
+
var $requeststatus;
|
6405 |
+
var $resources;
|
6406 |
+
var $rrule;
|
6407 |
+
var $sequence;
|
6408 |
+
var $status;
|
6409 |
+
var $summary;
|
6410 |
+
var $url;
|
6411 |
+
var $xprop;
|
6412 |
+
// component subcomponents container
|
6413 |
+
var $components;
|
6414 |
+
/**
|
6415 |
+
* constructor for calendar component VTODO object
|
6416 |
+
*
|
6417 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6418 |
+
* @since 2.8.2 - 2011-05-01
|
6419 |
+
* @param array $config
|
6420 |
+
* @return void
|
6421 |
+
*/
|
6422 |
+
function vtodo( $config = array()) {
|
6423 |
+
$this->calendarComponent();
|
6424 |
+
|
6425 |
+
$this->attach = '';
|
6426 |
+
$this->attendee = '';
|
6427 |
+
$this->categories = '';
|
6428 |
+
$this->class = '';
|
6429 |
+
$this->comment = '';
|
6430 |
+
$this->completed = '';
|
6431 |
+
$this->contact = '';
|
6432 |
+
$this->created = '';
|
6433 |
+
$this->description = '';
|
6434 |
+
$this->dtstart = '';
|
6435 |
+
$this->due = '';
|
6436 |
+
$this->duration = '';
|
6437 |
+
$this->exdate = '';
|
6438 |
+
$this->exrule = '';
|
6439 |
+
$this->geo = '';
|
6440 |
+
$this->lastmodified = '';
|
6441 |
+
$this->location = '';
|
6442 |
+
$this->organizer = '';
|
6443 |
+
$this->percentcomplete = '';
|
6444 |
+
$this->priority = '';
|
6445 |
+
$this->rdate = '';
|
6446 |
+
$this->recurrenceid = '';
|
6447 |
+
$this->relatedto = '';
|
6448 |
+
$this->requeststatus = '';
|
6449 |
+
$this->resources = '';
|
6450 |
+
$this->rrule = '';
|
6451 |
+
$this->sequence = '';
|
6452 |
+
$this->status = '';
|
6453 |
+
$this->summary = '';
|
6454 |
+
$this->url = '';
|
6455 |
+
$this->xprop = '';
|
6456 |
+
|
6457 |
+
$this->components = array();
|
6458 |
+
|
6459 |
+
if( defined( 'ICAL_LANG' ) && !isset( $config['language'] ))
|
6460 |
+
$config['language'] = ICAL_LANG;
|
6461 |
+
if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE;
|
6462 |
+
if( !isset( $config['nl'] )) $config['nl'] = "\r\n";
|
6463 |
+
if( !isset( $config['format'] )) $config['format'] = 'iCal';
|
6464 |
+
if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR;
|
6465 |
+
$this->setConfig( $config );
|
6466 |
+
|
6467 |
+
}
|
6468 |
+
/**
|
6469 |
+
* create formatted output for calendar component VTODO object instance
|
6470 |
+
*
|
6471 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6472 |
+
* @since 2.5.1 - 2008-11-07
|
6473 |
+
* @param array $xcaldecl
|
6474 |
+
* @return string
|
6475 |
+
*/
|
6476 |
+
function createComponent( &$xcaldecl ) {
|
6477 |
+
$objectname = $this->_createFormat();
|
6478 |
+
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl;
|
6479 |
+
$component .= $this->createUid();
|
6480 |
+
$component .= $this->createDtstamp();
|
6481 |
+
$component .= $this->createAttach();
|
6482 |
+
$component .= $this->createAttendee();
|
6483 |
+
$component .= $this->createCategories();
|
6484 |
+
$component .= $this->createClass();
|
6485 |
+
$component .= $this->createComment();
|
6486 |
+
$component .= $this->createCompleted();
|
6487 |
+
$component .= $this->createContact();
|
6488 |
+
$component .= $this->createCreated();
|
6489 |
+
$component .= $this->createDescription();
|
6490 |
+
$component .= $this->createDtstart();
|
6491 |
+
$component .= $this->createDue();
|
6492 |
+
$component .= $this->createDuration();
|
6493 |
+
$component .= $this->createExdate();
|
6494 |
+
$component .= $this->createExrule();
|
6495 |
+
$component .= $this->createGeo();
|
6496 |
+
$component .= $this->createLastModified();
|
6497 |
+
$component .= $this->createLocation();
|
6498 |
+
$component .= $this->createOrganizer();
|
6499 |
+
$component .= $this->createPercentComplete();
|
6500 |
+
$component .= $this->createPriority();
|
6501 |
+
$component .= $this->createRdate();
|
6502 |
+
$component .= $this->createRelatedTo();
|
6503 |
+
$component .= $this->createRequestStatus();
|
6504 |
+
$component .= $this->createRecurrenceid();
|
6505 |
+
$component .= $this->createResources();
|
6506 |
+
$component .= $this->createRrule();
|
6507 |
+
$component .= $this->createSequence();
|
6508 |
+
$component .= $this->createStatus();
|
6509 |
+
$component .= $this->createSummary();
|
6510 |
+
$component .= $this->createUrl();
|
6511 |
+
$component .= $this->createXprop();
|
6512 |
+
$component .= $this->createSubComponent();
|
6513 |
+
$component .= $this->componentEnd1.$objectname.$this->componentEnd2;
|
6514 |
+
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) {
|
6515 |
+
foreach( $this->xcaldecl as $localxcaldecl )
|
6516 |
+
$xcaldecl[] = $localxcaldecl;
|
6517 |
+
}
|
6518 |
+
return $component;
|
6519 |
+
}
|
6520 |
+
}
|
6521 |
+
/*********************************************************************************/
|
6522 |
+
/*********************************************************************************/
|
6523 |
+
/**
|
6524 |
+
* class for calendar component VJOURNAL
|
6525 |
+
*
|
6526 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6527 |
+
* @since 2.5.1 - 2008-10-12
|
6528 |
+
*/
|
6529 |
+
class vjournal extends calendarComponent {
|
6530 |
+
var $attach;
|
6531 |
+
var $attendee;
|
6532 |
+
var $categories;
|
6533 |
+
var $comment;
|
6534 |
+
var $contact;
|
6535 |
+
var $class;
|
6536 |
+
var $created;
|
6537 |
+
var $description;
|
6538 |
+
var $dtstart;
|
6539 |
+
var $exdate;
|
6540 |
+
var $exrule;
|
6541 |
+
var $lastmodified;
|
6542 |
+
var $organizer;
|
6543 |
+
var $rdate;
|
6544 |
+
var $recurrenceid;
|
6545 |
+
var $relatedto;
|
6546 |
+
var $requeststatus;
|
6547 |
+
var $rrule;
|
6548 |
+
var $sequence;
|
6549 |
+
var $status;
|
6550 |
+
var $summary;
|
6551 |
+
var $url;
|
6552 |
+
var $xprop;
|
6553 |
+
/**
|
6554 |
+
* constructor for calendar component VJOURNAL object
|
6555 |
+
*
|
6556 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6557 |
+
* @since 2.8.2 - 2011-05-01
|
6558 |
+
* @param array $config
|
6559 |
+
* @return void
|
6560 |
+
*/
|
6561 |
+
function vjournal( $config = array()) {
|
6562 |
+
$this->calendarComponent();
|
6563 |
+
|
6564 |
+
$this->attach = '';
|
6565 |
+
$this->attendee = '';
|
6566 |
+
$this->categories = '';
|
6567 |
+
$this->class = '';
|
6568 |
+
$this->comment = '';
|
6569 |
+
$this->contact = '';
|
6570 |
+
$this->created = '';
|
6571 |
+
$this->description = '';
|
6572 |
+
$this->dtstart = '';
|
6573 |
+
$this->exdate = '';
|
6574 |
+
$this->exrule = '';
|
6575 |
+
$this->lastmodified = '';
|
6576 |
+
$this->organizer = '';
|
6577 |
+
$this->rdate = '';
|
6578 |
+
$this->recurrenceid = '';
|
6579 |
+
$this->relatedto = '';
|
6580 |
+
$this->requeststatus = '';
|
6581 |
+
$this->rrule = '';
|
6582 |
+
$this->sequence = '';
|
6583 |
+
$this->status = '';
|
6584 |
+
$this->summary = '';
|
6585 |
+
$this->url = '';
|
6586 |
+
$this->xprop = '';
|
6587 |
+
|
6588 |
+
if( defined( 'ICAL_LANG' ) && !isset( $config['language'] ))
|
6589 |
+
$config['language'] = ICAL_LANG;
|
6590 |
+
if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE;
|
6591 |
+
if( !isset( $config['nl'] )) $config['nl'] = "\r\n";
|
6592 |
+
if( !isset( $config['format'] )) $config['format'] = 'iCal';
|
6593 |
+
if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR;
|
6594 |
+
$this->setConfig( $config );
|
6595 |
+
|
6596 |
+
}
|
6597 |
+
/**
|
6598 |
+
* create formatted output for calendar component VJOURNAL object instance
|
6599 |
+
*
|
6600 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6601 |
+
* @since 2.5.1 - 2008-10-12
|
6602 |
+
* @param array $xcaldecl
|
6603 |
+
* @return string
|
6604 |
+
*/
|
6605 |
+
function createComponent( &$xcaldecl ) {
|
6606 |
+
$objectname = $this->_createFormat();
|
6607 |
+
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl;
|
6608 |
+
$component .= $this->createUid();
|
6609 |
+
$component .= $this->createDtstamp();
|
6610 |
+
$component .= $this->createAttach();
|
6611 |
+
$component .= $this->createAttendee();
|
6612 |
+
$component .= $this->createCategories();
|
6613 |
+
$component .= $this->createClass();
|
6614 |
+
$component .= $this->createComment();
|
6615 |
+
$component .= $this->createContact();
|
6616 |
+
$component .= $this->createCreated();
|
6617 |
+
$component .= $this->createDescription();
|
6618 |
+
$component .= $this->createDtstart();
|
6619 |
+
$component .= $this->createExdate();
|
6620 |
+
$component .= $this->createExrule();
|
6621 |
+
$component .= $this->createLastModified();
|
6622 |
+
$component .= $this->createOrganizer();
|
6623 |
+
$component .= $this->createRdate();
|
6624 |
+
$component .= $this->createRequestStatus();
|
6625 |
+
$component .= $this->createRecurrenceid();
|
6626 |
+
$component .= $this->createRelatedTo();
|
6627 |
+
$component .= $this->createRrule();
|
6628 |
+
$component .= $this->createSequence();
|
6629 |
+
$component .= $this->createStatus();
|
6630 |
+
$component .= $this->createSummary();
|
6631 |
+
$component .= $this->createUrl();
|
6632 |
+
$component .= $this->createXprop();
|
6633 |
+
$component .= $this->componentEnd1.$objectname.$this->componentEnd2;
|
6634 |
+
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) {
|
6635 |
+
foreach( $this->xcaldecl as $localxcaldecl )
|
6636 |
+
$xcaldecl[] = $localxcaldecl;
|
6637 |
+
}
|
6638 |
+
return $component;
|
6639 |
+
}
|
6640 |
+
}
|
6641 |
+
/*********************************************************************************/
|
6642 |
+
/*********************************************************************************/
|
6643 |
+
/**
|
6644 |
+
* class for calendar component VFREEBUSY
|
6645 |
+
*
|
6646 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6647 |
+
* @since 2.5.1 - 2008-10-12
|
6648 |
+
*/
|
6649 |
+
class vfreebusy extends calendarComponent {
|
6650 |
+
var $attendee;
|
6651 |
+
var $comment;
|
6652 |
+
var $contact;
|
6653 |
+
var $dtend;
|
6654 |
+
var $dtstart;
|
6655 |
+
var $duration;
|
6656 |
+
var $freebusy;
|
6657 |
+
var $organizer;
|
6658 |
+
var $requeststatus;
|
6659 |
+
var $url;
|
6660 |
+
var $xprop;
|
6661 |
+
// component subcomponents container
|
6662 |
+
var $components;
|
6663 |
+
/**
|
6664 |
+
* constructor for calendar component VFREEBUSY object
|
6665 |
+
*
|
6666 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6667 |
+
* @since 2.8.2 - 2011-05-01
|
6668 |
+
* @param array $config
|
6669 |
+
* @return void
|
6670 |
+
*/
|
6671 |
+
function vfreebusy( $config = array()) {
|
6672 |
+
$this->calendarComponent();
|
6673 |
+
|
6674 |
+
$this->attendee = '';
|
6675 |
+
$this->comment = '';
|
6676 |
+
$this->contact = '';
|
6677 |
+
$this->dtend = '';
|
6678 |
+
$this->dtstart = '';
|
6679 |
+
$this->duration = '';
|
6680 |
+
$this->freebusy = '';
|
6681 |
+
$this->organizer = '';
|
6682 |
+
$this->requeststatus = '';
|
6683 |
+
$this->url = '';
|
6684 |
+
$this->xprop = '';
|
6685 |
+
|
6686 |
+
if( defined( 'ICAL_LANG' ) && !isset( $config['language'] ))
|
6687 |
+
$config['language'] = ICAL_LANG;
|
6688 |
+
if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE;
|
6689 |
+
if( !isset( $config['nl'] )) $config['nl'] = "\r\n";
|
6690 |
+
if( !isset( $config['format'] )) $config['format'] = 'iCal';
|
6691 |
+
if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR;
|
6692 |
+
$this->setConfig( $config );
|
6693 |
+
|
6694 |
+
}
|
6695 |
+
/**
|
6696 |
+
* create formatted output for calendar component VFREEBUSY object instance
|
6697 |
+
*
|
6698 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6699 |
+
* @since 2.3.1 - 2007-11-19
|
6700 |
+
* @param array $xcaldecl
|
6701 |
+
* @return string
|
6702 |
+
*/
|
6703 |
+
function createComponent( &$xcaldecl ) {
|
6704 |
+
$objectname = $this->_createFormat();
|
6705 |
+
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl;
|
6706 |
+
$component .= $this->createUid();
|
6707 |
+
$component .= $this->createDtstamp();
|
6708 |
+
$component .= $this->createAttendee();
|
6709 |
+
$component .= $this->createComment();
|
6710 |
+
$component .= $this->createContact();
|
6711 |
+
$component .= $this->createDtstart();
|
6712 |
+
$component .= $this->createDtend();
|
6713 |
+
$component .= $this->createDuration();
|
6714 |
+
$component .= $this->createFreebusy();
|
6715 |
+
$component .= $this->createOrganizer();
|
6716 |
+
$component .= $this->createRequestStatus();
|
6717 |
+
$component .= $this->createUrl();
|
6718 |
+
$component .= $this->createXprop();
|
6719 |
+
$component .= $this->componentEnd1.$objectname.$this->componentEnd2;
|
6720 |
+
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) {
|
6721 |
+
foreach( $this->xcaldecl as $localxcaldecl )
|
6722 |
+
$xcaldecl[] = $localxcaldecl;
|
6723 |
+
}
|
6724 |
+
return $component;
|
6725 |
+
}
|
6726 |
+
}
|
6727 |
+
/*********************************************************************************/
|
6728 |
+
/*********************************************************************************/
|
6729 |
+
/**
|
6730 |
+
* class for calendar component VALARM
|
6731 |
+
*
|
6732 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6733 |
+
* @since 2.5.1 - 2008-10-12
|
6734 |
+
*/
|
6735 |
+
class valarm extends calendarComponent {
|
6736 |
+
var $action;
|
6737 |
+
var $attach;
|
6738 |
+
var $attendee;
|
6739 |
+
var $description;
|
6740 |
+
var $duration;
|
6741 |
+
var $repeat;
|
6742 |
+
var $summary;
|
6743 |
+
var $trigger;
|
6744 |
+
var $xprop;
|
6745 |
+
/**
|
6746 |
+
* constructor for calendar component VALARM object
|
6747 |
+
*
|
6748 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6749 |
+
* @since 2.8.2 - 2011-05-01
|
6750 |
+
* @param array $config
|
6751 |
+
* @return void
|
6752 |
+
*/
|
6753 |
+
function valarm( $config = array()) {
|
6754 |
+
$this->calendarComponent();
|
6755 |
+
|
6756 |
+
$this->action = '';
|
6757 |
+
$this->attach = '';
|
6758 |
+
$this->attendee = '';
|
6759 |
+
$this->description = '';
|
6760 |
+
$this->duration = '';
|
6761 |
+
$this->repeat = '';
|
6762 |
+
$this->summary = '';
|
6763 |
+
$this->trigger = '';
|
6764 |
+
$this->xprop = '';
|
6765 |
+
|
6766 |
+
if( defined( 'ICAL_LANG' ) && !isset( $config['language'] ))
|
6767 |
+
$config['language'] = ICAL_LANG;
|
6768 |
+
if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE;
|
6769 |
+
if( !isset( $config['nl'] )) $config['nl'] = "\r\n";
|
6770 |
+
if( !isset( $config['format'] )) $config['format'] = 'iCal';
|
6771 |
+
if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR;
|
6772 |
+
$this->setConfig( $config );
|
6773 |
+
|
6774 |
+
}
|
6775 |
+
/**
|
6776 |
+
* create formatted output for calendar component VALARM object instance
|
6777 |
+
*
|
6778 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6779 |
+
* @since 2.5.1 - 2008-10-22
|
6780 |
+
* @param array $xcaldecl
|
6781 |
+
* @return string
|
6782 |
+
*/
|
6783 |
+
function createComponent( &$xcaldecl ) {
|
6784 |
+
$objectname = $this->_createFormat();
|
6785 |
+
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl;
|
6786 |
+
$component .= $this->createAction();
|
6787 |
+
$component .= $this->createAttach();
|
6788 |
+
$component .= $this->createAttendee();
|
6789 |
+
$component .= $this->createDescription();
|
6790 |
+
$component .= $this->createDuration();
|
6791 |
+
$component .= $this->createRepeat();
|
6792 |
+
$component .= $this->createSummary();
|
6793 |
+
$component .= $this->createTrigger();
|
6794 |
+
$component .= $this->createXprop();
|
6795 |
+
$component .= $this->componentEnd1.$objectname.$this->componentEnd2;
|
6796 |
+
return $component;
|
6797 |
+
}
|
6798 |
+
}
|
6799 |
+
/**********************************************************************************
|
6800 |
+
/*********************************************************************************/
|
6801 |
+
/**
|
6802 |
+
* class for calendar component VTIMEZONE
|
6803 |
+
*
|
6804 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6805 |
+
* @since 2.5.1 - 2008-10-12
|
6806 |
+
*/
|
6807 |
+
class vtimezone extends calendarComponent {
|
6808 |
+
var $timezonetype;
|
6809 |
+
|
6810 |
+
var $comment;
|
6811 |
+
var $dtstart;
|
6812 |
+
var $lastmodified;
|
6813 |
+
var $rdate;
|
6814 |
+
var $rrule;
|
6815 |
+
var $tzid;
|
6816 |
+
var $tzname;
|
6817 |
+
var $tzoffsetfrom;
|
6818 |
+
var $tzoffsetto;
|
6819 |
+
var $tzurl;
|
6820 |
+
var $xprop;
|
6821 |
+
// component subcomponents container
|
6822 |
+
var $components;
|
6823 |
+
/**
|
6824 |
+
* constructor for calendar component VTIMEZONE object
|
6825 |
+
*
|
6826 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6827 |
+
* @since 2.8.2 - 2011-05-01
|
6828 |
+
* @param mixed $timezonetype optional, default FALSE ( STANDARD / DAYLIGHT )
|
6829 |
+
* @param array $config
|
6830 |
+
* @return void
|
6831 |
+
*/
|
6832 |
+
function vtimezone( $timezonetype=FALSE, $config = array()) {
|
6833 |
+
if( is_array( $timezonetype )) {
|
6834 |
+
$config = $timezonetype;
|
6835 |
+
$timezonetype = FALSE;
|
6836 |
+
}
|
6837 |
+
if( !$timezonetype )
|
6838 |
+
$this->timezonetype = 'VTIMEZONE';
|
6839 |
+
else
|
6840 |
+
$this->timezonetype = strtoupper( $timezonetype );
|
6841 |
+
$this->calendarComponent();
|
6842 |
+
|
6843 |
+
$this->comment = '';
|
6844 |
+
$this->dtstart = '';
|
6845 |
+
$this->lastmodified = '';
|
6846 |
+
$this->rdate = '';
|
6847 |
+
$this->rrule = '';
|
6848 |
+
$this->tzid = '';
|
6849 |
+
$this->tzname = '';
|
6850 |
+
$this->tzoffsetfrom = '';
|
6851 |
+
$this->tzoffsetto = '';
|
6852 |
+
$this->tzurl = '';
|
6853 |
+
$this->xprop = '';
|
6854 |
+
|
6855 |
+
$this->components = array();
|
6856 |
+
|
6857 |
+
if( defined( 'ICAL_LANG' ) && !isset( $config['language'] ))
|
6858 |
+
$config['language'] = ICAL_LANG;
|
6859 |
+
if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE;
|
6860 |
+
if( !isset( $config['nl'] )) $config['nl'] = "\r\n";
|
6861 |
+
if( !isset( $config['format'] )) $config['format'] = 'iCal';
|
6862 |
+
if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR;
|
6863 |
+
$this->setConfig( $config );
|
6864 |
+
|
6865 |
+
}
|
6866 |
+
/**
|
6867 |
+
* create formatted output for calendar component VTIMEZONE object instance
|
6868 |
+
*
|
6869 |
+
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
6870 |
+
* @since 2.5.1 - 2008-10-25
|
6871 |
+
* @param array $xcaldecl
|
6872 |
+
* @return string
|
6873 |
+
*/
|
6874 |
+
function createComponent( &$xcaldecl ) {
|
6875 |
+
$objectname = $this->_createFormat();
|
6876 |
+
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl;
|
6877 |
+
$component .= $this->createTzid();
|
6878 |
+
$component .= $this->createLastModified();
|
6879 |
+
$component .= $this->createTzurl();
|
6880 |
+
$component .= $this->createDtstart();
|
6881 |
+
$component .= $this->createTzoffsetfrom();
|
6882 |
+
$component .= $this->createTzoffsetto();
|
6883 |
+
$component .= $this->createComment();
|
6884 |
+
$component .= $this->createRdate();
|
6885 |
+
$component .= $this->createRrule();
|
6886 |
+
$component .= $this->createTzname();
|
6887 |
+
$component .= $this->createXprop();
|
6888 |
+
$component .= $this->createSubComponent();
|
6889 |
+
$component .= $this->componentEnd1.$objectname.$this->componentEnd2;
|
6890 |
+
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) {
|
6891 |
+
foreach( $this->xcaldecl as $localxcaldecl )
|
6892 |
+
$xcaldecl[] = $localxcaldecl;
|
6893 |
+
}
|
6894 |
+
return $component;
|
6895 |
+
}
|
6896 |
+
}
|
6897 |
+
?>
|
lib/iCalcreator-2.10/lgpl.txt
ADDED
@@ -0,0 +1,504 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
GNU LESSER GENERAL PUBLIC LICENSE
|
2 |
+
Version 2.1, February 1999
|
3 |
+
|
4 |
+
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
5 |
+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
6 |
+
Everyone is permitted to copy and distribute verbatim copies
|
7 |
+
of this license document, but changing it is not allowed.
|
8 |
+
|
9 |
+
[This is the first released version of the Lesser GPL. It also counts
|
10 |
+
as the successor of the GNU Library Public License, version 2, hence
|
11 |
+
the version number 2.1.]
|
12 |
+
|
13 |
+
Preamble
|
14 |
+
|
15 |
+
The licenses for most software are designed to take away your
|
16 |
+
freedom to share and change it. By contrast, the GNU General Public
|
17 |
+
Licenses are intended to guarantee your freedom to share and change
|
18 |
+
free software--to make sure the software is free for all its users.
|
19 |
+
|
20 |
+
This license, the Lesser General Public License, applies to some
|
21 |
+
specially designated software packages--typically libraries--of the
|
22 |
+
Free Software Foundation and other authors who decide to use it. You
|
23 |
+
can use it too, but we suggest you first think carefully about whether
|
24 |
+
this license or the ordinary General Public License is the better
|
25 |
+
strategy to use in any particular case, based on the explanations below.
|
26 |
+
|
27 |
+
When we speak of free software, we are referring to freedom of use,
|
28 |
+
not price. Our General Public Licenses are designed to make sure that
|
29 |
+
you have the freedom to distribute copies of free software (and charge
|
30 |
+
for this service if you wish); that you receive source code or can get
|
31 |
+
it if you want it; that you can change the software and use pieces of
|
32 |
+
it in new free programs; and that you are informed that you can do
|
33 |
+
these things.
|
34 |
+
|
35 |
+
To protect your rights, we need to make restrictions that forbid
|
36 |
+
distributors to deny you these rights or to ask you to surrender these
|
37 |
+
rights. These restrictions translate to certain responsibilities for
|
38 |
+
you if you distribute copies of the library or if you modify it.
|
39 |
+
|
40 |
+
For example, if you distribute copies of the library, whether gratis
|
41 |
+
or for a fee, you must give the recipients all the rights that we gave
|
42 |
+
you. You must make sure that they, too, receive or can get the source
|
43 |
+
code. If you link other code with the library, you must provide
|
44 |
+
complete object files to the recipients, so that they can relink them
|
45 |
+
with the library after making changes to the library and recompiling
|
46 |
+
it. And you must show them these terms so they know their rights.
|
47 |
+
|
48 |
+
We protect your rights with a two-step method: (1) we copyright the
|
49 |
+
library, and (2) we offer you this license, which gives you legal
|
50 |
+
permission to copy, distribute and/or modify the library.
|
51 |
+
|
52 |
+
To protect each distributor, we want to make it very clear that
|
53 |
+
there is no warranty for the free library. Also, if the library is
|
54 |
+
modified by someone else and passed on, the recipients should know
|
55 |
+
that what they have is not the original version, so that the original
|
56 |
+
author's reputation will not be affected by problems that might be
|
57 |
+
introduced by others.
|
58 |
+
|
59 |
+
Finally, software patents pose a constant threat to the existence of
|
60 |
+
any free program. We wish to make sure that a company cannot
|
61 |
+
effectively restrict the users of a free program by obtaining a
|
62 |
+
restrictive license from a patent holder. Therefore, we insist that
|
63 |
+
any patent license obtained for a version of the library must be
|
64 |
+
consistent with the full freedom of use specified in this license.
|
65 |
+
|
66 |
+
Most GNU software, including some libraries, is covered by the
|
67 |
+
ordinary GNU General Public License. This license, the GNU Lesser
|
68 |
+
General Public License, applies to certain designated libraries, and
|
69 |
+
is quite different from the ordinary General Public License. We use
|
70 |
+
this license for certain libraries in order to permit linking those
|
71 |
+
libraries into non-free programs.
|
72 |
+
|
73 |
+
When a program is linked with a library, whether statically or using
|
74 |
+
a shared library, the combination of the two is legally speaking a
|
75 |
+
combined work, a derivative of the original library. The ordinary
|
76 |
+
General Public License therefore permits such linking only if the
|
77 |
+
entire combination fits its criteria of freedom. The Lesser General
|
78 |
+
Public License permits more lax criteria for linking other code with
|
79 |
+
the library.
|
80 |
+
|
81 |
+
We call this license the "Lesser" General Public License because it
|
82 |
+
does Less to protect the user's freedom than the ordinary General
|
83 |
+
Public License. It also provides other free software developers Less
|
84 |
+
of an advantage over competing non-free programs. These disadvantages
|
85 |
+
are the reason we use the ordinary General Public License for many
|
86 |
+
libraries. However, the Lesser license provides advantages in certain
|
87 |
+
special circumstances.
|
88 |
+
|
89 |
+
For example, on rare occasions, there may be a special need to
|
90 |
+
encourage the widest possible use of a certain library, so that it becomes
|
91 |
+
a de-facto standard. To achieve this, non-free programs must be
|
92 |
+
allowed to use the library. A more frequent case is that a free
|
93 |
+
library does the same job as widely used non-free libraries. In this
|
94 |
+
case, there is little to gain by limiting the free library to free
|
95 |
+
software only, so we use the Lesser General Public License.
|
96 |
+
|
97 |
+
In other cases, permission to use a particular library in non-free
|
98 |
+
programs enables a greater number of people to use a large body of
|
99 |
+
free software. For example, permission to use the GNU C Library in
|
100 |
+
non-free programs enables many more people to use the whole GNU
|
101 |
+
operating system, as well as its variant, the GNU/Linux operating
|
102 |
+
system.
|
103 |
+
|
104 |
+
Although the Lesser General Public License is Less protective of the
|
105 |
+
users' freedom, it does ensure that the user of a program that is
|
106 |
+
linked with the Library has the freedom and the wherewithal to run
|
107 |
+
that program using a modified version of the Library.
|
108 |
+
|
109 |
+
The precise terms and conditions for copying, distribution and
|
110 |
+
modification follow. Pay close attention to the difference between a
|
111 |
+
"work based on the library" and a "work that uses the library". The
|
112 |
+
former contains code derived from the library, whereas the latter must
|
113 |
+
be combined with the library in order to run.
|
114 |
+
|
115 |
+
GNU LESSER GENERAL PUBLIC LICENSE
|
116 |
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
117 |
+
|
118 |
+
0. This License Agreement applies to any software library or other
|
119 |
+
program which contains a notice placed by the copyright holder or
|
120 |
+
other authorized party saying it may be distributed under the terms of
|
121 |
+
this Lesser General Public License (also called "this License").
|
122 |
+
Each licensee is addressed as "you".
|
123 |
+
|
124 |
+
A "library" means a collection of software functions and/or data
|
125 |
+
prepared so as to be conveniently linked with application programs
|
126 |
+
(which use some of those functions and data) to form executables.
|
127 |
+
|
128 |
+
The "Library", below, refers to any such software library or work
|
129 |
+
which has been distributed under these terms. A "work based on the
|
130 |
+
Library" means either the Library or any derivative work under
|
131 |
+
copyright law: that is to say, a work containing the Library or a
|
132 |
+
portion of it, either verbatim or with modifications and/or translated
|
133 |
+
straightforwardly into another language. (Hereinafter, translation is
|
134 |
+
included without limitation in the term "modification".)
|
135 |
+
|
136 |
+
"Source code" for a work means the preferred form of the work for
|
137 |
+
making modifications to it. For a library, complete source code means
|
138 |
+
all the source code for all modules it contains, plus any associated
|
139 |
+
interface definition files, plus the scripts used to control compilation
|
140 |
+
and installation of the library.
|
141 |
+
|
142 |
+
Activities other than copying, distribution and modification are not
|
143 |
+
covered by this License; they are outside its scope. The act of
|
144 |
+
running a program using the Library is not restricted, and output from
|
145 |
+
such a program is covered only if its contents constitute a work based
|
146 |
+
on the Library (independent of the use of the Library in a tool for
|
147 |
+
writing it). Whether that is true depends on what the Library does
|
148 |
+
and what the program that uses the Library does.
|
149 |
+
|
150 |
+
1. You may copy and distribute verbatim copies of the Library's
|
151 |
+
complete source code as you receive it, in any medium, provided that
|
152 |
+
you conspicuously and appropriately publish on each copy an
|
153 |
+
appropriate copyright notice and disclaimer of warranty; keep intact
|
154 |
+
all the notices that refer to this License and to the absence of any
|
155 |
+
warranty; and distribute a copy of this License along with the
|
156 |
+
Library.
|
157 |
+
|
158 |
+
You may charge a fee for the physical act of transferring a copy,
|
159 |
+
and you may at your option offer warranty protection in exchange for a
|
160 |
+
fee.
|
161 |
+
|
162 |
+
2. You may modify your copy or copies of the Library or any portion
|
163 |
+
of it, thus forming a work based on the Library, and copy and
|
164 |
+
distribute such modifications or work under the terms of Section 1
|
165 |
+
above, provided that you also meet all of these conditions:
|
166 |
+
|
167 |
+
a) The modified work must itself be a software library.
|
168 |
+
|
169 |
+
b) You must cause the files modified to carry prominent notices
|
170 |
+
stating that you changed the files and the date of any change.
|
171 |
+
|
172 |
+
c) You must cause the whole of the work to be licensed at no
|
173 |
+
charge to all third parties under the terms of this License.
|
174 |
+
|
175 |
+
d) If a facility in the modified Library refers to a function or a
|
176 |
+
table of data to be supplied by an application program that uses
|
177 |
+
the facility, other than as an argument passed when the facility
|
178 |
+
is invoked, then you must make a good faith effort to ensure that,
|
179 |
+
in the event an application does not supply such function or
|
180 |
+
table, the facility still operates, and performs whatever part of
|
181 |
+
its purpose remains meaningful.
|
182 |
+
|
183 |
+
(For example, a function in a library to compute square roots has
|
184 |
+
a purpose that is entirely well-defined independent of the
|
185 |
+
application. Therefore, Subsection 2d requires that any
|
186 |
+
application-supplied function or table used by this function must
|
187 |
+
be optional: if the application does not supply it, the square
|
188 |
+
root function must still compute square roots.)
|
189 |
+
|
190 |
+
These requirements apply to the modified work as a whole. If
|
191 |
+
identifiable sections of that work are not derived from the Library,
|
192 |
+
and can be reasonably considered independent and separate works in
|
193 |
+
themselves, then this License, and its terms, do not apply to those
|
194 |
+
sections when you distribute them as separate works. But when you
|
195 |
+
distribute the same sections as part of a whole which is a work based
|
196 |
+
on the Library, the distribution of the whole must be on the terms of
|
197 |
+
this License, whose permissions for other licensees extend to the
|
198 |
+
entire whole, and thus to each and every part regardless of who wrote
|
199 |
+
it.
|
200 |
+
|
201 |
+
Thus, it is not the intent of this section to claim rights or contest
|
202 |
+
your rights to work written entirely by you; rather, the intent is to
|
203 |
+
exercise the right to control the distribution of derivative or
|
204 |
+
collective works based on the Library.
|
205 |
+
|
206 |
+
In addition, mere aggregation of another work not based on the Library
|
207 |
+
with the Library (or with a work based on the Library) on a volume of
|
208 |
+
a storage or distribution medium does not bring the other work under
|
209 |
+
the scope of this License.
|
210 |
+
|
211 |
+
3. You may opt to apply the terms of the ordinary GNU General Public
|
212 |
+
License instead of this License to a given copy of the Library. To do
|
213 |
+
this, you must alter all the notices that refer to this License, so
|
214 |
+
that they refer to the ordinary GNU General Public License, version 2,
|
215 |
+
instead of to this License. (If a newer version than version 2 of the
|
216 |
+
ordinary GNU General Public License has appeared, then you can specify
|
217 |
+
that version instead if you wish.) Do not make any other change in
|
218 |
+
these notices.
|
219 |
+
|
220 |
+
Once this change is made in a given copy, it is irreversible for
|
221 |
+
that copy, so the ordinary GNU General Public License applies to all
|
222 |
+
subsequent copies and derivative works made from that copy.
|
223 |
+
|
224 |
+
This option is useful when you wish to copy part of the code of
|
225 |
+
the Library into a program that is not a library.
|
226 |
+
|
227 |
+
4. You may copy and distribute the Library (or a portion or
|
228 |
+
derivative of it, under Section 2) in object code or executable form
|
229 |
+
under the terms of Sections 1 and 2 above provided that you accompany
|
230 |
+
it with the complete corresponding machine-readable source code, which
|
231 |
+
must be distributed under the terms of Sections 1 and 2 above on a
|
232 |
+
medium customarily used for software interchange.
|
233 |
+
|
234 |
+
If distribution of object code is made by offering access to copy
|
235 |
+
from a designated place, then offering equivalent access to copy the
|
236 |
+
source code from the same place satisfies the requirement to
|
237 |
+
distribute the source code, even though third parties are not
|
238 |
+
compelled to copy the source along with the object code.
|
239 |
+
|
240 |
+
5. A program that contains no derivative of any portion of the
|
241 |
+
Library, but is designed to work with the Library by being compiled or
|
242 |
+
linked with it, is called a "work that uses the Library". Such a
|
243 |
+
work, in isolation, is not a derivative work of the Library, and
|
244 |
+
therefore falls outside the scope of this License.
|
245 |
+
|
246 |
+
However, linking a "work that uses the Library" with the Library
|
247 |
+
creates an executable that is a derivative of the Library (because it
|
248 |
+
contains portions of the Library), rather than a "work that uses the
|
249 |
+
library". The executable is therefore covered by this License.
|
250 |
+
Section 6 states terms for distribution of such executables.
|
251 |
+
|
252 |
+
When a "work that uses the Library" uses material from a header file
|
253 |
+
that is part of the Library, the object code for the work may be a
|
254 |
+
derivative work of the Library even though the source code is not.
|
255 |
+
Whether this is true is especially significant if the work can be
|
256 |
+
linked without the Library, or if the work is itself a library. The
|
257 |
+
threshold for this to be true is not precisely defined by law.
|
258 |
+
|
259 |
+
If such an object file uses only numerical parameters, data
|
260 |
+
structure layouts and accessors, and small macros and small inline
|
261 |
+
functions (ten lines or less in length), then the use of the object
|
262 |
+
file is unrestricted, regardless of whether it is legally a derivative
|
263 |
+
work. (Executables containing this object code plus portions of the
|
264 |
+
Library will still fall under Section 6.)
|
265 |
+
|
266 |
+
Otherwise, if the work is a derivative of the Library, you may
|
267 |
+
distribute the object code for the work under the terms of Section 6.
|
268 |
+
Any executables containing that work also fall under Section 6,
|
269 |
+
whether or not they are linked directly with the Library itself.
|
270 |
+
|
271 |
+
6. As an exception to the Sections above, you may also combine or
|
272 |
+
link a "work that uses the Library" with the Library to produce a
|
273 |
+
work containing portions of the Library, and distribute that work
|
274 |
+
under terms of your choice, provided that the terms permit
|
275 |
+
modification of the work for the customer's own use and reverse
|
276 |
+
engineering for debugging such modifications.
|
277 |
+
|
278 |
+
You must give prominent notice with each copy of the work that the
|
279 |
+
Library is used in it and that the Library and its use are covered by
|
280 |
+
this License. You must supply a copy of this License. If the work
|
281 |
+
during execution displays copyright notices, you must include the
|
282 |
+
copyright notice for the Library among them, as well as a reference
|
283 |
+
directing the user to the copy of this License. Also, you must do one
|
284 |
+
of these things:
|
285 |
+
|
286 |
+
a) Accompany the work with the complete corresponding
|
287 |
+
machine-readable source code for the Library including whatever
|
288 |
+
changes were used in the work (which must be distributed under
|
289 |
+
Sections 1 and 2 above); and, if the work is an executable linked
|
290 |
+
with the Library, with the complete machine-readable "work that
|
291 |
+
uses the Library", as object code and/or source code, so that the
|
292 |
+
user can modify the Library and then relink to produce a modified
|
293 |
+
executable containing the modified Library. (It is understood
|
294 |
+
that the user who changes the contents of definitions files in the
|
295 |
+
Library will not necessarily be able to recompile the application
|
296 |
+
to use the modified definitions.)
|
297 |
+
|
298 |
+
b) Use a suitable shared library mechanism for linking with the
|
299 |
+
Library. A suitable mechanism is one that (1) uses at run time a
|
300 |
+
copy of the library already present on the user's computer system,
|
301 |
+
rather than copying library functions into the executable, and (2)
|
302 |
+
will operate properly with a modified version of the library, if
|
303 |
+
the user installs one, as long as the modified version is
|
304 |
+
interface-compatible with the version that the work was made with.
|
305 |
+
|
306 |
+
c) Accompany the work with a written offer, valid for at
|
307 |
+
least three years, to give the same user the materials
|
308 |
+
specified in Subsection 6a, above, for a charge no more
|
309 |
+
than the cost of performing this distribution.
|
310 |
+
|
311 |
+
d) If distribution of the work is made by offering access to copy
|
312 |
+
from a designated place, offer equivalent access to copy the above
|
313 |
+
specified materials from the same place.
|
314 |
+
|
315 |
+
e) Verify that the user has already received a copy of these
|
316 |
+
materials or that you have already sent this user a copy.
|
317 |
+
|
318 |
+
For an executable, the required form of the "work that uses the
|
319 |
+
Library" must include any data and utility programs needed for
|
320 |
+
reproducing the executable from it. However, as a special exception,
|
321 |
+
the materials to be distributed need not include anything that is
|
322 |
+
normally distributed (in either source or binary form) with the major
|
323 |
+
components (compiler, kernel, and so on) of the operating system on
|
324 |
+
which the executable runs, unless that component itself accompanies
|
325 |
+
the executable.
|
326 |
+
|
327 |
+
It may happen that this requirement contradicts the license
|
328 |
+
restrictions of other proprietary libraries that do not normally
|
329 |
+
accompany the operating system. Such a contradiction means you cannot
|
330 |
+
use both them and the Library together in an executable that you
|
331 |
+
distribute.
|
332 |
+
|
333 |
+
7. You may place library facilities that are a work based on the
|
334 |
+
Library side-by-side in a single library together with other library
|
335 |
+
facilities not covered by this License, and distribute such a combined
|
336 |
+
library, provided that the separate distribution of the work based on
|
337 |
+
the Library and of the other library facilities is otherwise
|
338 |
+
permitted, and provided that you do these two things:
|
339 |
+
|
340 |
+
a) Accompany the combined library with a copy of the same work
|
341 |
+
based on the Library, uncombined with any other library
|
342 |
+
facilities. This must be distributed under the terms of the
|
343 |
+
Sections above.
|
344 |
+
|
345 |
+
b) Give prominent notice with the combined library of the fact
|
346 |
+
that part of it is a work based on the Library, and explaining
|
347 |
+
where to find the accompanying uncombined form of the same work.
|
348 |
+
|
349 |
+
8. You may not copy, modify, sublicense, link with, or distribute
|
350 |
+
the Library except as expressly provided under this License. Any
|
351 |
+
attempt otherwise to copy, modify, sublicense, link with, or
|
352 |
+
distribute the Library is void, and will automatically terminate your
|
353 |
+
rights under this License. However, parties who have received copies,
|
354 |
+
or rights, from you under this License will not have their licenses
|
355 |
+
terminated so long as such parties remain in full compliance.
|
356 |
+
|
357 |
+
9. You are not required to accept this License, since you have not
|
358 |
+
signed it. However, nothing else grants you permission to modify or
|
359 |
+
distribute the Library or its derivative works. These actions are
|
360 |
+
prohibited by law if you do not accept this License. Therefore, by
|
361 |
+
modifying or distributing the Library (or any work based on the
|
362 |
+
Library), you indicate your acceptance of this License to do so, and
|
363 |
+
all its terms and conditions for copying, distributing or modifying
|
364 |
+
the Library or works based on it.
|
365 |
+
|
366 |
+
10. Each time you redistribute the Library (or any work based on the
|
367 |
+
Library), the recipient automatically receives a license from the
|
368 |
+
original licensor to copy, distribute, link with or modify the Library
|
369 |
+
subject to these terms and conditions. You may not impose any further
|
370 |
+
restrictions on the recipients' exercise of the rights granted herein.
|
371 |
+
You are not responsible for enforcing compliance by third parties with
|
372 |
+
this License.
|
373 |
+
|
374 |
+
11. If, as a consequence of a court judgment or allegation of patent
|
375 |
+
infringement or for any other reason (not limited to patent issues),
|
376 |
+
conditions are imposed on you (whether by court order, agreement or
|
377 |
+
otherwise) that contradict the conditions of this License, they do not
|
378 |
+
excuse you from the conditions of this License. If you cannot
|
379 |
+
distribute so as to satisfy simultaneously your obligations under this
|
380 |
+
License and any other pertinent obligations, then as a consequence you
|
381 |
+
may not distribute the Library at all. For example, if a patent
|
382 |
+
license would not permit royalty-free redistribution of the Library by
|
383 |
+
all those who receive copies directly or indirectly through you, then
|
384 |
+
the only way you could satisfy both it and this License would be to
|
385 |
+
refrain entirely from distribution of the Library.
|
386 |
+
|
387 |
+
If any portion of this section is held invalid or unenforceable under any
|
388 |
+
particular circumstance, the balance of the section is intended to apply,
|
389 |
+
and the section as a whole is intended to apply in other circumstances.
|
390 |
+
|
391 |
+
It is not the purpose of this section to induce you to infringe any
|
392 |
+
patents or other property right claims or to contest validity of any
|
393 |
+
such claims; this section has the sole purpose of protecting the
|
394 |
+
integrity of the free software distribution system which is
|
395 |
+
implemented by public license practices. Many people have made
|
396 |
+
generous contributions to the wide range of software distributed
|
397 |
+
through that system in reliance on consistent application of that
|
398 |
+
system; it is up to the author/donor to decide if he or she is willing
|
399 |
+
to distribute software through any other system and a licensee cannot
|
400 |
+
impose that choice.
|
401 |
+
|
402 |
+
This section is intended to make thoroughly clear what is believed to
|
403 |
+
be a consequence of the rest of this License.
|
404 |
+
|
405 |
+
12. If the distribution and/or use of the Library is restricted in
|
406 |
+
certain countries either by patents or by copyrighted interfaces, the
|
407 |
+
original copyright holder who places the Library under this License may add
|
408 |
+
an explicit geographical distribution limitation excluding those countries,
|
409 |
+
so that distribution is permitted only in or among countries not thus
|
410 |
+
excluded. In such case, this License incorporates the limitation as if
|
411 |
+
written in the body of this License.
|
412 |
+
|
413 |
+
13. The Free Software Foundation may publish revised and/or new
|
414 |
+
versions of the Lesser General Public License from time to time.
|
415 |
+
Such new versions will be similar in spirit to the present version,
|
416 |
+
but may differ in detail to address new problems or concerns.
|
417 |
+
|
418 |
+
Each version is given a distinguishing version number. If the Library
|
419 |
+
specifies a version number of this License which applies to it and
|
420 |
+
"any later version", you have the option of following the terms and
|
421 |
+
conditions either of that version or of any later version published by
|
422 |
+
the Free Software Foundation. If the Library does not specify a
|
423 |
+
license version number, you may choose any version ever published by
|
424 |
+
the Free Software Foundation.
|
425 |
+
|
426 |
+
14. If you wish to incorporate parts of the Library into other free
|
427 |
+
programs whose distribution conditions are incompatible with these,
|
428 |
+
write to the author to ask for permission. For software which is
|
429 |
+
copyrighted by the Free Software Foundation, write to the Free
|
430 |
+
Software Foundation; we sometimes make exceptions for this. Our
|
431 |
+
decision will be guided by the two goals of preserving the free status
|
432 |
+
of all derivatives of our free software and of promoting the sharing
|
433 |
+
and reuse of software generally.
|
434 |
+
|
435 |
+
NO WARRANTY
|
436 |
+
|
437 |
+
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
438 |
+
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
439 |
+
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
440 |
+
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
441 |
+
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
442 |
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
443 |
+
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
444 |
+
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
445 |
+
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
446 |
+
|
447 |
+
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
448 |
+
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
449 |
+
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
450 |
+
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
451 |
+
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
452 |
+
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
453 |
+
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
454 |
+
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
455 |
+
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
456 |
+
DAMAGES.
|
457 |
+
|
458 |
+
END OF TERMS AND CONDITIONS
|
459 |
+
|
460 |
+
How to Apply These Terms to Your New Libraries
|
461 |
+
|
462 |
+
If you develop a new library, and you want it to be of the greatest
|
463 |
+
possible use to the public, we recommend making it free software that
|
464 |
+
everyone can redistribute and change. You can do so by permitting
|
465 |
+
redistribution under these terms (or, alternatively, under the terms of the
|
466 |
+
ordinary General Public License).
|
467 |
+
|
468 |
+
To apply these terms, attach the following notices to the library. It is
|
469 |
+
safest to attach them to the start of each source file to most effectively
|
470 |
+
convey the exclusion of warranty; and each file should have at least the
|
471 |
+
"copyright" line and a pointer to where the full notice is found.
|
472 |
+
|
473 |
+
<one line to give the library's name and a brief idea of what it does.>
|
474 |
+
Copyright (C) <year> <name of author>
|
475 |
+
|
476 |
+
This library is free software; you can redistribute it and/or
|
477 |
+
modify it under the terms of the GNU Lesser General Public
|
478 |
+
License as published by the Free Software Foundation; either
|
479 |
+
version 2.1 of the License, or (at your option) any later version.
|
480 |
+
|
481 |
+
This library is distributed in the hope that it will be useful,
|
482 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
483 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
484 |
+
Lesser General Public License for more details.
|
485 |
+
|
486 |
+
You should have received a copy of the GNU Lesser General Public
|
487 |
+
License along with this library; if not, write to the Free Software
|
488 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
489 |
+
|
490 |
+
Also add information on how to contact you by electronic and paper mail.
|
491 |
+
|
492 |
+
You should also get your employer (if you work as a programmer) or your
|
493 |
+
school, if any, to sign a "copyright disclaimer" for the library, if
|
494 |
+
necessary. Here is a sample; alter the names:
|
495 |
+
|
496 |
+
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
497 |
+
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
498 |
+
|
499 |
+
<signature of Ty Coon>, 1 April 1990
|
500 |
+
Ty Coon, President of Vice
|
501 |
+
|
502 |
+
That's all there is to it!
|
503 |
+
|
504 |
+
|
lib/iCalcreator-2.10/releaseNotes-2.10.txt
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
2.8.1 ######################
|
2 |
+
calendar property VERSION always first
|
3 |
+
|
4 |
+
2.8.2 ###################### / thanks Alvin and Jorge L P
|
5 |
+
function parse on calendar and component level
|
6 |
+
updated management of line folding
|
7 |
+
|
8 |
+
2.8.3 ######################
|
9 |
+
updated using.html, datetime parameter tz
|
10 |
+
|
11 |
+
2.8.4 ######################
|
12 |
+
updated function sort
|
13 |
+
allow sorting on Attendee, Categories, DTSTAMP, Location, Organizer, Priority, Resources, Status, Summary
|
14 |
+
|
15 |
+
2.8.5 ######################
|
16 |
+
function SelectComponents
|
17 |
+
allow select of calendar component properties,
|
18 |
+
function argument array( <propertyName> => <propertyValue>)
|
19 |
+
propertyName = 'Attendee'/'Categories'/'Location'/'Organizer'/'Priority'/'Resources'/'Status'/'Summary'/'UID'
|
20 |
+
propertyValue = (string) propertyValue / (array) ( propertyValue *[, propertyValue] )
|
21 |
+
|
22 |
+
2.8.6 ######################
|
23 |
+
function getProperty on calendar level
|
24 |
+
new arguments: 'DTSTART', 'Attendee', 'Categories', 'Location', 'Organizer', 'Priority', 'Resources', 'Status', 'Summary', 'UID' or 'Recurrence-id-uid'
|
25 |
+
Returns unique property values+counts from all calendar components,
|
26 |
+
output format: array(*[<uniquePropertyValue> => occurr_cnt])
|
27 |
+
|
28 |
+
2.8.7 ######################
|
29 |
+
bug in function iCalUtilityFunctions::_duration2date fixed
|
30 |
+
|
31 |
+
2.8.8 ######################
|
32 |
+
updated functions getProperty and deleteProperty
|
33 |
+
management of properties with multiple ocurrence
|
34 |
+
|
35 |
+
2.8.9 ###################### / thanks Jorge L P
|
36 |
+
bug in function SelectComponents
|
37 |
+
regarding X-CURRENT-*-values
|
38 |
+
|
39 |
+
2.8.10 ######################
|
40 |
+
bug in function setFreebusy
|
41 |
+
if property is empty.. .
|
42 |
+
|
43 |
+
2.9.1 ######################
|
44 |
+
consecutive calls with UID as argument,
|
45 |
+
function (calendar) getComponent
|
46 |
+
new argument, array( *[propertyName => propertyValue] )
|
47 |
+
|
48 |
+
2.9.2 ######################
|
49 |
+
Simple create of timezone (including standard/daylight) component
|
50 |
+
New function in iCalUtilityFunctions:createTimezone (, offsetSec2His)
|
51 |
+
|
52 |
+
2.9.3 ###################### / thanks Jorge L P
|
53 |
+
Management of properties with numeric (integer) content,
|
54 |
+
PERCENT-COMPLETE, PRIORITY, REPEAT, SEQUENCE, X-PROP
|
55 |
+
uppdate of get- and setfunctions
|
56 |
+
|
57 |
+
2.9.4 ###################### / thanks Jorge L P
|
58 |
+
update of function parse on calendar level
|
59 |
+
|
60 |
+
2.9.5 ######################
|
61 |
+
update of function parse on calendar and component level level
|
62 |
+
set config when creating new component
|
63 |
+
|
64 |
+
2.9.6 ######################
|
65 |
+
auto completion of (default) timezone when setting DTEND, DTSTART, DUE, RECURRENCE-ID
|
66 |
+
update of setfunctions for DTEND, DTSTART, DUE, RECURRENCE-ID
|
67 |
+
update of getConfig and all config setting on calendar and component level
|
68 |
+
|
69 |
+
2.9.7 ###################### / thanks Dan
|
70 |
+
bug in function selectComponents - sourceforge ID: 3307044
|
71 |
+
|
72 |
+
2.9.8 ###################### / thanks Jorge L P
|
73 |
+
bug in function createAttendee
|
74 |
+
|
75 |
+
2.9.9 ###################### / thanks Jorge L P
|
76 |
+
bug in iCalUtilityFunctions:_format_duration, TRIGGER with no duration
|
77 |
+
|
78 |
+
2.9.10 ###################### / thanks Andrew
|
79 |
+
Bug in iCalUtilityFunctions::_recur2date (, _setRexrule), BYSETPOS
|
80 |
+
|
81 |
+
2.9.12 ###################### / thanks Joc
|
82 |
+
function returnCalendar, new arguments for utf8 encoding and gzencode
|
lib/iCalcreator-2.10/summary.html
ADDED
@@ -0,0 +1,283 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
|
2 |
+
"http://www.w3.org/TR/html4/frameset.dtd">
|
3 |
+
<html>
|
4 |
+
<head>
|
5 |
+
<title>iCalcreator 2.10 summary</title>
|
6 |
+
<meta name="author" content="Kjell-Inge Gustafsson - kigkonsult" />
|
7 |
+
<meta name="copyright" content="2007-2011 Kjell-Inge Gustafsson - kigkonsult" />
|
8 |
+
<meta name="keywords" content="ical, calendar, calender, xcal, xml, icalender, rfc2445, vcalender, php, create" />
|
9 |
+
<meta name="description" content="iCalcreator" />
|
10 |
+
<style type="text/css">
|
11 |
+
body {
|
12 |
+
FONT-FAMILY : "Lucida Grande","Lucida Sans Unicode", "Bitstream Vera Sans", Lucida, Arial, Geneva, Helvetica, sans-serif;
|
13 |
+
FONT-SIZE : small;
|
14 |
+
MARGIN : 10px;
|
15 |
+
WIDTH : 800px;
|
16 |
+
}
|
17 |
+
h1 {
|
18 |
+
FONT-FAMILY : "Lucida Grande","Lucida Sans Unicode", "Bitstream Vera Sans", Lucida, Arial, Geneva, Helvetica, sans-serif;
|
19 |
+
FONT-SIZE : large;
|
20 |
+
}
|
21 |
+
h2 {
|
22 |
+
FONT-FAMILY : "Lucida Grande","Lucida Sans Unicode", "Bitstream Vera Sans", Lucida, Arial, Geneva, Helvetica, sans-serif;
|
23 |
+
FONT-SIZE : large;
|
24 |
+
}
|
25 |
+
h4 {
|
26 |
+
FONT-FAMILY : "Lucida Grande","Lucida Sans Unicode", "Bitstream Vera Sans", Lucida, Arial, Geneva, Helvetica, sans-serif;
|
27 |
+
FONT-SIZE : small;
|
28 |
+
FONT-WEIGHT : bold;
|
29 |
+
}
|
30 |
+
.code {
|
31 |
+
FONT-FAMILY : monospace;
|
32 |
+
FONT-SIZE : medium;
|
33 |
+
WHITE-SPACE : pre;
|
34 |
+
}
|
35 |
+
.comment {
|
36 |
+
FONT-FAMILY : arial;
|
37 |
+
FONT-SIZE : small;
|
38 |
+
FONT-STYLE : italic;
|
39 |
+
}
|
40 |
+
</style>
|
41 |
+
</head>
|
42 |
+
<body>
|
43 |
+
<h1>iCalcreator 2.10</h1>
|
44 |
+
iCalcreator class v2.10<br />
|
45 |
+
copyright (c) 2007-2011 Kjell-Inge Gustafsson, kigkonsult<br />
|
46 |
+
<a href="http://www.kigkonsult.se/iCalcreator/index.php" title="www.kigkonsult.se/iCalcreator" target="_blank">www.kigkonsult.se/iCalcreator</a><br />
|
47 |
+
ical@kigkonsult.se<br />
|
48 |
+
<br />
|
49 |
+
iCalcreator is a PHP class managing iCal formatted files for non-calendar
|
50 |
+
systems like CMS, project management systems and other applications able
|
51 |
+
to process calendar information like agendas, tasks, reports, totos,
|
52 |
+
journaling data and for communication with calendar systems and applications.
|
53 |
+
<br /><br />
|
54 |
+
This is a <b>short summary</b> how to use iCalcreator; create, parse, edit, select and output functionality.
|
55 |
+
<br /><br />
|
56 |
+
iCalcreator is built of a class file with support of a function class file and are calendar component property oriented.
|
57 |
+
Development environment is PHP version 5.x but coding is done to meet 4.x backward compatibility and may work.
|
58 |
+
<h4>iCal</h4>
|
59 |
+
A short iCal description is found at <a href="http://en.wikipedia.org/wiki/ICalendar#Core_object" title="iCalendar From Wikipedia, the free encyclopedia" target="_blank">Wikipedia</a>. If You are not familiar with iCal, read this first!<br />
|
60 |
+
Knowledge of calendar protocol rfc2445/rfc2446 is to recommend;<br />
|
61 |
+
<a href="http://www.kigkonsult.se/downloads/dl.php?f=rfc2445" title="RFC2445" target="_blank">rfc2445</a>
|
62 |
+
- Internet Calendaring and Scheduling Core Object Specification (iCalendar)<br />
|
63 |
+
<a href="http://www.kigkonsult.se/downloads/dl.php?f=rfc2446" title="RFC2446" target="_blank">rfc2446</a>
|
64 |
+
- iCalendar Transport-Independent Interoperability Protocol (iTIP) Scheduling Events, BusyTime, To-dos and Journal Entries <br />
|
65 |
+
All functions calls are made as simple as possible BUT (, !!!,) read these rfc's properly!<br />
|
66 |
+
<h4>Downloads</h4>
|
67 |
+
Download
|
68 |
+
<a href="http://www.kigkonsult.se/downloads/index.php#iCalcreator" title="iCalcreator complete manual" target="_blank"><b>complete manual</b></a>
|
69 |
+
and
|
70 |
+
<a href="http://www.kigkonsult.se/downloads/index.php#iCalcreator" title="iCalcreator coding samples" target="_blank"><b>coding samples</b></a>.
|
71 |
+
from <a href="http://www.kigkonsult.se/iCalcreator/index.php" title="iCalcreator" target="_blank">www.kigkonsult.se/iCalcreator</a>.
|
72 |
+
<h4>INSTALL</h4>
|
73 |
+
Unpack to any folder<br />
|
74 |
+
- add this folder to your include-path<br />
|
75 |
+
- or unpack to your application-(include)-folder<br />
|
76 |
+
Add "require_once [folder/]iCalcreator.class.php;" to your php-script.
|
77 |
+
<br />
|
78 |
+
<br />
|
79 |
+
If using php version 5.1 or higher, the default timezone need to be set/altered, now "Europe/Stockholm",
|
80 |
+
line 52 in the iCalcreator.class.php file.
|
81 |
+
<br />
|
82 |
+
When creating a new calendar/component instance, review config settings.
|
83 |
+
|
84 |
+
<h2>CREATE</h2>
|
85 |
+
|
86 |
+
<p class="code">require_once( "iCalcreator.class.php" );
|
87 |
+
$config = array( "unique_id" => "icaldomain.com" ); // <span class="comment">set Your unique id</span>
|
88 |
+
$v = new vcalendar( $config ); // <span class="comment">create a new calendar instance</span>
|
89 |
+
|
90 |
+
$v->setProperty( "method", "PUBLISH" ); // <span class="comment">required of some calendar software</span>
|
91 |
+
$v->setProperty( "x-wr-calname", "Calendar Sample" ); // <span class="comment">required of some calendar software</span>
|
92 |
+
$v->setProperty( "X-WR-CALDESC", "Calendar Description" ); // <span class="comment">required of some calendar software</span>
|
93 |
+
$tz = "Europe/Stockholm";
|
94 |
+
$v->setProperty( "X-WR-TIMEZONE", $tz ); // <span class="comment">required of some calendar software</span>
|
95 |
+
.. .
|
96 |
+
iCalUtilityFunctions::createTimezone( $v, $tz ) // <span class="comment">creates (very simple) timezone component(-s)</span>
|
97 |
+
.. .
|
98 |
+
$vevent = & $v->newComponent( "vevent" ); // <span class="comment">create an event calendar component</span>
|
99 |
+
$vevent->setProperty( "dtstart", array( "year"=>2007, "month"=>4, "day"=>1, "hour"=>19, "min"=>0, "sec"=>0 ));
|
100 |
+
$vevent->setProperty( "dtend", array( "year"=>2007, "month"=>4, "day"=>1, "hour"=>22, "min"=>30, "sec"=>0 ));
|
101 |
+
$vevent->setProperty( "LOCATION", "Central Placa" ); // <span class="comment">property name - case independent</span>
|
102 |
+
$vevent->setProperty( "summary", "PHP summit" );
|
103 |
+
$vevent->setProperty( "description", "This is a description" );
|
104 |
+
$vevent->setProperty( "comment", "This is a comment" );
|
105 |
+
$vevent->setProperty( "attendee", "attendee1@icaldomain.net" );
|
106 |
+
.. .
|
107 |
+
$vevent = & $v->newComponent( "vevent" ); // <span class="comment">create next event calendar component</span>
|
108 |
+
$vevent->setProperty( "dtstart", "20070401", array("VALUE" => "DATE"));// <span class="comment">alt. date format, now for an all-day event</span>
|
109 |
+
$vevent->setProperty( "organizer" , "boss@icaldomain.com" );
|
110 |
+
$vevent->setProperty( "summary", "ALL-DAY event" );
|
111 |
+
$vevent->setProperty( "description", "This is a description for an all-day event" );
|
112 |
+
$vevent->setProperty( "resources", "COMPUTER PROJECTOR" );
|
113 |
+
$vevent->setProperty( "rrule", array( "FREQ" => "WEEKLY", "count" => 4));// <span class="comment">weekly, four occasions</span>
|
114 |
+
$vevent->parse( "LOCATION:1CP Conference Room 4350" ); // <span class="comment">supporting parse of strict rfc2445 formatted text</span>
|
115 |
+
.. .
|
116 |
+
.. .// <span class="comment">all calendar components are described in <a href="http://www.kigkonsult.se/downloads/dl.php?f=rfc2445" title="RFC2445" target="_blank">rfc2445</a></span>
|
117 |
+
.. .// <span class="comment">a complete iCalcreator function list (ex. setProperty) in <a href="http://www.kigkonsult.se/downloads/index.php#iCalcreator" title="iCalcreator complete manual" target="_blank">iCalcreator manual</a></span>
|
118 |
+
.. .
|
119 |
+
$v->returnCalendar(); // <span class="comment">redirect calendar file to browser</span>
|
120 |
+
</p>
|
121 |
+
<h2>PARSE</h2>
|
122 |
+
<p class="code">require_once( "iCalcreator.class.php" );
|
123 |
+
$config = array( "unique_id" => "icaldomain.com" ); // <span class="comment">set Your unique id, required if any component UID is missing</span>
|
124 |
+
$v = new vcalendar( $config ); // <span class="comment">create a new calendar instance</span>
|
125 |
+
|
126 |
+
/* start parse of local file */
|
127 |
+
$config = array( "directory" => "calendar", "filename" => "file.ics" );
|
128 |
+
$v->setConfig( $config ); // <span class="comment">set directory and file name</span>
|
129 |
+
$v->parse();
|
130 |
+
|
131 |
+
/* start parse of remote file */
|
132 |
+
$v->setConfig( "url", "http://www.aDomain.net/file.ics" ); // <span class="comment">iCalcreator also support parse from or write to remote files</span>
|
133 |
+
$v->parse();
|
134 |
+
|
135 |
+
$v->setProperty( "method", "PUBLISH" ); // <span class="comment">required of some calendar software</span>
|
136 |
+
$v->setProperty( "x-wr-calname", "Calendar Sample" ); // <span class="comment">required of some calendar software</span>
|
137 |
+
$v->setProperty( "X-WR-CALDESC", "Calendar Description" ); // <span class="comment">required of some calendar software</span>
|
138 |
+
$v->setProperty( "X-WR-TIMEZONE", "Europe/Stockholm" ); // <span class="comment">required of some calendar software</span>
|
139 |
+
|
140 |
+
.. .
|
141 |
+
$v->sort(); // <span class="comment">ensure start date order</span>
|
142 |
+
.. .
|
143 |
+
</p>
|
144 |
+
<h2>EDIT</h2>
|
145 |
+
<p class="code">require_once( "iCalcreator.class.php" );
|
146 |
+
$config = array( "unique_id" => "icaldomain.com", "directory" => "calendar", "filename" => "file.ics" );
|
147 |
+
// <span class="comment">set Your unique id, import directory and file name</span>
|
148 |
+
$v = new vcalendar( $config ); // <span class="comment">create a new calendar instance</span>
|
149 |
+
|
150 |
+
$v->parse();
|
151 |
+
|
152 |
+
$v->setProperty( "method", "PUBLISH" ); // <span class="comment">required of some calendar software</span>
|
153 |
+
$v->setProperty( "x-wr-calname", "Calendar Sample" ); // <span class="comment">required of some calendar software</span>
|
154 |
+
$v->setProperty( "X-WR-CALDESC", "Calendar Description" ); // <span class="comment">required of some calendar software</span>
|
155 |
+
$v->setProperty( "X-WR-TIMEZONE", "Europe/Stockholm" ); // <span class="comment">required of some calendar software</span>
|
156 |
+
|
157 |
+
while( $vevent = $v->getComponent( "vevent" )) { // <span class="comment">read events, one by one</span>
|
158 |
+
$uid = $vevent->getProperty( "uid" ); // <span class="comment">uid required, one occurence (unique id/key for component)</span>
|
159 |
+
.. .
|
160 |
+
$dtstart = $vevent->getProperty( "dtstart" ); // <span class="comment">dtstart required, one occurence</span>
|
161 |
+
.. .
|
162 |
+
if( $description = $vevent->getProperty( "description", 1 )) { // <span class="comment">description optional, first occurence</span>
|
163 |
+
.. . // <span class="comment">edit the description</span>
|
164 |
+
$vevent->setProperty( "description", $description, FALSE, 1 ); // <span class="comment">update/replace the description</span>
|
165 |
+
}
|
166 |
+
while( $comment = $vevent->getProperty( "comment" )) { // <span class="comment">comment optional, may occur more than once </span>
|
167 |
+
.. . // <span class="comment">manage comments</span>
|
168 |
+
}
|
169 |
+
.. .
|
170 |
+
while( $vevent->deleteProperty( "attendee" ))
|
171 |
+
continue; // <span class="comment">remove all ATTENDEE properties .. .</span>
|
172 |
+
.. .
|
173 |
+
$v->setComponent ( $vevent, $uid ); // <span class="comment">update/replace event in calendar with <b>uid</b> as key </span>
|
174 |
+
}
|
175 |
+
.. .
|
176 |
+
.. .// <span class="comment">a complete iCalcreator function list (ex. getProperty, deleteProperty) in <a href="http://www.kigkonsult.se/downloads/index.php" title="iCalcreator complete manual" target="_blank">iCalcreator manual</a></span>
|
177 |
+
.. .
|
178 |
+
</p>
|
179 |
+
<h2>SELECT</h2>
|
180 |
+
<p class="code">require_once( "iCalcreator.class.php" );
|
181 |
+
$config = array( "unique_id" => "icaldomain.com" ); // <span class="comment">set Your unique id</span>
|
182 |
+
$v = new vcalendar( $config ); // <span class="comment">create a new calendar instance</span>
|
183 |
+
|
184 |
+
$v->setConfig( "url", "http://www.aDomain.net/file.ics" ); // <span class="comment">iCalcreator also support remote files</span>
|
185 |
+
$v->parse();
|
186 |
+
$v->sort(); // <span class="comment">ensure start date order</span>
|
187 |
+
|
188 |
+
$v->setProperty( "method", "PUBLISH" ); // <span class="comment">required of some calendar software</span>
|
189 |
+
$v->setProperty( "x-wr-calname", "Calendar Sample" ); // <span class="comment">required of some calendar software</span>
|
190 |
+
$v->setProperty( "X-WR-CALDESC", "Calendar Description" ); // <span class="comment">required of some calendar software</span>
|
191 |
+
$v->setProperty( "X-WR-TIMEZONE", "Europe/Stockholm" ); // <span class="comment">required of some calendar software</span>
|
192 |
+
|
193 |
+
$eventArray = $v->selectComponents(); // <span class="comment">select components occuring <b>today</b></span>
|
194 |
+
// <span class="comment">(including components with recurrence pattern)</span>
|
195 |
+
foreach( $eventArray as $year => $yearArray) {
|
196 |
+
foreach( $yearArray as $month => $monthArray ) {
|
197 |
+
foreach( $monthArray as $day => $dailyEventsArray ) {
|
198 |
+
foreach( $dailyEventsArray as $vevent ) {
|
199 |
+
$currddate = $event->getProperty( "x-current-dtstart" );
|
200 |
+
// <span class="comment">if member of a recurrence set (2nd occurence etc)</span>
|
201 |
+
// <span class="comment">returns array( "x-current-dtstart"</span>
|
202 |
+
// <span class="comment"> , <(string) date("Y-m-d [H:i:s][timezone/UTC offset]")>)</span>
|
203 |
+
$dtstart = $vevent->getProperty( "dtstart" ); // <span class="comment">dtstart required, one occurence, (orig. start date)</span>
|
204 |
+
$summary = $vevent->getProperty( "summary" );
|
205 |
+
$description = $vevent->getProperty( "description" );
|
206 |
+
.. .
|
207 |
+
.. .
|
208 |
+
}
|
209 |
+
}
|
210 |
+
}
|
211 |
+
}
|
212 |
+
|
213 |
+
$valueOcurr = $v->getProperty( "CATEGORIES" ); // <span class="comment">fetch specific property (unique) values and number of ocurrencies</span>
|
214 |
+
// <span class="comment">ATTENDEE, CATEGORIES, DTSTART, LOCATION, ORGANIZER, PRIORITY, RESOURCES, STATUS, SUMMARY, UID</span>
|
215 |
+
foreach( $valueOcurr as $uniqueValue => $ocurr ) {
|
216 |
+
.. .
|
217 |
+
}
|
218 |
+
|
219 |
+
$selectSpec = array( "CATEGORIES" => "course1" );
|
220 |
+
$specComps = $v->selectComponents( $selectSpec ); // <span class="comment">selects components based on specific property value(-s)</span>
|
221 |
+
// <span class="comment">ATTENDEE, CATEGORIES, LOCATION, ORGANIZER, PRIORITY, RESOURCES, STATUS, SUMMARY, UID</span>
|
222 |
+
foreach( $specComps as $comp ) {
|
223 |
+
.. .
|
224 |
+
}
|
225 |
+
</p>
|
226 |
+
<h2>OUTPUT</h2>
|
227 |
+
<p class="code">require_once( "iCalcreator.class.php" );
|
228 |
+
$config = array( "unique_id" => "icaldomain.com" ); // <span class="comment">set Your unique id</span>
|
229 |
+
$v = new vcalendar( $config ); // <span class="comment">create a new calendar instance</span>
|
230 |
+
|
231 |
+
$v->setProperty( "method", "PUBLISH" ); // <span class="comment">required of some calendar software</span>
|
232 |
+
$v->setProperty( "x-wr-calname", "Calendar Sample" ); // <span class="comment">required of some calendar software</span>
|
233 |
+
$v->setProperty( "X-WR-CALDESC", "Calendar Description" ); // <span class="comment">required of some calendar software</span>
|
234 |
+
$v->setProperty( "X-WR-TIMEZONE", "Europe/Stockholm" ); // <span class="comment">required of some calendar software</span>
|
235 |
+
.. .
|
236 |
+
.. .// <span class="comment">parse calendar file(s) and/or edit/create calendar components.. .</span>
|
237 |
+
.. .
|
238 |
+
</p>
|
239 |
+
<h4> // opt 1</h4>
|
240 |
+
<p class="code">.. .
|
241 |
+
$v->returnCalendar(); // <span class="comment">redirect calendar file to browser</span>
|
242 |
+
</p>
|
243 |
+
<h4> // opt 2</h4>
|
244 |
+
<p class="code">.. .
|
245 |
+
$config = array( "directory" => "depot", "filename" => "calendar.ics" );
|
246 |
+
$v->setConfig( $config ); // <span class="comment">set output directory and file name</span>
|
247 |
+
$v->saveCalendar(); // <span class="comment">save calendar to (local) file</span>
|
248 |
+
</p>
|
249 |
+
<h4> // opt 3</h4>
|
250 |
+
<p class="code">.. .
|
251 |
+
$config = array( "url" => "http://www.aDomain.net/file.ics" );
|
252 |
+
$v->setConfig( $config ); // <span class="comment">set output url</span>
|
253 |
+
$v->saveCalendar(); // <span class="comment">save calendar to remote url</span>
|
254 |
+
</p>
|
255 |
+
|
256 |
+
<h2>COPYRIGHT AND LICENSE</h2>
|
257 |
+
|
258 |
+
<h4>Copyright</h4>
|
259 |
+
iCalcreator class<br />
|
260 |
+
copyright (c) 2007-2011 Kjell-Inge Gustafsson, kigkonsult<br />
|
261 |
+
<a href="http://www.kigkonsult.se/iCalcreator/index.php" title="www.kigkonsult.se/iCalcreator" target="_blank">www.kigkonsult.se/iCalcreator</a><br />
|
262 |
+
ical@kigkonsult.se<br />
|
263 |
+
|
264 |
+
<h4>License</h4>
|
265 |
+
|
266 |
+
This library is free software; you can redistribute it and/or
|
267 |
+
modify it under the terms of the GNU Lesser General Public
|
268 |
+
License as published by the Free Software Foundation; either
|
269 |
+
version 2.1 of the License, or (at your option) any later version.
|
270 |
+
<br /><br />
|
271 |
+
This library is distributed in the hope that it will be useful,
|
272 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
273 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
274 |
+
Lesser General Public License for more details.
|
275 |
+
<br /><br />
|
276 |
+
You should have received a copy of the GNU Lesser General Public
|
277 |
+
License along with this library; if not, write to the Free Software
|
278 |
+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
279 |
+
or download it <a href="http://www.kigkonsult.se/downloads/dl.php?f=LGPL" target="_blank">here</a>.
|
280 |
+
<br />
|
281 |
+
<br />
|
282 |
+
</body>
|
283 |
+
</html>
|
lib/iCalcreator-2.10/using.html
ADDED
@@ -0,0 +1,5683 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
|
2 |
+
"http://www.w3.org/TR/html4/frameset.dtd">
|
3 |
+
<html>
|
4 |
+
<head>
|
5 |
+
<title>iCalcreator 2.10 manual</title>
|
6 |
+
<meta name="author" content="Kjell-Inge Gustafsson - kigkonsult" />
|
7 |
+
<meta name="copyright" content="2007-2011 Kjell-Inge Gustafsson - kigkonsult" />
|
8 |
+
<meta name="keywords" content="ical, calendar, calender, xcal, xml, icalender, rfc2445, vcalender, php, create" />
|
9 |
+
<meta name="description" content="iCalcreator" />
|
10 |
+
<style type="text/css">
|
11 |
+
* {
|
12 |
+
BACKGROUND-COLOR: white;
|
13 |
+
COLOR : black;
|
14 |
+
}
|
15 |
+
a {
|
16 |
+
FONT-FAMILY : "Lucida Grande","Lucida Sans Unicode", "Bitstream Vera Sans", Lucida, Arial, Geneva, Helvetica, sans-serif;
|
17 |
+
FONT-SIZE : small;
|
18 |
+
}
|
19 |
+
a.ref {
|
20 |
+
background-color: transparent;
|
21 |
+
FONT-FAMILY : monospace, arial;
|
22 |
+
FONT-SIZE : small;
|
23 |
+
FONT-STYLE : normal;
|
24 |
+
TEXT-DECORATION : none;
|
25 |
+
}
|
26 |
+
body {
|
27 |
+
FONT-FAMILY : "Lucida Grande","Lucida Sans Unicode", "Bitstream Vera Sans", Lucida, Arial, Geneva, Helvetica, sans-serif;
|
28 |
+
FONT-SIZE : small;
|
29 |
+
MARGIN-LEFT : 10px;
|
30 |
+
WIDTH : 600px;
|
31 |
+
}
|
32 |
+
h1 {
|
33 |
+
BACKGROUND-COLOR: silver;
|
34 |
+
BORDER : thin solid black;
|
35 |
+
FONT-FAMILY : "Lucida Grande","Lucida Sans Unicode", "Bitstream Vera Sans", Lucida, Arial, Geneva, Helvetica, sans-serif;
|
36 |
+
FONT-SIZE : x-large;
|
37 |
+
FONT-WEIGHT : bold;
|
38 |
+
DISPLAY : block;
|
39 |
+
}
|
40 |
+
h2 {
|
41 |
+
FONT-FAMILY : "Lucida Grande","Lucida Sans Unicode", "Bitstream Vera Sans", Lucida, Arial, Geneva, Helvetica, sans-serif;
|
42 |
+
FONT-SIZE : large;
|
43 |
+
}
|
44 |
+
h3 {
|
45 |
+
FONT-FAMILY : "Lucida Grande","Lucida Sans Unicode", "Bitstream Vera Sans", Lucida, Arial, Geneva, Helvetica, sans-serif;
|
46 |
+
FONT-SIZE : medium;
|
47 |
+
}
|
48 |
+
h4 {
|
49 |
+
FONT-FAMILY : "Lucida Grande","Lucida Sans Unicode", "Bitstream Vera Sans", Lucida, Arial, Geneva, Helvetica, sans-serif;
|
50 |
+
FONT-SIZE : small;
|
51 |
+
FONT-WEIGHT : bold;
|
52 |
+
}
|
53 |
+
h5 {
|
54 |
+
FONT-FAMILY : "Lucida Grande","Lucida Sans Unicode", "Bitstream Vera Sans", Lucida, Arial, Geneva, Helvetica, sans-serif;
|
55 |
+
FONT-SIZE : small;
|
56 |
+
FONT-WEIGHT : normal;
|
57 |
+
TEXT-DECORATION : underline;
|
58 |
+
}
|
59 |
+
p {
|
60 |
+
FONT-FAMILY : "Lucida Grande","Lucida Sans Unicode", "Bitstream Vera Sans", Lucida, Arial, Geneva, Helvetica, sans-serif;
|
61 |
+
FONT-SIZE : small;
|
62 |
+
}
|
63 |
+
.bb {
|
64 |
+
BORDER-BOTTOM : gray dotted thin;
|
65 |
+
}
|
66 |
+
.blb {
|
67 |
+
BORDER-LEFT : gray dotted thin;
|
68 |
+
BORDER-BOTTOM : gray dotted thin;
|
69 |
+
TEXT-ALIGN : center;
|
70 |
+
}
|
71 |
+
.bl {
|
72 |
+
BORDER-LEFT : gray dotted thin;
|
73 |
+
}
|
74 |
+
.center {
|
75 |
+
TEXT-ALIGN : center;
|
76 |
+
}
|
77 |
+
.comment {
|
78 |
+
background-color: transparent;
|
79 |
+
FONT-FAMILY : monospace;
|
80 |
+
FONT-SIZE : medium;
|
81 |
+
FONT-STYLE : italic;
|
82 |
+
FONT-WEIGHT : 300;
|
83 |
+
xLETTER-SPACING : 0.1em;
|
84 |
+
WHITE-SPACE : pre;
|
85 |
+
}
|
86 |
+
.example {
|
87 |
+
background-color: #DCDCDC;
|
88 |
+
FONT-FAMILY : Courier, "Courier New";
|
89 |
+
FONT-SIZE : small;
|
90 |
+
FONT-WEIGHT : 500;
|
91 |
+
LINE-HEIGHT : 1.2em;
|
92 |
+
WHITE-SPACE : pre;
|
93 |
+
}
|
94 |
+
.format {
|
95 |
+
BORDER : gray dotted thin;
|
96 |
+
FONT-FAMILY : Courier, "Courier New";
|
97 |
+
FONT-SIZE : small;
|
98 |
+
FONT-WEIGHT : 500;
|
99 |
+
LINE-HEIGHT : 1.5em;
|
100 |
+
WHITE-SPACE : pre;
|
101 |
+
}
|
102 |
+
.header {
|
103 |
+
BACKGROUND-COLOR: silver;
|
104 |
+
BORDER : thin solid black;
|
105 |
+
FONT-FAMILY : "Lucida Grande","Lucida Sans Unicode", "Bitstream Vera Sans", Lucida, Arial, Geneva, Helvetica, sans-serif;
|
106 |
+
FONT-SIZE : xx-large;
|
107 |
+
WIDTH : 600px;
|
108 |
+
}
|
109 |
+
.label {
|
110 |
+
FONT-FAMILY : arial;
|
111 |
+
FONT-SIZE : small;
|
112 |
+
FONT-WEIGHT : bold;
|
113 |
+
LETTER-SPACING : 0.1em;
|
114 |
+
}
|
115 |
+
.quotes {
|
116 |
+
background-color: transparent;
|
117 |
+
FONT-FAMILY : arial;
|
118 |
+
FONT-SIZE : small;
|
119 |
+
FONT-STYLE : italic;
|
120 |
+
FONT-WEIGHT : 300;
|
121 |
+
LETTER-SPACING : 0.1em;
|
122 |
+
WHITE-SPACE : pre;
|
123 |
+
}
|
124 |
+
.ref {
|
125 |
+
BACKGROUND-COLOR: transparent;
|
126 |
+
FONT-FAMILY : monospace, arial;
|
127 |
+
FONT-SIZE : x-small;
|
128 |
+
xFONT-STYLE : italic;
|
129 |
+
xFONT-WEIGHT : 600;
|
130 |
+
VERTICAL-ALIGN : top;
|
131 |
+
LETTER-SPACING : 0.2em;
|
132 |
+
}
|
133 |
+
.top {
|
134 |
+
VERTICAL-ALIGN : top;
|
135 |
+
}
|
136 |
+
</style>
|
137 |
+
</head>
|
138 |
+
<body>
|
139 |
+
<a name="top"></a>
|
140 |
+
<p class="header">iCalcreator 2.10</p>
|
141 |
+
iCalcreator class v2.10<br />
|
142 |
+
copyright (c) 2007-2011 Kjell-Inge Gustafsson, kigkonsult<br />
|
143 |
+
<a href="http://www.kigkonsult.se/iCalcreator/index.php" title="www.kigkonsult.Se/iCalcreator" target="_blank">www.kigkonsult.Se/iCalcreator</a><br />
|
144 |
+
ical@kigkonsult.se<br />
|
145 |
+
|
146 |
+
<h2>Description:</h2>
|
147 |
+
iCalcreator is a PHP implementation of RFC2445/RFC2446 to manage iCal/xCal formatted files.
|
148 |
+
<br />
|
149 |
+
|
150 |
+
<a name="INTRO"></a><h1>1. INTRO</h1>
|
151 |
+
<p>
|
152 |
+
iCalcreator is a PHP class managing iCal formatted files for non-calendar
|
153 |
+
systems like CMS, project management systems and other applications able
|
154 |
+
to process calendar information like agendas, tasks, reports, todos,
|
155 |
+
journalling data and for communication with calendar systems and applications.
|
156 |
+
</p>
|
157 |
+
<p>
|
158 |
+
iCalcreator features create, parse, edit and select calendar and calendar components.
|
159 |
+
</p>
|
160 |
+
<p>
|
161 |
+
iCalcreator is built of a class file with support of a function class file and are calendar
|
162 |
+
component property oriented. Development environment is PHP version 5.x but coding is done
|
163 |
+
to meet 4.x backward compatibility and may work.
|
164 |
+
</p>
|
165 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a>
|
166 |
+
|
167 |
+
<a name="iCal"></a><h2>1.1 Ical</h2>
|
168 |
+
|
169 |
+
The iCalendar format, as described in <a href="http://www.kigkonsult.se/downloads/dl.php?f=rfc2445" title="Download RFC2445 in text format">rfc2445</a>
|
170 |
+
(and <a href="http://www.kigkonsult.se/downloads/dl.php?f=rfc2446" title="Download RFC2446 in text format">rfc2446</a>)
|
171 |
+
<p class="quotes">allows for the capture and exchange of information normally stored within a<br />calendaring and scheduling application</p>
|
172 |
+
and <p class="quotes">is an exchange format between applications or systems.</p>
|
173 |
+
|
174 |
+
<p>
|
175 |
+
A short iCal description is found at <a href="http://en.wikipedia.org/wiki/ICalendar#Core_object" title="iCalendar From Wikipedia, the free encyclopedia">Wikipedia</a>. If You are not familiar with iCal, read this first!<br />
|
176 |
+
Knowledge of calendar protocol rfc2445/rfc2446 is to recommend.
|
177 |
+
</p>
|
178 |
+
<p>
|
179 |
+
<a href="http://www.kigkonsult.se/downloads/dl.php?f=rfc2445" title="Download RFC2445 in text format">rfc2445</a>
|
180 |
+
- Internet Calendaring and Scheduling Core Object Specification (iCalendar),
|
181 |
+
<br />
|
182 |
+
download <a href="http://www.kigkonsult.se/downloads/dl.php?f=rfc2445" title="Download RFC2445 in text format">here</a>
|
183 |
+
or examine <a href="http://www.kigkonsult.se/iCalcreator/iCalDictionary/index.html" title="view online" target="_blank">online</a>.
|
184 |
+
</p>
|
185 |
+
<p>
|
186 |
+
<a href="http://www.kigkonsult.se/downloads/dl.php?f=rfc2446" title="Download RFC2446 in text format">rfc2446</a>
|
187 |
+
- iCalendar Transport-Independent Interoperability Protocol (iTIP) Scheduling Events, BusyTime, To-dos and Journal Entries,
|
188 |
+
download <a href="http://www.kigkonsult.se/downloads/dl.php?f=rfc2446" title="Download RFC2446 in text format">here</a>.
|
189 |
+
</p>
|
190 |
+
<p>
|
191 |
+
All iCalcreator functions calls are made as simple as possible BUT (, !!!,) read these rfc's properly!
|
192 |
+
xCal (iCal xml) output format is supported but still experimental.
|
193 |
+
</p>
|
194 |
+
<br />
|
195 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a>
|
196 |
+
|
197 |
+
<a name="This_manual"></a><h2>1.2 This manual</h2>
|
198 |
+
This style is used for text.
|
199 |
+
<p class="format">This style is used for formats.</p>
|
200 |
+
<p class="example">This style is used for PHP coding examples.
|
201 |
+
<span class="comment"> // this style is used for coding comments.</span></p>
|
202 |
+
<p class="comment">This style is used for content details.</p>
|
203 |
+
<p class="quotes">This style is used for RFC2445 quotes.</p>
|
204 |
+
<p>
|
205 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a>
|
206 |
+
|
207 |
+
<a name="Versioning"></a><h2>1.3 Versioning</h2>
|
208 |
+
|
209 |
+
The release numbering convention used is major.minor.micro.
|
210 |
+
<dl>
|
211 |
+
<dt>Major
|
212 |
+
<dd>Indicates a very large change in the core package. Rewrites or major milestones.
|
213 |
+
<dt>Minor
|
214 |
+
<dd>Significant amount of feature addition/modification.<br />odd number - development/experimental release<br /> even number - production release
|
215 |
+
<dt>Micro
|
216 |
+
<dd>Mostly bug fix and maintenance number.
|
217 |
+
<dt>(Suffix)
|
218 |
+
<dd>rc1 for first release candidate, a1 for alpha 1, etc.
|
219 |
+
</dl>
|
220 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a>
|
221 |
+
|
222 |
+
<a name="Support"></a><h2>1.4 Support</h2>
|
223 |
+
<p>
|
224 |
+
The main support channel is using iCalcreator
|
225 |
+
<a title="Sourceforge" href="http://sourceforge.net/projects/icalcreator/forums/" target="_blank">Sourceforge</a> forum.
|
226 |
+
</p>
|
227 |
+
<p>
|
228 |
+
Use the contact <a href="http://www.kigkonsult.se/contact/index.php" title="www.kigkonsult.Se/contact" target="_blank">page</a>
|
229 |
+
for queries, improvement/development issues or professional support and development.
|
230 |
+
Please note that paid support or consulting service has the highest priority.
|
231 |
+
</p>
|
232 |
+
<p>
|
233 |
+
Our services are available for support and designing and developing iCalcreator etc. customizations,
|
234 |
+
adaptations and other PHP/MySQL solutions with a special focus on software utility and reliability,
|
235 |
+
supported through our iterative acquire/design/transition process modell.
|
236 |
+
</p>
|
237 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a>
|
238 |
+
|
239 |
+
<a name="INSTALL"></a><h2>1.5 Install</h2>
|
240 |
+
Unpack to any folder<br />
|
241 |
+
- add this folder to your include-path<br />
|
242 |
+
- or unpack to your application-(include)-folder<br />
|
243 |
+
Add
|
244 |
+
<p class="format">require_once [folder/]iCalcreator.class.php;</p>
|
245 |
+
to your php-script.
|
246 |
+
<br />
|
247 |
+
<br />
|
248 |
+
If using php version 5.1 or higher, the default timezone need to be set/altered, now "Europe/Stockholm",
|
249 |
+
line 50 in the iCalcreator.class.php file.
|
250 |
+
<br />
|
251 |
+
<br />
|
252 |
+
When creating a new calendar/component instance, review <a href="#Calendar_configuration_functions">config</a> settings.
|
253 |
+
<br />
|
254 |
+
<br />
|
255 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a>
|
256 |
+
|
257 |
+
<a name="Additional_Descriptors"></a><h2>1.6 Additional Descriptors</h2>
|
258 |
+
The following properties (as described in <a href="http://en.wikipedia.org/wiki/ICalendar#Calendar_extensions" title="http://en.wikipedia.org/wiki/ICalendar#Calendar_extensions">wikipedia:iCal</a>) may be required when importing iCal files into some calendaring software (MS etc.):
|
259 |
+
<dl>
|
260 |
+
<dt>on calendar level
|
261 |
+
<dd><a href="#METHOD">METHOD</a> property (value PUBLISH etc.)
|
262 |
+
<dd><a href="#X-PROPERTY">X-WR-CALNAME</a> x-property
|
263 |
+
<dd><a href="#X-PROPERTY">X-WR-CALDESC</a> x-property
|
264 |
+
<dd><a href="#X-PROPERTY">X-WR-RELCALID</a> x-property <span class="comment">(a <a href="/wiki/Universally_Unique_Identifier" title="Universally Unique Identifier" class="mw-redirect">UUID</a>.)</span>
|
265 |
+
<dd><a href="#X-PROPERTY">X-WR-TIMEZONE</a> x-property
|
266 |
+
<dt>on component level
|
267 |
+
<dd><a href="#DTSTAMP">DTSTAMP</a> property (iCalcreator auto created)
|
268 |
+
<dd><a href="#UID">UID</a> property (iCalcreator auto created)
|
269 |
+
</dl>
|
270 |
+
Recommendation is also to set <a href="#Unique_id">unique_id</a> when creating a new vcalendar/component instance, to ensure accurate setting of all components <a href="#UID">UID</a> property, even before <a href="#parse_merge">parse</a>.
|
271 |
+
<p class="label">Example</p>
|
272 |
+
<p class="example">$config = array( "unique_id" => "domain.com" );
|
273 |
+
$vcalendar = new vcalendar( $config );
|
274 |
+
$vcalendar->setProperty( "method", "PUBLISH" )
|
275 |
+
$vcalendar->setProperty( "x-wr-calname", "Calendar Sample" );
|
276 |
+
$vcalendar->setProperty( "X-WR-CALDESC", "Calendar Description" );
|
277 |
+
$uuid = "3E26604A-50F4-4449-8B3E-E4F4932D05B5";
|
278 |
+
$vcalendar->setProperty( "X-WR-RELCALID", $uuid );
|
279 |
+
$vcalendar->setProperty( "X-WR-TIMEZONE", "Europe/Stockholm" );
|
280 |
+
.. .
|
281 |
+
</p>
|
282 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a>
|
283 |
+
|
284 |
+
<a name="Addendum"></a><h2>1.7 Addendum</h2>
|
285 |
+
<p>
|
286 |
+
Download iCalcreator <a title="download iCalcreator coding samples" href="http://www.kigkonsult.se/downloads/index.php" target="_blank">coding samples</a>.
|
287 |
+
<br />
|
288 |
+
Examples how to employ iCalcreator in software development:<br />
|
289 |
+
<a title="Create iCal event file on-demand from form" href="http://www.kigkonsult.se/eventCreator/index.php" target="_blank">The iCal file event editor</a> and
|
290 |
+
<a title="tinycal" href="http://www.kigkonsult.se/tinycal/index.php" target="_blank">tinycal</a>, calendar-in-a-box.
|
291 |
+
</p>
|
292 |
+
<p>
|
293 |
+
There are free iCal/xCal icons in the images directory, to use as buttons on a web page.
|
294 |
+
</p>
|
295 |
+
The PHP coding examples are only examples, recommendation is to use a
|
296 |
+
coding standard, the following, incomplete, list is a good start;
|
297 |
+
<br/>
|
298 |
+
<a href="http://www.dagbladet.no/development/phpcodingstandard/" target="_blank">http://www.dagbladet.no/development/phpcodingstandard/</a>
|
299 |
+
<!--
|
300 |
+
<br/>
|
301 |
+
<a href="http://ez.no/ezpublish/documentation/development/standards/php" target="_blank">http://ez.no/ezpublish/documentation/development/standards/php</a>
|
302 |
+
-->
|
303 |
+
<br/>
|
304 |
+
<a href="http://framework.zend.com/manual/en/coding-standard.overview.html" target="_blank">http://framework.zend.com/manual/en/coding-standard.overview.html</a>
|
305 |
+
<!--
|
306 |
+
<br/>
|
307 |
+
<a href="http://gforge.org/docman/view.php/1/2/coding-standards.html" target="_blank">http://gforge.org/docman/view.php/1/2/coding-standards.html</a>
|
308 |
+
-->
|
309 |
+
<br/>
|
310 |
+
<a href="http://pear.php.net/manual/en/standards.php" target="_blank">http://pear.php.net/manual/en/standards.php</a>
|
311 |
+
<br />
|
312 |
+
<br />
|
313 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a>
|
314 |
+
|
315 |
+
<a name="INDEX"><h2>1.8 INDEX</h2>
|
316 |
+
|
317 |
+
<a href="#INTRO">1. INTRO</a><br />
|
318 |
+
<br />
|
319 |
+
<a href="#iCal">1.1 Ical</a><br />
|
320 |
+
<a href="#This_manual">1.2 This manual</a><br />
|
321 |
+
<a href="#Versioning">1.3 Versioning</a><br />
|
322 |
+
<a href="#Support">1.4 Support</a><br />
|
323 |
+
<a href="#INSTALL">1.5 Install</a><br />
|
324 |
+
<a href="#Additional_Descriptors">1.6 Additional_Descriptors</a><br />
|
325 |
+
<a href="#Addendum">1.7 Addendum</a><br />
|
326 |
+
<a href="#INDEX">1.8 INDEX</a><br />
|
327 |
+
<br />
|
328 |
+
<a href="#Calendar_Component_list">2. Calendar Component list</a><br />
|
329 |
+
<br />
|
330 |
+
<a href="#VCALENDAR">2.1 VCALENDAR</a><br />
|
331 |
+
<a href="#VEVENT">2.2 VEVENT</a><br />
|
332 |
+
<a href="#VTODO">2.3 VTODO</a><br />
|
333 |
+
<a href="#VJOURNAL">2.4 VJOURNAL</a><br />
|
334 |
+
<a href="#VFREEBUSY">2.5 VFREEBUSY</a><br />
|
335 |
+
<a href="#VALARM">2.6 VALARM</a><br />
|
336 |
+
<a href="#VTIMEZONE">2.7 VTIMEZONE</a><br />
|
337 |
+
<a href="#CalProps">2.10 Component Properties</a><br />
|
338 |
+
<br />
|
339 |
+
<a href="#Function_list">3. Function list</a><br />
|
340 |
+
<br />
|
341 |
+
<a href="#Calendar_object_functions">3.1 Calendar object functions</a><br />
|
342 |
+
<br />
|
343 |
+
<a href="#Calendar_object_constructors">3.1.1 Constructors</a><br />
|
344 |
+
<a href="#vcalendar">3.1.1.1 vcalendar</a><br />
|
345 |
+
<a href="#vevent">3.1.1.2 vevent</a><br />
|
346 |
+
<a href="#vtodo">3.1.1.3 vtodo</a><br />
|
347 |
+
<a href="#vjournal">3.1.1.4 vjournal</a><br />
|
348 |
+
<a href="#vfreebusy">3.1.1.5 vfreebusy</a><br />
|
349 |
+
<a href="#valarm">3.1.1.6 valarm</a><br />
|
350 |
+
<a href="#vtimezone">3.1.1.7 vtimezone</a><br />
|
351 |
+
<a href="#standard">3.1.1.8 standard</a><br />
|
352 |
+
<a href="#daylight">3.1.1.9 daylight</a><br />
|
353 |
+
<br />
|
354 |
+
<a href="#Calendar_property_functions">3.1.2 Calendar property functions</a><br />
|
355 |
+
<a href="#deleteProperty">3.1.2.1 deleteProperty</a><br />
|
356 |
+
<a href="#getProperty">3.1.2.2 getProperty</a><br />
|
357 |
+
<a href="#setProperty">3.1.2.3 setProperty</a><br />
|
358 |
+
<a href="#CALSCALE">3.1.2.4 CALSCALE</a><br />
|
359 |
+
<a href="#METHOD">3.1.2.5 METHOD</a><br />
|
360 |
+
<a href="#VERSION">3.1.2.6 VERSION</a><br />
|
361 |
+
<a href="#X-PROPERTY">3.1.2.7 X-PROPERTY</a><br />
|
362 |
+
<br />
|
363 |
+
<a href="#Calendar_component_functions">3.1.3 Calendar component functions</a><br />
|
364 |
+
<a href="#deleteComponent">3.1.3.1 deleteComponent</a><br />
|
365 |
+
<a href="#getComponent">3.1.3.2 getComponent</a><br />
|
366 |
+
<a href="#newComponent">3.1.3.3 newComponent</a><br />
|
367 |
+
<a href="#selectComponents">3.1.3.4 selectComponents</a><br />
|
368 |
+
<a href="#setComponent">3.1.3.5 setComponent</a><br />
|
369 |
+
<br />
|
370 |
+
<a href="#Calendar_inputoutput_functions">3.1.4 Calendar input/output functions</a><br />
|
371 |
+
<a href="#parse_merge">3.1.4.1 parse and merge</a><br />
|
372 |
+
<a href="#createCalendar">3.1.4.2 createCalendar</a><br />
|
373 |
+
<a href="#returnCalendar">3.1.4.3 returnCalendar</a><br />
|
374 |
+
<a href="#saveCalendar">3.1.4.4 saveCalendar</a><br />
|
375 |
+
<a href="#sort">3.1.4.5 sort</a><br />
|
376 |
+
<a href="#useCachedCalendar">3.1.4.6 useCachedCalendar</a><br />
|
377 |
+
<br />
|
378 |
+
<a href="#Calendar_configuration_functions">3.1.5 Calendar configuration functions</a><br />
|
379 |
+
<a href="#configKeys">3.1.5.1 configuration keys</a><br />
|
380 |
+
<a href="#getConfig">3.1.5.2 getConfig</a><br />
|
381 |
+
<a href="#initConfig">3.1.5.3 calendar/component initialization</a><br />
|
382 |
+
<a href="#setConfig">3.1.5.4 setConfig</a><br />
|
383 |
+
<a href="#allowEmpty">3.1.5.5 Allow empty components</h4><br />
|
384 |
+
<a href="#Compsinfo">3.1.5.6 Component information</h4><br />
|
385 |
+
<a href="#Delimiter">3.1.5.7 Delimiter</a><br />
|
386 |
+
<a href="#Directory">3.1.5.8 Directory</a><br />
|
387 |
+
<a href="#Fileinfo">3.1.5.9 Fileinfo</a><br />
|
388 |
+
<a href="#Filename">3.1.5.10 Filename</a><br />
|
389 |
+
<a href="#Filesize">3.1.5.11 Filesize</a><br />
|
390 |
+
<a href="#Format">3.1.5.12 Format</a><br />
|
391 |
+
<a href="#Language">3.1.5.13 Language</a><br />
|
392 |
+
<a href="#NewlineChar">3.1.5.14 NewlineChar</a><br />
|
393 |
+
<a href="#dTZID">3.1.5.15 TZID</a><br />
|
394 |
+
<a href="#Unique_id">3.1.5.16 Unique_id</a><br />
|
395 |
+
<a href="#configURL">3.1.5.17 URL</a><br />
|
396 |
+
<br />
|
397 |
+
<a href="#Calendar_component_object_property_function_list">3.2 Calendar component/object property function list</a><br />
|
398 |
+
<br />
|
399 |
+
<a href="#deleteProperty_PROP">3.2.1 deleteProperty</a><br />
|
400 |
+
<a href="#getProperty_PROP">3.2.2 getProperty</a><br />
|
401 |
+
<a href="#parse">3.2.3 parse</a><br />
|
402 |
+
<a href="#setProperty_PROP">3.2.4 setProperty</a><br />
|
403 |
+
<br />
|
404 |
+
<a href="#ACTION">3.2.5 ACTION</a><br />
|
405 |
+
<a href="#ATTACH">3.2.6 ATTACH</a><br />
|
406 |
+
<a href="#ATTENDEE">3.2.7 ATTENDEE</a><br />
|
407 |
+
<a href="#CATEGORIES">3.2.8 CATEGORIES</a><br />
|
408 |
+
<a href="#CLASS">3.2.9 CLASS</a><br />
|
409 |
+
<a href="#COMMENT">3.2.10 COMMENT</a><br />
|
410 |
+
<a href="#COMPLETED">3.2.11 COMPLETED</a><br />
|
411 |
+
<a href="#CONTACT">3.2.12 CONTACT</a><br />
|
412 |
+
<a href="#CREATED">3.2.13 CREATED</a><br />
|
413 |
+
<a href="#DESCRIPTION">3.2.14 DESCRIPTION</a><br />
|
414 |
+
<a href="#DTEND">3.2.15 DTEND</a><br />
|
415 |
+
<a href="#DTSTAMP">3.2.16 DTSTAMP</a><br />
|
416 |
+
<a href="#DTSTART">3.2.17 DTSTART</a><br />
|
417 |
+
<a href="#DUE">3.2.18 DUE</a><br />
|
418 |
+
<a href="#DURATION">3.2.19 DURATION</a><br />
|
419 |
+
<a href="#EXDATE">3.2.20 EXDATE</a><br />
|
420 |
+
<a href="#EXRULE">3.2.21 EXRULE</a><br />
|
421 |
+
<a href="#FREEBUSY_PROP">3.2.22 FREEBUSY</a><br />
|
422 |
+
<a href="#GEO">3.2.23 GEO</a><br />
|
423 |
+
<a href="#LAST-MODIFIED">3.2.24 LAST-MODIFIED</a><br />
|
424 |
+
<a href="#LOCATION">3.2.25 LOCATION</a><br />
|
425 |
+
<a href="#ORGANIZER">3.2.26 ORGANIZER</a><br />
|
426 |
+
<a href="#PERCENT-COMPLETE">3.2.27 PERCENT-COMPLETE</a><br />
|
427 |
+
<a href="#PRIORITY">3.2.28 PRIORITY</a><br />
|
428 |
+
<a href="#RDATE">3.2.29 RDATE</a><br />
|
429 |
+
<a href="#RECURRENCE-ID">3.2.30 RECURRENCE-ID</a><br />
|
430 |
+
<a href="#RELATED-TO">3.2.31 RELATED-TO</a><br />
|
431 |
+
<a href="#REPEAT">3.2.32 REPEAT</a><br />
|
432 |
+
<a href="#REQUEST-STATUS">3.2.33 REQUEST-STATUS</a><br />
|
433 |
+
<a href="#RESOURCES">3.2.34 RESOURCES</a><br />
|
434 |
+
<a href="#RRULE">3.2.35 RRULE</a><br />
|
435 |
+
<a href="#SEQUENCE">3.2.36 SEQUENCE</a><br />
|
436 |
+
<a href="#STATUS">3.2.37 STATUS</a><br />
|
437 |
+
<a href="#SUMMARY">3.2.38 SUMMARY</a><br />
|
438 |
+
<a href="#TRANSP">3.2.39 TRANSP</a><br />
|
439 |
+
<a href="#TRIGGER">3.2.40 TRIGGER</a><br />
|
440 |
+
<a href="#TZID">3.2.41 TZID</a><br />
|
441 |
+
<a href="#TZNAME">3.2.42 TZNAME</a><br />
|
442 |
+
<a href="#TZOFFSETFROM">3.2.43 TZOFFSETFROM</a><br />
|
443 |
+
<a href="#TZOFFSETTO">3.2.44 TZOFFSETTO</a><br />
|
444 |
+
<a href="#TZURL">3.2.45 TZURL</a><br />
|
445 |
+
<a href="#UID">3.2.46 UID</a><br />
|
446 |
+
<a href="#URL">3.2.47 URL</a><br />
|
447 |
+
<a href="#X-PROPERTY_PROP">3.2.48 X-PROPERTY</a><br />
|
448 |
+
<br />
|
449 |
+
<a href="#Calendar_component_configuration_functions">3.3 Calendar Component configuration functions</a><br />
|
450 |
+
<br />
|
451 |
+
<a href="#Language_PROP">3.3.1 Language</a><br />
|
452 |
+
<br />
|
453 |
+
<a href="#Calendar_component_object_misc_functions">3.4 Calendar component object misc. functions</a><br />
|
454 |
+
<br />
|
455 |
+
<a href="#deleteComponent_PROP">3.4.1 deleteComponent</a><br />
|
456 |
+
<a href="#getComponent_PROP">3.4.2 getComponent</a><br />
|
457 |
+
<a href="#newComponent_PROP">3.4.3 newComponent</a><br />
|
458 |
+
<a href="#setComponent_PROP">3.4.4 setComponent</a><br />
|
459 |
+
<br />
|
460 |
+
<a href="#iCalUtilityFunctions">4. iCalUtilityFunctions</a><br />
|
461 |
+
<br />
|
462 |
+
<a href="#createTimezone">4.1 createTimezone</a><br />
|
463 |
+
<br />
|
464 |
+
<a href="#Copyright_and_Licence">5. COPYRIGHT AND LICENSE</a><br />
|
465 |
+
<br />
|
466 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a>
|
467 |
+
|
468 |
+
<a name="Calendar_Component_list"></a><h1>2. Calendar Component list</h1>
|
469 |
+
Quote from <a href="http://www.kigkonsult.se/iCalcreator/iCalDictionary/index.html" title="RFC2445 in HTML format">rfc2445</a>!
|
470 |
+
(Described in iCal output format, content corresponds to xCal format.)<br />
|
471 |
+
|
472 |
+
<a name="VCALENDAR"></a><h2>2.1 VCALENDAR</h2>
|
473 |
+
<p class="center">icalobject = 1*("BEGIN" ":" "VCALENDAR" CRLF</p>
|
474 |
+
<p class="center">icalbody</p>
|
475 |
+
<p class="center">"END" ":" "VCALENDAR" CRLF)</p>
|
476 |
+
<br />
|
477 |
+
icalbody = calprops component
|
478 |
+
<br />
|
479 |
+
calprops = 2*(
|
480 |
+
<br />
|
481 |
+
<p class="center">"prodid" and "version" are both REQUIRED, but MUST NOT occur more than once
|
482 |
+
<p class="center">prodid / <a href="#VERSION">version</a> /</p>
|
483 |
+
<p class="center">"calscale"and "method"are optional, but MUST NOT occur more than once</p>
|
484 |
+
<p class="center"><a href="#CALSCALE">calscale</a> / <a href="#METHOD">method</a> /</p>
|
485 |
+
<p class="center"><a href="#X-PROPERTY">x-prop</a></p>
|
486 |
+
)
|
487 |
+
<br />
|
488 |
+
<p class="center">component = 1*(<a href="#VEVENT">eventc</a> / <a href="#VTODO">todoc</a> / <a href="#VJOURNAL">journalc</a> / <a href="#VFREEBUSY">freebusyc</a> / <a href="#VTIMEZONE">timezonec</a> / iana-comp* / x-comp*)</p>
|
489 |
+
<p class="center">iana-comp = "BEGIN" ":" iana-token CRLF</p>
|
490 |
+
<p class="center">1*contentline</p>
|
491 |
+
<p class="center">"END" ":" iana-token CRLF</p>
|
492 |
+
<p class="center">x-comp = "BEGIN" ":" x-name CRLF</p>
|
493 |
+
<p class="center">1*contentline</p>
|
494 |
+
<p class="center">"END" ":" x-name CRLF</p>
|
495 |
+
*) <span class="comment">not supported by iCalcreator</span></p>
|
496 |
+
<br />
|
497 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_Component_list">[up]</a>
|
498 |
+
|
499 |
+
<a name="VEVENT"></a><h2>2.2 VEVENT</h2>
|
500 |
+
<p class="center">"BEGIN" ":" "VEVENT" CRLF</p>
|
501 |
+
<p class="center">eventprop *alarmc</p>
|
502 |
+
<p class="center">"END" ":" "VEVENT" CRLF</p>
|
503 |
+
eventprop = *(
|
504 |
+
<p class="center">the following are optional,but MUST NOT occur more than once</p>
|
505 |
+
<p class="center"><a href="#CLASS">class</a> / <a href="#CREATED">created</a> / <a href="#DESCRIPTION">description</a> / <a href="#DTSTART">dtstart</a> /</p>
|
506 |
+
<p class="center"><a href="#GEO">geo</a> / <a href="#LAST-MODIFIED">last-mod</a> / <a href="#LOCATION">location</a> / <a href="#ORGANIZER">organizer</a> / <a href="#PRIORITY">priority</a> / </p>
|
507 |
+
<p class="center"><a href="#DTSTAMP">dtstamp</a> / <a href="#SEQUENCE">seq</a> / <a href="#STATUS">status</a> / <a href="#SUMMARY">summary</a> / </p>
|
508 |
+
<p class="center"><a href="#TRANSP">transp</a> / <a href="#UID">uid</a> / <a href="#URL">url</a> / <a href="#RECURRENCE-ID">recurid</a> /</p>
|
509 |
+
<p class="center">either "<a href="#DTEND">dtend</a>" or "<a href="#DURATION">duration</a>" may appear in a "eventprop", </p>
|
510 |
+
<p class="center">but "<a href="#DTEND">dtend</a>" and "<a href="#DURATION">duration</a>" MUST NOT occur in the same "eventprop"</p>
|
511 |
+
<p class="center"><a href="#DTEND">dtend</a> / <a href="#DURATION">duration</a> /</p>
|
512 |
+
<p class="center">the following are optional, and MAY occur more than once</p>
|
513 |
+
<p class="center"><a href="#ATTACH">attach</a> / <a href="#ATTENDEE">attendee</a> / <a href="#CATEGORIES">categories</a> / <a href="#COMMENT">comment</a> / </p>
|
514 |
+
<p class="center"><a href="#CONTACT">contact</a> / <a href="#EXDATE">exdate</a> / <a href="#EXRULE">exrule</a> / <a href="#REQUEST-STATUS">rstatus</a> / </p>
|
515 |
+
<p class="center"><a href="#RELATED-TO">related</a> / <a href="#RESOURCES">resources</a> / <a href="#RDATE">rdate</a> / <a href="#RRULE">rrule</a> / <a href="#X-PROPERTY_PROP">x-prop</a></p>
|
516 |
+
)
|
517 |
+
<br />
|
518 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_Component_list">[up]</a>
|
519 |
+
|
520 |
+
<a name="VTODO"></a><h2>2.3 VTODO</h2>
|
521 |
+
<p class="center">"BEGIN" ":" "VTODO" CRLF</p>
|
522 |
+
<p class="center">todoprop *alarmc</p>
|
523 |
+
<p class="center">"END" ":" "VTODO" CRLF</p>
|
524 |
+
todoprop = *(
|
525 |
+
<p class="center">the following are optional, but MUST NOT occur more than once</p>
|
526 |
+
<p class="center"><a href="#CLASS">class</a> / <a href="#COMPLETED">completed</a> / <a href="#CREATED">created</a> / <a href="#DESCRIPTION">description</a> / <a href="#DTSTAMP">dtstamp</a> / <a href="#DTSTART">dtstart</a> / </p>
|
527 |
+
<p class="center"><a href="#GEO">geo</a> / <a href="#LAST-MODIFIED">last-mod</a> / <a href="#LOCATION">location</a> / <a href="#ORGANIZER">organizer</a> / <a href="#PERCENT-COMPLETE">percent</a> / <a href="#PRIORITY">priority</a> / </p>
|
528 |
+
<p class="center"><a href="#RECURRENCE-ID">recurid</a> / <a href="#SEQUENCE">seq</a> / <a href="#STATUS">status</a> / <a href="#SUMMARY">summary</a> /<a href="#UID">uid</a> / <a href="#URL">url</a> /</p>
|
529 |
+
<p class="center">either "<a href="#DUE">due</a>" or "<a href="#DURATION">duration</a>" may appear in a "todoprop",</p>
|
530 |
+
<p class="center"> but "<a href="#DUE">due</a>" and "<a href="#DURATION">duration</a>" MUST NOT occur in the same "todoprop"</p>
|
531 |
+
<p class="center"><a href="#DUE">due</a> / <a href="#DURATION">duration</a> /</p>
|
532 |
+
<p class="center">the following are optional,and MAY occur more than once</p>
|
533 |
+
<p class="center"><a href="#ATTACH">attach</a> / <a href="#ATTENDEE">attendee</a> / <a href="#CATEGORIES">categories</a> / <a href="#COMMENT">comment</a> / </p>
|
534 |
+
<p class="center"><a href="#CONTACT">contact</a> / <a href="#EXDATE">exdate</a> / <a href="#EXRULE">exrule</a> / <a href="#REQUEST-STATUS">rstatus</a> / </p>
|
535 |
+
<p class="center"><a href="#RELATED-TO">related</a> / <a href="#RESOURCES">resources</a> / <a href="#RDATE">rdate</a> / <a href="#RRULE">rrule</a> / <a href="#X-PROPERTY_PROP">x-prop</a></p>
|
536 |
+
)
|
537 |
+
<br />
|
538 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_Component_list">[up]</a>
|
539 |
+
|
540 |
+
<a name="VJOURNAL"></a><h2>2.4 VJOURNAL</h2>
|
541 |
+
<p class="center">journalc = "BEGIN" ":" "VJOURNAL" CRLF</p>
|
542 |
+
<p class="center">jourprop</p>
|
543 |
+
<p class="center">"END" ":" "VJOURNAL" CRLF</p>
|
544 |
+
jourprop = *(
|
545 |
+
<p class="center">the following are optional, but MUST NOT occur more than once</p>
|
546 |
+
<p class="center"><a href="#CLASS">class</a> / <a href="#CREATED">created</a> / <a href="#DESCRIPTION">description</a> / <a href="#DTSTART">dtstart</a> / </p>
|
547 |
+
<p class="center"><a href="#DTSTAMP">dtstamp</a> / <a href="#LAST-MODIFIED">last-mod</a> / <a href="#ORGANIZER">organizer</a> / <a href="#RECURRENCE-ID">recurid</a> / </p>
|
548 |
+
<p class="center"><a href="#SEQUENCE">seq</a> / <a href="#STATUS">status</a> / <a href="#SUMMARY">summary</a> /<a href="#UID">uid</a> / <a href="#URL">url</a> /</p>
|
549 |
+
<p class="center">the following are optional,and MAY occur more than once</p>
|
550 |
+
<p class="center"><a href="#ATTACH">attach</a> / <a href="#ATTENDEE">attendee</a> / <a href="#CATEGORIES">categories</a> / <a href="#COMMENT">comment</a> /</p>
|
551 |
+
<p class="center"><a href="#CONTACT">contact</a> / <a href="#EXDATE">exdate</a> / <a href="#EXRULE">exrule</a> / <a href="#RELATED-TO">related</a> / </p>
|
552 |
+
<p class="center"><a href="#RDATE">rdate</a> / <a href="#RRULE">rrule</a> / <a href="#REQUEST-STATUS">rstatus</a> / <a href="#X-PROPERTY_PROP">x-prop</a></p>
|
553 |
+
)
|
554 |
+
<br />
|
555 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_Component_list">[up]</a>
|
556 |
+
|
557 |
+
<a name="VFREEBUSY"></a><h2>2.5 VFREEBUSY</h2>
|
558 |
+
<p class="center">"BEGIN" ":" "VFREEBUSY" CRLF</p>
|
559 |
+
<p class="center">fbprop</p>
|
560 |
+
<p class="center">"END" ":" "VFREEBUSY" CRLF</p>
|
561 |
+
fbprop = *(
|
562 |
+
<p class="center">the following are optional, but MUST NOT occur more than once</p>
|
563 |
+
<p class="center"><a href="#CONTACT">contact</a> / <a href="#DTSTART">dtstart</a> / <a href="#DTEND">dtend</a> / <a href="#DURATION">duration</a> / </p>
|
564 |
+
<p class="center"><a href="#DTSTAMP">dtstamp</a> / <a href="#ORGANIZER">organizer</a> / <a href="#UID">uid</a> / <a href="#URL">url</a> / </p>
|
565 |
+
<p class="center">the following are optional,and MAY occur more than once</p>
|
566 |
+
<p class="center"><a href="#ATTENDEE">attendee</a> / <a href="#COMMENT">comment</a> / <a href="#FREEBUSY_PROP">freebusy</a> / <a href="#REQUEST-STATUS">rstatus</a> / <a href="#X-PROPERTY_PROP">x-prop</a></p>
|
567 |
+
)
|
568 |
+
<br />
|
569 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_Component_list">[up]</a>
|
570 |
+
|
571 |
+
<a name="VALARM"></a><h2>2.6 VALARM</h2>
|
572 |
+
<p class="center">"BEGIN" ":" "VALARM" CRLF</p>
|
573 |
+
<p class="center">(audioprop / dispprop / emailprop / procprop)</p>
|
574 |
+
<p class="center">"END" ":" "VALARM" CRLF</p> audioprop = 2*(
|
575 |
+
<p class="center">"<a href="#ACTION">action</a>" and "<a href="#TRIGGER">trigger</a>" are both REQUIRED, but MUST NOT occur more than once</p>
|
576 |
+
<p class="center"><a href="#ACTION">action</a> / <a href="#TRIGGER">trigger</a> /</p>
|
577 |
+
<p class="center">"<a href="#DURATION">duration</a>" and "<a href="#REPEAT">repeat</a>" are both optional,and MUST NOT occur more than once each,</p>
|
578 |
+
<p class="center">but if one occurs, so MUST the other</p>
|
579 |
+
<p class="center"><a href="#DURATION">duration</a> / <a href="#REPEAT">repeat</a> /</p>
|
580 |
+
<p class="center">the following is optional, but MUST NOT occur more than once</p>
|
581 |
+
<p class="center"><a href="#ATTACH">attach</a> / </p>
|
582 |
+
<p class="center">the following is optional, and MAY occur more than once</p>
|
583 |
+
<p class="center"><a href="#X-PROPERTY_PROP">x-prop</a></p>
|
584 |
+
)
|
585 |
+
<br />
|
586 |
+
dispprop = 3*(
|
587 |
+
<p class="center">the following are all REQUIRED, but MUST NOT occur more than once</p>
|
588 |
+
<p class="center"><a href="#ACTION">action</a> / <a href="#DESCRIPTION">description</a> / <a href="#TRIGGER">trigger</a> /</p>
|
589 |
+
<p class="center">"<a href="#DURATION">duration</a>" and "<a href="#REPEAT">repeat</a>" are both optional,and MUST NOT occur more than once each,</p>
|
590 |
+
<p class="center">but if one occurs, so MUST the other</p>
|
591 |
+
<p class="center"><a href="#DURATION">duration</a> / <a href="#REPEAT">repeat</a> /</p>
|
592 |
+
<p class="center">the following is optional, and MAY occur more than once</p>
|
593 |
+
<p class="center"><a href="#X-PROPERTY_PROP">x-prop</a></p>
|
594 |
+
)
|
595 |
+
<br />
|
596 |
+
emailprop = 5*(
|
597 |
+
<p class="center">the following are all REQUIRED, but MUST NOT occur more than once</p>
|
598 |
+
<p class="center"><a href="#ACTION">action</a> / <a href="#DESCRIPTION">description</a> / <a href="#TRIGGER">trigger</a> / <a href="#SUMMARY">summary</a></p>
|
599 |
+
<p class="center">the following is REQUIRED, and MAY occur more than once</p>
|
600 |
+
<p class="center"><a href="#ATTENDEE">attendee</a> / </p>
|
601 |
+
<p class="center">"<a href="#DURATION">duration</a>" and "<a href="#REPEAT">repeat</a>" are both optional, and MUST NOT occur more than once each,</p>
|
602 |
+
<p class="center">but if one occurs, so MUST the other</p>
|
603 |
+
<p class="center"><a href="#DURATION">duration</a> / <a href="#REPEAT">repeat</a> /</p>
|
604 |
+
<p class="center">the following are optional, and MAY occur more than once</p>
|
605 |
+
<p class="center"><a href="#ATTACH">attach</a> / <a href="#X-PROPERTY_PROP">x-prop</a></p>
|
606 |
+
)
|
607 |
+
<br />
|
608 |
+
procprop = 3*(
|
609 |
+
<p class="center">the following are all REQUIRED, but MUST NOT occur more than once</p>
|
610 |
+
<p class="center"><a href="#ACTION">action</a> / <a href="#ATTACH">attach</a> / <a href="#TRIGGER">trigger</a> /</p>
|
611 |
+
<p class="center">"<a href="#DURATION">duration</a>" and "<a href="#REPEAT">repeat</a>" are both optional, and MUST NOT occur more than once each,</p>
|
612 |
+
<p class="center">but if one occurs, so MUST the other</p>
|
613 |
+
<p class="center"><a href="#DURATION">duration</a> /
|
614 |
+
<a href="#REPEAT">repeat</a> /</p>
|
615 |
+
<p class="center">"<a href="#DESCRIPTION">description</a>" is optional, and MUST NOT occur more than once</p>
|
616 |
+
<p class="center"><a href="#DESCRIPTION">description</a> / </p>
|
617 |
+
<p class="center">the following is optional, and MAY occur more than once</p>
|
618 |
+
<p class="center"><a href="#X-PROPERTY_PROP">x-prop</a></p>
|
619 |
+
)
|
620 |
+
<br />
|
621 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_Component_list">[up]</a>
|
622 |
+
|
623 |
+
<a name="VTIMEZONE"></a><h2>2.7 VTIMEZONE</h2>
|
624 |
+
<p class="center">"BEGIN" ":" "VTIMEZONE" CRLF</p>
|
625 |
+
2*(
|
626 |
+
<p class="center">"<a href="#TZID">tzid</a>" is required, but MUST NOT occur more than once</p>
|
627 |
+
<p class="center"><a href="#TZID">tzid</a> / </p>
|
628 |
+
<p class="center">"<a href="#LAST-MODIFIED">last-mod</a>" and "<a href="#TZURL">tzurl</a>" are optional, but MUST NOT occur more than once</p>
|
629 |
+
<p class="center"><a href="#LAST-MODIFIED">last-mod</a> / <a href="#TZURL">tzurl</a> /</p>
|
630 |
+
<p class="center">one of "standardc" or "daylightc" MUST occur and each MAY occur more than once.</p>
|
631 |
+
<p class="center">standardc / daylightc /</p>
|
632 |
+
<p class="center">the following is optional, and MAY occur more than once</p>
|
633 |
+
<p class="center"><a href="#X-PROPERTY_PROP">x-prop</a></p>
|
634 |
+
)
|
635 |
+
<p class="center">"END" ":" "VTIMEZONE" CRLF</p>
|
636 |
+
<p class="center">standardc = "BEGIN" ":" "STANDARD" CRLF</p>
|
637 |
+
<p class="center">tzprop</p>
|
638 |
+
<p class="center">"END" ":" "STANDARD" CRLF</p>
|
639 |
+
<p class="center">daylightc = "BEGIN" ":" "DAYLIGHT" CRLF</p>
|
640 |
+
<p class="center">tzprop</p>
|
641 |
+
<p class="center">"END" ":" "DAYLIGHT" CRLF</p>
|
642 |
+
<br />
|
643 |
+
tzprop = 3*(
|
644 |
+
<p class="center">the following are each REQUIRED, but MUST NOT occur more than once</p>
|
645 |
+
<p class="center"><a href="#DTSTART">dtstart</a> / <a href="#TZOFFSETTO">tzoffsetto</a> / <a href="#TZOFFSETFROM">tzoffsetfrom</a> /</p>
|
646 |
+
<p class="center">the following are optional, and MAY occur more than once</p>
|
647 |
+
<p class="center"><a href="#COMMENT">comment</a> /<a href="#RDATE">rdate</a> / <a href="#RRULE">rrule</a> / <a href="#TZNAME">tzname</a> / <a href="#X-PROPERTY_PROP">x-prop</a></p>
|
648 |
+
)
|
649 |
+
<br />
|
650 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_Component_list">[up]</a>
|
651 |
+
|
652 |
+
<a name="CalProps"></a><h2>2.8 Component Properties</h2>
|
653 |
+
A comprehensive table showing relation between calendar components and properties.
|
654 |
+
<a href="#VTIMEZONE">vtimezone</a> properties are not included.
|
655 |
+
<br /><br />
|
656 |
+
<table>
|
657 |
+
<tr>
|
658 |
+
<td>0-1</td>
|
659 |
+
<td colspan="8">OPTIONAL property, MUST NOT occur more than once.</td>
|
660 |
+
</tr>
|
661 |
+
<tr>
|
662 |
+
<td>0-m</td>
|
663 |
+
<td colspan="8">OPTIONAL property, MAY occur more than once.</td>
|
664 |
+
</tr>
|
665 |
+
<tr>
|
666 |
+
<td>0 or 1=1</td>
|
667 |
+
<td colspan="8">A pair of OPTIONAL properties, MUST NOT occur more than once each.<br />If one occurs, so MUST the other</td>
|
668 |
+
</tr>
|
669 |
+
<tr>
|
670 |
+
<td>0*1</td>
|
671 |
+
<td colspan="8">A pair of OPTIONAL properties, MUST NOT occur more than once each.<br />If one occurs, so MUST NOT the other</td>
|
672 |
+
</tr>
|
673 |
+
<tr>
|
674 |
+
<td>1-m</td>
|
675 |
+
<td colspan="8">REQUIRED property, MAY occur more than once.</td>
|
676 |
+
</tr>
|
677 |
+
<tr>
|
678 |
+
<td>1</td>
|
679 |
+
<td colspan="8">REQUIRED property, MUST NOT occur more than once.</td>
|
680 |
+
</tr>
|
681 |
+
<tr>
|
682 |
+
<td colspan="9"> </td>
|
683 |
+
</tr>
|
684 |
+
<tr>
|
685 |
+
<td> </td>
|
686 |
+
<td class="bl bb center top" rowspan="2"><a class="ref" href="#VEVENT">v<br/>e<br/>v<br/>e<br/>n<br/>t</a></td>
|
687 |
+
<td class="bl bb center top" rowspan="2"><a class="ref" href="#VTODO">v<br/>t<br/>o<br/>d<br/>o</a></td>
|
688 |
+
<td class="bl bb center top" rowspan="2"><a class="ref" href="#VJOURNAL">v<br/>j<br/>o<br/>u<br/>r<br/>n<br/>a<br/>l</a></td>
|
689 |
+
<td class="bl bb center top" rowspan="2"><a class="ref" href="#VFREEBUSY">v<br/>f<br/>r<br/>e<br/>e<br/>b<br/>u<br/>s<br/>y</a></td>
|
690 |
+
<td class="bl top center" colspan="4"><a class="ref" href="#VALARM">v a l a r m</a></td>
|
691 |
+
</tr>
|
692 |
+
<tr>
|
693 |
+
<td class="bb"> </td>
|
694 |
+
<td class="bl bb center ref"><br/><br/><br/><br/>a<br/>u<br/>d<br/>i<br/>o</td>
|
695 |
+
<td class="bl bb center ref"><br/><br/>d<br/>i<br/>s<br/>p<br/>l<br/>a<br/>y</td>
|
696 |
+
<td class="bl bb center ref"><br/><br/><br/><br/>e<br/>m<br/>a<br/>i<br/>l</td>
|
697 |
+
<td class="bl bb center ref">p<br/>r<br/>o<br/>c<br/>e<br/>d<br/>u<br/>r<br/>e</td>
|
698 |
+
</tr>
|
699 |
+
<tr>
|
700 |
+
<td class="bb"><a class="ref" href="#ACTION">action</a></td>
|
701 |
+
<td class="blb"> </td>
|
702 |
+
<td class="blb"> </td>
|
703 |
+
<td class="blb"> </td>
|
704 |
+
<td class="blb"> </td>
|
705 |
+
<td class="blb">1</td>
|
706 |
+
<td class="blb">1</td>
|
707 |
+
<td class="blb">1</td>
|
708 |
+
<td class="blb">1</td>
|
709 |
+
</tr>
|
710 |
+
<tr>
|
711 |
+
<td class="bb"><a class="ref" href="#ATTACH">attach</a></td>
|
712 |
+
<td class="blb">0-m</td>
|
713 |
+
<td class="blb">0-m</td>
|
714 |
+
<td class="blb">0-m</td>
|
715 |
+
<td class="blb"></td>
|
716 |
+
<td class="blb">0-1</td>
|
717 |
+
<td class="blb"> </td>
|
718 |
+
<td class="blb">0-m</td>
|
719 |
+
<td class="blb">1</td>
|
720 |
+
</tr>
|
721 |
+
<tr>
|
722 |
+
<td class="bb"><a class="ref" href="#ATTENDEE">attendee</a></td>
|
723 |
+
<td class="blb">0-m</td>
|
724 |
+
<td class="blb">0-m</td>
|
725 |
+
<td class="blb">0-m</td>
|
726 |
+
<td class="blb">0-m</td>
|
727 |
+
<td class="blb"> </td>
|
728 |
+
<td class="blb"> </td>
|
729 |
+
<td class="blb">1-m</td>
|
730 |
+
<td class="blb"> </td>
|
731 |
+
</tr>
|
732 |
+
<tr>
|
733 |
+
<td class="bb"><a class="ref" href="#CATEGORIES">categories</a></td>
|
734 |
+
<td class="blb">0-m</td>
|
735 |
+
<td class="blb">0-m</td>
|
736 |
+
<td class="blb">0-m</td>
|
737 |
+
<td class="blb"> </td>
|
738 |
+
<td class="blb"> </td>
|
739 |
+
<td class="blb"> </td>
|
740 |
+
<td class="blb"> </td>
|
741 |
+
<td class="blb"> </td>
|
742 |
+
</tr>
|
743 |
+
<tr>
|
744 |
+
<td class="bb"><a class="ref" href="#CLASS">class</a></td>
|
745 |
+
<td class="blb">0-1</td>
|
746 |
+
<td class="blb">0-1</td>
|
747 |
+
<td class="blb">0-1</td>
|
748 |
+
<td class="blb"> </td>
|
749 |
+
<td class="blb"> </td>
|
750 |
+
<td class="blb"> </td>
|
751 |
+
<td class="blb"> </td>
|
752 |
+
<td class="blb"> </td>
|
753 |
+
</tr>
|
754 |
+
<tr>
|
755 |
+
<td class="bb"><a class="ref" href="#COMMENT">comment</a></td>
|
756 |
+
<td class="blb">0-m</td>
|
757 |
+
<td class="blb">0-m</td>
|
758 |
+
<td class="blb">0-m</td>
|
759 |
+
<td class="blb">0-m</td>
|
760 |
+
<td class="blb"> </td>
|
761 |
+
<td class="blb"> </td>
|
762 |
+
<td class="blb"> </td>
|
763 |
+
<td class="blb"> </td>
|
764 |
+
</tr>
|
765 |
+
<tr>
|
766 |
+
<td class="bb"><a class="ref" href="#COMPLETED">completed</a></td>
|
767 |
+
<td class="blb"> </td>
|
768 |
+
<td class="blb">0-1</td>
|
769 |
+
<td class="blb"> </td>
|
770 |
+
<td class="blb"> </td>
|
771 |
+
<td class="blb"> </td>
|
772 |
+
<td class="blb"> </td>
|
773 |
+
<td class="blb"> </td>
|
774 |
+
<td class="blb"> </td>
|
775 |
+
</tr>
|
776 |
+
<tr>
|
777 |
+
<td class="bb"><a class="ref" href="#CONTACT">contact</a></td>
|
778 |
+
<td class="blb">0-m</td>
|
779 |
+
<td class="blb">0-m</td>
|
780 |
+
<td class="blb">0-m</td>
|
781 |
+
<td class="blb">0-1</td>
|
782 |
+
<td class="blb"> </td>
|
783 |
+
<td class="blb"> </td>
|
784 |
+
<td class="blb"> </td>
|
785 |
+
<td class="blb"> </td>
|
786 |
+
</tr>
|
787 |
+
<tr>
|
788 |
+
<td class="bb"><a class="ref" href="#CREATED">created</a></td>
|
789 |
+
<td class="blb">0-1</td>
|
790 |
+
<td class="blb">0-1</td>
|
791 |
+
<td class="blb">0-1</td>
|
792 |
+
<td class="blb"> </td>
|
793 |
+
<td class="blb"> </td>
|
794 |
+
<td class="blb"> </td>
|
795 |
+
<td class="blb"> </td>
|
796 |
+
<td class="blb"> </td>
|
797 |
+
</tr>
|
798 |
+
<tr>
|
799 |
+
<td class="bb"><a class="ref" href="#DESCRIPTION">description</a></td>
|
800 |
+
<td class="blb">0-1</td>
|
801 |
+
<td class="blb">0-1</td>
|
802 |
+
<td class="blb">0-m</td>
|
803 |
+
<td class="blb"> </td>
|
804 |
+
<td class="blb"> </td>
|
805 |
+
<td class="blb">1</td>
|
806 |
+
<td class="blb">1</td>
|
807 |
+
<td class="blb">0-1</td>
|
808 |
+
</tr>
|
809 |
+
<tr>
|
810 |
+
<td class="bb"><a class="ref" href="#DTEND">dtend</a></td>
|
811 |
+
<td class="blb">0*1</td>
|
812 |
+
<td class="blb"> </td>
|
813 |
+
<td class="blb"> </td>
|
814 |
+
<td class="blb">0-1</td>
|
815 |
+
<td class="blb"> </td>
|
816 |
+
<td class="blb"> </td>
|
817 |
+
<td class="blb"> </td>
|
818 |
+
<td class="blb"> </td>
|
819 |
+
</tr>
|
820 |
+
<tr>
|
821 |
+
<td class="bb"><a class="ref" href="#DTSTAMP">dtstamp</a></td>
|
822 |
+
<td class="blb">0-1</td>
|
823 |
+
<td class="blb">0-1</td>
|
824 |
+
<td class="blb">0-1</td>
|
825 |
+
<td class="blb">0-1</td>
|
826 |
+
<td class="blb"> </td>
|
827 |
+
<td class="blb"> </td>
|
828 |
+
<td class="blb"> </td>
|
829 |
+
<td class="blb"> </td>
|
830 |
+
</tr>
|
831 |
+
<tr>
|
832 |
+
<td class="bb"><a class="ref" href="#DTSTART">dtstart</a></td>
|
833 |
+
<td class="blb">0-1</td>
|
834 |
+
<td class="blb">0-1</td>
|
835 |
+
<td class="blb">0-1</td>
|
836 |
+
<td class="blb">0-1</td>
|
837 |
+
<td class="blb"> </td>
|
838 |
+
<td class="blb"> </td>
|
839 |
+
<td class="blb"> </td>
|
840 |
+
<td class="blb"> </td>
|
841 |
+
</tr>
|
842 |
+
<tr>
|
843 |
+
<td class="bb"><a class="ref" href="#DUE">due</a></td>
|
844 |
+
<td class="blb"> </td>
|
845 |
+
<td class="blb">0*1</td>
|
846 |
+
<td class="blb"> </td>
|
847 |
+
<td class="blb"> </td>
|
848 |
+
<td class="blb"> </td>
|
849 |
+
<td class="blb"> </td>
|
850 |
+
<td class="blb"> </td>
|
851 |
+
<td class="blb"> </td>
|
852 |
+
</tr>
|
853 |
+
<tr>
|
854 |
+
<td class="bb"><a class="ref" href="#DURATION">duration</a></td>
|
855 |
+
<td class="blb">0*1</td>
|
856 |
+
<td class="blb">0*1</td>
|
857 |
+
<td class="blb"> </td>
|
858 |
+
<td class="blb">0-1</td>
|
859 |
+
<td class="blb">0 or 1=1</td>
|
860 |
+
<td class="blb">0 or 1=1</td>
|
861 |
+
<td class="blb">0 or 1=1</td>
|
862 |
+
<td class="blb">0 or 1=1</td>
|
863 |
+
</tr>
|
864 |
+
<tr>
|
865 |
+
<td class="bb"><a class="ref" href="#EXDATE">exdate</a></td>
|
866 |
+
<td class="blb">0-m</td>
|
867 |
+
<td class="blb">0-m</td>
|
868 |
+
<td class="blb">0-m</td>
|
869 |
+
<td class="blb"> </td>
|
870 |
+
<td class="blb"> </td>
|
871 |
+
<td class="blb"> </td>
|
872 |
+
<td class="blb"> </td>
|
873 |
+
<td class="blb"> </td>
|
874 |
+
</tr>
|
875 |
+
<tr>
|
876 |
+
<td class="bb"><a class="ref" href="#EXRULE">exrule</a></td>
|
877 |
+
<td class="blb">0-m</td>
|
878 |
+
<td class="blb">0-m</td>
|
879 |
+
<td class="blb">0-m</td>
|
880 |
+
<td class="blb"> </td>
|
881 |
+
<td class="blb"> </td>
|
882 |
+
<td class="blb"> </td>
|
883 |
+
<td class="blb"> </td>
|
884 |
+
<td class="blb"> </td>
|
885 |
+
</tr>
|
886 |
+
<tr>
|
887 |
+
<td class="bb"><a class="ref" href="#FREEBUSY_PROP">freebusy</a></td>
|
888 |
+
<td class="blb"> </td>
|
889 |
+
<td class="blb"> </td>
|
890 |
+
<td class="blb"> </td>
|
891 |
+
<td class="blb">0-m</td>
|
892 |
+
<td class="blb"> </td>
|
893 |
+
<td class="blb"> </td>
|
894 |
+
<td class="blb"> </td>
|
895 |
+
<td class="blb"> </td>
|
896 |
+
</tr>
|
897 |
+
<tr>
|
898 |
+
<td class="bb"><a class="ref" href="#GEO">geo</a></td>
|
899 |
+
<td class="blb">0-1</td>
|
900 |
+
<td class="blb">0-1</td>
|
901 |
+
<td class="blb"> </td>
|
902 |
+
<td class="blb"> </td>
|
903 |
+
<td class="blb"> </td>
|
904 |
+
<td class="blb"> </td>
|
905 |
+
<td class="blb"> </td>
|
906 |
+
<td class="blb"> </td>
|
907 |
+
</tr>
|
908 |
+
<tr>
|
909 |
+
<td class="bb"><a class="ref" href="#LAST-MODIFIED">last-mod</a></td>
|
910 |
+
<td class="blb">0-1</td>
|
911 |
+
<td class="blb">0-1</td>
|
912 |
+
<td class="blb">0-1</td>
|
913 |
+
<td class="blb"></td>
|
914 |
+
<td class="blb"> </td>
|
915 |
+
<td class="blb"> </td>
|
916 |
+
<td class="blb"> </td>
|
917 |
+
<td class="blb"> </td>
|
918 |
+
</tr>
|
919 |
+
<tr>
|
920 |
+
<td class="bb"><a class="ref" href="#LOCATION">location</a></td>
|
921 |
+
<td class="blb">0-1</td>
|
922 |
+
<td class="blb">0-1</td>
|
923 |
+
<td class="blb"> </td>
|
924 |
+
<td class="blb"> </td>
|
925 |
+
<td class="blb"> </td>
|
926 |
+
<td class="blb"> </td>
|
927 |
+
<td class="blb"> </td>
|
928 |
+
<td class="blb"> </td>
|
929 |
+
</tr>
|
930 |
+
<tr>
|
931 |
+
<td class="bb"><a class="ref" href="#ORGANIZER">organizer</a></td>
|
932 |
+
<td class="blb">0-1</td>
|
933 |
+
<td class="blb">0-1</td>
|
934 |
+
<td class="blb">0-1</td>
|
935 |
+
<td class="blb">0-1</td>
|
936 |
+
<td class="blb"> </td>
|
937 |
+
<td class="blb"> </td>
|
938 |
+
<td class="blb"> </td>
|
939 |
+
<td class="blb"> </td>
|
940 |
+
</tr>
|
941 |
+
<tr>
|
942 |
+
<td class="bb"><a class="ref" href="#PERCENT-COMPLETE">percent</a></td>
|
943 |
+
<td class="blb"> </td>
|
944 |
+
<td class="blb">0-1</td>
|
945 |
+
<td class="blb"> </td>
|
946 |
+
<td class="blb"> </td>
|
947 |
+
<td class="blb"> </td>
|
948 |
+
<td class="blb"> </td>
|
949 |
+
<td class="blb"> </td>
|
950 |
+
<td class="blb"> </td>
|
951 |
+
</tr>
|
952 |
+
<tr>
|
953 |
+
<td class="bb"><a class="ref" href="#PRIORITY">priority</a></td>
|
954 |
+
<td class="blb">0-1</td>
|
955 |
+
<td class="blb">0-1</td>
|
956 |
+
<td class="blb"> </td>
|
957 |
+
<td class="blb"> </td>
|
958 |
+
<td class="blb"> </td>
|
959 |
+
<td class="blb"> </td>
|
960 |
+
<td class="blb"> </td>
|
961 |
+
<td class="blb"> </td>
|
962 |
+
</tr>
|
963 |
+
<tr>
|
964 |
+
<td class="bb"><a class="ref" href="#RDATE">rdate</a></td>
|
965 |
+
<td class="blb">0-m</td>
|
966 |
+
<td class="blb">0-m</td>
|
967 |
+
<td class="blb">0-m</td>
|
968 |
+
<td class="blb"> </td>
|
969 |
+
<td class="blb"> </td>
|
970 |
+
<td class="blb"> </td>
|
971 |
+
<td class="blb"> </td>
|
972 |
+
<td class="blb"> </td>
|
973 |
+
</tr>
|
974 |
+
<tr>
|
975 |
+
<td class="bb"><a class="ref" href="#RECURRENCE-ID">recurid</a></td>
|
976 |
+
<td class="blb">0-1</td>
|
977 |
+
<td class="blb">0-1</td>
|
978 |
+
<td class="blb">0-1</td>
|
979 |
+
<td class="blb"> </td>
|
980 |
+
<td class="blb"> </td>
|
981 |
+
<td class="blb"> </td>
|
982 |
+
<td class="blb"> </td>
|
983 |
+
<td class="blb"> </td>
|
984 |
+
</tr>
|
985 |
+
<tr>
|
986 |
+
<td class="bb"><a class="ref" href="#RELATED-TO">related</a></td>
|
987 |
+
<td class="blb">0-m</td>
|
988 |
+
<td class="blb">0-m</td>
|
989 |
+
<td class="blb">0-m</td>
|
990 |
+
<td class="blb"> </td>
|
991 |
+
<td class="blb"> </td>
|
992 |
+
<td class="blb"> </td>
|
993 |
+
<td class="blb"> </td>
|
994 |
+
<td class="blb"> </td>
|
995 |
+
</tr>
|
996 |
+
<tr>
|
997 |
+
<td class="bb"><a class="ref" href="#REPEAT">repeat</a></td>
|
998 |
+
<td class="blb"> </td>
|
999 |
+
<td class="blb"> </td>
|
1000 |
+
<td class="blb"> </td>
|
1001 |
+
<td class="blb"> </td>
|
1002 |
+
<td class="blb">0 or 1=1</td>
|
1003 |
+
<td class="blb">0 or 1=1</td>
|
1004 |
+
<td class="blb">0 or 1=1</td>
|
1005 |
+
<td class="blb">0 or 1=1</td>
|
1006 |
+
</tr>
|
1007 |
+
<tr>
|
1008 |
+
<td class="bb"><a class="ref" href="#RESOURCES">resources</a></td>
|
1009 |
+
<td class="blb">0-m</td>
|
1010 |
+
<td class="blb">0-m</td>
|
1011 |
+
<td class="blb"> </td>
|
1012 |
+
<td class="blb"> </td>
|
1013 |
+
<td class="blb"> </td>
|
1014 |
+
<td class="blb"> </td>
|
1015 |
+
<td class="blb"> </td>
|
1016 |
+
<td class="blb"> </td>
|
1017 |
+
</tr>
|
1018 |
+
<tr>
|
1019 |
+
<td class="bb"><a class="ref" href="#RRULE">rrule</a></td>
|
1020 |
+
<td class="blb">0-m</td>
|
1021 |
+
<td class="blb">0-m</td>
|
1022 |
+
<td class="blb">0-m</td>
|
1023 |
+
<td class="blb"> </td>
|
1024 |
+
<td class="blb"> </td>
|
1025 |
+
<td class="blb"> </td>
|
1026 |
+
<td class="blb"> </td>
|
1027 |
+
<td class="blb"> </td>
|
1028 |
+
</tr>
|
1029 |
+
<tr>
|
1030 |
+
<td class="bb"><a class="ref" href="#REQUEST-STATUS">rstatus</a></td>
|
1031 |
+
<td class="blb">0-m</td>
|
1032 |
+
<td class="blb">0-m</td>
|
1033 |
+
<td class="blb">0-m</td>
|
1034 |
+
<td class="blb">0-m</td>
|
1035 |
+
<td class="blb"> </td>
|
1036 |
+
<td class="blb"> </td>
|
1037 |
+
<td class="blb"> </td>
|
1038 |
+
<td class="blb"> </td>
|
1039 |
+
</tr>
|
1040 |
+
<tr>
|
1041 |
+
<td class="bb"><a class="ref" href="#SEQUENCE">sequence</a></td>
|
1042 |
+
<td class="blb">0-1</td>
|
1043 |
+
<td class="blb">0-1</td>
|
1044 |
+
<td class="blb">0-1</td>
|
1045 |
+
<td class="blb"> </td>
|
1046 |
+
<td class="blb"> </td>
|
1047 |
+
<td class="blb"> </td>
|
1048 |
+
<td class="blb"> </td>
|
1049 |
+
<td class="blb"> </td>
|
1050 |
+
</tr>
|
1051 |
+
<tr>
|
1052 |
+
<td class="bb"><a class="ref" href="#STATUS">status</a></td>
|
1053 |
+
<td class="blb">0-1</td>
|
1054 |
+
<td class="blb">0-1</td>
|
1055 |
+
<td class="blb">0-1</td>
|
1056 |
+
<td class="blb"> </td>
|
1057 |
+
<td class="blb"> </td>
|
1058 |
+
<td class="blb"> </td>
|
1059 |
+
<td class="blb"> </td>
|
1060 |
+
<td class="blb"> </td>
|
1061 |
+
</tr>
|
1062 |
+
<tr>
|
1063 |
+
<td class="bb"><a class="ref" href="#SUMMARY">summary</a></td>
|
1064 |
+
<td class="blb">0-1</td>
|
1065 |
+
<td class="blb">0-1</td>
|
1066 |
+
<td class="blb">0-1</td>
|
1067 |
+
<td class="blb"> </td>
|
1068 |
+
<td class="blb"> </td>
|
1069 |
+
<td class="blb"> </td>
|
1070 |
+
<td class="blb">1</td>
|
1071 |
+
<td class="blb"> </td>
|
1072 |
+
</tr>
|
1073 |
+
<tr>
|
1074 |
+
<td class="bb"><a class="ref" href="#TRANSP">transp</a></td>
|
1075 |
+
<td class="blb">0-1</td>
|
1076 |
+
<td class="blb"> </td>
|
1077 |
+
<td class="blb"> </td>
|
1078 |
+
<td class="blb"> </td>
|
1079 |
+
<td class="blb"> </td>
|
1080 |
+
<td class="blb"> </td>
|
1081 |
+
<td class="blb"> </td>
|
1082 |
+
<td class="blb"> </td>
|
1083 |
+
</tr>
|
1084 |
+
<tr>
|
1085 |
+
<td class="bb"><a class="ref" href="#TRIGGER">trigger</a></td>
|
1086 |
+
<td class="blb"> </td>
|
1087 |
+
<td class="blb"> </td>
|
1088 |
+
<td class="blb"> </td>
|
1089 |
+
<td class="blb"> </td>
|
1090 |
+
<td class="blb">1</td>
|
1091 |
+
<td class="blb">1</td>
|
1092 |
+
<td class="blb">1</td>
|
1093 |
+
<td class="blb">1</td>
|
1094 |
+
</tr>
|
1095 |
+
<tr>
|
1096 |
+
<td class="bb"><a class="ref" href="#UID">uid</a></td>
|
1097 |
+
<td class="blb">0-1</td>
|
1098 |
+
<td class="blb">0-1</td>
|
1099 |
+
<td class="blb">0-1</td>
|
1100 |
+
<td class="blb">0-1</td>
|
1101 |
+
<td class="blb"> </td>
|
1102 |
+
<td class="blb"> </td>
|
1103 |
+
<td class="blb"> </td>
|
1104 |
+
<td class="blb"> </td>
|
1105 |
+
</tr>
|
1106 |
+
<tr>
|
1107 |
+
<td class="bb"><a class="ref" href="#URL">url</a></td>
|
1108 |
+
<td class="blb">0-1</td>
|
1109 |
+
<td class="blb">0-1</td>
|
1110 |
+
<td class="blb">0-1</td>
|
1111 |
+
<td class="blb">0-1</td>
|
1112 |
+
<td class="blb"> </td>
|
1113 |
+
<td class="blb"> </td>
|
1114 |
+
<td class="blb"> </td>
|
1115 |
+
<td class="blb"> </td>
|
1116 |
+
</tr>
|
1117 |
+
<tr>
|
1118 |
+
<td class="bb"><a class="ref" href="#X-PROPERTY_PROP">x-prop</a></td>
|
1119 |
+
<td class="blb">0-m</td>
|
1120 |
+
<td class="blb">0-m</td>
|
1121 |
+
<td class="blb">0-m</td>
|
1122 |
+
<td class="blb">0-m</td>
|
1123 |
+
<td class="blb">0-m</td>
|
1124 |
+
<td class="blb">0-m</td>
|
1125 |
+
<td class="blb">0-m</td>
|
1126 |
+
<td class="blb">0-m</td>
|
1127 |
+
</tr>
|
1128 |
+
</table>
|
1129 |
+
<p>
|
1130 |
+
If not set, <a href="#DTSTART">DTSTART</a> and <a href="#UID">UID</a> are created automatic by iCalcreator for <a href="#VEVENT">vevent</a>, <a href="#VTODO">vtodo</a>, <a href="#VJOURNAL">vjournal</a> and <a href="#VFREEBUSY">vfreebusy</a> components
|
1131 |
+
when using calendar functions <a href="#saveCalendar">saveCalendar</a> or <a href="#returnCalendar">returnCalendar</a> or when fetching DTSTART/UID property value with
|
1132 |
+
component function <a href="#getProperty">getProperty</a>.
|
1133 |
+
</p>
|
1134 |
+
<br />
|
1135 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_Component_list">[up]</a>
|
1136 |
+
|
1137 |
+
<a name="Function_list"></a><h1>3. Function list</h1>
|
1138 |
+
|
1139 |
+
<a name="Calendar_object_functions"></a><h2>3.1 Calendar object functions</h2>
|
1140 |
+
|
1141 |
+
<a name="Calendar_object_constructors"></a><h3>3.1.1 Constructors</h3>
|
1142 |
+
<a name="vcalendar"></a><h2>3.1.1.1 vcalendar</h2>
|
1143 |
+
Create a new <a href="#VCALENDAR">VCALENDAR</a> object.
|
1144 |
+
<p class="label">Format</p>
|
1145 |
+
<p class="format">vcalendar()</p>
|
1146 |
+
<p class="label">Example</p>
|
1147 |
+
<p class="example">$config = array( 'unique_id' => 'domain.org' );
|
1148 |
+
$vcalendar = new vcalendar( $config );
|
1149 |
+
...
|
1150 |
+
</p>
|
1151 |
+
<br />
|
1152 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Function_list">[up]</a>
|
1153 |
+
|
1154 |
+
<a name="vevent"></a><h4>3.1.1.2 vevent</h4>
|
1155 |
+
<p class="label">Format 1</p>
|
1156 |
+
Create a new <a href="#VEVENT">VEVENT</a> object using a calendar factory-method, returning a reference to the new component.
|
1157 |
+
<p class="format">newComponent( 'vevent' )</p>
|
1158 |
+
<p class="label">Example</p>
|
1159 |
+
<p class="example">$config = array( 'unique_id' => 'domain.org' );
|
1160 |
+
$vcalendar = new vcalendar( $config );
|
1161 |
+
...
|
1162 |
+
$vevent = & $vcalendar->newComponent( 'vevent' );
|
1163 |
+
...
|
1164 |
+
</p>
|
1165 |
+
<p class="label">Format 2</p>
|
1166 |
+
Create a new <a href="#VEVENT">VEVENT</a> object.
|
1167 |
+
<p class="format">vevent()</p>
|
1168 |
+
<p class="label">Example</p>
|
1169 |
+
<p class="example">$config = array( 'unique_id' => 'domain.org' );
|
1170 |
+
$vcalendar = new vcalendar( $config );
|
1171 |
+
...
|
1172 |
+
$vevent = new vevent();
|
1173 |
+
...
|
1174 |
+
$vcalendar->setComponent( $vevent );
|
1175 |
+
// <span class="ref">required, inserts component object within calendar object</span>
|
1176 |
+
...
|
1177 |
+
</p>
|
1178 |
+
<br />
|
1179 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Function_list">[up]</a>
|
1180 |
+
|
1181 |
+
<a name="vtodo"></a><h4>3.1.1.3 vtodo</h4>
|
1182 |
+
<p class="label">Format 1</p>
|
1183 |
+
Create a new <a href="#VTODO">VTODO</a> object using a calendar factory-method, returning a reference to the new component.
|
1184 |
+
<p class="format">newComponent( 'vtodo' )</p>
|
1185 |
+
<p class="label">Example</p>
|
1186 |
+
<p class="example">$config = array( 'unique_id' => 'domain.org' );
|
1187 |
+
$vcalendar = new vcalendar( $config );
|
1188 |
+
...
|
1189 |
+
$vtodo = & $vcalendar->newComponent( 'vtodo' );
|
1190 |
+
...
|
1191 |
+
</p>
|
1192 |
+
<p class="label">Format 2</p>
|
1193 |
+
Create a new <a href="#VTODO">VTODO</a> object.
|
1194 |
+
<p class="format">vtodo()</p>
|
1195 |
+
<p class="label">Example</p>
|
1196 |
+
<p class="example">$config = array( 'unique_id' => 'domain.org' );
|
1197 |
+
$vcalendar = new vcalendar( $config );
|
1198 |
+
...
|
1199 |
+
$vtodo = new vtodo();
|
1200 |
+
...
|
1201 |
+
$vcalendar->setComponent( $vtodo );
|
1202 |
+
// <span class="ref">required, inserts component object within calendar object</span>
|
1203 |
+
...
|
1204 |
+
</p>
|
1205 |
+
<br />
|
1206 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Function_list">[up]</a>
|
1207 |
+
|
1208 |
+
<a name="vjournal"></a><h4>3.1.1.4 vjournal</h4>
|
1209 |
+
<p class="label">Format 1</p>
|
1210 |
+
Create a new <a href="#VJOUNAL">VJOURNAL</a> object using a calendar factory-method, returning a reference to the new component.
|
1211 |
+
<p class="format">newComponent( 'vjournal' )</p>
|
1212 |
+
<p class="label">Example</p>
|
1213 |
+
<p class="example">$config = array( 'unique_id' => 'domain.org' );
|
1214 |
+
$vcalendar = new vcalendar( $config );
|
1215 |
+
...
|
1216 |
+
$vjournal = & $vcalendar->newComponent( 'vjournal' );
|
1217 |
+
...
|
1218 |
+
</p>
|
1219 |
+
<p class="label">Format 2</p>
|
1220 |
+
Create a new <a href="#VJOURNAL">VJOURNAL</a> object.
|
1221 |
+
<p class="format">vjournal()</p>
|
1222 |
+
<p class="label">Example</p>
|
1223 |
+
<p class="example">$config = array( 'unique_id' => 'domain.org' );
|
1224 |
+
$vcalendar = new vcalendar( $config );
|
1225 |
+
...
|
1226 |
+
$vjournal = new vjournal();
|
1227 |
+
...
|
1228 |
+
$vcalendar->setComponent( $vjournal );
|
1229 |
+
...
|
1230 |
+
</p>
|
1231 |
+
<br />
|
1232 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Function_list">[up]</a>
|
1233 |
+
|
1234 |
+
<a name="vfreebusy"></a><h4>3.1.1.5 vfreebusy</h4>
|
1235 |
+
<p class="label">Format 1</p>
|
1236 |
+
Create a new <a href="#VFREEBUSY">VFREEBUSY</a> object using a calendar factory-method, returning a reference to the new component.
|
1237 |
+
<p class="format">newComponent( 'vfreebusy' )</p>
|
1238 |
+
<p class="label">Example</p>
|
1239 |
+
<p class="example">$config = array( 'unique_id' => 'domain.org' );
|
1240 |
+
$vcalendar = new vcalendar( $config );
|
1241 |
+
...
|
1242 |
+
$vfreebusy = & $vcalendar->newComponent( 'vfreebusy' );
|
1243 |
+
...
|
1244 |
+
</p>
|
1245 |
+
<p class="label">Format 2</p>
|
1246 |
+
Create a new <a href="#VFREEBUSY">VFREEBUSY</a> object.
|
1247 |
+
<p class="format">vfreebusy()</p>
|
1248 |
+
<p class="label">Example</p>
|
1249 |
+
<p class="example">$config = array( 'unique_id' => 'domain.org' );
|
1250 |
+
$vcalendar = new vcalendar( $config );
|
1251 |
+
...
|
1252 |
+
$vfreebusy = new vfreebusy();
|
1253 |
+
...
|
1254 |
+
$vcalendar->setComponent( $vfreebusy );
|
1255 |
+
// <span class="ref">required, inserts component object within calendar object</span>
|
1256 |
+
...
|
1257 |
+
</p>
|
1258 |
+
<br />
|
1259 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Function_list">[up]</a>
|
1260 |
+
|
1261 |
+
<a name="valarm"></a><h4>3.1.1.6 valarm</h4>
|
1262 |
+
<p class="label">Format 1</p>
|
1263 |
+
Create a new <a href="#VALARM">VALARM</a> object using a component factory-method, returning a reference to the new (sub-)component.
|
1264 |
+
<p class="format">newComponent( 'valarm' )</p>
|
1265 |
+
<p class="label">Example</p>
|
1266 |
+
<p class="example">$config = array( 'unique_id' => 'domain.org' );
|
1267 |
+
$vcalendar = new vcalendar( $config );
|
1268 |
+
...
|
1269 |
+
$vevent = & $vcalendar->newComponent( 'vevent' );
|
1270 |
+
...
|
1271 |
+
$valarm = & $vevent->newComponent( 'valarm' );
|
1272 |
+
...
|
1273 |
+
</p>
|
1274 |
+
<p class="label">Format 2</p>
|
1275 |
+
Create a new <a href="#VALARM">VALARM</a> object.
|
1276 |
+
<p class="format">valarm()</p>
|
1277 |
+
<p class="label">Example</p>
|
1278 |
+
<p class="example">$config = array( 'unique_id' => 'domain.org' );
|
1279 |
+
$vcalendar = new vcalendar( $config );
|
1280 |
+
...
|
1281 |
+
$vevent = new vevent();
|
1282 |
+
...
|
1283 |
+
$valarm = new valarm();
|
1284 |
+
...
|
1285 |
+
$vevent->setComponent( $valarm );
|
1286 |
+
// <span class="ref">required, inserts subcomponent object within component object</span>
|
1287 |
+
$vcalendar->setComponent( $vevent );
|
1288 |
+
// <span class="ref">required, inserts component object within calendar object</span>
|
1289 |
+
...
|
1290 |
+
</p>
|
1291 |
+
<br />
|
1292 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Function_list">[up]</a>
|
1293 |
+
|
1294 |
+
<a name="vtimezone"></a><h4>3.1.1.7 vtimezone</h4>
|
1295 |
+
<p class="label">Format 1</p>
|
1296 |
+
Create a new <a href="#VTIMEZONE">VTIMEZONE</a> object using a calendar factory-method, returning a reference to the new component.
|
1297 |
+
<p class="format">newComponent( 'vtimezone' )</p>
|
1298 |
+
<p class="label">Example</p>
|
1299 |
+
<p class="example">$config = array( 'unique_id' => 'domain.org' );
|
1300 |
+
$vcalendar = new vcalendar( $config );
|
1301 |
+
...
|
1302 |
+
$vtimezone = & $vcalendar->newComponent( 'vtimezone' );
|
1303 |
+
...
|
1304 |
+
</p>
|
1305 |
+
<p class="label">Format 2</p>
|
1306 |
+
Create a new <a href="#VTIMEZONE">VTIMEZONE</a> object.
|
1307 |
+
<p class="format">vtimezone()</p>
|
1308 |
+
<p class="label">Example</p>
|
1309 |
+
<p class="example">$config = array( 'unique_id' => 'domain.org' );
|
1310 |
+
$vcalendar = new vcalendar( $config );
|
1311 |
+
...
|
1312 |
+
$vtimezone = new vtimezone();
|
1313 |
+
...
|
1314 |
+
$vcalendar->setComponent( $vtimezone );
|
1315 |
+
// <span class="ref">required, inserts component object within calendar object</span>
|
1316 |
+
...
|
1317 |
+
</p>
|
1318 |
+
<br />
|
1319 |
+
<h5>Auto create timezone components</h5>
|
1320 |
+
It is possible to auto create timezone components, using a function in iCalUtilityFunctions class, createTimezone,
|
1321 |
+
and utilizing The PHP DateTimeZone class (PHP 5 >= 5.2.0).
|
1322 |
+
<p class="label">Format</p>
|
1323 |
+
<p class="format">iCalUtilityFunctions::createTimezone( vcalendar calendar, string timezone)</p>
|
1324 |
+
<p class="comment">calendar = vcalendar instance
|
1325 |
+
timezone = a PHP5 (DateTimeZone) valid timezone
|
1326 |
+
</p>
|
1327 |
+
<p class="label">Example</p>
|
1328 |
+
<p class="example">$config = array( 'unique_id' => 'domain.org' );
|
1329 |
+
$vcalendar = new vcalendar( $config );
|
1330 |
+
iCalUtilityFunctions::createTimezone( $vcalendar, 'Europe/Stockholm' )</p>
|
1331 |
+
will results in (when using function createCalendar/returnCalendar)
|
1332 |
+
<p class="comment">BEGIN:VTIMEZONE
|
1333 |
+
TZID:Europe/Stockholm
|
1334 |
+
BEGIN:STANDARD
|
1335 |
+
DTSTART:20101031T020000
|
1336 |
+
TZOFFSETFROM:+0200
|
1337 |
+
TZOFFSETTO:+0100
|
1338 |
+
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
|
1339 |
+
TZNAME:CET
|
1340 |
+
END:STANDARD
|
1341 |
+
BEGIN:DAYLIGHT
|
1342 |
+
DTSTART:20100328T030000
|
1343 |
+
TZOFFSETFROM:+0100
|
1344 |
+
TZOFFSETTO:+0200
|
1345 |
+
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
|
1346 |
+
TZNAME:CEST
|
1347 |
+
END:DAYLIGHT
|
1348 |
+
END:VTIMEZONE</p>
|
1349 |
+
<br />
|
1350 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Function_list">[up]</a>
|
1351 |
+
|
1352 |
+
<a name="standard"></a><h4>3.1.1.8 standard</h4>
|
1353 |
+
<p class="label">Format 1</p>
|
1354 |
+
Create a new <a href="#VTIMEZONE">VTIMEZONE</a> <b>standard</b> object using a component factory-method, returning a reference to the new (sub-)component.
|
1355 |
+
<p class="format">newComponent( 'standard' )</p>
|
1356 |
+
<p class="label">Example</p>
|
1357 |
+
<p class="example">$config = array( 'unique_id' => 'domain.org' );
|
1358 |
+
$vcalendar = new vcalendar( $config );
|
1359 |
+
...
|
1360 |
+
$vtimezone = & $vcalendar->newComponent( 'vtimezone' );
|
1361 |
+
...
|
1362 |
+
$standard = & $vtimezone->newComponent( 'standard' );
|
1363 |
+
...
|
1364 |
+
$daylight = & $vtimezone->newComponent( 'daylight' );
|
1365 |
+
...
|
1366 |
+
</p>
|
1367 |
+
<p class="label">Format 2</p>
|
1368 |
+
Create a new <a href="#VTIMEZONE">VTIMEZONE</a> STANDARD object.
|
1369 |
+
<p class="format">vtimezone( 'standard' )</p>
|
1370 |
+
<p class="label">Example</p>
|
1371 |
+
<p class="example">$config = array( 'unique_id' => 'domain.org' );
|
1372 |
+
$vcalendar = new vcalendar( $config );
|
1373 |
+
...
|
1374 |
+
$vtimezone = new vtimezone();
|
1375 |
+
...
|
1376 |
+
$standard = new vtimezone( 'standard' );
|
1377 |
+
...
|
1378 |
+
$vtimezone->setComponent( $standard );
|
1379 |
+
// <span class="ref">required, inserts subcomponent object within component object</span>
|
1380 |
+
$daylight = new vtimezone( 'daylight' );
|
1381 |
+
...
|
1382 |
+
$vtimezone->setComponent( $daylight );
|
1383 |
+
// <span class="ref">required, inserts subcomponent object within component object</span>
|
1384 |
+
$vcalendar->setComponent( $vtimezone );
|
1385 |
+
// <span class="ref">required, inserts component object within calendar object</span>
|
1386 |
+
...
|
1387 |
+
</p>
|
1388 |
+
<br />
|
1389 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Function_list">[up]</a>
|
1390 |
+
|
1391 |
+
<a name="daylight"></a><h4>3.1.1.9 daylight</h4>
|
1392 |
+
<p class="label">Format 1</p>
|
1393 |
+
Create a new <a name="VTIMEZONE">VTIMEZONE</a> <b>daylight</b> object using a component factory-method, returning a reference to the new (sub-)component.
|
1394 |
+
<p class="format">newComponent( 'standard' )</p>
|
1395 |
+
<p class="label">Example</p>
|
1396 |
+
<p class="example">$config = array( 'unique_id' => 'domain.org' );
|
1397 |
+
$vcalendar = new vcalendar( $config );
|
1398 |
+
...
|
1399 |
+
$vtimezone = & $vcalendar->newComponent( 'vtimezone' );
|
1400 |
+
...
|
1401 |
+
$standard = & $vtimezone->newComponent( 'standard' );
|
1402 |
+
...
|
1403 |
+
$daylight = & $vtimezone->newComponent( 'daylight' );
|
1404 |
+
...
|
1405 |
+
</p>
|
1406 |
+
<p class="label">Format 2</p>
|
1407 |
+
Create a new <a href="#VTIMEZONE">VTIMEZONE</a> DAYLIGHT object.
|
1408 |
+
<p class="format">vtimezone( 'daylight' )</p>
|
1409 |
+
<p class="label">Example</p>
|
1410 |
+
<p class="example"></p>
|
1411 |
+
<p class="example">$config = array( 'unique_id' => 'domain.org' );
|
1412 |
+
$vcalendar = new vcalendar( $config );
|
1413 |
+
...
|
1414 |
+
$vtimezone = new vtimezone();
|
1415 |
+
...
|
1416 |
+
$standard = new vtimezone( 'standard' );
|
1417 |
+
...
|
1418 |
+
$vtimezone->setComponent( $standard );
|
1419 |
+
$daylight = new vtimezone( 'daylight' );
|
1420 |
+
...
|
1421 |
+
$vtimezone->setComponent( $daylight );
|
1422 |
+
$vcalendar->setComponent( $vtimezone );
|
1423 |
+
...
|
1424 |
+
</p>
|
1425 |
+
<br />
|
1426 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Function_list">[up]</a>
|
1427 |
+
|
1428 |
+
|
1429 |
+
<a name="Calendar_property_functions"></a><h3>3.1.2 Calendar property functions</h3>
|
1430 |
+
|
1431 |
+
<a name="deleteProperty"></a><h4>3.1.2.1 deleteProperty</h4>
|
1432 |
+
General calendar deleteProperty function, simplifying removal of calendar properties.<br />
|
1433 |
+
FALSE is returned if no property exists or when end-of-properties at consecutive function calls.
|
1434 |
+
<p class="label">Format</p>
|
1435 |
+
<p class="format">deleteProperty( [ string PropName [, int order=1 ] )</p>
|
1436 |
+
<p class="comment">propName - case independent, rfc2445 component property names,
|
1437 |
+
unknown/missing propName will be regarded as <a href="#X-PROPERTY">X-property</a>.
|
1438 |
+
order - if missing 1st/next occurrence,
|
1439 |
+
used with multiple (property) occurrences
|
1440 |
+
</p>
|
1441 |
+
<p class="label">Example 1</p>
|
1442 |
+
<p class="example">$config = array( "unique_id" => "domain.com", "filename" => "file.ics" );
|
1443 |
+
$vcalendar = new vcalendar( $config );
|
1444 |
+
$vcalendar->parse();
|
1445 |
+
if( !$vcalendar->deleteProperty( "method" ))
|
1446 |
+
echo "METHOD property not found";
|
1447 |
+
.. .
|
1448 |
+
</p>
|
1449 |
+
<br />
|
1450 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_property_functions">[up]</a>
|
1451 |
+
|
1452 |
+
<a name="getProperty"></a><h4>3.1.2.2 getProperty</h4>
|
1453 |
+
<p class="label">Format 1</p>
|
1454 |
+
General calendar getProperty function, simplifying fetch of calendar properties.<br />
|
1455 |
+
FALSE is returned if no property exists or when end-of-properties at consecutive function calls.
|
1456 |
+
<p class="format">getProperty( [ string PropName [, int order=1 [, bool complete=FALSE ]]] )</p>
|
1457 |
+
<p class="comment">propName - case independent, rfc2445 component property names,
|
1458 |
+
unknown/missing propName will be regarded as <a href="#X-PROPERTY">X-property</a>.
|
1459 |
+
order - if missing 1st/next occurrence,
|
1460 |
+
used with multiply (property) occurrences
|
1461 |
+
complete - FALSE (default) : output only property value
|
1462 |
+
- TRUE : output =
|
1463 |
+
array( "value"=> <value> ,"params" => <parameter array>)
|
1464 |
+
</p>
|
1465 |
+
<p class="label">Example 1</p>
|
1466 |
+
<p class="example">$config = array( "unique_id" => "domain.com", "filename" => "file.ics" );
|
1467 |
+
$vcalendar = new vcalendar( $config );
|
1468 |
+
$vcalendar->parse();
|
1469 |
+
$calscale = $vcalendar->getProperty( "calscale" );
|
1470 |
+
.. .
|
1471 |
+
</p>
|
1472 |
+
<p class="label">Example 2</p>
|
1473 |
+
<p class="example">$config = array( "unique_id" => "domain.com", "filename" => "file.ics" );
|
1474 |
+
$vcalendar = new vcalendar( $config );
|
1475 |
+
$vcalendar->parse();
|
1476 |
+
while( $xprop = $vcalendar->getProperty( )) { // <span class="ref">get x-properties in order.. .</span>
|
1477 |
+
.. .
|
1478 |
+
</p>
|
1479 |
+
<p class="label">Format 2</p>
|
1480 |
+
Ability to fetch specific property (unique) values and number of ocurrencies,
|
1481 |
+
<a href="#ATTENDEE">ATTENDEE</a>, <a href="#CATEGORIES">CATEGORIES</a>, <a href="#DTSTART">DTSTART</a>, <a href="#LOCATION">LOCATION</a>, <a href="#ORGANIZER">ORGANIZER</a>, <a href="#PRIORITY">PRIORITY</a>, <a href="#RESOURCES">RESOURCES</a>,
|
1482 |
+
<a href="#STATUS">STATUS</a>, <a href="#SUMMARY">SUMMARY</a>, <a href="#UID">UID</a> or "RECURRENCE-ID-UID" (alt. "R-UID" ) from <b>ALL</b> components within calendar.<br />
|
1483 |
+
Outputs an array( *[<unique-property-value> => <number of ocurrency>] )<br />or an empty array if no hits.<br />
|
1484 |
+
If a property contains multiple values (ex. "RESOURCES:pc,developer" or "CATAGORIES:course1,courseB"), they are split into unique values.
|
1485 |
+
<p class="format">getProperty( string PropName )</p>
|
1486 |
+
<p class="comment">propName - case independent, above
|
1487 |
+
<a href="#DTSTART">DTSTART</a> as argument returns dates, in format "YYYYMMDD",
|
1488 |
+
"RECURRENCE-ID-UID"returns <a href="#UID">UID</a> values for component(-s) where <a href="#RECURRENCE-ID">RECURRENCE-ID</a> is set.
|
1489 |
+
<a href="#ATTENDEE">ATTENDEE</a> and <a href="#ORGANIZER">ORGANIZER</a> values are prefixed by protocol ex."MAILTO:chair@ical.net".
|
1490 |
+
</p>
|
1491 |
+
<br />
|
1492 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_property_functions">[up]</a>
|
1493 |
+
|
1494 |
+
<a name="setProperty"></a><h4>3.1.2.3 setProperty</h4>
|
1495 |
+
General calendar setProperty function,simplifying insert of calendar properties.<br />
|
1496 |
+
A successful update returns TRUE.
|
1497 |
+
<p class="label">Format</p>
|
1498 |
+
<p class="format">setProperty( string PropName, mixed Proparg_1 *[, mixed Proparg_n] )</p>
|
1499 |
+
propName case independent, strict rfc2445 calendar property names, unknown propName will be regarded as <a href="#X-PROPERTY">X-property</a>.
|
1500 |
+
<p class="label">Example</p>
|
1501 |
+
<p class="example">$config = array( "unique_id" => "domain.com", "filename" => "file.ics" );
|
1502 |
+
$vcalendar = new vcalendar( $config ); // <span class="ref">initiate new CALENDAR</span>
|
1503 |
+
$vcalendar->setProperty( "calscale", "GREGORIAN" );
|
1504 |
+
</p>
|
1505 |
+
<br />
|
1506 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_property_functions">[up]</a>
|
1507 |
+
|
1508 |
+
<a name="CALSCALE"></a><h4>3.1.2.4 CALSCALE</h4>
|
1509 |
+
This property defines the calendar scale used for the calendar information specified in the iCalendar object.
|
1510 |
+
<br /><br />
|
1511 |
+
The default value is "GREGORIAN", implied when missing.
|
1512 |
+
<h5>Delete CALSCALE</h5>
|
1513 |
+
Remove CALSCALE from component.
|
1514 |
+
<p class="label">Format</p>
|
1515 |
+
<p class="format">deleteProperty( "calscale" )</p>
|
1516 |
+
<p class="label">Example</p>
|
1517 |
+
<p class="example">$vcalendar->deleteProperty( "CALSCALE" );</p>
|
1518 |
+
<h5>Get Calscale</h5>
|
1519 |
+
Fetch property value.
|
1520 |
+
<p class="label">Format</p>
|
1521 |
+
<p class="format">getProperty( "calscale" )</p>
|
1522 |
+
<p class="label">Example</p>
|
1523 |
+
<p class="example">$config = array( "unique_id" => "domain.com", "filename" => "file.ics" );
|
1524 |
+
$vcalendar = new vcalendar( $config );
|
1525 |
+
$vcalendar->parse();
|
1526 |
+
$calscale = $vcalendar->getProperty( "calscale" );
|
1527 |
+
.. .
|
1528 |
+
</p>
|
1529 |
+
<h5>Set CALSCALE</h5>
|
1530 |
+
Insert property value.
|
1531 |
+
<p class="label">Format</p>
|
1532 |
+
<p class="format">setProperty( "calscale", string value )</p>
|
1533 |
+
<p class="label">Example</p>
|
1534 |
+
<p class="example">
|
1535 |
+
$config = array( "unique_id" => "domain.com" );
|
1536 |
+
$vcalendar = new vcalendar( $config ); // <span class="ref">initiate new CALENDAR</span>
|
1537 |
+
$vcalendar->setProperty( "calscale", "GREGORIAN" );
|
1538 |
+
.. .
|
1539 |
+
</p>
|
1540 |
+
<br />
|
1541 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_property_functions">[up]</a>
|
1542 |
+
|
1543 |
+
|
1544 |
+
<a name="METHOD"></a><h4>3.1.2.5 METHOD</h4>
|
1545 |
+
This property defines the iCalendar object method associated with the calendar object.
|
1546 |
+
<br /><br />
|
1547 |
+
METHOD property (value PUBLISH etc.) may be required when importing iCal files
|
1548 |
+
into some calendaring software (MS etc.), as well as <a href="#X-PROPERTY">x-properties</a>
|
1549 |
+
"X-WR-CALNAME", "X-WR-CALDESC" and "X-WR-TIMEZONE"
|
1550 |
+
and (auto created) <a href="#DTSTAMP">DTSTAMP</a> and <a href="#UID">UID</a> properties.
|
1551 |
+
<h5>Delete METHOD</h5>
|
1552 |
+
Remove METHOD from component.
|
1553 |
+
<p class="label">Format</p>
|
1554 |
+
<p class="format">deleteProperty( "METHOD" )</p>
|
1555 |
+
<p class="label">Example</p>
|
1556 |
+
<p class="example">$vcalendar->deleteProperty( "METHOD" );</p>
|
1557 |
+
<h5>Get METHOD</h5>
|
1558 |
+
Fetch property value.
|
1559 |
+
<p class="label">Format</p>
|
1560 |
+
<p class="format">getProperty( "method" );</p>
|
1561 |
+
<p class="label">Example</p>
|
1562 |
+
<p class="example">$config = array( "unique_id" => "domain.com" );
|
1563 |
+
$vcalendar = new vcalendar( $config );
|
1564 |
+
$vcalendar->parse();
|
1565 |
+
$method = $vcalendar->getProperty( "method" )
|
1566 |
+
.. .
|
1567 |
+
</p>
|
1568 |
+
<h5>Set METHOD</h5>
|
1569 |
+
Insert property value.
|
1570 |
+
<p class="label">Format</p>
|
1571 |
+
<p class="format">setProperty( "method", string value )</p>
|
1572 |
+
<p class="label">Example</p>
|
1573 |
+
<p class="example">$config = array( "unique_id" => "domain.com" );
|
1574 |
+
$vcalendar = new vcalendar( $config ); // <span class="ref">initiate new CALENDAR</span>
|
1575 |
+
$vcalendar->setProperty( "method", "PUBLISH" )
|
1576 |
+
</p>
|
1577 |
+
<br />
|
1578 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_property_functions">[up]</a>
|
1579 |
+
|
1580 |
+
|
1581 |
+
<a name="VERSION"></a><h4>3.1.2.6 VERSION</h4>
|
1582 |
+
This property specifies the identifier corresponding to the highest version number or the minimum
|
1583 |
+
and maximum range of the iCalendar specification that is required in order to interpret the iCalendar object.<br />
|
1584 |
+
This property is always placed first in the calendar file.<br />
|
1585 |
+
<h5>Get Version</h5>
|
1586 |
+
Fetch property value.
|
1587 |
+
<p class="label">Format</p>
|
1588 |
+
<p class="format">getProperty( "version" )</p>
|
1589 |
+
<p class="label">Example</p>
|
1590 |
+
<p class="example">$config = array( "unique_id" => "domain.com", "filename" => "file.ics" );
|
1591 |
+
$vcalendar = new vcalendar( $config );
|
1592 |
+
$vcalendar->parse();
|
1593 |
+
$version = $vcalendar->getProperty( "version" )
|
1594 |
+
.. .
|
1595 |
+
</p>
|
1596 |
+
<h5>Set Version</h5>
|
1597 |
+
Insert property value.
|
1598 |
+
Only version 2.0 valid, version is <b>AUTO</b> generated at calendar creation.
|
1599 |
+
<p class="label">Format</p>
|
1600 |
+
<p class="format">setProperty( "version", string version )</p>
|
1601 |
+
<p class="label">Example</p>
|
1602 |
+
<p class="example">$config = array( "unique_id" => "domain.com" );
|
1603 |
+
$vcalendar = new vcalendar( $config ); // <span class="ref">initiate new CALENDAR</span>
|
1604 |
+
$vcalendar->setProperty( "version", "2.0" )
|
1605 |
+
</p>
|
1606 |
+
<br />
|
1607 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_property_functions">[up]</a>
|
1608 |
+
|
1609 |
+
<a name="X-PROPERTY"></a><h4>3.1.2.7 X-PROPERTY</h4>
|
1610 |
+
A calendar, non-standard property with a TEXT value and a name with an "X-" prefix. In a calendar,
|
1611 |
+
an x-prop, with an unique name, can occur only once but the number of x-props are unlimited.
|
1612 |
+
<br /><br />
|
1613 |
+
X-properties "X-WR-CALNAME", "X-WR-CALDESC" and "X-WR-TIMEZONE" may be required when importing iCal files
|
1614 |
+
into some calendaring software (MS etc.), as well as <a href="#METHOD">METHOD</a> property (value PUBLISH etc.)
|
1615 |
+
and (auto created) <a href="#DTSTAMP">DTSTAMP</a> and <a href="#UID">UID</a> properties.
|
1616 |
+
<h5>Delete X-PROPERTY</h5>
|
1617 |
+
Remove X-PROPERTY from calendar.
|
1618 |
+
<p class="label">Format</p>
|
1619 |
+
<p class="format">deleteProperty( "<X-PROPERTY>" )</p>
|
1620 |
+
<p class="label">Example 1</p>
|
1621 |
+
<p class="example">$vcalendar->deleteProperty( "<X-PROPERTY>" );</p>
|
1622 |
+
<p class="label">Example 2</p>
|
1623 |
+
Deleting all x-properties.
|
1624 |
+
<p class="example">while( $vcalendar->deleteProperty())
|
1625 |
+
continue;</p>
|
1626 |
+
<h5>Get X-PROPERTY</h5>
|
1627 |
+
Fetch property value.
|
1628 |
+
<p class="label">Format</p>
|
1629 |
+
<p class="format">getProperty()<br />
|
1630 |
+
getProperty( "<X-PROPERTY>" )</p>
|
1631 |
+
<p class="comment">output = array( propertyName<span class="ref">1</span>, propertyData<span class="ref">2</span> )</p>
|
1632 |
+
<p class="format">getProperty( FALSE, propOrderNo/FALSE, TRUE )</p>
|
1633 |
+
<p class="comment">output = array( propertyName<span class="ref">1</span>
|
1634 |
+
, array( "value" => propertyData<span class="ref">2</span> )
|
1635 |
+
, "params" => params<span class="ref"> 3</span>))
|
1636 |
+
</p>
|
1637 |
+
<p class="label">Example 1</p>
|
1638 |
+
<p class="example">$config = array( "unique_id" => "domain.com", "filename" => "file.ics" );
|
1639 |
+
$vcalendar = new vcalendar( $config );
|
1640 |
+
$vcalendar->parse();
|
1641 |
+
while( $xprop = $vcalendar->getProperty( )) { //<span class="ref">read all x-props in a loop</span>
|
1642 |
+
.. .
|
1643 |
+
</p>
|
1644 |
+
<p class="comment">$xprop = array( propertyName<span class="ref">1</span>, propertyData<span class="ref">2</span> )</p>
|
1645 |
+
<p class="label">Example 2</p>
|
1646 |
+
<p class="example">$config = array( "unique_id" => "domain.com", "filename" => "file.ics" );
|
1647 |
+
$vcalendar = new vcalendar( $config );
|
1648 |
+
$vcalendar->parse();
|
1649 |
+
if( $xprop = $vcalendar->getProperty( "X-WR-TIMEZONE" )) {
|
1650 |
+
//<span class="ref">if exists, read X-WR-TIMEZONE x-prop</span>
|
1651 |
+
.. .
|
1652 |
+
</p>
|
1653 |
+
<p class="comment">$xprop = array( "X-WR-TIMEZONE", propertyData<span class="ref">2</span> )</p>
|
1654 |
+
<p class="label">Example 3</p>
|
1655 |
+
<p class="example">$config = array( "unique_id" => "domain.com", "filename" => "file.ics" );
|
1656 |
+
$vcalendar = new vcalendar( $config );
|
1657 |
+
$vcalendar->parse();
|
1658 |
+
while( $xprop = $vcalendar->getProperty( FALSE, FALSE, TRUE )) {
|
1659 |
+
.. .
|
1660 |
+
</p>
|
1661 |
+
<p class="comment">$xprop = array( propertyName<span class="ref">1</span>
|
1662 |
+
, array( "value " => propertyData<span class="ref">2</span> )
|
1663 |
+
, "params "=> params<span class="ref"> 3</span> )
|
1664 |
+
</p>
|
1665 |
+
<h5>Set X-PROPERTY</h5>
|
1666 |
+
Insert property name and value. If an x-prop with the same name already exists, it will be replaced.
|
1667 |
+
PropertyNames are always stored upperCase, ex. x-wr-calname => X-WR-CALNAME.
|
1668 |
+
<p class="label">Format</p>
|
1669 |
+
<p class="format">setProperty( propertyName, propertyData [, params ] )</p>
|
1670 |
+
<p class="comment">propertyName<span class="ref">1</span> = Any property name with a "X-" prefix
|
1671 |
+
propertyData<span class="ref">2</span> = Value type TEXT
|
1672 |
+
params<span class="ref">3</span> = array( ["LANGUAGE" => "<lang>"] [, xparam] )
|
1673 |
+
xparam = *[ xparamkey => xparamvalue ]
|
1674 |
+
propOrderNo = int ordernumber, 1=1st, 2=2nd etc</p>
|
1675 |
+
</p>
|
1676 |
+
<p class="label">Example</p>
|
1677 |
+
<p class="example">$config = array( "unique_id" => "domain.com" );
|
1678 |
+
$vcalendar = new vcalendar( $config ); // initiate new CALENDAR
|
1679 |
+
// <span class="ref">set some X-properties.. .</span>
|
1680 |
+
$vcalendar->setProperty( "x-wr-calname", "Calendar Sample" )
|
1681 |
+
$vcalendar->setProperty( "X-WR-CALDESC", "Calendar Description" );
|
1682 |
+
$vcalendar->setProperty( "X-WR-TIMEZONE", "Europe/Stockholm" );
|
1683 |
+
</p>
|
1684 |
+
<br />
|
1685 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_property_functions">[up]</a>
|
1686 |
+
|
1687 |
+
<a name="Calendar_component_functions"></a><h3>3.1.3 Calendar component functions</h3>
|
1688 |
+
|
1689 |
+
<a name="deleteComponent"></a><h4>3.1.3.1 deleteComponent</h4>
|
1690 |
+
Remove component from calendar.<br />
|
1691 |
+
FALSE is returned if no property exists or when end-of-properties at consecutive function calls.
|
1692 |
+
<p class="label">format 1</p>
|
1693 |
+
Remove component with order number (1st=1, 2nd=2.. .).
|
1694 |
+
<p class="format">deleteComponent( int orderNumber )</p>
|
1695 |
+
<p class="label">format 2</p>
|
1696 |
+
Remove component with component type (e.g. "vevent") and order 1 alt. suborder number.
|
1697 |
+
<p class="format">deleteComponent( string componentType [, int componentSuborderNumber])</p>
|
1698 |
+
<p class="label">format 3</p>
|
1699 |
+
Remove component with <a href="#UID">UID</a>. N.B <a href="#UID">UID</a> is NOT set for
|
1700 |
+
<a href="#VALARM">ALARM</a> / <a href="#VTIMEZONE">TIMEZONE</a> components.
|
1701 |
+
<p class="format">deleteComponent( string <a href="#UID">UID</a> )</p>
|
1702 |
+
<p class="label">Example 1</p>
|
1703 |
+
<p class="example">$config = array( "unique_id" => "domain.com", "filename" => "file.ics" );
|
1704 |
+
$vcalendar = new vcalendar( $config );
|
1705 |
+
$vcalendar->parse();
|
1706 |
+
$vcalendar->deleteComponent( 1 );
|
1707 |
+
$vcalendar->deleteComponent( "vtodo", 2 );
|
1708 |
+
$vcalendar->deleteComponent( "20070803T194810CEST-0123U3PXiX@domain.com");
|
1709 |
+
.. .
|
1710 |
+
</p>
|
1711 |
+
<p class="label">Example 2</p>
|
1712 |
+
Deleting all components, using format 2 without order number.
|
1713 |
+
<p class="example">$config = array( "unique_id" => "domain.com", "filename" => "file.ics" );
|
1714 |
+
$vcalendar = new vcalendar( $config );
|
1715 |
+
$vcalendar->parse();
|
1716 |
+
.. .
|
1717 |
+
while( $vcalendar->deleteComponent( "vevent"))
|
1718 |
+
continue;
|
1719 |
+
.. .
|
1720 |
+
$vtodo = $vcalendar->getComponent( 'vtodo' );
|
1721 |
+
while( $vtodo->deleteComponent( "valarm"))
|
1722 |
+
continue;
|
1723 |
+
.. .
|
1724 |
+
</p>
|
1725 |
+
<br />
|
1726 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_functions">[up]</a>
|
1727 |
+
|
1728 |
+
<a name="getComponent"></a><h4>3.1.3.2 getComponent</h4>
|
1729 |
+
Get component from calendar.<br />
|
1730 |
+
FALSE is returned if no property exists or when end-of-properties at consecutive function calls.
|
1731 |
+
|
1732 |
+
<p class="label">format 1</p>
|
1733 |
+
Get next component, until end-of-components.
|
1734 |
+
<p class="format">getComponent()</p>
|
1735 |
+
|
1736 |
+
<p class="label">format 2</p>
|
1737 |
+
Get specific component with order number (1st=1, 2nd=2.. .).
|
1738 |
+
<p class="format">getComponent( int orderNumber )</p>
|
1739 |
+
|
1740 |
+
<p class="label">format 3</p>
|
1741 |
+
Get (first/next) component with component type (until end-of-components) alt.
|
1742 |
+
get specific component with component type and suborder number (1st=1, 2nd=2.. .).
|
1743 |
+
<p class="format">getComponent( string componentType [, int componentSuborderNumber])</p>
|
1744 |
+
|
1745 |
+
<p class="label">format 4</p>
|
1746 |
+
Get (first/next) component with <a href="#UID">UID</a> as key. (<a href="#UID">UID</a> is NOT set for
|
1747 |
+
<a href="#VALARM">ALARM</a> / <a href="#VTIMEZONE">TIMEZONE</a> components.)
|
1748 |
+
<p class="format">getComponent( string <a href="#UID">UID</a> )</p>
|
1749 |
+
|
1750 |
+
<p class="label">format 5</p>
|
1751 |
+
Get (first/next) component based on specific property contents;
|
1752 |
+
<a href="#DTSTART">DTSTART</a>, <a href="#DTEND">DTEND</a>, <a href="#DUE">DUE</a>, <a href="#CREATED">CREATED</a>, <a href="#COMPLETED">COMPLETED</a>, <a href="#DTSTAMP">DTSTAMP</a>, <a href="#LAST-MODIFIED">LAST-MODIFIED</a>, <a href="#RECURRENCE-ID">RECURRENCE-ID</a>,
|
1753 |
+
<a href="#ATTENDEE">ATTENDEE</a>, <a href="#CATEGORIES">CATEGORIES</a>, <a href="#LOCATION">LOCATION</a>, <a href="#ORGANIZER">ORGANIZER</a>, <a href="#PRIORITY">PRIORITY</a>, <a href="RESOURCES">RESOURCES</a>, <a href="STATUS">STATUS</a>, <a href="#SUMMARY">SUMMARY</a>, <a href="#UID">UID</a>.
|
1754 |
+
For the property "SUMMARY" ,if a search value (any case) exists within property value, a hit exists.
|
1755 |
+
For the other, non-date, properties an exact (strict case) match is required.<br />
|
1756 |
+
Note, <a href="#ATTENDEE">ATTENDEE</a> and <a href="#ORGANIZER">ORGANIZER</a> values must be prefixed by protocol ex."MAILTO:chair@ical.net".
|
1757 |
+
|
1758 |
+
<p class="format">getComponent( array(*[string propertyName => string uniqueValue] ))</p>
|
1759 |
+
<p class="comment">propertyName = property name, above
|
1760 |
+
propertyData = unique property value (strict case),
|
1761 |
+
date format "YYYYMMDD" (if any side is DATE, only dates are used),
|
1762 |
+
datetime format "YYYYMMDDTHHMMSS"
|
1763 |
+
</p>
|
1764 |
+
<p class="label">Example 1</p>
|
1765 |
+
<p class="example">$config = array( "unique_id" => "domain.com", "filename" => "file.ics" );
|
1766 |
+
$vcalendar = new vcalendar( $config );
|
1767 |
+
$vcalendar->parse();
|
1768 |
+
while( $comp = $vcalendar->getComponent()) {
|
1769 |
+
.. .
|
1770 |
+
}
|
1771 |
+
.. .
|
1772 |
+
</p>
|
1773 |
+
<p class="label">Example 2</p>
|
1774 |
+
<p class="example">$config = array( "unique_id" => "domain.com", "filename" => "file.ics" );
|
1775 |
+
$vcalendar = new vcalendar( $config );
|
1776 |
+
$vcalendar->parse();
|
1777 |
+
if( $comp = $vcalendar->getComponent( 1 )) {
|
1778 |
+
.. .
|
1779 |
+
}
|
1780 |
+
.. .
|
1781 |
+
</p>
|
1782 |
+
<p class="label">Example 3</p>
|
1783 |
+
<p class="example">$config = array( "unique_id" => "domain.com", "filename" => "file.ics" );
|
1784 |
+
$vcalendar = new vcalendar( $config );
|
1785 |
+
$vcalendar->parse();
|
1786 |
+
if( $comp = $vcalendar->getComponent( "vtodo", 2 ) {
|
1787 |
+
.. .
|
1788 |
+
}
|
1789 |
+
.. .
|
1790 |
+
</p>
|
1791 |
+
<p class="label">Example 4</p>
|
1792 |
+
<p class="example">$config = array( "unique_id" => "domain.com", "filename" => "file.ics" );
|
1793 |
+
$vcalendar = new vcalendar( $config );
|
1794 |
+
$vcalendar->parse();
|
1795 |
+
$uid = "20070803T194810CEST-0123U3PXiX@domain.com";
|
1796 |
+
if($comp = $vcalendar->getComponent( $uid ){
|
1797 |
+
.. .
|
1798 |
+
}
|
1799 |
+
.. .
|
1800 |
+
</p>
|
1801 |
+
<br />
|
1802 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_functions">[up]</a>
|
1803 |
+
|
1804 |
+
<a name="newComponent"></a><h4>3.1.3.3 newComponent</h4>
|
1805 |
+
Create component (<a href="#VEVENT">EVENT</a> / <a href="#VTODO">VTODO</a> / <a href="#VJOURNAL">VJOURNAL</a> / <a href="#VFREEBUSY">VFREEBUSY</a> / <a href="#VTIMEZONE">VTIMEZONE</a>)
|
1806 |
+
using a calendar factory-method, returning a reference to the new component.
|
1807 |
+
<p class="label">Format</p>
|
1808 |
+
<p class="format">newComponent( string componentType )</p>
|
1809 |
+
<p class="label">Example</p>
|
1810 |
+
<p class="example">$config = array( 'unique_id' => 'domain.org' );
|
1811 |
+
$vcalendar = new vcalendar( $config );
|
1812 |
+
...
|
1813 |
+
$vevent = & $vcalendar->newComponent( 'vevent' );
|
1814 |
+
...
|
1815 |
+
</p>
|
1816 |
+
|
1817 |
+
<br />
|
1818 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_functions">[up]</a>
|
1819 |
+
|
1820 |
+
<a name="selectComponents"></a><h4>3.1.3.4 selectComponents</h4>
|
1821 |
+
<p class="label">Format 1</p>
|
1822 |
+
Selects <a href="#VEVENT">EVENT</a> / <a href="#VTODO">VTODO</a> / <a href="#VJOURNAL">VJOURNAL</a> / <a href="#VFREEBUSY">VFREEBUSY</a> components from calendar on based on <i>dates</i> (notice <a href="#date_restriction">date restriction</a>), based on the initial <a href="#DTSTART">DTSTART</a> property
|
1823 |
+
along with the <a href="#RRULE">RRULE</a>, <a href="#RDATE">RDATE</a>, <a href="#EXDATE">EXDATE</a> and <a href="#EXRULE">EXRULE</a> properties in the component.
|
1824 |
+
If property <a href="#DTSTART">DTSTART</a> is missing in a <a href="#VTODO">VTODO</a> component then <a href="#DTSTART">DUE</a> is used.<br />
|
1825 |
+
<br />
|
1826 |
+
Limitation; if using component properties <a href="#UID">UID</a> in combination with <a href="#SEQUENCE">SEQUENCE</a> and <a href="#RECURRENCE-ID">RECURRENCE-ID</a> (i.e an individual instance within the recurrence set),
|
1827 |
+
the use of recurrence-id parameter "RANGE" ("THISANDPRIOR" and/or "THISANDFUTURE") has no effect.<br />
|
1828 |
+
<br />
|
1829 |
+
This function requires calendar components in order, i.e. execute <a href="#sort">sort</a> before "selectComponents", notice example below.<br />
|
1830 |
+
<br />
|
1831 |
+
FALSE is returned if no selected component exists.
|
1832 |
+
<p class="format">selectComponents([ int startYear, int startMonth, int startDay
|
1833 |
+
[, int endYear, int endMonth, int endDay
|
1834 |
+
[, mixed cType [, bool flat [,bool any [,bool split]]]]]])
|
1835 |
+
</p>
|
1836 |
+
Returns an array with components (events.. .).
|
1837 |
+
For all recurrent instances of a calendar component, an x-property,
|
1838 |
+
"X-CURRENT-DTSTART" and opt. also "X-CURRENT-DTEND" alt. "X-CURRENT-DUE",
|
1839 |
+
has been created with a TEXT content, "Y-m-d [H:i:s][timezone/UTC offset]"
|
1840 |
+
showing the current start and opt. also end alt. due date.<br />
|
1841 |
+
Also a "X-RECURRENCE" x-property is set with order number (valid if selectComponents is called from DTSTART date).
|
1842 |
+
<p class="comment">startYear : start year (4*digit), default current year
|
1843 |
+
startMonth : start month (1-2*digit), default current month
|
1844 |
+
startDay : start day (1-2*digit), default current day
|
1845 |
+
endYear : end year (4*digit), default startYear
|
1846 |
+
endMonth : end month (-2*digit), default startMonth
|
1847 |
+
endDay : end day (1-2*digit), default startDay
|
1848 |
+
cType : calendar component type(-s), string/array
|
1849 |
+
('vevent', 'vtodo', 'vjournal', 'vfreebusy')
|
1850 |
+
FALSE (default) all
|
1851 |
+
flat : TRUE => output : array[] (ignores split)
|
1852 |
+
FALSE (default) =>
|
1853 |
+
output : array[Year][Month][Day][]
|
1854 |
+
any : TRUE (default) -
|
1855 |
+
select component that occurs within period
|
1856 |
+
FALSE -
|
1857 |
+
only components that starts (DTSTART) within period
|
1858 |
+
split : TRUE (default) -
|
1859 |
+
one component copy for every day it occurs
|
1860 |
+
within the period (implies flat=FALSE)
|
1861 |
+
FALSE - one occurrence of component in output array
|
1862 |
+
,start date/recurrence date
|
1863 |
+
</p>
|
1864 |
+
<p class="label">Example</p>
|
1865 |
+
<p class="example">$config = array( "unique_id" => "domain.com",
|
1866 |
+
"directory" => "import",
|
1867 |
+
"filename" => "file.ics" );
|
1868 |
+
$vcalendar = new vcalendar( $config );
|
1869 |
+
$vcalendar->parse();
|
1870 |
+
$vcalendar->sort();
|
1871 |
+
$events_arr = $vcalendar->selectComponents( 2007,11,1,2007,11,30,'vevent');
|
1872 |
+
// <span class="comment">select all events occurring 1-30 nov. 2007</span>
|
1873 |
+
foreach( $events_arr as $year => $year_arr ) {
|
1874 |
+
foreach( $year_arr as $month => $month_arr ) {
|
1875 |
+
foreach( $month_arr as $day => $day_arr ) {
|
1876 |
+
foreach( $day_arr as $event ) {
|
1877 |
+
$currddate = $event->getProperty( 'x-current-dtstart' );
|
1878 |
+
<span class="comment">// if member of a recurrence set, returns
|
1879 |
+
// array(' x-current-dtstart',
|
1880 |
+
// <(string) date("Y-m-d [H:i:s][timezone/UTC offset]")>)</span>
|
1881 |
+
$startDate = $event->getProperty( 'dtstart' );
|
1882 |
+
$summary = $event->getProperty( 'summary' );
|
1883 |
+
$description = $event->getProperty( 'description' );
|
1884 |
+
.. .
|
1885 |
+
</p>
|
1886 |
+
<p class="label">format 2</p>
|
1887 |
+
Using this format, the function selects components based on specific property value(-s),
|
1888 |
+
<a href="#ATTENDEE">ATTENDEE</a>, <a href="#CATEGORIES">CATEGORIES</a>, <a href="#LOCATION">LOCATION, <a href="#ORGANIZER">ORGANIZER</a>, <a href="#PRIORITY">PRIORITY</a>, <a href="#RESOURCES">RESOURCES</a>, <a href="#STATUS">STATUS</a>, <a href="#SUMMARY">SUMMARY</a> or <a href="#UID">UID</a>.
|
1889 |
+
For the property "SUMMARY" ,if a search value (any case) exists within property value, a hit exists.
|
1890 |
+
For the other properties an exact (strict case) match is required.<br />
|
1891 |
+
<a href="#ATTENDEE">ATTENDEE</a> and <a href="#ORGANIZER">ORGANIZER</a> search values must be prefixed by protocol ex. "MAILTO:chair@ical.net".
|
1892 |
+
Multiple search properties may coexist.
|
1893 |
+
<p class="format">selectComponents( searchArray )</p>
|
1894 |
+
Outputs an array of matched (unique) components in <a href="#UID">UID</a> order.
|
1895 |
+
<p class="comment">searchArray : array( propertyName => propertyValue )
|
1896 |
+
propertyName : above (any case)
|
1897 |
+
propertyValue : string value / array( *[string value] )
|
1898 |
+
</p>
|
1899 |
+
<p class="label">Example</p>
|
1900 |
+
<p class="example">$config = array( "unique_id" => "domain.com",
|
1901 |
+
"directory" => "import",
|
1902 |
+
"filename" => "file.ics" );
|
1903 |
+
$vcalendar = new vcalendar( $config );
|
1904 |
+
$vcalendar->parse();
|
1905 |
+
$vcalendar->sort();
|
1906 |
+
$searchArray = array( "PRIORITY" => array( 1, 2, 3, 4, 5 ));
|
1907 |
+
$mediumHighPrioArr = $vcalendar->selectComponents( $searchArray );
|
1908 |
+
// <span class="comment">select all components with high (1) and medium priority</span>
|
1909 |
+
if( !empty( $mediumHighPrioArr )) {
|
1910 |
+
$mediumHighPrioCal = new vcalendar();
|
1911 |
+
$mediumHighPrioCal->setProperty("X-WR-CALDESC", "High-Medium events");
|
1912 |
+
foreach( $mediumHighPrioArr as $mediumHighPrioComponent )
|
1913 |
+
$mediumHighPrioCal->setComponent( $mediumHighPrioComponent );
|
1914 |
+
$mediumHighPrioCal->returnCalendar();
|
1915 |
+
}
|
1916 |
+
.. .
|
1917 |
+
</p>
|
1918 |
+
<br />
|
1919 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_functions">[up]</a>
|
1920 |
+
|
1921 |
+
<a name="setComponent"></a><h4>3.1.3.5 setComponent</h4>
|
1922 |
+
Replace or update component in calendar.
|
1923 |
+
Also add calendar component to calendar when calendar component is created with the procedural (<b>non</b>-factory) method,
|
1924 |
+
see example <a href="#vevent">VEVENT</a>, format 2.
|
1925 |
+
A successful update return TRUE.
|
1926 |
+
<p class="label">format 1</p>
|
1927 |
+
Insert last in component chain.
|
1928 |
+
<p class="format">setComponent( component )
|
1929 |
+
addComponent( component ) // <span class="ref">alias</span>
|
1930 |
+
</p>
|
1931 |
+
<p class="comment">addComponent, may be removed i future versions.</p>
|
1932 |
+
<p class="label">format 2</p>
|
1933 |
+
Insert/replace component with order number (1st=1, 2nd=2.. .).
|
1934 |
+
If replace and orderNumber is not found, component is inserted last in chain.
|
1935 |
+
<p class="format">setComponent( component, int orderNumber )</p>
|
1936 |
+
<p class="label">format 3</p>
|
1937 |
+
Replace component with component type and 1st alt. component order number.
|
1938 |
+
If orderNumber is not found, component is inserted last in chain.
|
1939 |
+
<p class="format">setComponent( component, string componentType [,int component suborder no])</p>
|
1940 |
+
<p class="label">format 4</p>
|
1941 |
+
Replace component with <a href="#UID">UID</a>.
|
1942 |
+
N.B <a href="#UID">UID</a> is NOT set for <a href="#VALARM">ALARM</a> / <a href="#VTIMEZONE">TIMEZONE</a> components.
|
1943 |
+
If <a href="#UID">UID</a> is not found, component is inserted last in chain.
|
1944 |
+
<p class="format">setComponent( component, string <a href="#UID">UID</a> )</p>
|
1945 |
+
<p class="label">Example</p>
|
1946 |
+
<p class="example">$config = array( "unique_id" => "domain.com", "filename" => "file.ics" );
|
1947 |
+
$vcalendar = new vcalendar( $config );
|
1948 |
+
$vcalendar->parse();
|
1949 |
+
$vevent = vcalendar->getComponent( 1 ); //<span class="comment">fetch first EVENT</span>
|
1950 |
+
$vevent->setProperty( "dtstart" //<span class="comment">update <a href="#DTSTART">DTSTART</a> property</span>
|
1951 |
+
, 2006, 12, 24, 19, 30, 00 );
|
1952 |
+
.. .
|
1953 |
+
$vcalendar->setComponent( $vevent, 1 ); // replace first component
|
1954 |
+
.. .
|
1955 |
+
</p>
|
1956 |
+
<br />
|
1957 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_functions">[up]</a>
|
1958 |
+
|
1959 |
+
<a name="Calendar_inputoutput_functions"></a><h3>3.1.4 Calendar input/output functions</h3>
|
1960 |
+
|
1961 |
+
<a name="parse_merge"></a><h4>3.1.4.1 parse and merge</h4>
|
1962 |
+
Parse iCal file(-s) or string/array calendarContent into a single vcalendar object (components, properties and parameters),
|
1963 |
+
including multiple vcalendars (within a single ICS file) parse, e.g. Oracle Calendar exports.
|
1964 |
+
|
1965 |
+
<br /><br />
|
1966 |
+
As long as php.ini directive "allow_url_fopen" is enabled, remote files, URLs; protocol "http" ("webcal"), are supported. A remote file, URL, <b>must</b> be prefixed by "http://" ("webcal://") and suffixed by a valid filename.! Recommendation is to download (cache) remote file before parsing, due to execution time and control.
|
1967 |
+
<br /><br />
|
1968 |
+
If missing, component property <a href="#UID">UID</a> is created when parsing. For that reason <a href="#Unique_id">UNIQUE_ID</a> might need to be set before parsing, Se examples below.
|
1969 |
+
<br /><br />
|
1970 |
+
Notice <a href="#date_restriction">date restriction</a>!
|
1971 |
+
<br /><br />
|
1972 |
+
If parse error occurs (like file access error, invalid calendar file or calendar file without components), FALSE is returned.
|
1973 |
+
<p class="label">Format</p>
|
1974 |
+
<p class="format">parse( [ mixed textToParse ] )</p>
|
1975 |
+
<p class="comment">textToParse = string calendarContent
|
1976 |
+
ex. result from "file_get_contents( 'filename')"
|
1977 |
+
array calendarContent
|
1978 |
+
ex. result from "file( 'filename', FILE_IGNORE_NEW_LINES )"</p>
|
1979 |
+
<p class="label">parse example 1</p>
|
1980 |
+
<p class="example">$config = array( "unique_id" => "domain.com", "filename" => "file.ics" );
|
1981 |
+
$vcalendar = new vcalendar( $config );
|
1982 |
+
$vcalendar->parse();
|
1983 |
+
.. .
|
1984 |
+
</p>
|
1985 |
+
<p class="label">parse example 2</p>
|
1986 |
+
<p class="example">
|
1987 |
+
$config = array( "unique_id" => "domain.com",
|
1988 |
+
"url" => "http://www.ical.net/calendars/calendar.ics" );
|
1989 |
+
$vcalendar = new vcalendar( $config );
|
1990 |
+
$vcalendar->parse();
|
1991 |
+
.. .
|
1992 |
+
</p>
|
1993 |
+
<p class="label">parse example 3</p>
|
1994 |
+
<p class="example">$config = array( "unique_id" => "domain.com",
|
1995 |
+
"url" => "http://www.ical.net/calendars/calendar.ics" );
|
1996 |
+
$vcalendar = new vcalendar( $config );
|
1997 |
+
...
|
1998 |
+
$str = array(
|
1999 |
+
'BEGIN:VCALENDAR',
|
2000 |
+
'PRODID:-//test.org//NONSGML kigkonsult.se iCalcreator 2.10//',
|
2001 |
+
'VERSION:2.0',
|
2002 |
+
'BEGIN:VEVENT',
|
2003 |
+
'DTSTART:20101224T190000Z',
|
2004 |
+
'DTEND:20101224T200000Z',
|
2005 |
+
'DTSTAMP:20101020T103827Z',
|
2006 |
+
'UID:20101020T113827-1234GkdhFR@test.org',
|
2007 |
+
'DESCRIPTION:example',
|
2008 |
+
'END:VEVENT',
|
2009 |
+
'END:VCALENDAR');
|
2010 |
+
$vcalendar->parse( $str );
|
2011 |
+
...
|
2012 |
+
</p>
|
2013 |
+
<p class="label">merge example</p>
|
2014 |
+
<p class="example">$config = array( "unique_id" => "domain.com",
|
2015 |
+
"directory" => "import" );
|
2016 |
+
$vcalendar = new vcalendar( $config );
|
2017 |
+
|
2018 |
+
$vcalendar->setConfig( "filename", "file1.ics" );
|
2019 |
+
$vcalendar->parse();
|
2020 |
+
|
2021 |
+
$vcalendar->setConfig( "filename", "file2.ics" );
|
2022 |
+
$vcalendar->parse();
|
2023 |
+
|
2024 |
+
$vcalendar->sort();
|
2025 |
+
$vcalendar->setConfig( "directory", "export" );
|
2026 |
+
$vcalendar->setConfig( "filename", "icalmerge.ics" );
|
2027 |
+
$vcalendar->saveCalendar();
|
2028 |
+
.. .
|
2029 |
+
</p>
|
2030 |
+
<br />
|
2031 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_inputoutput_functions">[up]</a>
|
2032 |
+
|
2033 |
+
<a name="createCalendar"></a><h4>3.1.4.2 createCalendar</h4>
|
2034 |
+
Generate and return calendar in a string, testing.. .?
|
2035 |
+
<p class="label">Format</p>
|
2036 |
+
<p class="format">createCalendar()</p>
|
2037 |
+
<p class="label">Example</p>
|
2038 |
+
<p class="example">.. .
|
2039 |
+
$str = $vcalendar->createCalendar();
|
2040 |
+
echo $str;
|
2041 |
+
</p>
|
2042 |
+
<br />
|
2043 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_inputoutput_functions">[up]</a>
|
2044 |
+
|
2045 |
+
<a name="returnCalendar"></a><h4>3.1.4.3 returnCalendar</h4>
|
2046 |
+
Redirect calendar content to user browser. Filename, addressed to browser, is auto generated if missing or not set;<br />
|
2047 |
+
<span class="format">$filename = date( "YmdHis" ).".ics" </span><br />
|
2048 |
+
<p class="label">Format</p>
|
2049 |
+
<p class="format">returnCalendar( [bool utf8Encode [, bool gzip ]] )</p>
|
2050 |
+
<p class="comment">utf8Encode = TRUE: utf8 encoded output, FALSE: (default) no encoding
|
2051 |
+
gzip = TRUE: gzip compressed output and header 'Content-Encoding: gzip' set,
|
2052 |
+
FALSE: (default) no compressing</p>
|
2053 |
+
<p class="label">Example 1</p>
|
2054 |
+
<p class="example">$config = array( "unique_id" => "domain.com" );
|
2055 |
+
$vcalendar = new vcalendar( $config );
|
2056 |
+
.. .
|
2057 |
+
$vevent = & $vcalendar->newComponent( 'vevent' );
|
2058 |
+
$vevent->setProperty( "dtstart", array( "year" => 2007
|
2059 |
+
, "month" => 4
|
2060 |
+
, "day" => 1
|
2061 |
+
, "hour" => 19 ));
|
2062 |
+
$vevent->setProperty( "duration", 0, 0, 3 ));
|
2063 |
+
$vevent->setProperty( "LOCATION", "Central Plaza" );
|
2064 |
+
$vevent->setProperty( "summary", "PHP summit" );
|
2065 |
+
.. .
|
2066 |
+
$vcalendar->returnCalendar();
|
2067 |
+
</p>
|
2068 |
+
<p class="label">Example 2</p>
|
2069 |
+
<p class="example">$config = array( "unique_id" => "domain.com",
|
2070 |
+
"directory" => "import",
|
2071 |
+
"filename" => "file.ics" );
|
2072 |
+
$vcalendar = new vcalendar( $config );
|
2073 |
+
$vcalendar->parse();
|
2074 |
+
$utf8Encode = TRUE;
|
2075 |
+
$hacPar = 'HTTP_ACCEPT_ENCODING';
|
2076 |
+
if( isset( $_SERVER[$hacPar] ) &&
|
2077 |
+
( FALSE !== strpos( strtolower( $_SERVER[$hacPar] ), 'gzip' )))
|
2078 |
+
$gzip = TRUE;
|
2079 |
+
else
|
2080 |
+
$gzip = FALSE;
|
2081 |
+
$vcalendar->returnCalendar( $utf8Encode, $gzip );
|
2082 |
+
</p>
|
2083 |
+
<br />
|
2084 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_inputoutput_functions">[up]</a>
|
2085 |
+
|
2086 |
+
<a name="saveCalendar"></a><h4>3.1.4.4 saveCalendar</h4>
|
2087 |
+
Save ical calendar in a file, uses present directory if directory not set, filename is auto generated if missing or not set;<br />
|
2088 |
+
<span class="format">$filename = date( "YmdHis" ).".ics" </span><br />
|
2089 |
+
Directory/filename <b>must</b> be writeable, delimiter default PHP constant DIRECTORY_SEPARATOR.
|
2090 |
+
<br /><br />
|
2091 |
+
As long as php.ini directive "allow_url_fopen" is enabled, remote files, URLs; protocol "http" ("webcal"), are supported. Recommendation is to save to a local file and upload later, due to execution time and control.
|
2092 |
+
<br /><br />
|
2093 |
+
If file error occurs, FALSE is returned.
|
2094 |
+
<p class="label">Format</p>
|
2095 |
+
<p class="format">saveCalendar ( string directory/FALSE
|
2096 |
+
[, string filename/FALSE
|
2097 |
+
[, string delimiter/FALSE ]] )
|
2098 |
+
</p>
|
2099 |
+
Parameters for <span class="format">directory/filename/delimiter</span>, kept for backward compatibility,
|
2100 |
+
may be removed i future versions. Recommendation is to use <span class="format">setConfig</span>, Se
|
2101 |
+
example below.
|
2102 |
+
<p class="label">Example</p>
|
2103 |
+
<p class="example">.. .
|
2104 |
+
$vcalendar->setConfig( array( "directory" => "depot",
|
2105 |
+
"filename" => "calendar.ics" ));
|
2106 |
+
$result = $vcalendar->saveCalendar();
|
2107 |
+
if( !$result )
|
2108 |
+
echo "error when saving.. ."
|
2109 |
+
</p>
|
2110 |
+
<br />
|
2111 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_inputoutput_functions">[up]</a>
|
2112 |
+
|
2113 |
+
<a name="sort"></a><h4>3.1.4.5 sort</h4>
|
2114 |
+
<p class="label">Format 1</p>
|
2115 |
+
Sort created/parsed calendar components on the following (prioritized) keys:<br />
|
2116 |
+
1 - X-CURRENT-DTSTART - X-CURRENT-DTEND/X-CURRENT-DUE<br />
|
2117 |
+
(if created in function <a href="#selectComponents">selectComponents</a>)<br />
|
2118 |
+
1 - <a href="#DTSTART">DTSTART</a> - <a href="#DTEND">DTEND</a> alt. <a href="#DURATION">DURATION</a> (<a href="#VEVENT">VEVENT</a> and <a href="#VFREEBUSY">VFREEBUSY</a> components)<br />
|
2119 |
+
1 - <a href="#DTSTART">DTSTART</a> - <a href="#DUE">DUE</a> alt. <a href="#DURATION">DURATION</a> (<a href="#VTODO">VTODO</a> components)<br />
|
2120 |
+
1 - <a href="#DTSTART">DTSTART</a> (<a href="#VJOURNAL">VJOURNAL</a> components)<br />
|
2121 |
+
2 - <a href="#CREATED">CREATED</a> / <a href="#DTSTAMP">DTSTAMP</a><br />
|
2122 |
+
3 - <a href="#UID">UID</a><br />
|
2123 |
+
<a href="#VTIMEZONE">VTIMEZONE</a> component(-s) are always sorted first in chain.<br />
|
2124 |
+
Sub-components (<a href="#VTIMEZONE">STANDARD</a> / <a href="#VTIMEZONE">DAYLIGHT</a> / <a href="#VALARM">ALARM</a>), if exists, are not sorted.
|
2125 |
+
<p class="format">sort()</p>
|
2126 |
+
<p class="label">Example</p>
|
2127 |
+
<p class="example">$config = array( "unique_id" => "domain.com",
|
2128 |
+
"directory" => "import",
|
2129 |
+
"filename" => "file.ics" );
|
2130 |
+
$vcalendar = new vcalendar( $config );
|
2131 |
+
$vcalendar->parse();
|
2132 |
+
$vcalendar->sort();
|
2133 |
+
$vcalendar->returnCalendar();
|
2134 |
+
</p>
|
2135 |
+
|
2136 |
+
<p class="label">Format 2</p>
|
2137 |
+
Sort created/parsed calendar components on specific property values and ascending order.
|
2138 |
+
<p class="format">sort( sortArgument )</p>
|
2139 |
+
<p class="comment">sortArgument: "<a href="#ATTENDEE">ATTENDEE</a>" / "<a href="#CATEGORIES">CATEGORIES</a>" / "<a href="#DTSTAMP">DTSTAMP</a>" / "<a href="#LOCATION">LOCATION"</a>" /
|
2140 |
+
"<a href="#ORGANIZER">ORGANIZER</a>" /"<a href="#RESOURCES">RESOURCES</a>" / "<a href="#PRIORITY">PRIORITY</a>" / "<a href="#STATUS">STATUS</a>" / "<a href="#SUMMARY">SUMMARY</a>"
|
2141 |
+
for a property where multiple ocurrence may exist
|
2142 |
+
(<a href="#ATTENDEE">ATTENDEE</a>, <a href="#CATEGORIES">CATEGORIES</a>, <a href="#RESOURCES">RESOURCES</a> ),
|
2143 |
+
lowest (alphabetic) value is used as sort parameter.
|
2144 |
+
</p>
|
2145 |
+
<br />
|
2146 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_inputoutput_functions">[up]</a>
|
2147 |
+
|
2148 |
+
<a name="useCachedCalendar"></a><h4>3.1.4.6 useCachedCalendar</h4>
|
2149 |
+
If recent version of local (non-empty and saved) calendar file exists, an HTTP redirect header is sent otherwise FALSE is returned.
|
2150 |
+
<p class="label">Format</p>
|
2151 |
+
<p class="format">useCachedCalendar( [ int timeout ] )
|
2152 |
+
useCachedCalendar( string directory/FALSE
|
2153 |
+
, string filename/FALSE
|
2154 |
+
, string delimiter/FALSE
|
2155 |
+
[, int timeout ] )
|
2156 |
+
</p>
|
2157 |
+
<p class="comment">timeout : default 3600 sec
|
2158 |
+
Second format with parameters for <span class="format">directory/filename/delimiter</span>,<br />kept for backward compatibility, may be removed i future<br />versions. Recommendation is to use <span class="format">setConfig</span>, Se example below.</span></p>
|
2159 |
+
<p class="label">Example</p>
|
2160 |
+
<p class="example">.. .
|
2161 |
+
$vcalendar->setConfig( "directory", "depot" );
|
2162 |
+
$vcalendar->setConfig( "filename", "calendar.ics" );
|
2163 |
+
$vcalendar->useCachedCalendar();
|
2164 |
+
</p>
|
2165 |
+
<br />
|
2166 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_inputoutput_functions">[up]</a>
|
2167 |
+
|
2168 |
+
<a name="Calendar_configuration_functions"></a><h3>3.1.5 Calendar configuration functions</h3>
|
2169 |
+
|
2170 |
+
<a name="configKeys"></a><h4>3.1.5.1 configuration keys</h4>
|
2171 |
+
All configuration keys (allowEmpty, compsInfo etc.) case independent.
|
2172 |
+
<br />
|
2173 |
+
<br />
|
2174 |
+
<table>
|
2175 |
+
<tr>
|
2176 |
+
<td class="bl bb">key</td>
|
2177 |
+
<td class="bl bb">calendar</td>
|
2178 |
+
<td class="bl bb">component</td>
|
2179 |
+
<td class="bl bb">remark</td>
|
2180 |
+
</tr>
|
2181 |
+
<tr>
|
2182 |
+
<td class="bl bb"><a class="ref" href="#allowEmpty">allowEmpty</a></td>
|
2183 |
+
<td class="bl bb center">*</td>
|
2184 |
+
<td class="bl bb center">*</td>
|
2185 |
+
<td class="bl bb ref"> </td>
|
2186 |
+
</tr>
|
2187 |
+
<tr>
|
2188 |
+
<td class="bl bb"><a class="ref" href="#Compsinfo">Compsinfo</a></td>
|
2189 |
+
<td class="bl bb center">*</td>
|
2190 |
+
<td class="bl bb center">*</td>
|
2191 |
+
<td class="bl bb ref">getConfig only</td>
|
2192 |
+
</tr>
|
2193 |
+
<tr>
|
2194 |
+
<td class="bl bb"><a class="ref" href="#Delimiter">Delimiter</a></td>
|
2195 |
+
<td class="bl bb center">*</td>
|
2196 |
+
<td class="bl bb"> </td>
|
2197 |
+
<td class="bl bb ref"> </td>
|
2198 |
+
</tr>
|
2199 |
+
<tr>
|
2200 |
+
<td class="bl bb"><a class="ref" href="#Directory">Directory</a></td>
|
2201 |
+
<td class="bl bb center">*</td>
|
2202 |
+
<td class="bl bb"> </td>
|
2203 |
+
<td class="bl bb ref"> </td>
|
2204 |
+
</tr>
|
2205 |
+
<tr>
|
2206 |
+
<td class="bl bb"><a class="ref" href="#Filename">Filename</a></td>
|
2207 |
+
<td class="bl bb center">*</td>
|
2208 |
+
<td class="bl bb"> </td>
|
2209 |
+
<td class="bl bb ref"> </td>
|
2210 |
+
</tr>
|
2211 |
+
<tr>
|
2212 |
+
<td class="bl bb"><a class="ref" href="#Dirfile">Dirfile</a></td>
|
2213 |
+
<td class="bl bb center">*</td>
|
2214 |
+
<td class="bl bb"> </td>
|
2215 |
+
<td class="bl bb ref">getConfig only</td>
|
2216 |
+
</tr>
|
2217 |
+
<tr>
|
2218 |
+
<td class="bl bb"><a class="ref" href="#Filesize">Filesize</a></td>
|
2219 |
+
<td class="bl bb center">*</td>
|
2220 |
+
<td class="bl bb"> </td>
|
2221 |
+
<td class="bl bb ref">getConfig only</td>
|
2222 |
+
</tr>
|
2223 |
+
<tr>
|
2224 |
+
<td class="bl bb"><a class="ref" href="#Format">Format</a></td>
|
2225 |
+
<td class="bl bb center">*</td>
|
2226 |
+
<td class="bl bb"> </td>
|
2227 |
+
<td class="bl bb ref"> </td>
|
2228 |
+
</tr>
|
2229 |
+
<tr>
|
2230 |
+
<td class="bl bb"><a class="ref" href="#Language">Language</a></td>
|
2231 |
+
<td class="bl bb center">*</td>
|
2232 |
+
<td class="bl bb center">*</td>
|
2233 |
+
<td class="bl bb ref"> </td>
|
2234 |
+
</tr>
|
2235 |
+
<tr>
|
2236 |
+
<td class="bl bb"><a class="ref" href="#NewlineChar">NewlineChar</a></td>
|
2237 |
+
<td class="bl bb center">*</td>
|
2238 |
+
<td class="bl bb center">*</td>
|
2239 |
+
<td class="bl bb ref"> </td>
|
2240 |
+
</tr>
|
2241 |
+
<tr>
|
2242 |
+
<td class="bl bb"><a class="ref" href="#dTZID">TZID</a></td>
|
2243 |
+
<td class="bl bb center">*</td>
|
2244 |
+
<td class="bl bb center">*</td>
|
2245 |
+
<td class="bl bb ref"> </td>
|
2246 |
+
</tr>
|
2247 |
+
<tr>
|
2248 |
+
<td class="bl bb"><a class="ref" href="#Unique_id">Unique_id</a></td>
|
2249 |
+
<td class="bl bb center">*</td>
|
2250 |
+
<td class="bl bb center">*</td>
|
2251 |
+
<td class="bl bb ref"> </td>
|
2252 |
+
</tr>
|
2253 |
+
<tr>
|
2254 |
+
<td class="bl bb"><a class="ref" href="#configURL">URL</a></td>
|
2255 |
+
<td class="bl bb center">*</td>
|
2256 |
+
<td class="bl bb"> </td>
|
2257 |
+
<td class="bl bb ref"> </td>
|
2258 |
+
</tr>
|
2259 |
+
</table>
|
2260 |
+
<br />
|
2261 |
+
<br />
|
2262 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_configuration_functions">[up]</a>
|
2263 |
+
|
2264 |
+
<a name="getConfig"></a><h4>3.1.5.2 getConfig</h4>
|
2265 |
+
<p class="format">getConfig( [string key )</p>
|
2266 |
+
<p class="label">Example 1</p>
|
2267 |
+
<p class="example">.. .
|
2268 |
+
$filename = $vcalendar->getConfig( 'filename' );<span class="comment">
|
2269 |
+
.. .</p>
|
2270 |
+
In this example, notice <a href="#Filename">Filename</a></span>
|
2271 |
+
<br />
|
2272 |
+
<p class="label">Example 2</p>
|
2273 |
+
<p class="example">.. .
|
2274 |
+
$config = $vcalendar->getConfig();
|
2275 |
+
.. .</p>
|
2276 |
+
<p class="comment">Output= array( string key => mixed value
|
2277 |
+
*[, string key => mixed value] )</p>
|
2278 |
+
<br />
|
2279 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_configuration_functions">[up]</a>
|
2280 |
+
|
2281 |
+
<a name="initConfig"></a><h4>3.1.5.3 calendar/component initialization</h4>
|
2282 |
+
<p class="label">Format</p>
|
2283 |
+
When creating a new calendar.
|
2284 |
+
<p class="format">vcalendar( array( string key => mixed value *[,string key => mixed value]))</p>
|
2285 |
+
<p class="label">Example 1</p>
|
2286 |
+
<p class="example">$config = array( "unique_id" => "domain.com",
|
2287 |
+
"directory" => "import",
|
2288 |
+
"filename" => "file.ics" );
|
2289 |
+
$vcalendar = new vcalendar( $config );
|
2290 |
+
.. .
|
2291 |
+
</p>
|
2292 |
+
When creating a new calendar component.
|
2293 |
+
<p class="format">component( array( string key => mixed value *[,string key => mixed value]))</p>
|
2294 |
+
<p class="label">Example 2</p>
|
2295 |
+
<p class="example">$config = array( "unique_id" => "domain.com" );
|
2296 |
+
$vevent = new vevent( $config );
|
2297 |
+
.. .
|
2298 |
+
</p>
|
2299 |
+
<p class="label">Example 3</p>
|
2300 |
+
<p class="example">. ..
|
2301 |
+
$config = $vcalendar->getConfig();
|
2302 |
+
$vevent = new vevent( $config );
|
2303 |
+
.. .
|
2304 |
+
</p>
|
2305 |
+
Only component relevant configuration are set. If using the <a href="#newComponent">newComponent</a> function, configuration is set automatically.
|
2306 |
+
<br />
|
2307 |
+
<br />
|
2308 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_configuration_functions">[up]</a>
|
2309 |
+
|
2310 |
+
<a name="setConfig"></a><h4>3.1.5.4 setConfig</h4>
|
2311 |
+
A successful "setConfig" returns TRUE.
|
2312 |
+
<p class="label">Format 1</p>
|
2313 |
+
<p class="format">setConfig( array( string key=>mixed value *[, string key=>mixed value]))</p>
|
2314 |
+
<p class="label">Example 1</p>
|
2315 |
+
<p class="example">$config = array( "unique_id" => "domain.com",
|
2316 |
+
"directory" => "import",
|
2317 |
+
"filename" => "file.ics" );
|
2318 |
+
$vcalendar = new vcalendar();
|
2319 |
+
$vcalendar->setConfig( $config );
|
2320 |
+
.. .
|
2321 |
+
</p>
|
2322 |
+
<p class="label">Example 2</p>
|
2323 |
+
<p class="example">$config = array( "unique_id" => "domain.com" );
|
2324 |
+
$vevent = new vevent();
|
2325 |
+
$vevent->setConfig( $config );
|
2326 |
+
.. .
|
2327 |
+
</p>
|
2328 |
+
<p class="label">Format 2</p>
|
2329 |
+
<p class="format">setConfig( string key, string value )</p>
|
2330 |
+
<p class="label">Example 1</p>
|
2331 |
+
<p class="example">$vcalendar = new vcalendar();
|
2332 |
+
$vcalendar->setConfig( "directory", "depot" );
|
2333 |
+
.. .
|
2334 |
+
</p>
|
2335 |
+
<p class="label">Example 2</p>
|
2336 |
+
<p class="example">$vevent = new vevent();
|
2337 |
+
$vevent->setConfig( "unique_id", "domain.com" );
|
2338 |
+
.. .
|
2339 |
+
</p>
|
2340 |
+
<br />
|
2341 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_configuration_functions">[up]</a>
|
2342 |
+
|
2343 |
+
<a name="allowEmpty"></a><h4>3.1.5.5 Allow empty components</h4>
|
2344 |
+
Allow or reject empty calendar properties, default allow (TRUE).
|
2345 |
+
|
2346 |
+
<br />
|
2347 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_configuration_functions">[up]</a>
|
2348 |
+
|
2349 |
+
<a name="Compsinfo"></a><h4>3.1.5.6 Component information</h4>
|
2350 |
+
Only to use with function getConfig.<br/>
|
2351 |
+
<br />
|
2352 |
+
Get information about calendar components. Returns array with basic information
|
2353 |
+
about all components (in array format) within calendar.
|
2354 |
+
<p class="comment">Output = array ( *compinfo )
|
2355 |
+
compinfo = array ( "ordno" => int ordno,
|
2356 |
+
// <span class="ref">order number (1st=1, 2nd=2..)</span>
|
2357 |
+
, "type" => string type
|
2358 |
+
// <span class="ref">component type (vevent, vtodo.. .</span>
|
2359 |
+
, "uid" => string uid
|
2360 |
+
// <span class="ref">component <a href="#UID">UID</a> (not for <a href="#VALARM">ALARM</a> / <a href="#VTIMEZONE">TIMEZONE</a>)</span>
|
2361 |
+
, "props" =>
|
2362 |
+
array( *[ propertyName => Property count ])
|
2363 |
+
// <span class="ref">for every set property</span>
|
2364 |
+
, "sub" => array( *compinfo ))
|
2365 |
+
// <span class="ref">if subcomponents exists, an array for each subcomponent</span></p>
|
2366 |
+
<p class="label">Example</p>
|
2367 |
+
<p class="example">$config = array( "unique_id" => "domain.com",
|
2368 |
+
"directory" => "import",
|
2369 |
+
"filename" => "file.ics" );
|
2370 |
+
$vcalendar = new vcalendar( $config );
|
2371 |
+
$vcalendar->parse();
|
2372 |
+
$compsinfo = $vcalendar->getConfig( "compsinfo" );
|
2373 |
+
foreach( $compsinfo as compinfo) {
|
2374 |
+
echo " order number : ".$compinfo["ordno"]."<br />";
|
2375 |
+
echo " type : ".$compinfo["type"]."<br />";
|
2376 |
+
echo " UID : ".$compinfo["uid"]."<br />";
|
2377 |
+
foreach( $compinfo["props"] as $propertyName => $propertyCount )
|
2378 |
+
echo " $propertyName = $propertyCount";
|
2379 |
+
if( is_array( $compinfo["sub"] )) {
|
2380 |
+
foreach( $compinfo["sub"] as $subcompinfo ) {
|
2381 |
+
echo " order number : ".$subcompinfo["ordno"]."<br />";
|
2382 |
+
/* .. dito if subcomponents exists .. . */
|
2383 |
+
}
|
2384 |
+
}
|
2385 |
+
}
|
2386 |
+
</p>
|
2387 |
+
<br />
|
2388 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_configuration_functions">[up]</a>
|
2389 |
+
|
2390 |
+
<a name="Delimiter"></a><h4>3.1.5.7 Delimiter</h4>
|
2391 |
+
Directory/filename delimiter.
|
2392 |
+
<br />
|
2393 |
+
<br />
|
2394 |
+
Default PHP constant DIRECTORY_SEPARATOR. If used, <b>must</b> be set BEFORE filename!
|
2395 |
+
<br />
|
2396 |
+
<br />
|
2397 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_configuration_functions">[up]</a>
|
2398 |
+
|
2399 |
+
<a name="Directory"></a><h4>3.1.5.8 Directory</h4>
|
2400 |
+
Local directory to store/read iCal files, default "<b>.</b>".
|
2401 |
+
<br />
|
2402 |
+
<br />
|
2403 |
+
Directory <b>must</b> be set BEFORE <a href="#Filename">filename</a> and <b>must</b> exist and be writeable otherwise FALSE is returned.
|
2404 |
+
When setting Directory any previously set <a href="#configURL">URL</a> is removed.
|
2405 |
+
<br />
|
2406 |
+
<br />
|
2407 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_configuration_functions">[up]</a>
|
2408 |
+
|
2409 |
+
<a name="Fileinfo"></a><h4>3.1.5.9 Fileinfo</h4>
|
2410 |
+
Only available in function getConfig, giving information in array format about <a href="#Directory">directory</a>, <a href="#Filename">filename</a> and <a href="#Filesize">filesize</a>.
|
2411 |
+
<p class="label">Example</p>
|
2412 |
+
<p class="example">$fileinfo = $vcalendar->getConfig( "fileinfo" );</p>
|
2413 |
+
<p class="comment">output = array( <directory>, <filename>, <filesize> )</p>
|
2414 |
+
<br />
|
2415 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_configuration_functions">[up]</a>
|
2416 |
+
|
2417 |
+
<a name="Filename"></a><h4>3.1.5.10 Filename</h4>
|
2418 |
+
iCal local file name, default created like (if not set):<br />
|
2419 |
+
<p class="format">$filename = date( "YmdHis" ).".ics";</p>
|
2420 |
+
<p class="format">$filename = date( "YmdHis" ).".xml"; <span class="comment"> // if <a href="#Format">format</a> set to "xcal"</span></p>
|
2421 |
+
<br />
|
2422 |
+
If not set, filename is created when requested, ex. in functions <a href="#saveCalendar">saveCalendar</a> or getConfig('filename').
|
2423 |
+
<br />
|
2424 |
+
<br />
|
2425 |
+
Local filename <b>must</b> be set AFTER setting directory (and opt. delimiter)!
|
2426 |
+
Filename (and opt. directory) <b>must</b> be readable/writeable otherwise FALSE is returned.
|
2427 |
+
<br />
|
2428 |
+
<br />
|
2429 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_configuration_functions">[up]</a>
|
2430 |
+
|
2431 |
+
<a name="Filesize"></a><h4>3.1.5.11 Filesize</h4>
|
2432 |
+
Only when getting configuration (using function getConfig).<br/>
|
2433 |
+
Returns the size of the file in bytes, to be called<br />
|
2434 |
+
- after "saveCalendar()"<br />
|
2435 |
+
or<br />
|
2436 |
+
- after a "setConfig( "directory" / "filename" )" and before/after "parse()".<br />
|
2437 |
+
Getting the filesize for a remote file (URL) will always return zero.
|
2438 |
+
<br />
|
2439 |
+
<br />
|
2440 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_configuration_functions">[up]</a>
|
2441 |
+
|
2442 |
+
<a name="Format"></a><h4>3.1.5.12 Format</h4>
|
2443 |
+
Format for calendar output, "iCal"/"xCal", any case.
|
2444 |
+
<br />
|
2445 |
+
"iCal" is default (rfc2445), "xCal" force xml formatted output.
|
2446 |
+
<br />
|
2447 |
+
<br />
|
2448 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_configuration_functions">[up]</a>
|
2449 |
+
|
2450 |
+
<a name="Language"></a><h4>3.1.5.13 Language</h4>
|
2451 |
+
Language for calendar and component TEXT value properties as defined in [RFC 1766].
|
2452 |
+
<br />
|
2453 |
+
<br />
|
2454 |
+
If NOT set in TEXT property parameters, language from "setConfig( "language", .." at component level will be used, if set,
|
2455 |
+
otherwise language from "setConfig( "language", .." at calendar level will be used, if set.
|
2456 |
+
<br />
|
2457 |
+
<br />
|
2458 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_configuration_functions">[up]</a>
|
2459 |
+
|
2460 |
+
<a name="NewlineChar"></a><h4>3.1.5.14 NewlineChar</h4>
|
2461 |
+
Character(s) used for carriage return + line feed (CR+LF), default "\r\n".
|
2462 |
+
<br />
|
2463 |
+
<br />
|
2464 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_configuration_functions">[up]</a>
|
2465 |
+
|
2466 |
+
<a name="dTZID"></a><h4>3.1.5.15 TZID</h4>
|
2467 |
+
Default (local) timezone, will be used if no TZID parameter is used when setting <a href="#DTSTART">DTSTART</a>, <a href="#DTEND">DTEND</a>, <a href="#DUE">DUE</a> or <a href="#RECURRENCE-ID">RECURRENCE-ID</a> (auto completion).
|
2468 |
+
Note, some calendar software require <a href="#Additional_Descriptors">X-WR-TIMEZONE</a> (to be set manually).
|
2469 |
+
<br />
|
2470 |
+
<br />
|
2471 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_configuration_functions">[up]</a>
|
2472 |
+
|
2473 |
+
<a name="Unique_id"></a><h4>3.1.5.16 Unique_id</h4>
|
2474 |
+
Unique_id is used when creating property PRODID (default auto created) at calendar level
|
2475 |
+
and <a href="#UID">UID</a> at component level.
|
2476 |
+
<p class="quotes">PRODID
|
2477 |
+
RFC2445:
|
2478 |
+
* The identifier is RECOMMENDED to be the identical syntax to the
|
2479 |
+
* [RFC 822] addr-spec. A good method to assure uniqueness is to put the
|
2480 |
+
* domain name or a domain literal IP address of the host on which.. .<p>
|
2481 |
+
Default <b>AUTO</b> generated, PHP: gethostbyname( $_SERVER["SERVER_NAME"] )
|
2482 |
+
when running in a web server environment or "localhost" when doing command line execution.
|
2483 |
+
Used when setting other (domain) name than server name.
|
2484 |
+
<br />
|
2485 |
+
<br />
|
2486 |
+
A strong recommendation is <b>always</b> to set unique_id when creating a new vcalendar or component object,
|
2487 |
+
to ensure accurate creation of all components <a href="#UID">UID</a> property, also before <a href="#parse">parse</a>, in case of missing <a href="#UID">UID</a>.
|
2488 |
+
<br />
|
2489 |
+
<br />
|
2490 |
+
|
2491 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_configuration_functions">[up]</a>
|
2492 |
+
|
2493 |
+
<a name="configURL"></a><h4>3.1.5.17 URL</h4>
|
2494 |
+
When managing remote files with URL (writing using <a href="#saveCalendar">saveCalendar()</a>, or reading using <a href="#parse">parse()</a>),
|
2495 |
+
only protocol "http" ("webcal") is supported,
|
2496 |
+
i.e. <b>must</b> be prefixed by "http://" ("webcal://") and suffixed by a valid filename.
|
2497 |
+
|
2498 |
+
<h5>Set URL</h5>
|
2499 |
+
When setting URL, any previously set Directory is removed.<br />
|
2500 |
+
The URL filename part can be retrieved by "getConfig( 'filename' )".
|
2501 |
+
<br />
|
2502 |
+
<br />
|
2503 |
+
When storing a remote iCal file locally, only directory need to be set,
|
2504 |
+
filename remains unchanged (i.e. 1. set URL, 2. parse, 3. set directory).
|
2505 |
+
<p class="label">Example</p>
|
2506 |
+
<p class="example">$config = array( "unique_id" => "domain.com",
|
2507 |
+
"url", "http://www.iCal.net/depot/calendar.ics" );
|
2508 |
+
$vcalendar = new vcalendar( $config );
|
2509 |
+
$vcalendar->parse();
|
2510 |
+
$vcalendar->sort();
|
2511 |
+
.. .
|
2512 |
+
.. .
|
2513 |
+
$vcalendar->setConfig( "directory", "depot" );
|
2514 |
+
$vcalendar->saveCalendar(); // <span class="ref">local save in "depot" folder, </span>
|
2515 |
+
// <span class="ref">using original filename</span>
|
2516 |
+
</p>
|
2517 |
+
<br />
|
2518 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_configuration_functions">[up]</a>
|
2519 |
+
|
2520 |
+
<a name="Calendar_component_object_property_function_list"></a><h2>3.2 Calendar component object property function list</h2>
|
2521 |
+
<p>
|
2522 |
+
All calendar component property functions for get/set data.<br />
|
2523 |
+
For property format in detail, see
|
2524 |
+
RFC2445 - Internet Calendaring and Scheduling Core Object Specification (iCalendar) in <a href="http://www.kigkonsult.se/downloads/dl.php?f=rfc2445" title="RFC2445 in text format"><b>text</b></a>
|
2525 |
+
and <a href="http://www.kigkonsult.se/iCalcreator/iCalDictionary/index.html" title="RFC2445 in HTML format" target="_blank"><b>HTML</b></a> format.
|
2526 |
+
</p>
|
2527 |
+
<a name="DATE_WITH_UTC_TIME"></a>
|
2528 |
+
<span class="label">Notice:</span> for properties and DATE-TIME with <b>UTC</b> time.
|
2529 |
+
<p class="quotes">RFC2445:
|
2530 |
+
The date with UTC time, or absolute time, is identified by a LATIN CAPITAL
|
2531 |
+
LETTER Z suffix character (US-ASCII decimal 90), the UTC designator,
|
2532 |
+
appended to the time value. For example, the following represents January
|
2533 |
+
19, 1998, at 0700 UTC:</p>
|
2534 |
+
<p class="quotes">DTSTART:19980119T070000Z</p>
|
2535 |
+
<p class="quotes">The <a href="#TZID">TZID</a> property parameter MUST <b>NOT</b> be applied to DATE-TIME properties
|
2536 |
+
whose time values are specified in UTC.</p>
|
2537 |
+
</p>
|
2538 |
+
<p>
|
2539 |
+
<a name="date_restriction"></a>
|
2540 |
+
<span class="label">Notice:</span> date limitation.<br />
|
2541 |
+
Due to limitation in PHP date commands, e.g. <span class="format">mktime</span>, <span class="format">strtotime</span>, a date (e.g. while setting <a href="#DTSTART">DTSTART</a> property) before "January 1 1970 00:00:00 GMT" can force a PHP date command to generate an error or set date to "January 1 1970".
|
2542 |
+
</p>
|
2543 |
+
<a name="deleteProperty_PROP"></a><h3>3.2.1 deleteProperty</h3>
|
2544 |
+
General calendar delete property function,simplifying removal of calendar properties.<br />
|
2545 |
+
FALSE is returned if no property exists or when end-of-properties at consecutive function calls.
|
2546 |
+
<p class="label">Format</p>
|
2547 |
+
<p class="format">deleteProperty( [ string PropName [, int order=1 ] )</p>
|
2548 |
+
<p class="comment">propName - case independent, rfc2445 component property names,
|
2549 |
+
unknown/missing propName will be used as <a href="#X-PROPERTY_PROP">X-property</a>.
|
2550 |
+
order - if missing 1st/next occurrence,
|
2551 |
+
used with multiply (property) occurrences</p>
|
2552 |
+
<p class="label">Example</p>
|
2553 |
+
<p class="example">$config = array( "unique_id" => "domain.com",
|
2554 |
+
"directory" => "import",
|
2555 |
+
"filename" => "file.ics" );
|
2556 |
+
$vcalendar = new vcalendar( $config );
|
2557 |
+
$vcalendar->parse();
|
2558 |
+
$e = $vcalendar->getComponent( "vevent" );
|
2559 |
+
while( $e->deleteProperty( "comment" ))
|
2560 |
+
continue; // <span class="ref">remove all COMMENT properties</span>
|
2561 |
+
.. .
|
2562 |
+
</p>
|
2563 |
+
<br />
|
2564 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
2565 |
+
|
2566 |
+
<a name="getProperty_PROP"></a><h3>3.2.2 getProperty</h3>
|
2567 |
+
General get property function, simplifying fetch of calendar properties.<br />
|
2568 |
+
FALSE is returned if no property exists or when end-of-properties at consecutive function calls.
|
2569 |
+
<p class="label">Format</p>
|
2570 |
+
<p class="format">getProperty( string PropName [, int order=1 [, bool complete=FALSE ]] )</p>
|
2571 |
+
<p class="comment">propName - case independent, rfc2445 component property names,
|
2572 |
+
unknown/missing propName will be used as <a href="#X-PROPERTY_PROP">X-property</a>.
|
2573 |
+
order - if missing/FALSE 1st/next occurrence,
|
2574 |
+
otherwise with multiply occurrences (1st=1, 2nd=2.. .)
|
2575 |
+
complete - FALSE (default): output only property value
|
2576 |
+
TRUE : output =
|
2577 |
+
array("value" => <value>
|
2578 |
+
,"params"=> <parameter array>)
|
2579 |
+
</p>
|
2580 |
+
<p class="label">Example</p>
|
2581 |
+
<p class="example">$config = array( "unique_id" => "domain.com",
|
2582 |
+
"directory" => "import",
|
2583 |
+
"filename" => "file.ics" );
|
2584 |
+
$vcalendar = new vcalendar( $config );
|
2585 |
+
$vcalendar->parse();
|
2586 |
+
while( $vevent = $vcalendar->getComponent( "vevent" )) {
|
2587 |
+
$dtstart = $vevent->getProperty( "dtstart" ); // <span class="ref">one occurrence</span>
|
2588 |
+
$description = $vevent->getProperty( "description" ); // <span class="ref">one occurrence</span>
|
2589 |
+
while( $comment = $vevent->getProperty( "comment" )) {
|
2590 |
+
// <span class="ref">MAY occur more than once</span>
|
2591 |
+
.. .
|
2592 |
+
}
|
2593 |
+
.. .
|
2594 |
+
</p>
|
2595 |
+
<br />
|
2596 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
2597 |
+
|
2598 |
+
<a name="parse"></a><h3>3.2.3 parse</h3>
|
2599 |
+
Parse strict rfc2445 component property text and/or ALARMs.
|
2600 |
+
<br /><br />
|
2601 |
+
A rfc2445 strict formatted property text, in string or array format and starting with property name.
|
2602 |
+
<br />
|
2603 |
+
<br />
|
2604 |
+
Complete <a href="#VALARM">ALARM</a>s, all properties included, in array format and
|
2605 |
+
first array row as "BEGIN:VALARM", last as "END:VALARM"
|
2606 |
+
as well as <a href="#VTIMEZONE">TIMEZONE</a> and standard/daylight subcomponents.
|
2607 |
+
<br /><br />
|
2608 |
+
FALSE is returned if (read-file) problems occur.
|
2609 |
+
<p class="label">Format</p>
|
2610 |
+
<p class="format">parse( mixed propertyText )</p>
|
2611 |
+
<p class="comment">
|
2612 |
+
propertyText = string/array,
|
2613 |
+
rcf2445 formatted property/properties,
|
2614 |
+
property name <b>must</b> begin (first) line</p>
|
2615 |
+
<p class="label">example</p>
|
2616 |
+
<p class="example">.. .
|
2617 |
+
$vevent = & $vcalendar->newComponent( 'vevent' );
|
2618 |
+
$e->parse( 'DTSTAMP:19970324T1200Z' );
|
2619 |
+
$e->parse( 'SEQUENCE:0' );
|
2620 |
+
$e->parse( 'ORGANIZER:MAILTO:jdoe@host1.com' );
|
2621 |
+
$e->parse( array(
|
2622 |
+
'ATTENDEE;RSVP=TRUE:MAILTO:jsmith@host1.com',
|
2623 |
+
'ATTENDEE;RSVP=TRUE:MAILTO:jsmith@host2.com',
|
2624 |
+
'ATTENDEE;RSVP=TRUE:MAILTO:jsmith@host3.com',
|
2625 |
+
'ATTENDEE;RSVP=TRUE:MAILTO:jsmith@host4.com' ));
|
2626 |
+
$e->parse( 'DTSTART:19970324T123000Z' );
|
2627 |
+
$e->parse( 'DTEND:19970324T210000Z' );
|
2628 |
+
$e->parse( 'CATEGORIES:MEETING,PROJECT' );
|
2629 |
+
$e->parse( 'CLASS:PUBLIC' );
|
2630 |
+
$e->parse( 'SUMMARY:Calendaring Interoperability Planning Meeting' );
|
2631 |
+
$e->parse( 'STATUS:DRAFT' );
|
2632 |
+
$e->parse( array(
|
2633 |
+
'DESCRIPTION:Project xyz Review Meeting Minutes'
|
2634 |
+
,'Agenda'
|
2635 |
+
,'1. Review of project version 1.0 requirements.'
|
2636 |
+
,'2. Definition of project processes.'
|
2637 |
+
,'3. Review of project schedule.'
|
2638 |
+
,'Participants: John Smith, Jane Doe, Jim Dandy'
|
2639 |
+
,'- It was decided that the requirements need to be signed off by '.
|
2640 |
+
'product marketing.'
|
2641 |
+
,'- Project processes were accepted.'
|
2642 |
+
,'- Project schedule needs to account for scheduled holidays and employee'.
|
2643 |
+
' vacation time. Check with HR for specific dates.'
|
2644 |
+
,'- New schedule will be distributed by Friday.'
|
2645 |
+
,'- Next weeks meeting is cancelled. No meeting until 3/23.' ));
|
2646 |
+
$e->parse( 'LOCATION:LDB Lobby' );
|
2647 |
+
$e->parse(
|
2648 |
+
'ATTACH;FMTTYPE=application/postscript:ftp://xyz.com/pub/conf/bkgrnd.ps' );
|
2649 |
+
$e->parse( array(
|
2650 |
+
'BEGIN:VALARM',
|
2651 |
+
'ACTION:AUDIO',
|
2652 |
+
'TRIGGER;VALUE=DATE-TIME:19970224T070000Z',
|
2653 |
+
'ATTACH;FMTTYPE=audio/basic:http://host.com/pub/audio-files/ssbanner.aud',
|
2654 |
+
'REPEAT:4',
|
2655 |
+
'DURATION:PT1H',
|
2656 |
+
'X-alarm:non-standard ALARM property',
|
2657 |
+
'END:VALARM' ));
|
2658 |
+
$e->parse(
|
2659 |
+
'X-xomment:non-standard property will be displayed, comma escaped');
|
2660 |
+
.. .
|
2661 |
+
</p>
|
2662 |
+
<br />
|
2663 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
2664 |
+
|
2665 |
+
|
2666 |
+
<a name="setProperty_PROP"></a><h3>3.2.4 setProperty</h3>
|
2667 |
+
General set property function, simplifying insert of component properties. For properties where
|
2668 |
+
multiple occurrences are allowed, last parameter is an index, implementing replaceProperty functionality.<br />
|
2669 |
+
A successful update returns TRUE.
|
2670 |
+
<p class="label">Format</p>
|
2671 |
+
<p class="format">setProperty( string PropName, mixed Proparg_1 *[, mixed Proparg_n] )</p>
|
2672 |
+
<p class="comment">propName case independent, rfc2445 component property names,
|
2673 |
+
unknown propName will be regarded as <a href="#X-PROPERTY_PROP">X-property</a>.</p>
|
2674 |
+
<p class="label">Example</p>
|
2675 |
+
<p class="example">$vevent = & $vcalendar->newComponent( 'vevent' );
|
2676 |
+
$vevent->setProperty( "dtstart"
|
2677 |
+
, array("year"=>2007,"month"=>4,"day"=>1,"hour"=>19));
|
2678 |
+
$vevent->setProperty( "duration", 0, 0, 3 ));
|
2679 |
+
$vevent->setProperty( "LOCATION", "Central Plaza" );
|
2680 |
+
$vevent->setProperty( "summary", "PHP summit" );
|
2681 |
+
.. .
|
2682 |
+
</p>
|
2683 |
+
<br />
|
2684 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
2685 |
+
|
2686 |
+
|
2687 |
+
<a name="ACTION"></a><h3>3.2.5 ACTION</h3>
|
2688 |
+
This property defines the action to be invoked when an <a href="#VALARM">VALARM</a> is triggered,<br /> "AUDIO" / "DISPLAY" / "EMAIL" / "PROCEDURE". This property is REQUIRED and MUST NOT occur more than once.
|
2689 |
+
<h5>Delete ACTION</h5>
|
2690 |
+
Remove ACTION from component.
|
2691 |
+
<p class="label">Format</p>
|
2692 |
+
<p class="format">deleteProperty( "Action" )</p>
|
2693 |
+
<p class="label">Example</p>
|
2694 |
+
<p class="example">$valarm->deleteProperty( "Action" );</p>
|
2695 |
+
<h5>Get ACTION</h5>
|
2696 |
+
Fetch property value.
|
2697 |
+
<p class="label">Format 1</p>
|
2698 |
+
<p class="format">getProperty( "Action" )</p>
|
2699 |
+
<p class="comment">output = actionValue <span class="ref">1</span></p>
|
2700 |
+
<p class="label">Format 2</p>
|
2701 |
+
<p class="format">getProperty( "Action", FALSE , TRUE )</p>
|
2702 |
+
<p class="comment">output = array( "value" => actionValue<span class="ref">1</span>
|
2703 |
+
, "params" => xparam<span class="ref">2</span> )</p>
|
2704 |
+
<p class="label">Example</p>
|
2705 |
+
<p class="example">$action = $valarm->getProperty( "action" );</p>
|
2706 |
+
<h5>Set ACTION</h5>
|
2707 |
+
Insert property value.
|
2708 |
+
<p class="label">Format</p>
|
2709 |
+
<p class="format">setProperty( "Action", actionValue [, xparam ] )</p>
|
2710 |
+
<p class="comment">actionValue<span class="ref">1</span> = one of "AUDIO" / "DISPLAY" / "EMAIL" / "PROCEDURE"
|
2711 |
+
xparam<span class="ref">2</span> = array( *[ xparamkey => xparamvalue ] )</p>
|
2712 |
+
<p class="label">Example</p>
|
2713 |
+
<p class="example">$valarm->setProperty( "action", "DISPLAY" );</p>
|
2714 |
+
<br />
|
2715 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
2716 |
+
|
2717 |
+
|
2718 |
+
<a name="ATTACH"></a><h3>3.2.6 ATTACH</h3>
|
2719 |
+
The property provides the capability to associate a document object with a calendar component. The property is
|
2720 |
+
is REQUIRED and MUST NOT occur more than once in an "ALARM" ("ACTION" "procedure"),
|
2721 |
+
OPTIONAL and MUST NOT occur more than once in an "ALARM" ("ACTION" "audio") and
|
2722 |
+
OPTIONAL and MAY occur more than once in <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a>, <a href="#VJOURNAL">VJOURNAL</a> and <a href="#VALARM">VALARM</a> ("ACTION" "email") components.
|
2723 |
+
<br /><br />
|
2724 |
+
The default value type for ATTACH is URI. The value type can also be set to BINARY to indicate inline binary encoded content information (params <span class="ref">2</span>).
|
2725 |
+
<h5>Delete ATTACH</h5>
|
2726 |
+
Remove ATTACH from component.
|
2727 |
+
<p class="label">Format</p>
|
2728 |
+
<p class="format">deleteProperty( "ATTACH" )</p>
|
2729 |
+
<p class="label">Example 1</p>
|
2730 |
+
<p class="example">$valarm->deleteProperty( "ATTACH" );</p>
|
2731 |
+
<p class="label">Example 2</p>
|
2732 |
+
Delete ATTACH property no 2.
|
2733 |
+
<p class="format">$valarm->deleteProperty( "ATTACH", 2 );</p>
|
2734 |
+
<p class="label">Example 3</p>
|
2735 |
+
Deleting all ATTACH properties.
|
2736 |
+
<p class="example">while( $valarm->deleteProperty( "ATTACH" ))
|
2737 |
+
continue;</p>
|
2738 |
+
<h5>Get ATTACH</h5>
|
2739 |
+
Fetch property value.
|
2740 |
+
<p class="label">Format 1</p>
|
2741 |
+
<p class="format">getProperty( "Attach" )</p>
|
2742 |
+
<p class="comment">output = attachValue<span class="ref">1</span></p>
|
2743 |
+
<p class="label">Format 2</p>
|
2744 |
+
<p class="format">getProperty( "ATTACH", propOrderNo/FALSE , TRUE )</p>
|
2745 |
+
<p class="comment">output = array( "value" => attachValue<span class="ref">1</span>
|
2746 |
+
, "params" => params<span class="ref">2</span> )</p>
|
2747 |
+
<p class="label">Format 3</p>
|
2748 |
+
<p class="format">getProperty( "Attach", propOrderNo )</p>
|
2749 |
+
<p class="comment">Get propOrderNo ATTACH</p>
|
2750 |
+
<p class="label">Example</p>
|
2751 |
+
<p class="example">$attach = $valarm->getProperty( "attach" );</p>
|
2752 |
+
<h5>Set ATTACH</h5>
|
2753 |
+
Insert property value.
|
2754 |
+
<br />
|
2755 |
+
Parameters, if any, will be ordered as prescribed in rcf2445.
|
2756 |
+
<p class="label">Format</p>
|
2757 |
+
<p class="format">setProperty( "attach", attachValue<span class="ref">1</span> [, params [, propOrderNo ]] )</p>
|
2758 |
+
<p class="comment">attachValue<span class="ref">1</span> = URI / inline binary encoded content information.
|
2759 |
+
params<span class="ref">2</span> = array( [ "ENCODING" => "BASE64",
|
2760 |
+
"VALUE" => "BINARY" ]
|
2761 |
+
[, "FMTTYPE" => contentType ]
|
2762 |
+
[, xparam ] )
|
2763 |
+
contentType = The parameter value MUST be the TEXT for either
|
2764 |
+
an IANA registered content type or a non-standard
|
2765 |
+
content type.
|
2766 |
+
xparam = *[ xparamkey => xparamvalue ]
|
2767 |
+
propOrderNo = int ordernumber, 1=1st, 2=2nd etc</p>
|
2768 |
+
<p class="label">Example</p>
|
2769 |
+
<p class="example">$vevent->setProperty( "attach"
|
2770 |
+
, "ftp://domain.com/pub/docs/agenda.doc"
|
2771 |
+
, array( "FMTTYPE" => "application/binary" ));
|
2772 |
+
</p>
|
2773 |
+
<br />
|
2774 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
2775 |
+
|
2776 |
+
|
2777 |
+
<a name="ATTENDEE"></a><h3>3.2.7 ATTENDEE</h3>
|
2778 |
+
The property defines an "Attendee" within a calendar component and is OPTIONAL and MUST NOT occur more than once
|
2779 |
+
in a VALARM ("ACTION" "email"), OPTIONAL and MAY occur more than once in <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a>, <a href="#VJOURNAL">VJOURNAL</a> and <a href="#VFREEBUSY">VFREEBUSY</a> components.
|
2780 |
+
<br /><br />
|
2781 |
+
This value type for ATTENDEE is URI, a calendar user address.
|
2782 |
+
<h5>Delete ATTENDEE</h5>
|
2783 |
+
Remove ATTENDEE from component.
|
2784 |
+
<p class="label">Format</p>
|
2785 |
+
<p class="format">deleteProperty( "ATTENDEE" )</p>
|
2786 |
+
<p class="label">Example 1</p>
|
2787 |
+
<p class="example">$valarm->deleteProperty( "ATTENDEE" );</p>
|
2788 |
+
<p class="label">Example 2</p>
|
2789 |
+
Delete ATTENDEE property no 2.
|
2790 |
+
<p class="example">$valarm->deleteProperty( "ATTENDEE", 2 );</p>
|
2791 |
+
<p class="label">Example 3</p>
|
2792 |
+
Deleting all ATTENDEE properties.
|
2793 |
+
<p class="example">while( $valarm->deleteProperty( "ATTENDEE" ))
|
2794 |
+
continue;</p>
|
2795 |
+
<h5>Get ATTENDEE</h5>
|
2796 |
+
Fetch property value.
|
2797 |
+
<p class="label">Format 1</p>
|
2798 |
+
<p class="format">getProperty( "Attendee" )</p>
|
2799 |
+
<p class="comment">output = attendeeValue <span class="ref">1</span></p>
|
2800 |
+
<p class="label">Format 2</p>
|
2801 |
+
<p class="format">getProperty( "ATTENDEE", propOrderNo/FALSE , TRUE )</p>
|
2802 |
+
<p class="comment">output = array( "value" => attendeeValue<span class="ref">1</span>
|
2803 |
+
, "params" => array( params<span class="ref">2</span> ))</p>
|
2804 |
+
<p class="label">Format 3</p>
|
2805 |
+
<p class="format">getProperty( "ATTENDEE", propOrderNo )</p>
|
2806 |
+
<p class="comment">Get propOrderNo ATTENDEE</p>
|
2807 |
+
<p class="label">Example</p>
|
2808 |
+
<p class="example">$attendee = $valarm->getProperty( "attendee" );</p>
|
2809 |
+
<h5>Set ATTENDEE</h5>
|
2810 |
+
Insert property value. If exist, default parameter values are removed after input (params<span class="ref">2</span>).
|
2811 |
+
Property value must be prefixed by protocol (ftp://, http://,mailto:, file://.. . ref. rfc 1738 ), if missing, 'mailto:' is set (ex. indicating an internet mail address).
|
2812 |
+
Also MEMBER and DIR parameters must be prefixed by protocol. DELEGATED-TO, DELEGATED-FROM, SENT-BY parameters must use protocol 'mailto:', prefixed if missing (ex. indicating an internet mail address).
|
2813 |
+
<br />
|
2814 |
+
Parameters, if any, will be ordered as prescribed in rcf2445.
|
2815 |
+
<p class="label">Format</p>
|
2816 |
+
<p class="format">setProperty( "attendee", attendeeValue [, params [, propOrderNo ]] )</p>
|
2817 |
+
<p class="comment">attendeeValue<span class="ref">1</span> = a calendar user address, a URI as defined by
|
2818 |
+
[RFC 1738] or any other IANA registered form
|
2819 |
+
for a URI.
|
2820 |
+
params<span class="ref">2</span> = array( [CUTYPE] [,MEMBER] [,ROLE] [,PARTSTAT]
|
2821 |
+
[,RVSP] [,DELEGATED-TO] [,DELEGATED-FROM]
|
2822 |
+
[,SENT-BY] [,CN] [,DIR] [,LANGUAGE]
|
2823 |
+
[,xparams] )
|
2824 |
+
CUTYPE = "CUTYPE" => "INDIVIDUAL"
|
2825 |
+
(An individual, <b>Default</b>)
|
2826 |
+
/ "GROUP"
|
2827 |
+
(A group of individuals)
|
2828 |
+
/ "RESOURCE"
|
2829 |
+
(A physical resource)
|
2830 |
+
/ "ROOM"
|
2831 |
+
(A room resource)
|
2832 |
+
/ "UNKNOWN"
|
2833 |
+
(Otherwise not known)
|
2834 |
+
/ x-name
|
2835 |
+
(Experimental type)
|
2836 |
+
/ iana-token
|
2837 |
+
(Other IANA registered type)
|
2838 |
+
MEMBER = "MEMBER" => array( *[ "single member
|
2839 |
+
of the group or list membership"])
|
2840 |
+
ROLE = "ROLE" => "CHAIR"
|
2841 |
+
(Indicates chair of the calendar
|
2842 |
+
entity)
|
2843 |
+
/ "REQ-PARTICIPANT"
|
2844 |
+
(required participation, <b>Default</b>)
|
2845 |
+
/ "OPT-PARTICIPANT"
|
2846 |
+
(optional participation)
|
2847 |
+
/ "NON-PARTICIPANT"
|
2848 |
+
(information purposes only)
|
2849 |
+
/ x-name
|
2850 |
+
(Experimental role)
|
2851 |
+
/ iana-token
|
2852 |
+
(Other IANA role)
|
2853 |
+
PARTSTAT = "PARTSTAT" => "NEEDS-ACTION"
|
2854 |
+
(Event needs action, <b>Default</b>)
|
2855 |
+
/ "ACCEPTED"
|
2856 |
+
(Event accepted)
|
2857 |
+
/ "DECLINED"
|
2858 |
+
(Event declined)
|
2859 |
+
/ "TENTATIVE"
|
2860 |
+
(Event tentatively accepted)
|
2861 |
+
/ "DELEGATED"
|
2862 |
+
(Event delegated)
|
2863 |
+
/ "NEEDS-ACTION"
|
2864 |
+
(To-do needs action, <b>Default</b>)
|
2865 |
+
/ "ACCEPTED"
|
2866 |
+
(To-do accepted)
|
2867 |
+
/ "DECLINED"
|
2868 |
+
(To-do declined)
|
2869 |
+
/ "TENTATIVE"
|
2870 |
+
(To-do tentatively accepted)
|
2871 |
+
/ "DELEGATED"
|
2872 |
+
(To-do delegated)
|
2873 |
+
/ "COMPLETED"
|
2874 |
+
(To-do completed.
|
2875 |
+
<a href="#COMPLETED">COMPLETED</a> property
|
2876 |
+
has date/time completed)
|
2877 |
+
/ "IN-PROCESS"
|
2878 |
+
(To-do in process of being completed)
|
2879 |
+
/ "NEEDS-ACTION"
|
2880 |
+
(Journal needs action, <b>Default</b>)
|
2881 |
+
/ "ACCEPTED"
|
2882 |
+
(Journal accepted)
|
2883 |
+
/ "DECLINED"
|
2884 |
+
(Journal declined)
|
2885 |
+
/ x-name
|
2886 |
+
(Experimental status)
|
2887 |
+
/ iana-token
|
2888 |
+
(Other IANA registered status)
|
2889 |
+
RSVP = "RSVP" => "TRUE"
|
2890 |
+
/ "FALSE", <b>Default</b> (reply expectation)
|
2891 |
+
DELEGATED-TO = "DELEGATED-TO" => array(*["single calendar user
|
2892 |
+
to specified by the property
|
2893 |
+
has delegated participation"])
|
2894 |
+
DELEGATED-FROM = "DELEGATED-FROM" => array( *[ "single calendar user that
|
2895 |
+
have delegated their
|
2896 |
+
participation to the
|
2897 |
+
calendar user specified
|
2898 |
+
by the property" ] )
|
2899 |
+
SENT-BY = "SENT-BY" => single calendar user that is
|
2900 |
+
acting on behalf
|
2901 |
+
of the calendar user
|
2902 |
+
specified by the property"
|
2903 |
+
LANGUAGE = "LANGUAGE" => language for text values in CN parameter"
|
2904 |
+
CN = "CN" => "common name to be associated with the calendar
|
2905 |
+
user specified by the property"
|
2906 |
+
DIR = "DIR" => "reference to a directory entry associated with
|
2907 |
+
the calendar user specified by the property"
|
2908 |
+
xparam = *[ xparamkey => xparamvalue ]
|
2909 |
+
propOrderNo = int ordernumber, 1=1st, 2=2nd etc</p>
|
2910 |
+
See rules in detail in RFC2445 - Internet Calendaring and Scheduling Core Object Specification (iCalendar) in <a href="http://www.kigkonsult.se/downloads/dl.php?f=rfc2445" title="RFC2445 in text format"><b>text</b></a> and <a href="http://www.kigkonsult.se/iCalcreator/iCalDictionary/index.html" title="RFC2445 in HTML format" target="_blank"><b>HTML</b></a> format.
|
2911 |
+
<p class="label">Example</p>
|
2912 |
+
<p class="example">$vevent->setProperty( "attendee"
|
2913 |
+
, "attendee1@ical.net"
|
2914 |
+
$vevent->setProperty( "attendee"
|
2915 |
+
, "attendee2@ical.net"
|
2916 |
+
, array( "cutype" => "INDIVIDUAL"
|
2917 |
+
, "member" => array( "member1@ical.net"
|
2918 |
+
, "member2@ical.net"
|
2919 |
+
, "member3@ical.net" )
|
2920 |
+
, "role" => "CHAIR"
|
2921 |
+
, "PARTSTAT" => "ACCEPTED"
|
2922 |
+
, "RSVP" => "TRUE"
|
2923 |
+
, "DELEgated-to" => array( "part1@ical.net"
|
2924 |
+
, "part2@ical.net"
|
2925 |
+
, "part3@ical.net" )
|
2926 |
+
, "delegateD-FROM" =>array( "cio@ical.net"
|
2927 |
+
, "vice.cio@ical.net")
|
2928 |
+
, "SENT-BY" => "secretary@ical.net"
|
2929 |
+
, "LANGUAGE" => "us-EN"
|
2930 |
+
, "CN" => "John Doe"
|
2931 |
+
, "DIR" => "http://www.ical.net/info.doc"
|
2932 |
+
, "x-agenda" => "status reports" <span class="comment">// xparam</span>
|
2933 |
+
, "x-length" => "15 min" )); <span class="comment">// xparam</span>
|
2934 |
+
</p>
|
2935 |
+
<br />
|
2936 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
2937 |
+
|
2938 |
+
<a name="CATEGORIES"></a><h3>3.2.8 CATEGORIES</h3>
|
2939 |
+
This property defines the categories for a calendar component and is OPTIONAL and MAY occur more than once in <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a> and <a href="#VJOURNAL">VJOURNAL</a> components.<br /><br />
|
2940 |
+
The value type for CATEGORIES is TEXT.
|
2941 |
+
<h5>Delete CATEGORIES</h5>
|
2942 |
+
Remove CATEGORIES from component.
|
2943 |
+
<p class="label">Format</p>
|
2944 |
+
<p class="format">deleteProperty( "CATEGORIES" )</p>
|
2945 |
+
<p class="label">Example 1</p>
|
2946 |
+
<p class="example">$vevent->deleteProperty( "CATEGORIES" );</p>
|
2947 |
+
<p class="label">Example 2</p>
|
2948 |
+
Delete CATEGORIES property no 2.
|
2949 |
+
<p class="example">$vevent->deleteProperty( "CATEGORIES", 2 );</p>
|
2950 |
+
<p class="label">Example 3</p>
|
2951 |
+
Deleting all CATEGORIES properties.
|
2952 |
+
<p class="example">while( $vevent->deleteProperty( "CATEGORIES" ))
|
2953 |
+
continue;</p>
|
2954 |
+
<h5>Get CATEGORIES</h5>
|
2955 |
+
Fetch property value.
|
2956 |
+
<p class="label">Format 1</p>
|
2957 |
+
<p class="format">getProperty( "CATEGORIES" )</p>
|
2958 |
+
<p class="comment">output = categoryValue<span class="ref">1</span></p>
|
2959 |
+
<p class="label">Format 2</p>
|
2960 |
+
<p class="format">getProperty( "CATEGORIES", propOrderNo/FALSE , TRUE )</p>
|
2961 |
+
<p class="comment">output = array( "value" => categories<span class="ref">1</span>
|
2962 |
+
, "params" => params<span class="ref">2</span> )</p>
|
2963 |
+
<p class="label">Format 3</p>
|
2964 |
+
<p class="format">getProperty( "CATEGORIES", propOrderNo )</p>
|
2965 |
+
<p class="comment">Get propOrderNo CATEGORIES</p>
|
2966 |
+
<p class="label">Example</p>
|
2967 |
+
<p class="example">$categories = $valarm->getProperty( "categories" );</p>
|
2968 |
+
<h5>Set CATEGORIES</h5>
|
2969 |
+
Insert property value.
|
2970 |
+
<br />
|
2971 |
+
Parameters, if any, will be ordered as prescribed in rcf2445.
|
2972 |
+
<p class="label">Format</p>
|
2973 |
+
<p class="format">setProperty( "categories", mixed categories [, params [, propOrderNo ]] )</p>
|
2974 |
+
<p class="comment">categories<span class="ref">1</span> = string categoryValue / array( *categoryValue )
|
2975 |
+
categoryValue<span class="ref"> </span>= textual categories or subtypes of the calendar component,
|
2976 |
+
can be specified as a list of categories
|
2977 |
+
separated by the COMMA character
|
2978 |
+
params<span class="ref">2</span> = array( ["LANGUAGE" => "<lang>"][, xparam] )
|
2979 |
+
xparam<span class="ref"> </span> = *[ xparamkey => xparamvalue ]
|
2980 |
+
propOrderNo<span class="ref"> </span> = int ordernumber, 1=1st, 2=2nd etc</p>
|
2981 |
+
<p class="label">Example</p>
|
2982 |
+
<p class="example">$vevent->setProperty( "categories", "project_x" );</p>
|
2983 |
+
<br />
|
2984 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
2985 |
+
|
2986 |
+
|
2987 |
+
<a name="CLASS"></a><h3>3.2.9 CLASS</h3>
|
2988 |
+
This property defines the access classification for a calendar component and is OPTIONAL
|
2989 |
+
and MUST NOT occur more than once in <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a> and <a href="#VJOURNAL">VJOURNAL</a> components.
|
2990 |
+
<h5>Delete CLASS</h5>
|
2991 |
+
Remove CLASS from component.
|
2992 |
+
<p class="label">Format</p>
|
2993 |
+
<p class="format">deleteProperty( "CLASS" )</p>
|
2994 |
+
<p class="label">Example</p>
|
2995 |
+
<p class="example">$vjournal->deleteProperty( "CLASS" );</p>
|
2996 |
+
<h5>Get CLASS</h5>
|
2997 |
+
Fetch property value.
|
2998 |
+
<p class="label">Format 1</p>
|
2999 |
+
<p class="format">getProperty( "CLASS" )</p>
|
3000 |
+
<p class="comment">output = classValue<span class="ref">1</span></p>
|
3001 |
+
<p class="label">Format 2</p>
|
3002 |
+
<p class="format">getProperty( "CLASS", FALSE , TRUE )</p>
|
3003 |
+
<p class="comment">output = array "value" => classValue<span class="ref">1</span>
|
3004 |
+
, "params" => xparam<span class="ref">2</span> )</p>
|
3005 |
+
<p class="label">Example</p>
|
3006 |
+
<p class="example">$class = $valarm->getProperty( "class" );</p>
|
3007 |
+
<h5>Set CLASS</h5>
|
3008 |
+
Insert property value.
|
3009 |
+
<p class="label">Format</p>
|
3010 |
+
<p class="format">setProperty( "class", string classvalue [, xparam ] )</p>
|
3011 |
+
<p class="comment">classvalue<span class="ref">1</span> = "PUBLIC"
|
3012 |
+
/ "PRIVATE"
|
3013 |
+
/ "CONFIDENTIAL"
|
3014 |
+
/ iana-token
|
3015 |
+
/ x-name
|
3016 |
+
xparam<span class="ref">2</span> = array( *[ xparamkey => xparamvalue ] )</p>
|
3017 |
+
<p class="label">Example</p>
|
3018 |
+
<p class="example">$vevent->setProperty( "class", "CONFIDENTIAL" );</p>
|
3019 |
+
<br />
|
3020 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
3021 |
+
|
3022 |
+
<a name="COMMENT"></a><h3>3.2.10 COMMENT</h3>
|
3023 |
+
This property specifies non-processing information intended to provide a comment to the calendar user
|
3024 |
+
and is OPTIONAL and MAY occur more than once in <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a>, <a href="#VJOURNAL">VJOURNAL</a>, <a href="#VFREEBUSY">VFREEBUSY</a>, <a href="#VTIMEZONE">STANDARD</a> and <a href="#VTIMEZONE">DAYLIGHT</a> components.<br /><br />
|
3025 |
+
The value type for COMMENT is TEXT.
|
3026 |
+
<h5>Delete COMMENT</h5>
|
3027 |
+
Remove COMMENT from component.
|
3028 |
+
<p class="label">Format</p>
|
3029 |
+
<p class="format">deleteProperty( "COMMENT" )</p>
|
3030 |
+
<p class="label">Example 1</p>
|
3031 |
+
<p class="example">$vevent->deleteProperty( "COMMENT" );</p>
|
3032 |
+
<p class="label">Example 2</p>
|
3033 |
+
Delete COMMENT property no 2.
|
3034 |
+
<p class="example">$vevent->deleteProperty( "COMMENT", 2 );</p>
|
3035 |
+
<p class="label">Example 3</p>
|
3036 |
+
Deleting all COMMENT properties.
|
3037 |
+
<p class="example">while( $vevent->deleteProperty( "COMMENT" ))
|
3038 |
+
continue;</p>
|
3039 |
+
<h5>Get COMMENT</h5>
|
3040 |
+
Fetch property value.
|
3041 |
+
<p class="label">Format 1</p>
|
3042 |
+
<p class="format">getProperty( "COMMENT" )</p>
|
3043 |
+
<p class="comment">output = commentValue<span class="ref">1</span></p>
|
3044 |
+
<p class="label">Format 2</p>
|
3045 |
+
<p class="format">getProperty( "COMMENT", propOrderNo/FALSE , TRUE )</p>
|
3046 |
+
<p class="comment">output = array( "value" => commentValue<span class="ref">1</span>
|
3047 |
+
, "params" => params<span class="ref">2</span> )</p>
|
3048 |
+
<p class="label">Format 3</p>
|
3049 |
+
<p class="format">getProperty( "COMMENT", propOrderNo )</p>
|
3050 |
+
<p class="comment">Get propOrderNo COMMENT</p>
|
3051 |
+
<p class="label">Example</p>
|
3052 |
+
<p class="example">$comment = $vevent->getProperty( "comment" );</p>
|
3053 |
+
<h5>Set COMMENT</h5>
|
3054 |
+
Insert property value.
|
3055 |
+
<br />
|
3056 |
+
Parameters, if any, will be ordered as prescribed in rcf2445.
|
3057 |
+
<p class="label">Format</p>
|
3058 |
+
<p class="format">setProperty( "comment", commentValue [, params [, propOrderNo ]] )</p>
|
3059 |
+
<p class="comment">commentValue<span class="ref">1</span> = Value type Text
|
3060 |
+
params<span class="ref">2</span> = array( ["ALTREP" => "<an alternate text representation, URI>"]
|
3061 |
+
[, ["LANGUAGE" => "<lang>"]
|
3062 |
+
[, xparam] )
|
3063 |
+
xparam = *[ xparamkey => xparamvalue ]
|
3064 |
+
propOrderNo = int ordernumber, 1=1st, 2=2nd etc</p>
|
3065 |
+
<p class="label">Example</p>
|
3066 |
+
<p class="example">$vevent->setProperty( "comment", "this is a comment" );</p>
|
3067 |
+
<br />
|
3068 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
3069 |
+
|
3070 |
+
|
3071 |
+
<a name="COMPLETED"></a><h3>3.2.11 COMPLETED</h3>
|
3072 |
+
This property defines the date and time that a <a href="#VTODO">VTODO</a> was actually completed and is OPTIONAL and MUST NOT occur more than once.<br /><br />
|
3073 |
+
The value type for COMPLETED is <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME.
|
3074 |
+
<h5>Delete COMPLETED</h5>
|
3075 |
+
Remove COMPLETED from component.
|
3076 |
+
<p class="label">Format</p>
|
3077 |
+
<p class="format">deleteProperty( "COMPLETED" )</p>
|
3078 |
+
<p class="label">Example</p>
|
3079 |
+
<p class="example">$vtodo->deleteProperty( "COMPLETED" );</p>
|
3080 |
+
<h5>Get COMPLETED</h5>
|
3081 |
+
Fetch property value.
|
3082 |
+
<p class="label">Format 1</p>
|
3083 |
+
<p class="format">getProperty( "COMPLETED" )</p>
|
3084 |
+
<p class="comment">output = completedDate<span class="ref">1</span></p>
|
3085 |
+
<p class="label">Format 2</p>
|
3086 |
+
<p class="format">getProperty( "COMPLETED", FALSE , TRUE )</p>
|
3087 |
+
<p class="comment">output = array( "value" => completedDate<span class="ref">1</span>
|
3088 |
+
, "params" => xparam<span class="ref">2</span> )</p>
|
3089 |
+
<p class="label">Example</p>
|
3090 |
+
<p class="example">$completed = $vtodo->getProperty( "completed" );</p>
|
3091 |
+
<h5>Set COMPLETED</h5>
|
3092 |
+
Insert property value. Input date is always a <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME or, if "offset" parameter is used, converted to a <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME.
|
3093 |
+
<p class="label">Format</p>
|
3094 |
+
<p class="format">setProperty( "completed", completedDate [, xparam ] )</p>
|
3095 |
+
<p class="comment">completedDate<span class="ref">1</span> = array( "year" => int year
|
3096 |
+
, "month" => int month
|
3097 |
+
, "day" => int day
|
3098 |
+
[, "hour" => int hour
|
3099 |
+
, "min" => int min
|
3100 |
+
, "sec" => int sec
|
3101 |
+
, "tz" => offset ]] )
|
3102 |
+
completedDate = int year
|
3103 |
+
, int month
|
3104 |
+
, int day
|
3105 |
+
[, int hour
|
3106 |
+
, int min
|
3107 |
+
, int sec ]
|
3108 |
+
completedDate = array( int year
|
3109 |
+
, int month
|
3110 |
+
, int day
|
3111 |
+
[, int hour
|
3112 |
+
, int min
|
3113 |
+
, int sec
|
3114 |
+
[, offset ]] )
|
3115 |
+
completedDate = array ( "timestamp" => int timestamp [, "tz" => offset])
|
3116 |
+
completedDate = string datestring // <span class="ref">string date,
|
3117 |
+
acceptable by strtotime-command,
|
3118 |
+
ex. "14 august 2006 16.00.00"
|
3119 |
+
(notice <a class="ref" href="#date_restriction">date restriction</a>)</span>
|
3120 |
+
offset = (+/-)HHmm[ss], local date + UTC offset => <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME
|
3121 |
+
xparam<span class="ref">2</span> = array( *[ xparamkey => xparamvalue ] )</p>
|
3122 |
+
<p class="label">Example 1</p>
|
3123 |
+
<p class="example">$config = array( "unique_id" => "domain.com");
|
3124 |
+
$vcalendar = new vcalendar( $config );
|
3125 |
+
$vtodo = & $vcalendar->newComponent( 'vtodo' );
|
3126 |
+
.. .
|
3127 |
+
$vtodo->setProperty( "completed", 2006, 8, 10, 10, 0, 0 );
|
3128 |
+
// <span class="ref">10 august 2006 10.00 UTC</span></p>
|
3129 |
+
<p class="label">Example 2</p>
|
3130 |
+
<p class="example">$date = array("year" => 2006, "month" => 10, "day" => 10,
|
3131 |
+
"hour" => 10, "min" => 0, "sec" => 0, "tz" => "+0200");
|
3132 |
+
// <span class="ref">local date + UTC offset => <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME</span>
|
3133 |
+
$vtodo->setProperty( "completed", $date );</p>
|
3134 |
+
<br />
|
3135 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
3136 |
+
|
3137 |
+
|
3138 |
+
<a name="CONTACT"></a><h3>3.2.12 CONTACT</h3>
|
3139 |
+
The property is used to represent textual contact information or alternately a reference to textual contact information associated with the calendar component. The property is OPTIONAL and MUST NOT occur more than once in a VFREEBUSY or MAY occur more than once in <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a> and <a href="#VJOURNAL">VJOURNAL</a> components.<br /><br />
|
3140 |
+
The value type for CONTACT is TEXT.
|
3141 |
+
<h5>Delete CONTACT</h5>
|
3142 |
+
Remove CONTACT from component.
|
3143 |
+
<p class="label">Format</p>
|
3144 |
+
<p class="format">deleteProperty( "CONTACT" )</p>
|
3145 |
+
<p class="label">Example 1</p>
|
3146 |
+
<p class="example">$vevent->deleteProperty( "CONTACT" );</p>
|
3147 |
+
<p class="label">Example 2</p>
|
3148 |
+
Delete CONTACT property no 2.
|
3149 |
+
<p class="example">$vevent->deleteProperty( "CONTACT", 2 );</p>
|
3150 |
+
<p class="label">Example 3</p>
|
3151 |
+
Deleting all CONTACT properties.
|
3152 |
+
<p class="example">while( $vevent->deleteProperty( "CONTACT" ))
|
3153 |
+
continue;</p>
|
3154 |
+
<h5>Get CONTACT</h5>
|
3155 |
+
Fetch property value.
|
3156 |
+
<p class="label">Format 1</p>
|
3157 |
+
<p class="format">getProperty( "CONTACT" )</p>
|
3158 |
+
<p class="comment">output = contactValue<span class="ref">1</span></p>
|
3159 |
+
<p class="label">Format 2</p>
|
3160 |
+
<p class="format">getProperty( "CONTACT", propOrderNo/FALSE , TRUE )</p>
|
3161 |
+
<p class="comment">output = array( "value" => contactValue<span class="ref">1</span>
|
3162 |
+
, "params" => params<span class="ref">2</span> )</p>
|
3163 |
+
<p class="label">Format 3</p>
|
3164 |
+
<p class="format">getProperty( "CONTACT", propOrderNo )</p>
|
3165 |
+
<p class="comment">Get propOrderNo CONTACT</p>
|
3166 |
+
<p class="label">Example</p>
|
3167 |
+
<p class="example">$contact = $vevent->getProperty( "contact" );</p>
|
3168 |
+
<h5>Set CONTACT</h5>
|
3169 |
+
Insert property value.
|
3170 |
+
<br />
|
3171 |
+
Parameters, if any, will be ordered as prescribed in rcf2445.
|
3172 |
+
<p class="label">Format</p>
|
3173 |
+
<p class="format">setproperty( "contact", contactValue [, params [, propOrderNo ]] )</p>
|
3174 |
+
<p class="comment">contactValue<span class="ref">1</span> = Value type TEXT
|
3175 |
+
params<span class="ref">2</span> = array ( ["ALTREP" => "<an alternate text representation, URI>"]
|
3176 |
+
[, "LANGUAGE" => "<lang>"]
|
3177 |
+
[, xparam] )
|
3178 |
+
xparam = *[ xparamkey => xparamvalue ]
|
3179 |
+
propOrderNo = int ordernumber, 1=1st, 2=2nd etc</p>
|
3180 |
+
<p class="label">Example</p>
|
3181 |
+
<p class="example">$c->setProperty( "contact", "tel 012-34 56 789" )</p>
|
3182 |
+
<br />
|
3183 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
3184 |
+
|
3185 |
+
|
3186 |
+
<a name="CREATED"></a><h3>3.2.13 CREATED</h3>
|
3187 |
+
This property specifies the date and time that the calendar information was created by the calendar user agent in the calendar store. Note: This is analogous to the creation date and time for a file in the file system. The property is OPTIONAL and MUST NOT occur more than once in <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a> and <a href="#VJOURNAL">VJOURNAL</a> components.<br /><br />
|
3188 |
+
The value type for CREATED is <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME.
|
3189 |
+
<h5>Delete CREATED</h5>
|
3190 |
+
Remove CREATED from component.
|
3191 |
+
<p class="label">Format</p>
|
3192 |
+
<p class="format">deleteProperty( "CREATED" )</p>
|
3193 |
+
<p class="label">Example</p>
|
3194 |
+
<p class="example">$vevent->deleteProperty( "CREATED" );</p>
|
3195 |
+
<h5>Get CREATED</h5>
|
3196 |
+
Fetch property value.
|
3197 |
+
<p class="label">Format 1</p>
|
3198 |
+
<p class="format">getProperty( "CREATED" )</p>
|
3199 |
+
<p class="comment">output = createdDate<span class="ref">1</span></p>
|
3200 |
+
<p class="label">Format 2</p>
|
3201 |
+
<p class="format">getProperty( "CREATED", FALSE , TRUE )</p>
|
3202 |
+
<p class="comment">output = array( "value" => createdDate<span class="ref">1</span>
|
3203 |
+
, "params" => xparam<span class="ref">2</span> )</p>
|
3204 |
+
<p class="label">Example</p>
|
3205 |
+
<p class="example">$created = $vevent->getProperty( "CREATED" );</p>
|
3206 |
+
<h5>Set CREATED</h5>
|
3207 |
+
Insert property value. Input date is always a <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME or, if "offset" parameter is used, converted to a <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME.
|
3208 |
+
<p class="label">Format</p>
|
3209 |
+
<p class="format">setProperty( "created", [ createdDate [, xparam ]] )</p>
|
3210 |
+
<p class="comment">createdDate<span class="ref">1</span> = array( "year" => int year
|
3211 |
+
, "month" => int month
|
3212 |
+
, "day" => int day
|
3213 |
+
[, "hour" => int hour
|
3214 |
+
, "min" => int min
|
3215 |
+
, "sec" => int sec
|
3216 |
+
, "tz" => offset ]] )
|
3217 |
+
createdDate = int year
|
3218 |
+
, int month
|
3219 |
+
, int day
|
3220 |
+
[, int hour
|
3221 |
+
, int min
|
3222 |
+
, int sec ]
|
3223 |
+
createdDate = array( int year
|
3224 |
+
, int month
|
3225 |
+
, int day
|
3226 |
+
[, int hour
|
3227 |
+
, int min
|
3228 |
+
, int sec
|
3229 |
+
[, offset ]] )
|
3230 |
+
createdDate = array ( "timestamp" => int timestamp [, "tz" => offset ])
|
3231 |
+
createdDate = string datestring // <span class="ref">string date,
|
3232 |
+
acceptable by strtotime-command,
|
3233 |
+
ex. "14 august 2006 16.00.00"
|
3234 |
+
(notice <a class="ref" href="#date_restriction">date restriction</a>)</span>
|
3235 |
+
offset = (+/-)HHmm[ss], local date + UTC offset => <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME
|
3236 |
+
xparam<span class="ref">2</span> = array( *[ xparamkey => xparamvalue ] )</p>
|
3237 |
+
<p class="label">Example 1</p>
|
3238 |
+
<p class="example">$config = array( "unique_id" => "domain.com" );
|
3239 |
+
$vcalendar = new vcalendar( $config );
|
3240 |
+
$vtodo = & $vcalendar->newComponent( 'vtodo' );
|
3241 |
+
.. .
|
3242 |
+
$vtodo->setProperty( "created", 2006, 8, 11, 14, 30, 35 );
|
3243 |
+
// <span class="ref">11 august 2006 14.30.35 UTC</span> </p>
|
3244 |
+
<p class="label">Example 2</p>
|
3245 |
+
<p class="example">$date = array("year" => 2006, "month" => 10, "day" => 10,
|
3246 |
+
"hour" => 10, "min" => 0, "sec" => 0, "tz" => "+0200");
|
3247 |
+
// <span class="ref">local date + UTC offset => <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME</span>
|
3248 |
+
$vtodo->setProperty( "created", $date );
|
3249 |
+
.. .</p>
|
3250 |
+
<p class="label">Example 3</p>
|
3251 |
+
<p class="example">$vevent->setProperty( "created" );
|
3252 |
+
// <span class="ref">current UTC date-time is set if called without parameters</span></p>
|
3253 |
+
<br />
|
3254 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
3255 |
+
|
3256 |
+
|
3257 |
+
<a name="DESCRIPTION"></a><h3>3.2.14 DESCRIPTION</h3>
|
3258 |
+
This property provides a more complete textual description of the calendar component, than that provided by the <a href="#SUMMARY">SUMMARY</a> property (, analogous to a mail BODY). The property is OPTIONAL, MUST NOT occur more than once within <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a> or <a href="#VALARM">VALARM</a> (PROCEDURE) but can be specified multiple times within a <a href="#VJOURNAL">VJOURNAL</a> calendar component. The property is REQUIRED in <a href="#VALARM">VALARM</a> (DISPLAY, EMAIL) component.<br /><br />
|
3259 |
+
The value type for DESCRIPTION is TEXT.
|
3260 |
+
<h5>Delete DESCRIPTION</h5>
|
3261 |
+
Remove DESCRIPTION from component.
|
3262 |
+
<p class="label">Format</p>
|
3263 |
+
<p class="format">deleteProperty( "DESCRIPTION" )</p>
|
3264 |
+
<p class="label">Example 1</p>
|
3265 |
+
<p class="example">$vevent->deleteProperty( "DESCRIPTION" );</p>
|
3266 |
+
<p class="label">Example 2</p>
|
3267 |
+
Delete DESCRIPTION property no 2.
|
3268 |
+
<p class="example">$vjournal->deleteProperty( "DESCRIPTION", 2 );</p>
|
3269 |
+
<p class="label">Example 3</p>
|
3270 |
+
Deleting all DESCRIPTION properties.
|
3271 |
+
<p class="example">while( $vjournal->deleteProperty( "DESCRIPTION" ))
|
3272 |
+
continue;</p>
|
3273 |
+
<h5>Get DESCRIPTION</h5>
|
3274 |
+
Fetch property value.
|
3275 |
+
<p class="label">Format 1</p>
|
3276 |
+
<p class="format">getProperty( "DESCRIPTION" )</p>
|
3277 |
+
<p class="comment">output = descriptionValue<span class="ref">1</span></p>
|
3278 |
+
<p class="label">Format 2</p>
|
3279 |
+
<p class="format">getProperty( "DESCRIPTION", FALSE , TRUE )</p>
|
3280 |
+
<p class="comment">output = array( "value" => descriptionValue<span class="ref">1</span>
|
3281 |
+
, "params" => params<span class="ref">2</span> )</p>
|
3282 |
+
<p class="label">Example</p>
|
3283 |
+
<p class="example">$description = $vevent->getProperty( "description" );</p>
|
3284 |
+
<h5>Set DESCRIPTION</h5>
|
3285 |
+
Insert property value.
|
3286 |
+
<br />
|
3287 |
+
Parameters, if any, will be ordered as prescribed in rcf2445.
|
3288 |
+
<p class="label">Format</p>
|
3289 |
+
<p class="format">setProperty( "description", descriptionValue [, params [, propOrderNo ]] )</p>
|
3290 |
+
<p class="comment">descriptionValue<span class="ref">1</span> = Value type TEXT
|
3291 |
+
params<span class="ref">2</span> = array( ["ALTREP" => "<an alternate text representation, URI>"]
|
3292 |
+
[, "LANGUAGE" => "<lang>"]
|
3293 |
+
[, xparam] )
|
3294 |
+
xparam = *[ xparamkey => xparamvalue ]
|
3295 |
+
propOrderNo = int ordernumber, 1=1st, 2=2nd etc</p>
|
3296 |
+
<p class="label">Example</p>
|
3297 |
+
<p class="example">$vevent->setProperty( "description", "This is a description" );</p>
|
3298 |
+
<br />
|
3299 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
3300 |
+
|
3301 |
+
|
3302 |
+
<a name="DTEND"></a><h3>3.2.15 DTEND</h3>
|
3303 |
+
This property specifies the date and time that a calendar component ends.
|
3304 |
+
The property is OPTIONAL and MUST NOT occur more than once in VFREEBUSY and VEVENT. In VEVENT, it only occurs
|
3305 |
+
if DURATION NOT occurs.
|
3306 |
+
<br /><br />
|
3307 |
+
The default value type for DTEND is DATE-TIME, can be set to a DATE value type.
|
3308 |
+
<br /><br />
|
3309 |
+
Notice that an end date without a time is in effect midnight of the day before the date, so for timeless dates, use the date following the event date for it to be correct. For an "all-day event" and using timeless dates, the DTEND is equal DTSTART plus one day, example all-day event (2007-12-01)<br />DTSTART;VALUE=DATE:20071201<br /> DTEND;VALUE=DATE:20071202.
|
3310 |
+
<h5>Delete DTEND</h5>
|
3311 |
+
Remove DTEND from component.
|
3312 |
+
<p class="label">Format</p>
|
3313 |
+
<p class="format">deleteProperty( "DTEND" )</p>
|
3314 |
+
<p class="label">Example</p>
|
3315 |
+
<p class="example">$vevent->deleteProperty( "DTEND" );</p>
|
3316 |
+
<h5>Get DTEND</h5>
|
3317 |
+
Fetch property value.
|
3318 |
+
<p class="label">Format 1</p>
|
3319 |
+
<p class="format">getProperty( "DTEND" )</p>
|
3320 |
+
<p class="comment">output = dtendDate<span class="ref">1</span></p>
|
3321 |
+
<p class="label">Format 2</p>
|
3322 |
+
<p class="format">getProperty( "DTEND", FALSE , TRUE )</span>
|
3323 |
+
<p class="comment">output = array( "value" => dtendDate<span class="ref">1</span>
|
3324 |
+
, "params" => params<span class="ref">2</span> )</p>
|
3325 |
+
<p class="label">Example</p>
|
3326 |
+
<p class="example">$dtend = $vevent->getProperty( "dtend" );</p>
|
3327 |
+
<h5>Set DTEND</h5>
|
3328 |
+
Insert property value. If DATE value type is expected, "VALUE" = "DATE" <b>must</b> be set
|
3329 |
+
(in params<span class="ref">2</span>) otherwise DATE-TIME (default) value type is set.
|
3330 |
+
<br />
|
3331 |
+
<br />
|
3332 |
+
If no timezone parameter (tz or tzidparam below) is set (then local time is assumed) and config <a href="#dTZID">TZID</a> is set, date-time values will be set WITH timezone from config.
|
3333 |
+
<br />
|
3334 |
+
<br />
|
3335 |
+
Parameters, if any, will be ordered as prescribed in rcf2445.
|
3336 |
+
<p class="label">Format</p>
|
3337 |
+
<p class="format">setProperty( "dtend", dtendDate [, params<span class="ref">2</span> ] )</span>
|
3338 |
+
<p class="comment">dtendDate<span class="ref">1</span> = array ( "year" => int year
|
3339 |
+
, "month" => int month
|
3340 |
+
, "day" => int day
|
3341 |
+
[, "hour" => int hour
|
3342 |
+
, "min" => int min
|
3343 |
+
, "sec" => int sec
|
3344 |
+
[, "tz" => mixed tz ]] )
|
3345 |
+
dtendDate = int year
|
3346 |
+
, int month
|
3347 |
+
, int day
|
3348 |
+
[, int hour
|
3349 |
+
, int min
|
3350 |
+
, int sec
|
3351 |
+
[, mixed tz ]]
|
3352 |
+
dtendDate = array( int year
|
3353 |
+
, int month
|
3354 |
+
, int day
|
3355 |
+
[, int hour
|
3356 |
+
, int min
|
3357 |
+
, int sec
|
3358 |
+
[, mixed tz ]] )
|
3359 |
+
dtendDate = array( "timestamp" => int timestamp [,"tz" => mixed tz])
|
3360 |
+
dtendDate = string datestring // <span class="ref">string date,
|
3361 |
+
acceptable by strtotime-command,
|
3362 |
+
ex. "14 august 2006 16.00.00"
|
3363 |
+
(notice <a class="ref" href="#date_restriction">date restriction</a>)</span>
|
3364 |
+
dtendDate : Within the "VFREEBUSY" calendar component,
|
3365 |
+
the time MUST be specified in the <a href="#DATE_WITH_UTC_TIME">UTC</a> time format.
|
3366 |
+
tz = <timezone identifier> / UTC offset
|
3367 |
+
(timezone will be used as tzidparam (below), if tzidparam not set)
|
3368 |
+
offset = (+/-)HHmm[ss], local date + UTC offset => <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME
|
3369 |
+
params<span class="ref">2</span> = array([ tzidparam/datetimeparam/dateparam ] *[,xparams])
|
3370 |
+
tzidparam = "TZID" => <timezone identifier>
|
3371 |
+
// <span class="ref">output as local date-time with timezone identifier</span>
|
3372 |
+
datetimeparam = "VALUE" => "DATE-TIME" // <span class="ref">default, output as date-time</span>
|
3373 |
+
dateparam = "VALUE" => "DATE" // <span class="ref">output as DATE, ex. all-day event</span>
|
3374 |
+
xparams = xparamkey => xparamvalue</p>
|
3375 |
+
<p class="label">Example 1</p>
|
3376 |
+
<p class="example">$vevent->setProperty( "dtend"
|
3377 |
+
, 2006, 8, 11, 16, 30, 0 );
|
3378 |
+
<span class="ref">// 11 august 2006 16.30.00 local date</span></p>
|
3379 |
+
<p class="label">Example 2</p>
|
3380 |
+
<p class="example">$vfreebusy->setProperty( "dtend"
|
3381 |
+
, 2006, 8, 11, 16, 30, 0, "-040000" );
|
3382 |
+
<span class="ref">// 11 august 2006 16.30.00 -040000 :
|
3383 |
+
local date + UTC offset => <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME</span></p>
|
3384 |
+
<p class="label">Example 3</p>
|
3385 |
+
<p class="example">$vevent->setProperty( "dtend"
|
3386 |
+
, array( 'year' =>, 2006, 'month' => 8, 'day'=> 11 )
|
3387 |
+
, array( 'VALUE' => 'DATE' ));
|
3388 |
+
<span class="ref">// end of one or more all-day events</span></p>
|
3389 |
+
<br />
|
3390 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
3391 |
+
|
3392 |
+
|
3393 |
+
<a name="DTSTAMP"></a><h3>3.2.16 DTSTAMP</h3>
|
3394 |
+
The property indicates the date/time that the instance of the iCalendar object was created and is OPTIONAL and MUST NOT occur more than once in <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a>, <a href="#VJOURNAL">VJOURNAL</a> and <a href="#VFREEBUSY">VFREEBUSY</a> components. However, DTSTAMP is <b>AUTO</b> GENERATED in iCalcreator.
|
3395 |
+
<br /><br />
|
3396 |
+
DTSTAMP may be required when importing iCal files into some calendaring software<br />(MS etc.),
|
3397 |
+
as well as (calendar) <a href="#X-PROPERTY">x-properties</a> "X-WR-CALNAME", "X-WR-CALDESC" and<br />"X-WR-TIMEZONE",
|
3398 |
+
<a href="#METHOD">METHOD</a> property (value PUBLISH etc.) and (also auto created) <a href="#UID">UID</a> property.
|
3399 |
+
<br /><br />
|
3400 |
+
The value type for DTSTAMP is <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME.
|
3401 |
+
<h5>Delete DTSTAMP</h5>
|
3402 |
+
If DTSTAMP if removed from a component, DTSTAMP will automatically be recreated when calendar output functions like <a href="#createCalendar">createCalendar</a>, <a href="#returnCalendar">returnCalendar</a> or <a href="#saveCalendar">saveCalendar</a> is executed.
|
3403 |
+
<p class="label">Format</p>
|
3404 |
+
<p class="format">deleteProperty( "DTSTAMP" )</p>
|
3405 |
+
<p class="label">Example</p>
|
3406 |
+
<p class="example">$vevent->deleteProperty( "DTSTAMP" );</p>
|
3407 |
+
<h5>Get DTSTAMP</h5>
|
3408 |
+
Fetch property value.
|
3409 |
+
<p class="label">Format 1</p>
|
3410 |
+
<p class="format">getProperty( "DTSTAMP" )</p>
|
3411 |
+
<p class="comment">output = dtstampDate<span class="ref">1</span></p>
|
3412 |
+
<p class="label">Format 2</p>
|
3413 |
+
<p class="format">getProperty( "DTSTAMP", FALSE , TRUE )</p>
|
3414 |
+
<p class="comment">output = array( "value" => dtstampDate<span class="ref">1</span>
|
3415 |
+
, "params" => xparam<span class="ref">2</span> )</p>
|
3416 |
+
<p class="label">Example</p>
|
3417 |
+
<p class="example">$dtstamp = $vevent->getProperty( "dtstamp" );</p>
|
3418 |
+
<h5>Set DTSTAMP</h5>
|
3419 |
+
Insert property value. Input date is always a <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME or, if "offset" parameter is used, converted to a <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME.
|
3420 |
+
<p class="label">Format</p>
|
3421 |
+
<p class="format">setProperty( "dtstamp", dtstampDate [, xparam ] )</p>
|
3422 |
+
<p class="comment">dtstampDate<span class="ref">1</span> = array( "year" => int year
|
3423 |
+
, "month" => int month
|
3424 |
+
, "day" => int day
|
3425 |
+
[, "hour" => int hour
|
3426 |
+
, "min" => int min
|
3427 |
+
, "sec" => int sec
|
3428 |
+
, "tz" => offset ]] )
|
3429 |
+
dtstampDate = int year
|
3430 |
+
, int month
|
3431 |
+
, int day
|
3432 |
+
[, int hour
|
3433 |
+
, int min
|
3434 |
+
, int sec ]
|
3435 |
+
dtstampDate = array( int year
|
3436 |
+
, int month
|
3437 |
+
, int day
|
3438 |
+
[, int hour
|
3439 |
+
, int min
|
3440 |
+
, int sec
|
3441 |
+
[, offset ]] )
|
3442 |
+
dtstampDate = array ( "timestamp" => int timestamp [, "tz" => offset ])
|
3443 |
+
dtstampDate = string datestring // <span class="ref">string date,
|
3444 |
+
acceptable by strtotime-command,
|
3445 |
+
ex. "14 august 2006 16.00.00"
|
3446 |
+
(notice <a class="ref" href="#date_restriction">date restriction</a>)</span>
|
3447 |
+
offset = (+/-)HHmm[ss], local date + UTC offset => <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME
|
3448 |
+
xparam<span class="ref">2</span> = array( *[ xparamkey => xparamvalue ] )</p>
|
3449 |
+
<p class="label">Example 1</p>
|
3450 |
+
<p class="example">$config = array( "unique_id" => "domain.com" );
|
3451 |
+
$vcalendar = new vcalendar( $config );
|
3452 |
+
$vtodo = & $vcalendar->newComponent( 'vtodo' );
|
3453 |
+
.. .
|
3454 |
+
$vtodo->setProperty( "dstamp"
|
3455 |
+
, 2006, 8, 11, 7, 30, 1 );
|
3456 |
+
<span class="ref">// 11 august 2006 07.30.01 UTC</span></p>
|
3457 |
+
<p class="label">Example 2</p>
|
3458 |
+
<p class="example">$date = array("year" => 2006, "month" => 10, "day" => 10,
|
3459 |
+
"hour" => 10, "min" => 0, "sec" => 0, "tz" => "+0200");
|
3460 |
+
// <span class="ref">local date + UTC offset => <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME</span>
|
3461 |
+
$vtodo->setProperty( "dtstamp", $date );
|
3462 |
+
.. .</p>
|
3463 |
+
<br />
|
3464 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
3465 |
+
|
3466 |
+
<a name="DTSTART"></a><h3>3.2.17 DTSTART</h3>
|
3467 |
+
This property specifies when the calendar component begins.<br />
|
3468 |
+
The property is OPTIONAL and MUST NOT occur more than once in <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a>, <a href="#VJOURNAL">VJOURNAL</a> and <a href="#VFREEBUSY">VFREEBUSY</a> components.<br />
|
3469 |
+
The property is REQUIRED, but MUST NOT occur more than once in <a href="#VTIMEZONE">STANDARD</a> and <a href="#VTIMEZONE">DAYLIGHT</a> components.<br /><br />
|
3470 |
+
The default value type for DTSTART is DATE-TIME, can be set to a DATE value type.<br /><br />
|
3471 |
+
For an "all-day event" and using timeless dates, example (2007-12-01)<br />
|
3472 |
+
DTSTART;VALUE=DATE:20071201<br />
|
3473 |
+
DTEND;VALUE=DATE:20071202. // <span class="ref">opt., in effect midnight of the day <u>before</u> the date!!</span>
|
3474 |
+
<h5>Delete DTSTART</h5>
|
3475 |
+
Remove DTSTART from component.
|
3476 |
+
<p class="label">Format</p>
|
3477 |
+
<p class="format">deleteProperty( "DTSTART" )</p>
|
3478 |
+
<p class="label">Example</p>
|
3479 |
+
<p class="example">$vevent->deleteProperty( "DTSTART" );</p>
|
3480 |
+
<h5>Get DTSTART</h5>
|
3481 |
+
Fetch property value.
|
3482 |
+
<p class="label">Format 1</p>
|
3483 |
+
<p class="format">getProperty( "DTSTART" )</p>
|
3484 |
+
<p class="comment">output = dtstartDate<span class="ref">1</span></p>
|
3485 |
+
<p class="label">Format 2</p>
|
3486 |
+
<p class="format">getProperty( "DTSTART", FALSE , TRUE )</p>
|
3487 |
+
<p class="comment">output = array( "value" => dtstartDate<span class="ref">1</span>
|
3488 |
+
, "params" => params<span class="ref">2</span> )</p>
|
3489 |
+
<p class="label">Example</p>
|
3490 |
+
<p class="example">$dtstart = $vevent->getProperty( "dtstart" );</p>
|
3491 |
+
<h5>Set DTSTART</h5>
|
3492 |
+
Insert property value. If DATE value type is expected, "VALUE" = "DATE" <b>must</b> be set (in params<span class="ref">2</span>) otherwise DATE-TIME (default) value type is set.
|
3493 |
+
<br />
|
3494 |
+
<br />
|
3495 |
+
If no timezone parameter (tz or tzidparam below) is set (then local time is assumed) and config <a href="#dTZID">TZID</a> is set, date-time values will be set WITH timezone from config.
|
3496 |
+
<br />
|
3497 |
+
<br />
|
3498 |
+
Parameters, if any, will be ordered as prescribed in rcf2445.
|
3499 |
+
<p class="label">Format</p>
|
3500 |
+
<p class="format">setProperty( "dtstart", dtstartDate [, params ] )</p>
|
3501 |
+
<p class="comment">dtstartDate<span class="ref">1</span> = array( "year" => int year
|
3502 |
+
, "month" => int month
|
3503 |
+
, "day" => int day
|
3504 |
+
[, "hour" => int hour
|
3505 |
+
, "min" => int min
|
3506 |
+
, "sec" => int sec
|
3507 |
+
[, "tz" => mixed tz ]] )
|
3508 |
+
dtstartDate = int year
|
3509 |
+
, int month
|
3510 |
+
, int day
|
3511 |
+
[, int hour
|
3512 |
+
, int min
|
3513 |
+
, int sec
|
3514 |
+
[, mixed tz ]]
|
3515 |
+
dtstartDate = array( int year
|
3516 |
+
, int month
|
3517 |
+
, int day
|
3518 |
+
[, int hour
|
3519 |
+
, int min
|
3520 |
+
, int sec
|
3521 |
+
[, mixed tz ]] )
|
3522 |
+
dtstartDate = array("timestamp" => int timestamp [, "tz" => mixed tz])
|
3523 |
+
dtstartDate = string datestring // <span class="ref">string date,
|
3524 |
+
acceptable by strtotime-command,
|
3525 |
+
ex. "14 august 2006 16.00.00"
|
3526 |
+
(notice <a class="ref" href="#date_restriction">date restriction</a>)</span>
|
3527 |
+
dtstartDate : Within the "VFREEBUSY" calendar component,
|
3528 |
+
the dtstartDate MUST be specified in the <a href="#DATE_WITH_UTC_TIME">UTC</a> time format.
|
3529 |
+
tz = <timezone identifier> / offset
|
3530 |
+
(timezone will be used as tzidparam (below), if tzidparam not set)
|
3531 |
+
offset = (+/-)HHmm[ss], local date + UTC offset => <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME
|
3532 |
+
params<span class="ref">2</span> = array([ tzidparam/datetimeparam/dateparam ] *[, xparams])
|
3533 |
+
tzidparam = "TZID" => <timezone identifier>
|
3534 |
+
// <span class="ref">output as local date-time with timezone identifier</span>
|
3535 |
+
datetimeparam = "VALUE" => "DATE-TIME" // <span class="ref">default, output as date-time</span>
|
3536 |
+
dateparam = "VALUE" => "DATE" // <span class="ref">output as DATE, ex. all-day event</span>
|
3537 |
+
xparams = xparamkey => xparamvalue</p>
|
3538 |
+
<p class="label">Example 1</p>
|
3539 |
+
<p class="example">$vevent->setProperty( "dstart"
|
3540 |
+
, 2006, 8, 11, 7, 30, 1 );
|
3541 |
+
<span class="comment">// 11 august 2006 07.30.01 local date</span></p>
|
3542 |
+
<p class="label">Example 2</p>
|
3543 |
+
<p class="example">$vevent->setProperty( "dstart"
|
3544 |
+
, 2006, 8, 11, 16, 30, 0, "-040000" );
|
3545 |
+
<span class="comment">// 11 august 2006 16.30.00 -040000,
|
3546 |
+
// local date + UTC offset => <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME</span></p>
|
3547 |
+
<p class="label">Example 3</p>
|
3548 |
+
<p class="example">$vevent->setProperty( "dtstart"
|
3549 |
+
, array( 'year' =>, 2006, 'month' => 8, 'day'=> 11 )
|
3550 |
+
, array( 'VALUE' => 'DATE' ));
|
3551 |
+
<span class="comment">// start of an all-day event, or a period of (entire) days</span></p>
|
3552 |
+
<br />
|
3553 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
3554 |
+
|
3555 |
+
|
3556 |
+
<a name="DUE"></a><h3>3.2.18 DUE</h3>
|
3557 |
+
This property defines the date and time when a <a href="#VTODO">VTODO</a> is expected to be completed
|
3558 |
+
and is OPTIONAL and MUST NOT occur more than once and only if DURATION NOT occurs.<br /><br />
|
3559 |
+
The default value type for DUE is DATE-TIME, can be set to a DATE value type.
|
3560 |
+
<h5>Delete DUE</h5>
|
3561 |
+
Remove DUE from component.
|
3562 |
+
<p class="label">Format</p>
|
3563 |
+
<p class="format">deleteProperty( "DUE" )</p>
|
3564 |
+
<p class="label">Example</p>
|
3565 |
+
<p class="example">$vtodo->deleteProperty( "DUE" );</p>
|
3566 |
+
<h5>Get DUE</h5>
|
3567 |
+
Fetch property value.
|
3568 |
+
<p class="label">Format 1</p>
|
3569 |
+
<p class="format">getProperty( "DUE" )</p>
|
3570 |
+
<p class="comment">output = dueDate<span class="ref">1</span></p>
|
3571 |
+
<p class="label">Format 2</p>
|
3572 |
+
<p class="format">getProperty( "DUE", FALSE , TRUE )</p>
|
3573 |
+
<p class="comment">output = array( "value" => dueDate<span class="ref">1</span>
|
3574 |
+
, "params" => params<span class="ref">2</span> )</p>
|
3575 |
+
<p class="label">Example</p>
|
3576 |
+
<p class="example">$due = $vtodo->getProperty( "due" );</p>
|
3577 |
+
<h5>Set DUE</h5>
|
3578 |
+
Insert property value. If DATE value type is expected, "VALUE" = "DATE" <b>must</b> be set
|
3579 |
+
(in params<span class="ref">2</span>) otherwise DATE-TIME (default) value type is set.
|
3580 |
+
<br />
|
3581 |
+
<br />
|
3582 |
+
If no timezone parameter (tz or tzidparam below) is set (then local time is assumed) and config <a href="#dTZID">TZID</a> is set, date-time values will be set WITH timezone from config.
|
3583 |
+
<br />
|
3584 |
+
<br />
|
3585 |
+
Parameters, if any, will be ordered as prescribed in rcf2445.
|
3586 |
+
<p class="label">Format</p>
|
3587 |
+
<p class="format">setProperty( "due", dueDate [, params ] )</p>
|
3588 |
+
<p class="comment">dueDate<span class="ref">1</span> = array( "year" => int year
|
3589 |
+
, "month" => int month
|
3590 |
+
, "day" => int day
|
3591 |
+
[, "hour" => int hour
|
3592 |
+
, "min" => int min
|
3593 |
+
, "sec" => int sec
|
3594 |
+
[, "tz" => mixed tz ]] )
|
3595 |
+
dueDate = int year
|
3596 |
+
, int month
|
3597 |
+
, int day
|
3598 |
+
[, int hour
|
3599 |
+
, int min
|
3600 |
+
, int sec
|
3601 |
+
[, mixed tz ]]
|
3602 |
+
dueDate = array( int year
|
3603 |
+
, int month
|
3604 |
+
, int day
|
3605 |
+
[, int hour
|
3606 |
+
, int min
|
3607 |
+
, int sec
|
3608 |
+
[, mixed tz ]] )
|
3609 |
+
dueDate = array( "timestamp" => int timestamp [, "tz" => mixed tz])
|
3610 |
+
dueDate = string datestring // <span class="ref">string date,
|
3611 |
+
acceptable by strtotime-command,
|
3612 |
+
ex. "14 august 2006 16.00.00"
|
3613 |
+
(notice <a class="ref" href="#date_restriction">date restriction</a>)</span>
|
3614 |
+
tz = <timezone identifier> / offset
|
3615 |
+
(timezone will be used as tzidparam (below), if tzidparam not set)
|
3616 |
+
offset = (+/-)HHmm[ss], local date + UTC offset => <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME
|
3617 |
+
params<span class="ref">2</span> = array([ tzidparam/datetimeparam/dateparam ] *[, xparams])
|
3618 |
+
tzidparam = "TZID" => <timezone identifier>
|
3619 |
+
// <span class="ref">output as local date-time with timezone identifier</span>
|
3620 |
+
datetimeparam = "VALUE" => "DATE-TIME" // <span class="ref">default, output as date-time</span>
|
3621 |
+
dateparam = "VALUE" => "DATE" // <span class="ref">output as DATE, "during the day"</span>
|
3622 |
+
xparams = xparamkey => xparamvalue<p/>
|
3623 |
+
<p class="label">Example 1</p>
|
3624 |
+
<p class="example">$vtodo->setProperty( "due"
|
3625 |
+
, 2006, 8, 11, 18, 0, 0 );
|
3626 |
+
<span class="comment">// 11 august 2005 18.00.00 local date</span></p>
|
3627 |
+
<p class="label">Example 2</p>
|
3628 |
+
<p class="example">$vtodo->setProperty( "due"
|
3629 |
+
, 2006, 8, 11, 16, 30, 0, "-040000" );
|
3630 |
+
<span class="comment">// 11 august 2006 16.30.00 -040000
|
3631 |
+
// local date + UTC offset sets <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME</span></p>
|
3632 |
+
<p class="label">Example 3</p>
|
3633 |
+
<p class="example">$vtodo->setProperty( "due"
|
3634 |
+
, array( 'year' =>, 2006, 'month' => 8, 'day'=> 11 )
|
3635 |
+
, array( 'VALUE' => 'DATE' ));
|
3636 |
+
<span class="comment">// due "during the day"</span></p>
|
3637 |
+
<br />
|
3638 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
3639 |
+
|
3640 |
+
|
3641 |
+
<a name="DURATION"></a><h3>3.2.19 DURATION</h3>
|
3642 |
+
The property specifies a positive duration of time<br />
|
3643 |
+
In a VEVENT it is OPTIONAL and MUST NOT occur more than once and MUST NOT occur in pair with DTEND. If one occurs, so MUST NOT the other.<br />
|
3644 |
+
In a VTODO it is OPTIONAL and MUST NOT occur more than once and MUST NOT occur in pair with DUE. If one occurs, so MUST NOT the other.<br />
|
3645 |
+
In a VFREEBUSY it is OPTIONAL and MUST NOT occur more than once.<br />
|
3646 |
+
In a VALARM it is OPTIONAL and MUST NOT occur more than once and MUST occur in pair with TRIGGER. If one occurs, so MUST the other.
|
3647 |
+
<h5>Delete DURATION</h5>
|
3648 |
+
Remove DURATION from component.
|
3649 |
+
<p class="label">Format</p>
|
3650 |
+
<p class="format">deleteProperty( "DURATION" )</p>
|
3651 |
+
<p class="label">Example</p>
|
3652 |
+
<p class="example">$valarm->deleteProperty( "DURATION" );</p>
|
3653 |
+
<h5>Get DURATION</h5>
|
3654 |
+
Fetch property value.
|
3655 |
+
<p class="label">Format 1</p>
|
3656 |
+
<p class="format">getProperty( "DURATION" )</p>
|
3657 |
+
<p class="comment">output = duration<span class="ref">1</span></p>
|
3658 |
+
<p class="label">Format 2</p>
|
3659 |
+
<p class="format">getProperty( "DURATION", FALSE , TRUE )</p>
|
3660 |
+
<p class="comment">output = array( "value" => duration<span class="ref">1</span>
|
3661 |
+
, "params" => xparam<span class="ref">2</span> )</p>
|
3662 |
+
<p class="label">Example</p>
|
3663 |
+
<p class="example">$duration = $vtodo->getProperty( "duration" );</p>
|
3664 |
+
<p class="label">option</p>
|
3665 |
+
If a 4th argument is used and set to TRUE, returned output is in a DATE-TIME
|
3666 |
+
output format (like <a href="#DTEND">DTEND</a> / <a href="#DUE">DUE</a>), based on
|
3667 |
+
<a href="#DTSTART">DTSTART</a> value with added DURATION value.
|
3668 |
+
<h5>Set DURATION</h5>
|
3669 |
+
Insert property value.
|
3670 |
+
<p class="label">Format</p>
|
3671 |
+
<p class="format">setProperty( "duration", duration [, xparam ] )</p>
|
3672 |
+
<p class="comment">
|
3673 |
+
duration<span class="ref">1</span> = array ( "week" => int week )
|
3674 |
+
duration<span class="ref">1</span> = array ( "day" => int day )
|
3675 |
+
[, "hour" => int hour
|
3676 |
+
, "min" => int min
|
3677 |
+
, "sec" => int sec ])
|
3678 |
+
duration = array ( "sec" => int sec )
|
3679 |
+
duration = array( int week/false
|
3680 |
+
[, int day/false
|
3681 |
+
[, int hour
|
3682 |
+
, int min
|
3683 |
+
, int sec ]] )
|
3684 |
+
duration = int week/false
|
3685 |
+
[, int day/false
|
3686 |
+
[, int hour
|
3687 |
+
, int min
|
3688 |
+
, int sec ]]
|
3689 |
+
duration = string dur-value = ["+"] "P" (dur-date/dur-time/dur-week)
|
3690 |
+
dur-date = dur-day [dur-time]
|
3691 |
+
dur-time = "T" (dur-hour / dur-minute / dur-second)
|
3692 |
+
dur-week = 1*DIGIT "W"
|
3693 |
+
dur-hour = 1*DIGIT "H" [dur-minute]
|
3694 |
+
dur-minute = 1*DIGIT "M" [dur-second]
|
3695 |
+
dur-second = 1*DIGIT "S"
|
3696 |
+
dur-day = 1*DIGIT "D"
|
3697 |
+
xparam<span class="ref">2</span> = array( *[ xparamkey => xparamvalue ] )</p>
|
3698 |
+
<p class="label">Example 1</p>
|
3699 |
+
<p class="example">$vtodo->setProperty "duration"
|
3700 |
+
, array( "day" => 1 )); </p>
|
3701 |
+
<p class="ref">// one day</p>
|
3702 |
+
<p class="label">Example 2</p>
|
3703 |
+
<p class="example">$vtodo->setProperty( "duration"
|
3704 |
+
, "PT4H" );
|
3705 |
+
<p class="ref"> // four hours</p>
|
3706 |
+
<br />
|
3707 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
3708 |
+
|
3709 |
+
|
3710 |
+
<a name="EXDATE"></a><h3>3.2.20 EXDATE</h3>
|
3711 |
+
This property defines the list of date/time exceptions for a recurring calendar component and is OPTIONAL and MAY occur more than once in <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a>, <a href="#VJOURNAL">VJOURNAL</a> components.<br /><br />
|
3712 |
+
The default value type for EXDATE is DATE-TIME, can be set to a DATE value type.
|
3713 |
+
<h5>Delete EXDATE</h5>
|
3714 |
+
Remove EXDATE from component.
|
3715 |
+
<p class="label">Format</p>
|
3716 |
+
<p class="format">deleteProperty( "EXDATE" )</p>
|
3717 |
+
<p class="label">Example 1</p>
|
3718 |
+
<p class="example">$vtodo->deleteProperty( "EXDATE" );</p>
|
3719 |
+
<p class="label">Example 2</p>
|
3720 |
+
Delete EXDATE property no 2.
|
3721 |
+
<p class="example">$vjournal->deleteProperty( "EXDATE", 2 );</p>
|
3722 |
+
<p class="label">Example 3</p>
|
3723 |
+
Deleting all EXDATE properties.
|
3724 |
+
<p class="example">while( $vjournal->deleteProperty( "EXDATE" ))
|
3725 |
+
continue;</p>
|
3726 |
+
<h5>Get EXDATE</h5>
|
3727 |
+
Fetch property value.
|
3728 |
+
<p class="label">Format 1</p>
|
3729 |
+
<p class="format">getProperty( "EXDATE" )<p>
|
3730 |
+
<p class="comment">output = exdates<span class="ref">1</span></p>
|
3731 |
+
<p class="label">Format 2</p>
|
3732 |
+
<p class="format">getProperty( "exdate", propOrderNo/FALSE, TRUE )</p>
|
3733 |
+
<p class="comment">output = array( "value" => exdates<span class="ref">1</span>
|
3734 |
+
, "params" => xparams<span class="ref">2</span> )</p>
|
3735 |
+
<p class="label">Format 3</p>
|
3736 |
+
<p class="format">getProperty( "EXDATE", propOrderNo )</p>
|
3737 |
+
<p class="comment">Get propOrderNo EXDATE</p>
|
3738 |
+
<p class="label">Example</p>
|
3739 |
+
<p class="example">$exdate = $vtodo->getProperty( "exdate" );</p>
|
3740 |
+
<h5>Set EXDATE</h5>
|
3741 |
+
Insert property value.<br />
|
3742 |
+
If "TZID" is set in params, ex. "TZID" = "CET",
|
3743 |
+
all timezone or offset in dates are ignored and DATE-TIME value type is set.<br />
|
3744 |
+
If DATE value type is set in params ("VALUE" = "DATE"), all timezone or offset in dates are ignored.<br />
|
3745 |
+
If no "VALUE" parameter in params, DATE-TIME (default) value type is set.<br />
|
3746 |
+
If empty params and offset in 1st date, all remaining dates are set to UTC.<br />
|
3747 |
+
If no "TZID" is set in params and timezone in 1st date, all remaining dates are within this timezone and param "TZID" is set.<br />
|
3748 |
+
If none of the above rules are applicable, DATE-TIME and local date is set default.
|
3749 |
+
<br />
|
3750 |
+
Parameters, if any, will be ordered as prescribed in rcf2445.
|
3751 |
+
<p class="label">Format</p>
|
3752 |
+
<p class="format">setProperty( "exdate", exdates [, xparams [, propOrderNo ]] )</p>
|
3753 |
+
<p class="comment">exdates<span class="ref">1</span> = array ( date *[, date ] )
|
3754 |
+
date = array( int year
|
3755 |
+
, int month
|
3756 |
+
, int day
|
3757 |
+
[, int hour
|
3758 |
+
, int min
|
3759 |
+
, int sec
|
3760 |
+
[, mixed tz ]] )
|
3761 |
+
date<span class="ref">1</span> = array( "year" => int year
|
3762 |
+
, "month" => int month
|
3763 |
+
, "day" => int day
|
3764 |
+
[, "hour" => int hour
|
3765 |
+
, "min" => int min
|
3766 |
+
, "sec" => int sec
|
3767 |
+
[, "tz" => mixed tz ]] )
|
3768 |
+
date = array( "timestamp" => int timestamp [, "tz" => mixed tz])
|
3769 |
+
date = string datestring // <span class="ref">string date,
|
3770 |
+
acceptable by strtotime-command,
|
3771 |
+
ex. "14 august 2006 16.00.00"
|
3772 |
+
(notice <a class="ref" href="#date_restriction">date restriction</a>)</span>
|
3773 |
+
tz = <timezone identifier> / offset
|
3774 |
+
(timezone will be used as tzidparam (below), if tzidparam not set)
|
3775 |
+
offset = (+/-)HHmm[ss], local date + UTC offset => <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME
|
3776 |
+
params<span class="ref">2</span> = array([(datetimeparam/dateparam) / tzidparam] [,xparam])
|
3777 |
+
datetimeparam = "VALUE" => "DATE-TIME" // <span class="ref">default, output as date-time</span>
|
3778 |
+
dateparam = "VALUE" => "DATE" // <span class="ref">output as DATE</span>
|
3779 |
+
tzidparam = "TZID" => <timezone identifier>
|
3780 |
+
xparams = *[ xparamkey => xparamvalue ]
|
3781 |
+
propOrderNo = int ordernumber, 1=1st, 2=2nd etc</p>
|
3782 |
+
<p class="label">Example 1</p>
|
3783 |
+
<p class="example">$vevent->setProperty( "exdate"
|
3784 |
+
, array( array( 2006, 8, 14, 16, 0, 0 ));
|
3785 |
+
<span class="ref">// >exclude 2006-08-14 16.00.00 (local date) from recurrence pattern</span></p>
|
3786 |
+
<p class="label">Example 2</p>
|
3787 |
+
<p class="example">$vevent->setProperty( "exdate"
|
3788 |
+
, array( array('year' =>,2006,'month' => 8,'day'=> 11))
|
3789 |
+
, array( 'VALUE' => 'DATE' ));
|
3790 |
+
<span class="ref">// exclude 2006-08-11 from recurrence pattern;</span></p>
|
3791 |
+
<br />
|
3792 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
3793 |
+
|
3794 |
+
|
3795 |
+
<a name="EXRULE"></a><h3>3.2.21 EXRULE</h3>
|
3796 |
+
This property defines a rule or repeating pattern for an exception to a recurrence set and is OPTIONAL and MAY occur more than once in <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a>, <a href="#VJOURNAL">VJOURNAL</a> components.
|
3797 |
+
<h5>Delete EXRULE</h5>
|
3798 |
+
Remove EXRULE from component.
|
3799 |
+
<p class="label">Format</p>
|
3800 |
+
<p class="format">deleteProperty( "EXRULE" )</p>
|
3801 |
+
<p class="label">Example 1</p>
|
3802 |
+
<p class="example">$vtodo->deleteProperty( "EXRULE" );</p>
|
3803 |
+
<p class="label">Example 2</p>
|
3804 |
+
Delete EXRULE property no 2.
|
3805 |
+
<p class="example">$vjournal->deleteProperty( "EXRULE", 2 );</p>
|
3806 |
+
<p class="label">Example 3</p>
|
3807 |
+
Deleting all EXRULE properties.
|
3808 |
+
<p class="example">while( $vjournal->deleteProperty( "EXRULE" ))
|
3809 |
+
continue;</p>
|
3810 |
+
<h5>Get EXRULE</h5>
|
3811 |
+
Fetch property value.
|
3812 |
+
<p class="label">Format 1</p>
|
3813 |
+
<p class="format">getProperty( "EXRULE" )</p>
|
3814 |
+
<p class="comment">output = recur<span class="ref">1</span></p>
|
3815 |
+
<p class="label">Format 2</p>
|
3816 |
+
<p class="format">getProperty( "exrule", propOrderNo/FALSE, TRUE )</p>
|
3817 |
+
<p class="comment">output = array( "value" => recur<span class="ref">1</span>
|
3818 |
+
, "params" => xparam<span class="ref">2</span> )</p>
|
3819 |
+
<p class="label">Format 3</p>
|
3820 |
+
<p class="format">getProperty( "EXRULE", propOrderNo )</p>
|
3821 |
+
<p class="comment">Get propOrderNo EXRULE</p>
|
3822 |
+
<p class="label">Example</p>
|
3823 |
+
<p class="example">$exrule = $vtodo->getProperty( "exrule" );</p>
|
3824 |
+
<h5>Set EXRULE</h5>
|
3825 |
+
Insert property value.
|
3826 |
+
<br />
|
3827 |
+
Parameters, will be ordered as prescribed in rcf2445.
|
3828 |
+
<p class="label">Format</p>
|
3829 |
+
<p class="format">setProperty( "exrule", recur [, xparams [, propOrderNo ]] )</p>
|
3830 |
+
See rules in detail in RFC2445 - Internet Calendaring and Scheduling Core Object Specification (iCalendar) in <a href="http://www.kigkonsult.se/iCalcreator/downloads/dl.php?f=rfc2445" title="RFC2445 in text format"><b>text</b></a>
|
3831 |
+
and <a href="http://www.kigkonsult.se/iCalcreator/iCalDictionary/index.html" title="RFC2445 in HTML format" target="_blank"><b>HTML</b></a> format.
|
3832 |
+
<p class="comment">recur<span class="ref">1</span> = array( "FREQ"=>freq
|
3833 |
+
// <span class="ref">either UNTIL or COUNT may appear in a "recur",
|
3834 |
+
but UNTIL and COUNT MUST NOT occur in the same "recur"</span>
|
3835 |
+
[, "UNTIL" "=>" >enddate ]
|
3836 |
+
[, "COUNT" "=>" 1*DIGIT ]
|
3837 |
+
// <span class="ref">the rest of these keywords are optional,
|
3838 |
+
but MUST NOT occur more than once</span>
|
3839 |
+
[, "INTERVAL" "=>" 1*DIGIT ]
|
3840 |
+
[, "BYSECOND" "=>" byseclist ]
|
3841 |
+
[, "BYMINUTE" "=>" byminlist ]
|
3842 |
+
[, "BYHOUR" "=>" byhrlist ]
|
3843 |
+
[, "BYDAY" "=>" bywdaylist ]
|
3844 |
+
[, "BYMONTHDAY" "=>" bymodaylist ]
|
3845 |
+
[, "BYYEARDAY" "=>" byyrdaylist ]
|
3846 |
+
[, "BYWEEKNO" "=>" bywknolist ]
|
3847 |
+
[, "BYMONTH" "=>" bymolist ]
|
3848 |
+
[, "BYSETPOS" "=>" bysplist ]
|
3849 |
+
[, "WKST" "=>" weekday ]
|
3850 |
+
[, x-name "=>" text ] )
|
3851 |
+
freq = "SECONDLY" /
|
3852 |
+
"MINUTELY" /
|
3853 |
+
"HOURLY" /
|
3854 |
+
"DAILY" /
|
3855 |
+
"WEEKLY" /
|
3856 |
+
"MONTHLY" /
|
3857 |
+
"YEARLY"
|
3858 |
+
enddate = date
|
3859 |
+
enddate = / date-time ;An <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME value
|
3860 |
+
byseclist = seconds
|
3861 |
+
byseclist = array(seconds *(, seconds ))
|
3862 |
+
seconds = 1DIGIT / 2DIGIT ;0 to 59
|
3863 |
+
byminlist = minutes
|
3864 |
+
byminlist = array( minutes *(, minutes ))
|
3865 |
+
minutes = 1DIGIT / 2DIGIT ;0 to 59
|
3866 |
+
byhrlist = hour
|
3867 |
+
byhrlist = array( hour *(, hour ))
|
3868 |
+
hour = 1DIGIT / 2DIGIT ;0 to 23
|
3869 |
+
bywdaylist = weekdaynum
|
3870 |
+
bywdaylist = array( weekdaynum *("," weekdaynum ))
|
3871 |
+
weekdaynum = array( [([plus] ordwk / minus ordwk)], "DAY" => weekday )
|
3872 |
+
plus = "+"
|
3873 |
+
minus = "-"
|
3874 |
+
ordwk = 1DIGIT / 2DIGIT ;1 to 53
|
3875 |
+
weekday = "SU" / "MO" / "TU" / "WE" / "TH" / "FR" / "SA"
|
3876 |
+
; Corresponding to
|
3877 |
+
; SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY,
|
3878 |
+
; FRIDAY, SATURDAY and SUNDAY days of the week.
|
3879 |
+
bymodaylist = monthdaynum
|
3880 |
+
bymodaylist = array( monthdaynum *(, monthdaynum ))
|
3881 |
+
monthdaynum = ( [plus] ordmoday ) / ( minus ordmoday )
|
3882 |
+
ordmoday = 1DIGIT / 2DIGIT ;1 to 31
|
3883 |
+
byyrdaylist = yeardaynum
|
3884 |
+
byyrdaylist = array( yeardaynum *(, yeardaynum ))
|
3885 |
+
yeardaynum = ( [plus] ordyrday ) / ( minus ordyrday )
|
3886 |
+
ordyrday = 1DIGIT / 2DIGIT / 3DIGIT ;1 to 366
|
3887 |
+
bywknolist = weeknum
|
3888 |
+
bywknolist = array( weeknum *(, weeknum ))
|
3889 |
+
weeknum = ( [plus] ordwk ) / ( minus ordwk )
|
3890 |
+
bymolist = monthnum
|
3891 |
+
bymolist = array( monthnum *(, monthnum ))
|
3892 |
+
monthnum = 1DIGIT / 2DIGIT ;1 to 12
|
3893 |
+
bysplist = setposday
|
3894 |
+
bysplist = array( setposday *(, setposday ))
|
3895 |
+
setposday = yeardaynum</p>
|
3896 |
+
<p class="comment">
|
3897 |
+
xparam<span class="ref">2</span> = array( *[ xparamkey => xparamvalue ] )
|
3898 |
+
propOrderNo = int ordernumber, 1=1st, 2=2nd etc</p>
|
3899 |
+
<p class="label">Example</p>
|
3900 |
+
<p class="example">$vevent->setProperty( "Exrule"
|
3901 |
+
, array( "FREQ" => "MONTHLY"
|
3902 |
+
, "UNTIL" => "20060831"
|
3903 |
+
// <span class="ref">DATE / DATE-TIME in <a href="#DATE_WITH_UTC_TIME">UTC</a> format; string/array, see <a href="#CREATED">CREATED</a> format</span>
|
3904 |
+
, "INTERVAL" => 2
|
3905 |
+
, "WKST" => "SU"
|
3906 |
+
, "BYSECOND" => 2
|
3907 |
+
, "BYMINUTE" => array( 2, -4, 6 ) // (*)
|
3908 |
+
, "BYHOUR" => array( 2, 4, -6 ) // (*)
|
3909 |
+
, "BYMONTHDAY" => -2 // (*)
|
3910 |
+
, "BYYEARDAY" => 2 // (*)
|
3911 |
+
, "BYWEEKNO" => array( 2, -4, 6 ) // (*)
|
3912 |
+
, "BYMONTH" => 2 // (*)
|
3913 |
+
, "BYSETPOS" => array( 2, -4, 6 ) // (*)
|
3914 |
+
, "BYday" => array( array(-2, "DAY" => "WE" )
|
3915 |
+
, array( 3, "DAY" => "TH")
|
3916 |
+
, array( 5, "DAY" => "FR")
|
3917 |
+
, array( "DAY" => "MO"))
|
3918 |
+
// (**)
|
3919 |
+
, "X-NAME" => "x-value" )
|
3920 |
+
, array( "xparamkey" => "xparamValue" ));
|
3921 |
+
|
3922 |
+
$vtodo->setProperty( >"exrule"
|
3923 |
+
, array( "FREQ" => "WEEKLY"
|
3924 |
+
, "COUNT" => 2
|
3925 |
+
, "INTERVAL" => 2
|
3926 |
+
, "WKST" => "SU"
|
3927 |
+
, "BYSECOND" => array( -2, 4, 6 ) // (*)
|
3928 |
+
, "BYMINUTE" => -2 // (*)
|
3929 |
+
, "BYHOUR" => 2 // (*)
|
3930 |
+
, "BYMONTHDAY" => array( 2, -4, 6 ) // (*)
|
3931 |
+
, "BYYEARDAY" => array( -2, 4, 6 ) // (*)
|
3932 |
+
, "BYWEEKNO" => -2 // (*)
|
3933 |
+
, "BYMONTH" => array( 2, 4, -6 ) // (*)
|
3934 |
+
, "BYSETPOS" => -2 // (*)
|
3935 |
+
, "BYday" => array( 5, "DAY" => "WE" )
|
3936 |
+
// (**)
|
3937 |
+
, "X-NAME" => "x-value" )
|
3938 |
+
, array( "xparamkey" => "xparamValue" ));
|
3939 |
+
//<span class="ref">(*) single value/array of values</span>
|
3940 |
+
//<span class="ref">(**) single value array /array of arrays</span>
|
3941 |
+
</p>
|
3942 |
+
<br />
|
3943 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
3944 |
+
|
3945 |
+
|
3946 |
+
<a name="FREEBUSY_PROP"></a><h3>3.2.22 FREEBUSY</h3>
|
3947 |
+
The property defines one or more free or busy time intervals in a <a href="#VFREEBUSY">VFREEBUSY</a> calendar component.<br /><br />
|
3948 |
+
The value type for FREEBUSY is PERIOD. A PERIOD is a DATE-TIME/DATE-TIME or a DATE-TIME/duration.
|
3949 |
+
<h5>Delete FREEBUSY</h5>
|
3950 |
+
Remove FREEBUSY from component.
|
3951 |
+
<p class="label">Format</p>
|
3952 |
+
<p class="format">deleteProperty( "FREEBUSY" )</p>
|
3953 |
+
<p class="label">Example 1</p>
|
3954 |
+
<p class="example">$vfreebusy->deleteProperty( "FREEBUSY" );</p>
|
3955 |
+
<p class="label">Example 2</p>
|
3956 |
+
Delete FREEBUSY property no 2.
|
3957 |
+
<p class="example">$vfreebusy->deleteProperty( "FREEBUSY", 2 );</p>
|
3958 |
+
<p class="label">Example 3</p>
|
3959 |
+
Deleting all FREEBUSY properties.
|
3960 |
+
<p class="example">while( $vfreebusy->deleteProperty( "FREEBUSY" ))
|
3961 |
+
continue;</p>
|
3962 |
+
<h5>Get FREEBUSY</h5>
|
3963 |
+
Fetch property value.
|
3964 |
+
<p class="label">Format 1</p>
|
3965 |
+
<p class="format">getProperty( "FREEBUSY" )</p>
|
3966 |
+
<p class="comment">output = array( "fbtyp" => freebusytype<span class="ref">1</span> , periods<span class="ref">2</span> )</p>
|
3967 |
+
<p class="label">Format 3</p>
|
3968 |
+
<p class="format">getProperty( "FREEBUSY", propOrderNo/FALSE , TRUE )</p>
|
3969 |
+
<p class="comment">output = array( "value" => array("fbtype" => freebusytype<span class="ref">1</span> ,periods<span class="ref">2</span>)
|
3970 |
+
, "params" => xparams<span class="ref"> 3</span> )</p>
|
3971 |
+
<p class="label">Format 3</p>
|
3972 |
+
<p class="format">getProperty( "FREEBUSY", propOrderNo )</p>
|
3973 |
+
<p class="comment">Get propOrderNo FREEBUSY</p>
|
3974 |
+
<p class="label">Example</p>
|
3975 |
+
<p class="example">$freebusy = $vfreebusy->getProperty( "FREEBUSY" );</p>
|
3976 |
+
<h5>Set FREEBUSY</h5>
|
3977 |
+
Insert property value. A FREEBUSY input date is always a <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME.
|
3978 |
+
<p class="label">Format</p>
|
3979 |
+
<p class="format">setProperty( "freebusy",freebusytype,fbperiods [,xparams [,propOrderNo ]] )</p>
|
3980 |
+
<p class="comment">freebusytype<span class="ref">1</span> = one of "FREE"
|
3981 |
+
/ "BUSY" <b>Default</b>
|
3982 |
+
/ "BUSY-UNAVAILABLE"
|
3983 |
+
/ "BUSY-TENTATIVE"
|
3984 |
+
/ x-name
|
3985 |
+
fbperiods = array( periods<span class="ref">2</span> )
|
3986 |
+
periods<span class="ref">2</span> = array( startdate, enddate/duration )
|
3987 |
+
*[, array( startdate, enddate/duration )]
|
3988 |
+
startdate/enddate = array( int year
|
3989 |
+
, int month
|
3990 |
+
, int day
|
3991 |
+
, int int hour
|
3992 |
+
, int min
|
3993 |
+
, int day )
|
3994 |
+
startdate/enddate = array( "year" => int year
|
3995 |
+
, "month" => int month
|
3996 |
+
, "day" => int day
|
3997 |
+
, "hour" => int hour
|
3998 |
+
, "min" => int min
|
3999 |
+
, "sec" => int sec ) // <span class="ref">output format</span>
|
4000 |
+
startdate/enddate = array( "timestamp" => int timestamp )
|
4001 |
+
startdate/enddate = string datestring // <span class="ref">string date,
|
4002 |
+
acceptable by strtotime-command,
|
4003 |
+
ex. "14 august 2006 16.00.00"
|
4004 |
+
(notice <a class="ref" href="#date_restriction">date restriction</a>)</span>
|
4005 |
+
startdate/enddate : date and time values MUST be an <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME
|
4006 |
+
duration = array( int week/false
|
4007 |
+
[, int day/false
|
4008 |
+
, int hour
|
4009 |
+
, int min
|
4010 |
+
, int sec] )
|
4011 |
+
duration = array( "week" => int week/false
|
4012 |
+
[, "day" => int day/false
|
4013 |
+
[, "hour" => int hour
|
4014 |
+
, "min" => int min
|
4015 |
+
, "sec" => int sec ]] ); // <span class="ref">output format</span>
|
4016 |
+
duration = array( "sec" => int sec )
|
4017 |
+
duration = string dur-value
|
4018 |
+
= (["+"]/"-") "P" (dur-date/dur-time/dur-week)
|
4019 |
+
dur-date = dur-day [dur-time]
|
4020 |
+
dur-time = "T" (dur-hour / dur-minute / dur-second)
|
4021 |
+
dur-week = 1*DIGIT "W"
|
4022 |
+
dur-hour = 1*DIGIT "H" [dur-minute]
|
4023 |
+
dur-minute = 1*DIGIT "M" [dur-second]
|
4024 |
+
dur-second = 1*DIGIT "S"
|
4025 |
+
dur-day = 1*DIGIT "D"
|
4026 |
+
xparams<span class="ref">3</span> = array( *[ xparamkey => xparamvalue ] )
|
4027 |
+
propOrderNo = int ordernumber, 1=1st, 2=2nd etc</p>
|
4028 |
+
<p class="label">Example</p>
|
4029 |
+
See rules in detail in RFC2445 - Internet Calendaring and Scheduling Core Object Specification (iCalendar) in <a href="http://www.kigkonsult.se/downloads/dl.php?f=rfc2445" title="RFC2445 in text format"><b>text</b></a>
|
4030 |
+
and <a href="http://www.kigkonsult.se/iCalcreator/iCalDictionary/index.html" title="RFC2445 in HTML format" target="_blank"><b>HTML</b></a> format.
|
4031 |
+
<p class="example">$fdate1 = array ( 2001, 1, 1, 1, 1, 1 );
|
4032 |
+
alt.
|
4033 |
+
$fdate1 = array ( "year" => 2001
|
4034 |
+
, "month" => 1
|
4035 |
+
, "day" => 1
|
4036 |
+
, "hour" => 1
|
4037 |
+
, "min" => 1
|
4038 |
+
, "sec" => 1 );
|
4039 |
+
$fdate2 = array ( 2002, 2, 2, 2, 2, 2 );
|
4040 |
+
$fdate3 = array ( 2003, 3, 3, 3, 3, 3 );
|
4041 |
+
$fdate4 = "4 April 2005 4:4:4";
|
4042 |
+
$fdate7 = array ( "year" => 2007
|
4043 |
+
, "month" => 7
|
4044 |
+
, "day" => 7 );
|
4045 |
+
$fdur6 = array ( "week" => 0
|
4046 |
+
, "day" => 5
|
4047 |
+
, "hour" => 5
|
4048 |
+
, "min" => 5
|
4049 |
+
, "sec" => 5 );
|
4050 |
+
$fdur7 = array ( 0, 0, 6 ); // <span class="ref">duration for 6 hours</span>
|
4051 |
+
$fdur8 = "P2D"; // <span class="ref">duration two days</span>
|
4052 |
+
$freebusy->setProperty "freebusy"
|
4053 |
+
, "FREE"
|
4054 |
+
, array( array( $fdate1, $fdate2 )
|
4055 |
+
, array( $fdate3, $fdur6 )
|
4056 |
+
, array( $fdate4, $fdate5 )));
|
4057 |
+
$freebusy->setProperty("freebusy"
|
4058 |
+
, "Busy"
|
4059 |
+
, array( array( array( $fdate1, $fdate2 )
|
4060 |
+
, array( $fdate3, $fdur8 )
|
4061 |
+
, array( $fdate4, $fdur7 )
|
4062 |
+
, array( $fdate1, $fdate3 )));</p>
|
4063 |
+
<br />
|
4064 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
4065 |
+
|
4066 |
+
|
4067 |
+
<a name="GEO"></a><h3>3.2.23 GEO</h3>
|
4068 |
+
This property specifies information related to the global position for the activity specified by VEVENT and VTODO components and is OPTIONAL and MUST NOT occur more than once.
|
4069 |
+
<br /><br />
|
4070 |
+
Value type for latitude and longitude is FLOAT. "Values for latitude and longitude shall be expressed as decimal fractions of degrees. Whole degrees of latitude shall be represented by a two-digit decimal number ranging from 0 through 90. Whole degrees of longitude shall be represented by a decimal number ranging from 0 through 180. When a decimal fraction of a degree is specified, it shall be separated from the whole number of degrees by a decimal point."
|
4071 |
+
<h5>Delete GEO</h5>
|
4072 |
+
Remove GEO from component.
|
4073 |
+
<p class="label">Format</p>
|
4074 |
+
<p class="format">deleteProperty( "GEO" )</p>
|
4075 |
+
<p class="label">Example</p>
|
4076 |
+
<p class="example">$vevent->deleteProperty( "FREEBUSY" );</p>
|
4077 |
+
<h5>Get GEO</h5>
|
4078 |
+
Fetch property value.
|
4079 |
+
<p class="label">Format 1</p>
|
4080 |
+
<p class="format">getProperty( "GEO" )</p>
|
4081 |
+
<p class="comment">output = array( "latitude" => <latitude>
|
4082 |
+
, "longitude" => <longitude>))</p>
|
4083 |
+
<p class="label">Format 2</p>
|
4084 |
+
<p class="format">getProperty( "GEO", FALSE , TRUE )</p>
|
4085 |
+
<p class="comment">output = array( "value" => array ( "latitude" => <latitude>
|
4086 |
+
, "longitude" => <longitude>))
|
4087 |
+
, "params" => xparam <span class="ref">1</span> )</p>
|
4088 |
+
<p class="label">Example</p>
|
4089 |
+
<p class="example">$geo = $vevent->getProperty( "GEO" );</p>
|
4090 |
+
<h5>Set GEO</h5>
|
4091 |
+
Insert property value.
|
4092 |
+
<p class="label">Format</p>
|
4093 |
+
<p class="format">setProperty( "geo", float latitude, float longitude [, xparam ] )</p>
|
4094 |
+
<p class="comment">xparam <span class="ref">1</span> = array( *[ xparamkey => xparamvalue ] )</p>
|
4095 |
+
<p class="label">Example</p>
|
4096 |
+
<p class="example">$vevent->setProperty( "geo", 11.23456, -23.45678 );</p>
|
4097 |
+
<br />
|
4098 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
4099 |
+
|
4100 |
+
|
4101 |
+
<a name="LAST-MODIFIED"></a><h3>3.2.24 LAST-MODIFIED</h3>
|
4102 |
+
The property specifies the date and time that the information associated with the calendar component was last revised in the calendar store. The property is OPTIONAL and MUST NOT occur more than once in <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a>, <a href="#VJOURNAL">VJOURNAL</a> and <a href="#VTIMEZONE">VTIMEZONE</a> components.<br /><br />
|
4103 |
+
The value type for LAST-MODIFIED is <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME.
|
4104 |
+
<h5>Delete LAST-MODIFIED</h5>
|
4105 |
+
Remove LAST-MODIFIED from component.
|
4106 |
+
<p class="label">Format</p>
|
4107 |
+
<p class="format">deleteProperty( "LAST-MODIFIED" )</p>
|
4108 |
+
<p class="label">Example</p>
|
4109 |
+
<p class="example">$vevent->deleteProperty( "LAST-MODIFIED" );</p>
|
4110 |
+
<h5>Get LAST-MODIFIED</h5>
|
4111 |
+
Fetch property value.
|
4112 |
+
<p class="label">Format 1</p>
|
4113 |
+
<p class="format">getProperty( "LAST-MODIFIED" )</p>
|
4114 |
+
<p class="comment">output = moddate<span class="ref">1</span></p>
|
4115 |
+
<p class="label">Format 2</p>
|
4116 |
+
<p class="format">getProperty( "LAST-MODIFIED", FALSE , TRUE )</p>
|
4117 |
+
<p class="comment">output = array( "value" => moddate<span class="ref">1</span>
|
4118 |
+
, "params" => xparam<span class="ref">2</span> )</p>
|
4119 |
+
<p class="label">Example</p>
|
4120 |
+
<p class="example">$lastMod = $vevent->getProperty( "LAST-MODIFIED" );</p>
|
4121 |
+
<h5>Set LAST-MODIFIED</h5>
|
4122 |
+
Insert property value. Input date is always a <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME or, if "offset" parameter is used, converted to a <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME.
|
4123 |
+
<p class="label">Format</p>
|
4124 |
+
<p class="format">setProperty( "Last-Modified" [, moddate [, xparam ]] )</p>
|
4125 |
+
<p class="comment">moddate<span class="ref">1</span> = array( "year" => int year
|
4126 |
+
, "month" => int month
|
4127 |
+
, "day" => int day
|
4128 |
+
[, "hour" => int hour
|
4129 |
+
, "min" => int min
|
4130 |
+
, "sec" => int sec
|
4131 |
+
, "tz" => offset ]] )
|
4132 |
+
completedDate = int year
|
4133 |
+
, int month
|
4134 |
+
, int day
|
4135 |
+
[, int hour
|
4136 |
+
, int min
|
4137 |
+
, int sec ]
|
4138 |
+
completedDate = array( int year
|
4139 |
+
, int month
|
4140 |
+
, int day
|
4141 |
+
[, int hour
|
4142 |
+
, int min
|
4143 |
+
, int sec
|
4144 |
+
[, offset ]] )
|
4145 |
+
completedDate = array ( "timestamp" => int timestamp [, "tz" => offset])
|
4146 |
+
completedDate = string datestring // <span class="ref">string date,
|
4147 |
+
acceptable by strtotime-command,
|
4148 |
+
ex. "14 august 2006 16.00.00"
|
4149 |
+
(notice <a class="ref" href="#date_restriction">date restriction</a>)</span>
|
4150 |
+
offset = (+/-)HHmm[ss], local date + UTC offset => <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME
|
4151 |
+
xparam<span class="ref">2</span> = array( *[ xparamkey => xparamvalue ] )</p>
|
4152 |
+
<p class="label">Example 1</p>
|
4153 |
+
<p class="example">$config = array( "unique_id" => "domain.com" );
|
4154 |
+
$vcalendar = new vcalendar( $config );
|
4155 |
+
$vtodo = & $vcalendar->newComponent( 'vtodo' );
|
4156 |
+
.. .
|
4157 |
+
$vtodo->setProperty("last-modified"
|
4158 |
+
, <td>2006, 8, 14, 12, 1, 2 );
|
4159 |
+
<span class="ref">// 14 august 2006 12.01.02 UTC</span></p>
|
4160 |
+
<p class="label">Example 2</p>
|
4161 |
+
<p class="example">$date = array("year" => 2006, "month" => 10, "day" => 10,
|
4162 |
+
"hour" => 10, "min" => 0, "sec" => 0, "tz" => "+0200");
|
4163 |
+
<span class="ref">// local date + UTC offset => <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME</span>
|
4164 |
+
$vtodo->setProperty( "last-modified", $date );
|
4165 |
+
.. .</p>
|
4166 |
+
<p class="label">Example 3</p>
|
4167 |
+
<p class="example">$vevent->setProperty( "last-modified" );
|
4168 |
+
<span class="ref">// current UTC DATE-TIME is set if called without parameters</span></p>
|
4169 |
+
<br />
|
4170 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
4171 |
+
|
4172 |
+
<a name="LOCATION"></a><h3>3.2.25 LOCATION</h3>
|
4173 |
+
The property defines the intended venue for the activity defined by a calendar component. The property is OPTIONAL and MUST NOT occur more than once in <a href="#VEVENT">VEVENT</a> and <a href="#VTODO">VTODO</a> components.
|
4174 |
+
<br /><br />
|
4175 |
+
The value type for LOCATION is TEXT.
|
4176 |
+
<h5>Delete LOCATION</h5>
|
4177 |
+
Remove LOCATION from component.
|
4178 |
+
<p class="label">Format</p>
|
4179 |
+
<p class="format">deleteProperty( "LOCATION" )</p>
|
4180 |
+
<p class="label">Example</p>
|
4181 |
+
<p class="example">$vevent->deleteProperty( "LOCATION" );</p>
|
4182 |
+
<h5>Get LOCATION</h5>
|
4183 |
+
Fetch property value.
|
4184 |
+
<p class="label">Format 1</p>
|
4185 |
+
<p class="format">getProperty( "LOCATION" )</p>
|
4186 |
+
<p class="comment">output = location<span class="ref">1</span></p>
|
4187 |
+
<p class="label">Format 2</p>
|
4188 |
+
<p class="format">getProperty( "LOCATION", FALSE , TRUE )</p>
|
4189 |
+
<p class="comment">output = array( "value" => location<span class="ref">1</span>
|
4190 |
+
, "params" => param<span class="ref">2</span> )</p>
|
4191 |
+
<p class="label">Example</p>
|
4192 |
+
<p class="example">$location = $vevent->getProperty( "LOCATION" );</p>
|
4193 |
+
<h5>Set LOCATION</h5>
|
4194 |
+
Insert property value.
|
4195 |
+
<br />
|
4196 |
+
Parameters, if any, will be ordered as prescribed in rcf2445.
|
4197 |
+
<p class="label">Format</p>
|
4198 |
+
<p class="format">setProperty( "location", string location [, array param] )</p>
|
4199 |
+
<p class="comment">location<span class="ref">1</span> = Value type TEXT
|
4200 |
+
params<span class="ref">2</span> = array( ["ALTREP" => "<an alternate text representation, URI>"]
|
4201 |
+
[, "LANGUAGE" => "<lang>"]
|
4202 |
+
[, xparam ]
|
4203 |
+
xparam = *[ xparamkey => xparamvalue ]</p>
|
4204 |
+
<p class="label">Example</p>
|
4205 |
+
<p class="example">$vevent->setProperty( "location", "Buckingham Palace" );</p>
|
4206 |
+
<br />
|
4207 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
4208 |
+
|
4209 |
+
|
4210 |
+
<a name="ORGANIZER"></a><h3>3.2.26 ORGANIZER</h3>
|
4211 |
+
The property defines the organizer for a calendar component and is OPTIONAL and MUST NOT occur more than once in <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a>, <a href="#VJOURNAL">VJOURNAL</a> and <a href="#VFREEBUSY">VFREEBUSY</a> components.<br /><br />
|
4212 |
+
This value type for ORGANIZER is URI, a calendar user address.
|
4213 |
+
<h5>Delete ORGANIZER</h5>
|
4214 |
+
Remove ORGANIZER from component.
|
4215 |
+
<p class="label">Format</p>
|
4216 |
+
<p class="format">deleteProperty( "ORGANIZER" )</p>
|
4217 |
+
<p class="label">Example</p>
|
4218 |
+
<p class="example">$vevent->deleteProperty( "ORGANIZER" );</p>
|
4219 |
+
<h5>Get ORGANIZER</h5>
|
4220 |
+
Fetch property value.
|
4221 |
+
<p class="label">Format 1</p>
|
4222 |
+
<p class="format">getProperty( "ORGANIZER" )</p>
|
4223 |
+
<p class="comment">output = organizer<span class="ref">1</span></p>
|
4224 |
+
<p class="label">Format 2</p>
|
4225 |
+
<p class="format">getProperty( "ORGANIZER", FALSE , TRUE )</p>
|
4226 |
+
<p class="comment">output = array( "value" => organizer<span class="ref">1</span>
|
4227 |
+
, "params" => params<span class="ref">2</span> )</p>
|
4228 |
+
<p class="label">Example</p>
|
4229 |
+
<p class="example">$organizer = $vevent->getProperty( "ORGANIZER" );</p>
|
4230 |
+
<h5>Set ORGANIZER</h5>
|
4231 |
+
Insert property value.
|
4232 |
+
Property value must be prefixed by protocol (ftp://, http://,mailto:, file://.. . ref. rfc 1738 ).
|
4233 |
+
Also DIR parameter must be prefixed by protocol.
|
4234 |
+
SENT-BY parameter must use protocol "mailto:", prefixed if missing.
|
4235 |
+
<br />
|
4236 |
+
Parameters, if any, will be ordered as prescribed in rcf2445.
|
4237 |
+
<p class="label">Format</p>
|
4238 |
+
<p class="format">setProperty( "organizer", organizer [, params] )</p>
|
4239 |
+
<p class="comment">organizer<span class="ref">1</span> = a calendar user address, a URI as defined by [RFC
|
4240 |
+
1738] or any other IANA registered form for a URI.
|
4241 |
+
params<span class="ref">2</span> = array( ["LANGUAGE" => "<lang>"
|
4242 |
+
(applies to the CN parameter value) ]
|
4243 |
+
[, "CN" => "common name to be associated
|
4244 |
+
with the calendar user
|
4245 |
+
specified by the property"]
|
4246 |
+
[, "DIR" => "reference to a directory
|
4247 |
+
entry associated with the calendar user
|
4248 |
+
specified by the property" ]
|
4249 |
+
[, "SENT-BY" => "single calendar user
|
4250 |
+
that is acting on behalf
|
4251 |
+
of the calendar user
|
4252 |
+
specified by the property" ]
|
4253 |
+
[, xparam ]
|
4254 |
+
xparam = *[ xparamkey => xparamvalue ]</p>
|
4255 |
+
<p class="label">Example</p>
|
4256 |
+
<p class="example">
|
4257 |
+
$dir = "ldap://domain.com:6666/o=3DDC%20Comp,c=3DUS??(cn=3DJohn%20Doe)";
|
4258 |
+
$vevent->setProperty( "organizer"
|
4259 |
+
, "ical@domain.com"
|
4260 |
+
, array( "CN" => "John Doe"
|
4261 |
+
, "DIR" => $dir
|
4262 |
+
, "SENT-BY" => "secretary@domain.com"
|
4263 |
+
, "X-Key1" => "X-Value1"
|
4264 |
+
, "X-Key2" => "X-Value2" ));</p>
|
4265 |
+
<br />
|
4266 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
4267 |
+
|
4268 |
+
|
4269 |
+
<a name="PERCENT-COMPLETE"></a><h3>3.2.27 PERCENT-COMPLETE</h3>
|
4270 |
+
This property is used by an assignee or delegatee of a <a href="#VTODO">VTODO</a> to convey the percent completion of a <a href="#VTODO">VTODO</a> to the Organizer and is OPTIONAL and MUST NOT occur more than once.<br /><br />
|
4271 |
+
The property value is a positive integer between zero and one hundred. A value of "0" indicates the <a href="#VTODO">VTODO</a> has not yet been started. A value of "100" indicates that the <a href="#VTODO">VTODO</a> has been completed. Integer values in between indicate the percent partially complete.
|
4272 |
+
<h5>Delete PERCENT-COMPLETE</h5>
|
4273 |
+
Remove PERCENT-COMPLETE from component.
|
4274 |
+
<p class="label">Format</p>
|
4275 |
+
<p class="format">deleteProperty( "PERCENT-COMPLETE" )</p>
|
4276 |
+
<p class="label">Example</p>
|
4277 |
+
<p class="example">$vtodo->deleteProperty( "PERCENT-COMPLETE" );</p>
|
4278 |
+
<h5>Get PERCENT-COMPLETE</h5>
|
4279 |
+
Fetch property value.
|
4280 |
+
<p class="label">Format 1</p>
|
4281 |
+
<p class="format">getProperty( "PERCENT-COMPLETE" )</p>
|
4282 |
+
<p class="comment">output = percent<span class="ref">1</span></p>
|
4283 |
+
<p class="label">Format 2</p>
|
4284 |
+
<p class="format">getProperty( "PRIORITY", FALSE , TRUE )</p>
|
4285 |
+
<p class="comment">output = array( "value" => percent<span class="ref">1</span>
|
4286 |
+
, "params" => xparam<span class="ref">2</span> )</p>
|
4287 |
+
<p class="label">Example</p>
|
4288 |
+
<p class="example">$percent = $vtodo->getProperty( "PERCENT-COMPLETE" );</p>
|
4289 |
+
<h5>Set PERCENT-COMPLETE</h5>
|
4290 |
+
Insert property value.
|
4291 |
+
<p class="label">Format</p>
|
4292 |
+
<p class="format">setProperty( "Percent-Complete", percent [, xparam ] )</p>
|
4293 |
+
<p class="comment">percent<span class="ref">1</span> = Value type INTEGER
|
4294 |
+
xparam<span class="ref">2</span> = array( *[ xparamkey => xparamvalue ] )</p>
|
4295 |
+
<p class="label">Example</p>
|
4296 |
+
<p class="example">$vtodo->setProperty( "percent-complete", 90 );</p>
|
4297 |
+
<br />
|
4298 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
4299 |
+
|
4300 |
+
|
4301 |
+
<a name="PRIORITY"></a><h3>3.2.28 PRIORITY</h3>
|
4302 |
+
The property defines the relative priority for a calendar component and is OPTIONAL and MUST NOT occur more than once in <a href="#VEVENT">VEVENT</a> and <a href="#VTODO">VTODO</a> components.<br /><br />
|
4303 |
+
The priority is specified as an integer in the range zero to nine.<br />
|
4304 |
+
A value of zero (US-ASCII decimal 48) specifies an undefined priority.<br />
|
4305 |
+
A value of one (US-ASCII decimal 49) is the highest priority.<br />
|
4306 |
+
A value of two (US-ASCII decimal 50) is the second highest priority.<br />
|
4307 |
+
Subsequent numbers specify a decreasing ordinal priority.<br />
|
4308 |
+
A value of nine (US-ASCII decimal 58) is the lowest priority.
|
4309 |
+
<h5>Delete PRIORITY</h5>
|
4310 |
+
Remove PRIORITY from component.
|
4311 |
+
<p class="label">Format</p>
|
4312 |
+
<p class="format">deleteProperty( "PRIORITY" )</p>
|
4313 |
+
<p class="label">Example</p>
|
4314 |
+
<p class="example">$vevent->deleteProperty( "PRIORITY" );</p>
|
4315 |
+
<h5>Get PRIORITY</h5>
|
4316 |
+
Fetch property value.
|
4317 |
+
<p class="label">Format 1</p>
|
4318 |
+
<p class="format">getProperty( "PRIORITY" )</p>
|
4319 |
+
<p class="comment">output = priority<span class="ref">1</span></p>
|
4320 |
+
<p class="label">Format 2</p>
|
4321 |
+
<p class="format">getProperty( "PRIORITY", FALSE , TRUE )</p>
|
4322 |
+
<p class="comment">output = array( "value" => priority<span class="ref">1</span>
|
4323 |
+
, "params" => xparam<span class="ref">2</span> )</p>
|
4324 |
+
<p class="label">Example</p>
|
4325 |
+
<p class="example">$priority = $vevent->getProperty( "priority" );</p>
|
4326 |
+
<h5>Set PRIORITY</h5>
|
4327 |
+
Insert property value.
|
4328 |
+
<p class="label">Format</p>
|
4329 |
+
<p class="format">setProperty( "priority", priority [, xparam ] )</p>
|
4330 |
+
<p class="comment">priority<span class="ref">1</span> = Value type INTEGER
|
4331 |
+
xparam<span class="ref">2</span> = array( *[ xparamkey => xparamvalue ] )</p>
|
4332 |
+
<p class="label">Example</p>
|
4333 |
+
<p class="example">$vevent->setProperty( "priority", 3 );</p>
|
4334 |
+
<br />
|
4335 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
4336 |
+
|
4337 |
+
|
4338 |
+
<a name="RDATE"></a><h3>3.2.29 RDATE</h3>
|
4339 |
+
This property defines the list of date/times for a recurrence set and is OPTIONAL and MAY occur more than once in <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a>, <a href="#VJOURNAL">VJOURNAL</a>, <a href="#VTIMEZONE">STANDARD</a> and <a href="#VTIMEZONE">DAYLIGHT</a> components.<br /><br />
|
4340 |
+
The default value type for RDATE is DATE-TIME, can be set to DATE or PERIOD (params <span class="ref">2</span>).
|
4341 |
+
<h5>Delete RDATE</h5>
|
4342 |
+
Remove RDATE from component.
|
4343 |
+
<p class="label">Format</p>
|
4344 |
+
<p class="format">deleteProperty( "RDATE" )</p>
|
4345 |
+
<p class="label">Example 1</p>
|
4346 |
+
<p class="example">$vtodo->deleteProperty( "RDATE" );</p>
|
4347 |
+
<p class="label">Example 2</p>
|
4348 |
+
Delete RDATE property no 2.
|
4349 |
+
<p class="example">$vjournal->deleteProperty( "RDATE", 2 );</p>
|
4350 |
+
<p class="label">Example 3</p>
|
4351 |
+
Deleting all RDATE properties.
|
4352 |
+
<p class="example">while( $vjournal->deleteProperty( "RDATE" ))
|
4353 |
+
continue;</p>
|
4354 |
+
<h5>Get RDATE</h5>
|
4355 |
+
Fetch property value.
|
4356 |
+
<p class="label">Format 1</p>
|
4357 |
+
<p class="format">getProperty( "RDATE" )</p>
|
4358 |
+
<p class="comment">output = dates<span class="ref">1</span></p>
|
4359 |
+
<p class="label">Format 2</p>
|
4360 |
+
<p class="format">getProperty( "RDATE", propOrderNo/FALSE , TRUE )</p>
|
4361 |
+
<p class="comment">output = array( "value" => dates<span class="ref">1</span>
|
4362 |
+
, "params" => params<span class="ref">2</span> )</p>
|
4363 |
+
<p class="label">Format 3</p>
|
4364 |
+
<p class="format">getProperty( "RDATE", propOrderNo )</p>
|
4365 |
+
<p class="comment">Get propOrderNo RDATE</p>
|
4366 |
+
<p class="label">Example</p>
|
4367 |
+
<p class="example">$rdates = $vevent->getProperty( "RDATE" );</p>
|
4368 |
+
<h5>Set RDATE</h5>
|
4369 |
+
Insert property value.<br />
|
4370 |
+
If "TZID" is set in params, ex. "TZID" = "CET", all timezone or offset in dates are ignored and DATE-TIME value type is set.<br />
|
4371 |
+
If DATE value type is set in params ("VALUE" = "DATE"), all timezone or offset in dates are ignored.<br />
|
4372 |
+
If "PERIOD" is set in params ("VALUE" = "PERIOD"), DATE-TIME value type is set.<br />
|
4373 |
+
If no "VALUE" parameter in params, DATE-TIME (default) value type is set.<br />
|
4374 |
+
If empty params and offset in 1st date, all remaining dates are set to UTC.<br />
|
4375 |
+
If no "TZID" is set in params and timezone in 1st date, all remaining dates are within this timezone and param "TZID" is set.<br />
|
4376 |
+
If none of the above rules are applicable, DATE-TIME and local date is set default.
|
4377 |
+
<br />
|
4378 |
+
Parameters, if any, will be ordered as prescribed in rcf2445.
|
4379 |
+
<p class="label">Format</p>
|
4380 |
+
<p class="format">setProperty( "rdate", dates [, params [, propOrderNo ]] )</p>
|
4381 |
+
<p class="comment">dates<span class="ref">1</span> = array ( date2 *[, date2 ] )
|
4382 |
+
date2 = date
|
4383 |
+
date2 = array( startdate, enddate/duration ) ]
|
4384 |
+
startdate = date
|
4385 |
+
enddate = date
|
4386 |
+
date = array( int year
|
4387 |
+
, int month
|
4388 |
+
, int day
|
4389 |
+
[, int int hour
|
4390 |
+
, int min
|
4391 |
+
, int day
|
4392 |
+
, mixed tz ] )
|
4393 |
+
date = array( "year" => int year
|
4394 |
+
, "month" => int month
|
4395 |
+
, "day" => int day
|
4396 |
+
[, "hour" => int hour
|
4397 |
+
, "min" => int min
|
4398 |
+
, "sec" => int sec
|
4399 |
+
[, "tz" => mixed tz ]] )
|
4400 |
+
// <span class="ref">output format</span>
|
4401 |
+
date = array( "timestamp" => int timestamp
|
4402 |
+
[, "tz" => mixed tz ] )
|
4403 |
+
date = string datestring // <span class="ref">string date,
|
4404 |
+
acceptable by strtotime-command,
|
4405 |
+
ex. "14 august 2006 16.00.00"
|
4406 |
+
(notice <a class="ref" href="#date_restriction">date restriction</a>)</span>
|
4407 |
+
tz = timezone / offset
|
4408 |
+
(timezone will be used as tzidparam, if tzidparam not exists)
|
4409 |
+
offset = (+/-)HHmm[ss], local date + UTC offset => <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME
|
4410 |
+
duration = array( int week/false
|
4411 |
+
[, int day/false
|
4412 |
+
, int hour
|
4413 |
+
, int min
|
4414 |
+
, int sec] )
|
4415 |
+
duration = array([ "week" => int week/false ,] /
|
4416 |
+
[ "day" => int day/false
|
4417 |
+
[, "hour" => int hour
|
4418 |
+
, "min" => int min
|
4419 |
+
, "sec" => int sec ]] );
|
4420 |
+
// <span class="ref">output format, only used keys</span>
|
4421 |
+
duration = array( "sec" => int sec );
|
4422 |
+
duration = string format duration like "P15DT5H0M20S"
|
4423 |
+
params<span class="ref">2</span> = ([tzidparam ( / datetimeparam / dateparam / periodparam )]
|
4424 |
+
*[, xparams ] )
|
4425 |
+
tzidparam = "TZID" => <timezone identifier>
|
4426 |
+
// <span class="ref">output as local DATE-TIME with timezone identifier</span>
|
4427 |
+
datetimeparam = "VALUE" => "DATE-TIME" // <span class="ref">default, output as DATE-TIME</span>
|
4428 |
+
dateparam = "VALUE" => "DATE" // <span class="ref">output as DATE</span>
|
4429 |
+
periodparam = "VALUE" => "PERIOD" // <span class="ref">output as PERIOD (datetime)</span>
|
4430 |
+
xparams = xparamkey => xparamvalue
|
4431 |
+
propOrderNo = int ordernumber, 1=1st, 2=2nd etc</p>
|
4432 |
+
<p class="label">Example</p>
|
4433 |
+
See rules in detail in RFC2445 - Internet Calendaring and Scheduling Core Object Specification (iCalendar) in <a href="http://www.kigkonsult.se/downloads/dl.php?f=rfc2445" title="RFC2445 in text format"><b>text</b></a>
|
4434 |
+
and <a href="http://www.kigkonsult.se/iCalcreator/iCalDictionary/index.html" title="RFC2445 in HTML format" target="_blank"><b>HTML</b></a> format.<br />
|
4435 |
+
<p class="example">// $rdate1 = array ( 2001, 1, 1, 1, 1, 1 );
|
4436 |
+
// alt.
|
4437 |
+
$rdate1 = array( "year" => 2001
|
4438 |
+
, "month" => 1
|
4439 |
+
, "day" => 1
|
4440 |
+
, "hour" => 1
|
4441 |
+
, "min" => 1
|
4442 |
+
, "sec" => 1
|
4443 |
+
, "tz" => "GMT" );
|
4444 |
+
$rdate2 = array( 2002, 2, 2, 2, 2, 2, "GMT" );
|
4445 |
+
$rdate3 = "3 March 2003 03.03.03";
|
4446 |
+
$rdate4 = array( 2004, 4, 4, 4, 4, 4, "GMT" );
|
4447 |
+
$rdate5 = array( 2005, 10, 5, 5, 5, 5 );
|
4448 |
+
$rdate8 = array( "year" => 2007, "month" => 7, "day" => 7 );
|
4449 |
+
$rdur6 = array( "week" => 0
|
4450 |
+
, "day" => 0
|
4451 |
+
, "hour" => 5
|
4452 |
+
, "min" => 5
|
4453 |
+
, "sec" => 5 );
|
4454 |
+
$rdur7 = array( 0, 0, 6 );
|
4455 |
+
<span class="comment">// duration for 6 hours</span>
|
4456 |
+
$rdur8 = array( "week" => 8 );
|
4457 |
+
<span class="comment">// duration for 8 weeks</span>
|
4458 |
+
|
4459 |
+
$vevent = & $vcalendar->newComponent( 'vevent' );
|
4460 |
+
$vevent->setProperty( "rdate", array( $rdate1 ));
|
4461 |
+
<span class="comment">// one recurrence date, date in 7-params format (DATE-TIME)</span>
|
4462 |
+
|
4463 |
+
$vevent->setProperty( "rdate", array( $rdate1, $rdate2 ));
|
4464 |
+
<span class="comment">// two dates, date 7-params format (DATE-TIME)</span>
|
4465 |
+
|
4466 |
+
$vevent->setProperty( "rdate", array( array( $rdate1, $rdate2 )
|
4467 |
+
, array( $rdate3, $rdate4 ))
|
4468 |
+
, array( 'VALUE' => 'PERIOD' ));
|
4469 |
+
<span class="comment">// Both fromdate and enddate must have 7 params (DATE-TIME) !!!</span>
|
4470 |
+
|
4471 |
+
$vevent->setProperty( "rdate", array( array( $rdate2, $rdur6 ))
|
4472 |
+
, array( 'VALUE' => 'PERIOD' ));
|
4473 |
+
<span class="comment">// one duration (fromdate-duration)</span>
|
4474 |
+
|
4475 |
+
$vevent->setProperty( "rdate", array( array( $rdate1, $date2 )
|
4476 |
+
, array( $rdate3, $rdur7 ))
|
4477 |
+
, array( 'VALUE' => 'PERIOD' ));
|
4478 |
+
<span class="comment">// period, pairs of fromdate+enddate and fromdate-duration</span>
|
4479 |
+
|
4480 |
+
$vevent->setProperty( "rdate", array( $rdate5, $date8 ))
|
4481 |
+
, array( 'VALUE' => 'DATE' ));
|
4482 |
+
<span class="comment">// dates in DATE format</span>
|
4483 |
+
.. .</p>
|
4484 |
+
<br />
|
4485 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
4486 |
+
|
4487 |
+
|
4488 |
+
<a name="RECURRENCE-ID"></a><h3>3.2.30 RECURRENCE-ID</h3>
|
4489 |
+
This property is used in conjunction with the <a href="#UID">UID</a> and <a href="#SEQUENCE">SEQUENCE</a> property to identify a specific instance of a recurring <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a> or <a href="#VJOURNAL">VJOURNAL</a> calendar component and is OPTIONAL and MAY NOT occur more than once.<br /><br />
|
4490 |
+
The property value is the effective value of the <a href="#DTSTART">DTSTART</a> property of the recurrence instance. The default value type is DATE-TIME, can be set to DATE (params <span class="ref">2</span>).
|
4491 |
+
<h5>Delete RECURRENCE-ID</h5>
|
4492 |
+
Remove RECURRENCE-ID from component.
|
4493 |
+
<p class="label">Format</p>
|
4494 |
+
<p class="format">deleteProperty( "RECURRENCE-ID" )</p>
|
4495 |
+
<p class="label">Example</p>
|
4496 |
+
<p class="example">$vevent->deleteProperty( "RECURRENCE-ID" );</p>
|
4497 |
+
<h5>Get RECURRENCE-ID</h5>
|
4498 |
+
Fetch property value.
|
4499 |
+
<p class="label">Format 1</p>
|
4500 |
+
<p class="format">getProperty( "RECURRENCE-ID" )</p>
|
4501 |
+
<p class="comment">output = recurrIdDate<span class="ref">1</span></p>
|
4502 |
+
<p class="label">Format 2</p>
|
4503 |
+
<p class="format">getProperty( "RECURRENCE-ID", FALSE , TRUE )</p>
|
4504 |
+
<p class="comment">output = array( "value" => recurrIdDate<span class="ref">1</span>
|
4505 |
+
, "params" => params<span class="ref">2</span> )</p>
|
4506 |
+
<p class="label">Example</p>
|
4507 |
+
<p class="example">$recurrDate = $vtodo->getProperty( "RECURRENCE-ID" );</p>
|
4508 |
+
<h5>Set RECURRENCE-ID</h5>
|
4509 |
+
Insert property value. If DATE value type is expected, "VALUE" = "DATE" <b>must</b> be set (in params<span class="ref">2</span>) otherwise DATE-TIME (default) value type is set.
|
4510 |
+
<br />
|
4511 |
+
<br />
|
4512 |
+
If no timezone parameter (tz or tzidparam below) is set (then local time is assumed) and config <a href="#dTZID">TZID</a> is set, date-time values will be set WITH timezone from config.
|
4513 |
+
<p class="label">Format</p>
|
4514 |
+
<p class="format">setProperty( "recurrence-id", recurrIdDate [, params ] )</p>
|
4515 |
+
<p class="comment">recurrIdDate<span class="ref">1</span> = array( "year" => int year
|
4516 |
+
, "month" => int month
|
4517 |
+
, "day" => int day
|
4518 |
+
[, "hour" => int hour
|
4519 |
+
, "min" => int min
|
4520 |
+
, "sec" => int sec
|
4521 |
+
[, "tz" => mixed tz ]] )
|
4522 |
+
recurrIdDate = int year
|
4523 |
+
, int month
|
4524 |
+
, int day
|
4525 |
+
[, int hour
|
4526 |
+
, int min
|
4527 |
+
, int sec
|
4528 |
+
[, mixed tz ]]
|
4529 |
+
recurrIdDate = array( int year
|
4530 |
+
, int month
|
4531 |
+
, int day
|
4532 |
+
[, int hour
|
4533 |
+
, int min
|
4534 |
+
, int sec
|
4535 |
+
[, mixed tz ]] )
|
4536 |
+
recurrIdDate = array( "timestamp" => int timestamp
|
4537 |
+
[, "tz" => mixed tz ] )
|
4538 |
+
recurrIdDate = string datestring // <span class="ref">string date,
|
4539 |
+
acceptable by strtotime-command,
|
4540 |
+
ex. "14 august 2006 16.00.00"
|
4541 |
+
(notice <a class="ref" href="#date_restriction">date restriction</a>)</span>
|
4542 |
+
tz = timezone / offset
|
4543 |
+
(timezone will be used as tzidparam, if tzidparam not exists)
|
4544 |
+
offset = (+/-)HHmm[ss], local date + UTC offset => <a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME
|
4545 |
+
params<span class="ref">2</span> = array([ datetimeparam/dateparam/tzidparam ]
|
4546 |
+
[, rangeparam ]
|
4547 |
+
[, xparam ] )
|
4548 |
+
datetimeparam = "VALUE" => "DATE-TIME" // <span class="ref">default, output as DATE-TIME</span>
|
4549 |
+
dateparam = "VALUE" => "DATE" // <span class="ref">output as DATE</span>
|
4550 |
+
tzidparam = "TZID" => <timezone identifier>
|
4551 |
+
// <span class="ref">output as local date-time with timezone identifier</span>
|
4552 |
+
rangeparam = "RANGE" => ( "THISANDPRIOR" / "THISANDFUTURE" )
|
4553 |
+
// <span class="ref">range parameter</span>
|
4554 |
+
xparam = *[ xparamkey => xparamvalue ]</p>
|
4555 |
+
<p class="label">Example</p>
|
4556 |
+
<p class="example">$vtodo->setProperty( "recurrence-id", "3 March 2003 03.03.03" );
|
4557 |
+
<span class="comment">// 3 march 2003 03.03.03 local time</span></p>
|
4558 |
+
<br />
|
4559 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
4560 |
+
|
4561 |
+
|
4562 |
+
<a name="RELATED-TO"></a><h3>3.2.31 RELATED-TO</h3>
|
4563 |
+
The property is used to represent a relationship or reference between one calendar component and another and is OPTIONAL and MAY occur more than once in <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a>, <a href="#VJOURNAL">VJOURNAL</a> components.<br /><br />
|
4564 |
+
The property value consists of the persistent, globally unique identifier of another calendar component. This value would be represented in a calendar component by the <a href="#UID">UID</a> property.<br /><br />
|
4565 |
+
The value type for RELATED-TO is TEXT.
|
4566 |
+
<h5>Delete RELATED-TO</h5>
|
4567 |
+
Remove RELATED-TO from component.
|
4568 |
+
<p class="label">Format</p>
|
4569 |
+
<p class="format">deleteProperty( "RELATED-TO" )</p>
|
4570 |
+
<p class="label">Example 1</p>
|
4571 |
+
<p class="example">$vtodo->deleteProperty( "RELATED-TO" );</p>
|
4572 |
+
<p class="label">Example 2</p>
|
4573 |
+
Delete RELATED-TO property no 2.
|
4574 |
+
<p class="example">$vjournal->deleteProperty( "RELATED-TO", 2 );</p>
|
4575 |
+
<p class="label">Example 3</p>
|
4576 |
+
Deleting all RELATED-TO properties.
|
4577 |
+
<p class="example">while( $vjournal->deleteProperty( "RELATED-TO" ))
|
4578 |
+
continue;</p>
|
4579 |
+
<h5>Get RELATED-TO</h5>
|
4580 |
+
Fetch property value.
|
4581 |
+
<p class="label">Format 1</p>
|
4582 |
+
<p class="format">getProperty( "RELATED-TO" )</p>
|
4583 |
+
<p class="comment">output = relid<span class="ref">1</span></p>
|
4584 |
+
<p class="label">Format 2</p>
|
4585 |
+
<p class="format">getProperty( "RELATED-TO", propOrderNo/FALSE , TRUE )</p>
|
4586 |
+
<p class="comment">output = array( "value" => relid<span class="ref">1</span>
|
4587 |
+
, "params" => params<span class="ref">2</span> )</p>
|
4588 |
+
<p class="label">Format 3</p>
|
4589 |
+
<p class="format">getProperty( "RELATED-TO", propOrderNo )</p>
|
4590 |
+
<p class="comment">Get propOrderNo RELATED-TO</p>
|
4591 |
+
<p class="label">Example</p>
|
4592 |
+
<p class="example">$relatedId = $vtodo->getProperty( "RELATED-TO" );</p>
|
4593 |
+
<h5>Set RELATED-TO</h5>
|
4594 |
+
Insert property value.
|
4595 |
+
<p class="label">Format</p>
|
4596 |
+
<p class="format">setProperty( "Related-To", relid [, params [, propOrderNo ]] )</p>
|
4597 |
+
<p class="comment">relid<span class="ref">1</span> = Value type TEXT.
|
4598 |
+
params<span class="ref">2</span> = array( [ reltype ] [, xparam] )
|
4599 |
+
reltype = "RELTYPE" => ("PARENT" (Default)
|
4600 |
+
/ "CHILD"
|
4601 |
+
/ "SIBLING"
|
4602 |
+
/ iana-token
|
4603 |
+
/ x-name)
|
4604 |
+
xparam = *[ xparamkey => xparamvalue ]
|
4605 |
+
propOrderNo = int ordernumber, 1=1st, 2=2nd etc</p>
|
4606 |
+
<p class="label">Example</p>
|
4607 |
+
<p class="example">$vtodo->setProperty( "related-to", "19960401-080045-4000F192713@host.com");</p>
|
4608 |
+
<br />
|
4609 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
4610 |
+
|
4611 |
+
<a name="REPEAT"></a><h3>3.2.32 REPEAT</h3>
|
4612 |
+
This property defines the number of time the <a href="#VALARM">ALARM</a> should be repeated, after the initial trigger.
|
4613 |
+
If the <a href="#VALARM">ALARM</a> triggers more than once, then this property MUST be specified along with the <a href="#DURATION">DURATION</a> property.
|
4614 |
+
<h5>Delete REPEAT</h5>
|
4615 |
+
Remove REPEAT from component.
|
4616 |
+
<p class="label">Format</p>
|
4617 |
+
<p class="format">deleteProperty( "REPEAT" )</p>
|
4618 |
+
<p class="label">Example</p>
|
4619 |
+
<p class="example">$valarm->deleteProperty( "REPEAT" );</p>
|
4620 |
+
<h5>Get REPEAT</h5>
|
4621 |
+
Fetch property value.
|
4622 |
+
<p class="label">Format 1</p>
|
4623 |
+
<p class="format">getProperty( "REPEAT" )</p>
|
4624 |
+
<p class="comment">output = repeatTimes<span class="ref">1</span></p>
|
4625 |
+
<p class="label">Format 2</p>
|
4626 |
+
<p class="format">getProperty( "REPEAT", FALSE , TRUE )</p>
|
4627 |
+
<p class="comment">output = array( "value" => repeatTimes<span class="ref">1</span>
|
4628 |
+
, "params" => xparam<span class="ref">2</span> )</p>
|
4629 |
+
<p class="label">Example</p>
|
4630 |
+
<p class="example">$repeat = $vtodo->getProperty( "REPEAT" );</p>
|
4631 |
+
<h5>Set REPEAT</h5>
|
4632 |
+
Insert property value.
|
4633 |
+
<p class="label">Format</p>
|
4634 |
+
<p class="format">setProperty( "repeat", repeatTimes [, xparam ] )</p>
|
4635 |
+
<p class="comment">repeatTimes<span class="ref">1</span> = Value type INTEGER
|
4636 |
+
xparam<span class="ref">2</span> = array( *[ xparamkey => xparamvalue ] )</p>
|
4637 |
+
<p class="label">Example</p>
|
4638 |
+
<p class="example">$valarm->setProperty( "repeat", 2 );</p>
|
4639 |
+
<br />
|
4640 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
4641 |
+
|
4642 |
+
|
4643 |
+
<a name="REQUEST-STATUS"></a><h3>3.2.33 REQUEST-STATUS</h3>
|
4644 |
+
This property defines the status code returned for a scheduling request and is OPTIONAL and MAY occur more than once in <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a>, <a href="#VJOURNAL">VJOURNAL</a> and <a href="#VFREEBUSY">VFREEBUSY</a> components.
|
4645 |
+
<h5>Delete REQUEST-STATUS</h5>
|
4646 |
+
Remove REQUEST-STATUS from component.
|
4647 |
+
<p class="label">Format</p>
|
4648 |
+
<p class="format">deleteProperty( "REQUEST-STATUS" )</p>
|
4649 |
+
<p class="label">Example 1</p>
|
4650 |
+
<p class="example">$vtodo->deleteProperty( "REQUEST-STATUS" );</p>
|
4651 |
+
<p class="label">Example 2</p>
|
4652 |
+
Delete REQUEST-STATUS property no 2.
|
4653 |
+
<p class="example">$vjournal->deleteProperty( "REQUEST-STATUS", 2 );</p>
|
4654 |
+
<p class="label">Example 3</p>
|
4655 |
+
Deleting all REQUEST-STATUS properties.
|
4656 |
+
<p class="example">while( $vjournal->deleteProperty( "REQUEST-STATUS" ))
|
4657 |
+
continue;</p>
|
4658 |
+
<h5>Get REQUEST-STATUS</h5>
|
4659 |
+
Fetch property value.
|
4660 |
+
<p class="label">Format 1</p>
|
4661 |
+
<p class="format">getProperty( "REQUEST-STATUS" )</p>
|
4662 |
+
<p class="comment">output = array( "statcode" => statcode<span class="ref">1</span>
|
4663 |
+
, "text" => errtext<span class="ref">2</span>
|
4664 |
+
[ , "extdata" => extraData<span class="ref"> 3</span> ] )</p>
|
4665 |
+
<p class="label">Format 2</p>
|
4666 |
+
<p class="format">getProperty( "REQUEST-STATUS", propOrderNo/FALSE, TRUE )</p>
|
4667 |
+
<p class="comment">output = array( "value" => array( "statcode" => statcode<span class="ref">1</span>
|
4668 |
+
, "text" => errtext<span class="ref">2</span>
|
4669 |
+
[ , "extdata" => extraData<span class="ref">3</span> ] )
|
4670 |
+
, "params" => params<span class="ref">4</span> )</p>
|
4671 |
+
<p class="label">Format 3</p>
|
4672 |
+
<p class="format">getProperty( "REQUEST-STATUS", propOrderNo )</p>
|
4673 |
+
<p class="comment">Get propOrderNo REQUEST-STATUS</p>
|
4674 |
+
<p class="label">Example</p>
|
4675 |
+
<p class="example">$requestStatus = $vtodo->getProperty( "REQUEST-STATUS" );</p>
|
4676 |
+
<h5>Set REQUEST-STATUS</h5>
|
4677 |
+
Insert property value.
|
4678 |
+
<p class="label">Format</p>
|
4679 |
+
<p class="format">setProperty( "Request-Status"
|
4680 |
+
, statcode, errtext [,extraData/FALSE [,params [,propOrderNo]]])</p>
|
4681 |
+
<p class="comment">statcode<span class="ref">1</span> = Hierarchical, numeric return status code
|
4682 |
+
(1*DIGIT *("." 1*DIGIT))
|
4683 |
+
errtext<span class="ref">2</span> = Textual status description
|
4684 |
+
extraData<span class="ref">3</span> = Textual exception data.
|
4685 |
+
For example, the offending property name and value
|
4686 |
+
or complete property line.
|
4687 |
+
params<span class="ref">4</span> = array( ["LANGUAGE" => "<lang>"] [, xparam ] )
|
4688 |
+
xparam = *[ xparamkey => xparamvalue ]
|
4689 |
+
propOrderNo = int ordernumber, 1=1st, 2=2nd etc</p>
|
4690 |
+
<p class="label">Example</p>
|
4691 |
+
<p class="example">$vfreebusy->setProperty("request-status"
|
4692 |
+
, 2.0
|
4693 |
+
, "Invalid property value"
|
4694 |
+
, "DTSTART:96-Apr-31");</p>
|
4695 |
+
<br />
|
4696 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
4697 |
+
|
4698 |
+
|
4699 |
+
<a name="RESOURCES"></a><h3>3.2.34 RESOURCES</h3>
|
4700 |
+
This property defines the equipment or resources anticipated for an activity specified by a calendar entity and is OPTIONAL and MAY occur more than once in <a href="#VEVENT">VEVENT</a> and <a href="#VTODO">VTODO</a> components.<br /><br />
|
4701 |
+
The value type for RESOURCES is TEXT.
|
4702 |
+
<h5>Delete RESOURCES</h5>
|
4703 |
+
Remove RESOURCES from component.
|
4704 |
+
<p class="label">Format</p>
|
4705 |
+
<p class="format">deleteProperty( "RESOURCES" )</p>
|
4706 |
+
<p class="label">Example 1</p>
|
4707 |
+
<p class="example">$vevent->deleteProperty( "RESOURCES" );</p>
|
4708 |
+
<p class="label">Example 2</p>
|
4709 |
+
Delete RESOURCES property no 2.
|
4710 |
+
<p class="example">$vevent->deleteProperty( "RESOURCES", 2 );</p>
|
4711 |
+
<p class="label">Example 3</p>
|
4712 |
+
Deleting all RESOURCES properties.
|
4713 |
+
<p class="example">while( $vevent->deleteProperty( "RESOURCES" ))
|
4714 |
+
continue;</p>
|
4715 |
+
<h5>Get RESOURCES</h5>
|
4716 |
+
Fetch property value.
|
4717 |
+
<p class="label">Format 1</p>
|
4718 |
+
<p class="format">getProperty( "RESOURCES" )</p>
|
4719 |
+
<p class="comment">output = resources<span class="ref">1</span></p>
|
4720 |
+
<p class="label">Format 2</p>
|
4721 |
+
<p class="format">getProperty( "RESOURCES", propOrderNo/FALSE, TRUE )</p>
|
4722 |
+
<p class="comment">output = array( "value" => resources<span class="ref">1</span>
|
4723 |
+
, "params" => params<span class="ref">2</span> )</p>
|
4724 |
+
<p class="label">Format 3</p>
|
4725 |
+
<p class="format">getProperty( "RESOURCES", propOrderNo )</p>
|
4726 |
+
<p class="comment">Get propOrderNo RESOURCES</p>
|
4727 |
+
<p class="label">Example</p>
|
4728 |
+
<p class="example">$resources = $vtodo->getProperty( "RESOURCES" );</p>
|
4729 |
+
<h5>Set RESOURCES</h5>
|
4730 |
+
Insert property value.
|
4731 |
+
<br />
|
4732 |
+
Parameters, if any, will be ordered as prescribed in rcf2445.
|
4733 |
+
<p class="label">Format</p>
|
4734 |
+
<p class="format">setProperty( "resources", resources [, params [, propOrderNo ]] )</p>
|
4735 |
+
<p class="comment">resources<span class="ref">1</span> = string resource / array( *resource )
|
4736 |
+
resource = textual resources or subtypes of the calendar component,
|
4737 |
+
can be specified as a list of resources
|
4738 |
+
separated by the COMMA character.
|
4739 |
+
params<span class="ref">2</span> = array([ "ALTREP" => "<an alternate text representation, URI>"]
|
4740 |
+
[, "LANGUAGE" => "<lang>"]
|
4741 |
+
[, xparam] )
|
4742 |
+
xparam = *[ xparamkey => xparamvalue ]
|
4743 |
+
propOrderNo = int ordernumber, 1=1st, 2=2nd etc</p>
|
4744 |
+
<p class="label">Example</p>
|
4745 |
+
<p class="example">$vevent->setProperty( "resources", "COMPUTER PROJECTOR" );</p>
|
4746 |
+
<br />
|
4747 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
4748 |
+
|
4749 |
+
|
4750 |
+
<a name="RRULE"></a><h3>3.2.35 RRULE</h3>
|
4751 |
+
This property defines a rule or repeating pattern for recurring <a href="#VEVENT">EVENTs</a>, <a href="#VTODO">TODOs</a>, <a href="#VTIMEZONE">STANDARD</a> or <a href="#VTIMEZONE">DAYLIGHT</a> definitions and is OPTIONAL and MAY occur more than once.
|
4752 |
+
<h5>Delete RRULE</h5>
|
4753 |
+
Remove RRULE from component.
|
4754 |
+
<p class="label">Format</p>
|
4755 |
+
<p class="format">deleteProperty( "RRULE" )</p>
|
4756 |
+
<p class="label">Example 1</p>
|
4757 |
+
<p class="example">$vevent->deleteProperty( "RRULE" );</p>
|
4758 |
+
<p class="label">Example 2</p>
|
4759 |
+
Delete RRULE property no 2.
|
4760 |
+
<p class="example">$vevent->deleteProperty( "RRULE", 2 );</p>
|
4761 |
+
<p class="label">Example 3</p>
|
4762 |
+
Deleting all RRULE properties.
|
4763 |
+
<p class="example">while( $vevent->deleteProperty( "RRULE" ))
|
4764 |
+
continue;</p>
|
4765 |
+
<h5>Get RRULE</h5>
|
4766 |
+
Fetch property value.
|
4767 |
+
<p class="label">Format 1</p>
|
4768 |
+
<p class="format">getProperty( "RRULE" )</p>
|
4769 |
+
<p class="comment">output = recur<span class="ref">1</span></p>
|
4770 |
+
<p class="label">Format 2</p>
|
4771 |
+
<p class="format">getProperty( "RRULE", propOrderNo/FALSE, TRUE )</p>
|
4772 |
+
<p class="comment">output = array( "value" => recur<span class="ref">1</span>
|
4773 |
+
, "params" => xparams<span class="ref">2</span> )</p>
|
4774 |
+
<p class="label">Format 3</p>
|
4775 |
+
<p class="format">getProperty( "RRULE", propOrderNo )</p>
|
4776 |
+
<p class="comment">Get propOrderNo RRULE</p>
|
4777 |
+
<p class="label">Example</p>
|
4778 |
+
<p class="example">$rrules = $vtodo->getProperty( "RRULE" );</p>
|
4779 |
+
<h5>Set RRULE</h5>
|
4780 |
+
Insert property value.
|
4781 |
+
<br />
|
4782 |
+
Parameters will be ordered as prescribed in rcf2445.
|
4783 |
+
<p class="label">Format</p>
|
4784 |
+
<p class="format">setProperty( "rrule", recur [, xparams [, propOrderNo ]] )</p>
|
4785 |
+
<p>
|
4786 |
+
For rules example see <a href="#EXRULE">Exrule</a> format and in detail in RFC2445 - Internet Calendaring and Scheduling Core Object Specification (iCalendar) in <a href="http://www.kigkonsult.se/downloads/dl.php?f=rfc2445" title="RFC2445 in text format"><b>text</b></a>
|
4787 |
+
and <a href="http://www.kigkonsult.se/iCalcreator/iCalDictionary/index.html" title="RFC2445 in HTML format" target="_blank"><b>HTML</b></a> format.
|
4788 |
+
</p>
|
4789 |
+
<p class="comment">recur<span class="ref">1</span> = see <a href="#EXRULE">Exrule</a>
|
4790 |
+
xparams<span class="ref">2</span> = array( *[ xparamkey => xparamvalue ] )
|
4791 |
+
propOrderNo = int ordernumber, 1=1st, 2=2nd etc</p>
|
4792 |
+
<br />
|
4793 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
4794 |
+
|
4795 |
+
<a name="SEQUENCE"></a><h3>3.2.36 SEQUENCE</h3>
|
4796 |
+
This property defines the revision sequence number of the calendar component within a sequence of revisions.
|
4797 |
+
The property is OPTIONAL and MUST NOT occur more than once in <a href="#VEVENT">VEVENT</a>,
|
4798 |
+
<a href="#VTODO">VTODO</a> and <a href="#VJOURNAL">VJOURNAL</a> components.
|
4799 |
+
<br />
|
4800 |
+
<p class="quotes">
|
4801 |
+
It is monotonically incremented by the <a href="#ORGANIZER">ORGANIZER's</a> CUA (Calendar User Agent)
|
4802 |
+
each time the <a href="#ORGANIZER">ORGANIZER</a> makes a significant revision to the calendar component.
|
4803 |
+
When the <a href="#ORGANIZER">ORGANIZER</a> makes changes to one of the following properties, the
|
4804 |
+
sequence number MUST be incremented: <a href="#DTSTART">DTSTART</a>, <a href="#DTEND">DTEND</a>, <a href="#DUE">DUE</a>, <a href="#RDATE">RDATE</a>, <a href="#RRULE">RRULE</a>,
|
4805 |
+
<a href="#EXDATE">EXDATE</a>, <a href="#EXRULE">EXRULE</a>, <a href="#STATUS">STATUS</a>. In addition, changes made by the <a href="#ORGANIZER">ORGANIZER</a> to other
|
4806 |
+
properties can also force the sequence number to be incremented. The <a href="#ORGANIZER">ORGANIZER</a>
|
4807 |
+
CUA MUST increment the sequence number when ever it makes changes to
|
4808 |
+
properties in the calendar component that the <a href="#ORGANIZER">ORGANIZER</a> deems will jeopardize
|
4809 |
+
the validity of the participation status of the <a href="#ATTENDEE">Attendees</a>. For example, changing
|
4810 |
+
the location of a meeting from one locale to another distant locale could effectively
|
4811 |
+
impact the participation status of the <a href="#ATTENDEE">Attendees</a>.
|
4812 |
+
</p>
|
4813 |
+
<h5>Delete SEQUENCE</h5>
|
4814 |
+
Remove SEQUENCE from component.
|
4815 |
+
<p class="label">Format</p>
|
4816 |
+
<p class="format">deleteProperty( "SEQUENCE" )</p>
|
4817 |
+
<p class="label">Example</p>
|
4818 |
+
<p class="example">$vtodo->deleteProperty( "SEQUENCE" );</p>
|
4819 |
+
<h5>Get SEQUENCE</h5>
|
4820 |
+
Fetch property value.
|
4821 |
+
<p class="label">Format 1</p>
|
4822 |
+
<p class="format">getProperty( "SEQUENCE" )</p>
|
4823 |
+
<p class="comment">output = sequence<span class="ref">1</span></p>
|
4824 |
+
<p class="label">Format 2</p>
|
4825 |
+
<p class="format">getProperty( "SEQUENCE", FALSE , TRUE )</p>
|
4826 |
+
<p class="comment">output = array( "value" => sequence<span class="ref">1</span>
|
4827 |
+
, "params" => xparam<span class="ref">2</span> )</p>
|
4828 |
+
<p class="label">Example</p>
|
4829 |
+
<p class="example">$sequence = $vtodo->getProperty( "SEQUENCE" );</p>
|
4830 |
+
<h5>Set SEQUENCE</h5>
|
4831 |
+
Insert property value.
|
4832 |
+
<p class="label">Format</p>
|
4833 |
+
<p class="format">setProperty( "sequence" [, sequence [, xparam ]] )</p>
|
4834 |
+
<p class="comment">sequence<span class="ref">1</span> = Value type INTEGER
|
4835 |
+
xparam<span class="ref">2</span> = array( *[ xparamkey => xparamvalue ] )</p>
|
4836 |
+
<p class="label">Example 1</p>
|
4837 |
+
<p class="example">$vevent->setProperty( "sequence", 2 );
|
4838 |
+
<span class="comment">// set sequence number to 2</span></p>
|
4839 |
+
<p class="label">Example 2</p>
|
4840 |
+
<p class="example">$vevent->setProperty( "sequence" );
|
4841 |
+
<span class="comment">// force sequence number to be set to 1
|
4842 |
+
// or, if sequence exists, incremented by 1</span></p>
|
4843 |
+
<br />
|
4844 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
4845 |
+
|
4846 |
+
|
4847 |
+
<a name="STATUS"></a><h3>3.2.37 STATUS</h3>
|
4848 |
+
This property defines the overall status or confirmation for the calendar component. The property is OPTIONAL and MUST NOT occur more than once in <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a> and <a href="#VJOURNAL">VJOURNAL</a> components.
|
4849 |
+
<h5>Delete STATUS</h5>
|
4850 |
+
Remove STATUS from component.
|
4851 |
+
<p class="label">Format</p>
|
4852 |
+
<p class="format">deleteProperty( "STATUS" )</p>
|
4853 |
+
<p class="label">Example</p>
|
4854 |
+
<p class="example">$vtodo->deleteProperty( "STATUS" );</p>
|
4855 |
+
<h5>Get STATUS</h5>
|
4856 |
+
Fetch property value.
|
4857 |
+
<p class="label">Format 1</p>
|
4858 |
+
<p class="format">getProperty( "STATUS" )</p>
|
4859 |
+
<p class="comment">output = status<span class="ref">1</span></p>
|
4860 |
+
<p class="label">Format 2</p>
|
4861 |
+
<p class="format">getProperty( "STATUS", FALSE , TRUE )</p>
|
4862 |
+
<p class="comment">output = array( "value" => status<span class="ref">1</span>
|
4863 |
+
, "params" => xparam<span class="ref">2</span> )</p>
|
4864 |
+
<p class="label">Example</p>
|
4865 |
+
<p class="example">$status = $vtodo->getProperty( "STATUS" );</p>
|
4866 |
+
<h5>Set STATUS</h5>
|
4867 |
+
Insert property value.
|
4868 |
+
<p class="label">Format</p>
|
4869 |
+
<p class="format">setProperty( "status", status [, xparam ] )</p>
|
4870 |
+
<p class="comment"> // <span class="ref">Status values for a <a href="#vevent">VEVENT</a></span>
|
4871 |
+
status<span class="ref">1</span> = "TENTATIVE" // <span class="ref">Indicates event is tentative</span>
|
4872 |
+
/ "CONFIRMED" // <span class="ref">Indicates event is definite</span>
|
4873 |
+
/ "CANCELLED" // <span class="ref">Indicates event was cancelled</span>
|
4874 |
+
// <span class="ref">Status values for <a href="#VTODO">VTODO</a></span>
|
4875 |
+
status<span class="ref">1</span> = "NEEDS-ACTION" // <span class="ref">Indicates to-do needs action</span>
|
4876 |
+
/ "COMPLETED" // <span class="ref">Indicates to-do completed</span>
|
4877 |
+
/ "IN-PROCESS" // <span class="ref">Indicates to-do in process of</span>
|
4878 |
+
/ "CANCELLED" // <span class="ref">Indicates to-do was cancelled</span>
|
4879 |
+
// <span class="ref">Status values for <a href="#VJOURNAL">VJOURNAL</a></span>
|
4880 |
+
status<span class="ref">1</span> = "DRAFT" // <span class="ref">Indicates journal is draft</span>
|
4881 |
+
/ "FINAL" // <span class="ref">Indicates journal is final</span>
|
4882 |
+
/ "CANCELLED" // <span class="ref">Indicates journal is removed</span>
|
4883 |
+
xparam<span class="ref">2</span> = array( *[ xparamkey => xparamvalue ] )</p>
|
4884 |
+
<p class="label">Example</p>
|
4885 |
+
<p class="example">$vevent->setProperty( "Status", "COMPLETED" );</p>
|
4886 |
+
<br />
|
4887 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
4888 |
+
|
4889 |
+
|
4890 |
+
<a name="SUMMARY"></a><h3>3.2.38 SUMMARY</h3>
|
4891 |
+
This property defines a short ("one line") summary or subject for the calendar component. (In "rfc2445, Recommended Practices", up to 255 characters) (, analogous to a mail SUBJECT). The property is OPTIONAL and MUST NOT occur more than once in <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a> and <a href="#VJOURNAL">VJOURNAL</a> components. The property is REQUIRED and MUST occur once in <a href="#VALARM">VALARM</a> (EMAIL) calendar component.<br /><br />
|
4892 |
+
The value type for SUMMARY is TEXT.
|
4893 |
+
<h5>Delete SUMMARY</h5>
|
4894 |
+
Remove SUMMARY from component.
|
4895 |
+
<p class="label">Format</p>
|
4896 |
+
<p class="format">deleteProperty( "SUMMARY" )</p>
|
4897 |
+
<p class="label">Example</p>
|
4898 |
+
<p class="example">$vevent->deleteProperty( "SUMMARY" );</p>
|
4899 |
+
<h5>Get SUMMARY</h5>
|
4900 |
+
Fetch property value.
|
4901 |
+
<p class="label">Format 1</p>
|
4902 |
+
<p class="format">getProperty( "SUMMARY" )</p>
|
4903 |
+
<p class="comment">output = summary<span class="ref">1</span></p>
|
4904 |
+
<p class="label">Format 2</p>
|
4905 |
+
<p class="format">getProperty( "SUMMARY", FALSE , TRUE )</p>
|
4906 |
+
<p class="comment">output = array( "value" => summary<span class="ref">1</span>
|
4907 |
+
, "params" => params<span class="ref">2</span> )</p>
|
4908 |
+
<p class="label">Example</p>
|
4909 |
+
<p class="example">$summary = $vtodo->getProperty( "SUMMARY" );</p>
|
4910 |
+
<h5>Set SUMMARY</h5>
|
4911 |
+
Insert property value.
|
4912 |
+
<br />
|
4913 |
+
Parameters, if any, will be ordered as prescribed in rcf2445.
|
4914 |
+
<p class="label">Format</p>
|
4915 |
+
<p class="format">setProperty( "summary", summary [, params ] )</p>
|
4916 |
+
<p CLASS="comment">summary<span class="ref">1</span> = Value type TEXT,
|
4917 |
+
a short, one line summary about the activity or journal entry.
|
4918 |
+
params<span class="ref">2</span> = array( ["ALTREP" => "<an alternate text representation, URI>"]
|
4919 |
+
[, "LANGUAGE" => "<lang>"]
|
4920 |
+
[, xparam ] )
|
4921 |
+
xparam = *[ xparamkey => xparamvalue ]</p>
|
4922 |
+
<p class="label">Example</p>
|
4923 |
+
<p class="example">$vevent->setProperty( "summary", "This is a summary" );</p>
|
4924 |
+
<br />
|
4925 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
4926 |
+
|
4927 |
+
|
4928 |
+
<a name="TRANSP"></a><h3>3.2.39 TRANSP</h3>
|
4929 |
+
This property defines whether an <a href="#VEVENT">EVENT</a> is transparent or not to busy time searches and is OPTIONAL and MUST NOT occur more than once.
|
4930 |
+
<h5>Delete TRANSP</h5>
|
4931 |
+
Remove TRANSP from component.
|
4932 |
+
<p class="label">Format</p>
|
4933 |
+
<p class="format">deleteProperty( "TRANSP" )</p>
|
4934 |
+
<p class="label">Example</p>
|
4935 |
+
<p class="example">$vevent->deleteProperty( "TRANSP" );</p>
|
4936 |
+
<h5>Get TRANSP</h5>
|
4937 |
+
Fetch property value.
|
4938 |
+
<p class="label">Format 1</p>
|
4939 |
+
<p class="format">getProperty( "TRANSP" )</p>
|
4940 |
+
<p class="comment">output = transp<span class="ref">1</span></p>
|
4941 |
+
<p class="label">Format 2</p>
|
4942 |
+
<p class="format">getProperty( "TRANSP", FALSE , TRUE )</p>
|
4943 |
+
<p class="comment">output = array( "value" => transp<span class="ref">1</span>
|
4944 |
+
, "params" => xparam<span class="ref">2</span> )</p>
|
4945 |
+
<p class="label">Example</p>
|
4946 |
+
<p class="example">$transp = $vtodo->getProperty( "TRANSP" );</p>
|
4947 |
+
<h5>Set TRANSP</h5>
|
4948 |
+
Insert property value.
|
4949 |
+
<p class="label">Format</p>
|
4950 |
+
<p class="format">setProperty( "transp", transp [, xparam ] )</p>
|
4951 |
+
<p class="comment">transp<span class="ref">1</span> = "OPAQUE" / "TRANSPARENT"
|
4952 |
+
xparam<span class="ref">2</span> = array( *[ xparamkey => xparamvalue ] )</p>
|
4953 |
+
<p class="label">Example</p>
|
4954 |
+
<p class="example">$vevent->setProperty( "transp", "TRANSPARENT" );</p>
|
4955 |
+
<br />
|
4956 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
4957 |
+
|
4958 |
+
|
4959 |
+
<a name="TRIGGER"></a><h3>3.2.40 TRIGGER</h3>
|
4960 |
+
This property specifies when an <a href="#VALARM">ALARM</a> will trigger and is REQUIRED and MUST NOT occur more than once.<br /><br />
|
4961 |
+
The default value type is DURATION. The value type can be set to a DATE-TIME value type, in which case the value MUST specify an <a href="#DATE_WITH_UTC_TIME">UTC</a> formatted DATE-TIME value.
|
4962 |
+
<h5>Delete TRIGGER</h5>
|
4963 |
+
Remove TRIGGER from component.
|
4964 |
+
<p class="label">Format</p>
|
4965 |
+
<p class="format">deleteProperty( "TRIGGER" )</p>
|
4966 |
+
<p class="label">Example</p>
|
4967 |
+
<p class="example">$valarm->deleteProperty( "TRIGGER" );</p>
|
4968 |
+
<h5>Get TRIGGER</h5>
|
4969 |
+
Fetch property value.
|
4970 |
+
<p class="label">Format 1</p>
|
4971 |
+
<p class="format">getProperty( "TRIGGER" )</p>
|
4972 |
+
<p class="comment">output = duration/date</p>
|
4973 |
+
<p class="label">Format 2</p>
|
4974 |
+
<p class="format">getProperty( "TRIGGER", FALSE , TRUE )</p>
|
4975 |
+
<p class="comment">output = array( "value" => duration<span class="ref">1</span>/date<span class="ref">3</span> )
|
4976 |
+
, "params" => params<span class="ref">4</span> )
|
4977 |
+
<p class="label">Example</p>
|
4978 |
+
<p class="example">$trigger = $vtodo->getProperty( "TRIGGER" );</p>
|
4979 |
+
<h5>Set TRIGGER</h5>
|
4980 |
+
Insert property value.
|
4981 |
+
<p class="label">Format 1</p>
|
4982 |
+
<p class="format">setProperty( "trigger", duration<span class="ref">1</span> [, params<span class="ref">4</span> ] )</p>
|
4983 |
+
<p class="label">Format 2</p>
|
4984 |
+
<p class="format">setProperty( "trigger", duration<span class="ref">2</span> [, params<span class="ref">4</span> ] )</p>
|
4985 |
+
<p class="label">Format 3</p>
|
4986 |
+
<p class="format">setProperty( "trigger", date<span class="ref">3</span> [, params<span class="ref">4</span> ] )</p>
|
4987 |
+
<p class="label">Format</p>
|
4988 |
+
<p class="format">setProperty( "trigger", int year/FALSE
|
4989 |
+
, int month/FALSE
|
4990 |
+
, int day/FALSE
|
4991 |
+
[, int week/FALSE
|
4992 |
+
[, int hour/FALSE
|
4993 |
+
, int min/FALSE
|
4994 |
+
, int sec/FALSE
|
4995 |
+
[, bool relatedStart=TRUE
|
4996 |
+
[, bool before=TRUE
|
4997 |
+
[, array params<span class="ref">4</span> ]]]]] )</p>
|
4998 |
+
<p class="comment">duration<span class="ref">1</span> = array( "week" => int week
|
4999 |
+
, "relatedStart" => bool relstart
|
5000 |
+
, "before" => bool before )
|
5001 |
+
duration<span class="ref">1</span> = array( "day" => int day
|
5002 |
+
, "hour" => int hour
|
5003 |
+
, "min" => int min
|
5004 |
+
, "sec" => int sec
|
5005 |
+
, "relatedStart" => bool relstart
|
5006 |
+
, "before" => bool before )
|
5007 |
+
relatedStart = TRUE : related start (default),
|
5008 |
+
FALSE : related end
|
5009 |
+
before = TRUE : before relatedStart (default),
|
5010 |
+
FALSE : after relatedStart
|
5011 |
+
duration<span class="ref">2</span> = string dur-value = (["+"]/"-")"P"(dur-date/dur-time/dur-week)
|
5012 |
+
dur-date = dur-day [dur-time]
|
5013 |
+
dur-time = "T" (dur-hour / dur-minute / dur-second)
|
5014 |
+
dur-week = 1*DIGIT "W"
|
5015 |
+
dur-day = 1*DIGIT "D"
|
5016 |
+
dur-hour = 1*DIGIT "H" [dur-minute]
|
5017 |
+
dur-minute = 1*DIGIT "M" [dur-second]
|
5018 |
+
dur-second = 1*DIGIT "S"
|
5019 |
+
date<span class="ref">3</span> = array( "year" => int year // <span class="ref"><a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME</span>
|
5020 |
+
, "month" => int month
|
5021 |
+
, "day" => int day
|
5022 |
+
[, "hour" => int hour
|
5023 |
+
, "min" => int min
|
5024 |
+
, "sec" => int sec ])
|
5025 |
+
date<span class="ref">3</span> = array ( "timestamp" => int timestamp ) // <span class="ref"><a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME</span>
|
5026 |
+
date<span class="ref">3</span> = string datestring // <span class="ref">string date,
|
5027 |
+
acceptable by strtotime-command,
|
5028 |
+
ex. "14 august 2006 16.00.00"
|
5029 |
+
(notice <a class="ref" href="#date_restriction">date restriction</a>)</span>
|
5030 |
+
// <span class="ref"><a href="#DATE_WITH_UTC_TIME">UTC</a> DATE-TIME</span>
|
5031 |
+
params<span class="ref">4</span> = array( [[ reltype [, trigRelparam ]] / datetimeparam ]
|
5032 |
+
[, xparams ] )
|
5033 |
+
reltyp = "RELATED" => "START" (default) / "END"
|
5034 |
+
trigRelparam = "VALUE" => "DURATION"
|
5035 |
+
datetimeparam= "VALUE" => "DATE-TIME"
|
5036 |
+
xparam = *[ xparamkey => xparamvalue ]</p>
|
5037 |
+
<p class="label">Example 1</p>
|
5038 |
+
<p class="example">$valarm->setProperty( "trigger"
|
5039 |
+
, FALSE, FALSE, FALSE, FALSE, 1, 2, 3 );
|
5040 |
+
<span class="comment">// duration, 1 hour 2 min 3 sec, before start</span></p>
|
5041 |
+
<p class="label">Example 2</p>
|
5042 |
+
<p class="example">$valarm->setProperty( "trigger"
|
5043 |
+
, array ("hour"=>1,"min"=>2,"sec"=>3 );
|
5044 |
+
<span class="comment">// duration, 1 hour 2 min 3 sec, before start</span></p>
|
5045 |
+
<p class="label">Example 3</p>
|
5046 |
+
<p class="example">$valarm->setProperty( "trigger"
|
5047 |
+
, "PT1H2M3S" );
|
5048 |
+
<span class="comment">// duration, 1 hour 2 min 3 sec, before start</span></p>
|
5049 |
+
<p class="label">Example 4</p>
|
5050 |
+
<p class="example">$valarm->setProperty( "trigger"
|
5051 |
+
, FALSE, FALSE, FALSE, 1
|
5052 |
+
, FALSE, FALSE, FALSE, FALSE, FALSE );
|
5053 |
+
<span class="comment">// duration, 1 week after end</span></p>
|
5054 |
+
<p class="label">Example 5</p>
|
5055 |
+
<p class="example">$valarm->setProperty( "trigger"
|
5056 |
+
, array ( "week" => 1
|
5057 |
+
, "relatedStart" => FALSE
|
5058 |
+
, "before" => FALSE ));
|
5059 |
+
<span class="comment">// duration, 1 week after end</span></p>
|
5060 |
+
<p class="label">Example 6</p>
|
5061 |
+
<p class="example">$valarm->setProperty( "trigger"
|
5062 |
+
, "P1W"
|
5063 |
+
, array( "related" => "END" ));
|
5064 |
+
<span class="comment">// duration, 1 week after end</span></p>
|
5065 |
+
<p class="label">Example 7</p>
|
5066 |
+
<p class="example">$valarm->setProperty( "trigger"
|
5067 |
+
, array( "year" => 2007
|
5068 |
+
, "month" => 6
|
5069 |
+
, "day" => 5,
|
5070 |
+
, "hour" => 2
|
5071 |
+
, "min" => 2
|
5072 |
+
, "sec" => 3 ));</p>
|
5073 |
+
<br />
|
5074 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
5075 |
+
|
5076 |
+
|
5077 |
+
<a name="TZID"></a><h3>3.2.41 TZID</h3>
|
5078 |
+
This property specifies the text value that uniquely identifies the <a href="#VTIMEZONE">VTIMEZONE</a> calendar component and is REQUIRED, but MUST NOT occur more than once. <br /><br />
|
5079 |
+
The value type for TZID is TEXT.
|
5080 |
+
<h5>Delete TZID</h5>
|
5081 |
+
Remove TZID from component.
|
5082 |
+
<p class="label">Format</p>
|
5083 |
+
<p class="format">deleteProperty( "TZID" )</p>
|
5084 |
+
<p class="label">Example</p>
|
5085 |
+
<p class="example">$vtimezone->deleteProperty( "TZID" );</p>
|
5086 |
+
<h5>Get TZID</h5>
|
5087 |
+
Fetch property value.
|
5088 |
+
<p class="label">Format 1</p>
|
5089 |
+
<p class="format">getProperty( "TZID" )</p>
|
5090 |
+
<p class="comment">output = tzid<span class="ref">1</span></p>
|
5091 |
+
<p class="label">Format 2</p>
|
5092 |
+
<p class="format">getProperty( "TZID", FALSE , TRUE )</p>
|
5093 |
+
<p class="comment">output = array( "value" => tzid<span class="ref">1</span>
|
5094 |
+
, "params" => xparam<span class="ref">2</span> )</p>
|
5095 |
+
<p class="label">Example</p>
|
5096 |
+
<p class="example">$tzid = $vtimezone->getProperty( "TZID" );</p>
|
5097 |
+
<h5>Set TZID</h5>
|
5098 |
+
Insert property value.
|
5099 |
+
<p class="label">Format</p>
|
5100 |
+
<p class="format">setProperty( "tzid", tzid [, xparam ] )</p>
|
5101 |
+
<p class="comment">tzid<span class="ref">1</span> = Value type TEXT
|
5102 |
+
xparam<span class="ref">2</span> = array( *[ xparamkey => xparamvalue ] )</p>
|
5103 |
+
<p class="label">Example</p>
|
5104 |
+
<p class="example">$config = array( "unique_id" => "domain.com" );
|
5105 |
+
$vcalendar = new vcalendar( $config );
|
5106 |
+
$vtimezone = & $vcalendar->newComponent( 'vtimezone' );
|
5107 |
+
$vtimezone->setProperty( "tzid", "US-Eastern" );
|
5108 |
+
.. .</p>
|
5109 |
+
<br />
|
5110 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
5111 |
+
|
5112 |
+
|
5113 |
+
<a name="TZNAME"></a><h3>3.2.42 TZNAME</h3>
|
5114 |
+
This property specifies the customary designation for a <a href="#VTIMEZONE">STANDARD</a> or <a href="#VTIMEZONE">DAYLIGHT</a> description and is OPTIONAL and MAY occur more than once.<br /><br />
|
5115 |
+
The value type for TZNAME is TEXT.
|
5116 |
+
<h5>Delete TZNAME</h5>
|
5117 |
+
Remove TZNAME from component.
|
5118 |
+
<p class="label">Format</p>
|
5119 |
+
<p class="format">deleteProperty( "TZNAME" )</p>
|
5120 |
+
<p class="label">Example 1</p>
|
5121 |
+
<p class="example">$vtimezonestd->deleteProperty( "TZNAME" );</p>
|
5122 |
+
<p class="label">Example 2</p>
|
5123 |
+
Delete TZNAME property no 2.
|
5124 |
+
<p class="example">$vtimezonestd->deleteProperty( "TZNAME", 2 );</p>
|
5125 |
+
<p class="label">Example 3</p>
|
5126 |
+
Deleting all TZNAME properties.
|
5127 |
+
<p class="example">while( $vtimezonestd->deleteProperty( "TZNAME" ))
|
5128 |
+
continue;</p>
|
5129 |
+
<h5>Get TZNAME</h5>
|
5130 |
+
Fetch property value.
|
5131 |
+
<p class="label">Format 1</p>
|
5132 |
+
<p class="format">getProperty( "TZNAME" )</p>
|
5133 |
+
<p class="comment">output = tzname<span class="ref">1</span></p>
|
5134 |
+
<p class="label">Format 2</p>
|
5135 |
+
<p class="format">getProperty( "TZNAME", propOrderNo/FALSE, TRUE )</p>
|
5136 |
+
<p class="comment">output = array( "value" => tzname<span class="ref">1</span>
|
5137 |
+
, "params" => params<span class="ref">2</span> )</p>
|
5138 |
+
<p class="label">Format 3</p>
|
5139 |
+
<p class="format">getProperty( "TZNAME", propOrderNo )</p>
|
5140 |
+
<p class="comment">Get propOrderNo TZNAME</p>
|
5141 |
+
<p class="label">Example</p>
|
5142 |
+
<p class="example">$tzname = $timezonestandard->getProperty( "TZNAME" );</p>
|
5143 |
+
<h5>Set TZNAME</h5>
|
5144 |
+
Insert property value.
|
5145 |
+
<p class="label">Format</p>
|
5146 |
+
<p class="format">setProperty( "tzname", tzname [, params [, propOrderNo ]] )</p>
|
5147 |
+
<p class="comment">tzname<span class="ref">1</span> = Value type TEXT
|
5148 |
+
params<span class="ref">2</span> = array( [ "LANGUAGE" => "<lang>" ] [, xparam ] )
|
5149 |
+
xparam = *[ xparamkey => xparamvalue ]
|
5150 |
+
propOrderNo = int ordernumber, 1=1st, 2=2nd etc</p>
|
5151 |
+
<p class="label">Example</p>
|
5152 |
+
<p class="example">$config = array( "unique_id" => "domain.com" );
|
5153 |
+
$vcalendar = new vcalendar( $config );
|
5154 |
+
$vtimezone = & $vcalendar->newComponent( 'vtimezone' );
|
5155 |
+
$vtimezone->setProperty( "Tzid", "US-Eastern" );
|
5156 |
+
$vtimezone->setProperty( "Last-Modified", "19870101" );
|
5157 |
+
$standard = & $vtimezone->newComponent( "standard" );
|
5158 |
+
$standard->setProperty( "tzname", "EST" );
|
5159 |
+
.. .</p>
|
5160 |
+
<br />
|
5161 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
5162 |
+
|
5163 |
+
|
5164 |
+
<a name="TZOFFSETFROM"></a><h3>3.2.43 TZOFFSETFROM</h3>
|
5165 |
+
This property specifies the offset which is in use prior to this <a href="#VTIMEZONE">TIMEZONE</a> observance.
|
5166 |
+
The property is REQUIRED, but MUST NOT occur more than once in <a href="#VTIMEZONE">STANDARD</a> and <a href="#VTIMEZONE">DAYLIGHT</a> components.
|
5167 |
+
<h5>Delete TZOFFSETFROM</h5>
|
5168 |
+
Remove TZOFFSETFROM from component.
|
5169 |
+
<p class="label">Format</p>
|
5170 |
+
<p class="format">deleteProperty( "TZOFFSETFROM" )</p>
|
5171 |
+
<p class="label">Example</p>
|
5172 |
+
<p class="example">$vtimezonestd->deleteProperty( "TZOFFSETFROM" );</p>
|
5173 |
+
<h5>Get TZOFFSETFROM</h5>
|
5174 |
+
Fetch property value.
|
5175 |
+
<p class="label">Format 1</p>
|
5176 |
+
<p class="format">getProperty( "TZOFFSETFROM" )</p>
|
5177 |
+
<p class="comment">output = tzoffsetfrom<span class="ref">1</span></p>
|
5178 |
+
<p class="label">Format 2</p>
|
5179 |
+
<p class="format">getProperty( "TZOFFSETFROM", FALSE , TRUE )</p>
|
5180 |
+
<p class="comment">output = array( "value" => tzoffsetfrom<span class="ref">1</span>
|
5181 |
+
, "params" => xparam<span class="ref">2</span> )</p>
|
5182 |
+
<p class="label">Example</p>
|
5183 |
+
<p class="example">$tzoffsetfrom = $timezonestandard->getProperty( "TZOFFSETFROM" );</p>
|
5184 |
+
<h5>Set TZOFFSETFROM</h5>
|
5185 |
+
Insert property value.
|
5186 |
+
<p class="label">Format</p>
|
5187 |
+
<p class="format">setProperty( "tzoffsetfrom", tzoffsetfrom [, xparam ] )</p>
|
5188 |
+
<p class="comment">tzoffsetfrom<span class="ref">1</span> = (+/-)HHmm[ss], UTC offset
|
5189 |
+
xparam<span class="ref">2</span> = array( *[ xparamkey => xparamvalue ] )</p>
|
5190 |
+
<p class="label">Example</p>
|
5191 |
+
<p class="example">$config = array( "unique_id" => "domain.com" );
|
5192 |
+
$vcalendar = new vcalendar( $config );
|
5193 |
+
$vtimezone = & $vcalendar->newComponent( 'vtimezone' );
|
5194 |
+
$vtimezone->setProperty( "Tzid", "US-Eastern" );
|
5195 |
+
$vtimezone->setProperty( "Last-Modified", "19870101" );
|
5196 |
+
$standard = & $vtimezone->newComponent( "standard" );
|
5197 |
+
$standard->setProperty( "tzname", "EST" );
|
5198 |
+
$standard->setProperty( "tzoffsetfrom", "-0500" );
|
5199 |
+
.. .</p>
|
5200 |
+
<br />
|
5201 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
5202 |
+
|
5203 |
+
|
5204 |
+
<a name="TZOFFSETTO"></a><h3>3.2.44 TZOFFSETTO</h3>
|
5205 |
+
This property specifies the offset which is in use in this <a href="#VTIMEZONE">TIMEZONE</a> observance.
|
5206 |
+
The property is REQUIRED, but MUST NOT occur more than once in <a href="#VTIMEZONE">STANDARD</a> and <a href="#VTIMEZONE">DAYLIGHT</a> components.
|
5207 |
+
<h5>Delete TZOFFSETTO</h5>
|
5208 |
+
Remove TZOFFSETTO from component.
|
5209 |
+
<p class="label">Format</p>
|
5210 |
+
<p class="format">deleteProperty( "TZOFFSETTO" )</p>
|
5211 |
+
<p class="label">Example</p>
|
5212 |
+
<p class="example">$daylight->deleteProperty( "TZOFFSETTO" );</p>
|
5213 |
+
<h5>Get TZOFFSETTO</h5>
|
5214 |
+
Fetch property value.
|
5215 |
+
<p class="label">Format 1</p>
|
5216 |
+
<p class="format">getProperty( "TZOFFSETTO" )</p>
|
5217 |
+
<p class="comment">output = tzoffsetto<span class="ref">1</span></p>
|
5218 |
+
<p class="label">Format 2</p>
|
5219 |
+
<p class="format">getProperty( "TZOFFSETTO", FALSE , TRUE )</p>
|
5220 |
+
<p class="comment">output = array( "value" => tzoffsetto<span class="ref">1</span>
|
5221 |
+
, "params" => xparam<span class="ref">2</span> )</p>
|
5222 |
+
<p class="label">Example</p>
|
5223 |
+
<p class="example">$tzoffsetto = $timezonestandard->getProperty( "TZOFFSETTO" );</p>
|
5224 |
+
<h5>Set TZOFFSETTO</h5>
|
5225 |
+
Insert property value.
|
5226 |
+
<p class="label">Format</p>
|
5227 |
+
<p class="format">setproperty( "tzoffsetto", tzoffsetto [, xparam ] )</p>
|
5228 |
+
<p class="comment">tzoffsetto<span class="ref">1</span> = (+/-)HHmm[ss], UTC offset
|
5229 |
+
xparam<span class="ref">2</span> = array( *[ xparamkey => xparamvalue ] )</p>
|
5230 |
+
<p class="label">Example</p>
|
5231 |
+
<p class="example">$config = array( "unique_id" => "domain.com" );
|
5232 |
+
$vcalendar = new vcalendar( $config );
|
5233 |
+
$vtimezone = & $vcalendar->newComponent( 'vtimezone' );
|
5234 |
+
$vtimezone->setProperty( "Tzid", "US-Eastern" );
|
5235 |
+
$vtimezone->setProperty( "Last-Modified", "19870101" );
|
5236 |
+
$standard = & $vtimezone->newComponent( "standard" );
|
5237 |
+
.. .
|
5238 |
+
$daylight = & $vtimezone->newComponent( "daylight" );
|
5239 |
+
$daylight->setProperty( "tzoffsetto", "1345" );
|
5240 |
+
.. .</p>
|
5241 |
+
<br />
|
5242 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
5243 |
+
|
5244 |
+
|
5245 |
+
<a name="TZURL"></a><h3>3.2.45 TZURL</h3>
|
5246 |
+
The TZURL provides a means for a <a href="#VTIMEZONE">VTIMEZONE</a> component to point to
|
5247 |
+
a network location that can be used to retrieve an up-to-date version of itself. The property
|
5248 |
+
is OPTIONAL and MUST NOT occur more than once.
|
5249 |
+
<h5>Delete TZURL</h5>
|
5250 |
+
Remove TZURL from component.
|
5251 |
+
<p class="label">Format</p>
|
5252 |
+
<p class="format">deleteProperty( "TZURL" )</p>
|
5253 |
+
<p class="label">Example</p>
|
5254 |
+
<p class="example">$vtimezone->deleteProperty( "TZURL" );</p>
|
5255 |
+
<h5>Get TZURL</h5>
|
5256 |
+
Fetch property value.
|
5257 |
+
<p class="label">Format 1</p>
|
5258 |
+
<p class="format">getProperty( "TZURL" )</p>
|
5259 |
+
<p class="comment">output = tzurl<span class="ref">1</span></p>
|
5260 |
+
<p class="label">Format 2</p>
|
5261 |
+
<p class="format">getProperty( "TZURL", FALSE , TRUE )</p>
|
5262 |
+
<p class="comment">output = array( "value" => tzurl<span class="ref">1</span>
|
5263 |
+
, "params" => xparam<span class="ref">2</span> )</p>
|
5264 |
+
<p class="label">Example</p>
|
5265 |
+
<p class="example">$tzurl = $timezonestandard->getProperty( "TZURL" );</p>
|
5266 |
+
<h5>Set TZURL</h5>
|
5267 |
+
Insert property value.
|
5268 |
+
<p class="label">Format</p>
|
5269 |
+
<p class="format">setProperty( "tzurl", tzurl [, xparam ] )</p>
|
5270 |
+
<p class="comment">tzurl<span class="ref">1</span> = Value type URI
|
5271 |
+
xparam<span class="ref">2</span> = array( *[ xparamkey => xparamvalue ] )</p>
|
5272 |
+
<p class="label">Example</p>
|
5273 |
+
<p class="example">$tz = "http://zones.stds_r_us.net/tz/US-Eastern" );
|
5274 |
+
$config = array( "unique_id" => "domain.com" );
|
5275 |
+
$vcalendar = new vcalendar( $config );
|
5276 |
+
$vtimezone = & $vcalendar->newComponent( 'vtimezone' );
|
5277 |
+
$vtimezone->setProperty( "Tzid", "US-Eastern" );
|
5278 |
+
$vtimezone->setProperty( "Last-Modified", "19870101T000000" );
|
5279 |
+
$vtimezone->setProperty( "tzurl", $tz );
|
5280 |
+
.. .
|
5281 |
+
.. .</p>
|
5282 |
+
<br />
|
5283 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
5284 |
+
|
5285 |
+
|
5286 |
+
<a name="UID"></a><h3>3.2.46 UID</h3>
|
5287 |
+
The persistent, globally <b>U</b>nique <b>ID</b>entifier for the calendar component.
|
5288 |
+
The property is OPTIONAL and MUST NOT occur more than once in <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a>, <a href="#VJOURNAL">VJOURNAL</a> and <a href="#VFREEBUSY">VFREEBUSY</a> components.<br />
|
5289 |
+
However, UID is <b>AUTOMATICALLY</b> generated in iCalcreator and configuration <a href="#Unique_id">unique_id</a>, is used when auto-creating component UID.
|
5290 |
+
<br />
|
5291 |
+
<br />
|
5292 |
+
UID generated format :
|
5293 |
+
<p class="format">date("Ymd\THisT")."-".[microSec][random]."@".<a href="#Unique_id">unique_id</a>
|
5294 |
+
</p>
|
5295 |
+
microSec = microseconds, 4 pos<br />
|
5296 |
+
random = 6 characters aA-zZ, 0-9
|
5297 |
+
<p class="label">Example</p>
|
5298 |
+
<p class="example">"20070803T194810CEST-0123U3PXiX@domain.com"</p>
|
5299 |
+
UID may be required when importing iCal files into some calendaring software (MS etc.),
|
5300 |
+
as well as (calendar) <a href="#X-PROPERTY">x-properties</a> "X-WR-CALNAME", "X-WR-CALDESC" and "X-WR-TIMEZONE",
|
5301 |
+
<a href="#METHOD">METHOD</a> property (value PUBLISH etc.) and (also auto created) <a href="#DTSTAMP">DTSTAMP</a> property.
|
5302 |
+
<br /><br />
|
5303 |
+
The value type for UID is TEXT.
|
5304 |
+
<h5>Delete UID</h5>
|
5305 |
+
If UID is remove from a component, UID will automatically be recreated when calendar output functions like <a href="#createCalendar">createCalendar</a>, <a href="#returnCalendar">returnCalendar</a> or <a href="#saveCalendar">saveCalendar</a> is executed.
|
5306 |
+
<p class="label">Format</p>
|
5307 |
+
<p class="format">deleteProperty( "UID" )</p>
|
5308 |
+
<p class="label">Example</p>
|
5309 |
+
<p class="example">$vevent->deleteProperty( "UID" );</p>
|
5310 |
+
<h5>Get UID</h5>
|
5311 |
+
Fetch property value.
|
5312 |
+
<p class="label">Format 1</p>
|
5313 |
+
<p class="format">getProperty( "UID" )</p>
|
5314 |
+
<p class="comment">output = uid<span class="ref">1</span></p>
|
5315 |
+
<p class="label">Format 2</p>
|
5316 |
+
<p class="format">getProperty( "UID", FALSE , TRUE )</p>
|
5317 |
+
<p class="comment">output = array( "value" => uid<span class="ref">1</span>
|
5318 |
+
, "params" => xparam<span class="ref">2</span> )</p>
|
5319 |
+
<p class="label">Example</p>
|
5320 |
+
<p class="example">$uid = $vevent->getProperty( "UID" );</p>
|
5321 |
+
<h5>Set UID</h5>
|
5322 |
+
Insert property value, overrides any previously set or auto-created UID.<br />
|
5323 |
+
Do <b>NOT</b> use an integer UID or only a component name in UID (ex. "vevent"), this may cause malfunction in <a href="#setComponent">setComponent</a> with index or UID argument.
|
5324 |
+
<p class="label">Format</p>
|
5325 |
+
<p class="format">setProperty( "uid", uid [, xparam ] )</p>
|
5326 |
+
<p class="comment">uid<span class="ref">1</span> = Value type TEXT
|
5327 |
+
xparam<span class="ref">2</span> = array( *[ xparamkey => xparamvalue ] )</p>
|
5328 |
+
<p class="label">Example</p>
|
5329 |
+
<p class="example">$vevent->setProperty("uid","20070803T194810CEST-0123U3PXiX@domain.com");</p>
|
5330 |
+
<br />
|
5331 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
5332 |
+
|
5333 |
+
|
5334 |
+
<a name="URL"></a><h3>3.2.47 URL</h3>
|
5335 |
+
This property defines a Uniform Resource Locator (URL) associated with the iCalendar object.
|
5336 |
+
The property is OPTIONAL and MUST NOT occur more than once in <a href="#VEVENT">VEVENT</a>, <a href="#VTODO">VTODO</a>, <a href="#VJOURNAL">VJOURNAL</a> and <a href="#VFREEBUSY">VFREEBUSY</a> components.
|
5337 |
+
<h5>Delete URL</h5>
|
5338 |
+
Remove URL from component.
|
5339 |
+
<p class="label">Format</p>
|
5340 |
+
<p class="format">deleteProperty( "URL" )</p>
|
5341 |
+
<p class="label">Example</p>
|
5342 |
+
<p class="example">$vevent->deleteProperty( "URL" );</p>
|
5343 |
+
<h5>Get URL</h5>
|
5344 |
+
Fetch property value.
|
5345 |
+
<p class="label">Format 1</p>
|
5346 |
+
<p class="format">getProperty( "URL" )</p>
|
5347 |
+
<p class="comment">output = url<span class="ref">1</span></p>
|
5348 |
+
<p class="label">Format 2</p>
|
5349 |
+
<p class="format">getProperty( "URL", FALSE , TRUE )</p>
|
5350 |
+
<p class="comment">output = array "value" => url<span class="ref">1</span>
|
5351 |
+
, "params" => xparam<span class="ref">2</span> )</p>
|
5352 |
+
<p class="label">Example</p>
|
5353 |
+
<p class="example">$url = $vevent->getProperty( "URL" );</p>
|
5354 |
+
<h5>Set URL</h5>
|
5355 |
+
Insert property value.<br/>
|
5356 |
+
<p class="label">Format</p>
|
5357 |
+
<p class="format">setProperty( "url", url [, xparam ] )</p>
|
5358 |
+
<p class="comment">url<span class="ref">1</span> = Value type URI
|
5359 |
+
xparam<span class="ref">2</span> = array( *[ xparamkey => xparamvalue ] (</p>
|
5360 |
+
<p class="label">Example</p>
|
5361 |
+
<p class="example">$vtodo->setProperty( "url", "http://www.icaldomain.net" );</p>
|
5362 |
+
<br />
|
5363 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
5364 |
+
|
5365 |
+
|
5366 |
+
<a name="X-PROPERTY_PROP"></a><h3>3.2.48 X-PROPERTY</h3>
|
5367 |
+
A calendar, non-standard property with a TEXT value and a name with an "X-" prefix. In a calendar,
|
5368 |
+
an x-prop, with an unique name, can occur only once but the number of x-props are unlimited.
|
5369 |
+
<br />
|
5370 |
+
<h5>Delete X-PROPERTY</h5>
|
5371 |
+
Remove X-PROPERTY from component.
|
5372 |
+
<p class="label">Format</p>
|
5373 |
+
<p class="format">deleteProperty( "<X-PROPERTY>" )</p>
|
5374 |
+
<p class="label">Example 1</p>
|
5375 |
+
<p class="example">$vevent->deleteProperty( "<X-PROPERTY>" );</p>
|
5376 |
+
<p class="label">Example 2</p>
|
5377 |
+
Deleting all x-properties.
|
5378 |
+
<p class="example">while( $vevent->deleteProperty())
|
5379 |
+
continue;</p>
|
5380 |
+
<h5>Get X-property</h5>
|
5381 |
+
Fetch property value.
|
5382 |
+
<p class="label">Format 1</p>
|
5383 |
+
<p class="format">getProperty( "<X-PROPERTY>" )</p>
|
5384 |
+
<p class="comment">output = array( propertyName<span class="ref">1</span>
|
5385 |
+
, propertyData<span class="ref">2</span> )</p>
|
5386 |
+
<p class="label">Format 2</p>
|
5387 |
+
<p class="format">getProperty()</p>
|
5388 |
+
<p class="comment">output = array( propertyName<span class="ref">1</span>
|
5389 |
+
, propertyData<span class="ref">2</span> )</p>
|
5390 |
+
<p class="label">Format 3</p>
|
5391 |
+
<p class="format">getProperty( FALSE, propOrderNo/FALSE, TRUE )</p>
|
5392 |
+
<p class="comment">output = array( propertyName<span class="ref">1</span>
|
5393 |
+
, array ( "value" => propertyData<span class="ref">2</span> )
|
5394 |
+
, "params" => params<span class="ref"> 3</span>))</p>
|
5395 |
+
<p class="label">Format 4</p>
|
5396 |
+
<p class="format">getProperty( FALSE, propOrderNo )</p>
|
5397 |
+
<p class="comment">Get propOrderNo X-property</p>
|
5398 |
+
|
5399 |
+
<p class="label">Example 1</p>
|
5400 |
+
<p class="example">$config = array( "unique_id" => "domain.com",
|
5401 |
+
"filename", "file.ics" ); );
|
5402 |
+
$vcalendar = new vcalendar( $config );
|
5403 |
+
$vcalendar->parse();
|
5404 |
+
if( FALSE !== ( $d = $vcalendar->getProperty( 'X-WR-TIMEZONE' )))
|
5405 |
+
echo $d[1];
|
5406 |
+
.. .</p>
|
5407 |
+
<p class="comment"> // $xprop = array( propertyName<span class="ref">1</span>, propertyData<span class="ref">2</span> )</p>
|
5408 |
+
|
5409 |
+
<p class="label">Example 2</p>
|
5410 |
+
<p class="example">$config = array( "unique_id" => "domain.com",
|
5411 |
+
"filename", "file.ics" ); );
|
5412 |
+
$vcalendar = new vcalendar( $config );
|
5413 |
+
$vcalendar->parse();
|
5414 |
+
while( $xprop = $vcalendar->getProperty( )) {
|
5415 |
+
.. .</p>
|
5416 |
+
<p class="comment"> // $xprop = array( propertyName<span class="ref">1</span>, propertyData<span class="ref">2</span> )</p>
|
5417 |
+
|
5418 |
+
<p class="label">Example 3</p>
|
5419 |
+
<p class="example">$config = array( "unique_id" => "domain.com",
|
5420 |
+
"filename", "file.ics" ); );
|
5421 |
+
$vcalendar = new vcalendar( $config );
|
5422 |
+
$vcalendar->parse();
|
5423 |
+
while( $xprop = $vcalendar->getProperty( "X-ABC-MMSUBJ" )) {
|
5424 |
+
.. .</p>
|
5425 |
+
<p class="comment"> // $xprop = array( "X-ABC-MMSUBJ", propertyData<span class="ref">2</span> )</p>
|
5426 |
+
<p class="label">Example 4</p>
|
5427 |
+
<p class="example">$config = array( "unique_id" => "domain.com",
|
5428 |
+
"filename", "file.ics" ); );
|
5429 |
+
$vcalendar = new vcalendar( $config );
|
5430 |
+
$vcalendar->parse();
|
5431 |
+
while( $xprop = $vcalendar->getProperty( FALSE, FALSE, TRUE )) {
|
5432 |
+
.. .</p>
|
5433 |
+
<p class="comment"> // $xprop = array( propertyName<span class="ref">1</span>
|
5434 |
+
// , array( "value" => propertyData<span class="ref">2</span> )
|
5435 |
+
// , "params" => params<span class="ref"> 3</span> )</p>
|
5436 |
+
<h5>Set X-property</h5>
|
5437 |
+
Insert property name and value. If an x-prop with the same name already exists, it will be replaced.
|
5438 |
+
<p class="label">Format</p>
|
5439 |
+
<p class="format">setProperty( propertyName, propertyData [, params ] )</p>
|
5440 |
+
<p class="comment">propertyName<span class="ref">1</span> = Any property name with a "X-" prefix
|
5441 |
+
propertyData<span class="ref">2</span> = Value type TEXT
|
5442 |
+
params<span class="ref">3</span> = array( ["LANGUAGE" => "<lang>"] [, xparam] )
|
5443 |
+
xparam = *[ xparamkey => xparamvalue ]</p>
|
5444 |
+
propOrderNo = int ordernumber, 1=1st, 2=2nd etc</p>
|
5445 |
+
<p class="label">Example</p>
|
5446 |
+
<p class="example">$component->setProperty("X-ABC-MMSUBJ","http://load.noise.org/mysubj.wav");</p>
|
5447 |
+
<br />
|
5448 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_object_property_function_list">[up]</a>
|
5449 |
+
|
5450 |
+
|
5451 |
+
|
5452 |
+
<a NAME="Calendar_component_configuration_functions"></a><h2>3.3 Calendar Component configuration functions</h2>
|
5453 |
+
|
5454 |
+
<a name="Language_PROP"></a><h3>3.3.1 Language</h3>
|
5455 |
+
Language for specific calendar component as defined in [RFC 1766].<br />
|
5456 |
+
Language set at component level can be overridden by specific component property parameter.<br />
|
5457 |
+
A successful "setConfig" returns TRUE.
|
5458 |
+
<h5>Get language</h5>
|
5459 |
+
Language for calendar (only if language is set at component level).
|
5460 |
+
<p class="label">Format</p>
|
5461 |
+
<p class="format">getConfig( "language" )</p>
|
5462 |
+
<p class="label">Example</p>
|
5463 |
+
<p class="example">$lang = $vevent->getConfig( "language" );</p>
|
5464 |
+
<h5>Set LANGUAGE</h5>
|
5465 |
+
<p class="label">Format</p>
|
5466 |
+
<p class="format">setConfig( "language", string <lang> )</p>
|
5467 |
+
<p class="label">Example</p>
|
5468 |
+
<p class="example">$vevent->setConfig( "language", "en" );</p>
|
5469 |
+
<br />
|
5470 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_configuration_functions">[up]</a>
|
5471 |
+
|
5472 |
+
<a name="Calendar_component_object_misc_functions"></a><h2>3.4 Calendar component object misc. functions</h2>
|
5473 |
+
Calendar component subcomponent functions
|
5474 |
+
|
5475 |
+
<a name="deleteComponent_PROP"></a><h4>3.4.1 deleteComponent</h4>
|
5476 |
+
Remove subcomponent from component.
|
5477 |
+
<p class="label">Format</p>
|
5478 |
+
<p class="format">deleteComponent( int orderNumber )</p>
|
5479 |
+
<p class="comment">Remove component with order number (1st=1, 2nd=2.. .).</p>
|
5480 |
+
<p class="format">deleteComponent( string componentType [, int componentSuborderNumber])</p>
|
5481 |
+
<p class="comment">Remove component with component type (ex. "vevent")
|
5482 |
+
and order 1 alt. suborder number.</p>
|
5483 |
+
<p class="format">deleteComponent( string <a href="#UID">UID</a> )</p>
|
5484 |
+
<p class="comment">Remove component with <a href="#UID">UID</a>.
|
5485 |
+
N.B <a href="#UID">UID</a> is NOT set for <a href="#VALARM">ALARM</a> / <a href="#VTIMEZONE">timezone</a> components.</p>
|
5486 |
+
<p class="label">Example 1</p>
|
5487 |
+
Delete first subcomponent.
|
5488 |
+
<p class="example">$config = array( "unique_id" => "domain.com",
|
5489 |
+
"filename", "file.ics" ); );
|
5490 |
+
$vcalendar = new vcalendar( $config );
|
5491 |
+
$vcalendar->parse();
|
5492 |
+
$comp1 = $vcalendar->getComponent();
|
5493 |
+
$comp1->deleteComponent( 1 );
|
5494 |
+
.. .</p>
|
5495 |
+
<p class="label">Example 2</p>
|
5496 |
+
Delete all subcomponents.
|
5497 |
+
<p class="example">$config = array( "unique_id" => "domain.com",
|
5498 |
+
"filename", "file.ics" ); );
|
5499 |
+
$vcalendar = new vcalendar( $config );
|
5500 |
+
$vcalendar->parse();
|
5501 |
+
$comp1 = $vcalendar->getComponent();
|
5502 |
+
while( $comp1->deleteComponent( 'valarm' )
|
5503 |
+
continue;
|
5504 |
+
.. .</p>
|
5505 |
+
<br />
|
5506 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_configuration_functions">[up]</a>
|
5507 |
+
|
5508 |
+
<a name="getComponent_PROP"></a><h4>3.4.2 getComponent</h4>
|
5509 |
+
Get subComponent from component.
|
5510 |
+
<p class="label">Format 1</p>
|
5511 |
+
<p class="format">getComponent()</p>
|
5512 |
+
<p class="comment">Get next component until end-of-components.</p>
|
5513 |
+
<p class="label">Format 2</p>
|
5514 |
+
<p class="format">getComponent( int orderNumber )</p>
|
5515 |
+
<p class="comment">Get component with order number (1st=1, 2nd=2.. .).</p>
|
5516 |
+
<p class="label">Format 3</p>
|
5517 |
+
<p class="format">getComponent( string componentType [, int componentSuborderNumber])</p>
|
5518 |
+
<p class="comment">Get (next) component with component type (until end-of-components)
|
5519 |
+
alt. component with component type and suborder number (1st=1, 2nd=2..).</p>
|
5520 |
+
<p class="label">Format 4</p>
|
5521 |
+
<p class="format">getComponent( string <a href="#UID">UID</a> )</p>
|
5522 |
+
<p class="comment">Get component with <a href="#UID">UID</a>.
|
5523 |
+
N.B <a href="#UID">UID</a> is NOT set for <a href="#VALARM">ALARM</a> / <a href="#VTIMEZONE">timezone</a> components.</p>
|
5524 |
+
<p class="label">Example</p>
|
5525 |
+
<p class="example">$config = array( "unique_id" => "domain.com",
|
5526 |
+
"filename", "file.ics" ); );
|
5527 |
+
$vcalendar = new vcalendar( $config );
|
5528 |
+
$vcalendar->parse();
|
5529 |
+
$comp1 = $vcalendar->getComponent());
|
5530 |
+
while( $subComp = $comp1->getComponent()) {
|
5531 |
+
.. .</p>
|
5532 |
+
<br />
|
5533 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_configuration_functions">[up]</a>
|
5534 |
+
|
5535 |
+
<a name="newComponent"></a><h4>3.4.3 newComponent</h4>
|
5536 |
+
Create subcomponent (<a href="#VALARM">ALARN</a> / <a href="#VTIMEZONE">VTIMEZONE STANDARD</a> / <a href="#VTIMEZONE">VTIMEZONE DAYLIGHT</a>)
|
5537 |
+
using a component factory-method, returning a reference to the new component.
|
5538 |
+
<p class="label">Format</p>
|
5539 |
+
<p class="format">newComponent( string componentType )</p>
|
5540 |
+
<p class="label">Example 1</p>
|
5541 |
+
<p class="example">$config = array( 'unique_id' => 'domain.org' );
|
5542 |
+
$vcalendar = new vcalendar( $config );
|
5543 |
+
...
|
5544 |
+
$vevent = & $vcalendar->newComponent( 'vevent' );
|
5545 |
+
$vevent->setProperty( "dtstart" // <span class="ref">add some <a href="#VEVENT">EVENT</a> properties</span>
|
5546 |
+
, 2006, 12, 24, 19, 30, 00 );
|
5547 |
+
$vevent->setProperty(.. .
|
5548 |
+
...
|
5549 |
+
$valarm = & $vevent->newComponent( 'valarm' );
|
5550 |
+
$valarm->setProperty( "trigger", .. .
|
5551 |
+
...
|
5552 |
+
</p>
|
5553 |
+
<p class="label">Example 2</p>
|
5554 |
+
<p class="example">$config = array( 'unique_id' => 'domain.org' );
|
5555 |
+
$vcalendar = new vcalendar( $config );
|
5556 |
+
...
|
5557 |
+
$vtimezone = & $vcalendar->newComponent( 'vtimezone' );
|
5558 |
+
$vtimezone->setProperty(.. .
|
5559 |
+
...
|
5560 |
+
$standard = & $vtimezone->newComponent( 'standard' );
|
5561 |
+
$standard->setProperty(.. .
|
5562 |
+
...
|
5563 |
+
$daylight = & $vtimezone->newComponent( 'daylight' );
|
5564 |
+
$daylight->setProperty(.. .
|
5565 |
+
...
|
5566 |
+
</p>
|
5567 |
+
|
5568 |
+
<br />
|
5569 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_configuration_functions">[up]</a>
|
5570 |
+
|
5571 |
+
<a name="setComponent_PROP"></a><h4>3.4.4 setComponent</h4>
|
5572 |
+
Add calendar component to calendar or replace/update component in calendar.
|
5573 |
+
<p class="label">Format 1</p>
|
5574 |
+
<p class="format">setComponent( component )
|
5575 |
+
addSubComponent( component ) // <span class="ref">alias</span></p>
|
5576 |
+
<p class="comment">Insert last in component chain.</p>
|
5577 |
+
<p class="label">Format 2</p>
|
5578 |
+
<p class="format">setComponent( component, int orderNumber )</p>
|
5579 |
+
<p class="comment">Replace component with order number(1st=1, 2nd=2.. .).
|
5580 |
+
If orderNumber is not found, component is inserted last in chain.</p>
|
5581 |
+
<p class="label">Format 3</p>
|
5582 |
+
<p class="format">setComponent( component, string componentType [,component suborder number])</p>
|
5583 |
+
<p class="comment">Replace component with component type and component order number.
|
5584 |
+
if orderNumber is not found, component is inserted last in chain. </p>
|
5585 |
+
<p class="label">Example</p>
|
5586 |
+
<p class="example">$config = array( "unique_id" => "domain.com" );
|
5587 |
+
$vcalendar = new vcalendar( $config ); // <span class="ref">initiate new CALENDAR</span>
|
5588 |
+
.. .
|
5589 |
+
$vevent = new vevent();
|
5590 |
+
$vevent->setProperty( "dtstart" // <span class="ref">add some <a href="#VEVENT">EVENT</a> properties</span>
|
5591 |
+
, 2006, 12, 24, 19, 30, 00 );
|
5592 |
+
$vevent->setProperty(.. .
|
5593 |
+
.. .
|
5594 |
+
$valarm = new valarm();
|
5595 |
+
$valarm->setProperty( "trigger", .. .
|
5596 |
+
.. .
|
5597 |
+
$vevent->setComponent( $valarm );
|
5598 |
+
$vcalendar->setComponent( $vevent );
|
5599 |
+
.. .
|
5600 |
+
</p>
|
5601 |
+
<br />
|
5602 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a> <a href="#Calendar_component_configuration_functions">[up]</a>
|
5603 |
+
|
5604 |
+
<a name="iCalUtilityFunctions"></a><h1>4. iCalUtilityFunctions</a></h1>
|
5605 |
+
iCalUtilityFunctions.class.php contains static functions used by iCalcreator,
|
5606 |
+
also usable outside the iCalcreator class. Only function createTimezone is described here,
|
5607 |
+
please examine the class file for other functions.
|
5608 |
+
<br />
|
5609 |
+
<br />
|
5610 |
+
<a name="createTimezone"></a><h4>4.1 createTimezone</a></h4>
|
5611 |
+
The function, applied on a iCalcrator instance (as argument) creates very simple
|
5612 |
+
vtimezone and standard/daylight components. (PHP 5 >= 5.2.0)
|
5613 |
+
<p class="label">Format</p>
|
5614 |
+
<p class="format">createTimezone( calendar, timezone [, xprops ] )</p>
|
5615 |
+
<p class="comment">calendar = iCalcreator instance
|
5616 |
+
timezone = an PHP (DateTimeZone) valid timezone
|
5617 |
+
xprops = array( *[ x-propName => value ] ), timezone non-standard properties
|
5618 |
+
</p>
|
5619 |
+
<p class="label">Example</p>
|
5620 |
+
<p class="example">$config = array( "unique_id" => "domain.com" );
|
5621 |
+
$vcalendar = new vcalendar( $config );
|
5622 |
+
.. .
|
5623 |
+
$PHPtz = 'Europe/Stockholm';
|
5624 |
+
$xprops = array( 'X-LIC-LOCATION' => $PHPtz );
|
5625 |
+
iCalUtilityFunctions::createTimezone( $vcalendar,
|
5626 |
+
$PHPtz,
|
5627 |
+
$xprops );
|
5628 |
+
.. .
|
5629 |
+
</p>
|
5630 |
+
Output (from createCalendar or returnCalendar functions):<br />
|
5631 |
+
<span class="ref">
|
5632 |
+
BEGIN:VTIMEZONE<br />
|
5633 |
+
TZID:Europe/Stockholm<br />
|
5634 |
+
X-LIC-LOCATION:Europe/Stockholm<br />
|
5635 |
+
BEGIN:STANDARD<br />
|
5636 |
+
DTSTART:20101031T020000<br />
|
5637 |
+
TZOFFSETFROM:+0200<br />
|
5638 |
+
TZOFFSETTO:+0100<br />
|
5639 |
+
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10<br />
|
5640 |
+
TZNAME:CET<br />
|
5641 |
+
END:STANDARD<br />
|
5642 |
+
BEGIN:DAYLIGHT<br />
|
5643 |
+
DTSTART:20100328T030000<br />
|
5644 |
+
TZOFFSETFROM:+0100<br />
|
5645 |
+
TZOFFSETTO:+0200<br />
|
5646 |
+
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3<br />
|
5647 |
+
TZNAME:CEST<br />
|
5648 |
+
END:DAYLIGHT<br />
|
5649 |
+
END:VTIMEZONE
|
5650 |
+
</span>
|
5651 |
+
<br />
|
5652 |
+
<br />
|
5653 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a>
|
5654 |
+
|
5655 |
+
|
5656 |
+
<a name="Copyright_and_Licence"></a><h1>5. COPYRIGHT AND LICENSE</h1>
|
5657 |
+
<h2>Copyright</h2>
|
5658 |
+
iCalcreator class <br />
|
5659 |
+
copyright (c) 2007-2011 Kjell-Inge Gustafsson, kigkonsult<br />
|
5660 |
+
www.kigkonsult.Se/iCalcreator/index.php<br />
|
5661 |
+
ical@kigkonsult.se<br />
|
5662 |
+
|
5663 |
+
<h2>License</h2>
|
5664 |
+
|
5665 |
+
This library is free software; you can redistribute it and/or
|
5666 |
+
modify it under the terms of the GNU Lesser General Public
|
5667 |
+
License as published by the Free Software Foundation; either
|
5668 |
+
version 2.1 of the License, or (at your option) any later version.
|
5669 |
+
<br /><br />
|
5670 |
+
This library is distributed in the hope that it will be useful,
|
5671 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
5672 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
5673 |
+
Lesser General Public License for more details.
|
5674 |
+
<br /><br />
|
5675 |
+
You should have received a copy of the GNU Lesser General Public
|
5676 |
+
License along with this library; if not, write to the Free Software
|
5677 |
+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
5678 |
+
or download it <a href="http://www.kigkonsult.se/downloads/dl.php?f=LGPL">here</a>.
|
5679 |
+
<br />
|
5680 |
+
<br />
|
5681 |
+
<a href="#INDEX">[index]</a> <a href="#top">[top]</a>
|
5682 |
+
</body>
|
5683 |
+
</html>
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_i
|
|
4 |
Tags: calendar, event, events, ics, ics calendar, ical-feed, ics feed, wordpress ics importer, wordpress ical importer, upcoming events, todo, notes, journal, freebusy, availability, web calendar, web events, webcal, google calendar, ical, iCalendar, all-in-one, ai1ec, google calendar sync, ical sync, events sync, holiday calendar, calendar 2011, events 2011, widget, events widget, upcoming events widget, calendar widget, agenda widget
|
5 |
Requires at least: 3.1.3
|
6 |
Tested up to: 3.3
|
7 |
-
Stable tag: 1.2.
|
8 |
|
9 |
An event calendar system with month, week, agenda views, upcoming events widget, color-coded categories, recurrence, and import/export of .ics feeds.
|
10 |
|
@@ -57,6 +57,9 @@ The All-in-One Event Calendar Plugin also has a few features that will prove use
|
|
57 |
* [**Get Premium Support »**](http://theseednetwork.com/get-supported) from [The Seed Studio](http://theseednetwork.com/)
|
58 |
|
59 |
== Changelog ==
|
|
|
|
|
|
|
60 |
= Version 1.2.3 =
|
61 |
* Improvement: Days of the week in month recurrence [#170](http://trac.the-seed.ca/ticket/170)
|
62 |
* Improvement: Make Month view, Week view compatible with touchscreen devices [#210](http://trac.the-seed.ca/ticket/210)
|
4 |
Tags: calendar, event, events, ics, ics calendar, ical-feed, ics feed, wordpress ics importer, wordpress ical importer, upcoming events, todo, notes, journal, freebusy, availability, web calendar, web events, webcal, google calendar, ical, iCalendar, all-in-one, ai1ec, google calendar sync, ical sync, events sync, holiday calendar, calendar 2011, events 2011, widget, events widget, upcoming events widget, calendar widget, agenda widget
|
5 |
Requires at least: 3.1.3
|
6 |
Tested up to: 3.3
|
7 |
+
Stable tag: 1.2.4
|
8 |
|
9 |
An event calendar system with month, week, agenda views, upcoming events widget, color-coded categories, recurrence, and import/export of .ics feeds.
|
10 |
|
57 |
* [**Get Premium Support »**](http://theseednetwork.com/get-supported) from [The Seed Studio](http://theseednetwork.com/)
|
58 |
|
59 |
== Changelog ==
|
60 |
+
= Version 1.2.4 =
|
61 |
+
* Improvement: Added a lower version of iCalcreator for environments with PHP versions below 5.3.0
|
62 |
+
|
63 |
= Version 1.2.3 =
|
64 |
* Improvement: Days of the week in month recurrence [#170](http://trac.the-seed.ca/ticket/170)
|
65 |
* Improvement: Make Month view, Week view compatible with touchscreen devices [#210](http://trac.the-seed.ca/ticket/210)
|