12 require_once(
'iSchedule.php');
13 require_once(
'vComponent.php');
14 require_once(
'vCalendar.php');
15 require_once(
'WritableCollection.php');
16 include_once(
'freebusy-functions.php');
20 function __construct($principal) {
22 foreach( $principal AS $k => $v ) {
25 $this->username = $principal->username();
26 $this->user_no = $principal->user_no();
27 $this->principal_id = $principal->principal_id();
28 $this->email = $principal->email();
29 $this->dav_name = $principal->dav_name();
30 $this->principal = $principal;
32 $this->logged_in =
true;
36 function AllowedTo($do_something) {
42 if ( $d->validateRequest ( ) ) {
43 $ical =
new vCalendar( $request->raw_post );
45 $addresses = Array ();
46 $attendees = $ical->GetAttendees();
47 foreach( $attendees AS $v ) {
48 $email = preg_replace(
'/^mailto:/i',
'', $v->Value() );
49 $addresses[] = $email;
51 $organizer = $ical->GetOrganizer();
52 $addresses[] = preg_replace(
'/^mailto:/i',
'', $organizer->Value() );
53 $recipients = Array ();
54 $attendees_ok = Array ();
55 $attendees_fail = Array ();
56 if ( strpos ( $_SERVER[
'HTTP_RECIPIENT'],
',' ) ===
false ) {
57 $recipients[] = $_SERVER[
'HTTP_RECIPIENT'];
60 $rcpt = explode (
',', $_SERVER[
'HTTP_RECIPIENT'] );
61 foreach ( $rcpt as $k => $v ) {
62 $recipients[$k] = preg_replace(
'/^mailto:/i',
'', trim ( $v ) );
65 if ( ! in_array ( preg_replace(
'/^mailto:/i',
'', $_SERVER[
'HTTP_ORIGINATOR'] ), $addresses ) ) {
66 $request->DoResponse( 412, translate(
'sender must be organizer or attendee of event') );
68 foreach ( $recipients as $v ) {
69 if ( ! in_array ( preg_replace(
'/^mailto:/i',
'', $v ), $addresses ) ) {
70 dbg_error_log(
'ischedule',
'recipient missing from event ' . $v );
71 $reply->XMLResponse( 403, translate(
'recipient must be organizer or attendee of event') . $v );
74 $email = preg_replace(
'/^mailto:/',
'', $v );
75 dbg_error_log(
'ischedule',
'recipient ' . $v );
76 $schedule_target =
new Principal(
'email',$email);
77 if ( $schedule_target ==
false ){
78 array_push ( $attendees_fail, $schedule_target );
81 array_push ( $attendees_ok, $schedule_target );
84 $method = $ical->GetPValue(
'METHOD');
85 $content_type = explode (
';', $_SERVER[
'CONTENT_TYPE'] );
86 if ( $content_type[0] !=
'text/calendar' )
87 $reply->XMLResponse( 406,
'content must be text/calendar' );
88 $content_parts = Array ();
89 foreach ( $content_type as $v ) {
90 list ( $a, $b ) = explode (
'=', trim ( $v ), 2 );
91 $content_parts[strtolower($a)] = strtoupper($b);
93 if ( isset ( $content_parts[
'method'] ) )
94 $method = $content_parts[
'method'];
98 if ( $content_parts[
'component'] ==
'VFREEBUSY' ) {
99 ischedule_freebusy_request ( $ical, $attendees_ok, $attendees_fail );
101 if ( $content_parts[
'component'] ==
'VEVENT' ) {
102 ischedule_request ( $ical, $attendees_ok, $attendees_fail );
105 if ( $content_parts[
'component'] ==
'VTODO' ) {
106 ischedule_request ( $ical, $attendees_ok, $attendees_fail );
109 if ( $content_parts[
'component'] ==
'VJOURNAL' ) {
114 ischedule_request ( $ical, $attendees_ok, $attendees_fail );
117 ischedule_request ( $ical, $attendees_ok, $attendees_fail );
120 ischedule_request ( $ical, $attendees_ok, $attendees_fail );
128 case 'DECLINECOUNTER':
131 dbg_error_log(
'ischedule',
'invalid request' );
132 $request->DoResponse( 400, translate(
'invalid request') );
136 dbg_error_log(
'ischedule',
'invalid request' );
137 $request->DoResponse( 400, translate(
'invalid request') );
140 function ischedule_freebusy_request( $ic, $attendees, $attendees_fail) {
141 global $c, $session, $request;
142 $reply =
new XMLDocument( array(
"urn:ietf:params:xml:ns:ischedule" =>
"I" ) );
143 $icalAttendees = $ic->GetAttendees();
144 $responses = array();
145 $ical = $ic->GetComponents(
'VFREEBUSY');
147 $fbq_start = $ical->GetPValue(
'DTSTART');
148 $fbq_end = $ical->GetPValue(
'DTEND');
149 if ( ! ( isset($fbq_start) || isset($fbq_end) ) ) {
150 $request->DoResponse( 400,
'All valid freebusy requests MUST contain a DTSTART and a DTEND' );
156 foreach( $attendees AS $k => $attendee ) {
157 $response = $reply->NewXMLElement(
"response",
false,
false,
'urn:ietf:params:xml:ns:ischedule');
158 $fb = get_freebusy(
'^'.$attendee->dav_name, $range_start, $range_end );
160 $fb->AddProperty(
'UID', $ical->GetPValue(
'UID') );
161 $fb->SetProperties( $ical->GetProperties(
'ORGANIZER'),
'ORGANIZER');
162 foreach ( $ical->GetProperties(
'ATTENDEE') as $at ) {
163 if ( $at->Value() ==
'mailto:' . $attendee->email )
164 $fb->AddProperty( $at );
167 $vcal =
new vCalendar( array(
'METHOD' =>
'REPLY') );
168 $vcal->AddComponent( $fb );
170 $response = $reply->NewXMLElement(
"response",
false,
false,
'urn:ietf:params:xml:ns:ischedule' );
171 $response->NewElement(
"recipient",
'mailto:'.$attendee->email,
false,
'urn:ietf:params:xml:ns:ischedule' );
172 $response->NewElement(
"request-status",
"2.0;Success",
false,
'urn:ietf:params:xml:ns:ischedule' );
173 $response->NewElement(
"calendar-data", $vcal->Render(),
false,
'urn:ietf:params:xml:ns:ischedule' );
175 $responses[] = $response;
178 foreach ( $attendees_fail AS $k => $attendee ) {
179 $XMLresponse = $reply->NewXMLElement(
"response",
false,
false,
'urn:ietf:params:xml:ns:ischedule');
180 $XMLresponse->NewElement(
"recipient", $reply->href(
'mailto:'.$attendee));
181 $XMLresponse->NewElement(
"request-status",
'5.3;cannot schedule this user, unknown or access denied');
182 $responses[] = $XMLresponse;
184 $response = $reply->NewXMLElement(
"schedule-response", $responses, $reply->GetXmlNsArray(),
'urn:ietf:params:xml:ns:ischedule' );
185 $request->XMLResponse( 200, $response );
188 function ischedule_request( $ic, $attendees, $attendees_fail ) {
189 global $c, $session, $request;
190 $oldSession = $session;
191 $reply =
new XMLDocument( array(
"urn:ietf:params:xml:ns:ischedule" =>
"I" ) );
192 $responses = array();
193 $ical = $ic->GetComponents(
'VEVENT');
196 foreach ( $attendees AS $k => $attendee ) {
197 $XMLresponse = $reply->NewXMLElement(
"response",
false,
false,
'urn:ietf:params:xml:ns:ischedule');
198 dbg_error_log(
'ischedule',
'scheduling event for ' .$attendee->email);
199 $schedule_target =
new Principal(
'email',$attendee->email);
201 if ( $schedule_target->Exists() ) {
203 $attendee_calendar =
new WritableCollection(array(
'path' => $schedule_target->internal_url(
'schedule-default-calendar')));
204 if ( !$attendee_calendar->Exists() ) {
205 dbg_error_log(
'ERROR',
'Default calendar at "%s" does not exist for user "%s"',
206 $attendee_calendar->dav_name(), $schedule_target->username());
207 $response =
'5.3;cannot schedule this user, unknown or access denied';
210 $attendee_inbox =
new WritableCollection(array(
'path' => $schedule_target->internal_url(
'schedule-inbox')));
211 if ( ! $attendee_inbox->HavePrivilegeTo(
'schedule-deliver-invite') ) {
212 $response =
'3.8;denied';
214 else if ( $attendee_inbox->WriteCalendarMember($ic,
false) !== false ) {
215 $response =
'2.0;delivered';
218 $session = $oldSession;
220 dbg_error_log(
'ischedule',
'Status for attendee <%s> set to "%s"', $attendee->email, $response );
221 $XMLresponse->NewElement(
"recipient",
'mailto:'.$attendee->email,
false,
'urn:ietf:params:xml:ns:ischedule' );
222 $XMLresponse->NewElement(
"request-status", $response,
false,
'urn:ietf:params:xml:ns:ischedule' );
223 $responses[] = $XMLresponse;
226 foreach ( $attendees_fail AS $k => $attendee ) {
227 $XMLresponse = $reply->NewXMLElement(
"response",
false,
false,
'urn:ietf:params:xml:ns:ischedule');
228 $XMLresponse->NewElement(
"recipient",
'mailto:'.$attendee->email,
false,
'urn:ietf:params:xml:ns:ischedule' );
229 $XMLresponse->NewElement(
"request-status",
'5.3;cannot schedule this user, unknown or access denied',
false,
'urn:ietf:params:xml:ns:ischedule' );
230 $responses[] = $XMLresponse;
233 $response = $reply->NewXMLElement(
"schedule-response", $responses, $reply->GetXmlNsArray(),
'urn:ietf:params:xml:ns:ischedule' );
234 $request->XMLResponse( 200, $response );
237 function ischedule_cancel( $ic, $attendees, $attendees_fail ) {
238 global $c, $session, $request;
239 $reply =
new XMLDocument( array(
"DAV:" =>
"",
"urn:ietf:params:xml:ns:caldav" =>
"C",
"urn:ietf:params:xml:ns:ischedule" =>
"I" ) );
240 $responses = array();
241 $ical = $ic->GetComponents(
'VEVENT');
244 foreach ( $attendees AS $k => $attendee ) {
245 $XMLresponse = $reply->NewXMLElement(
"response",
false,
false,
'urn:ietf:params:xml:ns:ischedule');
246 dbg_error_log(
'ischedule',
'scheduling event for ' .$attendee->email);
247 $schedule_target =
new Principal(
'email',$attendee->email);
249 if ( $schedule_target->Exists() ) {
250 $attendee_calendar =
new WritableCollection(array(
'path' => $schedule_target->internal_url(
'schedule-default-calendar')));
251 if ( !$attendee_calendar->Exists() ) {
252 dbg_error_log(
'ERROR',
'Default calendar at "%s" does not exist for user "%s"',
253 $attendee_calendar->dav_name(), $schedule_target->username());
254 $response =
'5.3;cannot schedule this user, unknown or access denied';
257 $attendee_inbox =
new WritableCollection(array(
'path' => $schedule_target->internal_url(
'schedule-inbox')));
258 if ( ! $attendee_inbox->HavePrivilegeTo(
'schedule-deliver-invite') ) {
259 $response =
'3.8;denied';
261 else if ( $attendee_inbox->WriteCalendarMember($ic,
false) !== false ) {
262 $response =
'2.0;delivered';
266 dbg_error_log(
'PUT',
'Status for attendee <%s> set to "%s"', $attendee->email, $response );
267 $XMLresponse->NewElement(
"recipient", $reply->href(
'mailto:'.$attendee->email),
false,
'urn:ietf:params:xml:ns:ischedule' );
268 $XMLresponse->NewElement(
"request-status", $response,
false,
'urn:ietf:params:xml:ns:ischedule' );
269 $responses[] = $XMLresponse;
272 foreach ( $attendees_fail AS $k => $attendee ) {
273 $XMLresponse = $reply->NewXMLElement(
"response",
false,
false,
'urn:ietf:params:xml:ns:ischedule');
274 $XMLresponse->NewElement(
"recipient", $reply->href(
'mailto:'.$attendee->email),
false,
'urn:ietf:params:xml:ns:ischedule' );
275 $XMLresponse->NewElement(
"request-status",
'5.3;cannot schedule this user, unknown or access denied',
false,
'urn:ietf:params:xml:ns:ischedule' );
276 $responses[] = $XMLresponse;
279 $response = $reply->NewXMLElement(
"schedule-response", $responses, $reply->GetXmlNsArray(),
'urn:ietf:params:xml:ns:ischedule' );
280 $request->XMLResponse( 200, $response );