Example #1
0
 function processEmail()
 {
     $data = $this->getEmailRequest();
     if ($data['ticketId'] && ($ticket = Ticket::lookup($data['ticketId']))) {
         if ($msgid = $ticket->postMessage($data, 'Email')) {
             return $ticket;
         }
     }
     if (($thread = ThreadEntry::lookupByEmailHeaders($data)) && $thread->postEmail($data)) {
         return $thread->getTicket();
     }
     return $this->createTicket($data);
 }
Example #2
0
 function createTicket($mid)
 {
     global $ost;
     if (!($mailinfo = $this->getHeaderInfo($mid))) {
         return false;
     }
     // TODO: If the content-type of the message is 'message/rfc822',
     // then this is a message with the forwarded message as the
     // attachment. Download the body and pass it along to the mail
     // parsing engine.
     $info = Mail_Parse::splitHeaders($mailinfo['header']);
     if (strtolower($info['Content-Type']) == 'message/rfc822') {
         if ($wrapped = $this->getPart($mid, 'message/rfc822')) {
             require_once INCLUDE_DIR . 'api.tickets.php';
             // Simulate piping the contents into the system
             $api = new TicketApiController();
             $parser = new EmailDataParser();
             if ($data = $parser->parse($wrapped)) {
                 return $api->processEmail($data);
             }
         }
         // If any of this fails, create the ticket as usual
     }
     //Is the email address banned?
     if ($mailinfo['email'] && TicketFilter::isBanned($mailinfo['email'])) {
         //We need to let admin know...
         $ost->logWarning(_S('Ticket denied'), sprintf(_S('Banned email — %s'), $mailinfo['email']), false);
         return true;
         //Report success (moved or delete)
     }
     // Parse MS TNEF emails
     if (($struct = imap_fetchstructure($this->mbox, $mid)) && ($attachments = $this->getAttachments($struct))) {
         foreach ($attachments as $i => $info) {
             if (0 === strcasecmp('application/ms-tnef', $info['type'])) {
                 try {
                     $data = $this->decode(imap_fetchbody($this->mbox, $mid, $info['index']), $info['encoding']);
                     $tnef = new TnefStreamParser($data);
                     $this->tnef = $tnef->getMessage();
                     // No longer considered an attachment
                     unset($attachments[$i]);
                     // There should only be one of these
                     break;
                 } catch (TnefException $ex) {
                     // Noop -- winmail.dat remains an attachment
                 }
             }
         }
     }
     $vars = $mailinfo;
     $vars['name'] = $mailinfo['name'];
     $vars['subject'] = $mailinfo['subject'] ?: '[No Subject]';
     $vars['emailId'] = $mailinfo['emailId'] ?: $this->getEmailId();
     $vars['to-email-id'] = $mailinfo['emailId'] ?: 0;
     $vars['flags'] = new ArrayObject();
     if ($this->isBounceNotice($mid)) {
         // Fetch the original References and assign to 'references'
         if ($headers = $this->getOriginalMessageHeaders($mid)) {
             $vars['references'] = $headers['references'];
             $vars['in-reply-to'] = @$headers['in-reply-to'] ?: null;
         }
         // Fetch deliver status report
         $vars['message'] = $this->getDeliveryStatusMessage($mid) ?: $this->getBody($mid);
         $vars['thread-type'] = 'N';
         $vars['flags']['bounce'] = true;
     } else {
         $vars['message'] = $this->getBody($mid);
         $vars['flags']['bounce'] = TicketFilter::isBounce($info);
     }
     //Missing FROM name  - use email address.
     if (!$vars['name']) {
         list($vars['name']) = explode('@', $vars['email']);
     }
     if ($ost->getConfig()->useEmailPriority()) {
         $vars['priorityId'] = $this->getPriority($mid);
     }
     $ticket = null;
     $newticket = true;
     $errors = array();
     $seen = false;
     // Use the settings on the thread entry on the ticket details
     // form to validate the attachments in the email
     $tform = TicketForm::objects()->one()->getForm();
     $messageField = $tform->getField('message');
     $fileField = $messageField->getWidget()->getAttachments();
     // Fetch attachments if any.
     if ($messageField->isAttachmentsEnabled()) {
         // Include TNEF attachments in the attachments list
         if ($this->tnef) {
             foreach ($this->tnef->attachments as $at) {
                 $attachments[] = array('cid' => @$at->AttachContentId ?: false, 'data' => $at, 'size' => @$at->DataSize ?: null, 'type' => @$at->AttachMimeTag ?: false, 'name' => $at->getName());
             }
         }
         $vars['attachments'] = array();
         foreach ($attachments as $a) {
             $file = array('name' => $a['name'], 'type' => $a['type']);
             if (@$a['data'] instanceof TnefAttachment) {
                 $file['data'] = $a['data']->getData();
             } else {
                 // only fetch the body if necessary
                 $self = $this;
                 $file['data'] = function () use($self, $mid, $a) {
                     return $self->decode(imap_fetchbody($self->mbox, $mid, $a['index']), $a['encoding']);
                 };
             }
             // Include the Content-Id if specified (for inline images)
             $file['cid'] = isset($a['cid']) ? $a['cid'] : false;
             // Validate and save immediately
             try {
                 $file['id'] = $fileField->uploadAttachment($file);
             } catch (FileUploadError $ex) {
                 $file['error'] = $file['name'] . ': ' . $ex->getMessage();
             }
             $vars['attachments'][] = $file;
         }
     }
     // Allow signal handlers to interact with the message decoding
     Signal::send('mail.processed', $this, $vars);
     $seen = false;
     if (($thread = ThreadEntry::lookupByEmailHeaders($vars, $seen)) && ($t = $thread->getTicket()) && ($vars['staffId'] || !$t->isClosed() || $t->isReopenable()) && ($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;
         }
         // Log an error to the system logs
         $mailbox = Email::lookup($vars['emailId']);
         $ost->logError(_S('Mail Processing Exception'), sprintf(_S("Mailbox: %s | Error(s): %s"), $mailbox->getEmail(), print_r($errors, true)), false);
         // Indicate failure of mail processing
         return null;
     }
     return $ticket;
 }
Example #3
0
<?php
    $threadContent = "";
    if(isset($_REQUEST['thread_id'])&&is_numeric($_REQUEST['thread_id']))
    {
        $thread = ThreadEntry::lookup($_REQUEST['thread_id']);
        $threadContent = $thread->getMessage();
    }

?>



<form method="POST" action="/scp/modifyThread.php">
    <?php csrf_token(); ?>
    <input type="hidden" name="ticket_id" value="<?php echo $_REQUEST['ticket_id'];?>">
    <input type="hidden" name="thread_id" value="<?php echo $_REQUEST['thread_id'];?>">
    <label><b>Original Content:</b></label><br><hr>
    <?php echo $threadContent; ?><br><hr>
    <label><b>Input the new content:</b></label>
    <textarea name="thread_content" style="width:100%;height:150px;"></textarea>

    <div id="reply_form_attachments" class="attachments">
    <?php
    print $response_form->getField('attachments')->render();
    ?>
    <input type='submit' value="Save">
</form>
Example #4
0
 function processEmail($data = false)
 {
     if (!$data) {
         $data = $this->getEmailRequest();
     }
     if (($thread = ThreadEntry::lookupByEmailHeaders($data)) && ($t = $thread->getTicket()) && ($data['staffId'] || !$t->isClosed() || $t->isReopenable()) && $thread->postEmail($data)) {
         return $thread->getTicket();
     }
     return $this->createTicket($data);
 }
 function add($vars, &$errors)
 {
     //Check required params.
     if (!$vars || !is_array($vars) || !$vars['ticketId']) {
         $errors['err'] = __('Missing or invalid data');
     } elseif (!$vars['note']) {
         $errors['note'] = __('Note content is required');
     }
     if ($errors) {
         return false;
     }
     //TODO: use array_intersect_key  when we move to php 5 to extract just what we need.
     $vars['type'] = 'N';
     $vars['body'] = $vars['note'];
     return ThreadEntry::add($vars);
 }
Example #6
0
 function postReply($vars, &$errors, $alert = true, $claim = true)
 {
     global $thisstaff, $cfg;
     if (!$vars['poster'] && $thisstaff) {
         $vars['poster'] = $thisstaff;
     }
     if (!$vars['staffId'] && $thisstaff) {
         $vars['staffId'] = $thisstaff->getId();
     }
     if (!$vars['ip_address'] && $_SERVER['REMOTE_ADDR']) {
         $vars['ip_address'] = $_SERVER['REMOTE_ADDR'];
     }
     $attachments = array();
     $response = null;
     if ($vars['emailreply'] == 2 || $vars['emailreply'] == 1) {
         $responseBody = null;
         $finalBody = null;
         $threadIdList = array();
         if (isset($vars['thread_list'])) {
             $threadIdList = explode(",", $vars['thread_list']);
         }
         // $this->logErrors($vars['thread_list']);
         // $this->logErrors(json_encode($threadIdList));
         // if(!($clientThreadEntries = $this->getClientThread()))
         //     return null;
         // foreach ($clientThreadEntries as $clientThreadEntry) {
         //     if(!($response = ThreadEntry::lookup($clientThreadEntry['id'])))
         //         return null;
         if ($response = $this->getThread()->addResponse($vars, $errors)) {
             // $responseBody = $responseBody ."<br>--------------Reply from ".$response->getPoster()."--------------<br>";
             $responseBody = $responseBody . $response->ht['body'];
             if (isset($thisstaff) && $thisstaff->getSignature() && $vars['emailreply'] == 2 && sizeof($threadIdList) > 1) {
                 $responseBody = $responseBody . $thisstaff->getSignature();
             }
             // if($vars['emailreply']==1)
             $finalThreadBody = $response->ht['body'];
             $attachments = array_merge($attachments, $response->getAttachments());
         }
         foreach ($threadIdList as $threadId) {
             if ($threadId != "") {
                 $response = ThreadEntry::lookup(intval($threadId));
                 // return null;
                 if ($response->getType() == 'M') {
                     $responseBody = $responseBody . "<br>--------------Message from " . $response->getPoster() . "--------------<br>";
                     if ($response->getUserId() != 0) {
                         if ($user = $response->getUser()) {
                             $responseBody = $responseBody . "<b>Name:</b> " . $user->getFullName() . "<br>";
                             $responseBody = $responseBody . "<b>Email:</b> " . $user->getEmail() . "<br>";
                             if ($user->getPhoneNumber() != "") {
                                 $responseBody = $responseBody . "<b>Phone number:</b> " . $user->getPhoneNumber() . "<br>";
                             }
                         }
                     }
                 } else {
                     $responseBody = $responseBody . "<br>--------------Reply from " . $response->getPoster() . "--------------<br>";
                     if ($response->getStaffId() != 0) {
                         if ($currentThreadStaff = $response->getStaff()) {
                             $responseBody = $responseBody . "<b>Name:</b> " . $currentThreadStaff->getName() . "<br>";
                             $responseBody = $responseBody . "<b>Email:</b> " . $currentThreadStaff->getEmail() . "<br>";
                             // if($currentThreadStaff->getPhoneNumber() != "")
                             //     $responseBody = $responseBody ."<b>Phone number:</b> ".$currentThreadStaff->getPhoneNumber()."<br>";
                         }
                     }
                 }
                 $responseBody = $responseBody . $response->ht['body'];
                 $responseBody = $responseBody . "<br><br>";
                 $finalThreadBody = $response->ht['body'];
                 $attachments = array_merge($attachments, $response->getAttachments());
             }
         }
         $response->setBody(ThreadBody::fromFormattedText($responseBody, $response->ht['format']));
         $response->reload();
         if (!$this->postReplyFromThread($vars, $errors, $alert = true, $claim = true, $response, $attachments)) {
             return null;
         }
         $response->setBody(ThreadBody::fromFormattedText($finalThreadBody, $response->ht['format']));
         $response->reload();
     } else {
         if (!($response = $this->getThread()->addResponse($vars, $errors))) {
             return null;
         }
         if (!$this->postReplyFromThread($vars, $errors, $alert = true, $claim = true, $response, $attachments)) {
             return null;
         }
     }
     return $response;
 }
Example #7
0
<?php
require('staff.inc.php');
require_once(INCLUDE_DIR.'class.attachment.php');
require_once(INCLUDE_DIR.'class.thread.php');

error_reporting(~0); ini_set('display_errors', 1);
echo "1111";
if(!isset($_REQUEST['thread_id']))
{
	echo ("Thread ID not provided");
}
elseif(is_numeric($_REQUEST['thread_id'])&&($thread = ThreadEntry::lookup($_REQUEST['thread_id'])))
{
    foreach ($_REQUEST['attach:response'] as $fileID) {
    	$thread->saveAttachment($fileID);
    }
	header("Location: /scp/tickets.php?id=".$_REQUEST['ticket_id']);
}
if($_REQUEST['thread_content']!=null&&$_REQUEST['thread_content']!=""&&$thread->setBody(nl2br($_REQUEST['thread_content'])))
{
	$thread->reload();
	header("Location: /scp/tickets.php?id=".$_REQUEST['ticket_id']);
}


?>
Example #8
0
 function processEmail($data = false)
 {
     if (!$data) {
         $data = $this->getEmailRequest();
     }
     if (($thread = ThreadEntry::lookupByEmailHeaders($data)) && $thread->postEmail($data)) {
         return $thread->getTicket();
     }
     return $this->createTicket($data);
 }
 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;
 }