Optimized SyncML memory footprint; fixes various filter issues

This commit is contained in:
Jörg Lehrke 2009-11-29 14:03:45 +00:00
parent 7c67b5bd59
commit a0e1a238dd
3 changed files with 78 additions and 40 deletions

View File

@ -86,6 +86,13 @@ class calendar_ical extends calendar_boupdate
*/
var $uidExtension = false;
/**
* user preference: calendar to synchronize with
*
* @var int
*/
var $calendarOwner = 0;
/**
* Original timezone
*
@ -942,6 +949,7 @@ class calendar_ical extends calendar_boupdate
unset($event_to_store);
$event['reference'] = $event_info['master_event']['id'];
$event['category'] = $event_info['master_event']['category'];
$event['owner'] = $event_info['master_event']['owner'];
}
$event_to_store = $event; // prevent $event from being changed by update method
@ -1160,6 +1168,14 @@ class calendar_ical extends calendar_boupdate
{
$this->tzid = $deviceInfo['tzid'];
}
if (isset($GLOBALS['egw_info']['user']['preferences']['syncml']['calendar_owner']))
{
$owner = $GLOBALS['egw_info']['user']['preferences']['syncml']['calendar_owner'];
if (0 < (int)$owner && $this->check_perms(EGW_ACL_EDIT,0,$owner))
{
$this->calendarOwner = $owner;
}
}
if (!isset($this->productManufacturer) ||
$this->productManufacturer == '' ||
$this->productManufacturer == 'file')
@ -1549,7 +1565,7 @@ class calendar_ical extends calendar_boupdate
$recurence = $attributes['value'];
$type = preg_match('/FREQ=([^;: ]+)/i',$recurence,$matches) ? $matches[1] : $recurence[0];
// vCard 2.0 values for all types
if (preg_match('/UNTIL=([0-9T]+)/',$recurence,$matches))
if (preg_match('/UNTIL=([0-9TZ]+)/',$recurence,$matches))
{
$vcardData['recur_enddate'] = $this->vCalendar->_parseDateTime($matches[1]);
}
@ -1886,11 +1902,7 @@ class calendar_ical extends calendar_boupdate
{
//Horde::logMessage("vevent2egw: group participant $uid",
// __FILE__, __LINE__, PEAR_LOG_DEBUG);
if ($status == 'U')
{
}
else
if ($status != 'U')
{
// User tries to reply to the group invitiation
$members = $GLOBALS['egw']->accounts->members($uid, true);
@ -1904,7 +1916,7 @@ class calendar_ical extends calendar_boupdate
continue;
}
}
else continue; // can not find this group
else continue; // can't find this group
}
elseif ($attributes['value'] == 'Unknown')
{
@ -1954,12 +1966,14 @@ class calendar_ical extends calendar_boupdate
$event['participants'][$uid] =
calendar_so::combine_status($status, $quantity, 'CHAIR');
}
if (is_numeric($uid))
if (is_numeric($uid) && ($uid == $this->calendarOwner || !$this->calendarOwner))
{
// we can store the ORGANIZER as event owner
$event['owner'] = $uid;
}
else
{
// we must insert a CHAIR participant to keep the ORGANIZER
$event['owner'] = $this->user;
if (!isset($event['participants'][$uid]))
{
@ -1968,7 +1982,6 @@ class calendar_ical extends calendar_boupdate
calendar_so::combine_status('U', 1, 'CHAIR');
}
}
break;
}
break;
case 'CREATED': // will be written direct to the event
@ -2048,6 +2061,7 @@ class calendar_ical extends calendar_boupdate
break;
}
}
if ($this->calendarOwner) $event['owner'] = $this->calendarOwner;
//Horde::logMessage("vevent2egw:\n" . print_r($event, true),
// __FILE__, __LINE__, PEAR_LOG_DEBUG);
return $event;
@ -2239,8 +2253,8 @@ class calendar_ical extends calendar_boupdate
$recurrence_event['start'] = $event['recurrence'];
$recurrence_event['end'] = $event['recurrence'] + ($master_event['end'] - $master_event['start']);
// check for changed data
foreach (array('start','end','uid','owner','title','description',
'location','priority','public','special','non_blocking') as $key)
foreach (array('start','end','uid','title','location',
'priority','public','special','non_blocking') as $key)
{
if (!empty($event[$key]) && $recurrence_event[$key] != $event[$key])
{

View File

@ -935,6 +935,8 @@ ORDER BY cal_user_type, cal_usre_id
*/
function participants($cal_id,$participants,$change_since=0,$add_only=false)
{
$recurrences = array();
// remove group-invitations, they are NOT stored in the db
foreach($participants as $uid => $status)
{
@ -950,8 +952,15 @@ ORDER BY cal_user_type, cal_usre_id
$where[0] = '(cal_recur_date=0 OR cal_recur_date >= '.(int)$change_since.')';
}
if ($change_since !== false) // update existing entries
if ($change_since !== false)
{
// find all existing recurrences
foreach($this->db->select($this->user_table,'DISTINCT cal_recur_date',$where,__LINE__,__FILE__,false,'','calendar') as $row)
{
$recurrences[] = $row['cal_recur_date'];
}
// update existing entries
$existing_entries = $this->db->select($this->user_table,'DISTINCT cal_user_type,cal_user_id',$where,__LINE__,__FILE__,false,'','calendar');
// create a full list of participants which already exist in the db
@ -999,16 +1008,7 @@ ORDER BY cal_user_type, cal_usre_id
if (count($participants)) // participants which need to be added
{
// find all recurrences, as they all need the new parts to be added
$recurrences = array();
if ($change_since !== false) // existing entries
{
foreach($this->db->select($this->user_table,'DISTINCT cal_recur_date',$where,__LINE__,__FILE__,false,'','calendar') as $row)
{
$recurrences[] = $row['cal_recur_date'];
}
}
if (!count($recurrences)) $recurrences[] = 0; // insert the default one
if (!count($recurrences)) $recurrences[] = 0; // insert the default recurrence
// update participants
foreach($participants as $uid => $status)
@ -1315,7 +1315,7 @@ ORDER BY cal_user_type, cal_usre_id
{
$user_type = '';
$user_id = null;
$this->split_user($old_user,$user_type,$user_id);
self::split_user($old_user,$user_type,$user_id);
if ($user_type == 'u') // only accounts can be owners of events
{
@ -1369,14 +1369,24 @@ ORDER BY cal_user_type, cal_usre_id
*
* @param int $cal_id
* @param int $uid participant uid
* @param int $start=0 if != 0: startdate of the search/list (servertime)
* @param int $end=0 if != 0: enddate of the search/list (servertime)
*
* @return array recur_date => status pairs (index 0 => main status)
*/
function get_recurrences($cal_id, $uid)
function get_recurrences($cal_id, $uid, $start=0, $end=0)
{
$user_type = $user_id = null;
$this->split_user($uid, $user_type, $user_id);
self::split_user($uid, $user_type, $user_id);
$participant_status = array();
$where = array('cal_id' => $cal_id);
if ($start != 0 && $end == 0) $where[] = '(cal_recur_date = 0 OR cal_recur_date >= ' . (int)$start . ')';
if ($start == 0 && $end != 0) $where[] = '(cal_recur_date = 0 OR cal_recur_date =< ' . (int)$end . ')';
if ($start != 0 && $end != 0)
{
$where[] = '(cal_recur_date = 0 OR (cal_recur_date >= ' . (int)$start .
' AND cal_recur_date <= ' . (int)$end . '))';
}
foreach($this->db->select($this->user_table,'DISTINCT cal_recur_date',$where,__LINE__,__FILE__,false,'','calendar') as $row)
{
// inititalize the array
@ -1387,6 +1397,13 @@ ORDER BY cal_user_type, cal_usre_id
'cal_user_type' => $user_type ? $user_type : 'u',
'cal_user_id' => $user_id,
);
if ($start != 0 && $end == 0) $where[] = '(cal_recur_date = 0 OR cal_recur_date >= ' . (int)$start . ')';
if ($start == 0 && $end != 0) $where[] = '(cal_recur_date = 0 OR cal_recur_date =< ' . (int)$end . ')';
if ($start != 0 && $end != 0)
{
$where[] = '(cal_recur_date = 0 OR (cal_recur_date >= ' . (int)$start .
' AND cal_recur_date <= ' . (int)$end . '))';
}
foreach ($this->db->select($this->user_table,'cal_recur_date,cal_status,cal_quantity,cal_role',$where,
__LINE__,__FILE__,false,'','calendar') as $row)
{
@ -1416,7 +1433,7 @@ ORDER BY cal_user_type, cal_usre_id
foreach ($this->db->select($this->user_table,'DISTINCT cal_user_type,cal_user_id', $where,
__LINE__,__FILE__,false,'','calendar') as $row)
{
$uid = $this->combine_user($row['cal_user_type'], $row['cal_user_id']);
$uid = self::combine_user($row['cal_user_type'], $row['cal_user_id']);
$id = $row['cal_user_type'] . $row['cal_user_id'];
$participants[$id]['type'] = $row['cal_user_type'];
$participants[$id]['id'] = $row['cal_user_id'];
@ -1456,10 +1473,12 @@ ORDER BY cal_user_type, cal_usre_id
*
* @param array $event Recurring Event.
* @param string tz_id=null timezone for exports (null for event's timezone)
* @param int $start=0 if != 0: startdate of the search/list (servertime)
* @param int $end=0 if != 0: enddate of the search/list (servertime)
*
* @return array Array of exception days (false for non-recurring events).
*/
function get_recurrence_exceptions(&$event, $tz_id=null)
function get_recurrence_exceptions(&$event, $tz_id=null, $start=0, $end=0)
{
$cal_id = (int) $event['id'];
if (!$cal_id || $event['recur_type'] == MCAL_RECUR_NONE) return false;
@ -1489,7 +1508,7 @@ ORDER BY cal_user_type, cal_usre_id
case 'u': // account
case 'c': // contact
case 'e': // email address
$recurrences = $this->get_recurrences($event['id'], $uid);
$recurrences = $this->get_recurrences($event['id'], $uid, $start, $end);
foreach ($recurrences as $recur_date => $recur_status)
{
if ($recur_date)

View File

@ -423,15 +423,28 @@ class Horde_SyncML_Sync_TwoWaySync extends Horde_SyncML_Sync {
'type' => $syncType,
'filter' => $this->_filterExpression
)));
$state->mergeChangedItems($syncType, $registry->call($hordeType . '/listBy', array (
$changedItems =& $registry->call($hordeType . '/listBy', array (
'action' => 'modify',
'timestamp' => $refts,
'type' => $syncType,
'filter' => $this->_filterExpression
)));
));
$addedItems =& $registry->call($hordeType . '/listBy', array (
'action' => 'add',
'timestamp' => $refts,
'type' => $syncType,
'filter' => $this->_filterExpression
));
// added items may show up as changed, too
$changedItems = array_diff($changedItems, $addedItems);
$state->mergeChangedItems($syncType, $changedItems);
$state->mergeAddedItems($syncType, $addedItems);
Horde :: logMessage("SyncML: reading deleted items from database for $hordeType",
__FILE__, __LINE__, PEAR_LOG_DEBUG);
$state->setDeletedItems($syncType, $registry->call($hordeType . '/listBy', array (
'action' => 'delete',
'timestamp' => $refts,
@ -439,8 +452,6 @@ class Horde_SyncML_Sync_TwoWaySync extends Horde_SyncML_Sync {
'filter' => $this->_filterExpression
)));
Horde :: logMessage("SyncML: reading added items from database for $hordeType",
__FILE__, __LINE__, PEAR_LOG_DEBUG);
/* The items, which now match the filter criteria are show here, too
$delta_add = count($registry->call($hordeType . '/listBy', array (
'action' => 'add',
@ -449,12 +460,6 @@ class Horde_SyncML_Sync_TwoWaySync extends Horde_SyncML_Sync {
'filter' => $this->_filterExpression
)));
*/
$state->mergeAddedItems($syncType, $registry->call($hordeType . '/listBy', array (
'action' => 'add',
'timestamp' => $refts,
'type' => $syncType,
'filter' => $this->_filterExpression
)));
$this->_syncDataLoaded = TRUE;