jamesiarmes / php-ews

PHP Exchange Web Services
http://jamesarmes.com/php-ews/
MIT License
567 stars 302 forks source link

How to forward email with attachments #579

Open quantrpeter opened 4 years ago

quantrpeter commented 4 years ago

hi , How to forward email with attachments?

faktor009 commented 4 years ago

I don't know about the way how to directly add attachment to the Forward or Reply message during the send process. My way how to handle this it create a message (draft) only with SAVE_ONLY disposition.

$request = new CreateItemType();
$request->MessageDisposition = MessageDispositionType::SAVE_ONLY;

parse ItemId and ChangeKey from the response, you will need that for later sending. then add attachment with CreateAttachmentType. I'm uploading files base_64 encoded. But you can use your own way (link it from bucket or server). You need ItemId of the message you want to attach to.

// create a temporary file of uploaded file to get the mimetype
$filename = tempnam('/tmp', 'attachment');
$fp = fopen($filename, 'w');
fwrite($fp, base64_decode($attachment['content']));
fclose($fp);
$finfo    = finfo_open(FILEINFO_MIME);
$mime_type = finfo_file($finfo, $filename);
finfo_close($finfo);

// we have a temp file and mimetype, here it's the important part

$request = new CreateAttachmentType();
$request->ParentItemId = new ItemIdType();

// here copy the itemId of the message
$request->ParentItemId->Id = '{new message ItemId}';
$request->Attachments = new NonEmptyArrayOfAttachmentsType();

$attachmentObj = new FileAttachmentType();
// I'm using base64 encoded file
$attachmentObj->Content = base64_decode($attachment['content']);
$attachmentObj->Name = $attachment['filename'];
$attachmentObj->ContentType = $mime_type;

$request->Attachments->FileAttachment[] = $attachmentObj;
$response = $client->CreateAttachment($request);

and now you have to just send the message with SendItemType

$request = new SendItemType();
$request->ItemIds = new NonEmptyArrayOfBaseItemIdsType();

// Add the message to the request.
 $item = new ItemIdType();
$item->Id = '{new message ItemId}';
$item->ChangeKey = '{new message ChangeKey}';
$request->ItemIds->ItemId[] = $item;

// Configure the folder to save the sent message. I think you can ignore this when you don't want to save the message, also SaveItemToFolder set to false.

$send_folder = new TargetFolderIdType();
$send_folder->DistinguishedFolderId = new DistinguishedFolderIdType();
$send_folder->DistinguishedFolderId->Id = DistinguishedFolderIdNameType::SENT;
$request->SaveItemToFolder = true;

$request->SavedItemFolderId = $send_folder;

$response = $client->SendItem($request);
oskar3490 commented 2 years ago

private function saveMessageToDraft() : void { $messageList = Message::query()->where('is_sync', 0)->get(); $request = new CreateItemType(); $request->Items = new NonEmptyArrayOfAllItemsType(); $request->MessageDisposition = MessageDispositionType::SAVE_ONLY;

   foreach ($messageList as $item) {
       $message = new MessageType();
       $message->Subject = 'Message by ' . $item->cabinetUser->email;
       $message->ToRecipients = new ArrayOfRecipientsType();

       $recipient = new EmailAddressType();
       $recipient->Name = 'Admin';
       $recipient->EmailAddress = config('php-ews.admin_mail');

       $message->From = new SingleRecipientType();
       $message->From->Mailbox = new EmailAddressType();
       $message->From->Mailbox->EmailAddress = 'user';

       $message->ToRecipients->Mailbox[] = $recipient;

       $message->Body = new BodyType();
       $message->Body->BodyType = BodyTypeType::TEXT;
       $message->Body->_=$item->text;
       $request->Items->Message[] = $message;
   }

   $response = $this->client->CreateItem($request);

   $response_messages = $response->ResponseMessages->CreateItemResponseMessage;

   foreach ($response_messages as $key => $response_message) {
       if (isset($messageList[$key])) {
           $message_obj = $messageList[$key];
           if (!empty($message_obj->attachment)) {
               $response_message->messageObj = $message_obj;
               $this->attachFiles($response_message);
           } else {
               $message_id = $response_message->Items->Message[0]->ItemId->Id;
               $change_key = $response_message->Items->Message[0]->ItemId->ChangeKey;
               $this->sendMessage($message_id, $change_key);
           }
       } else {
           continue;
       }
   }

}

private function attachFiles($message) : void { $request = new CreateAttachmentType(); $request->ParentItemId = new ItemIdType(); $request->Attachments = new NonEmptyArrayOfAttachmentsType();

   $message_id = $message->Items->Message[0]->ItemId->Id;
   $request->ParentItemId->Id = $message_id;

   if (!empty($message->messageObj->attachment)) {
       foreach ($message->messageObj->attachment as $data) {
           $attachment_path = str_replace(env('APP_URL') . '/storage', '', $data['path']);
           $file = Storage::disk('public')->get($attachment_path);
           $attachment = new FileAttachmentType();
           $attachment->Name = $data['name'];
           $attachment->ContentType = $data['mime'];
           $attachment->Content = $file;
           $request->Attachments->FileAttachment[] = $attachment;
       }
   }

   $response = $this->client->CreateAttachment($request);
   $response_attachment_message = $response->ResponseMessages->CreateAttachmentResponseMessage; // array
   $change_key = $response_attachment_message[0]->Attachments->FileAttachment[0]->AttachmentId->RootItemChangeKey; // TODO: check how does it work with multiple attachments
   $this->sendMessage($message_id, $change_key);

}

private function sendMessage($message_id, $change_key) : void { $request = new SendItemType(); $request->SaveItemToFolder = true; $request->ItemIds = new NonEmptyArrayOfBaseItemIdsType();

   $item = new ItemIdType();
   $item->Id = $message_id;
   $item->ChangeKey = $change_key;
   $request->ItemIds->ItemId[] = $item;

   $send_folder = new TargetFolderIdType();
   $send_folder->DistinguishedFolderId = new DistinguishedFolderIdType();
   $send_folder->DistinguishedFolderId->Id = DistinguishedFolderIdNameType::SENT;
   $request->SavedItemFolderId = $send_folder;

   $this->client->SendItem($request);

}