Switch calendar query to new getVCalendarRange() function.

This fixes various bugs in time-range handling.
This commit is contained in:
Andrew McMillan 2011-10-06 23:34:18 +02:00
parent d54ad8f488
commit e913600c70
5 changed files with 185 additions and 12 deletions

View File

@ -87,9 +87,9 @@ function apply_filter( $filters, $item ) {
* Process a filter fragment returning an SQL fragment
*/
$need_post_filter = false;
$need_range_filter = false;
$range_filter = null;
function SqlFilterFragment( $filter, $components, $property = null, $parameter = null ) {
global $need_post_filter, $need_range_filter, $target_collection;
global $need_post_filter, $range_filter, $target_collection;
$sql = "";
$params = array();
if ( !is_array($filter) ) {
@ -160,7 +160,8 @@ function SqlFilterFragment( $filter, $components, $property = null, $parameter =
}
@dbg_error_log('calquery', 'filter-sql: %s', $sql);
@dbg_error_log('calquery', 'time-range-start: %s, time-range-end: %s, ', $params[':time_range_start'], $params[':time_range_end']);
$need_range_filter = array(new RepeatRuleDateTime($start),new RepeatRuleDateTime($finish));
$range_filter = new RepeatRuleDateRange((empty($start) ? null : new RepeatRuleDateTime($start)),
(empty($finish)? null : new RepeatRuleDateTime($finish)));
break;
case 'urn:ietf:params:xml:ns:caldav:text-match':
@ -344,10 +345,12 @@ if ( $qry->Exec("calquery",__LINE__,__FILE__) && $qry->rows() > 0 ) {
if ( $expanded->ComponentCount() == 0 ) continue;
if ( $need_expansion ) $calendar_object->caldav_data = $expanded->Render();
}
else if ( $need_range_filter ) {
else if ( isset($range_filter) ) {
$vResource = new vComponent($calendar_object->caldav_data);
$expanded = expand_event_instances($vResource, $need_range_filter[0], $need_range_filter[1]);
if ( $expanded->ComponentCount() == 0 ) continue;
$expanded = getVCalendarRange($vResource);
dbg_error_log('calquery', 'Expanded to %s:%s which might overlap %s:%s',
$expanded->from, $expanded->until, $range_filter->from, $range_filter->until );
if ( !$expanded->overlaps($range_filter) ) continue;
}
$responses[] = calendar_to_xml( $properties, $calendar_object );
}

View File

@ -2,12 +2,62 @@ HTTP/1.1 207 Multi-Status
Date: Dow, 01 Jan 2000 00:00:00 GMT
DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule
DAV: extended-mkcol, calendar-proxy, bind, addressbook
ETag: "882eeadb4b2e998ed4358acda515e963"
Content-Length: 1421
ETag: "ab07e565993a377f23fc062109bbf013"
Content-Length: 2857
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
<multistatus xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<response>
<href>/caldav.php/user1/home/2178279a-aec2-471f-832d-1f6df6203f2f.ics</href>
<propstat>
<prop>
<getetag>"509b0f0d8a3363379f9f5727f5dd74a0"</getetag>
<C:calendar-data>BEGIN:VCALENDAR
PRODID:-//Mozilla Calendar//NONSGML Sunbird//EN
VERSION:2.0
BEGIN:VTODO
CREATED:20070805T200215Z
LAST-MODIFIED:20070805T201531Z
DTSTAMP:20070805T200215Z
UID:2178279a-aec2-471f-832d-1f6df6203f2f
SUMMARY:Incomplete\, uncancelled
X-MOZ-LOCATIONPATH:2178279a-aec2-471f-832d-1f6df6203f2f.ics
DESCRIPTION:This task is incomplete and has not been cancelled (has no
status at all)
END:VTODO
END:VCALENDAR
</C:calendar-data>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/user1/home/917b9e47-b748-4550-a566-657fbe672447.ics</href>
<propstat>
<prop>
<getetag>"cb3d9dc3e8c157f53eba3ea0e1e0f146"</getetag>
<C:calendar-data>BEGIN:VCALENDAR
PRODID:-//Mozilla Calendar//NONSGML Sunbird//EN
VERSION:2.0
BEGIN:VTODO
CREATED:20070805T201557Z
LAST-MODIFIED:20070805T201643Z
DTSTAMP:20070805T201557Z
UID:917b9e47-b748-4550-a566-657fbe672447
SUMMARY:50% Complete\, uncancelled
STATUS:IN-PROCESS
PERCENT-COMPLETE:50
X-MOZ-LOCATIONPATH:917b9e47-b748-4550-a566-657fbe672447.ics
DESCRIPTION:This task is in progress (50% complete) and has not been
cancelled.
END:VTODO
END:VCALENDAR
</C:calendar-data>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/user1/home/e6eb5bc9-f7f9-4a0a-94e8-8e90eefc7d08.ics</href>
<propstat>
@ -59,6 +109,16 @@ END:VCALENDAR
</response>
</multistatus>
dtstart: >NULL<
due: >NULL<
rrule: >NULL<
summary: >Incomplete, uncancelled<
dtstart: >NULL<
due: >NULL<
rrule: >NULL<
summary: >50% Complete, uncancelled<
dtstart: >2007-12-09 13:30:00+13<
due: >2007-12-09 13:30:00+13<
rrule: >NULL<

View File

@ -35,9 +35,14 @@ SELECT dtstart, due,
FROM calendar_item JOIN caldav_data USING (dav_id)
WHERE calendar_item.dav_name ~ '^/user1/home/'
AND caldav_data.caldav_type = 'VTODO'
AND (rrule IS NOT NULL
OR (dtstart >= '20071101T110000Z' AND dtstart < '20080104T110000Z')
OR (due >= '20071101T110000Z' AND dtstart < '20080104T110000Z')
)
AND (rrule IS NOT NULL OR dtstart IS NULL
OR (
(
(due IS NULL AND dtstart > '20071101T110000Z')
OR due > '20071101T110000Z'
)
AND dtstart < '20080104T110000Z'
)
)
ENDQUERY

View File

@ -0,0 +1,62 @@
HTTP/1.1 207 Multi-Status
Date: Dow, 01 Jan 2000 00:00:00 GMT
DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule
DAV: extended-mkcol, calendar-proxy, bind, addressbook, calendar-auto-schedule
ETag: "8b72e0eb2a2a3afd42cf96e4df5e9974"
Content-Length: 950
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
<multistatus xmlns="DAV:">
<response>
<href>/caldav.php/user1/home/e70576e9-c1e0-431e-a507-0386fd82f223.ics</href>
<propstat>
<prop>
<getetag>"e8060931f30c1798ac58ffbe4ec0bffc"</getetag>
<getcontenttype>text/calendar</getcontenttype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/user1/home/da81c0ee-7871-11db-c6d6-f6927c144649.ics</href>
<propstat>
<prop>
<getetag>"6f16959eee5c920b45548840b1e9ea19"</getetag>
<getcontenttype>text/calendar</getcontenttype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/user1/home/0544-gzip-PUT.ics</href>
<propstat>
<prop>
<getetag>"6ddd18264a9d40c1c9d37a005eeb7e4f"</getetag>
<getcontenttype>text/calendar</getcontenttype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</multistatus>
dav_name: >/user1/home/4aaf8f37-f232-4c8e-a72e-e171d4c4fe54.ics<
dtstart: >2006-11-02 10:00:00+13<
rrule: >FREQ=WEEKLY;COUNT=26;INTERVAL=1;BYDAY=TH<
dav_name: >/user1/home/e70576e9-c1e0-431e-a507-0386fd82f223.ics<
dtstart: >2007-12-11 07:45:00+13<
rrule: >FREQ=WEEKLY;INTERVAL=1;BYDAY=TU,TH<
dav_name: >/user1/home/71e2ae82-7870-11db-c6d6-f6927c144649.ics<
dtstart: >2006-11-03 16:00:00+13<
rrule: >FREQ=WEEKLY;INTERVAL=2;UNTIL=20071222T235900<
dav_name: >/user1/home/da81c0ee-7871-11db-c6d6-f6927c144649.ics<
dtstart: >2006-11-03 07:30:00+13<
rrule: >FREQ=MONTHLY<
dav_name: >/user1/home/0544-gzip-PUT.ics<
dtstart: >2011-10-05 14:00:00+13<
rrule: >NULL<

View File

@ -0,0 +1,43 @@
#
# Testing with a process similar to iPhone 5
#
TYPE=REPORT
URL=http://mycaldav/caldav.php/user1/home/
HEAD
AUTH=user1:user1
HEADER=User-Agent: iOS/10.7.2 (11C35) dataaccessd/1.0
HEADER=Content-Type: text/xml
HEADER=Depth: 1
#
BEGINDATA
<?xml version="1.0" encoding="UTF-8"?>
<C:calendar-query xmlns:C="urn:ietf:params:xml:ns:caldav">
<A:prop xmlns:A="DAV:">
<A:getetag/>
<A:getcontenttype/>
</A:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:time-range start="20110922T000000Z"/>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>
ENDDATA
#
QUERY
SELECT caldav_data.dav_name, dtstart, rrule
FROM calendar_item JOIN caldav_data USING(dav_id)
WHERE caldav_data.dav_name ~ '^/user1/home/'
AND caldav_data.caldav_type = 'VEVENT'
AND (rrule IS NOT NULL OR dtstart IS NULL
OR ( (dtend IS NULL AND dtstart > '20110922T000000Z')
OR dtend > '20110922T000000Z'
)
)
ENDQUERY