diff --git a/inc/RRule-v2.php b/inc/RRule-v2.php index dac72677..774a43e1 100644 --- a/inc/RRule-v2.php +++ b/inc/RRule-v2.php @@ -73,6 +73,7 @@ class RepeatRuleDateTime extends DateTime { else { $tzid = $dtz->getName(); } + parent::__construct($date, $dtz); return $this; @@ -146,6 +147,9 @@ class RepeatRuleDateTime extends DateTime { return parent::format('s'); } + function epoch() { + return parent::format('U'); + } } diff --git a/inc/caldav-REPORT-multiget.php b/inc/caldav-REPORT-multiget.php index 1bb2a4de..7ab50f89 100644 --- a/inc/caldav-REPORT-multiget.php +++ b/inc/caldav-REPORT-multiget.php @@ -1,28 +1,54 @@ GetElements('urn:ietf:params:xml:ns:caldav:expand'); + if ( isset($expansion[0]) ) { + $need_expansion = true; + $expand_range_start = $expansion[0]->GetAttribute('start'); + $expand_range_end = $expansion[0]->GetAttribute('end'); + if ( isset($expand_range_start) ) $expand_range_start = new RepeatRuleDateTime($expand_range_start); + if ( isset($expand_range_end) ) $expand_range_end = new RepeatRuleDateTime($expand_range_end); + } +} + + /** * Build the array of properties to include in the report output */ -$mg_content = $xmltree->GetContent('urn:ietf:params:xml:ns:caldav:calendar-multiget'); -$proptype = $mg_content[0]->GetTag(); +$qry_content = $xmltree->GetContent('urn:ietf:params:xml:ns:caldav:calendar-multiget'); +$proptype = $qry_content[0]->GetTag(); $properties = array(); switch( $proptype ) { case 'DAV::prop': - $mg_props = $xmltree->GetPath('/urn:ietf:params:xml:ns:caldav:calendar-multiget/DAV::prop/*'); - foreach( $mg_props AS $k => $v ) { + $qry_props = $xmltree->GetPath('/urn:ietf:params:xml:ns:caldav:calendar-multiget/'.$proptype.'/*'); + foreach( $qry_content[0]->GetElements() AS $k => $v ) { $propertyname = preg_replace( '/^.*:/', '', $v->GetTag() ); $properties[$propertyname] = 1; + if ( $v->GetTag() == 'urn:ietf:params:xml:ns:caldav:calendar-data' ) check_for_expansion($v); } break; case 'DAV::allprop': $properties['allprop'] = 1; + if ( $qry_content[1]->GetTag() == 'DAV::include' ) { + foreach( $qry_content[1]->GetElements() AS $k => $v ) { + $include_properties[] = $v->GetTag(); /** $include_properties is referenced in DAVResource where allprop is expanded */ + if ( $v->GetTag() == 'urn:ietf:params:xml:ns:caldav:calendar-data' ) check_for_expansion($v); + } + } break; default: @@ -60,6 +86,11 @@ if ( isset($c->strict_result_ordering) && $c->strict_result_ordering ) $where .= $qry = new PgQuery( "SELECT caldav_data.*,calendar_item.* FROM caldav_data INNER JOIN calendar_item USING(dav_id, user_no, dav_name, collection_id) LEFT JOIN collection USING(collection_id)". $where ); if ( $qry->Exec('REPORT',__LINE__,__FILE__) && $qry->rows > 0 ) { while( $calendar_object = $qry->Fetch() ) { + if ( $need_expansion ) { + $ics = new iCalComponent($calendar_object->caldav_data); + $expanded = expand_event_instances($ics, $expand_range_start, $expand_range_end); + $calendar_object->caldav_data = $expanded->Render(); + } $responses[] = calendar_to_xml( $properties, $calendar_object ); } } diff --git a/inc/caldav-REPORT.php b/inc/caldav-REPORT.php index 6975347b..49748435 100644 --- a/inc/caldav-REPORT.php +++ b/inc/caldav-REPORT.php @@ -139,8 +139,8 @@ if ( class_exists('RepeatRule') ) { function expand_event_instances( $ics, $range_start = null, $range_end = null ) { $components = $ics->GetComponents(); - if ( !isset($range_start) ) { $range_start = new RepeatRuleDateTime($range_start); $range_start->modify('-6 weeks'); } - if ( !isset($range_end) ) { $range_end = new RepeatRuleDateTime($range_end); $range_end->modify('+4 months'); } + if ( !isset($range_start) ) { $range_start = new RepeatRuleDateTime(); $range_start->modify('-6 weeks'); } + if ( !isset($range_end) ) { $range_end = clone($range_start); $range_end->modify('+6 months'); } $new_components = array(); $result_limit = 1000; @@ -153,13 +153,16 @@ if ( class_exists('RepeatRule') ) { continue; } if ( !isset($dtstart) ) { - $dtstart = new RepeatRuleDateTime( $comp->GetPValue('DTSTART'), $comp->GetPParamValue('DTSTART', 'TZID') ); + $tzid = $comp->GetPParamValue('DTSTART', 'TZID'); + print( $tzid . "\n"); + $dtstart = new RepeatRuleDateTime( $comp->GetPValue('DTSTART'), $tzid ); $instances[$dtstart->UTC()] = $comp; } $p = $comp->GetPValue('RECURRENCE-ID'); if ( isset($p) && $p != '' ) { $range = $comp->GetPParamValue('RECURRENCE-ID', 'RANGE'); $recur_tzid = $comp->GetPParamValue('RECURRENCE-ID', 'TZID'); + print( __LINE__ . ' - ' .$recur_tzid . "\n"); $recur_utc = new RepeatRuleDateTime($p,$recur_tzid); $recur_utc = $recur_utc->UTC(); if ( isset($range) && $range == 'THISANDFUTURE' ) { @@ -185,31 +188,33 @@ if ( class_exists('RepeatRule') ) { $start_utc = $range_start->UTC(); $end_utc = $range_end->UTC(); foreach( $instances AS $utc => $comp ) { + if ( $utc > $end_utc ) break; + + $duration = $comp->GetPValue('DURATION'); + if ( !isset($duration) ) { + $dtend = new RepeatRuleDateTime( $comp->GetPValue('DTEND'), $comp->GetPParamValue('DTEND', 'TZID')); + $dtsrt = new RepeatRuleDateTime( $comp->GetPValue('DTSTART'), $comp->GetPParamValue('DTSTART', 'TZID')); + $duration = sprintf( 'PT%dM', intval(($dtend->epoch() - $dtsrt->epoch()) / 60) ); + } + if ( $utc < $start_utc ) { - $duration = $comp->GetPValue('DURATION'); - if ( !isset($duration) ) { - $dtend = new RepeatRuleDateTime( $comp->GetPValue('DTEND'), $comp->GetPValue('DTEND', 'TZID')); - $dtsrt = new RepeatRuleDateTime( $comp->GetPValue('DTSTART'), $comp->GetPValue('DTSTART', 'TZID')); - $duration = sprintf( '%d minutes', (($dtend->epoch() - $dtsrt->epoch()) / 60) ); - } - if ( isset($duration) ) { - if ( isset($last_duration) && $duration == $last_duration) { - if ( $utc < $early_start ) continue; - } - else { - $latest_start = clone($range_start); - $latest_start->modify('-'.$duration); - $early_start = $latest_start->UTC(); - $last_duration = $duration; - if ( $utc < $early_start ) continue; - } + if ( isset($last_duration) && $duration == $last_duration) { + if ( $utc < $early_start ) continue; } else { + $latest_start = clone($range_start); + $latest_start->modify('-'.$duration); + $early_start = $latest_start->UTC(); + $last_duration = $duration; + if ( $utc < $early_start ) continue; } - continue; } - if ( $utc > $end_utc ) break; - $new_components[] = $comp; + $component = clone($comp); + $component->ClearProperties('DTSTART'); + $component->ClearProperties('DTEND'); + $component->AddProperty('DTSTART', $utc ); + $component->AddProperty('DURATION', $duration ); + $new_components[] = $component; $in_range = true; }