Skip to content

Commit bfe0300

Browse files
committed
fix(other): display messages of type event calendar with ews
1 parent e50a877 commit bfe0300

File tree

1 file changed

+125
-46
lines changed

1 file changed

+125
-46
lines changed

modules/imap/hm-ews.php

Lines changed: 125 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public function get_folders($folder = null, $only_subscribed = false, $unsubscri
9797
'realname' => $name,
9898
'namespace' => '',
9999
'marked' => false, // doesn't seem to be used anywhere but imap returns it
100-
'noselect' => false, // all EWS folders are selectable
100+
'noselect' => false, // all EWS folders are selectable
101101
'can_have_kids' => true,
102102
'has_kids' => $folder->getChildFolderCount() > 0,
103103
'children' => $folder->getChildFolderCount(),
@@ -329,6 +329,7 @@ public function search($folder, $sort, $reverse, $flag_filter, $offset, $limit,
329329
} else {
330330
$folder = new Type\FolderIdType($folder);
331331
}
332+
332333
$request = array(
333334
'Traversal' => 'Shallow',
334335
'ItemShape' => array(
@@ -481,13 +482,39 @@ public function search($folder, $sort, $reverse, $flag_filter, $offset, $limit,
481482
}
482483
$request = Type::buildFromArray($request);
483484
$result = $this->ews->FindItem($request);
484-
$messages = $result->getItems()->getMessage() ?? [];
485-
if ($messages instanceof Type\MessageType) {
486-
$messages = [$messages];
485+
$items = [];
486+
$responseItems = $result->getItems();
487+
488+
if (method_exists($responseItems, 'getMessage') && $responseItems->getMessage()) {
489+
$messages = $responseItems->getMessage();
490+
if (!is_array($messages)) {
491+
$messages = [$messages];
492+
}
493+
$items = array_merge($items, $messages);
494+
}
495+
496+
if (method_exists($responseItems, 'getCalendarItem') && $responseItems->getCalendarItem()) {
497+
$calendarItems = $responseItems->getCalendarItem();
498+
if (!is_array($calendarItems)) {
499+
$calendarItems = [$calendarItems];
500+
}
501+
$items = array_merge($items, $calendarItems);
502+
}
503+
504+
if (method_exists($responseItems, 'getMeetingRequest') && $responseItems->getMeetingRequest()) {
505+
$meetingRequests = $responseItems->getMeetingRequest();
506+
if (!is_array($meetingRequests)) {
507+
$meetingRequests = [$meetingRequests];
508+
}
509+
$items = array_merge($items, $meetingRequests);
510+
}
511+
512+
$itemIds = [];
513+
foreach ($items as $item) {
514+
if (is_object($item) && method_exists($item, 'getItemId')) {
515+
$itemIds[] = bin2hex($item->getItemId()->getId());
516+
}
487517
}
488-
$itemIds = array_map(function($msg) {
489-
return bin2hex($msg->getItemId()->getId());
490-
}, $messages);
491518
return [$result->getTotalItemsInView(), $itemIds];
492519
}
493520

@@ -497,6 +524,7 @@ public function get_messages($folder, $sort, $reverse, $flag_filter, $offset, $l
497524
}
498525

499526
public function get_message_list($itemIds, $include_preview = false) {
527+
500528
if (empty($itemIds)) {
501529
return [];
502530
}
@@ -522,24 +550,25 @@ public function get_message_list($itemIds, $include_preview = false) {
522550
}, $itemIds),
523551
],
524552
);
553+
525554
$request = Type::buildFromArray($request);
526555
$result = $this->ews->GetItem($request);
527-
if ($result instanceof Type\MessageType) {
528-
$result = [$result];
529-
}
530556
$messages = [];
557+
531558
foreach ($result as $message) {
532559
$flags = $this->extract_flags($message);
533560
$uid = bin2hex($message->getItemId()->getId());
534561
$msg = [
535562
'uid' => $uid,
536563
'flags' => implode(' ', $flags),
537-
'internal_date' => $message->getDateTimeCreated(),
538-
'size' => $message->getSize(),
539-
'date' => $message->getDateTimeReceived(),
540-
'from' => $this->extract_mailbox($message->getFrom()),
541-
'to' => $this->extract_mailbox($message->getToRecipients()),
542-
'subject' => $message->getSubject(),
564+
'internal_date' => method_exists($message, 'getDateTimeCreated') && $message->getDateTimeCreated() ?
565+
$message->getDateTimeCreated()->format('Y-m-d H:i:s.u') : date('Y-m-d H:i:s.u'),
566+
'size' => method_exists($message, 'getSize') ? $message->getSize() : 0,
567+
'date' => method_exists($message, 'getDateTimeReceived') && $message->getDateTimeReceived() ?
568+
$message->getDateTimeReceived()->format('Y-m-d H:i:s.u') : date('Y-m-d H:i:s.u'),
569+
'from' => method_exists($message, 'getFrom') ? $this->extract_mailbox($message->getFrom()) : '',
570+
'to' => method_exists($message, 'getToRecipients') ? $this->extract_mailbox($message->getToRecipients()) : '',
571+
'subject' => method_exists($message, 'getSubject') ? $message->getSubject() : '',
543572
'content-type' => null,
544573
'timestamp' => time(),
545574
'charset' => null,
@@ -548,18 +577,21 @@ public function get_message_list($itemIds, $include_preview = false) {
548577
'google_thread_id' => null,
549578
'google_labels' => null,
550579
'list_archive' => null,
551-
'references' => $message->getRreferences(),
552-
'message_id' => $message->getInternetMessageId(),
580+
'references' => method_exists($message, 'getReferences') ? $message->getReferences() : null,
581+
'message_id' => method_exists($message, 'getInternetMessageId') ? $message->getInternetMessageId() : null,
553582
'x_auto_bcc' => null,
554583
'x_snoozed' => null,
555584
'x_schedule' => null,
556585
'x_profile_id' => null,
557586
'x_delivery' => null,
558587
];
559-
foreach ($message->getInternetMessageHeaders() as $header) {
560-
foreach (['x-gm-msgid' => 'google_msg_id', 'x-gm-thrid' => 'google_thread_id', 'x-gm-labels' => 'google_labels', 'x-auto-bcc' => 'x_auto_bcc', 'message-id' => 'message_id', 'references' => 'references', 'x-snoozed' => 'x_snoozed', 'x-schedule' => 'x_schedule', 'x-profile-id' => 'x_profile_id', 'x-delivery' => 'x_delivery', 'list-archive' => 'list_archive', 'content-type' => 'content-type', 'x-priority' => 'x-priority'] as $hname => $key) {
561-
if (strtolower($header->getHeaderName()) == $hname) {
562-
$msg[$key] = (string) $header;
588+
589+
if (method_exists($message, 'getInternetMessageHeaders') && $message->getInternetMessageHeaders()) {
590+
foreach ($message->getInternetMessageHeaders() as $header) {
591+
foreach (['x-gm-msgid' => 'google_msg_id', 'x-gm-thrid' => 'google_thread_id', 'x-gm-labels' => 'google_labels', 'x-auto-bcc' => 'x_auto_bcc', 'message-id' => 'message_id', 'references' => 'references', 'x-snoozed' => 'x_snoozed', 'x-schedule' => 'x_schedule', 'x-profile-id' => 'x_profile_id', 'x-delivery' => 'x_delivery', 'list-archive' => 'list_archive', 'content-type' => 'content-type', 'x-priority' => 'x-priority'] as $hname => $key) {
592+
if (method_exists($header, 'getHeaderName') && strtolower($header->getHeaderName()) == $hname) {
593+
$msg[$key] = (string) $header;
594+
}
563595
}
564596
}
565597
}
@@ -569,6 +601,7 @@ public function get_message_list($itemIds, $include_preview = false) {
569601
$cset = trim(mb_strtolower(str_replace(array('"', "'"), '', $matches[1])));
570602
}
571603
}
604+
572605
$msg['charset'] = $cset;
573606
$msg['preview_msg'] = $include_preview ? strip_tags($message->getBody()) : "";
574607
$messages[$uid] = $msg;
@@ -601,7 +634,7 @@ public function message_action($action, $itemIds, $folder=false, $keyword=false)
601634
break;
602635
case 'COPY':
603636
$newIds = $this->copy_items($itemIds, $folder);
604-
if ($newIds) {
637+
if ($newIds) {
605638
foreach ($newIds as $key => $newId) {
606639
$responses[] = ['oldUid' => $itemIds[$key], 'newUid' => $newId];
607640
}
@@ -924,9 +957,25 @@ protected function extract_mailbox($data) {
924957
}
925958
return $result;
926959
} elseif (is_object($data) && $data->Mailbox) {
927-
return $data->Mailbox->getName() . ' <' . $data->Mailbox->getEmailAddress() . '>';
928-
} elseif (is_object($data) && $data->getMailbox()) {
929-
return $data->getMailbox()->getName() . ' <' . $data->getMailbox()->getEmailAddress() . '>';
960+
if(is_array($data->Mailbox)) {
961+
$result = [];
962+
foreach ($data->Mailbox as $mailbox) {
963+
$result[] = $this->extract_mailbox($mailbox);
964+
}
965+
return $result;
966+
}else {
967+
return $data->Mailbox->getName() . ' <' . $data->Mailbox->getEmailAddress() . '>';
968+
}
969+
} elseif (is_object($data) && method_exists($data, 'getMailbox')) {
970+
$mailbox = $data->getMailbox()->getMailbox();
971+
972+
$name = $mailbox->getName();
973+
$email = $mailbox->getEmailAddress();
974+
return $name ? $name . ' <' . $email . '>' : $email;
975+
} elseif (is_object($data) && method_exists($data, 'getName') && method_exists($data, 'getEmailAddress')) {
976+
$name = $data->getName();
977+
$email = $data->getEmailAddress();
978+
return $name ? $name . ' <' . $email . '>' : $email;
930979
} else {
931980
return (string) $data;
932981
}
@@ -972,28 +1021,40 @@ protected function is_distinguished_folder(&$folder) {
9721021

9731022
protected function archive_items($itemIds) {
9741023
$result = true;
975-
$folders = $this->get_parent_folders_of_items($itemIds);
976-
foreach ($folders as $folder => $itemIds) {
977-
if ($this->is_distinguished_folder($folder)) {
978-
$folder = new Type\DistinguishedFolderIdType($folder);
979-
} else {
980-
$folder = new Type\FolderIdType($folder);
981-
}
982-
$request = [
983-
'ArchiveSourceFolderId' => $folder->toArray(true),
984-
'ItemIds' => [
985-
'ItemId' => $itemIds = array_map(function($itemId) {
986-
return (new Type\ItemIdType($itemId))->toArray();
987-
}, $itemIds),
988-
]
989-
];
990-
$request = Type::buildFromArray($request);
1024+
try {
1025+
$archiveFolder = null;
9911026
try {
992-
$result = $result && $this->ews->ArchiveItem($request);
1027+
$archiveFolder = $this->api->getFolderByDistinguishedId(Enumeration\DistinguishedFolderIdNameType::ARCHIVE_INBOX);
9931028
} catch (\Exception $e) {
994-
Hm_Msgs::add($e->getMessage(), 'danger');
995-
$result = false;
1029+
try {
1030+
$rootFolder = new Type\DistinguishedFolderIdType(Enumeration\DistinguishedFolderIdNameType::MESSAGE_ROOT);
1031+
$createRequest = [
1032+
'Folders' => ['Folder' => [
1033+
'DisplayName' => 'Archive'
1034+
]],
1035+
'ParentFolderId' => $rootFolder->toArray(true),
1036+
];
1037+
$createResult = $this->ews->CreateFolder($createRequest);
1038+
$archiveFolder = $this->api->getFolderByDisplayName('Archive', Enumeration\DistinguishedFolderIdNameType::MESSAGE_ROOT);
1039+
} catch (\Exception $createE) {
1040+
Hm_Msgs::add('Unable to create or find archive folder: ' . $createE->getMessage(), 'danger');
1041+
return false;
1042+
}
9961043
}
1044+
1045+
if (!$archiveFolder) {
1046+
Hm_Msgs::add('Archive folder not available', 'danger');
1047+
return false;
1048+
}
1049+
1050+
// use move_items to archive the items
1051+
$archiveFolderId = $archiveFolder->getFolderId()->getId();
1052+
$newIds = $this->move_items($itemIds, $archiveFolderId);
1053+
$result = !empty($newIds);
1054+
1055+
} catch (\Exception $e) {
1056+
Hm_Msgs::add('Archive operation failed: ' . $e->getMessage(), 'danger');
1057+
$result = false;
9971058
}
9981059
return $result;
9991060
}
@@ -1125,7 +1186,7 @@ protected function get_parent_folders_of_items($itemIds) {
11251186
$itemIds = array_map(function($itemId) {
11261187
return (new Type\ItemIdType(hex2bin($itemId)))->toArray();
11271188
}, $itemIds);
1128-
$folders = null;
1189+
$folders = [];
11291190
$request = [
11301191
'ItemShape' => [
11311192
'BaseShape' => 'IdOnly',
@@ -1152,3 +1213,21 @@ protected function get_parent_folders_of_items($itemIds) {
11521213
return $folders;
11531214
}
11541215
}
1216+
1217+
if(!hm_exists('flatten_headers_to_string')) {
1218+
function flatten_headers_to_string($headers, $key) {
1219+
if (!isset($headers[$key]) || !is_array($headers[$key])) {
1220+
return isset($headers[$key]) ? $headers[$key] : '';
1221+
}
1222+
1223+
$flattened_header = [];
1224+
foreach ($headers[$key] as $to_item) {
1225+
if (is_array($to_item)) {
1226+
$flattened_header = array_merge($flattened_header, $to_item);
1227+
} else {
1228+
$flattened_header[] = $to_item;
1229+
}
1230+
}
1231+
return implode(', ', $flattened_header);
1232+
}
1233+
}

0 commit comments

Comments
 (0)