connection->getMailbox(); try { // Get all emails (messages) // PHP.net imap_search criteria: http://php.net/manual/en/function.imap-search.php $mailsIds = $mailbox->searchMailbox('ALL'); } catch (PhpImap\Exceptions\ConnectionException $ex) { $this->logger->error("IMAP connection failed: " . implode(",", $ex->getErrors('all'))); die(); } if (!$mailsIds) { $this->logger->info('Mailbox is empty'); return; } // If '__DIR__' was defined in the first line, it will automatically // save all attachments to the specified directory foreach ($mailsIds as $mailId) { $mail = $mailbox->getMail($mailId); $this->logger->debug(print_r([ 'date' => $mail->date, 'message_id' => $mail->messageId, 'from' => $mail->fromAddress, 'subject' => $mail->subject, 'hasAttachments' => $mail->hasAttachments(), ], true)); if ($this->canProcessMail($mail)) { if ($this->processMail($mail)) { // for dev purposes //break; } $mailbox->deleteMail($mailId); $this->logger->debug("Deleted email with id=" . $mailId); } else { $this->logger->debug("Skipped mail with id=" . $mailId); } } $mailbox->disconnect(); } private function canProcessMail(IncomingMail $mail): bool { if (!$mail->hasAttachments()) { return false; } if (mb_stripos($mail->subject, 'Broker report') === false) { return false; } if (mb_stripos($mail->fromAddress, '@bcs.ru') === false) { return false; } return true; } private function processMail(IncomingMail $mail): bool { $mailProcessed = false; foreach ($mail->getAttachments() as $attachment) { if ($attachment->mimeType != 'application/zip') { continue; } $mailProcessed |= $this->processZipArchiveAttachment($attachment); } return $mailProcessed; } private function processZipArchiveAttachment(IncomingMailAttachment $attachment): bool { $zip = new \ZipArchive(); if ($zip->open($attachment->filePath) !== true) { $this->logger->error('ZIP open error: ' . $zip); return false; } $xmlFound = false; for ($i = 0; $i < $zip->numFiles; $i++) { $stat = $zip->statIndex($i); if (pathinfo($stat['name'])['extension'] !== 'xml') { continue; } $tmpdir = $this->getTmpDir(); $zip->extractTo($tmpdir, [$stat['name']]); $this->logger->debug("Extracted '$stat[name]' into '$tmpdir'"); $xmlString = file_get_contents($tmpdir . '/' . $stat['name']); $xml = simplexml_load_string($xmlString); $parsedPortfolio = $this->xmlParser->processXml($xml); $message = (new PresentationPortfolio)->toPrint($parsedPortfolio); if ($this->portfolioManager->updatePortfolio($parsedPortfolio, $xmlString)) { $this->telegramNotifier->notify('
' . $message . ''); } $fs = new Filesystem(); $fs->remove($tmpdir); $xmlFound = true; } return $xmlFound; } private function getTmpDir(): string { $tmpdir = Path::normalize(sys_get_temp_dir() . '/FINFOLLOW-' . random_int(0, 100)); $filesystem = new Filesystem(); $filesystem->mkdir($tmpdir); return $tmpdir; } }