diff --git a/calendar/inc/class.calendar_bo.inc.php b/calendar/inc/class.calendar_bo.inc.php index 1708591783..f80c7de0cb 100644 --- a/calendar/inc/class.calendar_bo.inc.php +++ b/calendar/inc/class.calendar_bo.inc.php @@ -1937,33 +1937,33 @@ class calendar_bo $etag .= ':'.$entry['modified']; // include exception etags into our own etag, if exceptions are included - if ($client_share_uid_excpetions && !empty($entry['uid']) && + if ($client_share_uid_excpetions && //!empty($entry['uid']) && $entry['recur_type'] != MCAL_RECUR_NONE && $entry['recur_exception']) { - $events =& $this->search(array( - //'query' => array('cal_uid' => $entry['uid']), - 'query' => array('cal_reference' => $entry['id']), - 'filter' => 'owner', // return all possible entries - 'daywise' => false, - 'enum_recuring' => false, - 'date_format' => 'server', - 'no_total' => true, - )); - foreach($events as $k => &$recurrence) + foreach($this->so->get_cal_data(array( + 'cal_reference' => $entry['id'], + ), 'cal_id,cal_reference,cal_etag,cal_modified'.(!$master_only ? ',cal_user_modified' : '')) as $recurrence) { + $recurrence = egw_db::strip_array_keys($data, 'cal_'); if ($recurrence['reference'] && $recurrence['id'] != $entry['id']) // ignore series master { - $exception_etag = $this->get_etag($recurrence, $nul); + // modified need to be max from modified and user_modified + if (!$master_only && $recurrence['modified'] < $recurrence['user_modified']) + { + $recurrence['modified'] = $recurrence['user_modified']; + } + $exception_etag = $this->get_etag($recurrence); // if $master_only, only add cal_etag, not max. user modification date if ($master_only) list(,$exception_etag) = explode(':',$exception_etag); - $exception_etags .= ':'.$this->get_etag($recurrence, $nul); + $exception_etags .= ':'.$exception_etag; } } if ($exception_etags) { $etag .= ':'.md5($exception_etags); // limit size, as there can be many exceptions } + //error_log(__METHOD__."($entry[id]: $entry[title]) returning $etag ".function_backtrace()); } //error_log(__METHOD__ . "($entry[id],$client_share_uid_excpetions) entry=".array2string($entry)." --> etag=$etag"); return $etag; diff --git a/calendar/inc/class.calendar_so.inc.php b/calendar/inc/class.calendar_so.inc.php index d94044b919..b717dec2a4 100644 --- a/calendar/inc/class.calendar_so.inc.php +++ b/calendar/inc/class.calendar_so.inc.php @@ -370,6 +370,29 @@ class calendar_so $where,__LINE__,__FILE__,false,'','calendar',0,'JOIN egw_cal ON egw_cal.cal_id=egw_cal_user.cal_id')->fetchColumn(); } + /** + * Query calendar main table and return iterator of query + * + * Use as: foreach(get_cal_data() as $data) { $data = egw_db::strip_array_keys($data, 'cal_'); // do something with $data + * + * @param array $query filter, keys have to use 'cal_' prefix + * @param string|array $cols='cal_id,cal_reference,cal_etag,cal_modified,cal_user_modified' cols to query + * @return Iterator as egw_db::select + */ + function get_cal_data(array $query, $cols='cal_id,cal_reference,cal_etag,cal_modified,cal_user_modified', $include_user_modified=false) + { + if (!is_array($cols)) $cols = explode(',', $cols); + + // special handling of cal_user_modified "pseudo" column + if (($key = array_search('cal_user_modified', $cols)) !== false) + { + $cols[$key] = $this->db->unix_timestamp('(SELECT MAX(cal_user_modified) FROM '. + $this->user_table.' WHERE '.$this->cal_table.'.cal_id='.$this->user_table.'.cal_id)'). + ' AS cal_user_modified'; + } + return $this->db->select($this->cal_table, $cols, $query, __LINE__, __FILE__); + } + /** * generate SQL to filter after a given category (incl. subcategories) * diff --git a/phpgwapi/inc/class.groupdav_handler.inc.php b/phpgwapi/inc/class.groupdav_handler.inc.php index e3aea35f99..947457458b 100644 --- a/phpgwapi/inc/class.groupdav_handler.inc.php +++ b/phpgwapi/inc/class.groupdav_handler.inc.php @@ -538,8 +538,12 @@ abstract class groupdav_handler */ public function add_resource($path, array $entry, array $props) { + // only run get_etag, if we really need it, as it might be expensive (eg. calendar) + if (!isset($props['getetag'])) + { + $props['getetag'] = $this->get_etag($entry); + } foreach(array( - 'getetag' => $this->get_etag($entry), 'getcontenttype' => 'text/calendar', 'getlastmodified' => $entry['modified'], 'displayname' => $entry['title'],