diff --git a/inc/WritableCollection.php b/inc/WritableCollection.php
index 93e38913..e9545057 100644
--- a/inc/WritableCollection.php
+++ b/inc/WritableCollection.php
@@ -4,12 +4,19 @@ include_once('DAVResource.php');
class WritableCollection extends DAVResource {
/**
- * Writes the data to a member in the collection and returns the segment_name of the resource in our internal namespace.
- * @param vComponent $data The resource to be written.
+ * Writes the data to a member in the collection and returns the segment_name of the
+ * resource in our internal namespace.
+ *
+ * @param vCalendar $vcal The resource to be written.
* @param boolean $create_resource True if this is a new resource.
- * @param $segment_name The name of the resource within the collection, or false on failure.
+ * @param boolean $do_scheduling True if we should also do scheduling for this write. Default false.
+ * @param string $segment_name The name of the resource within the collection, or null if this
+ * call should invent one based on the UID of the vCalendar.
+ * @param boolean $log_action Whether to log this action. Defaults to false since this is normally called
+ * in situations where one is writing secondary data.
+ * @return string The segment_name of the resource within the collection, as written, or false on failure.
*/
- function WriteCalendarMember( vComponent $data, $create_resource, $do_scheduling=true, $segment_name = null ) {
+ function WriteCalendarMember( vCalendar $vcal, $create_resource, $do_scheduling=false, $segment_name = null, $log_action=false ) {
if ( !$this->IsSchedulingCollection() && !$this->IsCalendar() ) {
dbg_error_log( 'PUT', '"%s" is not a calendar or scheduling collection!', $this->dav_name);
return false;
@@ -17,7 +24,7 @@ class WritableCollection extends DAVResource {
global $tz_regex, $session, $caldav_context;
- $resources = $data->GetComponents('VTIMEZONE',false); // Not matching VTIMEZONE
+ $resources = $vcal->GetComponents('VTIMEZONE',false); // Not matching VTIMEZONE
$user_no = $this->user_no();
$collection_id = $this->collection_id();
@@ -36,7 +43,7 @@ class WritableCollection extends DAVResource {
}
$path = $this->dav_name() . $segment_name;
- $caldav_data = $data->Render();
+ $caldav_data = $vcal->Render();
$etag = md5($caldav_data);
$weak_etag = null;
@@ -53,6 +60,7 @@ class WritableCollection extends DAVResource {
}
if ( $qry->rows() != 1 || !($row = $qry->Fetch()) ) {
// No dav_id? => We're toast!
+ dbg_error_log( 'PUT', 'No dav_id!!!', $path);
rollback_on_error( $caldav_context, $user_no, $path);
return false;
}
@@ -73,13 +81,13 @@ class WritableCollection extends DAVResource {
) );
if ( $create_resource ) {
- if ( !$this->IsSchedulingCollection() ) create_scheduling_requests($vcal);
+ if ( !$this->IsSchedulingCollection() && $do_scheduling ) do_scheduling_requests($vcal,true);
$sql = 'INSERT INTO caldav_data ( dav_id, user_no, dav_name, dav_etag, caldav_data, caldav_type, logged_user, created, modified, collection_id, weak_etag )
VALUES( :dav_id, :user_no, :dav_name, :etag, :dav_data, :caldav_type, :session_user, current_timestamp, current_timestamp, :collection_id, :weak_etag )';
$dav_params[':collection_id'] = $collection_id;
}
else {
- if ( !$this->IsSchedulingCollection() ) update_scheduling_requests($vcal);
+ if ( !$this->IsSchedulingCollection() && $do_scheduling ) do_scheduling_requests($vcal,false);
$sql = 'UPDATE caldav_data SET caldav_data=:dav_data, dav_etag=:etag, caldav_type=:caldav_type, logged_user=:session_user,
modified=current_timestamp, weak_etag=:weak_etag WHERE dav_id=:dav_id';
}
@@ -168,7 +176,7 @@ class WritableCollection extends DAVResource {
$due_prop = $first->GetProperty('DUE');
$tzid = $due_prop->GetParameterValue('TZID');
}
- $timezones = $data->GetComponents('VTIMEZONE');
+ $timezones = $vcal->GetComponents('VTIMEZONE');
foreach( $timezones AS $k => $tz ) {
if ( $tz->GetPValue('TZID') != $tzid ) {
/**
@@ -253,7 +261,7 @@ EOSQL;
if ( !$this->IsSchedulingCollection() ) {
write_alarms($dav_id, $first);
- write_attendees($dav_id, $first);
+ write_attendees($dav_id, $vcal);
if ( $log_action && function_exists('log_caldav_action') ) {
log_caldav_action( $put_action_type, $first->GetPValue('UID'), $user_no, $collection_id, $path );
}
@@ -278,25 +286,35 @@ EOSQL;
}
/**
- * Writes the data to a member in the collection and returns the segment_name of the resource in our internal namespace.
- * @param $data mixed The resource to be written.
+ * Writes the data to a member in the collection and returns the segment_name of the
+ * resource in our internal namespace.
+ *
+ * A caller who wants scheduling not to happen for this write must already
+ * know they are dealing with a calendar, so should be calling WriteCalendarMember
+ * directly.
+ *
+ * @param $resource mixed The resource to be written.
* @param $create_resource boolean True if this is a new resource.
* @param $segment_name The name of the resource within the collection, or false on failure.
+ * @param boolean $log_action Whether to log this action. Defaults to true since this is normally called
+ * in situations where one is writing primary data.
+ * @return string The segment_name that was given, or one that was assigned if null was given.
*/
- function WriteMember( $data, $create_resource, $segment_name = null ) {
+ function WriteMember( $resource, $create_resource, $segment_name = null, $log_action=true ) {
if ( ! $this->IsCollection() ) {
dbg_error_log( 'PUT', '"%s" is not a collection path', $this->dav_name);
return false;
}
- if ( ! is_object($data) ) {
+ if ( ! is_object($resource) ) {
dbg_error_log( 'PUT', 'No data supplied!' );
return false;
}
- if ( $data instanceof vComponent )
- return $this->WriteCalendarMember($data,$create_resource,$segment_name);
- else if ( $data instanceof VCard )
- return $this->WriteAddressbookMember($data,$create_resource,$segment_name);
+ if ( $resource instanceof vCalendar ) {
+ return $this->WriteCalendarMember($resource,$create_resource,true,$segment_name,$log_action);
+ }
+ else if ( $resource instanceof VCard )
+ return $this->WriteAddressbookMember($resource,$create_resource,$segment_name, $log_action);
return $segment_name;
}
diff --git a/inc/caldav-PUT-functions.php b/inc/caldav-PUT-functions.php
index b004c9cb..292e5b1e 100644
--- a/inc/caldav-PUT-functions.php
+++ b/inc/caldav-PUT-functions.php
@@ -309,83 +309,59 @@ function handle_schedule_reply ( vCalendar $ical ) {
}
-
-
/**
-* Create a scheduling request in the schedule inbox for the
+* Create/Update the scheduling requests for this resource. This includes updating
+* the scheduled user's default calendar.
* @param vComponent $resource The VEVENT/VTODO/... resource we are scheduling
-* @param vProperty $attendee The attendee we are scheduling
-* @return float The result of the scheduling request, per caldav-sched #3.5.4
+* @param boolean $create true if the scheduling requests are being created.
*/
-function write_scheduling_request( vComponent $resource, $attendee_value, $create_resource ) {
- $email = preg_replace( '/^mailto:/i', '', $attendee_value );
- $schedule_target = new Principal('email',$email);
- if ( $schedule_target->Exists() ) {
- $attendee_inbox = new WritableCollection(array('path' => $schedule_target->internal_url('schedule-inbox')));
- if ( ! $attendee_inbox->HavePrivilegeTo('schedule-deliver-invite') ) {
- $response = '3.8;'.translate('No authority to deliver invitations to user.');
- }
- else if ( $attendee_inbox->WriteCalendarMember($resource, $create_resource) === false ) {
- $response = '5.3;'.translate('No scheduling support for user');
+function do_scheduling_requests( vCalendar $resource, $create ) {
+ if ( ! is_object($resource) ) {
+ dbg_error_log( 'PUT', 'do_scheduling_requests called with non-object parameter (%s)', gettype($resource) );
+ return;
+ }
+
+ $attendees = $resource->GetAttendees();
+ if ( count($attendees) == 0 ) {
+ dbg_error_log( 'PUT', 'Event has no attendees - no scheduling required.', count($attendees) );
+ return;
+ }
+
+ dbg_error_log( 'PUT', 'Adding to scheduling inbox %d attendees', count($attendees) );
+ $schedule_request = clone($resource);
+ $schedule_request->AddProperty('METHOD','REQUEST');
+ foreach( $attendees AS $attendee ) {
+ $email = preg_replace( '/^mailto:/i', '', $attendee->Value() );
+ $schedule_target = new Principal('email',$email);
+ if ( $schedule_target->Exists() ) {
+ $attendee_calendar = new WritableCollection(array('path' => $schedule_target->internal_url('schedule-default-calendar')));
+ if ( !$attendee_calendar->Exists() ) {
+ dbg_error_log('ERROR','Default calendar at "%s" does not exist for user "%s"',
+ $attendee_calendar->dav_name(), $schedule_target->username());
+ $response = '5.3;'.translate('No scheduling support for user');
+ }
+ else if ( $attendee_calendar->WriteCalendarMember($resource, $create) === false ) {
+ dbg_error_log('ERROR','Could not write new calendar member to %s', $attendee_calendar->dav_name(),
+ $attendee_calendar->dav_name(), $schedule_target->username());
+ $response = '5.3;'.translate('No scheduling support for user');
+ }
+ else {
+ $attendee_inbox = new WritableCollection(array('path' => $schedule_target->internal_url('schedule-inbox')));
+ if ( ! $attendee_inbox->HavePrivilegeTo('schedule-deliver-invite') ) {
+ $response = '3.8;'.translate('No authority to deliver invitations to user.');
+ }
+ else if ( $attendee_inbox->WriteCalendarMember($schedule_request, $create) === false ) {
+ $response = '5.3;'.translate('No scheduling support for user');
+ }
+ else {
+ $response = '2.0;'.translate('Scheduling invitation delivered successfully');
+ }
+ }
}
else {
- $response = '2.0;'.translate('Scheduling invitation delivered successfully');
+ $response = '5.3;'.translate('No scheduling support for user');
}
- }
- else {
- $response = '5.3;'.translate('No scheduling support for user');
- }
- return '"'.$response.'"';
-}
-
-/**
-* Create scheduling requests in the schedule inbox for the
-* @param vComponent $resource The VEVENT/VTODO/... resource we are scheduling
-*/
-function create_scheduling_requests( vCalendar $resource ) {
- if ( ! is_object($resource) ) {
- dbg_error_log( 'PUT', 'create_scheduling_requests called with non-object parameter (%s)', gettype($resource) );
- return;
- }
-
- $attendees = $resource->GetAttendees();
- if ( count($attendees) == 0 ) {
- dbg_error_log( 'PUT', 'Event has no attendees - no scheduling required.', count($attendees) );
- return;
- }
-
- dbg_error_log( 'PUT', 'Adding to scheduling inbox %d attendees', count($attendees) );
- $schedule_request = new VCalendar( array('METHOD' => 'REQUEST') );
- $schedule_request->SetComponents( $resource->GetComponents() );
- foreach( $attendees AS $attendee ) {
- $schedule_status = write_scheduling_request( $schedule_request, $attendee->Value(), true );
- dbg_error_log( 'PUT', 'Status for attendee <%s> set to "%s"', $attendee->Value(), $schedule_status );
- $attendee->SetParameterValue( 'SCHEDULE-STATUS', $schedule_status );
- }
-}
-
-
-/**
-* Update scheduling requests in the schedule inbox for the
-* @param vComponent $resource The VEVENT/VTODO/... resource we are scheduling
-*/
-function update_scheduling_requests( vCalendar $resource ) {
- if ( ! is_object($resource) ) {
- dbg_error_log( 'PUT', 'update_scheduling_requests called with non-object parameter (%s)', gettype($resource) );
- return;
- }
-
- $attendees = $resource->GetAttendees();
- if ( count($attendees) == 0 ) {
- dbg_error_log( 'PUT', 'Event has no attendees - no scheduling required.', count($attendees) );
- return;
- }
-
- dbg_error_log( 'PUT', 'Adding to scheduling inbox %d attendees', count($attendees) );
- $schedule_request = new VCalendar( array('METHOD' => 'REQUEST') );
- $schedule_request->SetComponents( $resource->GetComponents() );
- foreach( $attendees AS $attendee ) {
- $schedule_status = write_scheduling_request( $schedule_request, $attendee->Value(), false );
+ $schedule_status = '"'.$response.'"';
dbg_error_log( 'PUT', 'Status for attendee <%s> set to "%s"', $attendee->Value(), $schedule_status );
$attendee->SetParameterValue( 'SCHEDULE-STATUS', $schedule_status );
}
@@ -484,7 +460,7 @@ EOSQL;
/** Construct the VCALENDAR data */
$vcal = new vCalendar();
$vcal->SetComponents($resource);
- create_scheduling_requests($vcal);
+ do_scheduling_requests($vcal,true);
$icalendar = $vcal->Render();
/** As ever, we mostly deal with the first resource component */
@@ -623,7 +599,7 @@ EOSQL;
write_alarms($dav_id, $first);
write_attendees($dav_id, $vcal);
- create_scheduling_requests( $vcal );
+ do_scheduling_requests( $vcal, true );
if ( isset($c->skip_bad_event_on_import) && $c->skip_bad_event_on_import ) $qry->Commit();
}
@@ -945,7 +921,7 @@ function write_resource( DAVResource $resource, $caldav_data, DAVResource $colle
if ( !isset($dav_params[':modified']) ) $dav_params[':modified'] = 'now';
if ( $put_action_type == 'INSERT' ) {
- if ( !$collection->IsSchedulingCollection() ) create_scheduling_requests($ic);
+ if ( !$collection->IsSchedulingCollection() ) do_scheduling_requests($ic,true);
$sql = 'INSERT INTO caldav_data ( dav_id, user_no, dav_name, dav_etag, caldav_data, caldav_type, logged_user, created, modified, collection_id, weak_etag )
VALUES( :dav_id, :user_no, :dav_name, :etag, :dav_data, :caldav_type, :session_user, :created, :modified, :collection_id, :weak_etag )';
$dav_params[':collection_id'] = $collection_id;
@@ -954,7 +930,7 @@ function write_resource( DAVResource $resource, $caldav_data, DAVResource $colle
$dav_params[':created'] = (isset($created) && $created != '' ? $created : $dtstamp);
}
else {
- if ( !$collection->IsSchedulingCollection() ) update_scheduling_requests($ic);
+ if ( !$collection->IsSchedulingCollection() ) do_scheduling_requests($ic,false);
$sql = 'UPDATE caldav_data SET caldav_data=:dav_data, dav_etag=:etag, caldav_type=:caldav_type, logged_user=:session_user,
modified=:modified, weak_etag=:weak_etag WHERE dav_id=:dav_id';
}
diff --git a/testing/tests/binding/1032-BIND-admin.result b/testing/tests/binding/1032-BIND-admin.result
index d41421be..cec700af 100644
--- a/testing/tests/binding/1032-BIND-admin.result
+++ b/testing/tests/binding/1032-BIND-admin.result
@@ -55,7 +55,7 @@ target_collection: >11<
target_resource_i: >NULL<
ticket_owner: >1003<
- bind_id: >1624<
+ bind_id: >1628<
bind_owner: >1<
bound_source_id: >12<
dav_displayname: >user3 home<
diff --git a/testing/tests/binding/1035-GET-mashup.result b/testing/tests/binding/1035-GET-mashup.result
index 53bec384..708d7b7b 100644
--- a/testing/tests/binding/1035-GET-mashup.result
+++ b/testing/tests/binding/1035-GET-mashup.result
@@ -2,7 +2,7 @@ HTTP/1.1 200 OK
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
-Content-Length: 20351
+Content-Length: 21247
Etag: "ae93907cb03bc025b8e733eb61f3a09e"
Content-Type: text/calendar; charset="utf-8"
@@ -380,6 +380,31 @@ X-MOZ-SEND-INVITATIONS:TRUE
SEQUENCE:1
END:VEVENT
BEGIN:VEVENT
+CREATED:20100319T103247Z
+LAST-MODIFIED:20100319T105620Z
+DTSTAMP:20100319T105620Z
+UID:70399cd7-50a4-4be4-a665-af593e19a7fd
+SUMMARY:An invited event. Black tie with pink polka dots is essential.
+ Do not bring a leopard. Any leopards which do attend will be forcibly
+ chained to a nearby fence.
+ORGANIZER;RSVP=TRUE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:user1@example.ne
+ t
+ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT:mailto:use
+ r2@example.net
+ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT:mailto:use
+ r3@example.net
+ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT:mailto:use
+ r4@example.net
+ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT:mailto:use
+ r5@example.net
+DTSTART:20100322T160000
+DTEND:20100322T170000
+X-MOZ-GENERATION:3
+TRANSP:OPAQUE
+X-MOZ-SEND-INVITATIONS:TRUE
+SEQUENCE:1
+END:VEVENT
+BEGIN:VEVENT
LAST-MODIFIED:20100125T214235Z
SEQUENCE:1
UID:73d1f980-ec28-012c-11f9-002421a2359e
diff --git a/testing/tests/binding/1036-REPORT-sync-initial-bound.result b/testing/tests/binding/1036-REPORT-sync-initial-bound.result
index c3150356..ac97945c 100644
--- a/testing/tests/binding/1036-REPORT-sync-initial-bound.result
+++ b/testing/tests/binding/1036-REPORT-sync-initial-bound.result
@@ -2,8 +2,8 @@ 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: "669141e7081e1e14a6bef5b2b6327659"
-Content-Length: 2040
+ETag: "0d70494d992ba29a4785b464a6325784"
+Content-Length: 2286
Content-Type: text/xml; charset="utf-8"
@@ -80,5 +80,14 @@ Content-Type: text/xml; charset="utf-8"
HTTP/1.1 200 OK
+
+ /caldav.php/user2/home/70399cd7-50a4-4be4-a665-af593e19a7fd.ics
+
+
+ "baad41c9f24bd1ecbdde6e58882df9b7"
+
+ HTTP/1.1 200 OK
+
+
5
diff --git a/testing/tests/binding/1100-BIND.result b/testing/tests/binding/1100-BIND.result
index 821d14fd..c91139c8 100644
--- a/testing/tests/binding/1100-BIND.result
+++ b/testing/tests/binding/1100-BIND.result
@@ -35,7 +35,7 @@ Content-Type: text/plain; charset="utf-8"
length: >8<
parent_container: >/user4/base/<
- bind_id: >1625<
+ bind_id: >1629<
bound_source_id: >1601<
dav_displayname: >A normal collection<
dav_name: >/user4/boundbase/<
diff --git a/testing/tests/binding/1101-PROPFIND-normal.result b/testing/tests/binding/1101-PROPFIND-normal.result
index df5e0191..f3609ca3 100644
--- a/testing/tests/binding/1101-PROPFIND-normal.result
+++ b/testing/tests/binding/1101-PROPFIND-normal.result
@@ -112,7 +112,7 @@
newcalendar
- /caldav.php/.resources/1614
+ /caldav.php/.resources/1618
diff --git a/testing/tests/binding/1102-PROPFIND-bound.result b/testing/tests/binding/1102-PROPFIND-bound.result
index b45ee58b..8c2270a4 100644
--- a/testing/tests/binding/1102-PROPFIND-bound.result
+++ b/testing/tests/binding/1102-PROPFIND-bound.result
@@ -125,7 +125,7 @@
newcalendar
- /caldav.php/.resources/1614
+ /caldav.php/.resources/1618
diff --git a/testing/tests/carddav/Restore-Database.result b/testing/tests/carddav/Restore-Database.result
index 0781c440..80453e61 100644
--- a/testing/tests/carddav/Restore-Database.result
+++ b/testing/tests/carddav/Restore-Database.result
@@ -1,6 +1,6 @@
setval
--------
- 1625
+ 1629
(1 row)
setval
diff --git a/testing/tests/scheduling/3010-PUT-with-attendees.result b/testing/tests/scheduling/3010-PUT-with-attendees.result
index b09f132a..0a51006b 100644
--- a/testing/tests/scheduling/3010-PUT-with-attendees.result
+++ b/testing/tests/scheduling/3010-PUT-with-attendees.result
@@ -5,12 +5,10 @@ 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: "e69b6d5b70189b96126c8993bcf1648a"
-Content-Length: 112
+Content-Length: 0
Content-Type: text/plain; charset="utf-8"
-Notice: Undefined variable: log_action in /home/karora/projects/davical/inc/WritableCollection.php on line 259
-
caldav_data: >BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Apple Inc.//iCal 3.0//EN
diff --git a/testing/tests/scheduling/Restore-Database.result b/testing/tests/scheduling/Restore-Database.result
index 4b4188ff..e6084764 100644
--- a/testing/tests/scheduling/Restore-Database.result
+++ b/testing/tests/scheduling/Restore-Database.result
@@ -1,6 +1,6 @@
setval
--------
- 1637
+ 1641
(1 row)
setval