forked from extern/egroupware
- move all filtering into SQL query in calendar_so, to be able to correctly return N rows starting from row M
- re-enabling propfind iterator again for calendar (fetching events in chunks of 500), to lower memory footprint Please note: changed SQL queries used for CalDAV do not take changed participants (or status) in exceptions into account
This commit is contained in:
parent
cec35e75d8
commit
66c61cb74e
@ -155,6 +155,10 @@ class calendar_bo
|
||||
* @var array $cached_holidays holidays plus birthdays (gets cached in the session for performance reasons)
|
||||
*/
|
||||
var $cached_holidays;
|
||||
/**
|
||||
* @var boholiday
|
||||
*/
|
||||
var $holidays;
|
||||
/**
|
||||
* Instance of the socal class
|
||||
*
|
||||
@ -422,10 +426,14 @@ class calendar_bo
|
||||
$this->check_move_horizont($end);
|
||||
}
|
||||
$daywise = !isset($params['daywise']) ? False : !!$params['daywise'];
|
||||
$enum_recuring = $daywise || !isset($params['enum_recuring']) || !!$params['enum_recuring'];
|
||||
$params['enum_recuring'] = $enum_recuring = $daywise || !isset($params['enum_recuring']) || !!$params['enum_recuring'];
|
||||
$cat_id = isset($params['cat_id']) ? $params['cat_id'] : 0;
|
||||
$filter = isset($params['filter']) ? $params['filter'] : 'all';
|
||||
$offset = isset($params['offset']) && $params['offset'] !== false ? (int) $params['offset'] : false;
|
||||
// socal::search() returns rejected group-invitations, as only the user not also the group is rejected
|
||||
// as we cant remove them efficiantly in SQL, we kick them out here, but only if just one user is displayed
|
||||
$remove_rejected_by_user = !in_array($filter,array('all','rejected','owner')) && count($params['users']) == 1 ? $params['users'][0] : null;
|
||||
|
||||
if ($this->debug && ($this->debug > 1 || $this->debug == 'search'))
|
||||
{
|
||||
$this->debug_message('calendar_bo::search(%1) start=%2, end=%3, daywise=%4, cat_id=%5, filter=%6, query=%7, offset=%8, num_rows=%9, order=%10, sql_filter=%11)',
|
||||
@ -433,7 +441,7 @@ class calendar_bo
|
||||
}
|
||||
// date2ts(,true) converts to server time, db2data converts again to user-time
|
||||
$events =& $this->so->search(isset($start) ? $this->date2ts($start,true) : null,isset($end) ? $this->date2ts($end,true) : null,
|
||||
$users,$cat_id,$filter,$offset,(int)$params['num_rows'],$params);
|
||||
$users,$cat_id,$filter,$offset,(int)$params['num_rows'],$params,$remove_rejected_by_user);
|
||||
|
||||
if (isset($params['cols']))
|
||||
{
|
||||
@ -442,24 +450,9 @@ class calendar_bo
|
||||
$this->total = $this->so->total;
|
||||
$this->db2data($events,isset($params['date_format']) ? $params['date_format'] : 'ts');
|
||||
|
||||
// socal::search() returns rejected group-invitations, as only the user not also the group is rejected
|
||||
// as we cant remove them efficiantly in SQL, we kick them out here, but only if just one user is displayed
|
||||
$remove_rejected_by_user = !in_array($filter,array('all','rejected','owner')) && count($params['users']) == 1 ? $params['users'][0] : false;
|
||||
//echo "<p align=right>remove_rejected_by_user=$remove_rejected_by_user, filter=$filter, params[users]=".print_r($param['users'])."</p>\n";
|
||||
foreach($events as $id => $event)
|
||||
{
|
||||
if (isset($start) && $event['end'] < $start)
|
||||
{
|
||||
unset($events[$id]); // remove former events (e.g. whole day)
|
||||
$this->total--;
|
||||
continue;
|
||||
}
|
||||
if ($remove_rejected_by_user && $event['participants'][$remove_rejected_by_user] == 'R')
|
||||
{
|
||||
unset($events[$id]); // remove the rejected event
|
||||
$this->total--;
|
||||
continue;
|
||||
}
|
||||
if ($params['enum_groups'] && $this->enum_groups($event))
|
||||
{
|
||||
$events[$id] = $event;
|
||||
@ -515,29 +508,11 @@ class calendar_bo
|
||||
$this->debug_message('socalendar::search daywise events=%1',False,$events);
|
||||
}
|
||||
}
|
||||
elseif(!$enum_recuring)
|
||||
{
|
||||
$recur_ids = array();
|
||||
foreach($events as $k => $event)
|
||||
{
|
||||
if ($event['recur_type'] != MCAL_RECUR_NONE)
|
||||
{
|
||||
if (!in_array($event['id'],$recur_ids))
|
||||
{
|
||||
$recur_ids[] = $event['id'];
|
||||
}
|
||||
unset($events[$k]);
|
||||
}
|
||||
}
|
||||
if (count($recur_ids))
|
||||
{
|
||||
$events = array_merge($this->read($recur_ids,null,false,$params['date_format']),$events);
|
||||
}
|
||||
}
|
||||
if ($this->debug && ($this->debug > 0 || $this->debug == 'search'))
|
||||
{
|
||||
$this->debug_message('calendar_bo::search(%1)=%2',True,$params,$events);
|
||||
}
|
||||
//error_log(__METHOD__."() returning ".count($events)." entries, total=$this->total ".function_backtrace());
|
||||
return $events;
|
||||
}
|
||||
|
||||
@ -1899,7 +1874,8 @@ class calendar_bo
|
||||
$entry['recur_type'] != MCAL_RECUR_NONE && $entry['recur_exception'])
|
||||
{
|
||||
$events =& $this->search(array(
|
||||
'query' => array('cal_uid' => $entry['uid']),
|
||||
//'query' => array('cal_uid' => $entry['uid']),
|
||||
'query' => array('cal_reference' => $entry['id']),
|
||||
'filter' => 'owner', // return all possible entries
|
||||
'daywise' => false,
|
||||
'enum_recuring' => false,
|
||||
|
@ -122,7 +122,12 @@ class calendar_groupdav extends groupdav_handler
|
||||
'enum_recuring' => false,
|
||||
'daywise' => false,
|
||||
'date_format' => 'server',
|
||||
'no_total' => true, // we need no total number of rows (saves extra query)
|
||||
);
|
||||
if ($this->client_shared_uid_exceptions) // do NOT return (non-virtual) exceptions
|
||||
{
|
||||
$filter['query'] = array('cal_reference' => 0);
|
||||
}
|
||||
|
||||
if ($path == '/calendar/')
|
||||
{
|
||||
@ -140,8 +145,7 @@ class calendar_groupdav extends groupdav_handler
|
||||
}
|
||||
if ($this->debug > 1)
|
||||
{
|
||||
error_log(__METHOD__."($path,,,$user,$id) filter=".
|
||||
array2string($filter));
|
||||
error_log(__METHOD__."($path,,,$user,$id) filter=".array2string($filter));
|
||||
}
|
||||
|
||||
// check if we have to return the full calendar data or just the etag's
|
||||
@ -157,12 +161,12 @@ class calendar_groupdav extends groupdav_handler
|
||||
}
|
||||
}
|
||||
}
|
||||
/* disabling not working iterator
|
||||
// return iterator, calling ourself to return result in chunks
|
||||
$files['files'] = new groupdav_propfind_iterator($this,$path,$filter,$files['files']);
|
||||
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Callback for profind interator
|
||||
*
|
||||
@ -171,15 +175,13 @@ class calendar_groupdav extends groupdav_handler
|
||||
* @param array|boolean $start=false false=return all or array(start,num)
|
||||
* @return array with "files" array with values for keys path and props
|
||||
*/
|
||||
/* disabling not working iterator
|
||||
function propfind_callback($path,array $filter,$start=false)
|
||||
{
|
||||
*/
|
||||
if ($this->debug) $starttime = microtime(true);
|
||||
|
||||
$calendar_data = $filter['calendar_data'];
|
||||
unset($filter['calendar_data']);
|
||||
/* disabling not working iterator
|
||||
|
||||
$files = array();
|
||||
|
||||
if (is_array($start))
|
||||
@ -187,8 +189,6 @@ class calendar_groupdav extends groupdav_handler
|
||||
$filter['offset'] = $start[0];
|
||||
$filter['num_rows'] = $start[1];
|
||||
}
|
||||
error_log(__METHOD__."($path,,".array2string($start).") filter=".array2string($filter));
|
||||
*/
|
||||
$events =& $this->bo->search($filter);
|
||||
if ($events)
|
||||
{
|
||||
@ -197,6 +197,7 @@ error_log(__METHOD__."($path,,".array2string($start).") filter=".array2string($f
|
||||
{
|
||||
if ($this->client_shared_uid_exceptions && $event['reference'])
|
||||
{
|
||||
throw new egw_exception_assertion_failed(__METHOD__."() event=".array2string($event));
|
||||
// this exception will be handled with the series master
|
||||
unset($events[$k]);
|
||||
continue;
|
||||
@ -228,10 +229,7 @@ error_log(__METHOD__."($path,,".array2string($start).") filter=".array2string($f
|
||||
{
|
||||
$props[] = HTTP_WebDAV_Server::mkprop('getcontentlength', ''); // expensive to calculate and no CalDAV client uses it
|
||||
}
|
||||
/* disabling not working iterator
|
||||
$files[] = array(
|
||||
*/
|
||||
$files['files'][] = array(
|
||||
'path' => $path.$this->get_path($event),
|
||||
'props' => $props,
|
||||
);
|
||||
@ -242,10 +240,7 @@ error_log(__METHOD__."($path,,".array2string($start).") filter=".array2string($f
|
||||
error_log(__METHOD__."($path) took ".(microtime(true) - $starttime).
|
||||
' to return '.count($files['files']).' items');
|
||||
}
|
||||
/* disabling not working iterator
|
||||
return $files;
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -98,7 +98,6 @@ class calendar_so
|
||||
*/
|
||||
protected static $tz_cache = array();
|
||||
|
||||
|
||||
/**
|
||||
* Constructor of the socal class
|
||||
*/
|
||||
@ -318,17 +317,18 @@ class calendar_so
|
||||
* @param string $params['append'] SQL to append to the query before $order, eg. for a GROUP BY clause
|
||||
* @param array $params['cfs'] custom fields to query, null = none, array() = all, or array with cfs names
|
||||
* @param array $params['users'] raw parameter as passed to calendar_bo::search() no memberships resolved!
|
||||
* @param int $remove_rejected_by_user=null add join to remove entry, if given user has rejected it
|
||||
* @return array of cal_ids, or false if error in the parameters
|
||||
*
|
||||
* ToDo: search custom-fields too
|
||||
*/
|
||||
function &search($start,$end,$users,$cat_id=0,$filter='all',$offset=False,$num_rows=0,array $params=array())
|
||||
function &search($start,$end,$users,$cat_id=0,$filter='all',$offset=False,$num_rows=0,array $params=array(),$remove_rejected_by_user=null)
|
||||
{
|
||||
//error_log('*** '.__METHOD__.'('.($start ? date('Y-m-d H:i',$start) : '').','.($end ? date('Y-m-d H:i',$end) : '').','.array2string($users).','.array2string($cat_id).",'$filter',".array2string($offset).",$num_rows,".array2string($params).') '.function_backtrace());
|
||||
error_log(__METHOD__.'('.($start ? date('Y-m-d H:i',$start) : '').','.($end ? date('Y-m-d H:i',$end) : '').','.array2string($users).','.array2string($cat_id).",'$filter',".array2string($offset).",$num_rows,".array2string($params).') '.function_backtrace());
|
||||
|
||||
$cols = self::get_columns('calendar', $this->cal_table);
|
||||
$cols[0] = $this->db->to_varchar($this->cal_table.'.cal_id');
|
||||
$cols = isset($params['cols']) ? $params['cols'] : "$this->repeats_table.recur_type,$this->repeats_table.recur_enddate,$this->repeats_table.recur_interval,$this->repeats_table.recur_data,$this->repeats_table.recur_exception,".implode(',',$cols).",cal_start,cal_end,cal_recur_date";
|
||||
$cols = isset($params['cols']) ? $params['cols'] : "$this->repeats_table.recur_type,$this->repeats_table.recur_enddate,$this->repeats_table.recur_interval,$this->repeats_table.recur_data,$this->repeats_table.recur_exception,".implode(',',$cols).",cal_start,cal_end,$this->user_table.cal_recur_date";
|
||||
|
||||
$where = array();
|
||||
if (is_array($params['query']))
|
||||
@ -376,8 +376,9 @@ class calendar_so
|
||||
// when we are able to use Union Querys, we do not OR our query, we save the needed parts for later construction of the union
|
||||
if ($useUnionQuery)
|
||||
{
|
||||
$user_or[] = $this->db->expression($table_def,array(
|
||||
$user_or[] = $this->db->expression($table_def,$this->user_table.'.',array(
|
||||
'cal_user_type' => $type,
|
||||
),' AND '.$this->user_table.'.',array(
|
||||
'cal_user_id' => $ids,
|
||||
));
|
||||
if ($type == 'u' && ($filter == 'owner'))
|
||||
@ -388,8 +389,9 @@ class calendar_so
|
||||
}
|
||||
else
|
||||
{
|
||||
$to_or[] = $this->db->expression($table_def,array(
|
||||
$to_or[] = $this->db->expression($table_def,$this->user_table.'.',array(
|
||||
'cal_user_type' => $type,
|
||||
),' AND '.$this->user_table.'.',array(
|
||||
'cal_user_id' => $ids,
|
||||
));
|
||||
if ($type == 'u' && ($filter == 'owner'))
|
||||
@ -410,24 +412,24 @@ class calendar_so
|
||||
{
|
||||
case 'showonlypublic':
|
||||
$where['cal_public'] = 1;
|
||||
$where[] = "cal_status != 'R'"; break;
|
||||
$where[] = "$this->user_table.cal_status != 'R'"; break;
|
||||
case 'deleted':
|
||||
$where[] = 'cal_deleted IS NOT NULL'; break;
|
||||
case 'unknown':
|
||||
$where[] = "cal_status='U'"; break;
|
||||
$where[] = "$this->user_table.cal_status='U'"; break;
|
||||
case 'accepted':
|
||||
$where[] = "cal_status='A'"; break;
|
||||
$where[] = "$this->user_table.cal_status='A'"; break;
|
||||
case 'tentative':
|
||||
$where[] = "cal_status='T'"; break;
|
||||
$where[] = "$this->user_table.cal_status='T'"; break;
|
||||
case 'rejected':
|
||||
$where[] = "cal_status='R'"; break;
|
||||
$where[] = "$this->user_table.cal_status='R'"; break;
|
||||
case 'delegated':
|
||||
$where[] = "cal_status='D'"; break;
|
||||
$where[] = "$this->user_table.cal_status='D'"; break;
|
||||
case 'all':
|
||||
case 'owner':
|
||||
break;
|
||||
default:
|
||||
$where[] = "cal_status != 'R'";
|
||||
$where[] = "$this->user_table.cal_status != 'R'";
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -435,11 +437,38 @@ class calendar_so
|
||||
{
|
||||
$where[] = $this->cat_filter($cat_id);
|
||||
}
|
||||
if ($start) $where[] = (int)$start.' < cal_end';
|
||||
if ($start)
|
||||
{
|
||||
if ($params['enum_recuring'])
|
||||
{
|
||||
$where[] = (int)$start.' < cal_end';
|
||||
}
|
||||
else
|
||||
{
|
||||
// we check recur_endate!=0, because it can be NULL, 0 or !=0 !!!
|
||||
$where[] = (int)$start.' < (CASE WHEN recur_type IS NULL THEN cal_end ELSE (CASE WHEN recur_enddate!=0 THEN recur_enddate ELSE 9999999999 END) END)';
|
||||
}
|
||||
}
|
||||
if (!$params['enum_recuring'])
|
||||
{
|
||||
$where[] = "$this->user_table.cal_recur_date=0";
|
||||
$cols = str_replace('cal_start','MIN(cal_start) AS cal_start',$cols);
|
||||
$group_by = 'GROUP BY '.$this->dates_table.'.cal_id';
|
||||
}
|
||||
if ($end) $where[] = 'cal_start < '.(int)$end;
|
||||
|
||||
if (!preg_match('/^[a-z_ ,]+$/i',$params['order'])) $params['order'] = 'cal_start'; // gard against SQL injection
|
||||
if (!preg_match('/^[a-z_ ,c]+$/i',$params['order'])) $params['order'] = 'cal_start'; // gard against SQL injection
|
||||
|
||||
if ($remove_rejected_by_user)
|
||||
{
|
||||
$rejected_by_user_join = "JOIN $this->user_table rejected_by_user".
|
||||
" ON $this->cal_table.cal_id=rejected_by_user.cal_id".
|
||||
" AND rejected_by_user.cal_user_type='u'".
|
||||
" AND rejected_by_user.cal_user_id=".$this->db->quote($remove_rejected_by_user).
|
||||
" AND rejected_by_user.cal_status!='R'";
|
||||
$where[] = "(recur_type IS NULL AND rejected_by_user.cal_recur_date=0 OR cal_start=rejected_by_user.cal_recur_date)";
|
||||
}
|
||||
//$starttime = microtime(true);
|
||||
if ($useUnionQuery)
|
||||
{
|
||||
// allow apps to supply participants and/or icons
|
||||
@ -448,89 +477,72 @@ class calendar_so
|
||||
// changed the original OR in the query into a union, to speed up the query execution under MySQL 5
|
||||
$select = array(
|
||||
'table' => $this->cal_table,
|
||||
'join' => "JOIN $this->dates_table ON $this->cal_table.cal_id=$this->dates_table.cal_id JOIN $this->user_table ON $this->cal_table.cal_id=$this->user_table.cal_id LEFT JOIN $this->repeats_table ON $this->cal_table.cal_id=$this->repeats_table.cal_id",
|
||||
'join' => "JOIN $this->dates_table ON $this->cal_table.cal_id=$this->dates_table.cal_id JOIN $this->user_table ON $this->cal_table.cal_id=$this->user_table.cal_id $rejected_by_user_join LEFT JOIN $this->repeats_table ON $this->cal_table.cal_id=$this->repeats_table.cal_id",
|
||||
'cols' => $cols,
|
||||
'where' => $where,
|
||||
'app' => 'calendar',
|
||||
'append'=> $params['append'],
|
||||
'append'=> $params['append'].' '.$group_by,
|
||||
);
|
||||
$selects = array();
|
||||
// we check if there are parts to use for the construction of our UNION query,
|
||||
// as replace the OR by construction of a suitable UNION for performance reasons
|
||||
if (!empty($owner_or)||!empty($user_or))
|
||||
{
|
||||
if (!empty($owner_or) && !empty($user_or))
|
||||
{
|
||||
// if the query is to be filtered by owner OR user we need 4 selects for the union
|
||||
//_debug_array($owner_or);
|
||||
$selects = array();
|
||||
foreach(array_keys($user_or) as $key)
|
||||
foreach($user_or as $user_sql)
|
||||
{
|
||||
$selects[] = $select;
|
||||
$selects[count($selects)-1]['where'][] = $user_or[$key];
|
||||
$selects[count($selects)-1]['where'][] = 'recur_type IS NULL AND cal_recur_date=0';
|
||||
$selects[count($selects)-1]['where'][] = $user_sql;
|
||||
if ($params['enum_recuring'])
|
||||
{
|
||||
$selects[count($selects)-1]['where'][] = "recur_type IS NULL AND $this->user_table.cal_recur_date=0";
|
||||
$selects[] = $select;
|
||||
$selects[count($selects)-1]['where'][] = $user_or[$key];
|
||||
$selects[count($selects)-1]['where'][] = 'cal_recur_date=cal_start';
|
||||
$selects[count($selects)-1]['where'][] = $user_sql;
|
||||
$selects[count($selects)-1]['where'][] = "$this->user_table.cal_recur_date=cal_start";
|
||||
}
|
||||
}
|
||||
// if the query is to be filtered by owner we need to add more selects for the union
|
||||
if ($owner_or)
|
||||
{
|
||||
$selects[] = $select;
|
||||
$selects[count($selects)-1]['where'][] = $owner_or;
|
||||
$selects[count($selects)-1]['where'][] = 'recur_type IS NULL AND cal_recur_date=0';
|
||||
if ($params['enum_recuring'])
|
||||
{
|
||||
$selects[count($selects)-1]['where'][] = "recur_type IS NULL AND $this->user_table.cal_recur_date=0";
|
||||
$selects[] = $select;
|
||||
$selects[count($selects)-1]['where'][] = $owner_or;
|
||||
$selects[count($selects)-1]['where'][] = 'cal_recur_date=cal_start';
|
||||
}
|
||||
else
|
||||
{
|
||||
// if the query is to be filtered only by user we need 2 selects for the union
|
||||
$selects = array();
|
||||
foreach(array_keys($user_or) as $key)
|
||||
{
|
||||
$selects[] = $select;
|
||||
$selects[count($selects)-1]['where'][] = $user_or[$key];
|
||||
$selects[count($selects)-1]['where'][] = 'recur_type IS NULL AND cal_recur_date=0';
|
||||
$selects[] = $select;
|
||||
$selects[count($selects)-1]['where'][] = $user_or[$key];
|
||||
$selects[count($selects)-1]['where'][] = 'cal_recur_date=cal_start';
|
||||
$selects[count($selects)-1]['where'][] = "$this->user_table.cal_recur_date=cal_start";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if the query is to be filtered by neither by user nor owner (should not happen?) we need 2 selects for the union
|
||||
$selects = array($select,$select);
|
||||
$selects[0]['where'][] = 'recur_type IS NULL AND cal_recur_date=0';
|
||||
$selects[1]['where'][] = 'cal_recur_date=cal_start';
|
||||
}
|
||||
if (is_numeric($offset)) // get the total too
|
||||
$selects[] = $select;
|
||||
if ($params['enum_recuring'])
|
||||
{
|
||||
$selects[count($selects)-1]['where'][] = "recur_type IS NULL AND $this->user_table.cal_recur_date=0";
|
||||
$selects[] = $select;
|
||||
$selects[count($selects)-1]['where'][] = "$this->user_table.cal_recur_date=cal_start";
|
||||
}
|
||||
}
|
||||
if (is_numeric($offset) && !$params['no_total']) // get the total too
|
||||
{
|
||||
$save_selects = $selects;
|
||||
// we only select cal_table.cal_id (and not cal_table.*) to be able to use DISTINCT (eg. MsSQL does not allow it for text-columns)
|
||||
$countSelects = count($selects);
|
||||
foreach(array_keys($selects) as $key)
|
||||
{
|
||||
$selects[$key]['cols'] = "DISTINCT $this->repeats_table.recur_type,$this->repeats_table.recur_enddate,$this->repeats_table.recur_interval,$this->repeats_table.recur_data,$this->repeats_table.recur_exception,".$this->db->to_varchar($this->cal_table.'.cal_id').",cal_start,cal_end,cal_recur_date";
|
||||
//$selects[0]['cols'] = $selects[1]['cols'] = "DISTINCT $this->repeats_table.*,$this->cal_table.cal_id,cal_start,cal_end,cal_recur_date";
|
||||
$selects[$key]['cols'] = "DISTINCT $this->repeats_table.recur_type,$this->repeats_table.recur_enddate,$this->repeats_table.recur_interval,$this->repeats_table.recur_data,$this->repeats_table.recur_exception,".$this->db->to_varchar($this->cal_table.'.cal_id').",cal_start,cal_end,$this->user_table.cal_recur_date";
|
||||
if (!$params['enum_recuring'])
|
||||
{
|
||||
$selects[$key]['cols'] = str_replace('cal_start','MIN(cal_start) AS cal_start',$selects[$key]['cols']);
|
||||
}
|
||||
}
|
||||
if (!isset($param['cols'])) self::get_union_selects($selects,$start,$end,$users,$cat_id,$filter,$params['query'],$params['users']);
|
||||
|
||||
$this->total = $this->db->union($selects,__LINE__,__FILE__)->NumRows();
|
||||
$i = 0;
|
||||
foreach(array_keys($selects) as $key)
|
||||
{
|
||||
if ($i >= $countSelects) continue;
|
||||
$i++;
|
||||
$selects[$key]['cols'] = $select['cols']; // restore the original cols
|
||||
//$selects[0]['cols'] = $selects[1]['cols'] = $select['cols']; // restore the original cols
|
||||
}
|
||||
$i = 0;
|
||||
$selections = array();
|
||||
foreach(array_keys($selects) as $key)
|
||||
{
|
||||
if ($i >= $countSelects) continue;
|
||||
$i++;
|
||||
$selections[] = $selects[$key];
|
||||
}
|
||||
|
||||
$selects = $selections;
|
||||
// restore original cols / selects
|
||||
$selects = $save_selects; unset($save_selects);
|
||||
}
|
||||
if (!isset($param['cols'])) self::get_union_selects($selects,$start,$end,$users,$cat_id,$filter,$params['query'],$params['users']);
|
||||
|
||||
@ -538,7 +550,7 @@ class calendar_so
|
||||
}
|
||||
else // MsSQL oder MySQL 3.23
|
||||
{
|
||||
$where[] = '(recur_type IS NULL AND cal_recur_date=0 OR cal_recur_date=cal_start)';
|
||||
$where[] = "(recur_type IS NULL AND $this->user_table.cal_recur_date=0 OR $this->user_table.cal_recur_date=cal_start)";
|
||||
|
||||
//_debug_array($where);
|
||||
if (is_numeric($offset)) // get the total too
|
||||
@ -546,12 +558,13 @@ class calendar_so
|
||||
// we only select cal_table.cal_id (and not cal_table.*) to be able to use DISTINCT (eg. MsSQL does not allow it for text-columns)
|
||||
$this->total = $this->db->select($this->cal_table,"DISTINCT $this->repeats_table.*,$this->cal_table.cal_id,cal_start,cal_end,cal_recur_date",
|
||||
$where,__LINE__,__FILE__,false,'','calendar',0,
|
||||
"JOIN $this->dates_table ON $this->cal_table.cal_id=$this->dates_table.cal_id JOIN $this->user_table ON $this->cal_table.cal_id=$this->user_table.cal_id LEFT JOIN $this->repeats_table ON $this->cal_table.cal_id=$this->repeats_table.cal_id")->NumRows();
|
||||
"JOIN $this->dates_table ON $this->cal_table.cal_id=$this->dates_table.cal_id JOIN $this->user_table ON $this->cal_table.cal_id=$this->user_table.cal_id $rejected_by_user_join LEFT JOIN $this->repeats_table ON $this->cal_table.cal_id=$this->repeats_table.cal_id")->NumRows();
|
||||
}
|
||||
$rs = $this->db->select($this->cal_table,($this->db->capabilities['distinct_on_text'] ? 'DISTINCT ' : '').$cols,
|
||||
$where,__LINE__,__FILE__,$offset,$params['append'].' ORDER BY '.$params['order'],'calendar',$num_rows,
|
||||
"JOIN $this->dates_table ON $this->cal_table.cal_id=$this->dates_table.cal_id JOIN $this->user_table ON $this->cal_table.cal_id=$this->user_table.cal_id LEFT JOIN $this->repeats_table ON $this->cal_table.cal_id=$this->repeats_table.cal_id");
|
||||
"JOIN $this->dates_table ON $this->cal_table.cal_id=$this->dates_table.cal_id JOIN $this->user_table ON $this->cal_table.cal_id=$this->user_table.cal_id $rejected_by_user_join LEFT JOIN $this->repeats_table ON $this->cal_table.cal_id=$this->repeats_table.cal_id");
|
||||
}
|
||||
//error_log(__METHOD__."() useUnionQuery=$useUnionQuery --> query took ".(microtime(true)-$starttime));
|
||||
if (isset($params['cols']))
|
||||
{
|
||||
return $rs; // if colums are specified we return the recordset / iterator
|
||||
@ -593,7 +606,7 @@ class calendar_so
|
||||
foreach($this->db->select($utcal_id_view,'*',array(
|
||||
//'cal_id' => array_unique($ids),
|
||||
'cal_recur_date' => $recur_dates,
|
||||
),__LINE__,__FILE__,false,'ORDER BY cal_id,cal_user_type DESC,'.self::STATUS_SORT,'calendar',$num_rows=0,$join='',
|
||||
),__LINE__,__FILE__,false,'ORDER BY cal_id,cal_user_type DESC,'.self::STATUS_SORT,'calendar',$num_rows,$join='',
|
||||
$this->db->get_table_definitions('calendar',$this->user_table)) as $row) // DESC puts users before resources and contacts
|
||||
{
|
||||
$id = $row['cal_id'];
|
||||
@ -645,6 +658,7 @@ class calendar_so
|
||||
}
|
||||
}
|
||||
//echo "<p>socal::search\n"; _debug_array($events);
|
||||
//error_log(__METHOD__."(,filter=".array2string($params['query']).",offset=$offset, num_rows=$num_rows) returning ".count($events)." entries".($offset!==false?" total=$this->total":'').' '.function_backtrace());
|
||||
return $events;
|
||||
}
|
||||
|
||||
@ -667,7 +681,7 @@ class calendar_so
|
||||
*/
|
||||
private static function get_union_selects(array &$selects,$start,$end,$users,$cat_id,$filter,$query,$users_raw)
|
||||
{
|
||||
if (in_array(basename($_SERVER['SCRIPT_FILENAME']),array('groupdav.php','rpc.php','xmlrpc.php')) ||
|
||||
if (in_array(basename($_SERVER['SCRIPT_FILENAME']),array('groupdav.php','rpc.php','xmlrpc.php','/activesync/index.php')) ||
|
||||
!in_array($GLOBALS['egw_info']['flags']['currentapp'],array('calendar','home')))
|
||||
{
|
||||
return; // disable integration for GroupDAV, SyncML, ...
|
||||
|
@ -459,16 +459,15 @@ class groupdav_propfind_iterator implements Iterator
|
||||
*
|
||||
* @param groupdav_handler $handler
|
||||
* @param array $filter filter for propfind call
|
||||
* @param array $files=null extra files/responses to return too
|
||||
* @param array $files=array() extra files/responses to return too
|
||||
*/
|
||||
public function __construct(groupdav_handler $handler, $path, array $filter,array &$files=null)
|
||||
public function __construct(groupdav_handler $handler, $path, array $filter,array &$files=array())
|
||||
{
|
||||
if ($this->debug) error_log(__METHOD__."('$path', ".array2string($filter).",)");
|
||||
$this->path = $path;
|
||||
$this->handler = $handler;
|
||||
$this->filter = $filter;
|
||||
$this->files = $files;
|
||||
$this->common_files = $files;
|
||||
$this->files = $this->common_files = $files;
|
||||
reset($this->files);
|
||||
}
|
||||
|
||||
@ -506,6 +505,12 @@ class groupdav_propfind_iterator implements Iterator
|
||||
if ($this->debug) error_log(__METHOD__."() returning TRUE");
|
||||
return true;
|
||||
}
|
||||
// check if previous query gave less then CHUNK_SIZE entries --> we're done
|
||||
if ($this->start && count($this->files) < self::CHUNK_SIZE)
|
||||
{
|
||||
if ($this->debug) error_log(__METHOD__."() returning FALSE (no more entries)");
|
||||
return false;
|
||||
}
|
||||
// try query further files via propfind callback of handler and store result in $this->files
|
||||
$this->files = $this->handler->propfind_callback($this->path,$this->filter,array($this->start,self::CHUNK_SIZE));
|
||||
if (!is_array($this->files) || !($entries = count($this->files)))
|
||||
@ -513,10 +518,10 @@ class groupdav_propfind_iterator implements Iterator
|
||||
if ($this->debug) error_log(__METHOD__."() returning FALSE (no more entries)");
|
||||
return false; // no further entries
|
||||
}
|
||||
$this->start += $entries;
|
||||
$this->start += self::CHUNK_SIZE;
|
||||
reset($this->files);
|
||||
|
||||
if ($this->debug) error_log(__METHOD__."() returning ".array2string(current($this->files) !== false));
|
||||
if ($this->debug) error_log(__METHOD__."() this->start=$this->start, entries=$entries, count(this->files)=".count($this->files)." returning ".array2string(current($this->files) !== false));
|
||||
|
||||
return current($this->files) !== false;
|
||||
}
|
||||
@ -528,11 +533,8 @@ class groupdav_propfind_iterator implements Iterator
|
||||
{
|
||||
if ($this->debug) error_log(__METHOD__."()");
|
||||
|
||||
// query first set of files via propfind callback of handler and store result in $this->files
|
||||
$this->start = 0;
|
||||
$files = $this->handler->propfind_callback($this->path,$this->filter,array($this->start,self::CHUNK_SIZE));
|
||||
$this->files = array_merge($this->common_files, $files);
|
||||
$this->start += self::CHUNK_SIZE;
|
||||
$this->files = $this->common_files;
|
||||
reset($this->files);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user