/** * Converts a text/calendar part into SyncMeetingRequest * * @access private * @param $part MIME part * @param $output SyncMail object */ private function parseMeetingCalendar($part, &$output) { $ical = new iCalComponent(); $ical->ParseFrom($part->body); if (isset($part->ctype_parameters["method"])) { switch (strtolower($part->ctype_parameters["method"])) { case "cancel": $output->messageclass = "IPM.Schedule.Meeting.Canceled"; break; case "counter": $output->messageclass = "IPM.Schedule.Meeting.Resp.Tent"; break; case "reply": $props = $ical->GetPropertiesByPath('!VTIMEZONE/ATTENDEE'); if (count($props) == 1) { $props_params = $props[0]->Parameters(); if (isset($props_params["PARTSTAT"])) { switch (strtolower($props_params["PARTSTAT"])) { case "accepted": $output->messageclass = "IPM.Schedule.Meeting.Resp.Pos"; break; case "needs-action": case "tentative": $output->messageclass = "IPM.Schedule.Meeting.Resp.Tent"; break; case "declined": $output->messageclass = "IPM.Schedule.Meeting.Resp.Neg"; break; default: ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->parseMeetingCalendar() - Unknown reply status %s", strtolower($props_params["PARTSTAT"]))); $output->messageclass = "IPM.Appointment"; break; } } else { ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->parseMeetingCalendar() - No reply status found")); $output->messageclass = "IPM.Appointment"; } } else { ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->parseMeetingCalendar() - There are not attendees")); $output->messageclass = "IPM.Appointment"; } break; case "request": $output->messageclass = "IPM.Schedule.Meeting.Request"; break; default: ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->parseMeetingCalendar() - Unknown method %s", strtolower($part->headers["method"]))); $output->messageclass = "IPM.Appointment"; break; } } else { ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->parseMeetingCalendar() - No method header")); $output->messageclass = "IPM.Appointment"; } $props = $ical->GetPropertiesByPath('VEVENT/DTSTAMP'); if (count($props) == 1) { $output->meetingrequest->dtstamp = Utils::MakeUTCDate($props[0]->Value()); } $props = $ical->GetPropertiesByPath('VEVENT/UID'); if (count($props) == 1) { $output->meetingrequest->globalobjid = $props[0]->Value(); } $props = $ical->GetPropertiesByPath('VEVENT/DTSTART'); if (count($props) == 1) { $output->meetingrequest->starttime = Utils::MakeUTCDate($props[0]->Value()); if (strlen($props[0]->Value()) == 8) { $output->meetingrequest->alldayevent = 1; } } $props = $ical->GetPropertiesByPath('VEVENT/DTEND'); if (count($props) == 1) { $output->meetingrequest->endtime = Utils::MakeUTCDate($props[0]->Value()); if (strlen($props[0]->Value()) == 8) { $output->meetingrequest->alldayevent = 1; } } $props = $ical->GetPropertiesByPath('VEVENT/ORGANIZER'); if (count($props) == 1) { $output->meetingrequest->organizer = str_ireplace("MAILTO:", "", $props[0]->Value()); } $props = $ical->GetPropertiesByPath('VEVENT/LOCATION'); if (count($props) == 1) { $output->meetingrequest->location = $props[0]->Value(); } $props = $ical->GetPropertiesByPath('VEVENT/CLASS'); if (count($props) == 1) { switch ($props[0]->Value()) { case "PUBLIC": $output->meetingrequest->sensitivity = "0"; break; case "PRIVATE": $output->meetingrequest->sensitivity = "2"; break; case "CONFIDENTIAL": $output->meetingrequest->sensitivity = "3"; break; default: ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->parseMeetingCalendar() - No sensitivity class. Using 2")); $output->meetingrequest->sensitivity = "2"; break; } } // Get $tz from first timezone $props = $ical->GetPropertiesByPath("VTIMEZONE/TZID"); if (count($props) > 0) { // TimeZones shouldn't have dots $tzname = str_replace(".", "", $props[0]->Value()); $tz = TimezoneUtil::GetFullTZFromTZName($tzname); } else { $tz = TimezoneUtil::GetFullTZ(); } $output->meetingrequest->timezone = base64_encode(TimezoneUtil::getSyncBlobFromTZ($tz)); // Fixed values $output->meetingrequest->instancetype = 0; $output->meetingrequest->responserequested = 1; $output->meetingrequest->busystatus = 2; // TODO: reminder $output->meetingrequest->reminder = ""; }
/** * Converts a text/calendar part into SyncMeetingRequest * This is called on received messages, it's not called for events generated from the mobile * * @access private * @param $part MIME part * @param $output SyncMail object * @param $is_sent_folder boolean */ function parse_meeting_calendar($part, &$output, $is_sent_folder) { $ical = new iCalComponent(); $ical->ParseFrom($part->body); ZLog::Write(LOGLEVEL_WBXML, sprintf("BackendIMAP->parse_meeting_calendar(): %s", $part->body)); // Get UID $uid = false; $props = $ical->GetPropertiesByPath("VEVENT/UID"); if (count($props) > 0) { $uid = $props[0]->Value(); } $method = false; $props = $ical->GetPropertiesByPath("VCALENDAR/METHOD"); if (count($props) > 0) { $method = strtolower($props[0]->Value()); ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->parse_meeting_calendar(): Using method from vcalendar object: %s", $method)); } else { if (isset($part->ctype_parameters["method"])) { $method = strtolower($part->ctype_parameters["method"]); ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->parse_meeting_calendar(): Using method from mime part object: %s", $method)); } } if ($method === false) { ZLog::Write(LOGLEVEL_WARN, sprintf("BackendIMAP->parse_meeting_calendar() - No method header, please report it to the developers")); $output->messageclass = "IPM.Appointment"; } else { switch ($method) { case "cancel": $output->messageclass = "IPM.Schedule.Meeting.Canceled"; $output->meetingrequest->disallownewtimeproposal = 1; ZLog::Write(LOGLEVEL_DEBUG, "BackendIMAP->parse_meeting_calendar(): Event canceled, removing calendar object"); delete_calendar_dav($uid); break; case "counter": ZLog::Write(LOGLEVEL_DEBUG, "BackendIMAP->parse_meeting_calendar(): Counter received"); $output->messageclass = "IPM.Schedule.Meeting.Resp.Tent"; $output->meetingrequest->disallownewtimeproposal = 0; break; case "reply": ZLog::Write(LOGLEVEL_DEBUG, "BackendIMAP->parse_meeting_calendar(): Reply received"); $props = $ical->GetPropertiesByPath('VEVENT/ATTENDEE'); for ($i = 0; $i < count($props); $i++) { $mailto = $props[$i]->Value(); $props_params = $props[$i]->Parameters(); $status = strtolower($props_params["PARTSTAT"]); if (!$is_sent_folder) { // Only evaluate received replies, not sent $res = update_calendar_attendee($uid, $mailto, $status); } else { $res = true; } if ($res) { // Only set messageclass for replies changing my calendar object switch ($status) { case "accepted": $output->messageclass = "IPM.Schedule.Meeting.Resp.Pos"; ZLog::Write(LOGLEVEL_DEBUG, "BackendIMAP->parse_meeting_calendar(): Update attendee -> accepted"); break; case "needs-action": $output->messageclass = "IPM.Schedule.Meeting.Resp.Tent"; ZLog::Write(LOGLEVEL_DEBUG, "BackendIMAP->parse_meeting_calendar(): Update attendee -> needs-action"); break; case "tentative": $output->messageclass = "IPM.Schedule.Meeting.Resp.Tent"; ZLog::Write(LOGLEVEL_DEBUG, "BackendIMAP->parse_meeting_calendar(): Update attendee -> tentative"); break; case "declined": $output->messageclass = "IPM.Schedule.Meeting.Resp.Neg"; ZLog::Write(LOGLEVEL_DEBUG, "BackendIMAP->parse_meeting_calendar(): Update attendee -> declined"); break; default: ZLog::Write(LOGLEVEL_WARN, sprintf("BackendIMAP->parse_meeting_calendar() - Unknown reply status <%s>, please report it to the developers", $status)); $output->messageclass = "IPM.Appointment"; break; } } } $output->meetingrequest->disallownewtimeproposal = 1; break; case "request": $output->messageclass = "IPM.Schedule.Meeting.Request"; $output->meetingrequest->disallownewtimeproposal = 0; ZLog::Write(LOGLEVEL_DEBUG, "BackendIMAP->parse_meeting_calendar(): New request"); // New meeting, we don't create it now, because we need to confirm it first, but if we don't create it we won't see it in the calendar break; default: ZLog::Write(LOGLEVEL_WARN, sprintf("BackendIMAP->parse_meeting_calendar() - Unknown method <%s>, please report it to the developers", strtolower($part->headers["method"]))); $output->messageclass = "IPM.Appointment"; $output->meetingrequest->disallownewtimeproposal = 0; break; } } $props = $ical->GetPropertiesByPath('VEVENT/DTSTAMP'); if (count($props) == 1) { $output->meetingrequest->dtstamp = Utils::MakeUTCDate($props[0]->Value()); } $props = $ical->GetPropertiesByPath('VEVENT/UID'); if (count($props) == 1) { $output->meetingrequest->globalobjid = $props[0]->Value(); } $props = $ical->GetPropertiesByPath('VEVENT/DTSTART'); if (count($props) == 1) { $output->meetingrequest->starttime = Utils::MakeUTCDate($props[0]->Value()); if (strlen($props[0]->Value()) == 8) { $output->meetingrequest->alldayevent = 1; } } $props = $ical->GetPropertiesByPath('VEVENT/DTEND'); if (count($props) == 1) { $output->meetingrequest->endtime = Utils::MakeUTCDate($props[0]->Value()); if (strlen($props[0]->Value()) == 8) { $output->meetingrequest->alldayevent = 1; } } $props = $ical->GetPropertiesByPath('VEVENT/ORGANIZER'); if (count($props) == 1) { $output->meetingrequest->organizer = str_ireplace("MAILTO:", "", $props[0]->Value()); } $props = $ical->GetPropertiesByPath('VEVENT/LOCATION'); if (count($props) == 1) { $output->meetingrequest->location = $props[0]->Value(); } $props = $ical->GetPropertiesByPath('VEVENT/CLASS'); if (count($props) == 1) { switch ($props[0]->Value()) { case "PUBLIC": $output->meetingrequest->sensitivity = "0"; break; case "PRIVATE": $output->meetingrequest->sensitivity = "2"; break; case "CONFIDENTIAL": $output->meetingrequest->sensitivity = "3"; break; default: ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->parse_meeting_calendar() - No sensitivity class. Using 2")); $output->meetingrequest->sensitivity = "2"; break; } } // Get $tz from first timezone $props = $ical->GetPropertiesByPath("VTIMEZONE/TZID"); if (count($props) > 0) { // TimeZones shouldn't have dots $tzname = str_replace(".", "", $props[0]->Value()); $tz = TimezoneUtil::GetFullTZFromTZName($tzname); } else { $tz = TimezoneUtil::GetFullTZ(); } $output->meetingrequest->timezone = base64_encode(TimezoneUtil::GetSyncBlobFromTZ($tz)); // Fixed values $output->meetingrequest->instancetype = 0; $output->meetingrequest->responserequested = 1; $output->meetingrequest->busystatus = 2; // TODO: reminder $output->meetingrequest->reminder = ""; }
<?php require_once 'vendor/autoload.php'; define('LOGLEVEL', LOGLEVEL_DEBUG); define('LOGUSERLEVEL', LOGLEVEL_DEVICEID); date_default_timezone_set('Europe/Madrid'); $body = file_get_contents('testing/samples/meeting_request.txt'); $ical = new iCalComponent(); $ical->ParseFrom($body); $props = $ical->GetPropertiesByPath("VTIMEZONE/TZID"); if (count($props) > 0) { $tzid = $props[0]->Value(); printf("TZID %s\n", $props[0]->Value()); } print_r(TimezoneUtil::GetFullTZFromTZName($tzid)); $body = file_get_contents('testing/samples/meeting_request_rim.txt'); $ical = new iCalComponent(); $ical->ParseFrom($body); $props = $ical->GetPropertiesByPath("VTIMEZONE/TZID"); if (count($props) > 0) { $tzid = $props[0]->Value(); printf("TZID %s\n", $props[0]->Value()); } print_r(TimezoneUtil::GetFullTZFromTZName($tzid));