/**
  * Pack timezone info for Sync
  *
  * @param array     $tz
  *
  * @access private
  * @return string
  */
 private function getSyncBlobFromTZ($tz)
 {
     // set the correct TZ name (done using the Bias)
     if (!isset($tz["tzname"]) || !$tz["tzname"] || !isset($tz["tznamedst"]) || !$tz["tznamedst"]) {
         $tz = TimezoneUtil::FillTZNames($tz);
     }
     $packed = pack("la64vvvvvvvv" . "la64vvvvvvvv" . "l", $tz["bias"], $tz["tzname"], 0, $tz["dstendmonth"], $tz["dstendday"], $tz["dstendweek"], $tz["dstendhour"], $tz["dstendminute"], $tz["dstendsecond"], $tz["dstendmillis"], $tz["stdbias"], $tz["tznamedst"], 0, $tz["dststartmonth"], $tz["dststartday"], $tz["dststartweek"], $tz["dststarthour"], $tz["dststartminute"], $tz["dststartsecond"], $tz["dststartmillis"], $tz["dstbias"]);
     return $packed;
 }
示例#2
0
/**
 * 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 = "";
}
示例#3
0
 /**
  * Reads an email object from MAPI
  *
  * @param mixed             $mapimessage
  * @param ContentParameters $contentparameters
  *
  * @access private
  * @return SyncEmail
  */
 private function getEmail($mapimessage, $contentparameters)
 {
     $message = new SyncMail();
     $this->getPropsFromMAPI($message, $mapimessage, MAPIMapping::GetEmailMapping());
     $emailproperties = MAPIMapping::GetEmailProperties();
     $messageprops = $this->getProps($mapimessage, $emailproperties);
     if (isset($messageprops[PR_SOURCE_KEY])) {
         $sourcekey = $messageprops[PR_SOURCE_KEY];
     } else {
         return false;
     }
     //set the body according to contentparameters and supported AS version
     $this->setMessageBody($mapimessage, $contentparameters, $message);
     $fromname = $fromaddr = "";
     if (isset($messageprops[$emailproperties["representingname"]])) {
         // remove encapsulating double quotes from the representingname
         $fromname = preg_replace('/^\\"(.*)\\"$/', "\${1}", $messageprops[$emailproperties["representingname"]]);
     }
     if (isset($messageprops[$emailproperties["representingentryid"]])) {
         $fromaddr = $this->getSMTPAddressFromEntryID($messageprops[$emailproperties["representingentryid"]]);
     }
     if ($fromname == $fromaddr) {
         $fromname = "";
     }
     if ($fromname) {
         $from = "\"" . w2u($fromname) . "\" <" . w2u($fromaddr) . ">";
     } else {
         //START CHANGED dw2412 HTC shows "error" if sender name is unknown
         $from = "\"" . w2u($fromaddr) . "\" <" . w2u($fromaddr) . ">";
     }
     //END CHANGED dw2412 HTC shows "error" if sender name is unknown
     $message->from = $from;
     // process Meeting Requests
     if (isset($message->messageclass) && strpos($message->messageclass, "IPM.Schedule.Meeting") === 0) {
         $message->meetingrequest = new SyncMeetingRequest();
         $this->getPropsFromMAPI($message->meetingrequest, $mapimessage, MAPIMapping::GetMeetingRequestMapping());
         $meetingrequestproperties = MAPIMapping::GetMeetingRequestProperties();
         $props = $this->getProps($mapimessage, $meetingrequestproperties);
         // Get the GOID
         if (isset($props[$meetingrequestproperties["goidtag"]])) {
             $message->meetingrequest->globalobjid = base64_encode($props[$meetingrequestproperties["goidtag"]]);
         }
         // Set Timezone
         if (isset($props[$meetingrequestproperties["timezonetag"]])) {
             $tz = $this->getTZFromMAPIBlob($props[$meetingrequestproperties["timezonetag"]]);
         } else {
             $tz = $this->getGMTTZ();
         }
         $message->meetingrequest->timezone = base64_encode(TimezoneUtil::GetSyncBlobFromTZ($tz));
         // send basedate if exception
         if (isset($props[$meetingrequestproperties["recReplTime"]]) || isset($props[$meetingrequestproperties["lidIsException"]]) && $props[$meetingrequestproperties["lidIsException"]] == true) {
             if (isset($props[$meetingrequestproperties["recReplTime"]])) {
                 $basedate = $props[$meetingrequestproperties["recReplTime"]];
                 $message->meetingrequest->recurrenceid = $this->getGMTTimeByTZ($basedate, $this->getGMTTZ());
             } else {
                 if (!isset($props[$meetingrequestproperties["goidtag"]]) || !isset($props[$meetingrequestproperties["recurStartTime"]]) || !isset($props[$meetingrequestproperties["timezonetag"]])) {
                     ZLog::Write(LOGLEVEL_WARN, "Missing property to set correct basedate for exception");
                 } else {
                     $basedate = Utils::ExtractBaseDate($props[$meetingrequestproperties["goidtag"]], $props[$meetingrequestproperties["recurStartTime"]]);
                     $message->meetingrequest->recurrenceid = $this->getGMTTimeByTZ($basedate, $tz);
                 }
             }
         }
         // Organizer is the sender
         if (strpos($message->messageclass, "IPM.Schedule.Meeting.Resp") === 0) {
             $message->meetingrequest->organizer = $message->to;
         } else {
             $message->meetingrequest->organizer = $message->from;
         }
         // Process recurrence
         if (isset($props[$meetingrequestproperties["isrecurringtag"]]) && $props[$meetingrequestproperties["isrecurringtag"]]) {
             $myrec = new SyncMeetingRequestRecurrence();
             // get recurrence -> put $message->meetingrequest as message so the 'alldayevent' is set correctly
             $this->getRecurrence($mapimessage, $props, $message->meetingrequest, $myrec, $tz);
             $message->meetingrequest->recurrences = array($myrec);
         }
         // Force the 'alldayevent' in the object at all times. (non-existent == 0)
         if (!isset($message->meetingrequest->alldayevent) || $message->meetingrequest->alldayevent == "") {
             $message->meetingrequest->alldayevent = 0;
         }
         // Instancetype
         // 0 = single appointment
         // 1 = master recurring appointment
         // 2 = single instance of recurring appointment
         // 3 = exception of recurring appointment
         $message->meetingrequest->instancetype = 0;
         if (isset($props[$meetingrequestproperties["isrecurringtag"]]) && $props[$meetingrequestproperties["isrecurringtag"]] == 1) {
             $message->meetingrequest->instancetype = 1;
         } else {
             if ((!isset($props[$meetingrequestproperties["isrecurringtag"]]) || $props[$meetingrequestproperties["isrecurringtag"]] == 0) && isset($message->meetingrequest->recurrenceid)) {
                 if (isset($props[$meetingrequestproperties["appSeqNr"]]) && $props[$meetingrequestproperties["appSeqNr"]] == 0) {
                     $message->meetingrequest->instancetype = 2;
                 } else {
                     $message->meetingrequest->instancetype = 3;
                 }
             }
         }
         // Disable reminder if it is off
         if (!isset($props[$meetingrequestproperties["reminderset"]]) || $props[$meetingrequestproperties["reminderset"]] == false) {
             $message->meetingrequest->reminder = "";
         } else {
             ///set the default reminder time to seconds
             if ($props[$meetingrequestproperties["remindertime"]] == 0x5ae980e1) {
                 $message->meetingrequest->reminder = 900;
             } else {
                 $message->meetingrequest->reminder = $props[$meetingrequestproperties["remindertime"]] * 60;
             }
         }
         // Set sensitivity to 0 if missing
         if (!isset($message->meetingrequest->sensitivity)) {
             $message->meetingrequest->sensitivity = 0;
         }
         // If the user is working from a location other than the office the busystatus should be interpreted as free.
         if (isset($message->meetingrequest->busystatus) && $message->meetingrequest->busystatus == fbWorkingElsewhere) {
             $message->meetingrequest->busystatus = fbFree;
         }
         // If the busystatus has the value of -1, we should be interpreted as tentative (1) / ZP-581
         if (isset($message->meetingrequest->busystatus) && $message->meetingrequest->busystatus == -1) {
             $message->meetingrequest->busystatus = fbTentative;
         }
         // if a meeting request response hasn't been processed yet,
         // do it so that the attendee status is updated on the mobile
         if (!isset($messageprops[$emailproperties["processed"]])) {
             // check if we are not sending the MR so we can process it - ZP-581
             $cuser = ZPush::GetBackend()->GetUserDetails(ZPush::GetBackend()->GetCurrentUsername());
             if (isset($cuser["emailaddress"]) && $cuser["emailaddress"] != $fromaddr) {
                 $req = new Meetingrequest($this->store, $mapimessage, $this->session);
                 if ($req->isMeetingRequestResponse()) {
                     $req->processMeetingRequestResponse();
                 }
                 if ($req->isMeetingCancellation()) {
                     $req->processMeetingCancellation();
                 }
             }
         }
         $message->contentclass = DEFAULT_CALENDAR_CONTENTCLASS;
     }
     // Add attachments
     $attachtable = mapi_message_getattachmenttable($mapimessage);
     $rows = mapi_table_queryallrows($attachtable, array(PR_ATTACH_NUM));
     $entryid = bin2hex($messageprops[$emailproperties["entryid"]]);
     foreach ($rows as $row) {
         if (isset($row[PR_ATTACH_NUM])) {
             if (Request::GetProtocolVersion() >= 12.0) {
                 $attach = new SyncBaseAttachment();
             } else {
                 $attach = new SyncAttachment();
             }
             $mapiattach = mapi_message_openattach($mapimessage, $row[PR_ATTACH_NUM]);
             $attachprops = mapi_getprops($mapiattach, array(PR_ATTACH_LONG_FILENAME, PR_ATTACH_FILENAME, PR_ATTACHMENT_HIDDEN, PR_ATTACH_CONTENT_ID, PR_ATTACH_CONTENT_ID_W, PR_ATTACH_MIME_TAG, PR_ATTACH_MIME_TAG_W, PR_ATTACH_METHOD, PR_DISPLAY_NAME, PR_DISPLAY_NAME_W, PR_ATTACH_SIZE));
             if (isset($attachprops[PR_ATTACH_MIME_TAG]) && strpos(strtolower($attachprops[PR_ATTACH_MIME_TAG]), 'signed') !== false || isset($attachprops[PR_ATTACH_MIME_TAG_W]) && strpos(strtolower($attachprops[PR_ATTACH_MIME_TAG_W]), 'signed') !== false) {
                 continue;
             }
             // the displayname is handled equaly for all AS versions
             $attach->displayname = w2u(isset($attachprops[PR_ATTACH_LONG_FILENAME]) ? $attachprops[PR_ATTACH_LONG_FILENAME] : (isset($attachprops[PR_ATTACH_FILENAME]) ? $attachprops[PR_ATTACH_FILENAME] : (isset($attachprops[PR_DISPLAY_NAME]) ? $attachprops[PR_DISPLAY_NAME] : "attachment.bin")));
             // fix attachment name in case of inline images
             if ($attach->displayname == "inline.txt" && (isset($attachprops[PR_ATTACH_MIME_TAG]) || $attachprops[PR_ATTACH_MIME_TAG_W])) {
                 $mimetype = isset($attachprops[PR_ATTACH_MIME_TAG]) ? $attachprops[PR_ATTACH_MIME_TAG] : $attachprops[PR_ATTACH_MIME_TAG_W];
                 $mime = explode("/", $mimetype);
                 if (count($mime) == 2 && $mime[0] == "image") {
                     $attach->displayname = "inline." . $mime[1];
                 }
             }
             // set AS version specific parameters
             if (Request::GetProtocolVersion() >= 12.0) {
                 $attach->filereference = $entryid . ":" . $row[PR_ATTACH_NUM];
                 $attach->method = isset($attachprops[PR_ATTACH_METHOD]) ? $attachprops[PR_ATTACH_METHOD] : ATTACH_BY_VALUE;
                 // if displayname does not have the eml extension for embedde messages, android and WP devices won't open it
                 if ($attach->method == ATTACH_EMBEDDED_MSG) {
                     if (strtolower(substr($attach->displayname, -4)) != '.eml') {
                         $attach->displayname .= '.eml';
                     }
                 }
                 $attach->estimatedDataSize = $attachprops[PR_ATTACH_SIZE];
                 if (isset($attachprops[PR_ATTACH_CONTENT_ID]) && $attachprops[PR_ATTACH_CONTENT_ID]) {
                     $attach->contentid = $attachprops[PR_ATTACH_CONTENT_ID];
                 }
                 if (!isset($attach->contentid) && isset($attachprops[PR_ATTACH_CONTENT_ID_W]) && $attachprops[PR_ATTACH_CONTENT_ID_W]) {
                     $attach->contentid = $attachprops[PR_ATTACH_CONTENT_ID_W];
                 }
                 if (isset($attachprops[PR_ATTACHMENT_HIDDEN]) && $attachprops[PR_ATTACHMENT_HIDDEN]) {
                     $attach->isinline = 1;
                 }
                 if (!isset($message->asattachments)) {
                     $message->asattachments = array();
                 }
                 array_push($message->asattachments, $attach);
             } else {
                 $attach->attsize = $attachprops[PR_ATTACH_SIZE];
                 $attach->attname = $entryid . ":" . $row[PR_ATTACH_NUM];
                 if (!isset($message->attachments)) {
                     $message->attachments = array();
                 }
                 array_push($message->attachments, $attach);
             }
         }
     }
     // Get To/Cc as SMTP addresses (this is different from displayto and displaycc because we are putting
     // in the SMTP addresses as well, while displayto and displaycc could just contain the display names
     $message->to = array();
     $message->cc = array();
     $reciptable = mapi_message_getrecipienttable($mapimessage);
     $rows = mapi_table_queryallrows($reciptable, array(PR_RECIPIENT_TYPE, PR_DISPLAY_NAME, PR_ADDRTYPE, PR_EMAIL_ADDRESS, PR_SMTP_ADDRESS, PR_ENTRYID));
     foreach ($rows as $row) {
         $address = "";
         $fulladdr = "";
         $addrtype = isset($row[PR_ADDRTYPE]) ? $row[PR_ADDRTYPE] : "";
         if (isset($row[PR_SMTP_ADDRESS])) {
             $address = $row[PR_SMTP_ADDRESS];
         } elseif ($addrtype == "SMTP" && isset($row[PR_EMAIL_ADDRESS])) {
             $address = $row[PR_EMAIL_ADDRESS];
         } elseif ($addrtype == "ZARAFA" && isset($row[PR_ENTRYID])) {
             $address = $this->getSMTPAddressFromEntryID($row[PR_ENTRYID]);
         }
         $name = isset($row[PR_DISPLAY_NAME]) ? $row[PR_DISPLAY_NAME] : "";
         if ($name == "" || $name == $address) {
             $fulladdr = w2u($address);
         } else {
             if (substr($name, 0, 1) != '"' && substr($name, -1) != '"') {
                 $fulladdr = "\"" . w2u($name) . "\" <" . w2u($address) . ">";
             } else {
                 $fulladdr = w2u($name) . "<" . w2u($address) . ">";
             }
         }
         if ($row[PR_RECIPIENT_TYPE] == MAPI_TO) {
             array_push($message->to, $fulladdr);
         } else {
             if ($row[PR_RECIPIENT_TYPE] == MAPI_CC) {
                 array_push($message->cc, $fulladdr);
             }
         }
     }
     if (is_array($message->to) && !empty($message->to)) {
         $message->to = implode(", ", $message->to);
     }
     if (is_array($message->cc) && !empty($message->cc)) {
         $message->cc = implode(", ", $message->cc);
     }
     // without importance some mobiles assume "0" (low) - Mantis #439
     if (!isset($message->importance)) {
         $message->importance = IMPORTANCE_NORMAL;
     }
     //TODO contentclass and nativebodytype and internetcpid
     if (!isset($message->internetcpid)) {
         $message->internetcpid = defined('STORE_INTERNET_CPID') ? constant('STORE_INTERNET_CPID') : INTERNET_CPID_WINDOWS1252;
     }
     $this->setFlag($mapimessage, $message);
     if (!isset($message->contentclass)) {
         $message->contentclass = DEFAULT_EMAIL_CONTENTCLASS;
     }
     if (!isset($message->nativebodytype)) {
         $message->nativebodytype = $this->getNativeBodyType($messageprops);
     }
     // reply, reply to all, forward flags
     if (isset($message->lastverbexecuted) && $message->lastverbexecuted) {
         $message->lastverbexecuted = Utils::GetLastVerbExecuted($message->lastverbexecuted);
     }
     return $message;
 }
示例#4
0
 /**
  * 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 = "";
 }
<?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));
示例#6
0
 function setUp()
 {
     // clearning the tz cache
     TimezoneUtil::$map = null;
 }
示例#7
0
 /**
  * Parse 1 VEvent
  * @param ical_vtodo $vtodo
  * @param SyncAppointment(Exception) $message
  * @param int $truncsize
  */
 private function _ParseVTodoToSyncObject($vtodo, $message, $truncsize)
 {
     //Default
     $message->reminderset = "0";
     $message->importance = "1";
     $message->complete = "0";
     $properties = $vtodo->GetProperties();
     foreach ($properties as $property) {
         switch ($property->Name()) {
             case "SUMMARY":
                 $message->subject = $property->Value();
                 break;
             case "STATUS":
                 switch ($property->Value()) {
                     case "NEEDS-ACTION":
                     case "IN-PROCESS":
                         $message->complete = "0";
                         break;
                     case "COMPLETED":
                     case "CANCELLED":
                         $message->complete = "1";
                         break;
                 }
                 break;
             case "COMPLETED":
                 $message->datecompleted = TimezoneUtil::MakeUTCDate($property->Value());
                 break;
             case "DUE":
                 $message->utcduedate = TimezoneUtil::MakeUTCDate($property->Value());
                 break;
             case "PRIORITY":
                 $priority = $property->Value();
                 if ($priority <= 3) {
                     $message->importance = "0";
                 }
                 if ($priority <= 6) {
                     $message->importance = "1";
                 }
                 if ($priority > 6) {
                     $message->importance = "2";
                 }
                 break;
             case "RRULE":
                 $message->recurrence = $this->_ParseRecurrence($property->Value(), "vtodo");
                 break;
             case "CLASS":
                 switch ($property->Value()) {
                     case "PUBLIC":
                         $message->sensitivity = "0";
                         break;
                     case "PRIVATE":
                         $message->sensitivity = "2";
                         break;
                     case "CONFIDENTIAL":
                         $message->sensitivity = "3";
                         break;
                 }
                 break;
             case "DTSTART":
                 $message->utcstartdate = TimezoneUtil::MakeUTCDate($property->Value());
                 break;
             case "SUMMARY":
                 $message->subject = $property->Value();
                 break;
             case "CATEGORIES":
                 $categories = explode(",", $property->Value());
                 $message->categories = $categories;
                 break;
         }
     }
     if (isset($message->recurrence)) {
         $message->recurrence->start = $message->utcstartdate;
     }
     $valarm = current($vtodo->GetComponents("VALARM"));
     if ($valarm) {
         $properties = $valarm->GetProperties();
         foreach ($properties as $property) {
             if ($property->Name() == "TRIGGER") {
                 $parameters = $property->Parameters();
                 if (array_key_exists("VALUE", $parameters) && $parameters["VALUE"] == "DATE-TIME") {
                     $message->remindertime = TimezoneUtil::MakeUTCDate($property->Value());
                     $message->reminderset = "1";
                 } elseif (!array_key_exists("VALUE", $parameters) || $parameters["VALUE"] == "DURATION") {
                     $val = str_replace("-", "", $property->Value());
                     $interval = new DateInterval($val);
                     $start = date_create("@" . $message->utcstartdate);
                     $message->remindertime = date_timestamp_get(date_sub($start, $interval));
                     $message->reminderset = "1";
                 }
             }
         }
     }
     return $message;
 }
示例#8
0
 /**
  * Generate a tzid from various formats
  *
  * @param str $timezone
  *
  * @access public
  * @return timezone id
  */
 public static function ParseTimezone($timezone)
 {
     //(GMT+01.00) Amsterdam / Berlin / Bern / Rome / Stockholm / Vienna
     if (preg_match('/GMT(\\+|\\-)0(\\d)/', $timezone, $matches)) {
         return "Etc/GMT" . $matches[1] . $matches[2];
     }
     //(GMT+10.00) XXX / XXX / XXX / XXX
     if (preg_match('/GMT(\\+|\\-)1(\\d)/', $timezone, $matches)) {
         return "Etc/GMT" . $matches[1] . "1" . $matches[2];
     }
     ///inverse.ca/20101018_1/Europe/Amsterdam or /inverse.ca/20101018_1/America/Argentina/Buenos_Aires
     if (preg_match('/\\/[.[:word:]]+\\/\\w+\\/(\\w+)\\/([\\w\\/]+)/', $timezone, $matches)) {
         return $matches[1] . "/" . $matches[2];
     }
     return TimezoneUtil::getMSTZnameFromTZName(trim($timezone, '"'));
 }