1<?php 2 3declare(strict_types=1); 4 5/** 6 * @copyright 2020 Christoph Wurst <christoph@winzerhof-wurst.at> 7 * 8 * @author 2020 Christoph Wurst <christoph@winzerhof-wurst.at> 9 * 10 * @license GNU AGPL version 3 or any later version 11 * 12 * This program is free software: you can redistribute it and/or modify 13 * it under the terms of the GNU Affero General Public License as 14 * published by the Free Software Foundation, either version 3 of the 15 * License, or (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU Affero General Public License for more details. 21 * 22 * You should have received a copy of the GNU Affero General Public License 23 * along with this program. If not, see <http://www.gnu.org/licenses/>. 24 */ 25 26namespace OCA\Mail\IMAP; 27 28use Horde_Imap_Client_Exception; 29use OCA\Mail\Account; 30use OCA\Mail\Db\Mailbox; 31use OCA\Mail\Db\Message; 32use OCA\Mail\Db\MessageMapper as DbMapper; 33use OCA\Mail\IMAP\MessageMapper as ImapMapper; 34use Psr\Log\LoggerInterface; 35use function array_key_exists; 36use function array_map; 37use function array_merge; 38use function array_reduce; 39 40class PreviewEnhancer { 41 42 /** @var IMAPClientFactory */ 43 private $clientFactory; 44 45 /** @var ImapMapper */ 46 private $imapMapper; 47 48 /** @var DbMapper */ 49 private $mapper; 50 51 /** @var LoggerInterface */ 52 private $logger; 53 54 public function __construct(IMAPClientFactory $clientFactory, 55 ImapMapper $imapMapper, 56 DbMapper $dbMapper, 57 LoggerInterface $logger) { 58 $this->clientFactory = $clientFactory; 59 $this->imapMapper = $imapMapper; 60 $this->mapper = $dbMapper; 61 $this->logger = $logger; 62 } 63 64 /** 65 * @param Message[] $messages 66 * 67 * @return Message[] 68 */ 69 public function process(Account $account, Mailbox $mailbox, array $messages): array { 70 $needAnalyze = array_reduce($messages, function (array $carry, Message $message) { 71 if ($message->getStructureAnalyzed()) { 72 // Nothing to do 73 return $carry; 74 } 75 76 return array_merge($carry, [$message->getUid()]); 77 }, []); 78 79 if (empty($needAnalyze)) { 80 // Nothing to enhance 81 return $messages; 82 } 83 84 try { 85 $data = $this->imapMapper->getBodyStructureData( 86 $this->clientFactory->getClient($account), 87 $mailbox->getName(), 88 $needAnalyze 89 ); 90 } catch (Horde_Imap_Client_Exception $e) { 91 // Ignore for now, but log 92 $this->logger->warning('Could not fetch structure detail data to enhance message previews: ' . $e->getMessage(), [ 93 'exception' => $e, 94 ]); 95 96 return $messages; 97 } 98 99 return $this->mapper->updatePreviewDataBulk(...array_map(function (Message $message) use ($data) { 100 if (!array_key_exists($message->getUid(), $data)) { 101 // Nothing to do 102 return $message; 103 } 104 105 /** @var MessageStructureData $structureData */ 106 $structureData = $data[$message->getUid()]; 107 $message->setFlagAttachments($structureData->hasAttachments()); 108 $message->setPreviewText($structureData->getPreviewText()); 109 $message->setStructureAnalyzed(true); 110 111 return $message; 112 }, $messages)); 113 } 114} 115