diff options
author | Anna Larch <anna@nextcloud.com> | 2021-02-17 15:44:52 +0300 |
---|---|---|
committer | Anna Larch <anna@nextcloud.com> | 2021-02-18 18:11:29 +0300 |
commit | 18f5c5adb2aacb1f053e7cc8455fe289dd11d7a8 (patch) | |
tree | 3abe2a3e1296f9a77d13d2abd7938cb141c0fb5f /lib/IMAP | |
parent | 2d66dffabe4f998dc5a4f20cb9723b0dafbde095 (diff) |
Add attachment dl method, add parts query wrapper
Signed-off-by: Anna Larch <anna@nextcloud.com>
Diffstat (limited to 'lib/IMAP')
-rw-r--r-- | lib/IMAP/MessageMapper.php | 107 |
1 files changed, 89 insertions, 18 deletions
diff --git a/lib/IMAP/MessageMapper.php b/lib/IMAP/MessageMapper.php index 96fdb2255..43b0ec096 100644 --- a/lib/IMAP/MessageMapper.php +++ b/lib/IMAP/MessageMapper.php @@ -471,28 +471,65 @@ class MessageMapper { } $structure = $structureResult->getStructure(); - $partsQuery = new Horde_Imap_Client_Fetch_Query(); - $partsQuery->fullText(); - foreach ($structure->partIterator() as $part) { + $partsQuery = $this->buildAttachmentsPartsQuery($structure, $attachmentIds); + + $parts = $client->fetch($mailbox, $partsQuery, [ + 'ids' => new Horde_Imap_Client_Ids([$uid]), + ]); + if (($messageData = $parts->first()) === null) { + throw new DoesNotExistException('Message does not exist'); + } + + $attachments = []; + foreach ($structure->partIterator() as $key => $part) { /** @var Horde_Mime_Part $part */ - if ($part->getMimeId() === '0') { - // Ignore message header - continue; - } - if (!empty($attachmentIds) && !in_array($part->getMIMEId(), $attachmentIds, true)) { - // We are looking for specific parts only and this is not one of them + + if (!$part->isAttachment()) { continue; } - $partsQuery->bodyPart($part->getMimeId(), [ - 'peek' => true, - ]); - $partsQuery->mimeHeader($part->getMimeId(), [ - 'peek' => true + $stream = $messageData->getBodyPart($key, true); + $mimeHeaders = $messageData->getMimeHeader($key, Horde_Imap_Client_Data_Fetch::HEADER_PARSE); + if ($enc = $mimeHeaders->getValue('content-transfer-encoding')) { + $part->setTransferEncoding($enc); + } + $part->setContents($stream, [ + 'usestream' => true, ]); - $partsQuery->bodyPartSize($part->getMimeId()); + $decoded = $part->getContents(); + + $attachments[] = $decoded; + } + return $attachments; + } + + /** + * Get Attachments with size, content and name properties + * + * @param Horde_Imap_Client_Socket $client + * @param string $mailbox + * @param integer $uid + * @param array|null $attachmentIds + * @return array[] + */ + public function getAttachments(Horde_Imap_Client_Socket $client, + string $mailbox, + int $uid, + ?array $attachmentIds = []): array { + $messageQuery = new Horde_Imap_Client_Fetch_Query(); + $messageQuery->structure(); + + $result = $client->fetch($mailbox, $messageQuery, [ + 'ids' => new Horde_Imap_Client_Ids([$uid]), + ]); + + if (($structureResult = $result->first()) === null) { + throw new DoesNotExistException('Message does not exist'); } + $structure = $structureResult->getStructure(); + $partsQuery = $this->buildAttachmentsPartsQuery($structure, $attachmentIds); + $parts = $client->fetch($mailbox, $partsQuery, [ 'ids' => new Horde_Imap_Client_Ids([$uid]), ]); @@ -516,14 +553,48 @@ class MessageMapper { $part->setContents($stream, [ 'usestream' => true, ]); - $decoded = $part->getContents(); - - $attachments[] = $decoded; + $attachments[] = [ + 'content' => $part->getContents(), + 'name' => $part->getName(), + 'size' => $part->getSize() + ]; } return $attachments; } /** + * Build the parts query for attachments + * + * @param $structure + * @param array $attachmentIds + * @return Horde_Imap_Client_Fetch_Query + */ + private function buildAttachmentsPartsQuery($structure, array $attachmentIds) : Horde_Imap_Client_Fetch_Query { + $partsQuery = new Horde_Imap_Client_Fetch_Query(); + $partsQuery->fullText(); + foreach ($structure->partIterator() as $part) { + /** @var Horde_Mime_Part $part */ + if ($part->getMimeId() === '0') { + // Ignore message header + continue; + } + if (!empty($attachmentIds) && !in_array($part->getMIMEId(), $attachmentIds, true)) { + // We are looking for specific parts only and this is not one of them + continue; + } + + $partsQuery->bodyPart($part->getMimeId(), [ + 'peek' => true, + ]); + $partsQuery->mimeHeader($part->getMimeId(), [ + 'peek' => true + ]); + $partsQuery->bodyPartSize($part->getMimeId()); + } + return $partsQuery; + } + + /** * @param Horde_Imap_Client_Socket $client * @param int[] $uids * |