mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-30 18:49:08 +01:00
04e778c065
again. I've also implimented more of rfc2445. I will continue to beat these classes into shape as I add more ical stuff and document what I have reverse engineered. Once I am satisfied that this is stable and production worthy I will probably backport this to the 1.0 branch. My casual testing has shown that this for the most part works as expected. I also plan on developing test harnesses for ical import/export.
3603 lines
84 KiB
PHP
Executable File
3603 lines
84 KiB
PHP
Executable File
<?php
|
||
/**************************************************************************\
|
||
* eGroupWare - iCalendar Parser *
|
||
* http://www.egroupware.org *
|
||
* Written by Mark Peters <skeeter@phpgroupware.org> *
|
||
* -------------------------------------------- *
|
||
* This program is free software; you can redistribute it and/or modify it *
|
||
* under the terms of the GNU General Public License as published by the *
|
||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||
* option) any later version. *
|
||
\**************************************************************************/
|
||
|
||
/* $Id$ */
|
||
|
||
define('FOLD_LENGTH',75);
|
||
|
||
define('VEVENT',1);
|
||
define('VTODO',2);
|
||
|
||
define('NONE',0);
|
||
define('CHAIR',1);
|
||
define('REQ_PARTICIPANT',2);
|
||
define('OPT_PARTICIPANT',3);
|
||
define('NON_PARTICIPANT',4);
|
||
|
||
define('INDIVIDUAL',1);
|
||
define('GROUP',2);
|
||
define('RESOURCE',4);
|
||
define('ROOM',8);
|
||
define('UNKNOWN',16);
|
||
|
||
/* event status */
|
||
define('NEEDS_ACTION',0);
|
||
define('ACCEPTED',1);
|
||
define('DECLINED',2);
|
||
define('TENTATIVE',3);
|
||
define('DELEGATED',4);
|
||
define('COMPLETED',5);
|
||
define('IN_PROCESS',6);
|
||
|
||
/* class */
|
||
define('PRIVATE',0);
|
||
define('PUBLIC',1);
|
||
define('CONFIDENTIAL',3);
|
||
|
||
/* transparency */
|
||
define('TRANSPARENT',0);
|
||
define('OPAQUE',1);
|
||
|
||
/* frequency */
|
||
define('SECONDLY',1);
|
||
define('MINUTELY',2);
|
||
define('HOURLY',3);
|
||
define('DAILY',4);
|
||
define('WEEKLY',5);
|
||
define('MONTHLY',6);
|
||
define('YEARLY',7);
|
||
|
||
define('FREE',0);
|
||
define('BUSY',1);
|
||
define('BUSY_UNAVAILABLE',2);
|
||
define('BUSY_TENTATIVE',3);
|
||
|
||
define('THISANDPRIOR',0);
|
||
define('THISANDFUTURE',1);
|
||
|
||
define('START',0);
|
||
define('END',1);
|
||
|
||
define('_8BIT',0);
|
||
define('_BASE64',1);
|
||
|
||
define('OTHER',99);
|
||
|
||
class boicalendar
|
||
{
|
||
var $public_functions = array(
|
||
'import' => True,
|
||
'export' => True,
|
||
'freebusy' => True,
|
||
);
|
||
|
||
var $ical;
|
||
var $line = 0;
|
||
var $event = Array();
|
||
var $todo = Array();
|
||
var $journal = Array();
|
||
var $freebusy = Array();
|
||
var $timezone = Array();
|
||
var $property = Array();
|
||
var $parameter = Array();
|
||
var $debug_str = False;
|
||
var $api = True;
|
||
var $chunk_split = True;
|
||
|
||
/*
|
||
* Base Functions
|
||
*/
|
||
|
||
function boicalendar()
|
||
{
|
||
$this->property = Array(
|
||
'action' => Array(
|
||
'type' => 'text',
|
||
'to_text' => True,
|
||
'valarm' => Array(
|
||
'state' => 'required',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'attach' => Array(
|
||
'type' => 'uri',
|
||
'to_text' => True,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'valarm' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
)
|
||
),
|
||
'attendee' => Array(
|
||
'type' => 'cal-address',
|
||
'to_text' => False,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'valarm' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'vfreebusy' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
)
|
||
),
|
||
'categories' => Array(
|
||
'type' => 'text',
|
||
'to_text' => True,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
)
|
||
),
|
||
'class' => Array(
|
||
'type' => 'text',
|
||
'to_text' => True,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'comment' => Array(
|
||
'type' => 'text',
|
||
'to_text' => True,
|
||
'daylight' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'standard' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'valarm' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'vfreebusy' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
)
|
||
),
|
||
'completed' => Array(
|
||
'type' => 'date-time',
|
||
'to_text' => False,
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'contact' => Array(
|
||
'type' => 'text',
|
||
'to_text' => True,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'vfreebusy' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
)
|
||
),
|
||
'created' => Array(
|
||
'type' => 'date-time',
|
||
'to_text' => False,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'description' => Array(
|
||
'type' => 'text',
|
||
'to_text' => True,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'valarm' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'dtend' => Array(
|
||
'type' => 'date-time',
|
||
'to_text' => False,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vfreebusy' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'dtstamp' => Array(
|
||
'type' => 'date-time',
|
||
'to_text' => False,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'vfreebusy' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'dtstart' => Array(
|
||
'type' => 'date-time',
|
||
'to_text' => False,
|
||
'daylight' => Array(
|
||
'state' => 'required',
|
||
'multiples' => False
|
||
),
|
||
'standard' => Array(
|
||
'state' => 'required',
|
||
'multiples' => False
|
||
),
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vfreebusy' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'due' => Array(
|
||
'type' => 'date-time',
|
||
'to_text' => False,
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'duration' => Array(
|
||
'type' => 'duration',
|
||
'to_text' => False,
|
||
'valarm' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vfreebusy' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'exdate' => Array(
|
||
'type' => 'date-time',
|
||
'to_text' => False,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
)
|
||
),
|
||
'exrule' => Array(
|
||
'type' => 'recur',
|
||
'to_text' => False,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
)
|
||
),
|
||
'freebusy' => Array(
|
||
'type' => 'freebusy',
|
||
'to_text' => False,
|
||
'vfreebusy' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
)
|
||
),
|
||
'geo' => Array(
|
||
'type' => 'float',
|
||
'to_text' => True,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'last_modified' => Array(
|
||
'type' => 'date-time',
|
||
'to_text' => False,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vtimezone' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'location' => Array(
|
||
'type' => 'text',
|
||
'to_text' => True,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'method' => Array(
|
||
'type' => 'text',
|
||
'to_text' => True,
|
||
'ical' => Array(
|
||
'state' => 'required',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'organizer' => Array(
|
||
'type' => 'cal-address',
|
||
'to_text' => False,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vfreebusy' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'percent_complete' => Array(
|
||
'type' => 'integer',
|
||
'to_text' => False,
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'priority' => Array(
|
||
'type' => 'integer',
|
||
'to_text' => True,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'prodid' => Array(
|
||
'type' => 'text',
|
||
'to_text' => True,
|
||
'ical' => Array(
|
||
'state' => 'required',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'rdate' => Array(
|
||
'type' => 'date-time',
|
||
'to_text' => False,
|
||
'daylight' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'standard' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
)
|
||
),
|
||
'recurrence_id' => Array(
|
||
'type' => 'date-time',
|
||
'to_text' => False,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'related_to' => Array(
|
||
'type' => 'text',
|
||
'to_text' => False,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
)
|
||
),
|
||
'request_status' => Array(
|
||
'type' => 'text',
|
||
'to_text' => True,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'vfreebusy' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
)
|
||
),
|
||
'resources' => Array(
|
||
'type' => 'text',
|
||
'to_text' => False,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'rrule' => Array(
|
||
'type' => 'recur',
|
||
'to_text' => False,
|
||
'daylight' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'standard' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'sequence' => Array(
|
||
'type' => 'integer',
|
||
'to_text' => True,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'status' => Array(
|
||
'type' => 'text',
|
||
'to_text' => True,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'summary' => Array(
|
||
'type' => 'text',
|
||
'to_text' => True,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'valarm' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'transp' => Array(
|
||
'type' => 'text',
|
||
'to_text' => True,
|
||
'vevent' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'trigger' => Array(
|
||
'type' => 'text',
|
||
'to_text' => True,
|
||
'valarm' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'tzid' => Array(
|
||
'type' => 'text',
|
||
'to_text' => True,
|
||
'vtimezone' => Array(
|
||
'state' => 'required',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'tzname' => Array(
|
||
'type' => 'text',
|
||
'to_text' => True,
|
||
'daylight' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
),
|
||
'standard' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => True
|
||
)
|
||
),
|
||
'tzoffsetfrom' => Array(
|
||
'type' => 'utc-offset',
|
||
'to_text' => True,
|
||
'daylight' => Array(
|
||
'state' => 'required',
|
||
'multiples' => False
|
||
),
|
||
'standard' => Array(
|
||
'state' => 'required',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'tzoffsetto' => Array(
|
||
'type' => 'utc-offset',
|
||
'to_text' => True,
|
||
'daylight' => Array(
|
||
'state' => 'required',
|
||
'multiples' => False
|
||
),
|
||
'standard' => Array(
|
||
'state' => 'required',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'tzurl' => Array(
|
||
'type' => 'uri',
|
||
'to_text' => True,
|
||
'vtimezone' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'uid' => Array(
|
||
'type' => 'text',
|
||
'to_text' => True,
|
||
'vevent' => Array(
|
||
'state' => 'required',
|
||
'multiples' => False
|
||
),
|
||
'vfreebusy' => Array(
|
||
'state' => 'required',
|
||
'multiples' => False
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'required',
|
||
'multiples' => False
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'required',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'url' => Array(
|
||
'type' => 'text',
|
||
'to_text' => True,
|
||
'vevent' => Array(
|
||
'state' => 'required',
|
||
'multiples' => False
|
||
),
|
||
'vfreebusy' => Array(
|
||
'state' => 'required',
|
||
'multiples' => False
|
||
),
|
||
'vjournal' => Array(
|
||
'state' => 'optional',
|
||
'multiples' => False
|
||
),
|
||
'vtodo' => Array(
|
||
'state' => 'required',
|
||
'multiples' => False
|
||
)
|
||
),
|
||
'version' => Array(
|
||
'type' => 'text',
|
||
'to_text' => True,
|
||
'ical' => Array(
|
||
'state' => 'required',
|
||
'multiples' => False
|
||
)
|
||
)
|
||
);
|
||
$this->parameter = Array(
|
||
'altrep' => Array(
|
||
'type' => 'uri',
|
||
'quoted' => True,
|
||
'to_text' => True,
|
||
'properties' => Array(
|
||
'comment' => True,
|
||
'description' => True,
|
||
'location' => True,
|
||
'prodid' => True,
|
||
'resources' => True,
|
||
'summary' => True,
|
||
'contact' => True
|
||
)
|
||
),
|
||
'byday' => Array(
|
||
'type' => 'text',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'rrule' => True
|
||
)
|
||
),
|
||
'byhour' => Array(
|
||
'type' => 'text',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'rrule' => True
|
||
)
|
||
),
|
||
'byminute' => Array(
|
||
'type' => 'text',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'rrule' => True
|
||
)
|
||
),
|
||
'bymonth' => Array(
|
||
'type' => 'text',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'rrule' => True
|
||
)
|
||
),
|
||
'bymonthday' => Array(
|
||
'type' => 'text',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'rrule' => True
|
||
)
|
||
),
|
||
'bysecond' => Array(
|
||
'type' => 'text',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'rrule' => True
|
||
)
|
||
),
|
||
'bysetpos' => Array(
|
||
'type' => 'text',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'rrule' => True
|
||
)
|
||
),
|
||
'byweekno' => Array(
|
||
'type' => 'text',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'rrule' => True
|
||
)
|
||
),
|
||
'byyearday' => Array(
|
||
'type' => 'text',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'rrule' => True
|
||
)
|
||
),
|
||
'class' => Array(
|
||
'type' => 'function',
|
||
'function' => 'switch_class',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'class' => True
|
||
)
|
||
),
|
||
'cn' => Array(
|
||
'type' => 'text',
|
||
'quoted' => True,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'attendee' => True,
|
||
'organizer' => True
|
||
)
|
||
),
|
||
'count' => Array(
|
||
'type' => 'integer',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'rrule' => True
|
||
)
|
||
),
|
||
'cu' => Array(
|
||
'type' => 'function',
|
||
'function' => 'switch_cu',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'attendee' => True
|
||
)
|
||
),
|
||
'delegated_from' => Array(
|
||
'type' => 'function',
|
||
'function' => 'switch_mailto',
|
||
'quoted' => True,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'attendee' => True
|
||
)
|
||
),
|
||
'delegated_to' => Array(
|
||
'type' => 'function',
|
||
'function' => 'switch_mailto',
|
||
'quoted' => True,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'attendee' => True
|
||
)
|
||
),
|
||
'dir' => Array(
|
||
'type' => 'dir',
|
||
'quoted' => True,
|
||
'to_text' => True,
|
||
'properties' => Array(
|
||
'attendee' => True,
|
||
'organizer' => True
|
||
)
|
||
),
|
||
'dtend' => Array(
|
||
'type' => 'function',
|
||
'function' => 'switch_date',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'dtend' => True
|
||
)
|
||
),
|
||
'dtstamp' => Array(
|
||
'type' => 'function',
|
||
'function' => 'switch_date',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'dtstamp' => True
|
||
)
|
||
),
|
||
'dtstart' => Array(
|
||
'type' => 'function',
|
||
'function' => 'switch_date',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'dtstart' => True
|
||
)
|
||
),
|
||
'encoding' => Array(
|
||
'type' => 'function',
|
||
'function' => 'switch_encoding',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'attach' => True
|
||
)
|
||
),
|
||
'fmttype' => Array(
|
||
'type' => 'text',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'attach' => True
|
||
)
|
||
),
|
||
'fbtype' => Array(
|
||
'type' => 'function',
|
||
'function' => 'switch_fbtype',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'attach' => True
|
||
)
|
||
),
|
||
'freq' => Array(
|
||
'type' => 'function',
|
||
'function' => 'switch_freq',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'rrule' => True
|
||
)
|
||
),
|
||
'interval' => Array(
|
||
'type' => 'integer',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'rrule' => True
|
||
)
|
||
),
|
||
'language' => Array(
|
||
'type' => 'text',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'categories' => True,
|
||
'comment' => True,
|
||
'description' => True,
|
||
'location' => True,
|
||
'resources' => True,
|
||
'summary' => True,
|
||
'tzname' => True,
|
||
'attendee' => True,
|
||
'contact' => True,
|
||
'organizer' => True,
|
||
'x-type' => True
|
||
)
|
||
),
|
||
'last_modified' => Array(
|
||
'type' => 'function',
|
||
'function' => 'switch_date',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'last_modified' => True
|
||
)
|
||
),
|
||
'mailto' => Array(
|
||
'type' => 'function',
|
||
'function' => 'switch_mailto',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'attendee' => True,
|
||
'organizer' => True
|
||
)
|
||
),
|
||
'member' => Array(
|
||
'type' => 'function',
|
||
'function' => 'switch_mailto',
|
||
'quoted' => True,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'attendee' => True
|
||
)
|
||
),
|
||
'partstat' => Array(
|
||
'type' => 'function',
|
||
'function' => 'switch_partstat',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'attendee' => True,
|
||
'organizer' => True
|
||
)
|
||
),
|
||
'range' => Array(
|
||
'type' => 'function',
|
||
'function' => 'switch_range',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'recurrence_id' => True
|
||
)
|
||
),
|
||
'related' => Array(
|
||
'type' => 'function',
|
||
'function' => 'switch_related',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'related_to' => True
|
||
)
|
||
),
|
||
'role' => Array(
|
||
'type' => 'function',
|
||
'function' => 'switch_role',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'attendee' => True,
|
||
'organizer' => True
|
||
)
|
||
),
|
||
'rsvp' => Array(
|
||
'type' => 'function',
|
||
'function' => 'switch_rsvp',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'attendee' => True
|
||
)
|
||
),
|
||
'sent_by' => Array(
|
||
'type' => 'function',
|
||
'function' => 'switch_mailto',
|
||
'quoted' => True,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'attendee' => True,
|
||
'organizer' => True
|
||
)
|
||
),
|
||
'tzid' => Array(
|
||
'type' => 'text',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'dtend' => True,
|
||
'due' => True,
|
||
'dtstart' => True,
|
||
'exdate' => True,
|
||
'rdate' => True,
|
||
'recurrence_id' => True
|
||
)
|
||
),
|
||
'until' => Array(
|
||
'type' => 'function',
|
||
'function' => 'switch_date',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'rrule' => True
|
||
)
|
||
),
|
||
'value' => Array(
|
||
'type' => 'value',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'calscale' => True,
|
||
'prodid' => True,
|
||
'method' => True,
|
||
'version' => True,
|
||
'attach' => True,
|
||
'categories' => True,
|
||
'class' => True,
|
||
'comment' => True,
|
||
'description' => True,
|
||
'geo' => True,
|
||
'location' => True,
|
||
'percent' => True,
|
||
'priority' => True,
|
||
'resources' => True,
|
||
'status' => True,
|
||
'summary' => True,
|
||
'completed' => True,
|
||
'dtend' => True,
|
||
'due' => True,
|
||
'dtstart' => True,
|
||
'duration' => True,
|
||
'freebusy' => True,
|
||
'transp' => True,
|
||
'tzid' => True,
|
||
'tzname' => True,
|
||
'tzoffsetfrom' => True,
|
||
'tzoffsetto' => True,
|
||
'tzurl' => True,
|
||
'attendee' => True,
|
||
'contact' => True,
|
||
'organizer' => True,
|
||
'recurrence_id' => True,
|
||
'url' => True,
|
||
'uid' => True,
|
||
'exdate' => True,
|
||
'exrule' => True,
|
||
'rdate' => True,
|
||
'rrule' => True,
|
||
'action' => True,
|
||
'repeat' => True,
|
||
'trigger' => True,
|
||
'created' => True,
|
||
'dtstamp' => True,
|
||
'last_modified' => True,
|
||
'sequence' => True,
|
||
'x_type' => True,
|
||
'request_status'=> True
|
||
)
|
||
),
|
||
'wkst' => Array(
|
||
'type' => 'string',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'rrule' => True
|
||
)
|
||
),
|
||
'x_type' => Array(
|
||
'type' => 'x_type',
|
||
'quoted' => False,
|
||
'to_text' => False,
|
||
'properties' => Array(
|
||
'calscale' => True,
|
||
'method' => True,
|
||
'prodid' => True,
|
||
'version' => True,
|
||
'attach' => True,
|
||
'categories' => True,
|
||
'class' => True,
|
||
'comment' => True,
|
||
'description' => True,
|
||
'geo' => True,
|
||
'location' => True,
|
||
'percent' => True,
|
||
'priority' => True,
|
||
'resources' => True,
|
||
'status' => True,
|
||
'summary' => True,
|
||
'completed' => True,
|
||
'dtend' => True,
|
||
'due' => True,
|
||
'dtstart' => True,
|
||
'duration' => True,
|
||
'freebusy' => True,
|
||
'transp' => True,
|
||
'tzid' => True,
|
||
'tzname' => True,
|
||
'tzoffsetfrom' => True,
|
||
'tzoffsetto' => True,
|
||
'tzurl' => True,
|
||
'attendee' => True,
|
||
'contact' => True,
|
||
'organizer' => True,
|
||
'recurrence_id' => True,
|
||
'url' => True,
|
||
'uid' => True,
|
||
'exdate' => True,
|
||
'exrule' => True,
|
||
'rdate' => True,
|
||
'rrule' => True,
|
||
'action' => True,
|
||
'repeat' => True,
|
||
'trigger' => True,
|
||
'created' => True,
|
||
'dtstamp' => True,
|
||
'last_modified' => True,
|
||
'sequence' => True,
|
||
'x_type' => True,
|
||
'request_status'=> True
|
||
)
|
||
)
|
||
);
|
||
if(!is_object($GLOBALS['phpgw']->datetime))
|
||
{
|
||
$GLOBALS['phpgw']->datetime = createobject('phpgwapi.datetime');
|
||
}
|
||
}
|
||
|
||
function set_var(&$event,$type,$value)
|
||
{
|
||
$type = strtolower(str_replace('-','_',$type));
|
||
$event[$type] = $value;
|
||
if(is_string($value))
|
||
{
|
||
$this->debug("Setting ".$type." = ".$value);
|
||
}
|
||
else
|
||
{
|
||
$this->debug("Setting ".$type." = "._debug_array($value,False));
|
||
}
|
||
}
|
||
|
||
function read_line_unfold($ical_text)
|
||
{
|
||
if($this->line < count($ical_text))
|
||
{
|
||
$str = str_replace("\r\n",'',$ical_text[$this->line]);
|
||
$this->line = $this->line + 1;
|
||
while(ereg("^[[:space:]]",$ical_text[$this->line]))
|
||
{
|
||
$str .= substr(str_replace("\r\n",'',$ical_text[$this->line]),1);
|
||
$this->line = $this->line + 1;
|
||
}
|
||
$this->debug("LINE : ".$str);
|
||
return $str;
|
||
}
|
||
else
|
||
{
|
||
return False;
|
||
}
|
||
}
|
||
|
||
function fold($str)
|
||
{
|
||
return $this->chunk_split==True ? chunk_split($str,FOLD_LENGTH,"\r\n") : $str."\r\n";
|
||
}
|
||
|
||
function strip_quotes($str)
|
||
{
|
||
return str_replace('"','',$str);
|
||
}
|
||
|
||
function from_text($str)
|
||
{
|
||
$str = str_replace("\\,",",",$str);
|
||
$str = str_replace("\\;",";",$str);
|
||
$str = str_replace("\\N","\n",$str);
|
||
$str = str_replace("\\n","\n",$str);
|
||
$str = str_replace("\\\\","\\",$str);
|
||
return "$str";
|
||
}
|
||
|
||
function to_text($str)
|
||
{
|
||
$str = str_replace("\\","\\\\",$str);
|
||
$str = str_replace(",","\\,",$str);
|
||
$str = str_replace(";","\\;",$str);
|
||
$str = str_replace("\n","\\n",$str);
|
||
return "$str";
|
||
}
|
||
|
||
function from_dir($str)
|
||
{
|
||
return str_replace('=3D','=',str_replace('%20',' ',$str));
|
||
}
|
||
|
||
function to_dir($str)
|
||
{
|
||
return str_replace('=','=3D',str_replace(' ','%20',$str));
|
||
}
|
||
|
||
function find_parameters($property)
|
||
{
|
||
static $cached_returns;
|
||
|
||
if(isset($cached_returns[$property]))
|
||
{
|
||
reset($cached_returns[$property]);
|
||
return $cached_returns[$property];
|
||
}
|
||
|
||
reset($this->parameter);
|
||
while(list($key,$param_array) = each($this->parameter))
|
||
{
|
||
if($param_array['properties'][$property])
|
||
{
|
||
$param[] = $key;
|
||
$this->debug('Property : '.$property.' = Parameter : '.$key);
|
||
}
|
||
}
|
||
reset($param);
|
||
$cached_returns[$property] = $param;
|
||
return $param;
|
||
}
|
||
|
||
function find_properties($ical_type)
|
||
{
|
||
static $cached_returns;
|
||
|
||
if(isset($cached_returns[$ical_type]))
|
||
{
|
||
reset($cached_returns[$ical_type]);
|
||
return $cached_returns[$ical_type];
|
||
}
|
||
|
||
reset($this->property);
|
||
while(list($key,$param_array) = each($this->property))
|
||
{
|
||
if($param_array[$ical_type])
|
||
{
|
||
$prop[] = $key;
|
||
}
|
||
}
|
||
reset($prop);
|
||
$cached_returns[$ical_type] = $prop;
|
||
return $prop;
|
||
}
|
||
|
||
function new_ical()
|
||
{
|
||
return Array();
|
||
}
|
||
|
||
/*
|
||
* Parse Functions
|
||
*/
|
||
|
||
function parse_geo(&$event,$value)
|
||
{
|
||
if(count($return_value) == 2)
|
||
{
|
||
$event['lat'] = $return_value[0];
|
||
$event['lon'] = $return_value[1];
|
||
}
|
||
}
|
||
|
||
function parse_xtype(&$event,$majortype,$value)
|
||
{
|
||
$temp_x_type['name'] = strtoupper(substr($majortype,2));
|
||
$temp_x_type['value'] = $value;
|
||
$event['x_type'][] = $temp_x_type;
|
||
}
|
||
|
||
function parse_parameters(&$event,$majortype,$value)
|
||
{
|
||
if(!ereg('[\=\;]',$value))
|
||
{
|
||
$return_value[] = Array(
|
||
'param' => $majortype,
|
||
'value' => $value
|
||
);
|
||
$value = '';
|
||
}
|
||
elseif(ereg('(.*(\:\\\\)?.*):(.*)',$value,$temp))
|
||
{
|
||
$this->debug('Value : '._debug_array($temp,False));
|
||
$this->debug('Param '.$majortype.' Value : '.$temp[3]);
|
||
if($temp[3])
|
||
{
|
||
$return_value[] = Array(
|
||
'param' => $majortype,
|
||
'value' => $temp[3]
|
||
);
|
||
$value = str_replace(':MAILTO','',$temp[1]);
|
||
}
|
||
while(ereg('(([A-Z\-]*)[=]([[:alnum:] \_\)\(\/\$\.\,\:\\\|\*\&\^\%\#\!\~\"\?\&\@\<\>\-]*))([\;]?)(.*)',$value,$temp))
|
||
{
|
||
$this->debug('Value : '._debug_array($temp,False));
|
||
$this->debug('Param '.$temp[2].' Value : '.$temp[3]);
|
||
$return_value[] = Array(
|
||
'param' => $temp[2],
|
||
'value' => $temp[3]
|
||
);
|
||
$value = chop($temp[5]);
|
||
$this->debug('Value would be = '.$value);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
while(ereg('(([A-Z\-]*)[=]([[:alnum:] \_\)\(\/\$\.\,\:\\\|\*\&\^\%\#\!\~\"\?\&\@\<\>\-]*))([\;]?)(.*)',$value,$temp))
|
||
{
|
||
$this->debug('Value : '._debug_array($temp,False));
|
||
$this->debug('Param '.$temp[2].' Value : '.$temp[3]);
|
||
$return_value[] = Array(
|
||
'param' => $temp[2],
|
||
'value' => $temp[3]
|
||
);
|
||
$value = chop($temp[5]);
|
||
$this->debug('Value would be = '.$value);
|
||
}
|
||
}
|
||
|
||
for($i=0;$i<count($return_value);$i++)
|
||
{
|
||
$name = strtolower($return_value[$i]['param']);
|
||
$value = $this->strip_quotes($return_value[$i]['value']);
|
||
if(substr($name,0,2) == 'x-')
|
||
{
|
||
$param = 'x_type';
|
||
$name = str_replace('-','_',$return_value[$i]['param']);
|
||
}
|
||
else
|
||
{
|
||
$param = str_replace('-','_',strtolower($name));
|
||
if(!isset($this->parameter[$param]) || $majortype == 'tzid')
|
||
{
|
||
if($majortype == 'attendee' || $majortype == 'organizer')
|
||
{
|
||
$param = 'mailto';
|
||
$name = $param;
|
||
}
|
||
else
|
||
{
|
||
$param = 'value';
|
||
}
|
||
}
|
||
}
|
||
$this->debug('name : '.$name.' : Param = '.$param);
|
||
if(@$this->parameter[$param]['properties'][$majortype])
|
||
{
|
||
switch(@$this->parameter[$param]['type'])
|
||
{
|
||
case 'dir':
|
||
$this->set_var($event,$name,$this->from_dir($value));
|
||
break;
|
||
case 'text':
|
||
$this->set_var($event,$name,$value);
|
||
break;
|
||
case 'x_type':
|
||
$this->parse_xtype($event,$name,$value);
|
||
break;
|
||
case 'function':
|
||
$function = $this->parameter[$param]['function'];
|
||
$this->set_var($event,$name,$this->$function($value));
|
||
break;
|
||
case 'uri':
|
||
if(@$this->parameter[$param]['to_text'])
|
||
{
|
||
$value = $this->to_text($value);
|
||
}
|
||
$this->set_var($event,$name,$value);
|
||
break;
|
||
case 'integer':
|
||
$this->set_var($event,$name,(int)$value);
|
||
break;
|
||
case 'value':
|
||
if(@$this->property[$majortype]['type'] == 'date-time')
|
||
{
|
||
$this->set_var($event,$param,$this->switch_date($name));
|
||
}
|
||
elseif($value <> "\\n" && $value)
|
||
{
|
||
$this->set_var($event[$majortype],$param,$value);
|
||
}
|
||
$this->debug('Event : '._debug_array($event,False));
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function parse_value(&$event,$majortype,$value,$mode)
|
||
{
|
||
$var = Array();
|
||
$this->debug('Mode : '.$mode.' Majortype : '.$majortype);
|
||
$this->parse_parameters($var,$majortype,$value);
|
||
if($this->property[$majortype][$mode]['multiples'])
|
||
{
|
||
$this->debug(_debug_array($var,False));
|
||
$event[$majortype][] = $var;
|
||
}
|
||
else
|
||
{
|
||
$this->debug('Majortype : '.$majortype);
|
||
$this->debug('Property : '.$this->property[$majortype]['type']);
|
||
if($this->property[$majortype]['type'] == 'date-time')
|
||
{
|
||
$this->debug('Got a DATE-TIME type!');
|
||
$t_var = $var[$majortype];
|
||
unset($var[$majortype]);
|
||
@reset($t_var);
|
||
while(list($key,$val) = @each($t_var))
|
||
{
|
||
$var[$key] = $val;
|
||
}
|
||
$this->debug($majortype.' : '._debug_array($var,False));
|
||
}
|
||
$this->set_var($event,$majortype,$var);
|
||
}
|
||
}
|
||
|
||
/*
|
||
* Build-Card Functions
|
||
*/
|
||
|
||
function build_xtype($x_type,$seperator='=')
|
||
{
|
||
$quote = '';
|
||
if($seperator == '=')
|
||
{
|
||
$quote = '"';
|
||
}
|
||
|
||
$return_value = $this->fold('X-'.$x_type['name'].$seperator.$quote.$x_type['value'].$quote);
|
||
if($seperator == '=')
|
||
{
|
||
return str_replace("\r\n",'',$return_value);
|
||
}
|
||
else
|
||
{
|
||
return $return_value;
|
||
}
|
||
}
|
||
|
||
function build_parameters($event,$property)
|
||
{
|
||
$str = '';
|
||
$include_mailto = False;
|
||
$include_datetime = False;
|
||
$param = $this->find_parameters($property);
|
||
|
||
if($property == 'exdate')
|
||
{
|
||
while(list($key,$value) = each($event))
|
||
{
|
||
$exdates[] = $this->switch_date($value);
|
||
}
|
||
return ':'.implode($exdates,',');
|
||
}
|
||
else
|
||
{
|
||
while(list($dumb_key,$key) = each($param))
|
||
{
|
||
if($key == 'value')
|
||
{
|
||
continue;
|
||
}
|
||
if($key == 'mailto')
|
||
{
|
||
$include_mailto = True;
|
||
continue;
|
||
}
|
||
$param_array = @$this->parameter[$key];
|
||
$type = @$this->parameter[$key]['type'];
|
||
if($type == 'date-time')
|
||
{
|
||
$include_datetime = True;
|
||
continue;
|
||
}
|
||
$quote = (@$this->parameter[$key]['quoted']?'"':'');
|
||
if(isset($event[$key]) && @$this->parameter[$key]['properties'][$property])
|
||
{
|
||
$change_text = @$this->parameter[$key]['to_text'];
|
||
$value = $event[$key];
|
||
if($change_text && $type == 'text')
|
||
{
|
||
$value = $this->to_text($value);
|
||
}
|
||
switch($type)
|
||
{
|
||
case 'dir':
|
||
$str .= ';'.str_replace('_','-',strtoupper($key)).'='.$quote.$this->to_dir($value).$quote;
|
||
break;
|
||
case 'function':
|
||
$str .= ';'.str_replace('_','-',strtoupper($key)).'=';
|
||
$function = $this->parameter[$key]['function'];
|
||
$this->debug($key.' Function Param : '.$value);
|
||
$str .= $quote.$this->$function($value).$quote;
|
||
break;
|
||
case 'text':
|
||
case 'string':
|
||
$str .= ';'.strtoupper($key).'='.$quote.$value.$quote;
|
||
break;
|
||
case 'date-time':
|
||
$str .= ($key=='until'?':':';UNTIL=').date('Ymd\THis',mktime($event['hour'],$event['min'],$event['sec'],$event['month'],$event['mday'],$event['year'])).(!@isset($event['tzid'])?'Z':'');
|
||
break;
|
||
}
|
||
unset($value);
|
||
}
|
||
}
|
||
|
||
if(!empty($event['x_type']))
|
||
{
|
||
$c_x_type = count($event['x_type']);
|
||
for($j=0;$j<$c_x_type;$j++)
|
||
{
|
||
$str .= ';'.$this->build_xtype($event['x_type'][$j],'=');
|
||
}
|
||
}
|
||
if(!empty($event['value']))
|
||
{
|
||
if($property == 'trigger')
|
||
{
|
||
$seperator = ';';
|
||
}
|
||
else
|
||
{
|
||
$seperator = ':';
|
||
}
|
||
$str .= $seperator.($this->parameter['value']['to_text']?$this->to_text($event['value']):$event['value']);
|
||
}
|
||
if($include_mailto == True)
|
||
{
|
||
$key = 'mailto';
|
||
$function = $this->parameter[$key]['function'];
|
||
$ret_value = $this->$function($event[$key]);
|
||
$str .= ($ret_value?':'.$ret_value:'');
|
||
}
|
||
if($include_datetime == True || @$this->property[$property]['type'] == 'date-time')
|
||
{
|
||
$str .= ':'.date('Ymd\THis',mktime($event['hour'],$event['min'],$event['sec'],$event['month'],$event['mday'],$event['year'])).(!@isset($event['tzid'])?'Z':'');
|
||
}
|
||
return ($property=='rrule'?':'.substr($str,1):$str);
|
||
}
|
||
}
|
||
|
||
function build_text($event,$property)
|
||
{
|
||
$str = '';
|
||
$param = $this->find_parameters($property);
|
||
while(list($dumb_key,$key) = each($param))
|
||
{
|
||
if(!empty($event[$key]) && $key != 'value')
|
||
{
|
||
$type = @$this->parameter[$key]['type'];
|
||
$quote = @$this->parameter[$key]['quote'];
|
||
if(@$this->parameter[$key]['to_text'] == True)
|
||
{
|
||
$value = $this->to_text($event[$key]);
|
||
}
|
||
else
|
||
{
|
||
$value = $event[$key];
|
||
}
|
||
switch($type)
|
||
{
|
||
case 'text':
|
||
$str .= ';'.strtoupper($key).'='.$quote.$value.$quote;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if(!empty($event['x_type']))
|
||
{
|
||
$c_x_type = count($event['x_type']);
|
||
for($j=0;$j<$c_x_type;$j++)
|
||
{
|
||
$str .= ';'.$this->build_xtype($event['x_type'][$j],'=');
|
||
}
|
||
}
|
||
if(!empty($event['value']))
|
||
{
|
||
$str .= ':'.($this->parameter['value']['to_text']?$this->to_text($event['value']):$event['value']);
|
||
}
|
||
return $str;
|
||
}
|
||
|
||
function build_card_internals($ical_item,$event)
|
||
{
|
||
$prop = $this->find_properties($ical_item);
|
||
reset($prop);
|
||
while(list($dumb_key,$key) = each($prop))
|
||
{
|
||
$value = $key;
|
||
$varray = $this->property[$key];
|
||
$type = $varray['type'];
|
||
$to_text = $varray['to_text'];
|
||
$state = @$varray[$ical_item]['state'];
|
||
$multiples = @$varray[$ical_item]['multiples'];
|
||
switch($type)
|
||
{
|
||
case 'date-time':
|
||
if(!empty($event[$value]))
|
||
{
|
||
if($multiples && $value != 'exdate')
|
||
{
|
||
for($i=0;$i<count($event[$value]);$i++)
|
||
{
|
||
$str .= $this->fold(strtoupper(str_replace('_','-',$value)).$this->build_parameters($event[$value][$i],$value));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
$str .= $this->fold(strtoupper(str_replace('_','-',$value)).$this->build_parameters($event[$value],$value));
|
||
}
|
||
}
|
||
elseif($value == 'dtstamp' || $value == 'created')
|
||
{
|
||
$str .= $this->fold(strtoupper(str_replace('_','-',$value)).':'.gmdate('Ymd\THis\Z'));
|
||
}
|
||
break;
|
||
case 'uri':
|
||
if(!empty($event[$value]))
|
||
{
|
||
for($i=0;$i<count($event[$value]);$i++)
|
||
{
|
||
$str .= $this->fold(strtoupper(str_replace('_','-',$value)).$this->build_parameters($event[$value][$i],$to_text));
|
||
}
|
||
}
|
||
break;
|
||
case 'recur':
|
||
if(!empty($event[$value]))
|
||
{
|
||
if($multiples)
|
||
{
|
||
for($i=0;$i<count($event[$value]);$i++)
|
||
{
|
||
$str .= $this->fold(strtoupper(str_replace('_','-',$value)).$this->build_parameters($event[$value][$i],$value));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
$str .= $this->fold(strtoupper(str_replace('_','-',$value)).$this->build_parameters($event[$value],$value));
|
||
}
|
||
}
|
||
break;
|
||
case 'integer':
|
||
if(!empty($event[$value]))
|
||
{
|
||
$str .= $this->fold(strtoupper(str_replace('_','-',$value)).':'.$event[$value]);
|
||
}
|
||
elseif($value == 'sequence' || $value == 'percent_complete')
|
||
{
|
||
$str .= $this->fold(strtoupper(str_replace('_','-',$value)).':0');
|
||
}
|
||
break;
|
||
case 'function':
|
||
$str .= ';'.str_replace('_','-',strtoupper($value)).'=';
|
||
$function = @$this->parameter[$key]['function'];
|
||
$str .= (@$this->parameter[$key]['quoted']?'"':'').$this->$function($event[$key]).(@$this->parameter[$key]['quoted']?'"':'');
|
||
break;
|
||
case 'float':
|
||
if(!empty($event[$value]))
|
||
{
|
||
$str .= $this->fold(strtoupper(str_replace('_','-',$value)).':'.$event[$value]['lat'].';'.$event[$value]['lon']);
|
||
}
|
||
break;
|
||
case 'text':
|
||
if(isset($event[$value]))
|
||
{
|
||
if(@$this->parameter[$key]['type'] != 'function')
|
||
{
|
||
if($multiples && count($event[$value]) > 1)
|
||
{
|
||
for($i=0;$i<count($event[$value]);$i++)
|
||
{
|
||
$str .= $this->fold(strtoupper(str_replace('_','-',$value)).$this->build_parameters($event[$value][$i],$value));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
$str .= $this->fold(strtoupper(str_replace('_','-',$value)).$this->build_parameters($event[$value],$value));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
$function = $this->parameter[$value]['function'];
|
||
if($multiples)
|
||
{
|
||
for($i=0;$i<count($event[$value]);$i++)
|
||
{
|
||
$str .= $this->fold(strtoupper(str_replace('_','-',$value)).':'.$this->$function($event[$value][$i]));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
$str .= $this->fold(strtoupper(str_replace('_','-',$value)).':'.$this->$function($event[$value]));
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case 'cal-address':
|
||
if(is_array($event[$value][0]))
|
||
{
|
||
for($j=0;$j<count($event[$value]);$j++)
|
||
{
|
||
$temp_output = $this->build_parameters($event[$value][$j],$value);
|
||
if($temp_output)
|
||
{
|
||
$str .= $this->fold(strtoupper(str_replace('_','-',$value)).$temp_output);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
$temp_output = $this->build_parameters($event[$value],$value);
|
||
if($temp_output)
|
||
{
|
||
$str .= $this->fold(strtoupper(str_replace('_','-',$value)).$temp_output);
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
if(!empty($event['x_type']))
|
||
{
|
||
for($i=0;$i<count($event['x_type']);$i++)
|
||
{
|
||
$str .= $this->build_xtype($event['x_type'][$i],':');
|
||
}
|
||
}
|
||
|
||
if($ical_item == 'vtimezone')
|
||
{
|
||
if($event['tzdata'])
|
||
{
|
||
for($k=0;$k<count($event['tzdata']);$k++)
|
||
{
|
||
$str .= 'BEGIN:'.strtoupper($event['tzdata'][$k]['type'])."\r\n";
|
||
$str .= $this->build_card_internals(strtolower($event['tzdata'][$k]['type']),$event['tzdata'][$k]);
|
||
$str .= 'END:'.strtoupper($event['tzdata'][$k]['type'])."\r\n";
|
||
}
|
||
}
|
||
}
|
||
elseif($event['alarm'])
|
||
{
|
||
for($k=0;$k<count($event['alarm']);$k++)
|
||
{
|
||
$str .= 'BEGIN:VALARM'."\r\n";
|
||
$str .= $this->build_card_internals('valarm',$event['alarm'][$k]);
|
||
$str .= 'END:VALARM'."\r\n";
|
||
}
|
||
}
|
||
return $str;
|
||
}
|
||
|
||
/*
|
||
* Switching Functions
|
||
*/
|
||
|
||
function switch_class($var)
|
||
{
|
||
if(is_string($var))
|
||
{
|
||
switch($var)
|
||
{
|
||
case 'PRIVATE':
|
||
return PRIVATE;
|
||
break;
|
||
case 'PUBLIC':
|
||
return PUBLIC;
|
||
break;
|
||
case 'CONFIDENTIAL':
|
||
return CONFIDENTIAL;
|
||
break;
|
||
}
|
||
}
|
||
elseif(is_int($var))
|
||
{
|
||
switch((int)$var)
|
||
{
|
||
case PRIVATE:
|
||
return 'PRIVATE';
|
||
break;
|
||
case PUBLIC:
|
||
return 'PUBLIC';
|
||
break;
|
||
case CONFIDENTIAL:
|
||
return 'CONFIDENTIAL';
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return $var;
|
||
}
|
||
}
|
||
|
||
function switch_cu($var)
|
||
{
|
||
if(gettype($var) == 'string')
|
||
{
|
||
switch($var)
|
||
{
|
||
case 'INDIVIDUAL':
|
||
return INDIVIDUAL;
|
||
break;
|
||
case 'GROUP':
|
||
return GROUP;
|
||
break;
|
||
case 'RESOURCE':
|
||
return RESOURCE;
|
||
break;
|
||
case 'ROOM':
|
||
return ROOM;
|
||
break;
|
||
case 'UNKNOWN':
|
||
return UNKNOWN;
|
||
break;
|
||
default:
|
||
return OTHER;
|
||
break;
|
||
}
|
||
}
|
||
elseif(gettype($var) == 'integer')
|
||
{
|
||
switch($var)
|
||
{
|
||
case INDIVIDUAL:
|
||
return 'INDIVIDUAL';
|
||
break;
|
||
case GROUP:
|
||
return 'GROUP';
|
||
break;
|
||
case RESOURCE:
|
||
return 'RESOURCE';
|
||
break;
|
||
case ROOM:
|
||
return 'ROOM';
|
||
break;
|
||
case UNKNOWN:
|
||
return 'UNKNOWN';
|
||
break;
|
||
default:
|
||
return 'X-OTHER';
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return $var;
|
||
}
|
||
}
|
||
|
||
function switch_date($var)
|
||
{
|
||
$this->debug('SWITCH_DATE: gettype = '.gettype($var));
|
||
if(is_string($var))
|
||
{
|
||
$dtime = Array();
|
||
if(strpos($var,':'))
|
||
{
|
||
$pos = explode(':',$var);
|
||
$var = $pos[1];
|
||
}
|
||
$this->set_var($dtime,'year',(int)(substr($var,0,4)));
|
||
$this->set_var($dtime,'month',(int)(substr($var,4,2)));
|
||
$this->set_var($dtime,'mday',(int)(substr($var,6,2)));
|
||
if(substr($var,8,1) == 'T')
|
||
{
|
||
$this->set_var($dtime,'hour',(int)(substr($var,9,2)));
|
||
$this->set_var($dtime,'min',(int)(substr($var,11,2)));
|
||
$this->set_var($dtime,'sec',(int)(substr($var,13,2)));
|
||
if(strlen($var) > 14)
|
||
{
|
||
if(substr($var,14,1) != 'Z')
|
||
{
|
||
if($this->api)
|
||
{
|
||
$dtime['hour'] -= $GLOBALS['phpgw_info']['users']['common']['tz_offset'];
|
||
if($dtime['hour'] < 0)
|
||
{
|
||
$dtime['mday'] -= 1;
|
||
$dtime['hour'] = 24 - $dtime['hour'];
|
||
}
|
||
elseif($dtime['hour'] >= 24)
|
||
{
|
||
$dtime['mday'] += 1;
|
||
$dtime['hour'] = $dtime['hour'] - 24;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
$this->set_var($dtime,'hour',0);
|
||
$this->set_var($dtime,'min',0);
|
||
$this->set_var($dtime,'sec',0);
|
||
if($this->api)
|
||
{
|
||
$dtime['hour'] -= $GLOBALS['phpgw_info']['users']['common']['tz_offset'];
|
||
if($dtime['hour'] < 0)
|
||
{
|
||
$dtime['mday'] -= 1;
|
||
$dtime['hour'] = 24 - $dtime['hour'];
|
||
}
|
||
elseif($dtime['hour'] >= 24)
|
||
{
|
||
$dtime['mday'] += 1;
|
||
$dtime['hour'] = $dtime['hour'] - 24;
|
||
}
|
||
}
|
||
}
|
||
$this->debug('DATETIME : '._debug_array($dtime,False));
|
||
return $dtime;
|
||
}
|
||
elseif(is_array($var))
|
||
{
|
||
return date('Ymd\THis\Z',mktime($var['hour'],$var['min'],$var['sec'],$var['month'],$var['mday'],$var['year']));
|
||
}
|
||
else
|
||
{
|
||
return $var;
|
||
}
|
||
}
|
||
|
||
function switch_encoding($var)
|
||
{
|
||
if(is_string($var))
|
||
{
|
||
switch($var)
|
||
{
|
||
case '8BIT':
|
||
return _8BIT;
|
||
break;
|
||
case 'BASE64':
|
||
return _BASE64;
|
||
break;
|
||
default:
|
||
return OTHER;
|
||
break;
|
||
}
|
||
}
|
||
elseif(is_int($var))
|
||
{
|
||
switch($var)
|
||
{
|
||
case _8BIT:
|
||
return '8BIT';
|
||
break;
|
||
case _BASE64:
|
||
return 'BASE64';
|
||
break;
|
||
case OTHER:
|
||
return 'OTHER';
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return $var;
|
||
}
|
||
}
|
||
|
||
function switch_fbtype($var)
|
||
{
|
||
if(is_string($var))
|
||
{
|
||
switch($var)
|
||
{
|
||
case 'FREE':
|
||
return FREE;
|
||
break;
|
||
case 'BUSY':
|
||
return BUSY;
|
||
break;
|
||
case 'BUSY-UNAVAILABLE':
|
||
return BUSY_UNAVAILABLE;
|
||
break;
|
||
case 'BUSY-TENTATIVE':
|
||
return BUSY_TENTATIVE;
|
||
break;
|
||
default:
|
||
return OTHER;
|
||
break;
|
||
}
|
||
}
|
||
elseif(is_int($var))
|
||
{
|
||
switch($var)
|
||
{
|
||
case FREE:
|
||
return 'FREE';
|
||
break;
|
||
case BUSY:
|
||
return 'BUSY';
|
||
break;
|
||
case BUSY_UNAVAILABLE:
|
||
return 'BUSY-UNAVAILABLE';
|
||
break;
|
||
case BUSY_TENTATIVE:
|
||
return 'BUSY-TENTATIVE';
|
||
break;
|
||
default:
|
||
return 'OTHER';
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return $var;
|
||
}
|
||
}
|
||
|
||
function switch_freq($var)
|
||
{
|
||
if(is_string($var))
|
||
{
|
||
switch($var)
|
||
{
|
||
case 'SECONDLY':
|
||
return SECONDLY;
|
||
break;
|
||
case 'MINUTELY':
|
||
return MINUTELY;
|
||
break;
|
||
case 'HOURLY':
|
||
return HOURLY;
|
||
break;
|
||
case 'DAILY':
|
||
return DAILY;
|
||
break;
|
||
case 'WEEKLY':
|
||
return WEEKLY;
|
||
break;
|
||
case 'MONTHLY':
|
||
return MONTHLY;
|
||
break;
|
||
case 'YEARLY':
|
||
return YEARLY;
|
||
break;
|
||
}
|
||
}
|
||
elseif(is_int($var))
|
||
{
|
||
switch($var)
|
||
{
|
||
case SECONDLY:
|
||
return 'SECONDLY';
|
||
break;
|
||
case MINUTELY:
|
||
return 'MINUTELY';
|
||
break;
|
||
case HOURLY:
|
||
return 'HOURLY';
|
||
break;
|
||
case DAILY:
|
||
return 'DAILY';
|
||
break;
|
||
case WEEKLY:
|
||
return 'WEEKLY';
|
||
break;
|
||
case MONTHLY:
|
||
return 'MONTHLY';
|
||
break;
|
||
case YEARLY:
|
||
return 'YEARLY';
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return $var;
|
||
}
|
||
}
|
||
|
||
function switch_mailto($var)
|
||
{
|
||
if(is_string($var))
|
||
{
|
||
if(strpos(' '.$var,':'))
|
||
{
|
||
$parts = explode(':',$var);
|
||
$var = $parts[1];
|
||
}
|
||
|
||
$parts = explode('@',$var);
|
||
$this->debug("Count of mailto parts : ".count($parts));
|
||
if(count($parts) == 2)
|
||
{
|
||
$this->debug("Splitting ".$parts[0]." @ ".$parts[1]);
|
||
$temp_address = Array();
|
||
$temp_address['user'] = $parts[0];
|
||
$temp_address['host'] = $parts[1];
|
||
return $temp_address;
|
||
}
|
||
else
|
||
{
|
||
return False;
|
||
}
|
||
}
|
||
elseif(is_array($var))
|
||
{
|
||
return $var['user'].'@'.$var['host'];
|
||
}
|
||
}
|
||
|
||
function switch_partstat($var)
|
||
{
|
||
$this->debug('PARTSTAT = '.$var);
|
||
if(is_string($var))
|
||
{
|
||
switch($var)
|
||
{
|
||
case 'NEEDS-ACTION':
|
||
return NEEDS_ACTION;
|
||
break;
|
||
case 'ACCEPTED':
|
||
return ACCEPTED;
|
||
break;
|
||
case 'DECLINED':
|
||
return DECLINED;
|
||
break;
|
||
case 'TENTATIVE':
|
||
return TENTATIVE;
|
||
break;
|
||
case 'DELEGATED':
|
||
return DELEGATED;
|
||
break;
|
||
case 'COMPLETED':
|
||
return COMPLETED;
|
||
break;
|
||
case 'IN-PROCESS':
|
||
return IN_PROCESS;
|
||
break;
|
||
default:
|
||
return OTHER;
|
||
break;
|
||
}
|
||
}
|
||
elseif(is_int($var))
|
||
{
|
||
switch((int)$var)
|
||
{
|
||
case NEEDS_ACTION:
|
||
return 'NEEDS-ACTION';
|
||
break;
|
||
case ACCEPTED:
|
||
return 'ACCEPTED';
|
||
break;
|
||
case DECLINED:
|
||
return 'DECLINED';
|
||
break;
|
||
case TENTATIVE:
|
||
return 'TENTATIVE';
|
||
break;
|
||
case DELEGATED:
|
||
return 'DELEGATED';
|
||
break;
|
||
case COMPLETED:
|
||
return 'COMPLETED';
|
||
break;
|
||
case IN_PROCESS:
|
||
return 'IN-PROCESS';
|
||
break;
|
||
default:
|
||
return 'X-OTHER';
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return $var;
|
||
}
|
||
}
|
||
|
||
function switch_range($var)
|
||
{
|
||
if(is_string($var))
|
||
{
|
||
switch($var)
|
||
{
|
||
case 'THISANDPRIOR':
|
||
return THISANDPRIOR;
|
||
break;
|
||
case 'THISANDFUTURE':
|
||
return THISANDFUTURE;
|
||
break;
|
||
}
|
||
}
|
||
elseif(is_int($var))
|
||
{
|
||
switch($var)
|
||
{
|
||
case THISANDPRIOR:
|
||
return 'THISANDPRIOR';
|
||
break;
|
||
case THISANDFUTURE:
|
||
return 'THISANDFUTURE';
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return $var;
|
||
}
|
||
}
|
||
|
||
function switch_related($var)
|
||
{
|
||
if(is_string($var))
|
||
{
|
||
switch($var)
|
||
{
|
||
case 'START':
|
||
return START;
|
||
break;
|
||
case 'END':
|
||
return END;
|
||
break;
|
||
}
|
||
}
|
||
elseif(is_int($var))
|
||
{
|
||
switch($var)
|
||
{
|
||
case START:
|
||
return 'START';
|
||
break;
|
||
case END:
|
||
return 'END';
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return $var;
|
||
}
|
||
}
|
||
|
||
function switch_reltype($var)
|
||
{
|
||
if(is_string($var))
|
||
{
|
||
switch($var)
|
||
{
|
||
case 'PARENT':
|
||
return PARENT;
|
||
break;
|
||
case 'CHILD':
|
||
return CHILD;
|
||
break;
|
||
case 'SIBLING':
|
||
return SIBLING;
|
||
break;
|
||
}
|
||
}
|
||
elseif(is_int($var))
|
||
{
|
||
switch($var)
|
||
{
|
||
case PARENT:
|
||
return 'PARENT';
|
||
break;
|
||
case CHILD:
|
||
return 'CHILD';
|
||
break;
|
||
case SIBLING:
|
||
return 'SIBLING';
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return $var;
|
||
}
|
||
}
|
||
|
||
function switch_role($var)
|
||
{
|
||
if(is_string($var))
|
||
{
|
||
switch($var)
|
||
{
|
||
case 'NONE':
|
||
return NONE;
|
||
break;
|
||
case 'CHAIR':
|
||
return CHAIR;
|
||
break;
|
||
case 'REQ-PARTICIPANT':
|
||
return REQ_PARTICIPANT;
|
||
break;
|
||
case 'OPT-PARTICIPANT':
|
||
return OPT_PARTICIPANT;
|
||
break;
|
||
case 'NON-PARTICIPANT':
|
||
return NON_PARTICIPANT;
|
||
break;
|
||
}
|
||
}
|
||
elseif(is_int($var))
|
||
{
|
||
switch($var)
|
||
{
|
||
case NONE:
|
||
return 'NONE';
|
||
break;
|
||
case CHAIR:
|
||
return 'CHAIR';
|
||
break;
|
||
case REQ_PARTICIPANT:
|
||
return 'REQ-PARTICIPANT';
|
||
break;
|
||
case OPT_PARTICIPANT:
|
||
return 'OPT-PARTICIPANT';
|
||
break;
|
||
case NON_PARTICIPANT:
|
||
return 'NON-PARTICIPANT';
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return $var;
|
||
}
|
||
}
|
||
|
||
function switch_rsvp($var)
|
||
{
|
||
if(is_string($var))
|
||
{
|
||
if($var == 'TRUE')
|
||
{
|
||
return 1;
|
||
}
|
||
elseif($var == 'FALSE')
|
||
{
|
||
return 0;
|
||
}
|
||
}
|
||
elseif(is_int($var) || $var == False)
|
||
{
|
||
if($var == 1)
|
||
{
|
||
return 'TRUE';
|
||
}
|
||
elseif($var == 0)
|
||
{
|
||
return 'FALSE';
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return $var;
|
||
}
|
||
}
|
||
|
||
function switch_transp($var)
|
||
{
|
||
if(is_string($var))
|
||
{
|
||
switch($var)
|
||
{
|
||
case 'TRANSPARENT':
|
||
return TRANSPARENT;
|
||
break;
|
||
case 'OPAQUE':
|
||
return OPAQUE;
|
||
break;
|
||
}
|
||
}
|
||
elseif(is_int($var))
|
||
{
|
||
switch($var)
|
||
{
|
||
case TRANSPARENT:
|
||
return 'TRANSPARENT';
|
||
break;
|
||
case OPAQUE:
|
||
return 'OPAQUE';
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return $var;
|
||
}
|
||
}
|
||
|
||
/*
|
||
* The brunt of the class
|
||
*/
|
||
|
||
function parse($ical_text)
|
||
{
|
||
$begin_regexp = '^';
|
||
$semi_colon_regexp = '[\;\:]';
|
||
$colon_regexp = '[\:]';
|
||
$catch_all_regexp = '(.*)';
|
||
$end_regexp = '$';
|
||
$property_regexp = $begin_regexp.'([A-Z\-]*)'.$semi_colon_regexp.$catch_all_regexp.$end_regexp;
|
||
$param_regexp = $begin_regexp.$catch_all_regexp.':'.$catch_all_regexp.$end_regexp;
|
||
|
||
$mode = 'none';
|
||
$text = $this->read_line_unfold($ical_text);
|
||
while($text)
|
||
{
|
||
ereg($property_regexp,$text,$temp);
|
||
$majortype = str_replace('-','_',strtolower($temp[1]));
|
||
$value = chop($temp[2]);
|
||
|
||
if($mode != 'none' && ($majortype != 'begin' && $majortype != 'end'))
|
||
{
|
||
$this->debug('PARSE:MAJORTYPE : '.$majortype);
|
||
if(isset($this->property[$majortype]))
|
||
{
|
||
$state = @$this->property[$majortype]["$mode"]['state'];
|
||
$type = @$this->property[$majortype]['type'];
|
||
$multiples = @$this->property[$majortype]["$mode"]['multiples'];
|
||
$do_to_text = @$this->property[$majortype]['to_text'];
|
||
}
|
||
elseif(substr($majortype,0,2) == 'x_')
|
||
{
|
||
$state = 'optional';
|
||
$type = 'xtype';
|
||
$multiples = True;
|
||
$do_to_test = True;
|
||
}
|
||
else
|
||
{
|
||
$state = '';
|
||
}
|
||
}
|
||
else
|
||
{
|
||
$state = 'required';
|
||
}
|
||
|
||
if($majortype == 'duration')
|
||
{
|
||
unset($dur);
|
||
|
||
// Split <20>DURATION<4F>
|
||
list($_f_['day_raw'], $_f_['time_raw']) = split('T', substr($value, 1, strlen($value)-1));
|
||
|
||
/* Datecode */
|
||
if(isset($_f_['day_raw']) || $_f_['day_raw'])
|
||
{
|
||
/* Days */
|
||
if(strstr($_f_['day_raw'],'D'))
|
||
{
|
||
$dur['days'] = eregi_replace("([0-9]+)D(.*)", "\\1", $_f_['day_raw']);
|
||
}
|
||
|
||
/* Weeks */
|
||
if(strstr($_f_['day_raw'],'W'))
|
||
{
|
||
$dur['weeks'] = eregi_replace("([^|.*]+D)?([0-9]+)W", "\\2", $_f_['day_raw']);
|
||
}
|
||
}
|
||
|
||
/* Timecode */
|
||
if(isset($_f_['time_raw']) || $_f_['time_raw'])
|
||
{
|
||
/* Hours */
|
||
if(strstr($_f_['time_raw'],'H'))
|
||
{
|
||
$dur['hours'] = eregi_replace("([0-9]+)H(.*)", "\\1", $_f_['time_raw']);
|
||
}
|
||
|
||
/* Minutes */
|
||
if(strstr($_f_['time_raw'],'M'))
|
||
{
|
||
$dur['minutes'] = eregi_replace("([^|.*]+H)?([0-9]+)M(.*)", "\\2", $_f_['time_raw']);
|
||
}
|
||
|
||
/* Seconds */
|
||
if(strstr($_f_['time_raw'],'S'))
|
||
{
|
||
$dur['seconds'] = eregi_replace("([^|.*]+M)?([0-9]+)S(.*)", "\\2", $_f_['time_raw']);
|
||
}
|
||
}
|
||
|
||
$dur['raw'] = Array(
|
||
'timecode' => $_f_['time_raw'],
|
||
'datecode' => $_f_['day_raw'],
|
||
'all' => $value
|
||
);
|
||
/* Add new parameters in Event */
|
||
$this->set_var($event, $majortype, $dur);
|
||
}
|
||
|
||
if($majortype == 'begin')
|
||
{
|
||
$tmode = $mode;
|
||
$mode = strtolower($value);
|
||
switch(strtolower($value))
|
||
{
|
||
case 'daylight':
|
||
case 'standard':
|
||
$t_event = Array();
|
||
$t_event = $event;
|
||
$event = Array();
|
||
break;
|
||
case 'valarm':
|
||
if($tmode == 'vevent' || $tmode == 'vtodo')
|
||
{
|
||
$t_event = $event;
|
||
unset($event);
|
||
$event = Array();
|
||
}
|
||
else
|
||
{
|
||
$mode = $tmode;
|
||
}
|
||
break;
|
||
case 'vcalendar':
|
||
$ical = $this->new_ical();
|
||
break;
|
||
case 'vevent':
|
||
case 'vfreebusy':
|
||
case 'vjournal':
|
||
case 'vtimezone':
|
||
case 'vtodo':
|
||
$event = Array();
|
||
break;
|
||
}
|
||
$event['type'] = strtolower($value);
|
||
}
|
||
elseif($majortype == 'end')
|
||
{
|
||
$mode = 'none';
|
||
switch(strtolower($value))
|
||
{
|
||
case 'daylight':
|
||
case 'standard':
|
||
$tzdata[] = $event;
|
||
unset($event);
|
||
$event = $t_event;
|
||
unset($t_event);
|
||
$mode = 'vtimezone';
|
||
break;
|
||
case 'valarm':
|
||
$alarm[] = $event;
|
||
unset($event);
|
||
$event = $t_event;
|
||
unset($t_event);
|
||
$mode = $tmode;
|
||
break;
|
||
case 'vevent':
|
||
if(!empty($alarm))
|
||
{
|
||
$event['alarm'] = $alarm;
|
||
unset($alarm);
|
||
}
|
||
$this->event[] = $event;
|
||
unset($event);
|
||
break;
|
||
case 'vfreebusy':
|
||
$this->freebusy[] = $event;
|
||
unset($event);
|
||
break;
|
||
case 'vjournal':
|
||
$this->journal[] = $event;
|
||
unset($event);
|
||
break;
|
||
case 'vtimezone':
|
||
if(!empty($tzdata))
|
||
{
|
||
$event['tzdata'] = $tzdata;
|
||
unset($tzdata);
|
||
}
|
||
$this->timezone[] = $event;
|
||
unset($event);
|
||
break;
|
||
case 'vtodo':
|
||
if(!empty($alarm))
|
||
{
|
||
$event['alarm'] = $alarm;
|
||
unset($alarm);
|
||
}
|
||
$this->todo[] = $event['alarm'];
|
||
unset($event);
|
||
break;
|
||
case 'vcalendar':
|
||
$this->ical = $ical;
|
||
$this->ical['event'] = $this->event;
|
||
$this->ical['freebusy'] = $this->freebusy;
|
||
$this->ical['journal'] = $this->journal;
|
||
$this->ical['timezone'] = $this->timezone;
|
||
$this->ical['todo'] = $this->todo;
|
||
break 2;
|
||
}
|
||
}
|
||
elseif($majortype == 'prodid' || $majortype == 'version' || $majortype == 'method' || $majortype == 'calscale')
|
||
{
|
||
$this->parse_parameters($ical,$majortype,$this->from_text($value));
|
||
}
|
||
elseif($state == 'optional' || $state == 'required')
|
||
{
|
||
$this->debug('Mode : '.$mode.' Majortype : '.$majortype);
|
||
if($do_to_text)
|
||
{
|
||
$value = $this->from_text($value);
|
||
}
|
||
switch($type)
|
||
{
|
||
case 'text':
|
||
$this->parse_parameters($event,$majortype,$value);
|
||
break;
|
||
case 'recur':
|
||
case 'date-time':
|
||
case 'cal-address':
|
||
$this->parse_value($event,$majortype,$value,$mode);
|
||
break;
|
||
case 'integer':
|
||
if($multiples)
|
||
{
|
||
$event[$majortype][] = (int)$value;
|
||
}
|
||
else
|
||
{
|
||
$this->set_var($event,$majortype,(int)$value);
|
||
}
|
||
break;
|
||
case 'float':
|
||
$event->$majortype = new class_geo;
|
||
$this->parse_geo($event->$majortype,$value);
|
||
break;
|
||
case 'utc-offset':
|
||
$this->set_var($event,$majortype,(int)$value);
|
||
break;
|
||
case 'uri':
|
||
$new_var = Array();
|
||
$this->parse_parameters($new_var,$majortype,$value);
|
||
if($multiples)
|
||
{
|
||
switch($mode)
|
||
{
|
||
case 'valarm':
|
||
$alarm['attach'][] = $new_var;
|
||
break;
|
||
default:
|
||
$event[$majortype][] = $new_var;
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
$event[$majortype] = $new_var;
|
||
}
|
||
unset($new_var);
|
||
break;
|
||
case 'xtype':
|
||
$this->parse_xtype($event,$majortype,$value);
|
||
break;
|
||
}
|
||
}
|
||
$text = $this->read_line_unfold($ical_text);
|
||
}
|
||
return $this->ical;
|
||
}
|
||
|
||
function build_ical($ical)
|
||
{
|
||
$var = Array(
|
||
'timezone',
|
||
'event',
|
||
'todo',
|
||
'journal',
|
||
'freebusy'
|
||
);
|
||
|
||
$str = 'BEGIN:VCALENDAR'."\r\n";
|
||
$str .= $this->fold('PRODID'.$this->build_text($ical['prodid'],'prodid'));
|
||
$str .= $this->fold('VERSION'.$this->build_text($ical['version'],'version'));
|
||
$str .= $this->fold('METHOD'.$this->build_text($ical['method'],'method'));
|
||
foreach($var as $vtype)
|
||
{
|
||
if($ical[$vtype])
|
||
{
|
||
for($i=0;$i<count($ical[$vtype]);$i++)
|
||
{
|
||
$str .= 'BEGIN:V'.strtoupper($vtype)."\r\n";
|
||
$str .= $this->build_card_internals('v'.$vtype,$ical[$vtype][$i]);
|
||
$str .= 'END:V'.strtoupper($vtype)."\r\n";
|
||
}
|
||
}
|
||
}
|
||
$str .= 'END:VCALENDAR'."\r\n";
|
||
|
||
return $str;
|
||
}
|
||
|
||
function switch_to_phpgw_status($partstat)
|
||
{
|
||
switch($partstat)
|
||
{
|
||
case 0:
|
||
return 'U';
|
||
break;
|
||
case 1:
|
||
return 'A';
|
||
break;
|
||
case 2:
|
||
return 'R';
|
||
break;
|
||
case 3:
|
||
return 'T';
|
||
break;
|
||
default:
|
||
return 'U';
|
||
break;
|
||
}
|
||
}
|
||
|
||
function switch_phpgw_status($status)
|
||
{
|
||
switch($status)
|
||
{
|
||
case 'U':
|
||
return 0;
|
||
break;
|
||
case 'A':
|
||
return 1;
|
||
break;
|
||
case 'R':
|
||
return 2;
|
||
break;
|
||
case 'T':
|
||
return 3;
|
||
break;
|
||
}
|
||
}
|
||
|
||
function is_owner($part_record)
|
||
{
|
||
if(($part_record['mailto']['user'].'@'.$part_record['mailto']['host'] == $GLOBALS['phpgw_info']['user']['preferences']['email']['address']) ||
|
||
($part_record['cn'] == $GLOBALS['phpgw_info']['user']['account_lid']))
|
||
{
|
||
return True;
|
||
}
|
||
else
|
||
{
|
||
return False;
|
||
}
|
||
}
|
||
|
||
function check_owner(&$event,$ical,$so_event)
|
||
{
|
||
if(!isset($event['participant'][$GLOBALS['phpgw_info']['user']['account_id']]))
|
||
{
|
||
if(isset($ical['organizer']))
|
||
{
|
||
if($this->is_owner($ical['organizer']))
|
||
{
|
||
$so_event->add_attribute('owner',$GLOBALS['phpgw_info']['user']['account_id']);
|
||
$so_event->add_attribute('participants',$this->switch_to_phpgw_status($ical['organizer']['partstat']),$GLOBALS['phpgw_info']['user']['account_id']);
|
||
}
|
||
}
|
||
elseif(isset($ical['attendee']))
|
||
{
|
||
$attendee_count = count($ical['attendee']);
|
||
|
||
for($j=0;$j<$attendee_count;$j++)
|
||
{
|
||
if($this->is_owner($ical['attendee'][$j]))
|
||
{
|
||
$so_event->add_attribute('participants',$this->switch_to_phpgw_status($ical['attendee'][$j]['partstat']),(int)$GLOBALS['phpgw_info']['user']['account_id']);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
$so_event->add_attribute('owner',$GLOBALS['phpgw_info']['user']['account_id']);
|
||
$so_event->add_attribute('participants','A',$GLOBALS['phpgw_info']['user']['account_id']);
|
||
}
|
||
}
|
||
}
|
||
|
||
function import_file()
|
||
{
|
||
if($_FILES['uploadedfile']['tmp_name'] == 'none' || $_FILES['uploadedfile']['tmp_name'] == '')
|
||
{
|
||
Header('Location: ' . $GLOBALS['phpgw']->link('/index.php',
|
||
Array(
|
||
'menuaction' => 'calendar.uiicalendar.import',
|
||
'action' => 'GetFile'
|
||
)
|
||
)
|
||
);
|
||
$GLOBALS['phpwg']->common->phpgw_exit();
|
||
}
|
||
$uploaddir = $GLOBALS['phpgw_info']['server']['temp_dir'] . SEP;
|
||
|
||
srand((double)microtime()*1000000);
|
||
$random_number = rand(100000000,999999999);
|
||
$newfilename = md5($_FILES['uploadedfile']['tmp_name'].", ".$uploadedfile_name.", "
|
||
. time() . getenv("REMOTE_ADDR") . $random_number );
|
||
|
||
$filename = $uploaddir . $newfilename;
|
||
|
||
move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $filename);
|
||
return $filename;
|
||
}
|
||
|
||
function import($mime_msg='')
|
||
{
|
||
if($_FILES['uploadedfile']['tmp_name'] != 'none' && $_FILES['uploadedfile']['tmp_name'] != '')
|
||
{
|
||
$filename = $this->import_file();
|
||
$fp=fopen($filename,'rt');
|
||
$mime_msg = fread($fp, filesize($filename));
|
||
fclose($fp);
|
||
unlink($filename);
|
||
|
||
/* explode can fail easily, so pre-chew the ical file */
|
||
$mime_msg = preg_replace("/(\r\n|\r)/", "\n", $mime_msg); /* dos2unix */
|
||
$mime_msg = preg_replace("/\n\n+/", "\n", $mime_msg); /* strip duplicate newlines */
|
||
$mime_msg = explode("\n",$mime_msg); /* explode the sanitized message into itself */
|
||
}
|
||
elseif(!$mime_msg)
|
||
{
|
||
Header('Location: ' . $GLOBALS['phpgw']->link('/index.php',
|
||
Array(
|
||
'menuaction' => 'calendar.uiicalendar.import',
|
||
'action' => 'GetFile'
|
||
)
|
||
)
|
||
);
|
||
$GLOBALS['phpwg']->common->phpgw_exit();
|
||
}
|
||
|
||
if(!is_object($GLOBALS['uicalendar']))
|
||
{
|
||
$so_event = createobject('calendar.socalendar',
|
||
Array(
|
||
'owner' => 0,
|
||
'filter' => '',
|
||
'category' => ''
|
||
)
|
||
);
|
||
}
|
||
else
|
||
{
|
||
$so_event = $GLOBALS['uicalendar']->bo->so;
|
||
}
|
||
|
||
$datetime_vars = Array(
|
||
'start' => 'dtstart',
|
||
'end' => 'dtend',
|
||
'modtime' => 'dtstamp',
|
||
'modtime' => 'last_modified'
|
||
);
|
||
|
||
$date_array = Array(
|
||
'Y' => 'year',
|
||
'm' => 'month',
|
||
'd' => 'mday',
|
||
'H' => 'hour',
|
||
'i' => 'min',
|
||
's' => 'sec'
|
||
);
|
||
|
||
/* time limit should be controlled elsewhere */
|
||
@set_time_limit(0);
|
||
|
||
$GLOBALS['phpgw_info']['user']['preferences'] = $GLOBALS['phpgw']->preferences->create_email_preferences();
|
||
$users_email = $GLOBALS['phpgw_info']['user']['preferences']['email']['address'];
|
||
$cats = CreateObject('phpgwapi.categories');
|
||
$ical = $this->parse($mime_msg);
|
||
switch($ical['version']['value'])
|
||
{
|
||
case '1.0':
|
||
$cat_sep = ';';
|
||
break;
|
||
case '2.0':
|
||
default:
|
||
$cat_sep = ',';
|
||
break;
|
||
}
|
||
$c_events = count($ical['event']);
|
||
for($i=0;$i<$c_events;$i++)
|
||
{
|
||
if($ical['event'][$i]['uid']['value'])
|
||
{
|
||
$uid_exists = $so_event->find_uid($ical['event'][$i]['uid']['value']);
|
||
}
|
||
else
|
||
{
|
||
$uid_exists = False;
|
||
}
|
||
if($uid_exists)
|
||
{
|
||
$event = $so_event->read_entry($uid_exists);
|
||
$this->check_owner($event,$ical['event'][$i],$so_event);
|
||
$event = $so_event->get_cached_event();
|
||
$so_event->add_entry($event);
|
||
}
|
||
else
|
||
{
|
||
$so_event->event_init();
|
||
$so_event->add_attribute('id',0);
|
||
$so_event->add_attribute('reference',0);
|
||
if($ical['event'][$i]['uid']['value'])
|
||
{
|
||
$so_event->add_attribute('uid',$ical['event'][$i]['uid']['value']);
|
||
}
|
||
if($ical['event'][$i]['summary']['value'])
|
||
{
|
||
$so_event->set_title($ical['event'][$i]['summary']['value']);
|
||
}
|
||
if($ical['event'][$i]['description']['value'])
|
||
{
|
||
$so_event->set_description($ical['event'][$i]['description']['value']);
|
||
}
|
||
if($ical['event'][$i]['location']['value'])
|
||
{
|
||
$so_event->add_attribute('location',$ical['event'][$i]['location']['value']);
|
||
}
|
||
if(isset($ical['event'][$i]['priority']))
|
||
{
|
||
$so_event->add_attribute('priority',$ical['event'][$i]['priority']);
|
||
}
|
||
else
|
||
{
|
||
$so_event->add_attribute('priority',2);
|
||
}
|
||
if(!isset($ical['event'][$i]['class']))
|
||
{
|
||
$ical['event'][$i]['class'] = 1;
|
||
}
|
||
$so_event->set_class($ical['event'][$i]['class']);
|
||
|
||
@reset($datetime_vars);
|
||
while(list($e_datevar,$i_datevar) = each($datetime_vars))
|
||
{
|
||
if(isset($ical['event'][$i][$i_datevar]))
|
||
{
|
||
$temp_time = $so_event->maketime($ical['event'][$i][$i_datevar]) + $GLOBALS['phpgw']->datetime->tz_offset;
|
||
@reset($date_array);
|
||
while(list($key,$var) = each($date_array))
|
||
{
|
||
$event[$e_datevar][$var] = (int)(date($key,$temp_time));
|
||
}
|
||
$so_event->set_date($e_datevar,$event[$e_datevar]['year'],$event[$e_datevar]['month'],$event[$e_datevar]['mday'],$event[$e_datevar]['hour'],$event[$e_datevar]['min'],$event[$e_datevar]['sec']);
|
||
}
|
||
}
|
||
if(!isset($ical['event'][$i]['categories']['value']) || !$ical['event'][$i]['categories']['value'])
|
||
{
|
||
$so_event->set_category(0);
|
||
}
|
||
else
|
||
{
|
||
$ical_cats = Array();
|
||
if(strpos($ical['event'][$i]['categories']['value'],$cat_sep))
|
||
{
|
||
$ical_cats = explode($cat_sep,$ical['event'][$i]['categories']['value']);
|
||
}
|
||
else
|
||
{
|
||
$ical_cats[] = $ical['event'][$i]['categories']['value'];
|
||
}
|
||
|
||
@reset($ical_cats);
|
||
$cat_id_nums = Array();
|
||
while(list($key,$cat) = each($ical_cats))
|
||
{
|
||
if(!$cats->exists('appandmains',$cat))
|
||
{
|
||
$cats->add(
|
||
Array(
|
||
'name' => $cat,
|
||
'descr' => $cat,
|
||
'parent' => '',
|
||
'access' => 'private',
|
||
'data' => ''
|
||
)
|
||
);
|
||
}
|
||
$cat_id_nums[] = $cats->name2id($cat);
|
||
}
|
||
@reset($cat_id_nums);
|
||
if(count($cat_id_nums) > 1)
|
||
{
|
||
$so_event->set_category(implode($cat_id_nums,','));
|
||
}
|
||
else
|
||
{
|
||
$so_event->set_category($cat_id_nums[0]);
|
||
}
|
||
}
|
||
|
||
/* rrule */
|
||
if(isset($ical['event'][$i]['rrule']) || isset($ical['event'][$i]['duration']))
|
||
{
|
||
/* recur_enddate */
|
||
if(isset($ical['event'][$i]['rrule']['until']))
|
||
{
|
||
$recur_enddate['year'] = (int)($ical['event'][$i]['rrule']['until']['year']);
|
||
$recur_enddate['month'] = (int)($ical['event'][$i]['rrule']['until']['month']);
|
||
$recur_enddate['mday'] = (int)($ical['event'][$i]['rrule']['until']['mday']);
|
||
$recur_enddate['hour'] = (int)($ical['event'][$i]['rrule']['until']['hour']);
|
||
$recur_enddate['min'] = (int)($ical['event'][$i]['rrule']['until']['min']);
|
||
$recur_enddate['sec'] = (int)($ical['event'][$i]['rrule']['until']['sec']);
|
||
}
|
||
elseif( isset($ical['event'][$i]['duration']) )
|
||
{
|
||
/* Create timecode for strtotime */
|
||
$ptimer = mktime($ical['event'][$i]['dtstart']['hour'],
|
||
$ical['event'][$i]['dtstart']['min'],
|
||
$ical['event'][$i]['dtstart']['sec'],
|
||
$ical['event'][$i]['dtstart']['month'],
|
||
$ical['event'][$i]['dtstart']['mday'],
|
||
$ical['event'][$i]['dtstart']['year']);
|
||
|
||
/*
|
||
* Subtract 1 second so we don't overlap with the beginning of
|
||
* another event.
|
||
*/
|
||
|
||
/* handle events with duration in weeks */
|
||
if ($ical['event'][$i]['duration']['weeks'] &&
|
||
($ical['event'][$i]['duration']['hours'] == 0) &&
|
||
($ical['event'][$i]['duration']['minutes'] == 0))
|
||
{
|
||
$ical['event'][$i]['duration']['days'] =
|
||
($ical['event'][$i]['duration']['days'] +
|
||
($ical['event'][$i]['duration']['weeks']*7)) - 1;
|
||
|
||
unset($ical['event'][$i]['duration']['weeks']);
|
||
|
||
$ical['event'][$i]['duration']['hours'] = "23";
|
||
$ical['event'][$i]['duration']['minutes'] = "59";
|
||
$ical['event'][$i]['duration']['seconds'] = "59";
|
||
}
|
||
/* handle events with duration in days */
|
||
if(($ical['event'][$i]['duration']['days'] && $ical['event'][$i]['duration']['hours'] == 0) &&
|
||
($ical['event'][$i]['duration']['minutes'] == 0))
|
||
{
|
||
$ical['event'][$i]['duration']['days']--;
|
||
$ical['event'][$i]['duration']['hours'] = "23";
|
||
$ical['event'][$i]['duration']['minutes'] = "59";
|
||
$ical['event'][$i]['duration']['seconds'] = "59";
|
||
}
|
||
|
||
/* Create string contains datetime for strtotime */
|
||
$pdate = "+";
|
||
if(isset($ical['event'][$i]['duration']['weeks']))
|
||
$pdate .= $ical['event'][$i]['duration']['weeks'] . " weeks ";
|
||
|
||
if(isset($ical['event'][$i]['duration']['days']))
|
||
$pdate .= $ical['event'][$i]['duration']['days'] . " days ";
|
||
|
||
if(isset($ical['event'][$i]['duration']['hours']))
|
||
$pdate .= $ical['event'][$i]['duration']['hours'] . " hours ";
|
||
|
||
if(isset($ical['event'][$i]['duration']['minutes']))
|
||
$pdate .= $ical['event'][$i]['duration']['minutes'] . " minutes ";
|
||
|
||
if(isset($ical['event'][$i]['duration']['seconds']))
|
||
$pdate .= $ical['event'][$i]['duration']['seconds'] . " seconds ";
|
||
|
||
/* What is datetime in 2192? */
|
||
$enddate = strtotime($pdate, $ptimer);
|
||
list(
|
||
$recur_enddate['year'],
|
||
$recur_enddate['month'],
|
||
$recur_enddate['mday'],
|
||
$recur_enddate['hour'],
|
||
$recur_enddate['min'],
|
||
$recur_enddate['sec']
|
||
) = split(":", date("Y:m:d:H:i:s", $enddate));
|
||
|
||
/* Set End of event */
|
||
$so_event->set_end(
|
||
$recur_enddate['year'],
|
||
$recur_enddate['month'],
|
||
$recur_enddate['mday'],
|
||
$recur_enddate['hour'],
|
||
$recur_enddate['min'],
|
||
$recur_enddate['sec']
|
||
);
|
||
}
|
||
else
|
||
{
|
||
$recur_enddate['year'] = 0;
|
||
$recur_enddate['month'] = 0;
|
||
$recur_enddate['mday'] = 0;
|
||
}
|
||
|
||
/* recur_data */
|
||
$recur_data = 0;
|
||
if(isset($ical['event'][$i]['rrule']['byday']))
|
||
{
|
||
$week_days = Array(
|
||
MCAL_M_SUNDAY => 'SU',
|
||
MCAL_M_MONDAY => 'MO',
|
||
MCAL_M_TUESDAY => 'TU',
|
||
MCAL_M_WEDNESDAY => 'WE',
|
||
MCAL_M_THURSDAY => 'TH',
|
||
MCAL_M_FRIDAY => 'FR',
|
||
MCAL_M_SATURDAY => 'SA'
|
||
);
|
||
@reset($week_days);
|
||
while(list($key,$val) = each($week_days))
|
||
{
|
||
if(strpos(' '.$ical['event'][$i]['rrule']['byday'],$val))
|
||
{
|
||
$recur_data += $key;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* interval */
|
||
if(!isset($ical['event'][$i]['rrule']['interval']))
|
||
{
|
||
$interval = 1;
|
||
}
|
||
else
|
||
{
|
||
$interval = (int)$ical['event'][$i]['rrule']['interval'];
|
||
}
|
||
|
||
/* recur_type */
|
||
switch($ical['event'][$i]['rrule']['freq'])
|
||
{
|
||
case SECONDLY:
|
||
$so_event->set_recur_secondly($recur_enddate['year'],$recur_enddate['month'],$recur_enddate['mday'],$interval);
|
||
break;
|
||
case MINUTELY:
|
||
$so_event->set_recur_minutely($recur_enddate['year'],$recur_enddate['month'],$recur_enddate['mday'],$interval);
|
||
break;
|
||
case HOURLY:
|
||
$so_event->set_recur_hourly($recur_enddate['year'],$recur_enddate['month'],$recur_enddate['mday'],$interval);
|
||
break;
|
||
case DAILY:
|
||
$so_event->set_recur_daily($recur_enddate['year'],$recur_enddate['month'],$recur_enddate['mday'],$interval);
|
||
break;
|
||
case WEEKLY:
|
||
$so_event->set_recur_weekly($recur_enddate['year'],$recur_enddate['month'],$recur_enddate['mday'],$interval,$recur_data);
|
||
break;
|
||
case MONTHLY:
|
||
$so_event->set_recur_monthly_mday($recur_enddate['year'],$recur_enddate['month'],$recur_enddate['mday'],$interval);
|
||
break;
|
||
case YEARLY:
|
||
$so_event->set_recur_yearly($recur_enddate['year'],$recur_enddate['month'],$recur_enddate['mday'],$interval);
|
||
break;
|
||
}
|
||
|
||
if(isset($ical['event'][$i]['rrule']['until']))
|
||
{
|
||
$so_event->add_attribute('recur_enddate',$ical['event'][$i]['rrule']['until']['year'],'year');
|
||
$so_event->add_attribute('recur_enddate',$ical['event'][$i]['rrule']['until']['month'],'month');
|
||
$so_event->add_attribute('recur_enddate',$ical['event'][$i]['rrule']['until']['mday'],'mday');
|
||
$so_event->add_attribute('recur_enddate',$ical['event'][$i]['rrule']['until']['hour'],'hour');
|
||
$so_event->add_attribute('recur_enddate',$ical['event'][$i]['rrule']['until']['minute'],'min');
|
||
$so_event->add_attribute('recur_enddate',$ical['event'][$i]['rrule']['until']['second'],'sec');
|
||
}
|
||
}
|
||
else
|
||
{
|
||
$so_event->set_recur_none();
|
||
}
|
||
|
||
/* the organizer must be the current user doing the importing */
|
||
if(!isset($ical['event'][$i]['organizer']) || !$this->is_owner($ical['event'][$i]['organizer']))
|
||
{
|
||
$so_event->add_attribute('owner',$GLOBALS['phpgw_info']['user']['account_id']);
|
||
$so_event->add_attribute('participants','A',$GLOBALS['phpgw_info']['user']['account_id']);
|
||
}
|
||
|
||
/* if the original organizer is an egroupware user, add the original user as an event participant */
|
||
/* NB: ['mailto'] has two parts, ['user'], containing the username, and ['host'], containing the domain of the user's email address */
|
||
if (isset($ical['event'][$i]['organizer']['mailto']['user']) && $GLOBALS['phpgw']->accounts->exists($ical['event'][$i]['organizer']['mailto']['user']) == True)
|
||
{
|
||
$so_event->add_attribute('participants','A',(int)$GLOBALS['phpgw']->accounts->name2id($ical['event'][$i]['organizer']['mailto']['user']));
|
||
}
|
||
|
||
$event = $so_event->get_cached_event();
|
||
$so_event->add_entry($event);
|
||
}
|
||
}
|
||
Header('Location: '.$GLOBALS['phpgw']->link('/index.php',
|
||
Array(
|
||
'menuaction' => 'calendar.uicalendar.view',
|
||
'cal_id' => $event['id']
|
||
)
|
||
)
|
||
);
|
||
$GLOBALS['phpgw']->common->phpgw_exit();
|
||
}
|
||
|
||
function export($params)
|
||
{
|
||
$event_id = $params['l_event_id'] ? $params['l_event_id'] : $_GET['cal_id'];
|
||
$this->chunk_split = $params['chunk_split'];
|
||
$method = $params['method'] ? $params['method'] : 'publish';
|
||
$vtype = $params['vtype'] ? $params['vtype'] : 'event';
|
||
|
||
$string_array = Array(
|
||
'summary' => 'description',
|
||
'location' => 'location',
|
||
'description' => 'title',
|
||
'uid' => 'uid'
|
||
);
|
||
|
||
$cats = CreateObject('phpgwapi.categories');
|
||
|
||
include(PHPGW_SERVER_ROOT.'/calendar/setup/setup.inc.php');
|
||
if(!is_array($event_id))
|
||
{
|
||
$ids[] = $event_id;
|
||
}
|
||
else
|
||
{
|
||
$ids = $event_id;
|
||
}
|
||
|
||
$ical = $this->new_ical();
|
||
|
||
$this->set_var($ical['prodid'],'value','-//eGroupWare//eGroupWare '.$setup_info['calendar']['version'].' MIMEDIR//'.strtoupper($GLOBALS['phpgw_info']['user']['preferences']['common']['lang']));
|
||
$this->set_var($ical['version'],'value','1.0');
|
||
$this->set_var($ical['method'],'value',strtoupper($method));
|
||
|
||
if(!$GLOBALS['phpgw_info']['flags']['included_classes']['uicalendar'])
|
||
{
|
||
if(!$GLOBALS['phpgw_info']['flags']['included_classes']['bocalendar'])
|
||
{
|
||
$so_event = createobject('calendar.socalendar',
|
||
Array(
|
||
'owner' => 0,
|
||
'filter' => '',
|
||
'category' => ''
|
||
)
|
||
);
|
||
}
|
||
else
|
||
{
|
||
$so_event = $GLOBALS['bocalendar']->so;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
$so_event = $GLOBALS['uicalendar']->bo->so;
|
||
}
|
||
|
||
foreach($ids as $event)
|
||
{
|
||
$ical_event = Array();
|
||
if (!is_array($event))
|
||
{
|
||
$event = $so_event->read_entry($event);
|
||
}
|
||
if($event['alarm'])
|
||
{
|
||
foreach($event['alarm'] as $alarm)
|
||
{
|
||
$ical_temp = Array();
|
||
$ical_temp['action']['value'] = 'DISPLAY';
|
||
$ical_temp['description']['value'] = $alarm['text'];
|
||
$this->set_var($ical_temp['trigger'],'value','VALUE=DATE-TIME:'.date('Ymd\THis\Z',$alarm['time']),'valarm');
|
||
$ical_event['alarm'][] = $ical_temp;
|
||
}
|
||
}
|
||
|
||
// $event has times in user's time zone, so have to adjust them to GMT, which is used by ical
|
||
// To do that one must substract the users time zone difference with the server and then substract the server's time zone difference with GMT
|
||
$gmt_offset = date('O'); // server's offset to GMT
|
||
$offset = ((int)(substr($gmt_offset, 0, 3)) + $GLOBALS['phpgw_info']['user']['preferences']['common']['tz_offset']) * 60 + (int)(substr($gmt_offset, 3, 2));
|
||
$event['start']['min'] -= $offset;
|
||
$event['end']['min'] -= $offset;
|
||
$event['modtime']['min'] -= $offset;
|
||
|
||
$ical_event['priority'] = $event['priority'];
|
||
$ical_event['class'] = (int)$event['public'];
|
||
$dtstart_mktime = $so_event->maketime($event['start']);
|
||
$this->parse_value($ical_event,'dtstart',date('Ymd\THis\Z',$dtstart_mktime),'vevent');
|
||
$dtend_mktime = $so_event->maketime($event['end']);
|
||
$this->parse_value($ical_event,'dtend',date('Ymd\THis\Z',$dtend_mktime),'vevent');
|
||
$mod_mktime = $so_event->maketime($event['modtime']);
|
||
$this->parse_value($ical_event,'last_modified',date('Ymd\THis\Z',$mod_mktime),'vevent');
|
||
foreach($string_array as $ical_value => $event_value)
|
||
{
|
||
if($event[$event_value])
|
||
{
|
||
$this->set_var($ical_event[$ical_value],'value',$event[$event_value]);
|
||
}
|
||
}
|
||
|
||
if ($event['category'])
|
||
{
|
||
$cats->categories(0,'calendar');
|
||
foreach(explode(',',$event['category']) as $cat)
|
||
{
|
||
$_cat = $cats->return_single($cat);
|
||
$cat_string[] = $_cat[0]['name'];
|
||
}
|
||
@reset($cat_string);
|
||
$this->set_var($ical_event['categories'],'value',implode($cat_string,','));
|
||
}
|
||
|
||
if(count($event['participants']) > 1)
|
||
{
|
||
if(!is_object($db))
|
||
{
|
||
$db = $GLOBALS['phpgw']->db;
|
||
}
|
||
foreach($event['participants'] as $part => $status)
|
||
{
|
||
$GLOBALS['phpgw']->accounts->get_account_name($part,$lid,$fname,$lname);
|
||
$name = $fname.' '.$lname;
|
||
|
||
$owner_status = $this->switch_partstat((int)$this->switch_phpgw_status($event['participants'][$part]));
|
||
|
||
$mail_prefs = $GLOBALS['phpgw']->preferences->create_email_preferences($part);
|
||
$mailto = $mail_prefs['email']['address'];
|
||
|
||
$str = 'CN="'.$name.'";PARTSTAT='.$owner_status.':'.$mailto;
|
||
if($part == $event['owner'])
|
||
{
|
||
$str = 'ROLE=CHAIR;'.$str;
|
||
}
|
||
else
|
||
{
|
||
$str = 'ROLE=REQ-PARTICIPANT;'.$str;
|
||
}
|
||
if ($method != 'reply' || $part == $GLOBALS['phpgw_info']['user']['account_id'])
|
||
{
|
||
$this->parse_value($ical_event,'attendee',$str,'vevent');
|
||
}
|
||
if($part == $event['owner'])
|
||
{
|
||
$this->parse_value($ical_event,'organizer',$str,'vevent');
|
||
}
|
||
}
|
||
}
|
||
if($event['recur_type'])
|
||
{
|
||
$str = '';
|
||
switch($event['recur_type'])
|
||
{
|
||
case MCAL_RECUR_SECONDLY:
|
||
$str .= 'FREQ=SECONDLY';
|
||
break;
|
||
case MCAL_RECUR_MINUTELY:
|
||
$str .= 'FREQ=MINUTELY';
|
||
break;
|
||
case MCAL_RECUR_HOURLY:
|
||
$str .= 'FREQ=HOURLY';
|
||
break;
|
||
case MCAL_RECUR_DAILY:
|
||
$str .= 'FREQ=DAILY';
|
||
break;
|
||
case MCAL_RECUR_WEEKLY:
|
||
$str .= 'FREQ=WEEKLY';
|
||
if($event['recur_data'])
|
||
{
|
||
$str .= ';BYDAY=';
|
||
for($i=1;$i<MCAL_M_ALLDAYS;$i=$i*2)
|
||
{
|
||
if($i & $event['recur_data'])
|
||
{
|
||
switch($i)
|
||
{
|
||
case MCAL_M_SUNDAY:
|
||
$day[] = 'SU';
|
||
break;
|
||
case MCAL_M_MONDAY:
|
||
$day[] = 'MO';
|
||
break;
|
||
CASE MCAL_M_TUESDAY:
|
||
$day[] = 'TU';
|
||
break;
|
||
case MCAL_M_WEDNESDAY:
|
||
$day[] = 'WE';
|
||
break;
|
||
case MCAL_M_THURSDAY:
|
||
$day[] = 'TH';
|
||
break;
|
||
case MCAL_M_FRIDAY:
|
||
$day[] = 'FR';
|
||
break;
|
||
case MCAL_M_SATURDAY:
|
||
$day[] = 'SA';
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
$str .= implode(',',$day);
|
||
}
|
||
break;
|
||
case MCAL_RECUR_MONTHLY_MDAY:
|
||
break;
|
||
case MCAL_RECUR_MONTHLY_WDAY:
|
||
break;
|
||
case MCAL_RECUR_YEARLY:
|
||
$str .= 'FREQ=YEARLY';
|
||
break;
|
||
}
|
||
if($event['recur_interval'])
|
||
{
|
||
$str .= ';INTERVAL='.$event['recur_interval'];
|
||
}
|
||
if($event['recur_enddate']['month'] != 0 && $event['recur_enddate']['mday'] != 0 && $event['recur_enddate']['year'] != 0)
|
||
{
|
||
$recur_mktime = $so_event->maketime($event['recur_enddate']) - $GLOBALS['phpgw']->datetime->tz_offset;
|
||
$str .= ';UNTIL='.date('Ymd\THis\Z',$recur_mktime);
|
||
}
|
||
$this->parse_value($ical_event,'rrule',$str,'vevent');
|
||
|
||
$exceptions = $event['recur_exception'];
|
||
if(is_array($exceptions))
|
||
{
|
||
foreach($exceptions as $except_datetime)
|
||
{
|
||
$ical_event['exdate'][] = $this->switch_date(date('Ymd\THis\Z',$except_datetime));
|
||
}
|
||
}
|
||
}
|
||
$ical_events[] = $ical_event;
|
||
}
|
||
|
||
$ical[$vtype] = $ical_events;
|
||
|
||
// iCals are by default utf-8
|
||
return $GLOBALS['phpgw']->translation->convert($this->build_ical($ical),$GLOBALS['phpgw']->translation->charset(),'utf-8');
|
||
}
|
||
|
||
function freebusy($params=False)
|
||
{
|
||
if (!$params) $params = $_GET;
|
||
$user = is_numeric($params['user']) ? (int) $params['user'] : $GLOBALS['phpgw']->accounts->name2id($params['user']);
|
||
$start = isset($params['start']) ? $params['start'] : date('Ymd');
|
||
$end = isset($params['end']) ? $params['end'] : (date('Y')+1).date('md');
|
||
|
||
$this->bo = CreateObject('calendar.bocalendar');
|
||
$events_per_day = $this->bo->store_to_cache(array(
|
||
'owner' => $user,
|
||
'syear' => (int) substr($start,0,4),
|
||
'smonth' => (int) substr($start,4,2),
|
||
'sday' => (int) substr($start,6,2),
|
||
'eyear' => (int) substr($end,0,4),
|
||
'emonth' => (int) substr($end,4,2),
|
||
'eday' => (int) substr($end,6,2),
|
||
'no_doubles' => True, // report events only on the startday
|
||
));
|
||
if (!is_array($events_per_day)) $events_per_day = array();
|
||
$ids = array();
|
||
foreach($events_per_day as $day => $events)
|
||
{
|
||
foreach($events as $event)
|
||
{
|
||
$ids[] = $event;
|
||
}
|
||
}
|
||
$browser = CreateObject('phpgwapi.browser');
|
||
$browser->content_header($GLOBALS['phpgw']->accounts->id2name($user).'.ifb','text/calendar');
|
||
|
||
echo $this->export(array(
|
||
'vtype' => 'freebusy',
|
||
'l_event_id' => $ids,
|
||
));
|
||
}
|
||
|
||
function debug($str='')
|
||
{
|
||
if($this->debug_str)
|
||
{
|
||
echo $str."<br>\n";
|
||
}
|
||
}
|
||
}
|
||
?>
|