public function testMixedEncodingStartingWithLatin1IsConvertedAndCoercedToUtf8() { $inputString = iconv("UTF-8", "ISO-8859-15", $this->testString); $inputString .= $this->testString; $outputString = $this->converter->convert($inputString); assertThat($outputString, startsWith($this->testString)); assertThat(strlen($outputString), is(greaterThan(2 * strlen($this->testString)))); }
function __construct($from_encoding = null, $convert_html_entities = false) { $this->from_encoding = $from_encoding ? $from_encoding : Encoding::system(); $this->encoding_converter = EncodingConverter::create($this->from_encoding, Utf8::NAME); $this->convert_html_entities = $convert_html_entities; $this->reset(); }
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 zip_extract() { if (logged_user()->isGuest()) { flash_error(lang('no access permissions')); ajx_current("empty"); return; } $fileId = array_var($_GET, 'id'); ajx_current("empty"); if (!zip_supported()) { flash_error(lang('zip not supported')); return; } $file = ProjectFiles::findById($fileId); if (!$file->canEdit(logged_user())) { flash_error(lang('no access permissions')); ajx_current("empty"); return; } if (!$file) { flash_error(lang('file dnx')); ajx_current("empty"); } else { $old_memory_limit = ini_get('memory_limit'); if (php_config_value_to_bytes($old_memory_limit) < 96*1024*1024) { ini_set('memory_limit', '96M'); } @set_time_limit(0); session_commit(); $content = $file->getLastRevision()->getFileContent(); $filepath = ROOT.'/tmp/'.rand().'.zip'; $handle = fopen($filepath, 'wb'); fwrite($handle, $content); fclose($handle); $encoder = EncodingConverter::instance(); $file_count = 0; $zip = new ZipArchive(); if ($zip->open($filepath)) { $tmp_dir = ROOT.'/tmp/'.rand().'/'; $zip->extractTo($tmp_dir); $i=0; $members = $file->getMemberIds(); while ($e_name = $zip->getNameIndex($i++)) { $tmp_path = $tmp_dir.$e_name; //removes weird characters $e_name = preg_match_all('/([\x09\x0a\x0d\x20-\x7e]'. // ASCII characters '|[\xc2-\xdf][\x80-\xbf]'. // 2-byte (except overly longs) '|\xe0[\xa0-\xbf][\x80-\xbf]'. // 3 byte (except overly longs) '|[\xe1-\xec\xee\xef][\x80-\xbf]{2}'. // 3 byte (except overly longs) '|\xed[\x80-\x9f][\x80-\xbf])+/', // 3 byte (except UTF-16 surrogates) $e_name, $clean_pieces); $e_name = join('?', $clean_pieces[0]); if (!is_dir($tmp_path)) { $this->upload_file(null, $e_name, $tmp_path, $members); $file_count++; } } $zip->close(); delete_dir($tmp_dir); } unlink($filepath); ajx_current("reload"); flash_success(lang('success extracting files', $file_count)); } } // zip_extract
function text_edit() { if (logged_user()->isGuest()) { flash_error(lang('no access permissions')); ajx_current("empty"); return; } $file_data = array_var($_POST, 'file'); if (!isset($file_data)) { // open text file $file = ProjectFiles::findById(get_id()); if (!$file instanceof ProjectFile) { flash_error(lang('file dnx')); ajx_current("empty"); return; } // if if (!$file->canEdit(logged_user())) { flash_error(lang('no access permissions')); ajx_current("empty"); return; } // if tpl_assign('file', $file); } else { ajx_current("empty"); // save new file content try { $file = ProjectFiles::findById(array_var($file_data, 'id')); if (!$file instanceof ProjectFile) { flash_error(lang('file dnx')); ajx_current("empty"); return; } // if if (!$file->canEdit(logged_user())) { flash_error(lang('no access permissions')); return; } // if DB::beginWork(); $post_revision = array_var($_POST, 'new_revision_document') == 'checked'; // change file? $revision_comment = ''; $file_dt['name'] = $file->getFilename(); $file_content = EncodingConverter::instance()->convert(detect_encoding(array_var($_POST, 'fileContent'), array('UTF-8', 'ISO-8859-1')), array_var($file_data, 'encoding'), array_var($_POST, 'fileContent')); $file_dt['size'] = strlen($file_content); $file_dt['type'] = $file->getTypeString(); $file_dt['tmp_name'] = ROOT . '/tmp/' . rand(); $handler = fopen($file_dt['tmp_name'], 'w'); fputs($handler, $file_content); fclose($handler); //$file->setFilename(array_var($postFile, 'name')); $file->save(); $file->handleUploadedFile($file_dt, $post_revision, $revision_comment); $ws = $file->getWorkspaces(); ApplicationLogs::createLog($file, $ws, ApplicationLogs::ACTION_EDIT); DB::commit(); unlink($file_dt['tmp_name']); flash_success(lang('success save file', $file->getFilename())); } catch (Exception $e) { DB::rollback(); unlink($file_dt['tmp_name']); flash_error(lang('error while saving')); } // try } // if }
/** * Images that are attachments are saved to the filesystem and the links to them are rebuilt * files are saved in root/tmp directory */ private function rebuild_body_html($html, $parts, $tmp_folder) { $enc_conv = EncodingConverter::instance(); $html = preg_replace("/src=cid:([^[:space:]>]*)/i", "src=\"cid:\$1\"", $html); $end_find = false; $to_find = 'src="cid:'; $end_pos = 0; while (!$end_find) { $part_name = ""; $cid_pos = strpos($html, $to_find, $end_pos); if ($cid_pos !== FALSE) { $cid_pos += strlen($to_find); $end_pos = strpos($html, '"', $cid_pos); $part_name = substr($html, $cid_pos, $end_pos - $cid_pos); } else { $end_find = true; } if (!$end_find) { if (!is_dir(ROOT . "{$tmp_folder}")) { mkdir(ROOT . "{$tmp_folder}"); } if (!is_array($parts)) { continue; } foreach ($parts as $part) { if (is_array($part['Headers'])) { if (isset($part['Headers']['content-id:']) && $part['Headers']['content-id:'] == "<{$part_name}>") { $filename = isset($part['FileName']) ? $part['FileName'] : $part_name; $filename = $enc_conv->convert(detect_encoding($filename), "ISO-8859-1", $filename, false); $file_content = $part['Body']; $handle = fopen(ROOT . "{$tmp_folder}/{$filename}", "wb"); fwrite($handle, $file_content); fclose($handle); $html = str_replace('src="cid:' . $part_name . '"', "src=\"" . ROOT_URL . "{$tmp_folder}/{$filename}\"", $html); $html = str_replace('src="cid:' . $part_name, "src=\"" . ROOT_URL . "{$tmp_folder}/{$filename}\"", $html); } else { if (isset($part['Parts'])) { $html = self::rebuild_body_html($html, $part['Parts'], $tmp_folder); } } } } } } return $html; }
function __construct($to_encoding = null) { $this->to_encoding = $to_encoding ? $to_encoding : Encoding::system(); $this->encoding_converter = EncodingConverter::create(Utf8::NAME, $this->to_encoding); $this->reset(); }
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; }
?> " action="<?php echo get_url('files', 'text_edit'); ?> " method="post" enctype="multipart/form-data"> <div> <input type="hidden" name="file[id]" value="<?php echo $file->getId(); ?> " /> <input type="hidden" name="file[name]" value="<?php echo clean($file->getFilename()); ?> " /> <input type="hidden" name="file[encoding]" value="<?php echo detect_encoding($filecontent, array('UTF-8', 'ISO-8859-1')); ?> " /> <input type="hidden" name="new_revision_document" value="" /> </div> <textarea class="textedit" name="fileContent"><?php echo htmlEntities(EncodingConverter::instance()->convert(detect_encoding($filecontent, array('UTF-8', 'ISO-8859-1')), 'UTF-8', $filecontent), null, 'UTF-8'); ?> </textarea> <?php add_page_action(lang("save"), "javascript:(function(){ var form = document.getElementById('{$iname}'); form.new_revision_document.value = 'checked'; form.onsubmit(); })()", "save"); ?> </form>
/** * Returns an encoder that convert from another encoding to this encoding. * * @param string|Encoder $from Encoding to convert from, defaults to system encoding. * @return Converter */ public function encoder($from = null) { $from = $from ? $from : Encoding::system(); $to = $this; return EncodingConverter::create($from, $to); }