mail api search on all folders

This commit is contained in:
Roman 2021-04-09 20:59:36 +02:00
parent d41cc29845
commit a962ff5914

@ -43,6 +43,7 @@ namespace Api\Mail {
use Driver\SQL\Strategy\UpdateStrategy; use Driver\SQL\Strategy\UpdateStrategy;
use External\PHPMailer\Exception; use External\PHPMailer\Exception;
use External\PHPMailer\PHPMailer; use External\PHPMailer\PHPMailer;
use Objects\ConnectionData;
use Objects\User; use Objects\User;
class Test extends MailAPI { class Test extends MailAPI {
@ -137,6 +138,7 @@ namespace Api\Mail {
} }
} }
// TODO: IMAP mail settings :(
class Sync extends MailAPI { class Sync extends MailAPI {
public function __construct(User $user, bool $externalCall = false) { public function __construct(User $user, bool $externalCall = false) {
@ -200,10 +202,13 @@ namespace Api\Mail {
} }
private function parseDate($date) { private function parseDate($date) {
$formats = [null, "D M d Y H:i:s e+"]; $formats = [null, "D M d Y H:i:s e+", "D, j M Y H:i:s e+"];
foreach ($formats as $format) { foreach ($formats as $format) {
try { try {
return ($format === null ? new \DateTime($date) : \DateTime::createFromFormat($format, $date)); $dateObj = ($format === null ? new \DateTime($date) : \DateTime::createFromFormat($format, $date));
if ($dateObj) {
return $dateObj;
}
} catch (\Exception $exception) { } catch (\Exception $exception) {
} }
} }
@ -211,59 +216,42 @@ namespace Api\Mail {
return $this->createError("Could not parse date: $date"); return $this->createError("Could not parse date: $date");
} }
public function execute($values = array()): bool { private function getReference(ConnectionData $mailConfig): string {
if (!parent::execute($values)) {
return false;
}
$mailConfig = $this->getMailConfig();
if (!$this->success) {
return false;
}
if (!function_exists("imap_open")) {
return $this->createError("IMAP is not enabled. Enable it inside the php config. For more information visit: https://www.php.net/manual/en/imap.setup.php");
}
$messageIds = $this->fetchMessageIds();
if ($messageIds === false) {
return false;
} else if (count($messageIds) === 0) {
// nothing to sync here
return true;
}
// TODO: IMAP mail settings :(
$port = 993; $port = 993;
$folder = ""; // $folder = "INBOX";
$host = str_replace("smtp", "imap", $mailConfig->getHost()); $host = str_replace("smtp", "imap", $mailConfig->getHost());
$flags = ["/ssl"];
return '{' . $host . ':' . $port . implode("", $flags) . '}';
}
private function connect(ConnectionData $mailConfig) {
$username = $mailConfig->getLogin(); $username = $mailConfig->getLogin();
$password = $mailConfig->getPassword(); $password = $mailConfig->getPassword();
$lastSync = intval($mailConfig->getProperty("last_sync", "0")); $ref = $this->getReference($mailConfig);
$flags = ["/ssl"]; $mbox = @imap_open($ref, $username, $password, OP_READONLY);
$mailboxStr = '{' . $host . ':' . $port . implode("", $flags) . '}' . $folder;
$mbox = @imap_open($mailboxStr, $username, $password, OP_READONLY);
if (!$mbox) { if (!$mbox) {
return $this->createError("Can't connect to mail server via IMAP: " . imap_last_error()); return $this->createError("Can't connect to mail server via IMAP: " . imap_last_error());
} }
if ($lastSync > 0) { return $mbox;
$lastSyncDateTime = (new \DateTime())->setTimeStamp($lastSync); }
$dateStr = $lastSyncDateTime->format("d-M-Y");
$searchCriteria = "SINCE \"$dateStr\""; private function listFolders(ConnectionData $mailConfig, $mbox) {
} else {
$lastSyncDateTime = null; $boxes = @imap_list($mbox, $this->getReference($mailConfig), '*');
$searchCriteria = "ALL"; if (!$boxes) {
return $this->createError("Error listing imap folders: " . imap_last_error());
} }
$now = (new \DateTime())->getTimestamp(); return $boxes;
}
private function runSearch($mbox, string $searchCriteria, ?\DateTime $lastSyncDateTime, &$messages) {
$result = @imap_search($mbox, $searchCriteria); $result = @imap_search($mbox, $searchCriteria);
if ($result === false) { if ($result === false) {
return $this->createError("Could not run search: " . imap_last_error()); return $this->createError("Could not run search: " . imap_last_error());
} }
$messages = [];
foreach ($result as $msgNo) { foreach ($result as $msgNo) {
$header = imap_headerinfo($mbox, $msgNo); $header = imap_headerinfo($mbox, $msgNo);
$date = $this->parseDate($header->date); $date = $this->parseDate($header->date);
@ -271,7 +259,7 @@ namespace Api\Mail {
return false; return false;
} }
if ($lastSync === 0 || \datetimeDiff($lastSyncDateTime, $date) > 0) { if ($lastSyncDateTime === null || \datetimeDiff($lastSyncDateTime, $date) > 0) {
$references = property_exists($header, "references") ? $references = property_exists($header, "references") ?
explode(" ", $header->references) : []; explode(" ", $header->references) : [];
@ -279,12 +267,8 @@ namespace Api\Mail {
$requestId = $this->findContactRequest($messageIds, $references); $requestId = $this->findContactRequest($messageIds, $references);
if ($requestId) { if ($requestId) {
$messageId = $header->message_id; $messageId = $header->message_id;
$senderAddress = null; $senderAddress = $header->senderaddress;
if (count($header->from) > 0) {
$senderAddress = $header->from[0]->mailbox . "@" . $header->from[0]->host;
}
// $body = imap_body($mbox, $msgNo);
$structure = imap_fetchstructure($mbox, $msgNo); $structure = imap_fetchstructure($mbox, $msgNo);
$attachments = []; $attachments = [];
$hasAttachments = (property_exists($structure, "parts")); $hasAttachments = (property_exists($structure, "parts"));
@ -315,6 +299,60 @@ namespace Api\Mail {
} }
} }
return true;
}
public function execute($values = array()): bool {
if (!parent::execute($values)) {
return false;
}
if (!function_exists("imap_open")) {
return $this->createError("IMAP is not enabled. Enable it inside the php config. For more information visit: https://www.php.net/manual/en/imap.setup.php");
}
$messageIds = $this->fetchMessageIds();
if ($messageIds === false) {
return false;
} else if (count($messageIds) === 0) {
// nothing to sync here
return true;
}
$mailConfig = $this->getMailConfig();
if (!$this->success) {
return false;
}
$mbox = $this->connect($mailConfig);
if ($mbox === false) {
return false;
}
$boxes = $this->listFolders($mailConfig, $mbox);
if ($boxes === false) {
return false;
}
$now = (new \DateTime())->getTimestamp();
$lastSync = intval($mailConfig->getProperty("last_sync", "0"));
if ($lastSync > 0) {
$lastSyncDateTime = (new \DateTime())->setTimeStamp($lastSync);
$dateStr = $lastSyncDateTime->format("d-M-Y");
$searchCriteria = "SINCE \"$dateStr\"";
} else {
$lastSyncDateTime = null;
$searchCriteria = "ALL";
}
$messages = [];
foreach ($boxes as $box) {
imap_reopen($mbox, $box);
if (!$this->runSearch($mbox, $searchCriteria, $lastSyncDateTime, $messages)) {
return false;
}
}
@imap_close($mbox); @imap_close($mbox);
if (!empty($messages) && !$this->insertMessages($messages)) { if (!empty($messages) && !$this->insertMessages($messages)) {
return false; return false;