forked from extern/egroupware
using new Horde_Icalendar class from vendor for CalDAV/CardDAV and iCal import/export instead of old code in phpgwapi/inc/horde
This commit is contained in:
parent
63cd244e97
commit
f0e2877698
@ -12,9 +12,6 @@
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php';
|
||||
require_once(EGW_SERVER_ROOT.'/phpgwapi/inc/horde/Horde/SyncML/State.php');
|
||||
|
||||
/**
|
||||
* Addressbook - vCard parser
|
||||
*
|
||||
@ -146,7 +143,7 @@ class addressbook_vcal extends addressbook_bo
|
||||
{
|
||||
if ($merge)
|
||||
{
|
||||
foreach ($contact as $key => $value)
|
||||
foreach (array_keys($contact) as $key)
|
||||
{
|
||||
if (!empty($old_contact[$key]))
|
||||
{
|
||||
@ -203,11 +200,7 @@ class addressbook_vcal extends addressbook_bo
|
||||
*/
|
||||
function getVCard($_id,$_charset='UTF-8',$extra_charset_attribute=true)
|
||||
{
|
||||
require_once(EGW_SERVER_ROOT.'/phpgwapi/inc/horde/Horde/iCalendar/vcard.php');
|
||||
|
||||
#Horde::logMessage("vCalAddressbook clientProperties:\n" . print_r($this->clientProperties, true), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||
|
||||
$vCard = new Horde_iCalendar_vcard($this->version);
|
||||
$vCard = new Horde_Icalendar_Vcard($this->version);
|
||||
$vCard->setAttribute('PRODID','-//EGroupware//NONSGML EGroupware Addressbook '.$GLOBALS['egw_info']['apps']['phpgwapi']['version'].'//'.
|
||||
strtoupper($GLOBALS['egw_info']['user']['preferences']['common']['lang']));
|
||||
|
||||
@ -551,8 +544,6 @@ class addressbook_vcal extends addressbook_bo
|
||||
array2string($_vcard)."\n",3,$this->logfile);
|
||||
}
|
||||
|
||||
require_once(EGW_SERVER_ROOT.'/phpgwapi/inc/horde/Horde/iCalendar.php');
|
||||
|
||||
if(!($_vcard instanceof Horde_iCalendar))
|
||||
{
|
||||
$container = false;
|
||||
@ -1058,9 +1049,7 @@ class addressbook_vcal extends addressbook_bo
|
||||
*/
|
||||
function getGroupVCard(array $list,$version='3.0')
|
||||
{
|
||||
require_once(EGW_SERVER_ROOT.'/phpgwapi/inc/horde/Horde/iCalendar/vcard.php');
|
||||
|
||||
$vCard = new Horde_iCalendar_vcard($version);
|
||||
$vCard = new Horde_Icalendar_Vcard($version);
|
||||
$vCard->setAttribute('PRODID','-//EGroupware//NONSGML EGroupware Addressbook '.$GLOBALS['egw_info']['apps']['phpgwapi']['version'].'//'.
|
||||
strtoupper($GLOBALS['egw_info']['user']['preferences']['common']['lang']));
|
||||
|
||||
|
@ -11,8 +11,6 @@
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php';
|
||||
|
||||
/**
|
||||
* EGroupware: CalDAV / GroupDAV access: calendar handler
|
||||
*
|
||||
@ -35,7 +33,7 @@ class calendar_groupdav extends groupdav_handler
|
||||
/**
|
||||
* vCalendar Instance for parsing
|
||||
*
|
||||
* @var Horde_iCalendar
|
||||
* @var Horde_Icalendar
|
||||
*/
|
||||
var $vCalendar;
|
||||
|
||||
@ -95,7 +93,7 @@ class calendar_groupdav extends groupdav_handler
|
||||
parent::__construct($app, $groupdav);
|
||||
|
||||
$this->bo = new calendar_boupdate();
|
||||
$this->vCalendar = new Horde_iCalendar;
|
||||
$this->vCalendar = new Horde_Icalendar;
|
||||
|
||||
// since 1.9.003 we allow clients to specify the URL when creating a new event, as specified by CalDAV
|
||||
if (version_compare($GLOBALS['egw_info']['apps']['calendar']['version'], '1.9.003', '>='))
|
||||
@ -1084,8 +1082,7 @@ class calendar_groupdav extends groupdav_handler
|
||||
*/
|
||||
protected function outbox_freebusy_request($ical, $charset, $user, array &$options)
|
||||
{
|
||||
include_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php';
|
||||
$vcal = new Horde_iCalendar();
|
||||
$vcal = new Horde_Icalendar();
|
||||
if (!$vcal->parsevCalendar($ical, 'VCALENDAR', $charset))
|
||||
{
|
||||
return '400 Bad request';
|
||||
@ -1098,7 +1095,7 @@ class calendar_groupdav extends groupdav_handler
|
||||
$handler->setSupportedFields('groupdav');
|
||||
$handler->calendarOwner = $handler->user = 0; // to NOT default owner/organizer to something
|
||||
if (!($component = $vcal->getComponent(0)) ||
|
||||
!($event = $handler->vevent2egw($component, $version, $handler->supportedFields, $this->groupdav->current_user_principal, 'Horde_iCalendar_vfreebusy')))
|
||||
!($event = $handler->vevent2egw($component, $version, $handler->supportedFields, $this->groupdav->current_user_principal, 'Horde_Icalendar_Vfreebusy')))
|
||||
{
|
||||
return '400 Bad request';
|
||||
}
|
||||
|
@ -12,8 +12,6 @@
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php';
|
||||
|
||||
/**
|
||||
* iCal import and export via Horde iCalendar classes
|
||||
*
|
||||
@ -178,7 +176,7 @@ class calendar_ical extends calendar_boupdate
|
||||
parent::__construct();
|
||||
if ($this->log) $this->logfile = $GLOBALS['egw_info']['server']['temp_dir']."/log-vcal";
|
||||
$this->clientProperties = $_clientProperties;
|
||||
$this->vCalendar = new Horde_iCalendar;
|
||||
$this->vCalendar = new Horde_Icalendar;
|
||||
$this->addressbook = new addressbook_bo;
|
||||
}
|
||||
|
||||
@ -231,7 +229,7 @@ class calendar_ical extends calendar_boupdate
|
||||
$version = '2.0';
|
||||
}
|
||||
|
||||
$vcal = new Horde_iCalendar;
|
||||
$vcal = new Horde_Icalendar;
|
||||
$vcal->setAttribute('PRODID','-//EGroupware//NONSGML EGroupware Calendar '.$GLOBALS['egw_info']['apps']['calendar']['version'].'//'.
|
||||
strtoupper($GLOBALS['egw_info']['user']['preferences']['common']['lang']));
|
||||
$vcal->setAttribute('VERSION', $version);
|
||||
@ -330,7 +328,7 @@ class calendar_ical extends calendar_boupdate
|
||||
if ($this->log)
|
||||
{
|
||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
||||
"($_id, $recurrence) Gratuitous pseudo exception, skipped ...\n",
|
||||
"(, $recurrence) Gratuitous pseudo exception, skipped ...\n",
|
||||
3,$this->logfile);
|
||||
}
|
||||
continue; // unsupported status only exception
|
||||
@ -377,7 +375,7 @@ class calendar_ical extends calendar_boupdate
|
||||
}
|
||||
}
|
||||
|
||||
$vevent = Horde_iCalendar::newComponent('VEVENT', $vcal);
|
||||
$vevent = Horde_Icalendar::newComponent('VEVENT', $vcal);
|
||||
$parameters = $attributes = $values = array();
|
||||
|
||||
if ($this->productManufacturer == 'sonyericsson')
|
||||
@ -429,6 +427,7 @@ class calendar_ical extends calendar_boupdate
|
||||
case 'ATTENDEE':
|
||||
foreach ((array)$event['participants'] as $uid => $status)
|
||||
{
|
||||
$quantity = $role = null;
|
||||
calendar_so::split_status($status, $quantity, $role);
|
||||
// do not include event owner/ORGANIZER as participant in his own calendar, if he is only participant
|
||||
if (count($event['participants']) == 1 && $event['owner'] == $uid) continue;
|
||||
@ -442,10 +441,9 @@ class calendar_ical extends calendar_boupdate
|
||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__ .
|
||||
'()attendee:' . array2string($info) ."\n",3,$this->logfile);
|
||||
}
|
||||
$participantCN = trim(empty($info['cn']) ? $info['name'] : $info['cn']);
|
||||
$participantCN = str_replace(array('\\', ',', ';', ':'),
|
||||
array('\\\\', '\\,', '\\;', '\\:'),
|
||||
$participantCN);
|
||||
trim(empty($info['cn']) ? $info['name'] : $info['cn']));
|
||||
if ($version == '1.0')
|
||||
{
|
||||
$participantURL = trim('"' . $participantCN . '"' . (empty($info['email']) ? '' : ' <' . $info['email'] .'>'));
|
||||
@ -861,7 +859,7 @@ class calendar_ical extends calendar_boupdate
|
||||
$attributes['LAST-MODIFIED'] = $event['modified'];
|
||||
}
|
||||
$attributes['DTSTAMP'] = time();
|
||||
foreach ((array)$event['alarm'] as $alarmID => $alarmData)
|
||||
foreach ((array)$event['alarm'] as $alarmData)
|
||||
{
|
||||
// skip over alarms that don't have the minimum required info
|
||||
if (!$alarmData['offset'] && !$alarmData['time']) continue;
|
||||
@ -928,7 +926,7 @@ class calendar_ical extends calendar_boupdate
|
||||
$alarmData['offset'] = false;
|
||||
}
|
||||
|
||||
$valarm = Horde_iCalendar::newComponent('VALARM',$vevent);
|
||||
$valarm = Horde_Icalendar::newComponent('VALARM',$vevent);
|
||||
if ($alarmData['offset'] !== false)
|
||||
{
|
||||
$valarm->setAttribute('TRIGGER', -$alarmData['offset'],
|
||||
@ -1122,6 +1120,7 @@ class calendar_ical extends calendar_boupdate
|
||||
|
||||
date_default_timezone_set($tzid);
|
||||
|
||||
$msg = null;
|
||||
foreach ($events as $event)
|
||||
{
|
||||
if (!is_array($event)) continue; // the iterator may return false
|
||||
@ -1390,8 +1389,7 @@ class calendar_ical extends calendar_boupdate
|
||||
// They can now only remove themselfs, if that is desired, after storing the event first.
|
||||
|| !isset($event['participants'][$event['owner']]))
|
||||
{
|
||||
$status = $event['owner'] == $this->user ? 'A' : 'U';
|
||||
$status = calendar_so::combine_status($status, 1, 'CHAIR');
|
||||
$status = calendar_so::combine_status($event['owner'] == $this->user ? 'A' : 'U', 1, 'CHAIR');
|
||||
if (!is_array($event['participants'])) $event['participants'] = array();
|
||||
$event['participants'][$event['owner']] = $status;
|
||||
}
|
||||
@ -1769,7 +1767,7 @@ class calendar_ical extends calendar_boupdate
|
||||
/**
|
||||
* get the value of an attribute by its name
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param array $components
|
||||
* @param string $name eg. 'DTSTART'
|
||||
* @param string $what ='value'
|
||||
* @return mixed
|
||||
@ -1789,7 +1787,7 @@ class calendar_ical extends calendar_boupdate
|
||||
static function valarm2egw(&$alarms, &$valarm)
|
||||
{
|
||||
$count = 0;
|
||||
foreach ($valarm->_attributes as $vattr)
|
||||
foreach ($valarm->getAllAttributes() as $vattr)
|
||||
{
|
||||
switch ($vattr['name'])
|
||||
{
|
||||
@ -2183,7 +2181,7 @@ class calendar_ical extends calendar_boupdate
|
||||
date_default_timezone_set($tzid);
|
||||
|
||||
$events = array();
|
||||
$vcal = new Horde_iCalendar;
|
||||
$vcal = new Horde_Icalendar;
|
||||
if (!$vcal->parsevCalendar($_vcalData, 'VCALENDAR', $charset))
|
||||
{
|
||||
if ($this->log)
|
||||
@ -2194,9 +2192,7 @@ class calendar_ical extends calendar_boupdate
|
||||
date_default_timezone_set($GLOBALS['egw_info']['server']['server_timezone']);
|
||||
return false;
|
||||
}
|
||||
$version = $vcal->getAttribute('VERSION');
|
||||
|
||||
foreach ($vcal->getComponents() as $n => $component)
|
||||
foreach ($vcal->getComponents() as $component)
|
||||
{
|
||||
if (($event = $this->_ical2egw_callback($component,$this->tzid,$principalURL)))
|
||||
{
|
||||
@ -2209,14 +2205,15 @@ class calendar_ical extends calendar_boupdate
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for egw_ical_iterator to convert Horde_iCalendar_vevent to EGw event array
|
||||
* Callback for egw_ical_iterator to convert Horde_iCalendar_Vevent to EGw event array
|
||||
*
|
||||
* @param Horde_iCalendar $component
|
||||
* @param string $tzid timezone
|
||||
* @param string $principalURL ='' Used for CalDAV imports
|
||||
* @return array|boolean event array or false if $component is no Horde_iCalendar_vevent
|
||||
* @param Horde_Icalendar $container =null container to access attributes on container
|
||||
* @return array|boolean event array or false if $component is no Horde_Icalendar_Vevent
|
||||
*/
|
||||
function _ical2egw_callback(Horde_iCalendar $component, $tzid, $principalURL='')
|
||||
function _ical2egw_callback(Horde_Icalendar $component, $tzid, $principalURL='', Horde_Icalendar $container=null)
|
||||
{
|
||||
//unset($component->_container); _debug_array($component);
|
||||
|
||||
@ -2225,8 +2222,9 @@ class calendar_ical extends calendar_boupdate
|
||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.'() '.get_class($component)." found\n",3,$this->logfile);
|
||||
}
|
||||
|
||||
if (!is_a($component, 'Horde_iCalendar_vevent') ||
|
||||
!($event = $this->vevent2egw($component, $component->_container->getAttribute('VERSION'), $this->supportedFields, $principalURL)))
|
||||
if (!is_a($component, 'Horde_Icalendar_Vevent') ||
|
||||
!($event = $this->vevent2egw($component, $container ? $container->getAttributeDefault('VERSION', '2.0') : '2.0',
|
||||
$this->supportedFields, $principalURL, $container)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -2246,7 +2244,7 @@ class calendar_ical extends calendar_boupdate
|
||||
$alarms = $event['alarm'];
|
||||
foreach ($component->getComponents() as $valarm)
|
||||
{
|
||||
if (is_a($valarm, 'Horde_iCalendar_valarm'))
|
||||
if (is_a($valarm, 'Horde_Icalendar_Valarm'))
|
||||
{
|
||||
$this->valarm2egw($alarms, $valarm);
|
||||
}
|
||||
@ -2266,12 +2264,14 @@ class calendar_ical extends calendar_boupdate
|
||||
* @param string $version vCal version (1.0/2.0)
|
||||
* @param array $supportedFields supported fields of the device
|
||||
* @param string $principalURL ='' Used for CalDAV imports, no longer used in favor of groupdav_principals::url2uid()
|
||||
* @param string $check_component='Horde_iCalendar_vevent'
|
||||
*
|
||||
* @param string $check_component ='Horde_Icalendar_Vevent'
|
||||
* @param Horde_Icalendar $container =null container to access attributes on container
|
||||
* @return array|boolean event on success, false on failure
|
||||
*/
|
||||
function vevent2egw(&$component, $version, $supportedFields, $principalURL='', $check_component='Horde_iCalendar_vevent')
|
||||
function vevent2egw($component, $version, $supportedFields, $principalURL='', $check_component='Horde_Icalendar_Vevent', Horde_Icalendar $container=null)
|
||||
{
|
||||
unset($principalURL); // not longer used, but required in function signature
|
||||
|
||||
if ($check_component && !is_a($component, $check_component))
|
||||
{
|
||||
if ($this->log)
|
||||
@ -2283,8 +2283,8 @@ class calendar_ical extends calendar_boupdate
|
||||
}
|
||||
|
||||
/*
|
||||
$mozillaACK = $component->getAttribute('X-MOZ-LASTACK');
|
||||
if ($this->productName == 'lightning' && !is_a($mozillaACK, 'PEAR_Error'))
|
||||
$mozillaACK = $component->getAttributeDefault('X-MOZ-LASTACK', null);
|
||||
if ($this->productName == 'lightning' && !isset($mozillaACK))
|
||||
{
|
||||
if ($this->log)
|
||||
{
|
||||
@ -2399,7 +2399,7 @@ class calendar_ical extends calendar_boupdate
|
||||
return false; // not a valid entry
|
||||
}
|
||||
// lets see what we can get from the vcard
|
||||
foreach ($component->_attributes as $attributes)
|
||||
foreach ($component->getAllAttributes() as $attributes)
|
||||
{
|
||||
switch ($attributes['name'])
|
||||
{
|
||||
@ -2421,9 +2421,10 @@ class calendar_ical extends calendar_boupdate
|
||||
break;
|
||||
case 'DESCRIPTION':
|
||||
$vcardData['description'] = str_replace("\r\n", "\n", $attributes['value']);
|
||||
$matches = null;
|
||||
if (preg_match('/\s*\[UID:(.+)?\]/Usm', $attributes['value'], $matches))
|
||||
{
|
||||
if (!isset($vCardData['uid'])
|
||||
if (!isset($vcardData['uid'])
|
||||
&& strlen($matches[1]) >= $minimum_uid_length)
|
||||
{
|
||||
$vcardData['uid'] = $matches[1];
|
||||
@ -2463,6 +2464,7 @@ class calendar_ical extends calendar_boupdate
|
||||
switch($type)
|
||||
{
|
||||
case 'D': // 1.0
|
||||
$recurenceMatches = null;
|
||||
if (preg_match('/D(\d+) #(\d+)/', $recurence, $recurenceMatches))
|
||||
{
|
||||
$vcardData['recur_interval'] = $recurenceMatches[1];
|
||||
@ -2495,6 +2497,7 @@ class calendar_ical extends calendar_boupdate
|
||||
$days = explode(' ',trim($recurenceMatches[2]));
|
||||
}
|
||||
|
||||
$repeatMatches = null;
|
||||
if (preg_match('/#(\d+)/',$recurenceMatches[4],$repeatMatches))
|
||||
{
|
||||
if ($repeatMatches[1]) $vcardData['recur_count'] = $repeatMatches[1];
|
||||
@ -2847,6 +2850,7 @@ class calendar_ical extends calendar_boupdate
|
||||
{
|
||||
// keep role 'CHAIR' from an external organizer, even if he is a regular participant with a different role
|
||||
// as this is currently the only way to store an external organizer and send him iMip responses
|
||||
$q = $r = null;
|
||||
if (isset($vcardData['participants'][$uid]) && ($s=$vcardData['participants'][$uid]) &&
|
||||
calendar_so::split_status($s, $q, $r) && $r == 'CHAIR')
|
||||
{
|
||||
@ -2857,9 +2861,11 @@ class calendar_ical extends calendar_boupdate
|
||||
$vcardData['participants'][$uid] =
|
||||
calendar_so::combine_status($status, $quantity, $role);
|
||||
|
||||
if (!$this->calendarOwner && is_numeric($uid) &&
|
||||
$role == 'CHAIR' &&
|
||||
is_a($component->getAttribute('ORGANIZER'), 'PEAR_Error'))
|
||||
try {
|
||||
if (!$this->calendarOwner && is_numeric($uid) && $role == 'CHAIR')
|
||||
$component->getAttribute('ORGANIZER');
|
||||
}
|
||||
catch(Horde_Icalendar_Exception $e)
|
||||
{
|
||||
// we can store the ORGANIZER as event owner
|
||||
$event['owner'] = $uid;
|
||||
@ -2906,9 +2912,8 @@ class calendar_ical extends calendar_boupdate
|
||||
}
|
||||
// check if the entry is a birthday
|
||||
// this field is only set from NOKIA clients
|
||||
try {
|
||||
$agendaEntryType = $component->getAttribute('X-EPOCAGENDAENTRYTYPE');
|
||||
if (!is_a($agendaEntryType, 'PEAR_Error'))
|
||||
{
|
||||
if (strtolower($agendaEntryType) == 'anniversary')
|
||||
{
|
||||
$event['special'] = '1';
|
||||
@ -2921,6 +2926,7 @@ class calendar_ical extends calendar_boupdate
|
||||
$event['special'] = '2';
|
||||
}
|
||||
}
|
||||
catch (Horde_Icalendar_Exception $e) {}
|
||||
|
||||
$event['priority'] = 2; // default
|
||||
$event['alarm'] = $alarms;
|
||||
@ -3001,13 +3007,15 @@ class calendar_ical extends calendar_boupdate
|
||||
}
|
||||
|
||||
// Apple iCal on OS X uses X-CALENDARSERVER-ACCESS: CONFIDENTIAL on VCALANDAR (not VEVENT!)
|
||||
if ($this->productManufacturer == 'GroupDAV' &&
|
||||
($x_calendarserver_access = $component->_container->getAttribute('X-CALENDARSERVER-ACCESS')) &&
|
||||
!is_a($x_calendarserver_access, 'PEAR_Error'))
|
||||
try {
|
||||
if ($this->productManufacturer == 'GroupDAV' && $container &&
|
||||
($x_calendarserver_access = $container->getAttribute('X-CALENDARSERVER-ACCESS')))
|
||||
{
|
||||
$event['public'] = (int)(strtoupper($x_calendarserver_access) == 'PUBLIC');
|
||||
}
|
||||
//error_log(__METHOD__."() X-CALENDARSERVER-ACCESS=".array2string($x_calendarserver_access).' --> public='.array2string($event['public']));
|
||||
}
|
||||
catch (Horde_Icalendar_Exception $e) {}
|
||||
|
||||
// if no end is given in iCal we use the default lenght from user prefs
|
||||
// whole day events get one day in calendar_boupdate::save()
|
||||
@ -3019,8 +3027,7 @@ class calendar_ical extends calendar_boupdate
|
||||
if ($this->calendarOwner) $event['owner'] = $this->calendarOwner;
|
||||
|
||||
// parsing ATTACH attributes for managed attachments
|
||||
$attr = $component->getAttribute('X-EGROUPWARE-ATTACH-INCLUDED');
|
||||
$event['attach-delete-by-put'] = !is_a($attr, PEAR_Error) && $attr === 'TRUE';
|
||||
$event['attach-delete-by-put'] = $component->getAttributeDefault('X-EGROUPWARE-ATTACH-INCLUDED', null) === 'TRUE';
|
||||
$event['attach'] = $component->getAllAttributes('ATTACH');
|
||||
|
||||
if ($this->log)
|
||||
@ -3078,14 +3085,13 @@ class calendar_ical extends calendar_boupdate
|
||||
if (!$start) $start = time(); // default now
|
||||
if (!$end) $end = time() + 100*DAY_s; // default next 100 days
|
||||
|
||||
$vcal = new Horde_iCalendar;
|
||||
$vcal = new Horde_Icalendar;
|
||||
$vcal->setAttribute('PRODID','-//EGroupware//NONSGML EGroupware Calendar '.$GLOBALS['egw_info']['apps']['calendar']['version'].'//'.
|
||||
strtoupper($GLOBALS['egw_info']['user']['preferences']['common']['lang']));
|
||||
$vcal->setAttribute('VERSION','2.0');
|
||||
$vcal->setAttribute('METHOD',$method);
|
||||
|
||||
$vfreebusy = Horde_iCalendar::newComponent('VFREEBUSY',$vcal);
|
||||
if ($uid) $vfreebusy->setAttribute('UID', $uid);
|
||||
$vfreebusy = Horde_Icalendar::newComponent('VFREEBUSY',$vcal);
|
||||
|
||||
$attributes = array(
|
||||
'DTSTAMP' => time(),
|
||||
|
@ -380,30 +380,24 @@ class calendar_timezones
|
||||
/**
|
||||
* Add VTIMEZONE component to VCALENDAR
|
||||
*
|
||||
* @param Horde_iCalendar $vcal
|
||||
* @param Horde_Icalendar $vcal
|
||||
* @param string $tzid
|
||||
* @return boolean false if no vtimezone component available, true on success
|
||||
*/
|
||||
public static function add_vtimezone($vcal, $tzid)
|
||||
public static function add_vtimezone(Horde_Icalendar $vcal, $tzid)
|
||||
{
|
||||
include_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php';
|
||||
// checking type of $val, now we included the object definition (no need to always include it!)
|
||||
if (!$vcal instanceof Horde_iCalendar)
|
||||
{
|
||||
throw new egw_exception_wrong_parameter(__METHOD__.'('.array2string($vcal).", '$tzid') no Horde_iCalendar!");
|
||||
}
|
||||
// check if we have vtimezone component data for $tzid
|
||||
if (!($vtimezone = calendar_timezones::tz2id($tzid, 'component')))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// $vtimezone is a string with a single VTIMEZONE component, afaik Horde_iCalendar can not add it directly
|
||||
// --> we have to parse it and let Horde_iCalendar add it again
|
||||
$horde_vtimezone = Horde_iCalendar::newComponent('VTIMEZONE',$container=false);
|
||||
// $vtimezone is a string with a single VTIMEZONE component, afaik Horde_Icalendar can not add it directly
|
||||
// --> we have to parse it and let Horde_Icalendar add it again
|
||||
$horde_vtimezone = Horde_Icalendar::newComponent('VTIMEZONE',$container=false);
|
||||
$horde_vtimezone->parsevCalendar($vtimezone,'VTIMEZONE');
|
||||
// DTSTART is in UTC time, Horde_iCalendar parses it in server timezone, which we need to set again for printing
|
||||
// DTSTART is in UTC time, Horde_Icalendar parses it in server timezone, which we need to set again for printing
|
||||
$standard = $horde_vtimezone->findComponent('STANDARD');
|
||||
if (is_a($standard, 'Horde_iCalendar'))
|
||||
if (is_a($standard, 'Horde_Icalendar'))
|
||||
{
|
||||
$time = $standard->getAttribute('DTSTART');
|
||||
$dtstart = new egw_time($time, egw_time::$server_timezone);
|
||||
@ -411,7 +405,7 @@ class calendar_timezones
|
||||
$standard->setAttribute('DTSTART', $dtstart->format('Ymd\THis'), array(), false);
|
||||
}
|
||||
$daylight = $horde_vtimezone->findComponent('DAYLIGHT');
|
||||
if (is_a($daylight, 'Horde_iCalendar'))
|
||||
if (is_a($daylight, 'Horde_Icalendar'))
|
||||
{
|
||||
$time = $daylight->getAttribute('DTSTART');
|
||||
$dtstart = new egw_time($time, egw_time::$server_timezone);
|
||||
@ -448,9 +442,8 @@ class calendar_timezones
|
||||
switch ($type)
|
||||
{
|
||||
case 'vcalendar':
|
||||
include_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php';
|
||||
// checking type of $val, now we included the object definition (no need to always include it!)
|
||||
$vcal = new Horde_iCalendar;
|
||||
$vcal = new Horde_Icalendar;
|
||||
$vcal->setAttribute('PRODID','-//EGroupware//NONSGML EGroupware Calendar '.$GLOBALS['egw_info']['apps']['calendar']['version'].'//'.
|
||||
strtoupper($GLOBALS['egw_info']['user']['preferences']['common']['lang']));
|
||||
self::add_vtimezone($vcal, $tzid);
|
||||
|
@ -7,12 +7,10 @@
|
||||
* @package infolog
|
||||
* @subpackage groupdav
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2007-13 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2007-15 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php';
|
||||
|
||||
/**
|
||||
* EGroupware: GroupDAV access: infolog handler
|
||||
*
|
||||
@ -66,7 +64,7 @@ class infolog_groupdav extends groupdav_handler
|
||||
parent::__construct($app, $groupdav);
|
||||
|
||||
$this->bo = new infolog_bo();
|
||||
$this->vCalendar = new Horde_iCalendar;
|
||||
$this->vCalendar = new Horde_Icalendar;
|
||||
|
||||
// since 1.9.002 we allow clients to specify the URL when creating a new event, as specified by CalDAV
|
||||
if (version_compare($GLOBALS['egw_info']['apps']['calendar']['version'], '1.9.002', '>='))
|
||||
|
@ -7,13 +7,10 @@
|
||||
* @author Joerg Lehrke <jlehrke@noc.de>
|
||||
* @author Ralf Becker <RalfBecker@outdoor-training.de>
|
||||
* @package infolog
|
||||
* @subpackage syncml
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php';
|
||||
|
||||
/**
|
||||
* InfoLog: Create and parse iCal's
|
||||
*/
|
||||
@ -119,7 +116,7 @@ class infolog_ical extends infolog_bo
|
||||
*/
|
||||
function exportVCalendar(array $tasks, $_version='2.0', $_method=null, $charset='UTF-8')
|
||||
{
|
||||
$vcal = new Horde_iCalendar;
|
||||
$vcal = new Horde_Icalendar;
|
||||
|
||||
foreach($tasks as $task)
|
||||
{
|
||||
@ -138,11 +135,11 @@ class infolog_ical extends infolog_bo
|
||||
* @param string $_version ='2.0' could be '1.0' too
|
||||
* @param string $_method ='PUBLISH'
|
||||
* @param string $charset ='UTF-8' encoding of the vcalendar, default UTF-8
|
||||
* @param Horde_iCalendar $vcal=null optional iCalendar object to add vtodo to
|
||||
* @param Horde_Icalendar $vcal =null optional iCalendar object to add vtodo to
|
||||
*
|
||||
* @return string|boolean string with vCal or false on error (eg. no permission to read the event)
|
||||
*/
|
||||
function exportVTODO($task, $_version='2.0',$_method='PUBLISH', $charset='UTF-8',Horde_iCalendar $vcal=null)
|
||||
function exportVTODO($task, $_version='2.0',$_method='PUBLISH', $charset='UTF-8',Horde_Icalendar $vcal=null)
|
||||
{
|
||||
if (is_array($task))
|
||||
{
|
||||
@ -190,7 +187,7 @@ class infolog_ical extends infolog_bo
|
||||
array2string($taskData)."\n",3,$this->logfile);
|
||||
}
|
||||
|
||||
if (!isset($vcal)) $vcal = new Horde_iCalendar;
|
||||
if (!isset($vcal)) $vcal = new Horde_Icalendar;
|
||||
$vcal->setAttribute('PRODID','-//EGroupware//NONSGML EGroupware InfoLog '.$GLOBALS['egw_info']['apps']['infolog']['version'].'//'.
|
||||
strtoupper($GLOBALS['egw_info']['user']['preferences']['common']['lang']),array(),false);
|
||||
$vcal->setAttribute('VERSION',$_version,array(),false);
|
||||
@ -203,7 +200,7 @@ class infolog_ical extends infolog_bo
|
||||
if (!calendar_timezones::add_vtimezone($vcal, $tzid))
|
||||
{
|
||||
error_log(__METHOD__."() unknown TZID='$tzid', defaulting to user timezone '".egw_time::$user_timezone->getName()."'!");
|
||||
calendar_timezones::add_vtimezone($vcal, $tzid=egw_time::$user_timezone->getName());
|
||||
calendar_timezones::add_vtimezone($vcal, egw_time::$user_timezone->getName());
|
||||
$tzid = null;
|
||||
}
|
||||
if (!isset(self::$tz_cache[$tzid]))
|
||||
@ -212,7 +209,7 @@ class infolog_ical extends infolog_bo
|
||||
}
|
||||
}
|
||||
|
||||
$vevent = Horde_iCalendar::newComponent('VTODO',$vcal);
|
||||
$vevent = Horde_Icalendar::newComponent('VTODO',$vcal);
|
||||
|
||||
if (!isset($this->clientProperties['SUMMARY']['Size']))
|
||||
{
|
||||
@ -407,7 +404,7 @@ class infolog_ical extends infolog_bo
|
||||
if ($value[1] == ':' && ($v = unserialize($value)) !== false) $value = $v;
|
||||
foreach((array)$value as $compvData)
|
||||
{
|
||||
$comp = Horde_iCalendar::newComponent(substr($name,3), $vevent);
|
||||
$comp = Horde_Icalendar::newComponent(substr($name,3), $vevent);
|
||||
$comp->parsevCalendar($compvData,substr($name,3),'utf-8');
|
||||
$vevent->addComponent($comp);
|
||||
}
|
||||
@ -440,7 +437,7 @@ class infolog_ical extends infolog_bo
|
||||
* set date-time attribute to DATE or DATE-TIME depending on value
|
||||
* 00:00 uses DATE else DATE-TIME
|
||||
*
|
||||
* @param Horde_iCalendar_* $vevent
|
||||
* @param Horde_Icalendar_* $vevent
|
||||
* @param string $attr attribute name
|
||||
* @param int $time timestamp in server-time
|
||||
* @param string $tzid timezone to use for client, null for user-time, false for server-time
|
||||
@ -448,7 +445,7 @@ class infolog_ical extends infolog_bo
|
||||
static function setDateOrTime(&$vevent, $attr, $time, $tzid)
|
||||
{
|
||||
$params = array();
|
||||
$time_in = $time;
|
||||
//$time_in = $time;
|
||||
|
||||
if ($tzid)
|
||||
{
|
||||
@ -508,7 +505,7 @@ class infolog_ical extends infolog_bo
|
||||
*
|
||||
* @param string $_vcalData
|
||||
* @param int $_taskID =-1 info_id, default -1 = new entry
|
||||
* @param boolean $merge=false merge data with existing entry
|
||||
* @param boolean $merge =false merge data with existing entry (no longer used)
|
||||
* @param int $user =null delegate new task to this account_id, default null
|
||||
* @param string $charset =null The encoding charset for $text. Defaults to
|
||||
* utf-8 for new format, iso-8859-1 for old format.
|
||||
@ -520,6 +517,7 @@ class infolog_ical extends infolog_bo
|
||||
function importVTODO(&$_vcalData, $_taskID=-1, $merge=false, $user=null, $charset=null, $caldav_name=null,
|
||||
array $callback_data=null)
|
||||
{
|
||||
unset($merge); // no longer used, but required by function signature
|
||||
|
||||
if ($this->tzid)
|
||||
{
|
||||
@ -575,7 +573,7 @@ class infolog_ical extends infolog_bo
|
||||
'info_access','info_status','info_percent','info_datecompleted',
|
||||
)));
|
||||
// remove all iCal fields not supported by EGroupware (stored like custom fields)
|
||||
foreach($old as $name => $value)
|
||||
foreach(array_keys($old) as $name)
|
||||
{
|
||||
if (substr($name,0,2) == '##') unset($old[$name]);
|
||||
}
|
||||
@ -644,7 +642,7 @@ class infolog_ical extends infolog_bo
|
||||
array2string($_vcalData)."\n",3,$this->logfile);
|
||||
}
|
||||
|
||||
$vcal = new Horde_iCalendar;
|
||||
$vcal = new Horde_Icalendar;
|
||||
if (!($vcal->parsevCalendar($_vcalData, 'VCALENDAR', $charset)))
|
||||
{
|
||||
if ($this->log)
|
||||
@ -655,8 +653,6 @@ class infolog_ical extends infolog_bo
|
||||
return false;
|
||||
}
|
||||
|
||||
$version = $vcal->getAttribute('VERSION');
|
||||
|
||||
if (isset($GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length']))
|
||||
{
|
||||
$minimum_uid_length = $GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length'];
|
||||
@ -670,7 +666,7 @@ class infolog_ical extends infolog_bo
|
||||
|
||||
foreach ($vcal->getComponents() as $component)
|
||||
{
|
||||
if (!is_a($component, 'Horde_iCalendar_vtodo'))
|
||||
if (!is_a($component, 'Horde_Icalendar_Vtodo'))
|
||||
{
|
||||
if ($this->log)
|
||||
{
|
||||
@ -689,15 +685,19 @@ class infolog_ical extends infolog_bo
|
||||
// iOS reminder app only sets COMPLETED, but never STATUS nor PERCENT-COMPLETED
|
||||
// if we have no STATUS, set STATUS by existence of COMPLETED and/or PERCENT-COMPLETE and X-INFOLOG-STATUS
|
||||
// if we have no PERCENT-COMPLETE set it from STATUS: 0=NEEDS-ACTION, 10=IN-PROCESS, 100=COMPLETED
|
||||
if (!($status = $component->getAttribute('STATUS')) || !is_scalar($status))
|
||||
try {
|
||||
$status = $component->getAttribute('STATUS');
|
||||
}
|
||||
catch (Horde_Icalendar_Exception $e)
|
||||
{
|
||||
$completed = $component->getAttribute('COMPLETED');
|
||||
$x_infolog_status = $component->getAttribute('X-INFOLOG-STATUS');
|
||||
unset($e);
|
||||
$completed = $component->getAttributeDefault('COMPLETED', null);
|
||||
$x_infolog_status = $component->getAttributeDefault('X-INFOLOG-STATUS', null);
|
||||
// check if we have a X-INFOLOG-STATUS and it's completed state is different from given COMPLETED attr
|
||||
if (is_scalar($x_infolog_status) &&
|
||||
($this->_status2vtodo[$x_infolog_status] === 'COMPLETED') != is_scalar($completed))
|
||||
{
|
||||
$percent_completed = $component->getAttribute('PERCENT-COMPLETE');
|
||||
$percent_completed = $component->getAttributeDefault('PERCENT-COMPLETE', null);
|
||||
$status = $completed && is_scalar($completed) ? 'COMPLETED' :
|
||||
($percent_completed && is_scalar($percent_completed) && $percent_completed > 0 ? 'IN-PROCESS' : 'NEEDS-ACTION');
|
||||
$component->setAttribute('STATUS', $status);
|
||||
@ -731,6 +731,7 @@ class infolog_ical extends infolog_bo
|
||||
|
||||
case 'DESCRIPTION':
|
||||
$value = str_replace("\r\n", "\n", $attribute['value']);
|
||||
$matches = null;
|
||||
if (preg_match('/\s*\[UID:(.+)?\]/Usm', $value, $matches))
|
||||
{
|
||||
if (!isset($taskData['info_uid'])
|
||||
@ -759,7 +760,7 @@ class infolog_ical extends infolog_bo
|
||||
case 'DURATION':
|
||||
if (!isset($taskData['info_startdate']))
|
||||
{
|
||||
$taskData['info_startdate'] = $component->getAttribute('DTSTART');
|
||||
$taskData['info_startdate'] = $component->getAttributeDefault('DTSTART', null);
|
||||
}
|
||||
$attribute['value'] += $taskData['info_startdate'];
|
||||
$taskData['##DURATION'] = $attribute['value'];
|
||||
@ -803,7 +804,7 @@ class infolog_ical extends infolog_bo
|
||||
case 'STATUS':
|
||||
// check if we (still) have X-INFOLOG-STATUS set AND it would give an unchanged status (no change by the user)
|
||||
$taskData['info_status'] = $this->vtodo2status($attribute['value'],
|
||||
($attr=$component->getAttribute('X-INFOLOG-STATUS')) && is_scalar($attr) ? $attr : null);
|
||||
$component->getAttributeDefault('X-INFOLOG-STATUS', null));
|
||||
break;
|
||||
|
||||
case 'SUMMARY':
|
||||
@ -923,7 +924,7 @@ class infolog_ical extends infolog_bo
|
||||
$note['info_cat'] = translation::convert($cats[0],
|
||||
translation::charset(), $charset);
|
||||
}
|
||||
$vnote = new Horde_iCalendar_vnote();
|
||||
$vnote = new Horde_Icalendar_Vnote();
|
||||
$vnote->setAttribute('PRODID','-//EGroupware//NONSGML EGroupware InfoLog '.$GLOBALS['egw_info']['apps']['infolog']['version'].'//'.
|
||||
strtoupper($GLOBALS['egw_info']['user']['preferences']['common']['lang']));
|
||||
$vnote->setAttribute('VERSION', '1.1');
|
||||
@ -961,15 +962,15 @@ class infolog_ical extends infolog_bo
|
||||
$options['ENCODING'] = 'FUNAMBOL-QP';
|
||||
}
|
||||
}
|
||||
$vevent->setAttribute($field, $value, $options);
|
||||
$vnote->setAttribute($field, $value, $options);
|
||||
}
|
||||
if ($note['info_startdate'])
|
||||
{
|
||||
$vnote->setAttribute('DCREATED',$note['info_startdate']);
|
||||
$vnote->setAttribute('CREATED',$note['info_startdate']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$vnote->setAttribute('DCREATED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_note',$_noteID,'add'));
|
||||
$vnote->setAttribute('CREATED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_note',$_noteID,'add'));
|
||||
}
|
||||
$vnote->setAttribute('LAST-MODIFIED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_note',$_noteID,'modify'));
|
||||
|
||||
@ -992,7 +993,7 @@ class infolog_ical extends infolog_bo
|
||||
* @param string $_vcalData
|
||||
* @param string $_type content type (eg.g text/plain)
|
||||
* @param int $_noteID =-1 info_id, default -1 = new entry
|
||||
* @param boolean $merge=false merge data with existing entry
|
||||
* @param boolean $merge =false merge data with existing entry (no longer used)
|
||||
* @param string $charset The encoding charset for $text. Defaults to
|
||||
* utf-8 for new format, iso-8859-1 for old format.
|
||||
*
|
||||
@ -1000,6 +1001,7 @@ class infolog_ical extends infolog_bo
|
||||
*/
|
||||
function importVNOTE(&$_vcalData, $_type, $_noteID=-1, $merge=false, $charset=null)
|
||||
{
|
||||
unset($merge); // no longer used, but required by function signature
|
||||
if ($this->log)
|
||||
{
|
||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||
@ -1068,9 +1070,9 @@ class infolog_ical extends infolog_bo
|
||||
case 'text/plain':
|
||||
$note = array();
|
||||
$note['info_type'] = 'note';
|
||||
$txt = translation::convert($_data, $charset);
|
||||
$txt = str_replace("\r\n", "\n", $txt);
|
||||
$txt = str_replace("\r\n", "\n", translation::convert($_data, $charset));
|
||||
|
||||
$match = null;
|
||||
if (preg_match('/([^\n]+)\n\n(.*)/ms', $txt, $match))
|
||||
{
|
||||
$note['info_subject'] = $match[1];
|
||||
@ -1083,19 +1085,18 @@ class infolog_ical extends infolog_bo
|
||||
break;
|
||||
|
||||
case 'text/x-vnote':
|
||||
$vnote = new Horde_iCalendar;
|
||||
if (!$vcal->parsevCalendar($_data, 'VCALENDAR', $charset)) return false;
|
||||
$version = $vcal->getAttribute('VERSION');
|
||||
$vnote = new Horde_Icalendar;
|
||||
if (!$vnote->parsevCalendar($_data, 'VCALENDAR', $charset)) return false;
|
||||
|
||||
$components = $vnote->getComponent();
|
||||
foreach ($components as $component)
|
||||
{
|
||||
if (is_a($component, 'Horde_iCalendar_vnote'))
|
||||
if (is_a($component, 'Horde_Icalendar_Vnote'))
|
||||
{
|
||||
$note = array();
|
||||
$note['info_type'] = 'note';
|
||||
|
||||
foreach ($component->_attributes as $attribute)
|
||||
foreach ($component->getAllAttributes() as $attribute)
|
||||
{
|
||||
switch ($attribute['name'])
|
||||
{
|
||||
@ -1193,10 +1194,9 @@ class infolog_ical extends infolog_bo
|
||||
")\n" , 3, $this->logfile);
|
||||
}
|
||||
|
||||
Horde::logMessage('setSupportedFields(' . $this->productManufacturer . ', '
|
||||
. $this->productName .', ' .
|
||||
($this->tzid ? $this->tzid : egw_time::$user_timezone->getName()) .')',
|
||||
__FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||
|
||||
//Horde::logMessage('setSupportedFields(' . $this->productManufacturer . ', '
|
||||
// . $this->productName .', ' .
|
||||
// ($this->tzid ? $this->tzid : egw_time::$user_timezone->getName()) .')',
|
||||
// __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user