/** * Process an incoming meeting request cancellation. This updates the * appointment in your calendar to show that the meeting has been cancelled. */ function processMeetingCancellation() { if (!$this->isMeetingCancellation()) { return; } if ($this->isLocalOrganiser()) { return; } if (!$this->isInCalendar()) { return; } $listProperties = $this->proptags; $listProperties['subject'] = PR_SUBJECT; $listProperties['sent_representing_name'] = PR_SENT_REPRESENTING_NAME; $listProperties['sent_representing_address_type'] = PR_SENT_REPRESENTING_ADDRTYPE; $listProperties['sent_representing_email_address'] = PR_SENT_REPRESENTING_EMAIL_ADDRESS; $listProperties['sent_representing_entryid'] = PR_SENT_REPRESENTING_ENTRYID; $listProperties['sent_representing_search_key'] = PR_SENT_REPRESENTING_SEARCH_KEY; $listProperties['rcvd_representing_name'] = PR_RCVD_REPRESENTING_NAME; $listProperties['rcvd_representing_address_type'] = PR_RCVD_REPRESENTING_ADDRTYPE; $listProperties['rcvd_representing_email_address'] = PR_RCVD_REPRESENTING_EMAIL_ADDRESS; $listProperties['rcvd_representing_entryid'] = PR_RCVD_REPRESENTING_ENTRYID; $listProperties['rcvd_representing_search_key'] = PR_RCVD_REPRESENTING_SEARCH_KEY; $messageProps = mapi_getprops($this->message, $listProperties); $goid = $messageProps[$this->proptags['goid']]; //GlobalID (0x3) if (!isset($goid)) { return; } // get delegator store, if delegate is processing this cancellation if (isset($messageProps[PR_RCVD_REPRESENTING_NAME])) { $delegatorStore = $this->getDelegatorStore($messageProps[PR_RCVD_REPRESENTING_NAME], array(PR_IPM_APPOINTMENT_ENTRYID)); $store = $delegatorStore['store']; $calFolder = $delegatorStore[PR_IPM_APPOINTMENT_ENTRYID]; } else { $store = $this->store; $calFolder = $this->openDefaultCalendar(); } // check for calendar access if ($this->checkCalendarWriteAccess($store) !== true) { // Throw an exception that we don't have write permissions on calendar folder, // allow caller to fill the error message throw new MAPIException(null, MAPI_E_NO_ACCESS); } $calendarItem = $this->getCorrespondentCalendarItem(true); $basedate = $this->getBasedateFromGlobalID($goid); if ($calendarItem !== false) { // if basedate is provided and we could not find the item then it could be that we are processing // an exception so get the exception and process it if ($basedate) { $calendarItemProps = mapi_getprops($calendarItem, array($this->proptags['recurring'])); if ($calendarItemProps[$this->proptags['recurring']] === true) { $recurr = new Recurrence($store, $calendarItem); // Set message class $messageProps[PR_MESSAGE_CLASS] = 'IPM.Appointment'; if ($recurr->isException($basedate)) { $recurr->modifyException($messageProps, $basedate); } else { $recurr->createException($messageProps, $basedate); } } } else { // set the properties of the cancellation object mapi_message_setprops($calendarItem, $messageProps); } mapi_savechanges($calendarItem); } }
/** * Process an incoming meeting request cancellation. This updates the * appointment in your calendar to show that the meeting has been cancelled. */ function processMeetingCancellation() { if ($this->isLocalOrganiser()) { return; } if (!$this->isMeetingCancellation()) { return; } if (!$this->isInCalendar()) { return; } $listProperties = $this->proptags; $listProperties['subject'] = PR_SUBJECT; $listProperties['sent_representing_name'] = PR_SENT_REPRESENTING_NAME; $listProperties['sent_representing_address_type'] = PR_SENT_REPRESENTING_ADDRTYPE; $listProperties['sent_representing_email_address'] = PR_SENT_REPRESENTING_EMAIL_ADDRESS; $listProperties['sent_representing_entryid'] = PR_SENT_REPRESENTING_ENTRYID; $listProperties['sent_representing_search_key'] = PR_SENT_REPRESENTING_SEARCH_KEY; $listProperties['rcvd_representing_name'] = PR_RCVD_REPRESENTING_NAME; $messageprops = mapi_getprops($this->message, $listProperties); $store = $this->store; $goid = $messageprops[$this->proptags['goid']]; //GlobalID (0x3) if (!isset($goid)) { return; } if (isset($messageprops[PR_RCVD_REPRESENTING_NAME])) { $delegatorStore = $this->getDelegatorStore($messageprops); $store = $delegatorStore['store']; $calFolder = $delegatorStore['calFolder']; } else { $calFolder = $this->openDefaultCalendar(); } // First, find the items in the calendar by GOID $calendaritems = $this->findCalendarItems($goid, $calFolder); $basedate = $this->getBasedateFromGlobalID($goid); if ($basedate) { // Calendaritems with GlobalID were not found, so find main recurring item using CleanGlobalID(0x23) if (empty($calendaritems)) { // This meeting req is of an occurrance $goid2 = $messageprops[$this->proptags['goid2']]; // First, find the items in the calendar by GOID $calendaritems = $this->findCalendarItems($goid2); foreach ($calendaritems as $entryid) { // Open each calendar item and set the properties of the cancellation object $calendaritem = mapi_msgstore_openentry($store, $entryid); if ($calendaritem) { $calendaritemProps = mapi_getprops($calendaritem, array($this->proptags['recurring'])); if ($calendaritemProps[$this->proptags['recurring']]) { $recurr = new Recurrence($store, $calendaritem); // Set message class $messageprops[PR_MESSAGE_CLASS] = 'IPM.Appointment'; if ($recurr->isException($basedate)) { $recurr->modifyException($messageprops, $basedate); } else { $recurr->createException($messageprops, $basedate); } } mapi_savechanges($calendaritem); } } } } if (!isset($calendaritem)) { foreach ($calendaritems as $entryid) { // Open each calendar item and set the properties of the cancellation object $calendaritem = mapi_msgstore_openentry($store, $entryid); mapi_message_setprops($calendaritem, $messageprops); mapi_savechanges($calendaritem); } } }
/** * Function which saves the exception data in an attachment. * @param array $exception_props the exception data (like any other MAPI appointment) * @param array $exception_recips list of recipients * @param mapi_message $copy_attach_from mapi message from which attachments should be copied * @return array properties of the exception */ function createExceptionAttachment($exception_props, $exception_recips = array(), $copy_attach_from = false) { // Create new attachment. $attachment = mapi_message_createattach($this->message); $props = array(); $props[PR_ATTACHMENT_FLAGS] = 2; $props[PR_ATTACHMENT_HIDDEN] = true; $props[PR_ATTACHMENT_LINKID] = 0; $props[PR_ATTACH_FLAGS] = 0; $props[PR_ATTACH_METHOD] = 5; $props[PR_DISPLAY_NAME] = "Exception"; $props[PR_EXCEPTION_STARTTIME] = $this->fromGMT($this->tz, $exception_props[$this->proptags["startdate"]]); $props[PR_EXCEPTION_ENDTIME] = $this->fromGMT($this->tz, $exception_props[$this->proptags["duedate"]]); mapi_message_setprops($attachment, $props); $imessage = mapi_attach_openobj($attachment, MAPI_CREATE | MAPI_MODIFY); if ($copy_attach_from) { $attachmentTable = mapi_message_getattachmenttable($copy_attach_from); if ($attachmentTable) { $attachments = mapi_table_queryallrows($attachmentTable, array(PR_ATTACH_NUM, PR_ATTACH_SIZE, PR_ATTACH_LONG_FILENAME, PR_ATTACHMENT_HIDDEN, PR_DISPLAY_NAME, PR_ATTACH_METHOD)); foreach ($attachments as $attach_props) { $attach_old = mapi_message_openattach($copy_attach_from, (int) $attach_props[PR_ATTACH_NUM]); $attach_newResourceMsg = mapi_message_createattach($imessage); mapi_copyto($attach_old, array(), array(), $attach_newResourceMsg, 0); mapi_savechanges($attach_newResourceMsg); } } } $props = $props + $exception_props; // FIXME: the following piece of code is written to fix the creation // of an exception. This is only a quickfix as it is not yet possible // to change an existing exception. // remove mv properties when needed foreach ($props as $propTag => $propVal) { if ((mapi_prop_type($propTag) & MV_FLAG) == MV_FLAG && is_null($propVal)) { unset($props[$propTag]); } } mapi_message_setprops($imessage, $props); $this->setExceptionRecipients($imessage, $exception_recips, true); mapi_message_savechanges($imessage); mapi_message_savechanges($attachment); }