/** * Function which replaces attachments with copy_from in copy_to. *@param resource $copy_from MAPI_message from which attachments are to be copied. *@param resource $copy_to MAPI_message to which attachment are to be copied. *@param boolean $copyExceptions if true then all exceptions should also be sent as attachments */ function replaceAttachments($copy_from, $copy_to, $copyExceptions = true) { /* remove all old attachments */ $attachmentTable = mapi_message_getattachmenttable($copy_to); if ($attachmentTable) { $attachments = mapi_table_queryallrows($attachmentTable, array(PR_ATTACH_NUM, PR_ATTACH_METHOD, PR_EXCEPTION_STARTTIME)); foreach ($attachments as $attach_props) { /* remove exceptions too? */ if (!$copyExceptions && $attach_props[PR_ATTACH_METHOD] == 5 && isset($attach_props[PR_EXCEPTION_STARTTIME])) { continue; } mapi_message_deleteattach($copy_to, $attach_props[PR_ATTACH_NUM]); } } $attachmentTable = false; /* copy new attachments */ $attachmentTable = mapi_message_getattachmenttable($copy_from); if ($attachmentTable) { $attachments = mapi_table_queryallrows($attachmentTable, array(PR_ATTACH_NUM, PR_ATTACH_METHOD, PR_EXCEPTION_STARTTIME)); foreach ($attachments as $attach_props) { if (!$copyExceptions && $attach_props[PR_ATTACH_METHOD] == 5 && isset($attach_props[PR_EXCEPTION_STARTTIME])) { continue; } $attach_old = mapi_message_openattach($copy_from, (int) $attach_props[PR_ATTACH_NUM]); $attach_newResourceMsg = mapi_message_createattach($copy_to); mapi_copyto($attach_old, array(), array(), $attach_newResourceMsg, 0); mapi_savechanges($attach_newResourceMsg); } } }
/** * Writes a SyncContact to MAPI * * @param mixed $mapimessage * @param SyncContact $contact * * @access private * @return boolean */ private function setContact($mapimessage, $contact) { mapi_setprops($mapimessage, array(PR_MESSAGE_CLASS => "IPM.Contact")); // normalize email addresses if (isset($contact->email1address) && ($contact->email1address = $this->extractEmailAddress($contact->email1address)) === false) { unset($contact->email1address); } if (isset($contact->email2address) && ($contact->email2address = $this->extractEmailAddress($contact->email2address)) === false) { unset($contact->email2address); } if (isset($contact->email3address) && ($contact->email3address = $this->extractEmailAddress($contact->email3address)) === false) { unset($contact->email3address); } $contactmapping = MAPIMapping::GetContactMapping(); $contactprops = MAPIMapping::GetContactProperties(); $this->setPropsInMAPI($mapimessage, $contact, $contactmapping); ///set display name from contact's properties $cname = $this->composeDisplayName($contact); //get contact specific mapi properties and merge them with the AS properties $contactprops = array_merge($this->getPropIdsFromStrings($contactmapping), $this->getPropIdsFromStrings($contactprops)); //contact specific properties to be set $props = array(); //need to be set in order to show contacts properly in outlook and wa $nremails = array(); $abprovidertype = 0; if (isset($contact->email1address)) { $this->setEmailAddress($contact->email1address, $cname, 1, $props, $contactprops, $nremails, $abprovidertype); } if (isset($contact->email2address)) { $this->setEmailAddress($contact->email2address, $cname, 2, $props, $contactprops, $nremails, $abprovidertype); } if (isset($contact->email3address)) { $this->setEmailAddress($contact->email3address, $cname, 3, $props, $contactprops, $nremails, $abprovidertype); } $props[$contactprops["addressbooklong"]] = $abprovidertype; $props[$contactprops["displayname"]] = $props[$contactprops["subject"]] = $cname; //pda multiple e-mail addresses bug fix for the contact if (!empty($nremails)) { $props[$contactprops["addressbookmv"]] = $nremails; } //set addresses $this->setAddress("home", $contact->homecity, $contact->homecountry, $contact->homepostalcode, $contact->homestate, $contact->homestreet, $props, $contactprops); $this->setAddress("business", $contact->businesscity, $contact->businesscountry, $contact->businesspostalcode, $contact->businessstate, $contact->businessstreet, $props, $contactprops); $this->setAddress("other", $contact->othercity, $contact->othercountry, $contact->otherpostalcode, $contact->otherstate, $contact->otherstreet, $props, $contactprops); //set the mailing address and its type if (isset($props[$contactprops["businessaddress"]])) { $props[$contactprops["mailingaddress"]] = 2; $this->setMailingAddress($contact->businesscity, $contact->businesscountry, $contact->businesspostalcode, $contact->businessstate, $contact->businessstreet, $props[$contactprops["businessaddress"]], $props, $contactprops); } elseif (isset($props[$contactprops["homeaddress"]])) { $props[$contactprops["mailingaddress"]] = 1; $this->setMailingAddress($contact->homecity, $contact->homecountry, $contact->homepostalcode, $contact->homestate, $contact->homestreet, $props[$contactprops["homeaddress"]], $props, $contactprops); } elseif (isset($props[$contactprops["otheraddress"]])) { $props[$contactprops["mailingaddress"]] = 3; $this->setMailingAddress($contact->othercity, $contact->othercountry, $contact->otherpostalcode, $contact->otherstate, $contact->otherstreet, $props[$contactprops["otheraddress"]], $props, $contactprops); } if (isset($contact->picture)) { $picbinary = base64_decode($contact->picture); $picsize = strlen($picbinary); if ($picsize < MAX_EMBEDDED_SIZE) { $props[$contactprops["haspic"]] = false; // TODO contact picture handling // check if contact has already got a picture. delete it first in that case // delete it also if it was removed on a mobile $picprops = mapi_getprops($mapimessage, array($props[$contactprops["haspic"]])); if (isset($picprops[$props[$contactprops["haspic"]]]) && $picprops[$props[$contactprops["haspic"]]]) { ZLog::Write(LOGLEVEL_DEBUG, "Contact already has a picture. Delete it"); $attachtable = mapi_message_getattachmenttable($mapimessage); mapi_table_restrict($attachtable, MAPIUtils::GetContactPicRestriction()); $rows = mapi_table_queryallrows($attachtable, array(PR_ATTACH_NUM)); if (isset($rows) && is_array($rows)) { foreach ($rows as $row) { mapi_message_deleteattach($mapimessage, $row[PR_ATTACH_NUM]); } } } // only set picture if there's data in the request if ($picbinary !== false && $picsize > 0) { $props[$contactprops["haspic"]] = true; $pic = mapi_message_createattach($mapimessage); // Set properties of the attachment $picprops = array(PR_ATTACH_LONG_FILENAME_A => "ContactPicture.jpg", PR_DISPLAY_NAME => "ContactPicture.jpg", 0x7fff000b => true, PR_ATTACHMENT_HIDDEN => false, PR_ATTACHMENT_FLAGS => 1, PR_ATTACH_METHOD => ATTACH_BY_VALUE, PR_ATTACH_EXTENSION_A => ".jpg", PR_ATTACH_NUM => 1, PR_ATTACH_SIZE => $picsize, PR_ATTACH_DATA_BIN => $picbinary); mapi_setprops($pic, $picprops); mapi_savechanges($pic); } } } if (isset($contact->asbody)) { $this->setASbody($contact->asbody, $props, $contactprops); } //set fileas if (defined('FILEAS_ORDER')) { $lastname = isset($contact->lastname) ? $contact->lastname : ""; $firstname = isset($contact->firstname) ? $contact->firstname : ""; $middlename = isset($contact->middlename) ? $contact->middlename : ""; $company = isset($contact->companyname) ? $contact->companyname : ""; $props[$contactprops["fileas"]] = Utils::BuildFileAs($lastname, $firstname, $middlename, $company); } else { ZLog::Write(LOGLEVEL_DEBUG, "FILEAS_ORDER not defined"); } mapi_setprops($mapimessage, $props); }
/** * Copies attachments from one message to another. * * @param MAPIMessage $toMessage * @param MAPIMessage $fromMessage * * @return void */ private function copyAttachments(&$toMessage, $fromMessage) { $attachtable = mapi_message_getattachmenttable($fromMessage); $rows = mapi_table_queryallrows($attachtable, array(PR_ATTACH_NUM)); foreach ($rows as $row) { if (isset($row[PR_ATTACH_NUM])) { $attach = mapi_message_openattach($fromMessage, $row[PR_ATTACH_NUM]); $newattach = mapi_message_createattach($toMessage); // Copy all attachments from old to new attachment $attachprops = mapi_getprops($attach); mapi_setprops($newattach, $attachprops); if (isset($attachprops[mapi_prop_tag(PT_ERROR, mapi_prop_id(PR_ATTACH_DATA_BIN))])) { // Data is in a stream $srcstream = mapi_openpropertytostream($attach, PR_ATTACH_DATA_BIN); $dststream = mapi_openpropertytostream($newattach, PR_ATTACH_DATA_BIN, MAPI_MODIFY | MAPI_CREATE); while (1) { $data = mapi_stream_read($srcstream, 4096); if (strlen($data) == 0) { break; } mapi_stream_write($dststream, $data); } mapi_stream_commit($dststream); } mapi_savechanges($newattach); } } }
/** * Function which clones current occurrence and sets appropriate properties. * The original recurring item is moved to next occurrence. *@param boolean $markComplete true if existing occurrence has to be mark complete else false. */ function regenerateTask($markComplete) { // Get all properties $taskItemProps = mapi_getprops($this->message); if (isset($this->action["subject"])) { $taskItemProps[$this->proptags["subject"]] = $this->action["subject"]; } if (isset($this->action["importance"])) { $taskItemProps[$this->proptags["importance"]] = $this->action["importance"]; } if (isset($this->action["startdate"])) { $taskItemProps[$this->proptags["startdate"]] = $this->action["startdate"]; $taskItemProps[$this->proptags["commonstart"]] = $this->action["startdate"]; } if (isset($this->action["duedate"])) { $taskItemProps[$this->proptags["duedate"]] = $this->action["duedate"]; $taskItemProps[$this->proptags["commonend"]] = $this->action["duedate"]; } $folder = mapi_msgstore_openentry($this->store, $taskItemProps[PR_PARENT_ENTRYID]); $newMessage = mapi_folder_createmessage($folder); $taskItemProps[$this->proptags["status"]] = $markComplete ? olTaskComplete : olTaskNotStarted; $taskItemProps[$this->proptags["complete"]] = $markComplete; $taskItemProps[$this->proptags["percent_complete"]] = $markComplete ? 1 : 0; // This occurrence has been marked as 'Complete' so disable reminder if ($markComplete) { $taskItemProps[$this->proptags["reset_reminder"]] = false; $taskItemProps[$this->proptags["reminder"]] = false; $taskItemProps[$this->proptags["datecompleted"]] = $this->action["datecompleted"]; unset($this->action[$this->proptags['datecompleted']]); } // Recurrence ends for this item $taskItemProps[$this->proptags["dead_occurrence"]] = true; $taskItemProps[$this->proptags["task_f_creator"]] = true; //OL props $taskItemProps[$this->proptags["side_effects"]] = 1296; $taskItemProps[$this->proptags["icon_index"]] = 1280; // Copy recipients $recipienttable = mapi_message_getrecipienttable($this->message); $recipients = mapi_table_queryallrows($recipienttable, array(PR_ENTRYID, PR_DISPLAY_NAME, PR_EMAIL_ADDRESS, PR_RECIPIENT_ENTRYID, PR_RECIPIENT_TYPE, PR_SEND_INTERNET_ENCODING, PR_SEND_RICH_INFO, PR_RECIPIENT_DISPLAY_NAME, PR_ADDRTYPE, PR_DISPLAY_TYPE, PR_RECIPIENT_TRACKSTATUS, PR_RECIPIENT_TRACKSTATUS_TIME, PR_RECIPIENT_FLAGS, PR_ROWID)); $copy_to_recipientTable = mapi_message_getrecipienttable($newMessage); $copy_to_recipientRows = mapi_table_queryallrows($copy_to_recipientTable, array(PR_ROWID)); foreach ($copy_to_recipientRows as $recipient) { mapi_message_modifyrecipients($newMessage, MODRECIP_REMOVE, array($recipient)); } mapi_message_modifyrecipients($newMessage, MODRECIP_ADD, $recipients); // Copy attachments $attachmentTable = mapi_message_getattachmenttable($this->message); 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($this->message, (int) $attach_props[PR_ATTACH_NUM]); $attach_newResourceMsg = mapi_message_createattach($newMessage); mapi_copyto($attach_old, array(), array(), $attach_newResourceMsg, 0); mapi_savechanges($attach_newResourceMsg); } } mapi_setprops($newMessage, $taskItemProps); mapi_savechanges($newMessage); // Update body of original message $msgbody = mapi_message_openproperty($this->message, PR_BODY); $msgbody = trim($this->windows1252_to_utf8($msgbody), ""); $separator = "------------\r\n"; if (!empty($msgbody) && strrpos($msgbody, $separator) === false) { $msgbody = $separator . $msgbody; $stream = mapi_openpropertytostream($this->message, PR_BODY, MAPI_CREATE | MAPI_MODIFY); mapi_stream_setsize($stream, strlen($msgbody)); mapi_stream_write($stream, $msgbody); mapi_stream_commit($stream); } // We need these properties to notify client return mapi_getprops($newMessage, array(PR_ENTRYID, PR_PARENT_ENTRYID, PR_STORE_ENTRYID)); }
function _storeAttachment($mapimessage, $part) { // attachment $attach = mapi_message_createattach($mapimessage); $filename = ""; // Filename is present in both Content-Type: name=.. and in Content-Disposition: filename= if (isset($part->ctype_parameters["name"])) { $filename = $part->ctype_parameters["name"]; } else { if (isset($part->d_parameters["name"])) { $filename = $part->d_parameters["filename"]; } else { if (isset($part->d_parameters["filename"])) { // sending appointment with nokia & android only filename is set $filename = $part->d_parameters["filename"]; } else { if (isset($part->d_parameters["filename*0"])) { for ($i = 0; $i < count($part->d_parameters); $i++) { if (isset($part->d_parameters["filename*" . $i])) { $filename .= $part->d_parameters["filename*" . $i]; } } } else { $filename = "untitled"; } } } } // Android just doesn't send content-type, so mimeDecode doesn't performs base64 decoding // on meeting requests text/calendar somewhere inside content-transfer-encoding if (isset($part->headers['content-transfer-encoding']) && strpos($part->headers['content-transfer-encoding'], 'base64')) { if (strpos($part->headers['content-transfer-encoding'], 'text/calendar') !== false) { $part->ctype_primary = 'text'; $part->ctype_secondary = 'calendar'; } if (!isset($part->headers['content-type'])) { $part->body = base64_decode($part->body); } } // Set filename and attachment type mapi_setprops($attach, array(PR_ATTACH_LONG_FILENAME => u2wi($filename), PR_ATTACH_METHOD => ATTACH_BY_VALUE)); // Set attachment data mapi_setprops($attach, array(PR_ATTACH_DATA_BIN => $part->body)); // Set MIME type mapi_setprops($attach, array(PR_ATTACH_MIME_TAG => $part->ctype_primary . "/" . $part->ctype_secondary)); mapi_savechanges($attach); }
/** * 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); }
function sendResponse($type, $prefix) { // Create a message in our outbox $outgoing = $this->createOutgoingMessage(); $messageprops = mapi_getprops($this->message, array(PR_SUBJECT)); $attach = mapi_message_createattach($outgoing); mapi_setprops($attach, array(PR_ATTACH_METHOD => ATTACH_EMBEDDED_MSG, PR_DISPLAY_NAME => $messageprops[PR_SUBJECT], PR_ATTACHMENT_HIDDEN => true)); $sub = mapi_attach_openproperty($attach, PR_ATTACH_DATA_OBJ, IID_IMessage, 0, MAPI_CREATE | MAPI_MODIFY); mapi_copyto($this->message, array(), array(PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_EMAIL_ADDRESS, PR_SENT_REPRESENTING_ADDRTYPE, PR_SENT_REPRESENTING_ENTRYID, PR_SENT_REPRESENTING_SEARCH_KEY), $outgoing); mapi_copyto($this->message, array(), array(), $sub); if (!$this->setRecipientsForResponse($outgoing, $type)) { return false; } switch ($type) { case tdmtTaskAcc: $messageclass = "IPM.TaskRequest.Accept"; break; case tdmtTaskDec: $messageclass = "IPM.TaskRequest.Decline"; break; case tdmtTaskUpd: $messageclass = "IPM.TaskRequest.Update"; break; } mapi_savechanges($sub); mapi_savechanges($attach); // Set Body $body = $this->getBody(); $stream = mapi_openpropertytostream($outgoing, PR_BODY, MAPI_CREATE | MAPI_MODIFY); mapi_stream_setsize($stream, strlen($body)); mapi_stream_write($stream, $body); mapi_stream_commit($stream); // Set subject, taskmode, message class, icon index, response time mapi_setprops($outgoing, array(PR_SUBJECT => $prefix . $messageprops[PR_SUBJECT], $this->props['taskmode'] => $type, PR_MESSAGE_CLASS => $messageclass, PR_ICON_INDEX => 0xffffffff, $this->props['assignedtime'] => time())); mapi_savechanges($outgoing); mapi_message_submitmessage($outgoing); return true; }
function _storeAttachment($mapimessage, $part) { // attachment $attach = mapi_message_createattach($mapimessage); // Filename is present in both Content-Type: name=.. and in Content-Disposition: filename= if (isset($part->ctype_parameters["name"])) { $filename = $part->ctype_parameters["name"]; } else { if (isset($part->d_parameters["name"])) { $filename = $part->d_parameters["filename"]; } else { if (isset($part->d_parameters["filename"])) { //sending appointment with nokia only filename is set $filename = $part->d_parameters["filename"]; } else { $filename = "untitled"; } } } // Set filename and attachment type mapi_setprops($attach, array(PR_ATTACH_LONG_FILENAME => u2w($filename), PR_ATTACH_METHOD => ATTACH_BY_VALUE)); // Set attachment data mapi_setprops($attach, array(PR_ATTACH_DATA_BIN => $part->body)); // Set MIME type mapi_setprops($attach, array(PR_ATTACH_MIME_TAG => $part->ctype_primary . "/" . $part->ctype_secondary)); mapi_savechanges($attach); }
function SendMail($rfc822, $forward = false, $reply = false, $parent = false) { $message = Mail_mimeDecode::decode(array('decode_headers' => true, 'decode_bodies' => true, 'include_bodies' => true, 'input' => $rfc822, 'crlf' => "\r\n", 'charset' => 'utf-8')); // Open the outbox and create the message there $storeprops = mapi_getprops($this->_defaultstore, array(PR_IPM_OUTBOX_ENTRYID, PR_IPM_SENTMAIL_ENTRYID)); if (!isset($storeprops[PR_IPM_OUTBOX_ENTRYID])) { debugLog("Outbox not found to create message"); return false; } $outbox = mapi_msgstore_openentry($this->_defaultstore, $storeprops[PR_IPM_OUTBOX_ENTRYID]); if (!$outbox) { debugLog("Unable to open outbox"); return false; } $mapimessage = mapi_folder_createmessage($outbox); mapi_setprops($mapimessage, array(PR_SUBJECT => u2w($message->headers["subject"]), PR_SENTMAIL_ENTRYID => $storeprops[PR_IPM_SENTMAIL_ENTRYID], PR_MESSAGE_CLASS => "IPM.Note", PR_MESSAGE_DELIVERY_TIME => time())); if (isset($message->headers["x-priority"])) { switch ($message->headers["x-priority"]) { case 1: case 2: $priority = PRIO_URGENT; $importance = IMPORTANCE_HIGH; break; case 4: case 5: $priority = PRIO_NONURGENT; $importance = IMPORTANCE_LOW; break; case 3: default: $priority = PRIO_NORMAL; $importance = IMPORTANCE_NORMAL; break; } mapi_setprops($mapimessage, array(PR_IMPORTANCE => $importance, PR_PRIORITY => $priority)); } $addresses = array(); $toaddr = $ccaddr = $bccaddr = array(); if (isset($message->headers["to"])) { $toaddr = Mail_RFC822::parseAddressList($message->headers["to"]); } if (isset($message->headers["cc"])) { $ccaddr = Mail_RFC822::parseAddressList($message->headers["cc"]); } if (isset($message->headers["bcc"])) { $bccaddr = Mail_RFC822::parseAddressList($message->headers["bcc"]); } // Add recipients $recips = array(); if (isset($toaddr)) { foreach (array(MAPI_TO => $toaddr, MAPI_CC => $ccaddr, MAPI_BCC => $bccaddr) as $type => $addrlist) { foreach ($addrlist as $addr) { $mapirecip[PR_ADDRTYPE] = "SMTP"; $mapirecip[PR_EMAIL_ADDRESS] = $addr->mailbox . "@" . $addr->host; if (isset($addr->personal) && strlen($addr->personal) > 0) { $mapirecip[PR_DISPLAY_NAME] = u2w($addr->personal); } else { $mapirecip[PR_DISPLAY_NAME] = $mapirecip[PR_EMAIL_ADDRESS]; } $mapirecip[PR_RECIPIENT_TYPE] = $type; $mapirecip[PR_ENTRYID] = mapi_createoneoff($mapirecip[PR_DISPLAY_NAME], $mapirecip[PR_ADDRTYPE], $mapirecip[PR_EMAIL_ADDRESS]); array_push($recips, $mapirecip); } } } mapi_message_modifyrecipients($mapimessage, 0, $recips); // Loop through subparts. We currently only support single-level // multiparts. The PDA currently only does this because you are adding // an attachment and the type will be multipart/mixed. if ($message->ctype_primary == "multipart" && $message->ctype_secondary == "mixed") { foreach ($message->parts as $part) { if ($part->ctype_primary == "text") { $body = u2w($part->body); } else { // attachment $attach = mapi_message_createattach($mapimessage); // Filename is present in both Content-Type: name=.. and in Content-Disposition: filename= if (isset($part->ctype_parameters["name"])) { $filename = $part->ctype_parameters["name"]; } else { if (isset($part->d_parameters["name"])) { $filename = $part->d_parameters["filename"]; } else { $filename = "untitled"; } } // Set filename and attachment type mapi_setprops($attach, array(PR_ATTACH_LONG_FILENAME => u2w($filename), PR_ATTACH_METHOD => ATTACH_BY_VALUE)); // Set attachment data mapi_setprops($attach, array(PR_ATTACH_DATA_BIN => $part->body)); // Set MIME type mapi_setprops($attach, array(PR_ATTACH_MIME_TAG => $part->ctype_primary . "/" . $part->ctype_secondary)); mapi_savechanges($attach); } } } else { $body = u2w($message->body); } if ($forward) { $orig = $forward; } if ($reply) { $orig = $reply; } if (isset($orig) && $orig) { // Append the original text body for reply/forward $entryid = mapi_msgstore_entryidfromsourcekey($this->_defaultstore, hex2bin($parent), hex2bin($orig)); $fwmessage = mapi_msgstore_openentry($this->_defaultstore, $entryid); if ($fwmessage) { $messageprops = mapi_getprops($fwmessage, array(PR_BODY)); if (isset($messageprops[PR_BODY])) { if ($forward) { // During a forward, we have to add the forward header ourselves. This is because // normally the forwarded message is added as an attachment. However, we don't want this // because it would be rather complicated to copy over the entire original message due // to the lack of IMessage::CopyTo .. $fwmessageprops = mapi_getprops($fwmessage, array(PR_SENT_REPRESENTING_NAME, PR_DISPLAY_TO, PR_DISPLAY_CC, PR_SUBJECT, PR_CLIENT_SUBMIT_TIME)); $body .= "\r\n\r\n"; $body .= "-----Original Message-----\r\n"; if (isset($fwmessageprops[PR_SENT_REPRESENTING_NAME])) { $body .= "From: " . $fwmessageprops[PR_SENT_REPRESENTING_NAME] . "\r\n"; } if (isset($fwmessageprops[PR_DISPLAY_TO]) && strlen($fwmessageprops[PR_DISPLAY_TO]) > 0) { $body .= "To: " . $fwmessageprops[PR_DISPLAY_TO] . "\r\n"; } if (isset($fwmessageprops[PR_DISPLAY_CC]) && strlen($fwmessageprops[PR_DISPLAY_CC]) > 0) { $body .= "Cc: " . $fwmessageprops[PR_DISPLAY_CC] . "\r\n"; } if (isset($fwmessageprops[PR_CLIENT_SUBMIT_TIME])) { $body .= "Sent: " . strftime("%x %X", $fwmessageprops[PR_CLIENT_SUBMIT_TIME]) . "\r\n"; } if (isset($fwmessageprops[PR_SUBJECT])) { $body .= "Subject: " . $fwmessageprops[PR_SUBJECT] . "\r\n"; } $body .= "\r\n"; } $body .= $messageprops[PR_BODY]; } } else { debugLog("Unable to open item with id {$orig} for forward/reply"); } } if ($forward) { // Add attachments from the original message in a forward $entryid = mapi_msgstore_entryidfromsourcekey($this->_defaultstore, hex2bin($parent), hex2bin($orig)); $fwmessage = mapi_msgstore_openentry($this->_defaultstore, $entryid); $attachtable = mapi_message_getattachmenttable($fwmessage); $rows = mapi_table_queryallrows($attachtable, array(PR_ATTACH_NUM)); foreach ($rows as $row) { if (isset($row[PR_ATTACH_NUM])) { $attach = mapi_message_openattach($fwmessage, $row[PR_ATTACH_NUM]); $newattach = mapi_message_createattach($mapimessage); // Copy all attachments from old to new attachment $attachprops = mapi_getprops($attach); mapi_setprops($newattach, $attachprops); if (isset($attachprops[mapi_prop_tag(PT_ERROR, mapi_prop_id(PR_ATTACH_DATA_BIN))])) { // Data is in a stream $srcstream = mapi_openpropertytostream($attach, PR_ATTACH_DATA_BIN); $dststream = mapi_openpropertytostream($newattach, PR_ATTACH_DATA_BIN, MAPI_MODIFY | MAPI_CREATE); while (1) { $data = mapi_stream_read($srcstream, 4096); if (strlen($data) == 0) { break; } mapi_stream_write($dststream, $data); } mapi_stream_commit($dststream); } mapi_savechanges($newattach); } } } mapi_setprops($mapimessage, array(PR_BODY => $body)); mapi_savechanges($mapimessage); mapi_message_submitmessage($mapimessage); return true; }
/** * Copies attachments from one message to another. * * @param MAPIMessage $toMessage * @param MAPIMessage $fromMessage * * @return void */ private function copyAttachments(&$toMessage, $fromMessage) { $attachtable = mapi_message_getattachmenttable($fromMessage); $rows = mapi_table_queryallrows($attachtable, array(PR_ATTACH_NUM)); foreach ($rows as $row) { if (isset($row[PR_ATTACH_NUM])) { $attach = mapi_message_openattach($fromMessage, $row[PR_ATTACH_NUM]); $newattach = mapi_message_createattach($toMessage); mapi_copyto($attach, array(), array(), $newattach, 0); mapi_savechanges($newattach); } } }
/** * Assign a contact picture to a contact * @param entryId contact entry id * @param contactPicture must be a valid jpeg file. If contactPicture is NULL will remove contact picture from contact if exists */ public function setContactPicture(&$contact, $contactPicture) { $this->logger->trace("setContactPicture"); // Find if contact picture is already set $contactAttachment = -1; $hasattachProp = mapi_getprops($contact, array(PR_HASATTACH)); if ($hasattachProp) { $attachmentTable = mapi_message_getattachmenttable($contact); $attachments = mapi_table_queryallrows($attachmentTable, array(PR_ATTACH_NUM, PR_ATTACH_SIZE, PR_ATTACH_LONG_FILENAME, PR_ATTACH_FILENAME, PR_ATTACHMENT_HIDDEN, PR_DISPLAY_NAME, PR_ATTACH_METHOD, PR_ATTACH_CONTENT_ID, PR_ATTACH_MIME_TAG, PR_ATTACHMENT_CONTACTPHOTO, PR_EC_WA_ATTACHMENT_HIDDEN_OVERRIDE)); foreach ($attachments as $attachmentRow) { if (isset($attachmentRow[PR_ATTACHMENT_CONTACTPHOTO]) && $attachmentRow[PR_ATTACHMENT_CONTACTPHOTO]) { $contactAttachment = $attachmentRow[PR_ATTACH_NUM]; break; } } } // Remove existing attachment if necessary if ($contactAttachment != -1) { $this->logger->trace("removing existing contact picture"); $attach = mapi_message_deleteattach($contact, $contactAttachment); } if ($contactPicture !== NULL) { $this->logger->debug("Saving contact picture as attachment"); // Create attachment $attach = mapi_message_createattach($contact); // Update contact attachment properties $properties = array(PR_ATTACH_SIZE => strlen($contactPicture), PR_ATTACH_LONG_FILENAME => 'ContactPicture.jpg', PR_ATTACHMENT_HIDDEN => false, PR_DISPLAY_NAME => 'ContactPicture.jpg', PR_ATTACH_METHOD => ATTACH_BY_VALUE, PR_ATTACH_MIME_TAG => 'image/jpeg', PR_ATTACHMENT_CONTACTPHOTO => true, PR_ATTACH_DATA_BIN => $contactPicture, PR_ATTACHMENT_FLAGS => 1, PR_ATTACH_EXTENSION_A => '.jpg', PR_ATTACH_NUM => 1); mapi_setprops($attach, $properties); mapi_savechanges($attach); } // Test if (mapi_last_hresult() > 0) { $this->logger->warn("Error saving contact picture: " . get_mapi_error_name()); } else { $this->logger->trace("contact picture done"); } }