function resolve($session, $name)
{
    $ab = mapi_openaddressbook($session);
    $resolved = mapi_ab_resolvename($ab, array(array(PR_DISPLAY_NAME => $name)), EMS_AB_ADDRESS_LOOKUP);
    $id = false;
    if ($resolved) {
        $id = $resolved[0][PR_ENTRYID];
    }
    return $id;
}
 /**
  * Writes a SyncAppointment to MAPI
  *
  * @param mixed             $mapimessage
  * @param SyncAppointment   $message
  *
  * @access private
  * @return boolean
  */
 private function setAppointment($mapimessage, $appointment)
 {
     // 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 = Utils::GetOLUidFromICalUid($appointment->uid);
     mapi_setprops($mapimessage, array(PR_MESSAGE_CLASS => "IPM.Appointment"));
     $appointmentmapping = MAPIMapping::GetAppointmentMapping();
     $this->setPropsInMAPI($mapimessage, $appointment, $appointmentmapping);
     $appointmentprops = MAPIMapping::GetAppointmentProperties();
     $appointmentprops = array_merge($this->getPropIdsFromStrings($appointmentmapping), $this->getPropIdsFromStrings($appointmentprops));
     //appointment specific properties to be set
     $props = array();
     //we also have to set the responsestatus and not only meetingstatus, so we use another mapi tag
     $props[$appointmentprops["responsestatus"]] = isset($appointment->responsestatus) ? $appointment->responsestatus : olResponseNone;
     //sensitivity is not enough to mark an appointment as private, so we use another mapi tag
     $private = isset($appointment->sensitivity) && $appointment->sensitivity == 0 ? false : true;
     // Set commonstart/commonend to start/end and remindertime to start, duration, private and cleanGlobalObjectId
     $props[$appointmentprops["commonstart"]] = $appointment->starttime;
     $props[$appointmentprops["commonend"]] = $appointment->endtime;
     $props[$appointmentprops["reminderstart"]] = $appointment->starttime;
     // Set reminder boolean to 'true' if reminder is set
     $props[$appointmentprops["reminderset"]] = isset($appointment->reminder) ? true : false;
     $props[$appointmentprops["duration"]] = $duration;
     $props[$appointmentprops["private"]] = $private;
     $props[$appointmentprops["uid"]] = $appointment->uid;
     // Set named prop 8510, unknown property, but enables deleting a single occurrence of a recurring
     // type in OLK2003.
     $props[$appointmentprops["sideeffects"]] = 369;
     if (isset($appointment->reminder) && $appointment->reminder >= 0) {
         // Set 'flagdueby' to correct value (start - reminderminutes)
         $props[$appointmentprops["flagdueby"]] = $appointment->starttime - $appointment->reminder * 60;
         $props[$appointmentprops["remindertime"]] = $appointment->reminder;
     } else {
         $props[$appointmentprops["reminderset"]] = false;
     }
     if (isset($appointment->asbody)) {
         $this->setASbody($appointment->asbody, $props, $appointmentprops);
     }
     if (isset($appointment->recurrence)) {
         // Set PR_ICON_INDEX to 1025 to show correct icon in category view
         $props[$appointmentprops["icon"]] = 1025;
         //if there aren't any exceptions, use the 'old style' set recurrence
         $noexceptions = true;
         $recurrence = new Recurrence($this->store, $mapimessage);
         $recur = array();
         $this->setRecurrence($appointment, $recur);
         // set the recurrence type to that of the MAPI
         $props[$appointmentprops["recurrencetype"]] = $recur["recurrencetype"];
         $starttime = $this->gmtime($localstart);
         $endtime = $this->gmtime($localend);
         //set recurrence start here because it's calculated differently for tasks and appointments
         $recur["start"] = $this->getDayStartOfTimestamp($this->getGMTTimeByTZ($localstart, $tz));
         $recur["startocc"] = $starttime["tm_hour"] * 60 + $starttime["tm_min"];
         $recur["endocc"] = $recur["startocc"] + $duration;
         // Note that this may be > 24*60 if multi-day
         //only tasks can regenerate
         $recur["regen"] = false;
         // 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
                     $basedate = $this->getDayStartOfTimestamp($exception->exceptionstarttime);
                     $mapiexception = array("basedate" => $basedate);
                     //other exception properties which are not handled in recurrence
                     $exceptionprops = array();
                     if (isset($exception->starttime)) {
                         $mapiexception["start"] = $this->getLocaltimeByTZ($exception->starttime, $tz);
                         $exceptionprops[$appointmentprops["starttime"]] = $exception->starttime;
                     }
                     if (isset($exception->endtime)) {
                         $mapiexception["end"] = $this->getLocaltimeByTZ($exception->endtime, $tz);
                         $exceptionprops[$appointmentprops["endtime"]] = $exception->endtime;
                     }
                     if (isset($exception->subject)) {
                         $exceptionprops[$appointmentprops["subject"]] = $mapiexception["subject"] = u2w($exception->subject);
                     }
                     if (isset($exception->location)) {
                         $exceptionprops[$appointmentprops["location"]] = $mapiexception["location"] = u2w($exception->location);
                     }
                     if (isset($exception->busystatus)) {
                         $exceptionprops[$appointmentprops["busystatus"]] = $mapiexception["busystatus"] = $exception->busystatus;
                     }
                     if (isset($exception->reminder)) {
                         $exceptionprops[$appointmentprops["reminderset"]] = $mapiexception["reminder_set"] = 1;
                         $exceptionprops[$appointmentprops["remindertime"]] = $mapiexception["remind_before"] = $exception->reminder;
                     }
                     if (isset($exception->alldayevent)) {
                         $exceptionprops[$appointmentprops["alldayevent"]] = $mapiexception["alldayevent"] = $exception->alldayevent;
                     }
                     if (!isset($recur["changed_occurences"])) {
                         $recur["changed_occurences"] = array();
                     }
                     if (isset($exception->body)) {
                         $exceptionprops[$appointmentprops["body"]] = u2w($exception->body);
                     }
                     array_push($recur["changed_occurences"], $mapiexception);
                     if (!empty($exceptionprops)) {
                         $noexceptions = false;
                         if ($recurrence->isException($basedate)) {
                             $recurrence->modifyException($exceptionprops, $basedate);
                         } else {
                             $recurrence->createException($exceptionprops, $basedate);
                         }
                     }
                 }
             }
         }
         //setRecurrence deletes the attachments from an appointment
         if ($noexceptions) {
             $recurrence->setRecurrence($tz, $recur);
         }
     } else {
         $props[$appointmentprops["isrecurring"]] = false;
     }
     //always set the PR_SENT_REPRESENTING_* props so that the attendee status update also works with the webaccess
     $p = array($appointmentprops["representingentryid"], $appointmentprops["representingname"], $appointmentprops["sentrepresentingaddt"], $appointmentprops["sentrepresentingemail"], $appointmentprops["sentrepresentinsrchk"]);
     $representingprops = $this->getProps($mapimessage, $p);
     if (!isset($representingprops[$appointmentprops["representingentryid"]])) {
         $props[$appointmentprops["representingname"]] = Request::GetAuthUser();
         $props[$appointmentprops["sentrepresentingemail"]] = Request::GetAuthUser();
         $props[$appointmentprops["sentrepresentingaddt"]] = "ZARAFA";
         $props[$appointmentprops["representingentryid"]] = mapi_createoneoff(Request::GetAuthUser(), "ZARAFA", Request::GetAuthUser());
         $props[$appointmentprops["sentrepresentinsrchk"]] = $props[$appointmentprops["sentrepresentingaddt"]] . ":" . $props[$appointmentprops["sentrepresentingemail"]];
     }
     // Do attendees
     if (isset($appointment->attendees) && is_array($appointment->attendees)) {
         $recips = array();
         // Outlook XP requires organizer in the attendee list as well
         $org = array();
         $org[PR_ENTRYID] = isset($representingprops[$appointmentprops["representingentryid"]]) ? $representingprops[$appointmentprops["representingentryid"]] : $props[$appointmentprops["representingentryid"]];
         $org[PR_DISPLAY_NAME] = isset($representingprops[$appointmentprops["representingname"]]) ? $representingprops[$appointmentprops["representingname"]] : $props[$appointmentprops["representingname"]];
         $org[PR_ADDRTYPE] = isset($representingprops[$appointmentprops["sentrepresentingaddt"]]) ? $representingprops[$appointmentprops["sentrepresentingaddt"]] : $props[$appointmentprops["sentrepresentingaddt"]];
         $org[PR_EMAIL_ADDRESS] = isset($representingprops[$appointmentprops["sentrepresentingemail"]]) ? $representingprops[$appointmentprops["sentrepresentingemail"]] : $props[$appointmentprops["sentrepresentingemail"]];
         $org[PR_SEARCH_KEY] = isset($representingprops[$appointmentprops["sentrepresentinsrchk"]]) ? $representingprops[$appointmentprops["sentrepresentinsrchk"]] : $props[$appointmentprops["sentrepresentinsrchk"]];
         $org[PR_RECIPIENT_FLAGS] = recipOrganizer | recipSendable;
         $org[PR_RECIPIENT_TYPE] = MAPI_TO;
         array_push($recips, $org);
         //open addresss book for user resolve
         $addrbook = $this->getAddressbook();
         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;
                 $recip[PR_RECIPIENT_FLAGS] = recipSendable;
             } else {
                 $recip[PR_DISPLAY_NAME] = u2w($attendee->name);
                 $recip[PR_SEARCH_KEY] = "SMTP:" . $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);
         $props[$appointmentprops["icon"]] = 1026;
         $props[$appointmentprops["mrwassent"]] = true;
     }
     mapi_setprops($mapimessage, $props);
 }
 function getDelegatorStore($messageprops)
 {
     // Find the organiser of appointment in addressbook
     $delegatorName = array(array(PR_DISPLAY_NAME => $messageprops[PR_RCVD_REPRESENTING_NAME]));
     $ab = mapi_openaddressbook($this->session);
     $user = mapi_ab_resolvename($ab, $delegatorName, EMS_AB_ADDRESS_LOOKUP);
     // Get StoreEntryID by username
     $delegatorEntryid = mapi_msgstore_createentryid($this->store, $user[0][PR_EMAIL_ADDRESS]);
     // Open store of the delegator
     $delegatorStore = mapi_openmsgstore($this->session, $delegatorEntryid);
     // Open root folder
     $delegatorRoot = mapi_msgstore_openentry($delegatorStore, null);
     // Get calendar entryID
     $delegatorRootProps = mapi_getprops($delegatorRoot, array(PR_IPM_APPOINTMENT_ENTRYID));
     // Open the calendar Folder
     $calFolder = mapi_msgstore_openentry($delegatorStore, $delegatorRootProps[PR_IPM_APPOINTMENT_ENTRYID]);
     return array('store' => $delegatorStore, 'calFolder' => $calFolder);
 }
 /**
  * Function adds recipients in recips array from the string.
  * 
  * @param array $recips recipient array.
  * @param string $recipString recipient string attendees.
  * @param int $type type of the recipient, MAPI_TO/MAPI_CC.
  */
 function setRecipsFromString(&$recips, $recipString, $recipType = MAPI_TO)
 {
     $ab = mapi_openaddressbook($this->session);
     $recipArray = explode(';', $recipString);
     foreach ($recipArray as $recip) {
         $recip = trim($recip);
         if (!empty($recip)) {
             try {
                 $userName = array(array(PR_DISPLAY_NAME => $recip));
                 $user = mapi_ab_resolvename($ab, $userName, EMS_AB_ADDRESS_LOOKUP);
                 $extraRecipient = array();
                 $extraRecipient[PR_RECIPIENT_TYPE] = $recipType;
                 $extraRecipient[PR_ENTRYID] = $user[0][PR_ENTRYID];
                 $extraRecipient[PR_DISPLAY_NAME] = $user[0][PR_DISPLAY_NAME];
                 $extraRecipient[PR_OBJECT_TYPE] = $user[0][PR_OBJECT_TYPE];
                 $extraRecipient[PR_EMAIL_ADDRESS] = $user[0][PR_EMAIL_ADDRESS];
                 $extraRecipient[PR_SMTP_ADDRESS] = $user[0][PR_SMTP_ADDRESS];
                 $extraRecipient[PR_ADDRTYPE] = $user[0][PR_ADDRTYPE];
                 array_push($recips, $extraRecipient);
             } catch (MAPIException $e) {
                 // We couldn't resolve the user, fallback to filling
                 // in the properties which we do know.
                 $extraRecipient = array();
                 $extraRecipient[PR_RECIPIENT_TYPE] = $recipType;
                 $extraRecipient[PR_DISPLAY_NAME] = $recip;
                 array_push($recips, $extraRecipient);
             }
         }
     }
 }
示例#5
0
文件: ics.php 项目: nnaannoo/paskot
 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));
     }
 }