/** * Function which sends response to organizer when attendee accepts, declines or proposes new time to a received meeting request. *@param integer $status response status of attendee *@param integer $proposalStartTime proposed starttime by attendee *@param integer $proposalEndTime proposed endtime by attendee *@param integer $basedate date of occurrence which attendee has responded */ function createResponse($status, $proposalStartTime = false, $proposalEndTime = false, $body = false, $store, $basedate = false, $calFolder) { $messageprops = mapi_getprops($this->message, array(PR_SENT_REPRESENTING_ENTRYID, PR_SENT_REPRESENTING_EMAIL_ADDRESS, PR_SENT_REPRESENTING_ADDRTYPE, PR_SENT_REPRESENTING_NAME, $this->proptags['goid'], $this->proptags['goid2'], $this->proptags['location'], $this->proptags['startdate'], $this->proptags['duedate'], $this->proptags['recurring'], $this->proptags['recurring_pattern'], $this->proptags['recurrence_data'], $this->proptags['timezone_data'], $this->proptags['timezone'], $this->proptags['updatecounter'], PR_SUBJECT, PR_MESSAGE_CLASS, PR_OWNER_APPT_ID, $this->proptags['is_exception'])); if ($basedate && $messageprops[PR_MESSAGE_CLASS] != "IPM.Schedule.Meeting.Request") { // we are creating response from a recurring calendar item object // We found basedate,so opened occurrence and get properties. $recurr = new Recurrence($store, $this->message); $exception = $recurr->getExceptionAttachment($basedate); if ($exception) { // Exception found, Now retrieve properties $imessage = mapi_attach_openobj($exception, 0); $imsgprops = mapi_getprops($imessage); // If location is provided, copy it to the response if (isset($imsgprops[$this->proptags['location']])) { $messageprops[$this->proptags['location']] = $imsgprops[$this->proptags['location']]; } // Update $messageprops with timings of occurrence $messageprops[$this->proptags['startdate']] = $imsgprops[$this->proptags['startdate']]; $messageprops[$this->proptags['duedate']] = $imsgprops[$this->proptags['duedate']]; // Meeting related properties $props[$this->proptags['meetingstatus']] = $imsgprops[$this->proptags['meetingstatus']]; $props[$this->proptags['responsestatus']] = $imsgprops[$this->proptags['responsestatus']]; $props[PR_SUBJECT] = $imsgprops[PR_SUBJECT]; } else { // Exceptions is deleted. // Update $messageprops with timings of occurrence $messageprops[$this->proptags['startdate']] = $recurr->getOccurrenceStart($basedate); $messageprops[$this->proptags['duedate']] = $recurr->getOccurrenceEnd($basedate); $props[$this->proptags['meetingstatus']] = olNonMeeting; $props[$this->proptags['responsestatus']] = olResponseNone; } $props[$this->proptags['recurring']] = false; $props[$this->proptags['is_exception']] = true; } else { // we are creating a response from meeting request mail (it could be recurring or non-recurring) // Send all recurrence info in response, if this is a recurrence meeting. $isRecurring = isset($messageprops[$this->proptags['recurring']]) && $messageprops[$this->proptags['recurring']]; $isException = isset($messageprops[$this->proptags['is_exception']]) && $messageprops[$this->proptags['is_exception']]; if ($isRecurring || $isException) { if ($isRecurring) { $props[$this->proptags['recurring']] = $messageprops[$this->proptags['recurring']]; } if ($isException) { $props[$this->proptags['is_exception']] = $messageprops[$this->proptags['is_exception']]; } $calendaritems = $this->findCalendarItems($messageprops[$this->proptags['goid2']], $calFolder); $calendaritem = mapi_msgstore_openentry($this->store, $calendaritems[0]); $recurr = new Recurrence($store, $calendaritem); } } // we are sending a response for recurring meeting request (or exception), so set some required properties if (isset($recurr) && $recurr) { if (!empty($messageprops[$this->proptags['recurring_pattern']])) { $props[$this->proptags['recurring_pattern']] = $messageprops[$this->proptags['recurring_pattern']]; } if (!empty($messageprops[$this->proptags['recurrence_data']])) { $props[$this->proptags['recurrence_data']] = $messageprops[$this->proptags['recurrence_data']]; } $props[$this->proptags['timezone_data']] = $messageprops[$this->proptags['timezone_data']]; $props[$this->proptags['timezone']] = $messageprops[$this->proptags['timezone']]; $this->generateRecurDates($recurr, $messageprops, $props); } // Create a response message $recip = array(); $recip[PR_ENTRYID] = $messageprops[PR_SENT_REPRESENTING_ENTRYID]; $recip[PR_EMAIL_ADDRESS] = $messageprops[PR_SENT_REPRESENTING_EMAIL_ADDRESS]; $recip[PR_ADDRTYPE] = $messageprops[PR_SENT_REPRESENTING_ADDRTYPE]; $recip[PR_DISPLAY_NAME] = $messageprops[PR_SENT_REPRESENTING_NAME]; $recip[PR_RECIPIENT_TYPE] = MAPI_TO; switch ($status) { case olResponseAccepted: $classpostfix = "Pos"; $subjectprefix = _("Accepted"); break; case olResponseDeclined: $classpostfix = "Neg"; $subjectprefix = _("Declined"); break; case olResponseTentative: $classpostfix = "Tent"; $subjectprefix = _("Tentatively accepted"); break; } if ($proposalStartTime && $proposalEndTime) { // if attendee has proposed new time then change subject prefix $subjectprefix = _("New Time Proposed"); } $props[PR_SUBJECT] = $subjectprefix . ": " . $messageprops[PR_SUBJECT]; $props[PR_MESSAGE_CLASS] = "IPM.Schedule.Meeting.Resp." . $classpostfix; if (isset($messageprops[PR_OWNER_APPT_ID])) { $props[PR_OWNER_APPT_ID] = $messageprops[PR_OWNER_APPT_ID]; } // Set GLOBALID AND CLEANGLOBALID, if exception then also set basedate into GLOBALID(0x3). $props[$this->proptags['goid']] = $this->setBasedateInGlobalID($messageprops[$this->proptags['goid2']], $basedate); $props[$this->proptags['goid2']] = $messageprops[$this->proptags['goid2']]; $props[$this->proptags['updatecounter']] = $messageprops[$this->proptags['updatecounter']]; // get the default store, in which we have to store the accepted email by delegate or normal user. $defaultStore = $this->openDefaultStore(); $props[PR_SENTMAIL_ENTRYID] = $this->getDefaultSentmailEntryID($defaultStore); if ($proposalStartTime && $proposalEndTime) { $props[$this->proptags['proposed_start_whole']] = $proposalStartTime; $props[$this->proptags['proposed_end_whole']] = $proposalEndTime; $props[$this->proptags['proposed_duration']] = round($proposalEndTime - $proposalStartTime) / 60; $props[$this->proptags['counter_proposal']] = true; } //Set body message in Appointment if (isset($body)) { $props[PR_BODY] = $this->getMeetingTimeInfo() ? $this->getMeetingTimeInfo() : $body; } // PR_START_DATE/PR_END_DATE is used in the UI in Outlook on the response message $props[PR_START_DATE] = $messageprops[$this->proptags['startdate']]; $props[PR_END_DATE] = $messageprops[$this->proptags['duedate']]; // Set startdate and duedate in response mail. $props[$this->proptags['startdate']] = $messageprops[$this->proptags['startdate']]; $props[$this->proptags['duedate']] = $messageprops[$this->proptags['duedate']]; // responselocation is used in the UI in Outlook on the response message if (isset($messageprops[$this->proptags['location']])) { $props[$this->proptags['responselocation']] = $messageprops[$this->proptags['location']]; $props[$this->proptags['location']] = $messageprops[$this->proptags['location']]; } // check if $store is set and it is not equal to $defaultStore (means its the delegation case) if (isset($store) && isset($defaultStore)) { $storeProps = mapi_getprops($store, array(PR_ENTRYID)); $defaultStoreProps = mapi_getprops($defaultStore, array(PR_ENTRYID)); if ($storeProps[PR_ENTRYID] !== $defaultStoreProps[PR_ENTRYID]) { // get the properties of the other user (for which the logged in user is a delegate). $storeProps = mapi_getprops($store, array(PR_MAILBOX_OWNER_ENTRYID)); $addrbook = mapi_openaddressbook($this->session); $addrbookitem = mapi_ab_openentry($addrbook, $storeProps[PR_MAILBOX_OWNER_ENTRYID]); $addrbookitemprops = mapi_getprops($addrbookitem, array(PR_DISPLAY_NAME, PR_EMAIL_ADDRESS)); // setting the following properties will ensure that the delegation part of message. $props[PR_SENT_REPRESENTING_ENTRYID] = $storeProps[PR_MAILBOX_OWNER_ENTRYID]; $props[PR_SENT_REPRESENTING_NAME] = $addrbookitemprops[PR_DISPLAY_NAME]; $props[PR_SENT_REPRESENTING_EMAIL_ADDRESS] = $addrbookitemprops[PR_EMAIL_ADDRESS]; $props[PR_SENT_REPRESENTING_ADDRTYPE] = "ZARAFA"; // get the properties of default store and set it accordingly $defaultStoreProps = mapi_getprops($defaultStore, array(PR_MAILBOX_OWNER_ENTRYID)); $addrbookitem = mapi_ab_openentry($addrbook, $defaultStoreProps[PR_MAILBOX_OWNER_ENTRYID]); $addrbookitemprops = mapi_getprops($addrbookitem, array(PR_DISPLAY_NAME, PR_EMAIL_ADDRESS)); // set the following properties will ensure the sender's details, which will be the default user in this case. //the function returns array($name, $emailaddr, $addrtype, $entryid, $searchkey); $defaultUserDetails = $this->getOwnerAddress($defaultStore); $props[PR_SENDER_ENTRYID] = $defaultUserDetails[3]; $props[PR_SENDER_EMAIL_ADDRESS] = $defaultUserDetails[1]; $props[PR_SENDER_NAME] = $defaultUserDetails[0]; $props[PR_SENDER_ADDRTYPE] = $defaultUserDetails[2]; } } // pass the default store to get the required store. $outbox = $this->openDefaultOutbox($defaultStore); $message = mapi_folder_createmessage($outbox); mapi_setprops($message, $props); mapi_message_modifyrecipients($message, MODRECIP_ADD, array($recip)); mapi_message_savechanges($message); mapi_message_submitmessage($message); }
/** * Function which sends response to organizer when attendee accepts, declines or proposes new time to a received meeting request. * @param integer $status response status of attendee * @param Array $proposeNewTimeProps properties of attendee's proposal * @param integer $basedate date of occurrence which attendee has responded */ function createResponse($status, $proposeNewTimeProps = array(), $body = false, $store, $basedate = false, $calFolder) { $messageprops = mapi_getprops($this->message, array(PR_SENT_REPRESENTING_ENTRYID, PR_SENT_REPRESENTING_EMAIL_ADDRESS, PR_SENT_REPRESENTING_ADDRTYPE, PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_SEARCH_KEY, $this->proptags['goid'], $this->proptags['goid2'], $this->proptags['location'], $this->proptags['startdate'], $this->proptags['duedate'], $this->proptags['recurring'], $this->proptags['recurring_pattern'], $this->proptags['recurrence_data'], $this->proptags['timezone_data'], $this->proptags['timezone'], $this->proptags['updatecounter'], PR_SUBJECT, PR_MESSAGE_CLASS, PR_OWNER_APPT_ID, $this->proptags['is_exception'])); if ($basedate && !$this->isMeetingRequest($messageprops[PR_MESSAGE_CLASS])) { // we are creating response from a recurring calendar item object // We found basedate,so opened occurrence and get properties. $recurr = new Recurrence($store, $this->message); $exception = $recurr->getExceptionAttachment($basedate); if ($exception) { // Exception found, Now retrieve properties $imessage = mapi_attach_openobj($exception, 0); $imsgprops = mapi_getprops($imessage); // If location is provided, copy it to the response if (isset($imsgprops[$this->proptags['location']])) { $messageprops[$this->proptags['location']] = $imsgprops[$this->proptags['location']]; } // Update $messageprops with timings of occurrence $messageprops[$this->proptags['startdate']] = $imsgprops[$this->proptags['startdate']]; $messageprops[$this->proptags['duedate']] = $imsgprops[$this->proptags['duedate']]; // Meeting related properties $props[$this->proptags['meetingstatus']] = $imsgprops[$this->proptags['meetingstatus']]; $props[$this->proptags['responsestatus']] = $imsgprops[$this->proptags['responsestatus']]; $props[PR_SUBJECT] = $imsgprops[PR_SUBJECT]; } else { // Exceptions is deleted. // Update $messageprops with timings of occurrence $messageprops[$this->proptags['startdate']] = $recurr->getOccurrenceStart($basedate); $messageprops[$this->proptags['duedate']] = $recurr->getOccurrenceEnd($basedate); $props[$this->proptags['meetingstatus']] = olNonMeeting; $props[$this->proptags['responsestatus']] = olResponseNone; } $props[$this->proptags['recurring']] = false; $props[$this->proptags['is_exception']] = true; } else { // we are creating a response from meeting request mail (it could be recurring or non-recurring) // Send all recurrence info in response, if this is a recurrence meeting. $isRecurring = isset($messageprops[$this->proptags['recurring']]) && $messageprops[$this->proptags['recurring']]; $isException = isset($messageprops[$this->proptags['is_exception']]) && $messageprops[$this->proptags['is_exception']]; if ($isRecurring || $isException) { if ($isRecurring) { $props[$this->proptags['recurring']] = $messageprops[$this->proptags['recurring']]; } if ($isException) { $props[$this->proptags['is_exception']] = $messageprops[$this->proptags['is_exception']]; } $calendaritems = $this->findCalendarItems($messageprops[$this->proptags['goid2']], $calFolder); $calendaritem = mapi_msgstore_openentry($store, $calendaritems[0]); $recurr = new Recurrence($store, $calendaritem); } } // we are sending a response for recurring meeting request (or exception), so set some required properties if (isset($recurr) && $recurr) { if (!empty($messageprops[$this->proptags['recurring_pattern']])) { $props[$this->proptags['recurring_pattern']] = $messageprops[$this->proptags['recurring_pattern']]; } if (!empty($messageprops[$this->proptags['recurrence_data']])) { $props[$this->proptags['recurrence_data']] = $messageprops[$this->proptags['recurrence_data']]; } $props[$this->proptags['timezone_data']] = $messageprops[$this->proptags['timezone_data']]; $props[$this->proptags['timezone']] = $messageprops[$this->proptags['timezone']]; $this->generateRecurDates($recurr, $messageprops, $props); } // Create a response message $recip = array(); $recip[PR_ENTRYID] = $messageprops[PR_SENT_REPRESENTING_ENTRYID]; $recip[PR_EMAIL_ADDRESS] = $messageprops[PR_SENT_REPRESENTING_EMAIL_ADDRESS]; $recip[PR_ADDRTYPE] = $messageprops[PR_SENT_REPRESENTING_ADDRTYPE]; $recip[PR_DISPLAY_NAME] = $messageprops[PR_SENT_REPRESENTING_NAME]; $recip[PR_RECIPIENT_TYPE] = MAPI_TO; $recip[PR_SEARCH_KEY] = $messageprops[PR_SENT_REPRESENTING_SEARCH_KEY]; switch ($status) { case olResponseAccepted: $classpostfix = 'Pos'; $subjectprefix = dgettext('zarafa', 'Accepted'); break; case olResponseDeclined: $classpostfix = 'Neg'; $subjectprefix = dgettext('zarafa', 'Declined'); break; case olResponseTentative: $classpostfix = 'Tent'; $subjectprefix = dgettext('zarafa', 'Tentatively accepted'); break; } if (!empty($proposeNewTimeProps)) { // if attendee has proposed new time then change subject prefix $subjectprefix = dgettext('zarafa', 'New Time Proposed'); } $props[PR_SUBJECT] = $subjectprefix . ': ' . $messageprops[PR_SUBJECT]; $props[PR_MESSAGE_CLASS] = 'IPM.Schedule.Meeting.Resp.' . $classpostfix; if (isset($messageprops[PR_OWNER_APPT_ID])) { $props[PR_OWNER_APPT_ID] = $messageprops[PR_OWNER_APPT_ID]; } // Set GlobalId AND CleanGlobalId, if exception then also set basedate into GlobalId(0x3). $props[$this->proptags['goid']] = $this->setBasedateInGlobalID($messageprops[$this->proptags['goid2']], $basedate); $props[$this->proptags['goid2']] = $messageprops[$this->proptags['goid2']]; $props[$this->proptags['updatecounter']] = isset($messageprops[$this->proptags['updatecounter']]) ? $messageprops[$this->proptags['updatecounter']] : 0; if (!empty($proposeNewTimeProps)) { // merge proposal properties to message properties which will be sent to organizer $props = $proposeNewTimeProps + $props; } //Set body message in Appointment if (isset($body)) { $props[PR_BODY] = $this->getMeetingTimeInfo() ? $this->getMeetingTimeInfo() : $body; } // PR_START_DATE/PR_END_DATE is used in the UI in Outlook on the response message $props[PR_START_DATE] = $messageprops[$this->proptags['startdate']]; $props[PR_END_DATE] = $messageprops[$this->proptags['duedate']]; // Set startdate and duedate in response mail. $props[$this->proptags['startdate']] = $messageprops[$this->proptags['startdate']]; $props[$this->proptags['duedate']] = $messageprops[$this->proptags['duedate']]; // responselocation is used in the UI in Outlook on the response message if (isset($messageprops[$this->proptags['location']])) { $props[$this->proptags['responselocation']] = $messageprops[$this->proptags['location']]; $props[$this->proptags['location']] = $messageprops[$this->proptags['location']]; } $message = $this->createOutgoingMessage($store); mapi_setprops($message, $props); mapi_message_modifyrecipients($message, MODRECIP_ADD, array($recip)); mapi_message_savechanges($message); mapi_message_submitmessage($message); }