Fix bug in query with empty component filter, and add regression test for that.

This commit is contained in:
Andrew McMillan 2007-08-27 20:27:42 +12:00
parent de2021dbab
commit f39f6af06a
3 changed files with 210 additions and 13 deletions

View File

@ -31,9 +31,19 @@ switch( $proptype ) {
* the case and leave it alone otherwise.
*/
$qry_filters = $xmltree->GetPath('/URN:IETF:PARAMS:XML:NS:CALDAV:CALENDAR-QUERY/URN:IETF:PARAMS:XML:NS:CALDAV:FILTER/*');
$qry_filters = $qry_filters[0]; // There can only be one FILTER element
if ( $qry_filters->GetTag() == "URN:IETF:PARAMS:XML:NS:CALDAV:COMP-FILTER" && $qry_filters->GetAttribute("NAME") == "VCALENDAR" )
$qry_filters = $qry_filters->GetContent(); // Everything is inside a VCALENDAR AFAICS
if ( count($qry_filters) == 1 ) {
$qry_filters = $qry_filters[0]; // There can only be one FILTER element
if ( $qry_filters->GetTag() == "URN:IETF:PARAMS:XML:NS:CALDAV:COMP-FILTER" && $qry_filters->GetAttribute("NAME") == "VCALENDAR" )
$qry_filters = $qry_filters->GetContent(); // Everything is inside a VCALENDAR AFAICS
else {
dbg_error_log("calquery", "Got bizarre CALDAV:FILTER[%s=%s]] which does not contain COMP-FILTER = VCALENDAR!!", $qry_filters->GetTag(), $qry_filters->GetAttribute("NAME") );
$qry_filters = false;
}
}
else {
$qry_filters = false;
}
/**
* While we can construct our SQL to apply some filters in the query, other filters
@ -49,7 +59,7 @@ function apply_filter( $filters, $item ) {
if ( count($filters) == 0 ) return true;
dbg_error_log("REPORT","Applying filter for item '%s'", $item->dav_name );
dbg_error_log("calquery","Applying filter for item '%s'", $item->dav_name );
$ical = new iCalendar( array( "icalendar" => $item->caldav_data) );
return $ical->TestFilter($filters);
}
@ -63,12 +73,12 @@ function SqlFilterFragment( $filter, $components, $property = null, $parameter =
global $need_post_filter;
$sql = "";
if ( !is_array($filter) ) {
dbg_error_log( "REPORT", "Filter is of type '%s', but should be an array of XML Tags.", gettype($filter) );
dbg_error_log( "calquery", "Filter is of type '%s', but should be an array of XML Tags.", gettype($filter) );
}
foreach( $filter AS $k => $v ) {
$tag = $v->GetTag();
dbg_error_log("REPORT", "Processing $tag into SQL - %d, '%s', %d\n", count($components), $property, isset($parameter) );
dbg_error_log("calquery", "Processing $tag into SQL - %d, '%s', %d\n", count($components), $property, isset($parameter) );
$not_defined = "";
switch( $tag ) {
@ -77,7 +87,7 @@ function SqlFilterFragment( $filter, $components, $property = null, $parameter =
case 'URN:IETF:PARAMS:XML:NS:CALDAV:IS-DEFINED':
if ( isset( $parameter ) ) {
$need_post_filter = true;
dbg_error_log("REPORT", "Could not handle IS-%sDEFINED on property %s, parameter %s in SQL", $not_defined, $property, $parameter );
dbg_error_log("calquery", "Could not handle IS-%sDEFINED on property %s, parameter %s in SQL", $not_defined, $property, $parameter );
return false; // Not handled in SQL
}
if ( isset( $property ) ) {
@ -142,8 +152,10 @@ function SqlFilterFragment( $filter, $components, $property = null, $parameter =
}
$components[] = $comp_filter_name;
$subfilter = $v->GetContent();
$success = SqlFilterFragment( $subfilter, $components, $property, $parameter );
if ( $success === false ) continue; else $sql .= $success;
if ( is_array( $subfilter ) ) {
$success = SqlFilterFragment( $subfilter, $components, $property, $parameter );
if ( $success === false ) continue; else $sql .= $success;
}
break;
case 'URN:IETF:PARAMS:XML:NS:CALDAV:PROP-FILTER':
@ -174,7 +186,7 @@ function SqlFilterFragment( $filter, $components, $property = null, $parameter =
case 'COMPLETED': /** TODO: this should be moved into the properties supported in SQL. */
default:
$need_post_filter = true;
dbg_error_log("REPORT", "Could not handle PROP-FILTER on %s in SQL", $propertyname );
dbg_error_log("calquery", "Could not handle PROP-FILTER on %s in SQL", $propertyname );
return false; // Can't handle PROP-FILTER conditions in the SQL for this property
}
$subfilter = $v->GetContent();
@ -192,7 +204,7 @@ function SqlFilterFragment( $filter, $components, $property = null, $parameter =
break;
}
}
dbg_error_log("REPORT", "Generated SQL was '%s'", $sql );
dbg_error_log("calquery", "Generated SQL was '%s'", $sql );
return $sql;
}
@ -219,14 +231,17 @@ function BuildSqlFilter( $filter ) {
$responses = array();
$where = " WHERE caldav_data.dav_name ~ ".qpg("^".$request->path)." ";
$where .= BuildSqlFilter( $qry_filters);
if ( is_array($qry_filters) ) {
dbg_log_array( "calquery", "qry_filters", $qry_filters, true );
$where .= BuildSqlFilter( $qry_filters );
}
$where .= "AND (calendar_item.class != 'PRIVATE' OR calendar_item.class IS NULL OR get_permissions($session->user_no,caldav_data.user_no) ~ 'A') "; // Must have 'all' permissions to see confidential items
if ( isset($c->hide_TODO) && $c->hide_TODO ) {
$where .= "AND (caldav_data.caldav_type NOT IN ('VTODO') OR get_permissions($session->user_no,caldav_data.user_no) ~ 'A') ";
}
$qry = new PgQuery( "SELECT * , get_permissions($session->user_no,caldav_data.user_no) as permissions FROM caldav_data INNER JOIN calendar_item USING(user_no, dav_name)". $where );
if ( $qry->Exec("REPORT",__LINE__,__FILE__) && $qry->rows > 0 ) {
if ( $qry->Exec("calquery",__LINE__,__FILE__) && $qry->rows > 0 ) {
while( $calendar_object = $qry->Fetch() ) {
if ( !$need_post_filter || apply_filter( $qry_filters, $calendar_object ) ) {
$responses[] = calendar_to_xml( $properties, $calendar_object );

View File

@ -0,0 +1,150 @@
HTTP/1.1 207 Multi-Status
Date: Dow, 01 Jan 2000 00:00:00 GMT
ETag: "5c9f342ddba9b5c267dac8ad62586abe"
Content-Length: 4276
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
<multistatus xmlns="DAV:">
<response>
<href>http://myapms/calendar/caldav.php/user1/home/2178279a-aec2-471f-832d-1f6df6203f2f.ics</href>
<propstat>
<prop>
<getetag>"509b0f0d8a3363379f9f5727f5dd74a0"</getetag>
<calendar-data xmlns="urn:ietf:params:xml:ns:caldav">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
</calendar-data>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>http://myapms/calendar/caldav.php/user1/home/917b9e47-b748-4550-a566-657fbe672447.ics</href>
<propstat>
<prop>
<getetag>"cb3d9dc3e8c157f53eba3ea0e1e0f146"</getetag>
<calendar-data xmlns="urn:ietf:params:xml:ns:caldav">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
</calendar-data>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>http://myapms/calendar/caldav.php/user1/home/0575d895-a006-4ed8-9be6-0d1b6b6b1f96.ics</href>
<propstat>
<prop>
<getetag>"00ad5eb1eb5507884710b0b66aa5d5c4"</getetag>
<calendar-data xmlns="urn:ietf:params:xml:ns:caldav">BEGIN:VCALENDAR
PRODID:-//Mozilla Calendar//NONSGML Sunbird//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:/mozilla.org/20070129_1/Antarctica/McMurdo
X-LIC-LOCATION:Antarctica/McMurdo
BEGIN:STANDARD
TZOFFSETFROM:+1300
TZOFFSETTO:+1200
TZNAME:NZST
DTSTART:19700315T030000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=3SU;BYMONTH=3
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETFROM:+1200
TZOFFSETTO:+1300
TZNAME:NZDT
DTSTART:19701004T020000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=10
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VTODO
CREATED:20070805T201647Z
LAST-MODIFIED:20070805T201834Z
DTSTAMP:20070805T201647Z
UID:0575d895-a006-4ed8-9be6-0d1b6b6b1f96
SUMMARY:Due 7/8/7 16:30\, completed
STATUS:COMPLETED
DUE;TZID=/mozilla.org/20070129_1/Antarctica/McMurdo:20070807T163000
COMPLETED:20070805T201737Z
PERCENT-COMPLETE:100
X-MOZ-LOCATIONPATH:0575d895-a006-4ed8-9be6-0d1b6b6b1f96.ics
DESCRIPTION:Due on 7/8/7 at 4:30pm\, but completed alread on 6/8/7
CATEGORIES:Projects
END:VTODO
END:VCALENDAR
</calendar-data>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>http://myapms/calendar/caldav.php/user1/home/b1679f77-673d-4f46-b3eb-2420e1bba301.ics</href>
<propstat>
<prop>
<getetag>"a2990674708634a311bb98a59865ca50"</getetag>
<calendar-data xmlns="urn:ietf:params:xml:ns:caldav">BEGIN:VCALENDAR
PRODID:-//Mozilla Calendar//NONSGML Sunbird//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:/mozilla.org/20070129_1/Antarctica/McMurdo
X-LIC-LOCATION:Antarctica/McMurdo
BEGIN:STANDARD
TZOFFSETFROM:+1300
TZOFFSETTO:+1200
TZNAME:NZST
DTSTART:19700315T030000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=3SU;BYMONTH=3
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETFROM:+1200
TZOFFSETTO:+1300
TZNAME:NZDT
DTSTART:19701004T020000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=10
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VTODO
CREATED:20070806T223244Z
LAST-MODIFIED:20070806T223411Z
DTSTAMP:20070806T223244Z
UID:b1679f77-673d-4f46-b3eb-2420e1bba301
SUMMARY:A Cancelled Task\, with a start and due date
STATUS:CANCELLED
DTSTART;TZID=/mozilla.org/20070129_1/Antarctica/McMurdo:20070808T111500
DUE;TZID=/mozilla.org/20070129_1/Antarctica/McMurdo:20070808T111500
X-MOZ-LOCATIONPATH:b1679f77-673d-4f46-b3eb-2420e1bba301.ics
DESCRIPTION:This is a task with a Start and a Due date\, but it has been
cancelled.
END:VTODO
END:VCALENDAR
</calendar-data>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</multistatus>

View File

@ -0,0 +1,32 @@
#
# Do a REPORT request (test operation in subdirectory of unrelated site)
#
TYPE=REPORT
URL=http://myapms/calendar/caldav.php/user1/home/
HEAD
HEADER=User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.7) Gecko/20061013 Thunderbird/1.5.0.7
HEADER=Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
HEADER=Accept-Language: en-us,en;q=0.5
HEADER=Accept-Encoding: gzip,deflate
HEADER=Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
HEADER=Content-Type: text/xml
HEADER=Depth: 1
BEGINDATA
<?xml version="1.0" encoding="UTF-8"?>
<calendar-query xmlns:D="DAV:" xmlns="urn:ietf:params:xml:ns:caldav">
<D:prop>
<D:getetag/>
<calendar-data/>
</D:prop>
<filter>
<comp-filter name="VCALENDAR">
<comp-filter name="VTODO"/>
</comp-filter>
</filter>
</calendar-query>
ENDDATA