$var = array(); $deptId = 0; $name = trim($from->personal, '"'); if ($from->comment && $from->comment[0]) { $name .= ' (' . $from->comment[0] . ')'; } $subj = utf8_encode($parser->getSubject()); if (!($body = Format::stripEmptyLines($parser->getBody())) && $subj) { $body = $subj; } $var['mid'] = $parser->getMessageId(); $var['email'] = $from->mailbox . '@' . $from->host; $var['name'] = $name ? utf8_encode($name) : $var['email']; $var['emailId'] = $emailId ? $emailId : $cfg->getDefaultEmailId(); $var['subject'] = $subj ? $subj : '[No Subject]'; $var['message'] = utf8_encode(Format::stripEmptyLines($body)); $var['header'] = $parser->getHeader(); $var['priorityId'] = $cfg->useEmailPriority() ? $parser->getPriority() : 0; $ticket = null; if (preg_match("[[#][0-9]{1,10}]", $var['subject'], $regs)) { $extid = trim(preg_replace("/[^0-9]/", "", $regs[0])); $ticket = new Ticket(Ticket::getIdByExtId($extid)); //Allow mismatched emails?? For now hell NO. if (!is_object($ticket) || strcasecmp($ticket->getEmail(), $var['email'])) { $ticket = null; } } $errors = array(); $msgid = 0; if (!$ticket) { //New tickets...
function createTicket($mid) { global $ost; if (!($mailinfo = $this->getHeaderInfo($mid))) { return false; } //Make sure the email is NOT already fetched... (undeleted emails) if ($mailinfo['mid'] && ($id = Ticket::getIdByMessageId(trim($mailinfo['mid']), $mailinfo['email']))) { return true; } //Reporting success so the email can be moved or deleted. //Is the email address banned? if ($mailinfo['email'] && EmailFilter::isBanned($mailinfo['email'])) { //We need to let admin know... $ost->logWarning('Ticket denied', 'Banned email - ' . $mailinfo['email']); return true; //Report success (moved or delete) } $emailId = $this->getEmailId(); $var['name'] = $this->mime_decode($mailinfo['name']); $var['email'] = $mailinfo['email']; $var['subject'] = $mailinfo['subject'] ? $this->mime_decode($mailinfo['subject']) : '[No Subject]'; $var['message'] = Format::stripEmptyLines($this->getBody($mid)); $var['header'] = $this->getHeader($mid); $var['emailId'] = $emailId ? $emailId : $ost->getConfig()->getDefaultEmailId(); //ok to default? $var['name'] = $var['name'] ? $var['name'] : $var['email']; //No name? use email $var['mid'] = $mailinfo['mid']; if (!$var['message']) { //An email with just attachments can have empty body. $var['message'] = '(EMPTY)'; } if ($ost->getConfig()->useEmailPriority()) { $var['priorityId'] = $this->getPriority($mid); } $ticket = null; $newticket = true; //Check the subject line for possible ID. if ($var['subject'] && preg_match("[[#][0-9]{1,10}]", $var['subject'], $regs)) { $tid = trim(preg_replace("/[^0-9]/", "", $regs[0])); //Allow mismatched emails?? For now NO. if (!($ticket = Ticket::lookupByExtId($tid)) || strcasecmp($ticket->getEmail(), $var['email'])) { $ticket = null; } } $errors = array(); if ($ticket) { if (!($msgid = $ticket->postMessage($var['message'], 'Email', $var['mid'], $var['header']))) { return false; } } elseif ($ticket = Ticket::create($var, $errors, 'Email')) { $msgid = $ticket->getLastMsgId(); } else { //TODO: Log error.. return null; } //Save attachments if any. if ($msgid && $ost->getConfig()->allowEmailAttachments() && ($struct = imap_fetchstructure($this->mbox, $mid)) && $struct->parts && ($attachments = $this->getAttachments($struct))) { //We're just checking the type of file - not size or number of attachments... // Restrictions are mainly due to PHP file uploads limitations foreach ($attachments as $a) { if ($ost->isFileTypeAllowed($a['name'], $a['mime'])) { $file = array('name' => $a['name'], 'type' => $a['mime'], 'data' => $this->decode($a['encoding'], imap_fetchbody($this->mbox, $mid, $a['index']))); $ticket->saveAttachment($file, $msgid, 'M'); } else { //This should be really a comment on message - NoT an internal note. //TODO: support comments on Messages and Responses. $error = sprintf('Attachment %s [%s] rejected because of file type', $a['name'], $a['mime']); $ticket->postNote('Email Attachment Rejected', $error, false); $ost->logDebug('Email Attachment Rejected (Ticket #' . $ticket->getExtId() . ')', $error); } } } return $ticket; }
function createTicket($mid,$emailid=0){ global $cfg; $mailinfo=$this->getHeaderInfo($mid); //Make sure the email is NOT one of the undeleted emails. if($mailinfo['mid'] && ($id=Ticket::getIdByMessageId(trim($mailinfo['mid']),$mailinfo['from']['email']))){ //TODO: Move emails to a fetched folder when delete is false?? return false; } $var['name']=$this->mime_decode($mailinfo['from']['name']); $var['email']=$mailinfo['from']['email']; $var['subject']=$mailinfo['subject']?$this->mime_decode($mailinfo['subject']):'[No Subject]'; $var['message']=Format::stripEmptyLines($this->getBody($mid)); $var['header']=$this->getHeader($mid); $var['emailId']=$emailid?$emailid:$cfg->getDefaultEmailId(); //ok to default? $var['name']=$var['name']?$var['name']:$var['email']; //No name? use email $var['mid']=$mailinfo['mid']; if($cfg->useEmailPriority()) $var['pri']=$this->getPriority($mid); $ticket=null; $newticket=true; //Check the subject line for possible ID. if(preg_match ("[[#][0-9]{1,10}]",$var['subject'],$regs)) { $extid=trim(preg_replace("/[^0-9]/", "", $regs[0])); $ticket= new Ticket(Ticket::getIdByExtId($extid)); //Allow mismatched emails?? For now NO. if(!$ticket || strcasecmp($ticket->getEmail(),$var['email'])) $ticket=null; } $errors=array(); if(!$ticket) { if(!($ticket=Ticket::create($var,$errors,'Email')) || $errors) return null; $msgid=$ticket->getLastMsgId(); }else{ $message=$var['message']; //Strip quoted reply...TODO: figure out how mail clients do it without special tag.. if($cfg->stripQuotedReply() && ($tag=$cfg->getReplySeparator()) && strpos($var['message'],$tag)) list($message)=split($tag,$var['message']); $msgid=$ticket->postMessage($message,'Email',$var['mid'],$var['header']); } //Save attachments if any. if($msgid && $cfg->allowEmailAttachments()){ if(($struct = imap_fetchstructure($this->mbox,$mid)) && $struct->parts) { if($ticket->getLastMsgId()!=$msgid) $ticket->setLastMsgId($msgid); $this->saveAttachments($ticket,$mid,$struct); } } return $ticket; }
$var = array(); $deptId = 0; $name = trim($from->personal, '"'); if ($from->comment && $from->comment[0]) { $name .= ' (' . $from->comment[0] . ')'; } $subj = mb_convert_encoding($parser->getSubject(), "UTF-8"); if (!($body = Format::stripEmptyLines($parser->getBody())) && $subj) { $body = $subj; } $var['mid'] = $parser->getMessageId(); $var['email'] = $from->mailbox . '@' . $from->host; $var['name'] = $name ? mb_convert_encoding($name, "UTF-8") : $var['email']; $var['emailId'] = $emailId ? $emailId : $cfg->getDefaultEmailId(); $var['subject'] = $subj ? $subj : '[No Subject]'; $var['message'] = mb_convert_encoding(Format::stripEmptyLines($body), "UTF-8"); $var['header'] = $parser->getHeader(); $var['pri'] = $cfg->useEmailPriority() ? $parser->getPriority() : 0; $ticket = null; if (preg_match("[[#][0-9]{1,10}]", $var['subject'], $regs)) { $extid = trim(preg_replace("/[^0-9]/", "", $regs[0])); $ticket = new Ticket(Ticket::getIdByExtId($extid)); //Allow mismatched emails?? For now hell NO. if (!is_object($ticket) || strcasecmp($ticket->getEmail(), $var['email'])) { $ticket = null; } } $errors = array(); $msgid = 0; if (!$ticket) { //New tickets...
if ($emailId = Email::getIdByEmail($ccaddr->mailbox . '@' . $ccaddr->host)) { break; } } } //TODO: Options to reject emails without a matching To address in db? May be it was Bcc? Current Policy: If you pipe, we accept policy require_once INCLUDE_DIR . 'class.ticket.php'; //We now need this bad boy! $var = array(); $name = trim($fromlist[0]->personal, '"'); $subj = $parser->getSubject(); $var['email'] = $fromlist[0]->mailbox . '@' . $fromlist[0]->host; $var['name'] = $name ? $name : $var['email']; $var['emailId'] = $emailId ? $emailId : $cfg->getDefaultEmailId(); $var['subject'] = $subj ? $subj : '[No Subject]'; $var['message'] = Format::stripEmptyLines($parser->getBody()); $var['header'] = $cfg->saveEmailHeaders() ? $parser->getHeader() : ''; //TODO: Finish $var['pri'] = $cfg->useEmailPriority() ? $parser->getPriority() : 0; $ticlet = null; if (ereg("[[][#][0-9]{1,10}[]]", $var['subject'], $regs)) { $extid = trim(preg_replace("/[^0-9]/", "", $regs[0])); $ticket = new Ticket(Ticket::getIdByExtId($extid)); //Allow mismatched emails?? For now hell NO. if (!is_object($ticket) || strcasecmp($ticket->getEmail(), $var['email'])) { $ticket = null; } } $errors = array(); $msgid = 0; if (!$ticket) {
function getClean() { return Format::stripEmptyLines($this->body); }
function createTicket($mid) { global $ost; if (!($mailinfo = $this->getHeaderInfo($mid))) { return false; } //Is the email address banned? if ($mailinfo['email'] && TicketFilter::isBanned($mailinfo['email'])) { //We need to let admin know... $ost->logWarning('Ticket denied', 'Banned email - ' . $mailinfo['email'], false); return true; //Report success (moved or delete) } $vars = $mailinfo; $vars['name'] = $this->mime_decode($mailinfo['name']); $vars['subject'] = $mailinfo['subject'] ? $this->mime_decode($mailinfo['subject']) : '[No Subject]'; $vars['message'] = Format::stripEmptyLines($this->getBody($mid)); $vars['emailId'] = $mailinfo['emailId'] ? $mailinfo['emailId'] : $this->getEmailId(); //Missing FROM name - use email address. if (!$vars['name']) { $vars['name'] = $vars['email']; } //An email with just attachments can have empty body. if (!$vars['message']) { $vars['message'] = '-'; } if ($ost->getConfig()->useEmailPriority()) { $vars['priorityId'] = $this->getPriority($mid); } $ticket = null; $newticket = true; $errors = array(); $seen = false; if (($thread = ThreadEntry::lookupByEmailHeaders($vars, $seen)) && ($message = $thread->postEmail($vars))) { if (!$message instanceof ThreadEntry) { // Email has been processed previously return $message; } $ticket = $message->getTicket(); } elseif ($seen) { // Already processed, but for some reason (like rejection), no // thread item was created. Ignore the email return true; } elseif ($ticket = Ticket::create($vars, $errors, 'Email')) { $message = $ticket->getLastMessage(); } else { //Report success if the email was absolutely rejected. if (isset($errors['errno']) && $errors['errno'] == 403) { // Never process this email again! ThreadEntry::logEmailHeaders(0, $vars['mid']); return true; } # check if it's a bounce! if ($vars['header'] && TicketFilter::isAutoBounce($vars['header'])) { $ost->logWarning('Bounced email', $vars['message'], false); return true; } //TODO: Log error.. return null; } //Save attachments if any. if ($message && $ost->getConfig()->allowEmailAttachments() && ($struct = imap_fetchstructure($this->mbox, $mid)) && ($attachments = $this->getAttachments($struct))) { foreach ($attachments as $a) { $file = array('name' => $a['name'], 'type' => $a['type']); //Check the file type if (!$ost->isFileTypeAllowed($file)) { $file['error'] = 'Invalid file type (ext) for ' . Format::htmlchars($file['name']); } else { //only fetch the body if necessary TODO: Make it a callback. $file['data'] = $this->decode(imap_fetchbody($this->mbox, $mid, $a['index']), $a['encoding']); } $message->importAttachment($file); } } return $ticket; }
function parse($stream) { global $cfg; $contents = ''; if (is_resource($stream)) { while (!feof($stream)) { $contents .= fread($stream, 8192); } } else { $contents = $stream; } $parser = new Mail_Parse($contents); if (!$parser->decode()) { //Decode...returns false on decoding errors return $this->err('Email parse failed [' . $parser->getError() . ']'); } $data = array(); //FROM address: who sent the email. if (($fromlist = $parser->getFromAddressList()) && !PEAR::isError($fromlist)) { $from = $fromlist[0]; //Default. foreach ($fromlist as $fromobj) { if (!Validator::is_email($fromobj->mailbox . '@' . $fromobj->host)) { continue; } $from = $fromobj; break; } $data['email'] = $from->mailbox . '@' . $from->host; $data['name'] = trim($from->personal, '"'); if ($from->comment && $from->comment[0]) { $data['name'] .= ' (' . $from->comment[0] . ')'; } //Use email address as name when FROM address doesn't have a name. if (!$data['name'] && $data['email']) { $data['name'] = $data['email']; } } //TO Address:Try to figure out the email address... associated with the incoming email. $emailId = 0; if ($tolist = $parser->getToAddressList()) { foreach ($tolist as $toaddr) { if ($emailId = Email::getIdByEmail($toaddr->mailbox . '@' . $toaddr->host)) { break; } } } //maybe we got CC'ed?? if (!$emailId && ($cclist = $parser->getCcAddressList())) { foreach ($cclist as $ccaddr) { if ($emailId = Email::getIdByEmail($ccaddr->mailbox . '@' . $ccaddr->host)) { break; } } } $data['subject'] = $parser->getSubject(); $data['message'] = Format::stripEmptyLines($parser->getBody()); $data['header'] = $parser->getHeader(); $data['mid'] = $parser->getMessageId(); $data['priorityId'] = $parser->getPriority(); $data['emailId'] = $emailId; $data['in-reply-to'] = $parser->struct->headers['in-reply-to']; $data['references'] = $parser->struct->headers['references']; if (($replyto = $parser->getReplyTo()) && !PEAR::isError($replyto)) { $replyto = $replyto[0]; $data['reply-to'] = $replyto->mailbox . '@' . $replyto->host; if ($replyto->personal) { $data['reply-to-name'] = trim($replyto->personal, " \t\n\r\v\""); } } if ($cfg && $cfg->allowEmailAttachments()) { $data['attachments'] = $parser->getAttachments(); } return $data; }