Example #1
0
 function _setAppointment($mapimessage, $appointment)
 {
     // MAPI stores months as the amount of minutes until the beginning of the month in a
     // non-leapyear. Why this is, is totally unclear.
     $monthminutes = array(0, 44640, 84960, 129600, 172800, 217440, 260640, 305280, 348480, 393120, 437760, 480960);
     // Get timezone info
     if (isset($appointment->timezone)) {
         $tz = $this->_getTZFromSyncBlob(base64_decode($appointment->timezone));
     } else {
         $tz = false;
     }
     mapi_setprops($mapimessage, array($this->_getPropIDFromString("PT_BINARY:{00062002-0000-0000-C000-000000000046}:0x8233") => $this->_getMAPIBlobFromTZ($tz)));
     //calculate duration because without it some webaccess views are broken. duration is in min
     $localstart = $this->_getLocaltimeByTZ($appointment->starttime, $tz);
     $localend = $this->_getLocaltimeByTZ($appointment->endtime, $tz);
     $duration = ($localend - $localstart) / 60;
     //nokia sends an yearly event with 0 mins duration but as all day event,
     //so make it end next day
     if ($appointment->starttime == $appointment->endtime && isset($appointment->alldayevent) && $appointment->alldayevent) {
         $duration = 1440;
         $appointment->endtime = $appointment->starttime + 24 * 60 * 60;
         $localend = $localstart + 24 * 60 * 60;
     }
     // is the transmitted UID OL compatible?
     // if not, encapsulate the transmitted uid
     $appointment->uid = getOLUidFromICalUid($appointment->uid);
     mapi_setprops($mapimessage, array(PR_MESSAGE_CLASS => "IPM.Appointment"));
     // START ADDED dw2412 Take care about notes
     if (isset($appointment->airsyncbasebody)) {
         switch ($appointment->airsyncbasebody->type) {
             case '3':
                 $appointment->rtf = $appointment->airsyncbasebody->data;
                 break;
             case '1':
                 $appointment->body = $appointment->airsyncbasebody->data;
                 break;
         }
     }
     if (isset($appointment->rtf)) {
         // start dw2412
         // Nokia MfE 2.9.158 sends contact notes with RTF and Body element.
         // The RTF is empty, the body contains the note therefore we need to unpack the rtf
         // to see if it is realy empty and in case not, take the appointment body.
         $rtf_body = new rtf();
         $rtf_body->loadrtf(base64_decode($appointment->rtf));
         $rtf_body->output("ascii");
         $rtf_body->parse();
         if (isset($appointment->body) && isset($rtf_body->out) && $rtf_body->out == "" && $appointment->body != "") {
             unset($appointment->rtf);
         }
         // end dw2412
     }
     // END ADDED dw2412 Take care about notes
     $this->_setPropsInMAPI($mapimessage, $appointment, $this->_appointmentmapping);
     //we also have to set the responsestatus and not only meetingstatus, so we use another mapi tag
     if (isset($appointment->meetingstatus)) {
         mapi_setprops($mapimessage, array($this->_getPropIDFromString("PT_LONG:{00062002-0000-0000-C000-000000000046}:0x8218") => $appointment->meetingstatus));
     }
     //sensitivity is not enough to mark an appointment as private, so we use another mapi tag
     if (isset($appointment->sensitivity) && $appointment->sensitivity == 0) {
         $private = false;
     } else {
         $private = true;
     }
     // Set commonstart/commonend to start/end and remindertime to start, duration, private and cleanGlobalObjectId
     mapi_setprops($mapimessage, array($this->_getPropIDFromString("PT_SYSTIME:{00062008-0000-0000-C000-000000000046}:0x8516") => $appointment->starttime, $this->_getPropIDFromString("PT_SYSTIME:{00062008-0000-0000-C000-000000000046}:0x8517") => $appointment->endtime, $this->_getPropIDFromString("PT_SYSTIME:{00062008-0000-0000-C000-000000000046}:0x8502") => $appointment->starttime, $this->_getPropIDFromString("PT_LONG:{00062002-0000-0000-C000-000000000046}:0x8213") => $duration, $this->_getPropIDFromString("PT_BOOLEAN:{00062008-0000-0000-C000-000000000046}:0x8506") => $private, $this->_getPropIDFromString("PT_BINARY:{6ED8DA90-450B-101B-98DA-00AA003F1305}:0x23") => $appointment->uid));
     // Set named prop 8510, unknown property, but enables deleting a single occurrence of a recurring
     // type in OLK2003.
     mapi_setprops($mapimessage, array($this->_getPropIDFromString("PT_LONG:{00062008-0000-0000-C000-000000000046}:0x8510") => 369));
     // Set reminder boolean to 'true' if reminderminutes > 30
     mapi_setprops($mapimessage, array($this->_getPropIDFromString("PT_BOOLEAN:{00062008-0000-0000-C000-000000000046}:0x8503") => isset($appointment->reminder) && $appointment->reminder > 0 ? true : false));
     if (isset($appointment->reminder) && $appointment->reminder > 0) {
         // Set 'flagdueby' to correct value (start - reminderminutes)
         mapi_setprops($mapimessage, array($this->_getPropIDFromString("PT_SYSTIME:{00062008-0000-0000-C000-000000000046}:0x8560") => $appointment->starttime - $appointment->reminder));
     }
     if (isset($appointment->recurrence)) {
         // Set PR_ICON_INDEX to 1025 to show correct icon in category view
         mapi_setprops($mapimessage, array(PR_ICON_INDEX => 1025));
         $recurrence = new Recurrence($this->_store, $mapimessage);
         if (!isset($appointment->recurrence->interval)) {
             $appointment->recurrence->interval = 1;
         }
         switch ($appointment->recurrence->type) {
             case 0:
                 $recur["type"] = 10;
                 if (isset($appointment->recurrence->dayofweek)) {
                     $recur["subtype"] = 1;
                 } else {
                     $recur["subtype"] = 0;
                 }
                 $recur["everyn"] = $appointment->recurrence->interval * (60 * 24);
                 break;
             case 1:
                 $recur["type"] = 11;
                 $recur["subtype"] = 1;
                 $recur["everyn"] = $appointment->recurrence->interval;
                 break;
             case 2:
                 $recur["type"] = 12;
                 $recur["subtype"] = 2;
                 $recur["everyn"] = $appointment->recurrence->interval;
                 break;
             case 3:
                 $recur["type"] = 12;
                 $recur["subtype"] = 3;
                 $recur["everyn"] = $appointment->recurrence->interval;
                 break;
             case 4:
                 $recur["type"] = 13;
                 $recur["subtype"] = 1;
                 $recur["everyn"] = $appointment->recurrence->interval * 12;
                 break;
             case 5:
                 $recur["type"] = 13;
                 $recur["subtype"] = 2;
                 $recur["everyn"] = $appointment->recurrence->interval * 12;
                 break;
             case 6:
                 $recur["type"] = 13;
                 $recur["subtype"] = 3;
                 $recur["everyn"] = $appointment->recurrence->interval * 12;
                 break;
         }
         // dw2412 Zarafa expects start & endtime in Localtime for the recurrence! We need localtime depending on tz provided.
         $starttime = $this->_localtimeByTZ($appointment->starttime, $tz, true);
         $endtime = $this->_localtimeByTZ($appointment->endtime, $tz, true);
         $recur["startocc"] = $starttime["tm_hour"] * 60 + $starttime["tm_min"];
         $recur["endocc"] = $recur["startocc"] + $duration;
         // Note that this may be > 24*60 if multi-day
         // dw2412 "start" and "end" are in Local Time when passing to class.recurrence
         $recur["start"] = $this->_getLocaltimeByTz($appointment->starttime, $tz);
         if (isset($appointment->alldayevent) && $appointment->alldayevent) {
             $recur["start"] = $this->_getLocaltimeByTz($appointment->starttime, $tz);
         } else {
             $recur["start"] = $this->_getDayStartOfTimestamp($appointment->starttime);
         }
         $recur["end"] = $this->_getDayStartOfTimestamp(0x7fffffff);
         // Maximum value for end by default
         if (isset($appointment->recurrence->until)) {
             $recur["term"] = 0x21;
             // dw2412 "end" is in Local Time when passing to class.recurrence
             $recur["end"] = $this->_getLocaltimeByTz($appointment->recurrence->until, $tz);
         } else {
             if (isset($appointment->recurrence->occurrences)) {
                 $recur["term"] = 0x22;
                 $recur["numoccur"] = $appointment->recurrence->occurrences;
             } else {
                 $recur["term"] = 0x23;
             }
         }
         if (isset($appointment->recurrence->dayofweek)) {
             $recur["weekdays"] = $appointment->recurrence->dayofweek;
         }
         if (isset($appointment->recurrence->weekofmonth)) {
             $recur["nday"] = $appointment->recurrence->weekofmonth;
         }
         if (isset($appointment->recurrence->monthofyear)) {
             $recur["month"] = $monthminutes[$appointment->recurrence->monthofyear - 1];
         }
         if (isset($appointment->recurrence->dayofmonth)) {
             $recur["monthday"] = $appointment->recurrence->dayofmonth;
         }
         // Process exceptions. The PDA will send all exceptions for this recurring item.
         if (isset($appointment->exceptions)) {
             foreach ($appointment->exceptions as $exception) {
                 // we always need the base date
                 if (!isset($exception->exceptionstarttime)) {
                     continue;
                 }
                 if (isset($exception->deleted) && $exception->deleted) {
                     // Delete exception
                     if (!isset($recur["deleted_occurences"])) {
                         $recur["deleted_occurences"] = array();
                     }
                     if (isset($appointment->alldayevent) && $appointment->alldayevent) {
                         array_push($recur["deleted_occurences"], $this->_getLocaltimeByTZ($exception->exceptionstarttime, $tz));
                     } else {
                         array_push($recur["deleted_occurences"], $this->_getLocaltimeByTZ($this->_getDayStartOfTimestamp($exception->exceptionstarttime)));
                     }
                 } else {
                     // Change exception
                     $mapiexception = array("basedate" => $this->_getDayStartOfTimestamp($exception->exceptionstarttime));
                     if (isset($exception->starttime)) {
                         $mapiexception["start"] = $this->_getLocaltimeByTZ($exception->starttime, $tz);
                     }
                     if (isset($exception->endtime)) {
                         $mapiexception["end"] = $this->_getLocaltimeByTZ($exception->endtime, $tz);
                     }
                     if (isset($exception->subject)) {
                         $mapiexception["subject"] = u2w($exception->subject);
                     }
                     if (isset($exception->location)) {
                         $mapiexception["location"] = u2w($exception->location);
                     }
                     if (isset($exception->busystatus)) {
                         $mapiexception["busystatus"] = $exception->busystatus;
                     }
                     if (isset($exception->reminder)) {
                         $mapiexception["reminder_set"] = 1;
                         $mapiexception["remind_before"] = $exception->reminder;
                     }
                     if (isset($exception->alldayevent)) {
                         $mapiexception["alldayevent"] = $exception->alldayevent;
                     }
                     if (!isset($recur["changed_occurences"])) {
                         $recur["changed_occurences"] = array();
                     }
                     array_push($recur["changed_occurences"], $mapiexception);
                 }
             }
         }
         $recurrence->setRecurrence($tz, $recur);
     } else {
         $isrecurringtag = $this->_getPropIDFromString("PT_BOOLEAN:{00062002-0000-0000-C000-000000000046}:0x8223");
         mapi_setprops($mapimessage, array($isrecurringtag => false));
     }
     // Do attendees
     if (isset($appointment->attendees) && is_array($appointment->attendees)) {
         $recips = array();
         foreach ($appointment->attendees as $attendee) {
             $recip = array();
             $recip[PR_DISPLAY_NAME] = u2w($attendee->name);
             $recip[PR_EMAIL_ADDRESS] = u2w($attendee->email);
             $recip[PR_ADDRTYPE] = "SMTP";
             // START CHANGED dw2412 to support AS 12.0 attendee type
             if (isset($attendee->type)) {
                 $recip[PR_RECIPIENT_TYPE] = $attendee->attendeetype;
             } else {
                 $recip[PR_RECIPIENT_TYPE] = MAPI_TO;
             }
             // END CHANGED dw2412 to support AS 12.0 attendee type
             $recip[PR_ENTRYID] = mapi_createoneoff($recip[PR_DISPLAY_NAME], $recip[PR_ADDRTYPE], $recip[PR_EMAIL_ADDRESS]);
             array_push($recips, $recip);
         }
         mapi_message_modifyrecipients($mapimessage, 0, $recips);
         mapi_setprops($mapimessage, array(PR_ICON_INDEX => 1026, $this->_getPropIDFromString("PT_BOOLEAN:{00062002-0000-0000-C000-000000000046}:0x8229") => true));
     }
     //START ADDED dw2412 Birthday & Anniversary create / update
     // update linked contacts (birthday & anniversary)
     $this->_setLinkedContact($mapimessage);
     //END ADDED dw2412 Birthday & Anniversary create / update
 }
Example #2
0
 function _setAppointment($mapimessage, $appointment)
 {
     // MAPI stores months as the amount of minutes until the beginning of the month in a
     // non-leapyear. Why this is, is totally unclear.
     $monthminutes = array(0, 44640, 84960, 129600, 172800, 217440, 260640, 305280, 348480, 393120, 437760, 480960);
     // Get timezone info
     if (isset($appointment->timezone)) {
         $tz = $this->_getTZFromSyncBlob(base64_decode($appointment->timezone));
     } else {
         $tz = false;
     }
     //calculate duration because without it some webaccess views are broken. duration is in min
     $localstart = $this->_getLocaltimeByTZ($appointment->starttime, $tz);
     $localend = $this->_getLocaltimeByTZ($appointment->endtime, $tz);
     $duration = ($localend - $localstart) / 60;
     //nokia sends an yearly event with 0 mins duration but as all day event,
     //so make it end next day
     if ($appointment->starttime == $appointment->endtime && isset($appointment->alldayevent) && $appointment->alldayevent) {
         $duration = 1440;
         $appointment->endtime = $appointment->starttime + 24 * 60 * 60;
         $localend = $localstart + 24 * 60 * 60;
     }
     // is the transmitted UID OL compatible?
     // if not, encapsulate the transmitted uid
     $appointment->uid = getOLUidFromICalUid($appointment->uid);
     mapi_setprops($mapimessage, array(PR_MESSAGE_CLASS => "IPM.Appointment"));
     $this->_setPropsInMAPI($mapimessage, $appointment, $this->_appointmentmapping);
     //we also have to set the responsestatus and not only meetingstatus, so we use another mapi tag
     if (isset($appointment->meetingstatus)) {
         mapi_setprops($mapimessage, array($this->_getPropIDFromString("PT_LONG:{00062002-0000-0000-C000-000000000046}:0x8218") => $appointment->meetingstatus));
     }
     //sensitivity is not enough to mark an appointment as private, so we use another mapi tag
     if (isset($appointment->sensitivity) && $appointment->sensitivity == 0) {
         $private = false;
     } else {
         $private = true;
     }
     // Set commonstart/commonend to start/end and remindertime to start, duration, private and cleanGlobalObjectId
     mapi_setprops($mapimessage, array($this->_getPropIDFromString("PT_SYSTIME:{00062008-0000-0000-C000-000000000046}:0x8516") => $appointment->starttime, $this->_getPropIDFromString("PT_SYSTIME:{00062008-0000-0000-C000-000000000046}:0x8517") => $appointment->endtime, $this->_getPropIDFromString("PT_SYSTIME:{00062008-0000-0000-C000-000000000046}:0x8502") => $appointment->starttime, $this->_getPropIDFromString("PT_LONG:{00062002-0000-0000-C000-000000000046}:0x8213") => $duration, $this->_getPropIDFromString("PT_BOOLEAN:{00062008-0000-0000-C000-000000000046}:0x8506") => $private, $this->_getPropIDFromString("PT_BINARY:{6ED8DA90-450B-101B-98DA-00AA003F1305}:0x23") => $appointment->uid));
     // Set named prop 8510, unknown property, but enables deleting a single occurrence of a recurring
     // type in OLK2003.
     mapi_setprops($mapimessage, array($this->_getPropIDFromString("PT_LONG:{00062008-0000-0000-C000-000000000046}:0x8510") => 369));
     // Set reminder boolean to 'true' if reminder is set
     mapi_setprops($mapimessage, array($this->_getPropIDFromString("PT_BOOLEAN:{00062008-0000-0000-C000-000000000046}:0x8503") => isset($appointment->reminder) ? true : false));
     if (isset($appointment->reminder) && $appointment->reminder > 0) {
         //start is in seconds and reminder in minutes, so it needs to be multiplied by 60
         // Set 'flagdueby' to correct value (start - reminderminutes)
         mapi_setprops($mapimessage, array($this->_getPropIDFromString("PT_SYSTIME:{00062008-0000-0000-C000-000000000046}:0x8560") => $appointment->starttime - $appointment->reminder * 60));
     }
     if (isset($appointment->recurrence)) {
         // Set PR_ICON_INDEX to 1025 to show correct icon in category view
         mapi_setprops($mapimessage, array(PR_ICON_INDEX => 1025));
         $recurrence = new Recurrence($this->_store, $mapimessage);
         if (!isset($appointment->recurrence->interval)) {
             $appointment->recurrence->interval = 1;
         }
         switch ($appointment->recurrence->type) {
             case 0:
                 $recur["type"] = 10;
                 if (isset($appointment->recurrence->dayofweek)) {
                     $recur["subtype"] = 1;
                 } else {
                     $recur["subtype"] = 0;
                 }
                 $recur["everyn"] = $appointment->recurrence->interval * (60 * 24);
                 break;
             case 1:
                 $recur["type"] = 11;
                 $recur["subtype"] = 1;
                 $recur["everyn"] = $appointment->recurrence->interval;
                 break;
             case 2:
                 $recur["type"] = 12;
                 $recur["subtype"] = 2;
                 $recur["everyn"] = $appointment->recurrence->interval;
                 break;
             case 3:
                 $recur["type"] = 12;
                 $recur["subtype"] = 3;
                 $recur["everyn"] = $appointment->recurrence->interval;
                 break;
             case 4:
                 $recur["type"] = 13;
                 $recur["subtype"] = 1;
                 $recur["everyn"] = $appointment->recurrence->interval * 12;
                 break;
             case 5:
                 $recur["type"] = 13;
                 $recur["subtype"] = 2;
                 $recur["everyn"] = $appointment->recurrence->interval * 12;
                 break;
             case 6:
                 $recur["type"] = 13;
                 $recur["subtype"] = 3;
                 $recur["everyn"] = $appointment->recurrence->interval * 12;
                 break;
         }
         $starttime = $this->gmtime($localstart);
         $endtime = $this->gmtime($localend);
         $recur["startocc"] = $starttime["tm_hour"] * 60 + $starttime["tm_min"];
         $recur["endocc"] = $recur["startocc"] + $duration;
         // Note that this may be > 24*60 if multi-day
         // "start" and "end" are in GMT when passing to class.recurrence
         $recur["start"] = $this->_getDayStartOfTimestamp($this->_getGMTTimeByTz($localstart, $tz));
         $recur["end"] = $this->_getDayStartOfTimestamp(0x7fffffff);
         // Maximum GMT value for end by default
         if (isset($appointment->recurrence->until)) {
             $recur["term"] = 0x21;
             $recur["end"] = $appointment->recurrence->until;
         } else {
             if (isset($appointment->recurrence->occurrences)) {
                 $recur["term"] = 0x22;
                 $recur["numoccur"] = $appointment->recurrence->occurrences;
             } else {
                 $recur["term"] = 0x23;
             }
         }
         if (isset($appointment->recurrence->dayofweek)) {
             $recur["weekdays"] = $appointment->recurrence->dayofweek;
         }
         if (isset($appointment->recurrence->weekofmonth)) {
             $recur["nday"] = $appointment->recurrence->weekofmonth;
         }
         if (isset($appointment->recurrence->monthofyear)) {
             $recur["month"] = $monthminutes[$appointment->recurrence->monthofyear - 1];
         }
         if (isset($appointment->recurrence->dayofmonth)) {
             $recur["monthday"] = $appointment->recurrence->dayofmonth;
         }
         // Process exceptions. The PDA will send all exceptions for this recurring item.
         if (isset($appointment->exceptions)) {
             foreach ($appointment->exceptions as $exception) {
                 // we always need the base date
                 if (!isset($exception->exceptionstarttime)) {
                     continue;
                 }
                 if (isset($exception->deleted) && $exception->deleted) {
                     // Delete exception
                     if (!isset($recur["deleted_occurences"])) {
                         $recur["deleted_occurences"] = array();
                     }
                     array_push($recur["deleted_occurences"], $this->_getDayStartOfTimestamp($exception->exceptionstarttime));
                 } else {
                     // Change exception
                     $mapiexception = array("basedate" => $this->_getDayStartOfTimestamp($exception->exceptionstarttime));
                     if (isset($exception->starttime)) {
                         $mapiexception["start"] = $this->_getLocaltimeByTZ($exception->starttime, $tz);
                     }
                     if (isset($exception->endtime)) {
                         $mapiexception["end"] = $this->_getLocaltimeByTZ($exception->endtime, $tz);
                     }
                     if (isset($exception->subject)) {
                         $mapiexception["subject"] = u2w($exception->subject);
                     }
                     if (isset($exception->location)) {
                         $mapiexception["location"] = u2w($exception->location);
                     }
                     if (isset($exception->busystatus)) {
                         $mapiexception["busystatus"] = $exception->busystatus;
                     }
                     if (isset($exception->reminder)) {
                         $mapiexception["reminder_set"] = 1;
                         $mapiexception["remind_before"] = $exception->reminder;
                     }
                     if (isset($exception->alldayevent)) {
                         $mapiexception["alldayevent"] = $exception->alldayevent;
                     }
                     if (!isset($recur["changed_occurences"])) {
                         $recur["changed_occurences"] = array();
                     }
                     array_push($recur["changed_occurences"], $mapiexception);
                 }
             }
         }
         $recurrence->setRecurrence($tz, $recur);
     } else {
         $isrecurringtag = $this->_getPropIDFromString("PT_BOOLEAN:{00062002-0000-0000-C000-000000000046}:0x8223");
         mapi_setprops($mapimessage, array($isrecurringtag => false));
     }
     // Do attendees
     if (isset($appointment->attendees) && is_array($appointment->attendees)) {
         $recips = array();
         //open addresss book for user resolve
         $addrbook = mapi_openaddressbook($this->_session);
         foreach ($appointment->attendees as $attendee) {
             $recip = array();
             $recip[PR_EMAIL_ADDRESS] = u2w($attendee->email);
             // lookup information in GAB if possible so we have up-to-date name for given address
             $userinfo = array(array(PR_DISPLAY_NAME => $recip[PR_EMAIL_ADDRESS]));
             $userinfo = mapi_ab_resolvename($addrbook, $userinfo, EMS_AB_ADDRESS_LOOKUP);
             if (mapi_last_hresult() == NOERROR) {
                 $recip[PR_DISPLAY_NAME] = $userinfo[0][PR_DISPLAY_NAME];
                 $recip[PR_EMAIL_ADDRESS] = $userinfo[0][PR_EMAIL_ADDRESS];
                 $recip[PR_SEARCH_KEY] = $userinfo[0][PR_SEARCH_KEY];
                 $recip[PR_ADDRTYPE] = $userinfo[0][PR_ADDRTYPE];
                 $recip[PR_ENTRYID] = $userinfo[0][PR_ENTRYID];
                 $recip[PR_RECIPIENT_TYPE] = MAPI_TO;
             } else {
                 $recip[PR_DISPLAY_NAME] = u2w($attendee->name);
                 $recip[PR_SEARCH_KEY] = $recip[PR_EMAIL_ADDRESS];
                 $recip[PR_ADDRTYPE] = "SMTP";
                 $recip[PR_RECIPIENT_TYPE] = MAPI_TO;
                 $recip[PR_ENTRYID] = mapi_createoneoff($recip[PR_DISPLAY_NAME], $recip[PR_ADDRTYPE], $recip[PR_EMAIL_ADDRESS]);
             }
             array_push($recips, $recip);
         }
         mapi_message_modifyrecipients($mapimessage, 0, $recips);
         mapi_setprops($mapimessage, array(PR_ICON_INDEX => 1026, $this->_getPropIDFromString("PT_BOOLEAN:{00062002-0000-0000-C000-000000000046}:0x8229") => true));
     }
 }
Example #3
0
 function extractProps($ical, &$mapiprops)
 {
     //mapping between partstat in ical and MAPI Meeting Response classes as well as icons
     $aClassMap = array("ACCEPTED" => array("class" => "IPM.Schedule.Meeting.Resp.Pos", "icon" => 0x405), "DECLINED" => array("class" => "IPM.Schedule.Meeting.Resp.Neg", "icon" => 0x406), "TENTATIVE" => array("class" => "IPM.Schedule.Meeting.Resp.Tent", "icon" => 0x407), "NEEDS-ACTION" => array("class" => "IPM.Schedule.Meeting.Request", "icon" => 0x404), "REQ-PARTICIPANT" => array("class" => "IPM.Schedule.Meeting.Request", "icon" => 0x404));
     $aical = preg_split("/[\n]/", $ical);
     $elemcount = count($aical);
     $i = 0;
     $nextline = $aical[0];
     //last element is empty
     while ($i < $elemcount - 1) {
         $line = $nextline;
         $nextline = $aical[$i + 1];
         //if a line starts with a space or a tab it belongs to the previous line
         while (strlen($nextline) > 0 && ($nextline[0] == " " || $nextline[0] == "\t")) {
             $line = rtrim($line) . substr($nextline, 1);
             $nextline = $aical[++$i + 1];
         }
         $line = rtrim($line);
         switch (strtoupper($line)) {
             case "BEGIN:VCALENDAR":
             case "BEGIN:VEVENT":
             case "END:VEVENT":
             case "END:VCALENDAR":
                 break;
             default:
                 unset($field, $data, $prop_pos, $property);
                 if (ereg("([^:]+):(.*)", $line, $line)) {
                     $field = $line[1];
                     $data = $line[2];
                     $property = $field;
                     $prop_pos = strpos($property, ';');
                     if ($prop_pos !== false) {
                         $property = substr($property, 0, $prop_pos);
                     }
                     $property = strtoupper($property);
                     switch ($property) {
                         case 'DTSTART':
                             $data = $this->getTimestampFromStreamerDate($data);
                             $namedStartTime = GetPropIDFromString($this->_store, "PT_SYSTIME:{00062002-0000-0000-C000-000000000046}:0x820d");
                             $mapiprops[$namedStartTime] = $data;
                             $namedCommonStart = GetPropIDFromString($this->_store, "PT_SYSTIME:{00062008-0000-0000-C000-000000000046}:0x8516");
                             $mapiprops[$namedCommonStart] = $data;
                             $clipStart = GetPropIDFromString($this->_store, "PT_SYSTIME:{00062002-0000-0000-C000-000000000046}:0x8235");
                             $mapiprops[$clipStart] = $data;
                             $mapiprops[PR_START_DATE] = $data;
                             break;
                         case 'DTEND':
                             $data = $this->getTimestampFromStreamerDate($data);
                             $namedEndTime = GetPropIDFromString($this->_store, "PT_SYSTIME:{00062002-0000-0000-C000-000000000046}:0x820e");
                             $mapiprops[$namedEndTime] = $data;
                             $namedCommonEnd = GetPropIDFromString($this->_store, "PT_SYSTIME:{00062008-0000-0000-C000-000000000046}:0x8517");
                             $mapiprops[$namedCommonEnd] = $data;
                             $clipEnd = GetPropIDFromString($this->_store, "PT_SYSTIME:{00062002-0000-0000-C000-000000000046}:0x8236");
                             $mapiprops[$clipEnd] = $data;
                             $mapiprops[PR_END_DATE] = $data;
                             break;
                         case 'UID':
                             $goid = GetPropIDFromString($this->_store, "PT_BINARY:{6ED8DA90-450B-101B-98DA-00AA003F1305}:0x3");
                             $goid2 = GetPropIDFromString($this->_store, "PT_BINARY:{6ED8DA90-450B-101B-98DA-00AA003F1305}:0x23");
                             $mapiprops[$goid] = $mapiprops[$goid2] = getOLUidFromICalUid($data);
                             break;
                         case 'ATTENDEE':
                             $fields = explode(";", $field);
                             foreach ($fields as $field) {
                                 $prop_pos = strpos($field, '=');
                                 if ($prop_pos !== false) {
                                     switch (substr($field, 0, $prop_pos)) {
                                         case 'PARTSTAT':
                                             $partstat = substr($field, $prop_pos + 1);
                                             break;
                                         case 'CN':
                                             $cn = substr($field, $prop_pos + 1);
                                             break;
                                         case 'ROLE':
                                             $role = substr($field, $prop_pos + 1);
                                             break;
                                         case 'RSVP':
                                             $rsvp = substr($field, $prop_pos + 1);
                                             break;
                                     }
                                 }
                             }
                             if (isset($partstat) && isset($aClassMap[$partstat]) && (!isset($mapiprops[PR_MESSAGE_CLASS]) || $mapiprops[PR_MESSAGE_CLASS] == "IPM.Schedule.Meeting.Request")) {
                                 $mapiprops[PR_MESSAGE_CLASS] = $aClassMap[$partstat]['class'];
                                 $mapiprops[PR_ICON_INDEX] = $aClassMap[$partstat]['icon'];
                             } elseif (isset($role) && isset($aClassMap[$role]) && (!isset($mapiprops[PR_MESSAGE_CLASS]) || $mapiprops[PR_MESSAGE_CLASS] == "IPM.Schedule.Meeting.Request")) {
                                 $mapiprops[PR_MESSAGE_CLASS] = $aClassMap[$role]['class'];
                                 $mapiprops[PR_ICON_INDEX] = $aClassMap[$role]['icon'];
                             }
                             // END ADDED dw2412 to support meeting requests on HTC Android Mail App
                             if (!isset($cn)) {
                                 $cn = "";
                             }
                             $data = str_replace("MAILTO:", "", $data);
                             $attendee[] = array('name' => stripslashes($cn), 'email' => stripslashes($data));
                             break;
                         case 'ORGANIZER':
                             $field = str_replace("ORGANIZER;CN=", "", $field);
                             $data = str_replace("MAILTO:", "", $data);
                             $organizer[] = array('name' => stripslashes($field), 'email' => stripslashes($data));
                             break;
                         case 'LOCATION':
                             $data = str_replace("\\n", "<br />", $data);
                             $data = str_replace("\\t", "&nbsp;", $data);
                             $data = str_replace("\\r", "<br />", $data);
                             $data = stripslashes($data);
                             $namedLocation = GetPropIDFromString($this->_store, "PT_STRING8:{00062002-0000-0000-C000-000000000046}:0x8208");
                             $mapiprops[$namedLocation] = $data;
                             $tneflocation = GetPropIDFromString($this->_store, "PT_STRING8:{6ED8DA90-450B-101B-98DA-00AA003F1305}:0x2");
                             $mapiprops[$tneflocation] = $data;
                             break;
                     }
                 }
                 break;
         }
         $i++;
     }
     $useTNEF = GetPropIDFromString($this->_store, "PT_BOOLEAN:{00062008-0000-0000-C000-000000000046}:0x8582");
     $mapiprops[$useTNEF] = true;
 }