/** * Creates a new issue from an email if appropriate. Also returns if this message is related * to a previous message. * * @access private * @param array $info An array of info about the email account. * @param string $headers The headers of the email. * @param string $message_body The body of the message. * @param string $date The date this message was sent * @param string $from The name and email address of the sender. * @param string $subject The subject of this message. * @return array An array of information about the message */ function createIssueFromEmail($info, $headers, $message_body, $date, $from, $subject) { $should_create_issue = false; $issue_id = ''; $associate_email = ''; $type = 'email'; $parent_id = ''; // we can't trust the in-reply-to from the imap c-client, so let's // try to manually parse that value from the full headers $references = Mail_API::getAllReferences($headers); $message_id = Mail_API::getMessageID($headers, $message_body); $setup = Setup::load(); if (@$setup['subject_based_routing']['status'] == 'enabled' && preg_match("/\\[#(\\d+)\\]( Note| BLOCKED)*/", $subject, $matches)) { $should_create_issue = false; $issue_id = $matches[1]; if (!Issue::exists($issue_id, false)) { $issue_id = ''; } elseif (!empty($matches[2])) { $type = 'note'; } } else { // - if this email is a reply: if (count($references) > 0) { foreach ($references as $reference_msg_id) { // -> check if the replied email exists in the database: if (Note::exists($reference_msg_id)) { // note exists // get what issue it belongs too. $issue_id = Note::getIssueByMessageID($reference_msg_id); $should_create_issue = false; $type = 'note'; $parent_id = Note::getIDByMessageID($reference_msg_id); break; } elseif (Support::exists($reference_msg_id) || Issue::getIssueByRootMessageID($reference_msg_id) != false) { // email or issue exists $issue_id = Support::getIssueByMessageID($reference_msg_id); if (empty($issue_id)) { $issue_id = Issue::getIssueByRootMessageID($reference_msg_id); } if (empty($issue_id)) { // parent email isn't associated with issue. // --> create new issue, associate current email and replied email to this issue $should_create_issue = true; $associate_email = $reference_msg_id; } else { // parent email is associated with issue: // --> associate current email with existing issue $should_create_issue = false; } break; } else { // no matching note, email or issue: // => create new issue and associate current email with it $should_create_issue = true; } } } else { // - if this email is not a reply: // -> create new issue and associate current email with it $should_create_issue = true; } if (empty($issue_id)) { $issue_id = Issue::getIssueBy($subject, 'iss_summary'); if (!empty($issue_id)) { $should_create_issue = false; } } } $sender_email = Mail_API::getEmailAddress($from); // only create a new issue if this email is coming from a known customer if ($should_create_issue && $info['ema_issue_auto_creation_options']['only_known_customers'] == 'yes' && Customer::hasCustomerIntegration($info['ema_prj_id'])) { list($customer_id, ) = Customer::getCustomerIDByEmails($info['ema_prj_id'], array($sender_email)); if (empty($customer_id)) { $should_create_issue = false; } } // check whether we need to create a new issue or not if ($info['ema_issue_auto_creation'] == 'enabled' && $should_create_issue) { $options = Email_Account::getIssueAutoCreationOptions($info['ema_id']); Auth::createFakeCookie(APP_SYSTEM_USER_ID, $info['ema_prj_id']); $issue_id = Issue::createFromEmail($info['ema_prj_id'], APP_SYSTEM_USER_ID, $from, Mime_Helper::fixEncoding($subject), $message_body, @$options['category'], $options['priority'], @$options['users'], $date, $message_id); // associate any existing replied-to email with this new issue if (!empty($associate_email) && !empty($reference_issue_id)) { $reference_sup_id = Support::getIDByMessageID($associate_email); Support::associate(APP_SYSTEM_USER_ID, $issue_id, array($reference_sup_id)); } } // need to check crm for customer association if (!empty($from)) { $details = Email_Account::getDetails($info['ema_id']); if (Customer::hasCustomerIntegration($info['ema_prj_id'])) { // check for any customer contact association @(list($customer_id, ) = Customer::getCustomerIDByEmails($info['ema_prj_id'], array($sender_email))); } } return array('should_create_issue' => $should_create_issue, 'associate_email' => $associate_email, 'issue_id' => $issue_id, 'customer_id' => @$customer_id, 'type' => $type, 'parent_id' => $parent_id); }
/** * Checks to make sure In-Reply-To and References headers are correct. * */ public static function rewriteThreadingHeaders($issue_id, $full_email, $headers, $type = 'email') { list($text_headers, $body) = Mime_Helper::splitHeaderBody($full_email); $msg_id = self::getMessageID($text_headers, $body); // check if the In-Reply-To header exists and if so, does it relate to a message stored in Eventum // if it does not, set new In-Reply-To header $reference_msg_id = self::getReferenceMessageID($text_headers); $reference_issue_id = false; if (!empty($reference_msg_id)) { // check if referenced msg id is associated with this issue if ($type == 'note') { $reference_issue_id = Note::getIssueByMessageID($reference_msg_id); } else { $reference_issue_id = Support::getIssueByMessageID($reference_msg_id); } } if (empty($reference_msg_id) || $reference_issue_id != $issue_id) { $reference_msg_id = Issue::getRootMessageID($issue_id); } $references = self::getReferences($issue_id, $reference_msg_id, $type); // now the fun part, re-writing the email headers if (empty($headers['message-id'])) { // add Message-ID since it doesn't exist (curses on Outlook 2003) $text_headers .= "\r\nMessage-ID: {$msg_id}"; $headers['message-id'] = $msg_id; } if (preg_match('/^In-Reply-To: (.*)/mi', $text_headers) > 0) { // replace existing header $text_headers = preg_replace('/^In-Reply-To: (.*)/mi', 'In-Reply-To: ' . $reference_msg_id, $text_headers, 1); } else { // add new header after message ID $text_headers = preg_replace('/^Message-ID: (.*)$/mi', "Message-ID: \$1\r\nIn-Reply-To: {$reference_msg_id}", $text_headers, 1); } $headers['in-reply-to'] = $reference_msg_id; if (preg_match('/^References: (.*)/mi', $text_headers) > 0) { // replace existing header $text_headers = preg_replace('/^References: (.*)/mi', 'References: ' . self::fold(implode(' ', $references)), $text_headers, 1); } else { // add new header after In-Reply-To $text_headers = preg_replace('/^In-Reply-To: (.*)$/mi', "In-Reply-To: \$1\r\nReferences: " . self::fold(implode(' ', $references)), $text_headers, 1); } $headers['references'] = self::fold(implode(' ', $references)); return array($text_headers . "\r\n\r\n" . $body, $headers); }