Exemplo n.º 1
0
 /**
  * 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);
 }
 /**
  * Checks if there has been any significant changes on appointment/meeting item.
  * Significant changes be:
  * 1) startdate has been changed
  * 2) duedate has been changed OR
  * 3) recurrence pattern has been created, modified or removed
  *
  * @param Array oldProps old props before an update
  * @param Number basedate basedate
  * @param Boolean isRecurrenceChanged for change in recurrence pattern.
  * isRecurrenceChanged true means Recurrence pattern has been changed, so clear all attendees response
  */
 function checkSignificantChanges($oldProps, $basedate, $isRecurrenceChanged = false)
 {
     $message = null;
     $attach = null;
     // If basedate is specified then we need to open exception message to clear recipient responses
     if ($basedate) {
         $recurrence = new Recurrence($this->store, $this->message);
         if ($recurrence->isException($basedate)) {
             $attach = $recurrence->getExceptionAttachment($basedate);
             if ($attach) {
                 $message = mapi_attach_openobj($attach, MAPI_MODIFY);
             }
         }
     } else {
         // use normal message or recurring series message
         $message = $this->message;
     }
     if (!$message) {
         return;
     }
     $newProps = mapi_getprops($message, array($this->proptags['startdate'], $this->proptags['duedate'], $this->proptags['updatecounter']));
     // Check whether message is updated or not.
     if (isset($newProps[$this->proptags['updatecounter']]) && $newProps[$this->proptags['updatecounter']] == 0) {
         return;
     }
     if ($newProps[$this->proptags['startdate']] != $oldProps[$this->proptags['startdate']] || $newProps[$this->proptags['duedate']] != $oldProps[$this->proptags['duedate']] || $isRecurrenceChanged) {
         $this->clearRecipientResponse($message);
         mapi_setprops($message, array($this->proptags['owner_critical_change'] => time()));
         mapi_savechanges($message);
         if ($attach) {
             // Also save attachment Object.
             mapi_savechanges($attach);
         }
     }
 }