db = $db; $this->erpApi = $erpApi; $this->ticketModule = $ticketModule; $this->formatter = $formatter; $this->mailClient = $mailClient; $this->mailAccount = $mailAccount; $this->projectId = $projectId; $this->config = $config; } /** * @param array $inboxMessageIds * * @return int amount of imported tickets */ public function importMessages(array $inboxMessageIds): int { $insertedMailsCount = 0; foreach ($inboxMessageIds as $messageNumber) { try { $message = $this->mailClient->fetchMessage((int)$messageNumber); } catch (Throwable $e) { $this->logger->error('Failed to fetch email from server', ['exception' => $e]); continue; } try { $this->importMessage($message); $insertedMailsCount++; if ($this->mailAccount->isDeleteAfterImportEnabled()) { $this->mailClient->deleteMessage((int)$messageNumber); } else { $this->mailClient->setFlags((int)$messageNumber, ['\\Seen']); } } catch (Throwable $e) { $this->logger->error('Error during email import', ['exception' => $e]); continue; } } $this->logger->debug( '{imported_count} of {total} emails imported successfully', ['imported_count' => $insertedMailsCount, 'total' => count($inboxMessageIds)] ); return $insertedMailsCount; } /** * @param MailMessageInterface $message * * @return void */ public function importMessage(MailMessageInterface $message): void { $DEBUG = 0; // extract email data $subject = $this->formatter->encodeToUtf8($message->getSubject()); $from = $this->formatter->encodeToUtf8($message->getSender()->getEmail()); $ccs = $message->getCcRecipients(); $cc_recv = []; foreach ($ccs as $cc) { $cc_recv[] = [ 'email' => $this->formatter->encodeToUtf8($cc->getEmail()), 'name' => $this->formatter->encodeToUtf8($cc->getName()), ]; } $plainTextBody = $message->getPlainTextBody(); if ($plainTextBody === null) { $plainTextBody = ''; } $htmlBody = $message->getHtmlBody(); if ($htmlBody === null) { $htmlBody = ''; } $action = $this->formatter->encodeToUtf8($plainTextBody); $action_html = $this->formatter->encodeToUtf8($htmlBody); if (strlen($action_html) < strlen($action)) { $action_html = nl2br($action); } $name_sender = $this->formatter->encodeToUtf8($message->getSender()->getName()); $mail_replyto = $this->formatter->encodeToUtf8($message->getReplyToAddress()); $verfasser_replyto = $this->formatter->encodeToUtf8($message->getSender()->getName()); //check if email exists in database $date = $message->getDate(); $timestamp = $date->getTimestamp(); $frommd5 = md5($from . $subject . $timestamp); $empfang = $date->format('Y-m-d H:i:s'); $sql = "SELECT COUNT(id) FROM `emailbackup_mails` WHERE `checksum`='$frommd5' AND `empfang`='$empfang' AND `webmail`='" . $this->mailAccount->getId() . "'"; if ($this->db->Select($sql) == 0) { $attachments = $message->getAttachments(); $anhang = count($attachments) > 0 ? 1 : 0; $mailacc = $this->mailAccount->getEmailAddress(); if (empty($mailacc) && count($message->getRecipients()) > 0) { $mailacc = array_values($message->getRecipients())[0]->getEmail(); } $mailaccid = $this->mailAccount->getId(); if (!$this->erpApi->isMailAdr($from)) { $from = $this->erpApi->filterMailAdr($from); } //fuege gegenenfalls ein $sql = "INSERT INTO `emailbackup_mails` ( `webmail`, `subject`, `sender`, `action`, `action_html`, `empfang`, `anhang`, `checksum` ) VALUES ( '$mailaccid', '" . $this->db->real_escape_string($subject) . "', '" . $this->db->real_escape_string($from) . "', '" . $this->db->real_escape_string($action) . "', '" . $this->db->real_escape_string($action_html) . "', '$empfang','$anhang','$frommd5' )"; $id = null; if ($DEBUG) { echo $sql; } else { $this->db->InsertWithoutLog($sql); $id = $this->db->GetInsertID(); } if ($DEBUG) { echo "ticket suchen oder anlegen\n"; } $_schluessel = null; $schluessel = null; $ticketexits = null; if (preg_match("/Ticket #[0-9]{12}/i", $subject, $matches)) { $schluessel = str_replace('Ticket #', '', $matches[0]); $ticketexits = $this->db->Select( "SELECT schluessel FROM ticket WHERE schluessel LIKE '" . $schluessel . "' AND schluessel!='' LIMIT 1" ); } $ticketnachricht = null; if ($ticketexits) { if ($DEBUG) { echo "ticket nummer in betreff gefunden\n"; } $schluessel = str_replace('Ticket #', '', $matches[0]); if ($action_html != '') { $sql = "INSERT INTO `ticket_nachricht` ( `id`, `ticket`, `zeit`, `text`, `betreff`, `medium`, `verfasser`, `mail`, `status`, `verfasser_replyto`, `mail_replyto` ) VALUES ( NULL, '$schluessel', FROM_UNIXTIME($timestamp), '" . $this->db->real_escape_string($action_html) . "', '" . $this->db->real_escape_string($subject) . "', 'email', '" . $this->db->real_escape_string($name_sender) . "', '" . $this->db->real_escape_string($from) . "', 'neu', '" . $this->db->real_escape_string($verfasser_replyto) . "', '" . $this->db->real_escape_string($mail_replyto) . "' );"; } else { $sql = "INSERT INTO `ticket_nachricht` ( `id`, `ticket`, `zeit`, `text`, `betreff`, `medium`, `verfasser`, `mail`, `status`, `verfasser_replyto`, `mail_replyto` ) VALUES ( NULL, '$schluessel', FROM_UNIXTIME($timestamp), '" . $this->db->real_escape_string($action) . "', '" . $this->db->real_escape_string($subject) . "', 'email', '" . $this->db->real_escape_string($name_sender) . "', '" . $this->db->real_escape_string($from) . "', 'neu', '" . $this->db->real_escape_string($verfasser_replyto) . "', '" . $this->db->real_escape_string($mail_replyto) . "' );"; } if (!$DEBUG) { $this->db->InsertWithoutLog( "UPDATE ticket_nachricht SET status = 'abgeschlossen' WHERE ticket LIKE '$schluessel'" ); $this->db->InsertWithoutLog($sql); $ticketnachricht = $this->db->GetInsertID(); $this->db->InsertWithoutLog( "UPDATE ticket SET status='neu', zugewiesen = 0, inbearbeitung=0 WHERE schluessel LIKE '$schluessel'" ); $this->db->Update( "UPDATE `ticket` AS `t` INNER JOIN ( SELECT COUNT(`id`) AS `co`, `ticket` FROM `ticket_nachricht` GROUP BY `ticket` ) AS `tn` ON t.schluessel = tn.ticket SET t.nachrichten_anz = tn.co WHERE t.schluessel = '$schluessel'" ); } } else { if (!$DEBUG) { if ($action_html != '') { $ticketnachricht = $this->ticketModule->CreateTicket( $this->projectId, $mailacc, $name_sender, $from, $subject, $action_html, $timestamp, "email", null, $verfasser_replyto, $mail_replyto ); // ACHTUNG immer Projekt eprooshop } else { $ticketnachricht = $this->ticketModule->CreateTicket( $this->projectId, $mailacc, $name_sender, $from, $subject, $action, $timestamp, "email", null, $verfasser_replyto, $mail_replyto ); // ACHTUNG immer Projekt eprooshop } $schluessel = $this->db->Select( "SELECT `ticket` FROM `ticket_nachricht` WHERE `id`='$ticketnachricht' LIMIT 1" ); } else { echo "Lege neues Ticket an\n"; } } if ($ticketnachricht > 0 && $id > 0) { $this->db->Update( "UPDATE `emailbackup_mails` SET ticketnachricht='$ticketnachricht' WHERE id='$id' LIMIT 1" ); if (is_array($cc_recv)) { foreach ($cc_recv as $mail) { if ($mail['name'] != '') { $cc_value = $this->db->real_escape_string($mail['name']) . ' <' . $this->db->real_escape_string($mail['email']) . ">"; } else { $cc_value = $this->db->real_escape_string($mail['email']); } if ($cc_value != '') { $sql = "INSERT INTO ticket_header (`id`,`ticket_nachricht`,`type`,`value`) VALUES ('', '$ticketnachricht', 'cc', '" . $cc_value . "')"; $this->db->InsertWithoutLog($sql); } } $cc_recv = []; } } // Prüfen ob Ordner vorhanden ansonsten anlegen $ordner = $this->config->WFuserdata . '/emailbackup/' . $this->config->WFdbname . "/$id"; if (!is_dir($ordner) && $id > 0) { if (!mkdir($ordner, 0777, true) && !is_dir($ordner)) { } $raw_full_email = $message->getRawContent(); file_put_contents($ordner . '/mail.txt', $raw_full_email); } //speichere anhang als datei if ($anhang == 1 && $id > 0) { $ordner = $this->config->WFuserdata . '/emailbackup/' . $this->config->WFdbname; if (!is_dir($ordner)) { if (!mkdir($ordner, 0777, true) && !is_dir($ordner)) { $this->logger->error("Folder \"{folder}\" was not created", ['folder' => $ordner]); } } // Prüfen ob Ordner vorhanden ansonsten anlegen $ordner = $this->config->WFuserdata . '/emailbackup/' . $this->config->WFdbname . "/$id"; if (!is_dir($ordner)) { if ($DEBUG) { echo "mkdir $ordner\n"; } else { if (!mkdir($ordner, 0777, true) && !is_dir($ordner)) { $this->logger->error("Folder \"{folder}\" was not created", ['folder' => $ordner]); } } } foreach ($attachments as $attachment) { if ($attachment->getFileName() !== '') { if ($DEBUG) { } else { $handle = fopen($ordner . '/' . $attachment->getFileName(), 'wb'); if ($handle) { fwrite($handle, $attachment->getContent()); fclose($handle); } } //Schreibe Anhänge in Datei-Tabelle $datei = $ordner . '/' . $attachment->getFileName(); $dateiname = $attachment->getFileName(); if (stripos($dateiname, '=?utf-8') !== false) { $dateiname = $this->formatter->encodeToUtf8($dateiname); $dateiname = htmlspecialchars_decode($dateiname); } if (stripos($dateiname, '=?iso-8859') !== false) { $dateiname = $this->formatter->encodeToUtf8($dateiname); $dateiname = htmlspecialchars_decode($dateiname); } if ($DEBUG) { echo "CreateDatei($dateiname,{$dateiname},\"\",\"\",\"datei\",\"Support Mail\",true," . $this->config->WFuserdata . "/dms/" . $this->config->WFdbname . ")\n"; } else { $tmpid = $this->erpApi->CreateDatei( $dateiname, $dateiname, '', '', $datei, 'Support Mail', true, $this->config->WFuserdata . '/dms/' . $this->config->WFdbname ); } if ($DEBUG) { echo "AddDateiStichwort $tmpid,'Anhang','Ticket',$ticketnachricht,true)\n"; } else { $this->erpApi->AddDateiStichwort( $tmpid, 'Anhang', 'Ticket', $ticketnachricht, true ); } } } } $text = $this->mailAccount->getAutoresponseText(); $betreff = $this->mailAccount->getAutoresponseSubject(); $text = str_replace('{TICKET}', $schluessel, $text); $text = str_replace('{BETREFF}', $subject, $text); $betreff = str_replace('{TICKET}', $schluessel, $betreff); $betreff = str_replace('{BETREFF}', $subject, $betreff); if ( $this->mailAccount->isAutoresponseEnabled() && $this->mailAccount->getAutoresponseText() !== '' && ( $this->erpApi->AutoresponderBlacklist($from) !== 1 || $this->mailAccount->isAutoresponseLimitEnabled() === false ) ) { if (!$this->erpApi->isHTML($text)) { $text = str_replace("\r\n", '
', $text); } $this->erpApi->MailSend( $this->mailAccount->getSenderEmailAddress(), '', $from, $name_sender, $betreff, $text ); } } } }