function SaveMail(&$content, MailAccount $account, $uidl, $state = 0, $imap_folder_name = '') { if (defined('DEBUG_EMAIL_RETRIEVAL') && DEBUG_EMAIL_RETRIEVAL) { self::log_connection_status(); Logger::log("UID: {$uidl}"); } if (!mysql_ping(DB::connection()->getLink())) { DB::connection()->reconnect(); Logger::log("*** Connection Lost -> Reconnected ***"); } if (defined('DEBUG_EMAIL_RETRIEVAL') && DEBUG_EMAIL_RETRIEVAL) { Logger::log("mem 1) " . format_filesize(memory_get_usage())); } if (strpos($content, '+OK ') > 0) { $content = substr($content, strpos($content, '+OK ')); } if (defined('DEBUG_EMAIL_RETRIEVAL') && DEBUG_EMAIL_RETRIEVAL) { Logger::log("mem 2) " . format_filesize(memory_get_usage())); } self::parseMail($content, $decoded, $parsedMail, $warnings); if (defined('DEBUG_EMAIL_RETRIEVAL') && DEBUG_EMAIL_RETRIEVAL) { Logger::log("mem 3) " . format_filesize(memory_get_usage())); } $encoding = array_var($parsedMail, 'Encoding', 'UTF-8'); $enc_conv = EncodingConverter::instance(); $to_addresses = self::getAddresses(array_var($parsedMail, "To")); $from = self::getAddresses(array_var($parsedMail, "From")); $message_id = self::getHeaderValueFromContent($content, "Message-ID"); $in_reply_to_id = self::getHeaderValueFromContent($content, "In-Reply-To"); if (defined('DEBUG_EMAIL_RETRIEVAL') && DEBUG_EMAIL_RETRIEVAL) { Logger::log("mem 4) " . format_filesize(memory_get_usage())); } $uid = trim($uidl); if (str_starts_with($uid, '<') && str_ends_with($uid, '>')) { $uid = utf8_substr($uid, 1, utf8_strlen($uid, $encoding) - 2, $encoding); } if ($uid == '') { $uid = trim($message_id); if ($uid == '') { $uid = array_var($parsedMail, 'Subject', 'MISSING UID'); } if (str_starts_with($uid, '<') && str_ends_with($uid, '>')) { $uid = utf8_substr($uid, 1, utf8_strlen($uid, $encoding) - 2, $encoding); } if (MailContents::mailRecordExists($account->getId(), $uid, $imap_folder_name == '' ? null : $imap_folder_name)) { return; } } if (!$from) { $parsedMail["From"] = self::getFromAddressFromContent($content); $from = array_var($parsedMail["From"][0], 'address', ''); if (defined('DEBUG_EMAIL_RETRIEVAL') && DEBUG_EMAIL_RETRIEVAL) { Logger::log("mem 4.1) " . format_filesize(memory_get_usage())); } } if (defined('DEBUG_EMAIL_RETRIEVAL') && DEBUG_EMAIL_RETRIEVAL) { Logger::log("mem 5) " . format_filesize(memory_get_usage())); } if (defined('EMAIL_MESSAGEID_CONTROL') && EMAIL_MESSAGEID_CONTROL) { if (trim($message_id) != "") { $id_condition = " AND `message_id`='" . trim($message_id) . "'"; } else { $id_condition = " AND `subject`='" . trim(array_var($parsedMail, 'Subject')) . "' AND `from`='{$from}'"; if (array_var($parsedMail, 'Date')) { $sent_date_dt = new DateTimeValue(strtotime(array_var($parsedMail, 'Date'))); $sent_date_str = $sent_date_dt->toMySQL(); $id_condition .= " AND `sent_date`='" . $sent_date_str . "'"; } } $same = MailContents::findOne(array('conditions' => "`account_id`=" . $account->getId() . $id_condition, 'include_trashed' => true)); if ($same instanceof MailContent) { return; } } if ($state == 0) { if ($from == $account->getEmailAddress()) { if (strpos($to_addresses, $from) !== FALSE) { $state = 5; } else { $state = 1; } //Show only in sent folder } } if (defined('DEBUG_EMAIL_RETRIEVAL') && DEBUG_EMAIL_RETRIEVAL) { Logger::log("mem 6) " . format_filesize(memory_get_usage())); self::log_connection_status(); } $from_spam_junk_folder = strpos(strtolower($imap_folder_name), 'spam') !== FALSE || strpos(strtolower($imap_folder_name), 'junk') !== FALSE || strpos(strtolower($imap_folder_name), 'trash') !== FALSE; $user_id = logged_user() instanceof User ? logged_user()->getId() : $account->getUserId(); if (defined('DEBUG_EMAIL_RETRIEVAL') && DEBUG_EMAIL_RETRIEVAL) { self::log_connection_status(); } $max_spam_level = user_config_option('max_spam_level', null, $user_id); if ($max_spam_level < 0) { $max_spam_level = 0; } $mail_spam_level = strlen(trim(array_var($decoded[0]['Headers'], 'x-spam-level:', ''))); // if max_spam_level >= 10 then nothing goes to junk folder $spam_in_subject = false; if (config_option('check_spam_in_subject')) { $spam_in_subject = strpos_utf(strtoupper(array_var($parsedMail, 'Subject')), "**SPAM**") !== false; } if ($max_spam_level < 10 && ($mail_spam_level > $max_spam_level || $from_spam_junk_folder) || $spam_in_subject) { $state = 4; // send to Junk folder } if (defined('DEBUG_EMAIL_RETRIEVAL') && DEBUG_EMAIL_RETRIEVAL) { Logger::log("mem 7) " . format_filesize(memory_get_usage())); self::log_connection_status(); } if (!isset($parsedMail['Subject'])) { $parsedMail['Subject'] = ''; } $mail = new MailContent(); $mail->setAccountId($account->getId()); $mail->setState($state); $mail->setImapFolderName($imap_folder_name); $mail->setFrom($from); $cc = trim(self::getAddresses(array_var($parsedMail, "Cc"))); if ($cc == '' && array_var($decoded, 0) && array_var($decoded[0], 'Headers')) { $cc = array_var($decoded[0]['Headers'], 'cc:', ''); } if (defined('DEBUG_EMAIL_RETRIEVAL') && DEBUG_EMAIL_RETRIEVAL) { self::log_connection_status(); Logger::log("mem 8) " . format_filesize(memory_get_usage())); } $mail->setCc($cc); $from_name = trim(array_var(array_var(array_var($parsedMail, 'From'), 0), 'name')); $from_encoding = detect_encoding($from_name); if ($from_name == '') { $from_name = $from; } else { if (strtoupper($encoding) == 'KOI8-R' || strtoupper($encoding) == 'CP866' || $from_encoding != 'UTF-8' || !$enc_conv->isUtf8RegExp($from_name)) { //KOI8-R and CP866 are Russian encodings which PHP does not detect $utf8_from = $enc_conv->convert($encoding, 'UTF-8', $from_name); if ($enc_conv->hasError()) { $utf8_from = utf8_encode($from_name); } $utf8_from = utf8_safe($utf8_from); $mail->setFromName($utf8_from); } else { $mail->setFromName($from_name); } } $subject_aux = $parsedMail['Subject']; $subject_encoding = detect_encoding($subject_aux); if (strtoupper($encoding) == 'KOI8-R' || strtoupper($encoding) == 'CP866' || $subject_encoding != 'UTF-8' || !$enc_conv->isUtf8RegExp($subject_aux)) { //KOI8-R and CP866 are Russian encodings which PHP does not detect $utf8_subject = $enc_conv->convert($encoding, 'UTF-8', $subject_aux); if ($enc_conv->hasError()) { $utf8_subject = utf8_encode($subject_aux); } $utf8_subject = utf8_safe($utf8_subject); $mail->setSubject($utf8_subject); } else { $utf8_subject = utf8_safe($subject_aux); $mail->setSubject($utf8_subject); } if (defined('DEBUG_EMAIL_RETRIEVAL') && DEBUG_EMAIL_RETRIEVAL) { self::log_connection_status(); Logger::log("mem 9) " . format_filesize(memory_get_usage())); } $mail->setTo($to_addresses); $sent_timestamp = false; if (array_key_exists("Date", $parsedMail)) { $sent_timestamp = strtotime($parsedMail["Date"]); } if ($sent_timestamp === false || $sent_timestamp === -1 || $sent_timestamp === 0) { $mail->setSentDate(DateTimeValueLib::now()); } else { $mail->setSentDate(new DateTimeValue($sent_timestamp)); } // if this constant is defined, mails older than this date will not be fetched if (defined('FIRST_MAIL_DATE')) { $first_mail_date = DateTimeValueLib::makeFromString(FIRST_MAIL_DATE); if ($mail->getSentDate()->getTimestamp() < $first_mail_date->getTimestamp()) { // return true to stop getting older mails from the server return true; } } $received_timestamp = false; if (array_key_exists("Received", $parsedMail) && $parsedMail["Received"]) { $received_timestamp = strtotime($parsedMail["Received"]); } if ($received_timestamp === false || $received_timestamp === -1 || $received_timestamp === 0) { $mail->setReceivedDate($mail->getSentDate()); } else { $mail->setReceivedDate(new DateTimeValue($received_timestamp)); if ($state == 5 && $mail->getSentDate()->getTimestamp() > $received_timestamp) { $mail->setReceivedDate($mail->getSentDate()); } } if (defined('DEBUG_EMAIL_RETRIEVAL') && DEBUG_EMAIL_RETRIEVAL) { self::log_connection_status(); Logger::log("mem 10) " . format_filesize(memory_get_usage())); } $mail->setSize(strlen($content)); $mail->setHasAttachments(!empty($parsedMail["Attachments"])); $mail->setCreatedOn(new DateTimeValue(time())); $mail->setCreatedById($account->getUserId()); $mail->setAccountEmail($account->getEmail()); $mail->setMessageId($message_id); $mail->setInReplyToId($in_reply_to_id); $mail->setUid($uid); $type = array_var($parsedMail, 'Type', 'text'); switch ($type) { case 'html': $utf8_body = $enc_conv->convert($encoding, 'UTF-8', array_var($parsedMail, 'Data', '')); if ($enc_conv->hasError()) { $utf8_body = utf8_encode(array_var($parsedMail, 'Data', '')); } $utf8_body = utf8_safe($utf8_body); $mail->setBodyHtml($utf8_body); break; case 'text': $utf8_body = $enc_conv->convert($encoding, 'UTF-8', array_var($parsedMail, 'Data', '')); if ($enc_conv->hasError()) { $utf8_body = utf8_encode(array_var($parsedMail, 'Data', '')); } $utf8_body = utf8_safe($utf8_body); $mail->setBodyPlain($utf8_body); break; case 'delivery-status': $utf8_body = $enc_conv->convert($encoding, 'UTF-8', array_var($parsedMail, 'Response', '')); if ($enc_conv->hasError()) { $utf8_body = utf8_encode(array_var($parsedMail, 'Response', '')); } $utf8_body = utf8_safe($utf8_body); $mail->setBodyPlain($utf8_body); break; default: break; } if (isset($parsedMail['Alternative'])) { foreach ($parsedMail['Alternative'] as $alt) { if ($alt['Type'] == 'html' || $alt['Type'] == 'text') { $body = $enc_conv->convert(array_var($alt, 'Encoding', 'UTF-8'), 'UTF-8', array_var($alt, 'Data', '')); if ($enc_conv->hasError()) { $body = utf8_encode(array_var($alt, 'Data', '')); } // remove large white spaces $exploded = preg_split("/[\\s]+/", $body, -1, PREG_SPLIT_NO_EMPTY); $body = implode(" ", $exploded); // remove html comments $body = preg_replace('/<!--.*-->/i', '', $body); } $body = utf8_safe($body); if ($alt['Type'] == 'html') { $mail->setBodyHtml($body); } else { if ($alt['Type'] == 'text') { $plain = html_to_text(html_entity_decode($utf8_body, null, "UTF-8")); $mail->setBodyPlain($plain); } } // other alternative parts (like images) are not saved in database. } } $repository_id = self::SaveContentToFilesystem($mail->getUid(), $content); $mail->setContentFileId($repository_id); if (defined('DEBUG_EMAIL_RETRIEVAL') && DEBUG_EMAIL_RETRIEVAL) { self::log_connection_status(); Logger::log("mem 11) " . format_filesize(memory_get_usage())); } try { if ($in_reply_to_id != "") { if ($message_id != "") { $conv_mail = MailContents::findOne(array("conditions" => "`account_id`=" . $account->getId() . " AND `in_reply_to_id` = '{$message_id}'")); if (!$conv_mail) { $conv_mail = MailContents::findOne(array("conditions" => "`account_id`=" . $account->getId() . " AND `message_id` = '{$in_reply_to_id}'")); } else { // Search for other discontinued conversation part to link it $other_conv_emails = MailContents::findAll(array("conditions" => "`account_id`=" . $account->getId() . " AND `message_id` = '{$in_reply_to_id}' AND `conversation_id`<>" . $conv_mail->getConversationId())); } } else { $conv_mail = MailContents::findOne(array("conditions" => "`account_id`=" . $account->getId() . " AND `message_id` = '{$in_reply_to_id}'")); } if ($conv_mail instanceof MailContent) { // Remove "Re: ", "Fwd: ", etc to compare the subjects $conv_original_subject = strtolower($conv_mail->getSubject()); if (($pos = strrpos($conv_original_subject, ":")) !== false) { $conv_original_subject = trim(substr($conv_original_subject, $pos + 1)); } } if ($conv_mail instanceof MailContent && strpos(strtolower($mail->getSubject()), strtolower($conv_original_subject)) !== false) { $mail->setConversationId($conv_mail->getConversationId()); if (isset($other_conv_emails) && is_array($other_conv_emails)) { foreach ($other_conv_emails as $ocm) { $ocm->setConversationId($conv_mail->getConversationId()); $ocm->save(); } } } else { $conv_id = MailContents::getNextConversationId($account->getId()); $mail->setConversationId($conv_id); } } else { $conv_id = MailContents::getNextConversationId($account->getId()); $mail->setConversationId($conv_id); } if (defined('DEBUG_EMAIL_RETRIEVAL') && DEBUG_EMAIL_RETRIEVAL) { self::log_connection_status(); Logger::log("mem 12) " . format_filesize(memory_get_usage())); } $mail->save(); if (defined('DEBUG_EMAIL_RETRIEVAL') && DEBUG_EMAIL_RETRIEVAL) { self::log_connection_status(); Logger::log("mem 13) " . format_filesize(memory_get_usage())); } // CLASSIFY RECEIVED MAIL WITH THE CONVERSATION if (user_config_option('classify_mail_with_conversation', null, $account->getUserId()) && isset($conv_mail) && $conv_mail instanceof MailContent) { $wss = $conv_mail->getWorkspaces(); foreach ($wss as $ws) { $acc_user = Users::findById($account->getUserId()); if ($acc_user instanceof User && $acc_user->hasProjectPermission($ws, ProjectUsers::CAN_READ_MAILS)) { $mail->addToWorkspace($ws); } } } // CLASSIFY MAILS IF THE ACCOUNT HAS A WORKSPACE if ($account->getColumnValue('workspace', 0) != 0) { $workspace = Projects::findById($account->getColumnValue('workspace', 0)); if ($workspace && $workspace instanceof Project && !$mail->hasWorkspace($workspace)) { $mail->addToWorkspace($workspace); } } //END CLASSIFY $user = Users::findById($account->getUserId()); if ($user instanceof User) { $mail->subscribeUser($user); } } catch (Exception $e) { FileRepository::deleteFile($repository_id); if (strpos($e->getMessage(), "Query failed with message 'Got a packet bigger than 'max_allowed_packet' bytes'") === false) { throw $e; } } unset($parsedMail); if (defined('DEBUG_EMAIL_RETRIEVAL') && DEBUG_EMAIL_RETRIEVAL) { Logger::log("mem fin) " . format_filesize(memory_get_usage())); self::log_connection_status(); } return false; }
function SaveMail(&$content, MailAccount $account, $uidl, $state = 0, $imap_folder_name = '', $read = null, &$received_count) { try { if (strpos($content, '+OK ') > 0) { $content = substr($content, strpos($content, '+OK ')); } self::parseMail($content, $decoded, $parsedMail, $warnings); $encoding = array_var($parsedMail, 'Encoding', 'UTF-8'); $enc_conv = EncodingConverter::instance(); $to_addresses = self::getAddresses(array_var($parsedMail, "To")); $from = self::getAddresses(array_var($parsedMail, "From")); $message_id = self::getHeaderValueFromContent($content, "Message-ID"); $in_reply_to_id = self::getHeaderValueFromContent($content, "In-Reply-To"); $uid = trim($uidl); if (str_starts_with($uid, '<') && str_ends_with($uid, '>')) { $uid = utf8_substr($uid, 1, utf8_strlen($uid, $encoding) - 2, $encoding); } if ($uid == '') { $uid = trim($message_id); if ($uid == '') { $uid = array_var($parsedMail, 'Subject', 'MISSING UID'); } if (str_starts_with($uid, '<') && str_ends_with($uid, '>')) { $uid = utf8_substr($uid, 1, utf8_strlen($uid, $encoding) - 2, $encoding); } } // do not save duplicate emails if (MailContents::mailRecordExists($account->getId(), $uid, $imap_folder_name == '' ? null : $imap_folder_name)) { return; } if (!$from) { $parsedMail["From"] = self::getFromAddressFromContent($content); $from = array_var($parsedMail["From"][0], 'address', ''); } if (defined('EMAIL_MESSAGEID_CONTROL') && EMAIL_MESSAGEID_CONTROL) { if (trim($message_id) != "") { $id_condition = " AND `message_id`='" . trim($message_id) . "' AND `from`='{$from}'"; } else { $id_condition = " AND `name`= " . DB::escape(trim(array_var($parsedMail, 'Subject'))) . " AND `from`='{$from}'"; if (array_var($parsedMail, 'Date')) { $sent_date_dt = new DateTimeValue(strtotime(array_var($parsedMail, 'Date'))); $sent_date_str = $sent_date_dt->toMySQL(); $id_condition .= " AND `sent_date`='" . $sent_date_str . "'"; } } $same = MailContents::findOne(array('conditions' => "`account_id`=" . $account->getId() . $id_condition, 'include_trashed' => true)); if ($same instanceof MailContent) { return; } } $from_spam_junk_folder = strpos(strtolower($imap_folder_name), 'spam') !== FALSE || strpos(strtolower($imap_folder_name), 'junk') !== FALSE || strpos(strtolower($imap_folder_name), 'trash') !== FALSE; $user_id = logged_user() instanceof Contact ? logged_user()->getId() : $account->getContactId(); $max_spam_level = user_config_option('max_spam_level', null, $user_id); if ($max_spam_level < 0) { $max_spam_level = 0; } $spam_level_header = 'x-spam-level:'; foreach ($decoded[0]['Headers'] as $hdr_name => $hdrval) { if (strpos(strtolower($hdr_name), "spamscore") !== false || strpos(strtolower($hdr_name), "x-spam-level")) { $spam_level_header = $hdr_name; break; } } $mail_spam_level = strlen(trim(array_var($decoded[0]['Headers'], $spam_level_header, ''))); // if max_spam_level >= 10 then nothing goes to junk folder $spam_in_subject = false; if (config_option('check_spam_in_subject')) { $spam_in_subject = strpos_utf(strtoupper(array_var($parsedMail, 'Subject')), "**SPAM**") !== false; } if ($max_spam_level < 10 && ($mail_spam_level > $max_spam_level || $from_spam_junk_folder) || $spam_in_subject) { $state = 4; // send to Junk folder } //if you are in the table spam MailSpamFilters if ($state != 4) { $spam_email = MailSpamFilters::getFrom($account->getId(), $from); if ($spam_email) { $state = 0; if ($spam_email[0]->getSpamState() == "spam") { $state = 4; } } else { if ($state == 0) { if (strtolower($from) == strtolower($account->getEmailAddress())) { if (strpos($to_addresses, $from) !== FALSE) { $state = 5; } else { $state = 1; } //Show only in sent folder } } } } if (!isset($parsedMail['Subject'])) { $parsedMail['Subject'] = ''; } $mail = new MailContent(); $mail->setAccountId($account->getId()); $mail->setState($state); $mail->setImapFolderName($imap_folder_name); $mail->setFrom($from); $cc = trim(self::getAddresses(array_var($parsedMail, "Cc"))); if ($cc == '' && array_var($decoded, 0) && array_var($decoded[0], 'Headers')) { $cc = array_var($decoded[0]['Headers'], 'cc:', ''); } $mail->setCc($cc); $from_name = trim(array_var(array_var(array_var($parsedMail, 'From'), 0), 'name')); $from_encoding = detect_encoding($from_name); if ($from_name == '') { $from_name = $from; } else { if (strtoupper($encoding) == 'KOI8-R' || strtoupper($encoding) == 'CP866' || $from_encoding != 'UTF-8' || !$enc_conv->isUtf8RegExp($from_name)) { //KOI8-R and CP866 are Russian encodings which PHP does not detect $utf8_from = $enc_conv->convert($encoding, 'UTF-8', $from_name); if ($enc_conv->hasError()) { $utf8_from = utf8_encode($from_name); } $utf8_from = utf8_safe($utf8_from); $mail->setFromName($utf8_from); } else { $mail->setFromName($from_name); } } $subject_aux = $parsedMail['Subject']; $subject_encoding = detect_encoding($subject_aux); $subject_multipart_encoding = array_var($parsedMail, 'SubjectEncoding', strtoupper($encoding)); if ($subject_multipart_encoding != 'UTF-8' && ($subject_multipart_encoding == 'KOI8-R' || $subject_multipart_encoding == 'CP866' || $subject_encoding != 'UTF-8' || !$enc_conv->isUtf8RegExp($subject_aux))) { //KOI8-R and CP866 are Russian encodings which PHP does not detect $utf8_subject = $enc_conv->convert($subject_multipart_encoding, 'UTF-8', $subject_aux); if ($enc_conv->hasError()) { $utf8_subject = utf8_encode($subject_aux); } $utf8_subject = utf8_safe($utf8_subject); $mail->setSubject($utf8_subject); } else { $utf8_subject = utf8_safe($subject_aux); $mail->setSubject($utf8_subject); } $mail->setTo($to_addresses); $sent_timestamp = false; if (array_key_exists("Date", $parsedMail)) { $sent_timestamp = strtotime($parsedMail["Date"]); } if ($sent_timestamp === false || $sent_timestamp === -1 || $sent_timestamp === 0) { $mail->setSentDate(DateTimeValueLib::now()); } else { $mail->setSentDate(new DateTimeValue($sent_timestamp)); } // if this constant is defined, mails older than this date will not be fetched if (defined('FIRST_MAIL_DATE')) { $first_mail_date = DateTimeValueLib::makeFromString(FIRST_MAIL_DATE); if ($mail->getSentDate()->getTimestamp() < $first_mail_date->getTimestamp()) { // return true to stop getting older mails from the server return true; } } $received_timestamp = false; if (array_key_exists("Received", $parsedMail) && $parsedMail["Received"]) { $received_timestamp = strtotime($parsedMail["Received"]); } if ($received_timestamp === false || $received_timestamp === -1 || $received_timestamp === 0) { $mail->setReceivedDate($mail->getSentDate()); } else { $mail->setReceivedDate(new DateTimeValue($received_timestamp)); if ($state == 5 && $mail->getSentDate()->getTimestamp() > $received_timestamp) { $mail->setReceivedDate($mail->getSentDate()); } } $mail->setSize(strlen($content)); $mail->setCreatedOn(new DateTimeValue(time())); $mail->setCreatedById($account->getContactId()); $mail->setAccountEmail($account->getEmail()); $mail->setMessageId($message_id); $mail->setInReplyToId($in_reply_to_id); // set hasAttachments=true onlu if there is any attachment with FileDisposition='attachment' $has_attachments = false; foreach (array_var($parsedMail, "Attachments", array()) as $attachment) { if (array_var($attachment, 'FileDisposition') == 'attachment') { $has_attachments = true; } } $mail->setHasAttachments($has_attachments); $mail->setUid($uid); $type = array_var($parsedMail, 'Type', 'text'); switch ($type) { case 'html': $utf8_body = $enc_conv->convert($encoding, 'UTF-8', array_var($parsedMail, 'Data', '')); //Solve bad syntax styles outlook if it exists if (substr_count($utf8_body, "<style>") != substr_count($utf8_body, "</style>") && substr_count($utf8_body, "/* Font Definitions */") >= 1) { $p1 = strpos($utf8_body, "/* Font Definitions */", 0); $utf8_body1 = substr($utf8_body, 0, $p1); $p0 = strrpos($utf8_body1, "</style>"); $html_content = ($p0 >= 0 ? substr($utf8_body1, 0, $p0) : $utf8_body1) . substr($utf8_body, $p1); $utf8_body = str_replace_first("/* Font Definitions */", "<style>", $utf8_body); } if ($enc_conv->hasError()) { $utf8_body = utf8_encode(array_var($parsedMail, 'Data', '')); } $utf8_body = utf8_safe($utf8_body); $mail->setBodyHtml($utf8_body); break; case 'text': $utf8_body = $enc_conv->convert($encoding, 'UTF-8', array_var($parsedMail, 'Data', '')); if ($enc_conv->hasError()) { $utf8_body = utf8_encode(array_var($parsedMail, 'Data', '')); } $utf8_body = utf8_safe($utf8_body); $mail->setBodyPlain($utf8_body); break; case 'delivery-status': $utf8_body = $enc_conv->convert($encoding, 'UTF-8', array_var($parsedMail, 'Response', '')); if ($enc_conv->hasError()) { $utf8_body = utf8_encode(array_var($parsedMail, 'Response', '')); } $utf8_body = utf8_safe($utf8_body); $mail->setBodyPlain($utf8_body); break; default: if (array_var($parsedMail, 'FileDisposition') == 'inline') { $attachs = array_var($parsedMail, 'Attachments', array()); $attached_body = ""; foreach ($attachs as $k => $attach) { if (array_var($attach, 'Type') == 'html' || array_var($attach, 'Type') == 'text') { $attached_body .= $enc_conv->convert(array_var($attach, 'Encoding'), 'UTF-8', array_var($attach, 'Data')); } } $mail->setBodyHtml($attached_body); } else { if (isset($parsedMail['FileName'])) { // content-type is a file type => set as it has attachments, they will be parsed when viewing email $mail->setHasAttachments(true); } } break; } if (isset($parsedMail['Alternative'])) { foreach ($parsedMail['Alternative'] as $alt) { if ($alt['Type'] == 'html' || $alt['Type'] == 'text') { $body = $enc_conv->convert(array_var($alt, 'Encoding', 'UTF-8'), 'UTF-8', array_var($alt, 'Data', '')); if ($enc_conv->hasError()) { $body = utf8_encode(array_var($alt, 'Data', '')); } // remove large white spaces //$exploded = preg_split("/[\s]+/", $body, -1, PREG_SPLIT_NO_EMPTY); //$body = implode(" ", $exploded); // remove html comments $body = preg_replace('/<!--.*-->/i', '', $body); } $body = utf8_safe($body); if ($alt['Type'] == 'html') { $mail->setBodyHtml($body); } else { if ($alt['Type'] == 'text') { $plain = html_to_text(html_entity_decode($body, null, "UTF-8")); $mail->setBodyPlain($plain); } } // other alternative parts (like images) are not saved in database. } } $repository_id = self::SaveContentToFilesystem($mail->getUid(), $content); $mail->setContentFileId($repository_id); // START TRANSACTION DB::beginWork(); // Conversation //check if exists a conversation for this mail $conv_mail = ""; if ($in_reply_to_id != "" && $message_id != "") { $conv_mail = MailContents::findOne(array("conditions" => "`account_id`=" . $account->getId() . " AND (`message_id` = '{$in_reply_to_id}' OR `in_reply_to_id` = '{$message_id}')")); //check if this mail is in two diferent conversations and fixit if ($conv_mail) { $other_conv_mail = MailContents::findOne(array("conditions" => "`account_id`=" . $account->getId() . " AND `conversation_id` != " . $conv_mail->getConversationId() . " AND (`message_id` = '{$in_reply_to_id}' OR `in_reply_to_id` = '{$message_id}')")); if ($other_conv_mail) { $other_conv = MailContents::findAll(array("conditions" => "`account_id`=" . $account->getId() . " AND `conversation_id` = " . $other_conv_mail->getConversationId())); if ($other_conv) { foreach ($other_conv as $mail_con) { $mail_con->setConversationId($conv_mail->getConversationId()); $mail_con->save(); } } } } } elseif ($in_reply_to_id != "") { $conv_mail = MailContents::findOne(array("conditions" => "`account_id`=" . $account->getId() . " AND `message_id` = '{$in_reply_to_id}'")); } elseif ($message_id != "") { $conv_mail = MailContents::findOne(array("conditions" => "`account_id`=" . $account->getId() . " AND `in_reply_to_id` = '{$message_id}'")); } if ($conv_mail instanceof MailContent) { $conv_id = $conv_mail->getConversationId(); } else { $conv_id = MailContents::getNextConversationId($account->getId()); } $mail->setConversationId($conv_id); $mail->save(); // CLASSIFY RECEIVED MAIL WITH THE CONVERSATION $classified_with_conversation = false; $member_ids = array(); if (user_config_option('classify_mail_with_conversation', null, $account->getContactId()) && isset($conv_mail) && $conv_mail instanceof MailContent) { $member_ids = array_merge($member_ids, $conv_mail->getMemberIds()); $classified_with_conversation = true; } // CLASSIFY MAILS IF THE ACCOUNT HAS A DIMENSION MEMBER AND NOT CLASSIFIED WITH CONVERSATION $account_owner = Contacts::findById($account->getContactId()); if ($account->getMemberId() != '' && !$classified_with_conversation) { $acc_mem_ids = explode(',', $account->getMemberId()); foreach ($acc_mem_ids as $acc_mem_id) { $member_ids[] = $acc_mem_id; } } foreach ($member_ids as $k => &$mem_id) { if ($mem_id == "") { unset($member_ids[$k]); } } if (count($member_ids) > 0) { $members = Members::instance()->findAll(array('conditions' => 'id IN (' . implode(',', $member_ids) . ')')); $mail->addToMembers($members, true); /* $ctrl = new ObjectController(); $ctrl->add_to_members($mail, $member_ids, $account_owner);*/ $mail_controller = new MailController(); $mail_controller->do_classify_mail($mail, $member_ids, null, false, true); } $user = Contacts::findById($account->getContactId()); if ($user instanceof Contact) { $mail->subscribeUser($user); } $mail->addToSharingTable(); $mail->orderConversation(); //if email is from an imap account copy the state (read/unread) from the server if (!is_null($read)) { $mail->setIsRead($account->getContactId(), $read); } // increase received count $received_count++; // to apply email rules $null = null; Hook::fire('after_mail_download', $mail, $null); DB::commit(); } catch (Exception $e) { $ret = null; Hook::fire('on_save_mail_error', array('content' => $content, 'account' => $account, 'exception' => $e), $ret); Logger::log($e->__toString()); DB::rollback(); if (FileRepository::isInRepository($repository_id)) { FileRepository::deleteFile($repository_id); } if (strpos($e->getMessage(), "Query failed with message 'Got a packet bigger than 'max_allowed_packet' bytes'") === false) { throw $e; } } unset($parsedMail); return false; }