<?php

/**
* @package Clientexec
*/
class SupportPipe extends NE_Model
{
    var $email;
    
    function SupportPipe()
    {
        parent::NE_Model();
    }
    
    function setEmail($email)
    {
        $this->email = $email;
    }
    
    function setEmailFromStdIn()
    {
        // read from stdin
        $fd = fopen("php://stdin", "r");
        $this->email = "";
        while (!feof($fd)) {
            $this->email .= fread($fd, 1024);
        }
        fclose($fd);
    }
    
    /**
     * this function returns an array containing all the admins of the requestid type
     * the array had the admin name as the key, and the email as the value
     * @param String $type the users.groupid you would like to retreive
     * @return array $admins
     */
    function getAllAdminOfType($type)
    {
        // Get the list of admins to display
        $query = "SELECT firstname, lastname, email FROM users WHERE groupid = ?";
        $result = $this->db->query($query,$type);
    
        while($tAdminData = $result->fetch()) {
            $admins[$tAdminData['firstname']." ".$tAdminData['lastname']] = $tAdminData['email'];
        }
    
        return $admins;
    }
    
    /**
     * this function is for retrieving the userid of a client based on the email
     * @param String $tUserEmail  the email address of the user
     * @return String $userId the userid of the user
     */
    function getUserIdForEmail($tUserEmail)
    {
        $query = "SELECT id FROM customuserfields WHERE type=".typeEMAIL;
        $result = $this->db->query($query);
        list($fieldId) = $result->fetch();
        if (!$fieldId) {
            return false;
        }
    
        $query = "SELECT userid FROM user_customuserfields WHERE customid=$fieldId AND value=?";
        $result = $this->db->query($query, $tUserEmail);
        list($userId) = $result->fetch();
        if ($userId) {
            return $userId;
        }
    
        $query = "SELECT userid FROM altuseremail WHERE email=? AND support=1";
        $result = $this->db->query($query, $tUserEmail);
        list($userId) = $result->fetch();
        if (!$userId) {
            return false;
        }
        return $userId;
    }
    
    function runPipe()
    {
        require_once 'classes/troubletickets.php';
        require_once 'classes/troubleticket.php';
        require_once 'classes/emailparser.php';
        require_once 'classes/TicketGateway.php';
        require_once 'classes/MailGateway.php';
        require_once 'classes/emailparser.php';
        
        if (!$this->settings->get('Email Piping In Use')) {
            $sql = "UPDATE `setting` SET value=1 WHERE name='Email Piping In Use'";
            $result = $this->db->query($sql);
        }
    
        // do not change
        $supportdir = dirname(__FILE__) . '/../uploads/support/';
    
        $ep = new EmailParser($this->email);
        $ep->parse();
        $from = $ep->getFrom();
        $subject = $ep->getSubject();
        $message = $ep->getMessage();
        $numAttachments = $ep->getNumAttachments();
        $validExtensions = explode(',',$this->settings->get('Allowed File Extensions'));
        
        // Quit if we've entered an autoresponder loop
        $this->logger->log(2, "Processing e-mail from $from");
        if (!$this->checkAutoresponder($from)) {
            $this->logger->log(2, "Discard incoming e-mail: we've entered an autoresponder loop");
            exit;
        }
    
        //ok, now we have the message and the subject, let's get the userid
        $userId = $this->getUserIdForEmail($from);
    
        //should be everything we need to submit a ticket. let's populate the post
        $_POST['userid'] = $userId;
        $_POST['subject'] = $subject;
        $mailGateway = new MailGateway();
        if ($userId != "" || ($this->settings->get('Allow Admins To Reply From Any E-mail Account') && preg_match("/.*\[ce-\d+-tech\]/", $subject))) {
            $tUser = new User($userId);
            if ($userId) {
                $tUser->PopulateCustomFields();
            }
            //see if this is a response to an existing ticket
            if (preg_match("/.*\[ce-(\d+).*\]/", $subject, $matchid)) {
                $responseId = $matchid[1];
                $remove = array('subject');
                $sendAssignedTo = true;
    
                $cTicket = new TroubleTicket($tUser, $responseId);
                $cTicket->SetStatus('1');
                $cTicket->SetLastLogDateTime(date('Y-m-d H-i-s'));
                $cTicket->Update();
                $fileattach = array();
                $filename = array();
                if ($numAttachments > 0 && is_writable($supportdir) && $this->settings->get('Allow Customer File Uploads')) {
                    for ($i = 0; $i < $numAttachments; $i++) {
                        $attachment = $ep->getAttachment($i);
                        $filekey = $cTicket->generateFileKey();
                        if (($pos = strrpos($attachment['name'], '.')) !== false) {
                            $len = strlen($attachment['name']) - ($pos+1);
                            $ext = substr($attachment['name'], -$len);
                        }
                        if (in_array($ext, $validExtensions) || in_array('*',$validExtensions)) {
                            $fp = @fopen($supportdir.$filekey, "w");
                            fwrite($fp, $attachment['string']);
                            fclose($fp);
                            chmod($supportdir.$filekey, 0666);
                            $cTicket->addFile($attachment['name'],$filekey,$userId);
                            $message = "** File Attached: ".$attachment['name']." **\n\n".$message;
                            $fileattach[] = $attachment['string'];
                            $filename[] = $attachment['name'];
                        }
                    }
                }
                $cTicketLog = new TroubleTicketLog($tUser);
                $cTicketLog->populated = true;
                $cTicketLog->setUserID($userId);
                $cTicketLog->setTroubleTicketID($responseId);
                $cTicketLog->setMessage($message);
                $cTicketLog->SetDateTime(date('Y-m-d H-i-s'));
                $cTicketLog->setLogAction(0);
                $cTicketLog->setExternalEmail(1);
                $cTicketLog->insert();

                if ($tUser->GetGroupID() == 1 && $userId != 0) {
                    $fullName = $tUser->getFullName();
                    //Get all the emails I need to send out an email for (emails in settings->admin->support->email for new templates
                    $strMessage = "Dear Support Member,\n\nThere has been an update to ticket #$responseId by $fullName\n\nMessage: $message";
                    if ($this->settings->get('E-mail For New Trouble Tickets') != "") {
                        $aSupportEmail = explode(",", $this->settings->get('E-mail For New Trouble Tickets'));
                                                    //Create Assigned Admin
                                                    $tAssignedAdmin =& new User($cTicket->GetAssignedToID());
                                                    $tAssignedAdmin->PopulateCustomFields();
    
                            foreach ($aSupportEmail as $email)
                            {
                                $email = trim($email);
                                if($email == $this->settings->get('Support E-mail')){
                                    //we can not notify the support email as this will result in an endless loop
                                    //try to notify the admin of this problem
                                    $strMessage = "Dear Admin, \n\n There is a problem in the helpdesk configuration. \n";
                                    $strMessage .= " The \'Support E-mail\' setting is the same email address as the \'E-mail For New Trouble Tickets\' setting\n";
                                    $strMessage .= " This configuration can result in and endless pipe loop.  Please go to admin -> settings -> supprt and make sure these values are not the same address";
                                    $adminEmail = "greg@cclhosting.com"; //find out how to get the admin email list
                                    $mailGateway->mailMessageEmail( $strMessage,
                                                                    $this->settings->get('Support E-mail'),
                                                                    $this->settings->get('Support E-mail'),
                                                                    $adminEmail,
                                                                    '',
                                                                    "Helpdesk Misconfiguration");
                                }
    
                                else if ($email!="") {
                                    $mailGateway->mailMessageEmail( $strMessage,
                                                                    $this->settings->get('Support E-mail'),
                                                                    $this->settings->get('Support E-mail'),
                                                                    $email,
                                                                    '',
                                                                    "[ce-{$responseId}-tech] Support ticket has been updated",
                                                                    3,
                                                                    0,
                                                                    $fileattach,
                                                                    $filename);
                                }
                                                            //Check to see if the assigned to email is the same
                                                            //If it is then set $sendassignedto to false since email
                                                            //has already been sent out to them
                                                            if (trim($tAssignedAdmin->getEmail())==trim($email)) $sendAssignedTo = false;
                            }
                    }
                    //also notify admin assigned to ticket
                    if (($cTicket->GetAssignedToID()!=0)&&($sendAssignedTo)) {
                        $mailGateway->mailMessage(  $strMessage,
                                                    $this->settings->get('Support E-mail'),
                                                    $this->settings->get('Support E-mail'),
                                                    $cTicket->GetAssignedToID(),
                                                    '',
                                                    "[ce-{$responseId}-tech] Support ticket has been updated",
                                                    3,
                                                    0,
                                                    'notifications',
                                                    $fileattach,
                                                    $filename,
                                                    MAILGATEWAY_CONTENTTYPE_PLAINTEXT);
                    }
                } else {
                    // notify client of admin reply
                    $tClient =& new User($cTicket->GetUserID());
                    $tClient->PopulateCustomFields();
                    /* replace tags */
                    $strEmailArr = $this->settings->get('Trouble Ticket Template');
                    if ($tClient->isHTMLMails()) {
                        $strEmailString = $strEmailArr['HTML'];
                        $contentType = MAILGATEWAY_CONTENTTYPE_HTML;
                    } else {
                        $strEmailString = $strEmailArr['plainText'];
                        $contentType = MAILGATEWAY_CONTENTTYPE_PLAINTEXT;
                    }

                    $strEmailString = str_replace("[COMPANYNAME]", $this->settings->get("Company Name"), $strEmailString);
                    $strEmailString = str_replace("[CLIENTNAME]", $tClient->getFullName(), $strEmailString);
                    $strEmailString = str_replace("[CLIENTEMAIL]", $tClient->getEmail(), $strEmailString);
                    $strEmailString = str_replace("[CLIENTAPPLICATIONURL]", $this->settings->get("ClientExec URL"), $strEmailString);
                    $strEmailString = str_replace("[DESCRIPTION]", $tClient->isHTMLMails()? nl2br($message) : $message, $strEmailString);
                    $strEmailString = str_replace("[TICKETNUMBER]", $responseId, $strEmailString);
                    $strEmailString = NE_Lib::replaceCustomFields($this->db,$strEmailString,$cTicket->GetUserID(), $this->settings->get('Date Format'));
                    
                    $strSubjectEmailString = "[ce-$responseId] " . $this->settings->get('Trouble Ticket Subject Template');
                    $strSubjectEmailString = str_replace("[COMPANYNAME]", $this->settings->get("Company Name"), $strSubjectEmailString);
                    $strSubjectEmailString = str_replace("[CLIENTNAME]", $tClient->getFullName(), $strSubjectEmailString);
                    $strSubjectEmailString = str_replace("[CLIENTEMAIL]", $tClient->getEmail(), $strSubjectEmailString);
                    $strSubjectEmailString = str_replace("[CLIENTAPPLICATIONURL]", $this->settings->get("ClientExec URL"), $strSubjectEmailString);
                    $strSubjectEmailString = str_replace("[DESCRIPTION]", $message, $strSubjectEmailString);
                    $strSubjectEmailString = str_replace("[TICKETNUMBER]", $responseId, $strSubjectEmailString);
    
                    if (@$this->settings->get('Email Piping In Use')) {
                        /* Add reply above this line */
                        $strEmailString = "+----------- Please reply above this line -----------+".
                        ($tClient->isHTMLMails()? "<br>" : "\n").$strEmailString;
                    }
    
                    $mailGateway->mailMessage(  $strEmailString,
                                                $this->settings->get('Support E-mail'),
                                                $this->settings->get('Support E-mail'),
                                                $cTicket->GetUserID(),
                                                '',
                                                $strSubjectEmailString,
                                                3,
                                                0,
                                                'notifications',
                                                $fileattach,
                                                $filename,
                                                $contentType);
                   
                }
            } else {
                if (!$userId || $tUser->isAdmin()) {
                    // Admins can't create tickets through piping!
                    return;
                }
                //ce ticket code
                $tTimeStamp = date('Y-m-d H-i-s');
                $cTicket = new TroubleTicket($tUser);
                $cTicket->populated = true;
                $cTickets = new TroubleTickets();
                $cTickets->GetAllTickets("id","All",true);
                if ($cTickets->m_TicketCount == 0)
                {
                    $cTickets->GetAllTickets("id","All",false);
                    {   //need to add id to post so that the initial invoice setting is used
                        if ($cTickets->m_TicketCount == 0) {
                        	 $id = $this->settings->get('Trouble Ticket Start Number');
                        	 $cTicket->setID($id);
                        }
                    }
                }
                
                $sql = "SELECT name FROM troubleticket_type ORDER BY myorder DESC LIMIT 1";
                $result = $this->db->query($sql);
                $row = $result->fetch();
    
                $cTicket->setUserId($userId);
                $cTicket->setSubject($subject);
                $cTicket->SetDateSubmitted($tTimeStamp);
                $cTicket->SetLastLogDateTime($tTimeStamp);
                $cTicket->SetMessageType($row['name']);
                $cTicket->SetPriority(3);
                $cTicket->SetStatus(2);
                $cTicket->SetAssignedToID(0);
                $newticket = $cTicket->insert();
                $ccTicket = new TroubleTicket($tUser, $newticket);
                $filename = array();
                $fileattach = array();
                if ($numAttachments > 0 && is_writable($supportdir) && $this->settings->get('Allow Customer File Uploads')) {
                    for ($i = 0; $i < $numAttachments; $i++) {
                        $attachment = $ep->getAttachment($i);
                        $filekey = $ccTicket->generateFileKey();
                        if (($pos = strrpos($attachment['name'], '.')) !== false) {
                            $len = strlen($attachment['name']) - ($pos+1);
                            $ext = substr($attachment['name'], -$len);
                        }
                        if (in_array($ext, $validExtensions) || in_array('*',$validExtensions)) {
                            $fp = @fopen($supportdir.$filekey, "w");
                            fwrite($fp, $attachment['string']);
                            fclose($fp);
                            chmod($supportdir.$filekey, 0666);
                            $ccTicket->addFile($attachment['name'],$filekey,$userId);
                            $message = "** File Attached: ".$attachment['name']." **\n\n".$message;
                            $fileattach[] = $attachment['string'];
                            $filename[] = $attachment['name'];
                        }
                    }
                }
                $ticketGateway = new TicketGateway();
                $ticketGateway->AddInitialLogForTicketID($newticket,$message,$tTimeStamp,$userId, true);
                
                // Send autoreply to new ticket.
                $strCustomerEmail = $this->settings->get('New Trouble Ticket Autoresponder Template');
                $tValue = 0;
                $tID = NE_Lib::getCustomUserFieldIDForName($this->db, "HTML Email Format");
                $tUser->getCustomFieldsValue($tID,$isHTML);
                if ($isHTML == 1) {
                    $strCustomerEmail = $strCustomerEmail['HTML'];
                } else {
                    $strCustomerEmail = $strCustomerEmail['plainText'];
                }
                $strCustomerEmail = str_replace("[COMPANYNAME]", $this->settings->get("Company Name"), $strCustomerEmail);
                $strCustomerEmail = str_replace("[CLIENTNAME]", $tUser->getFullName(), $strCustomerEmail);
                $strCustomerEmail = str_replace("[CLIENTEMAIL]", $tUser->getEmail(), $strCustomerEmail);
                $strCustomerEmail = str_replace("[CLIENTAPPLICATIONURL]", $this->settings->get("ClientExec URL"), $strCustomerEmail);
                $strCustomerEmail = str_replace("[DESCRIPTION]", $tUser->isHTMLMails()? nl2br($message) :$message, $strCustomerEmail);
                $strCustomerEmail = str_replace("[TICKETNUMBER]", $newticket, $strCustomerEmail);
                $strCustomerEmail = NE_Lib::replaceCustomFields($this->db, $strCustomerEmail,$cTicket->GetUserID(),$this->settings->get('Date Format'));
                
                $strSubjectCustomerEmail = "[ce-$newticket] " . $this->settings->get('New Trouble Ticket Autoresponder Subject Template');
                $strSubjectCustomerEmail = str_replace("[COMPANYNAME]", $this->settings->get("Company Name"), $strSubjectCustomerEmail);
                $strSubjectCustomerEmail = str_replace("[CLIENTNAME]", $tUser->getFullName(), $strSubjectCustomerEmail);
                $strSubjectCustomerEmail = str_replace("[CLIENTEMAIL]", $tUser->getEmail(), $strSubjectCustomerEmail);
                $strSubjectCustomerEmail = str_replace("[CLIENTAPPLICATIONURL]", $this->settings->get("ClientExec URL"), $strSubjectCustomerEmail);
                $strSubjectCustomerEmail = str_replace("[DESCRIPTION]", $message, $strSubjectCustomerEmail);
                $strSubjectCustomerEmail = str_replace("[TICKETNUMBER]", $newticket, $strSubjectCustomerEmail);
                
                $mailGateway->mailMessageEmail( $strCustomerEmail,
                                                $this->settings->get('Support E-mail'),
                                                $this->settings->get('Support E-mail'),
                                                $from,
                                                '',
                                                $strSubjectCustomerEmail,
                                                3,
                                                0,
                                                '',
                                                '',
                                                $isHTML? MAILGATEWAY_CONTENTTYPE_HTML : MAILGATEWAY_CONTENTTYPE_PLAINTEXT);
    
                $strMessage = "Dear Support Member,\n\nTrouble ticket #".$newticket." has been entered by ".$tUser->getFullName()."\nSubject: ".$_POST['subject']."\n\nMessage: ".$message;
    
                //Get all the emails I need to send out an email for
                if ($this->settings->get('E-mail For New Trouble Tickets') != ""){
                    $aSupportEmail = explode(",", $this->settings->get('E-mail For New Trouble Tickets'));
                    foreach ($aSupportEmail as $email)
                    {
                        $email = trim($email);
                        if (@$this->settings->get('Email Piping In Use')) {
                            /* Add reply above this line */
                            $strMessage = "+----------- Please reply above this line -----------+\n".$strMessage;
                        }
                        if($email == $this->settings->get('Support E-mail')){
                                //we can not notify the support email as this will result in an endless loop
                                //try to notify the admin of this problem
                                $admins = $this->getAllAdminOfType('2');
                                foreach($admins as $adminName=>$adminEmail)
                                {
                                    $strMessage = "Dear Admin, \n\n There is a problem in the helpdesk configuration. \n";
                                    $strMessage .= " The \'Support E-mail\' setting is the same email address as the \'E-mail For New Trouble Tickets\' setting\n";
                                    $strMessage .= " This configuration can result in and endless pipe loop.  Please go to admin -> settings -> supprt and make sure these values are not the same address";
                                    $mailGateway->mailMessageEmail( $strMessage,
                                                                    $this->settings->get('Support Email'),
                                                                    $this->settings->get('Support Email'),
                                                                    $adminEmail,
                                                                    '',
                                                                    "Helpdesk Misconfiguration",
                                                                    3,
                                                                    0,
                                                                    $fileattach,
                                                                    $filename);
                                }
                        }
                        else if ($email!="") {
                            $mailGateway->mailMessageEmail( $strMessage,
                                                            $this->settings->get('Support E-mail'),
                                                            $this->settings->get('Support E-mail'),
                                                            $email,
                                                            '',
                                                            "[ce-".$newticket."-tech] A new support ticket has been added",
                                                            3,
                                                            0,
                                                            $fileattach,
                                                            $filename);
                        }
                    }
                }
            }
        }
        //else we could not find this user, let's either bounce the message or forward it to the forward email
        else{
            if($this->settings->get('Alternate Support Address') != "")
            {
                if ($this->settings->get('Alternate Support Address') == $this->settings->get('Support E-mail')) {
                    //we can not notify the support email as this will result in an endless loop
                    //try to notify the admin of this problem
                    $admins = $this->getAllAdminOfType('2');
                    foreach($admins as $adminName=>$adminEmail)
                    {
                        $strMessage = "Dear Admin, \n\n There is a problem in the helpdesk configuration. \n";
                        $strMessage .= " The \'Support E-mail\' setting is the same email address as the \'E-mail For New Trouble Tickets\' setting\n";
                        $strMessage .= " This configuration can result in and endless pipe loop.  Please go to admin -> settings -> support and make sure these values are not the same address";
                        $mailGateway->mailMessageEmail( $strMessage,
                                                        $this->settings->get('Support E-mail'),
                                                        $this->settings->get('Support E-mail'),
                                                        $adminEmail,
                                                        '',
                                                        "Helpdesk Misconfiguration");
                    }
                } else {
                    $filename = array();
                    $fileattach = array();
                    for ($i = 0; $i < $numAttachments; $i++) {
                        $attachment = $ep->getAttachment($i);
                        $fileattach[] = $attachment['string'];
                        $filename[] = $attachment['name'];
                    }
                    $strSubject = "[Unknown helpdesk user] $subject";
                    $strMessage = "The following email was sent to: ".$this->settings->get('Support E-mail')."\n";
                    $strMessage .= "From:  ".$from."\n";
                    $strMessage .= "Subject:  ".$subject."\n";
                    $strMessage .= "The email could not be piped to the helpdesk because a user with that email address could not be found.\n\n";
                    $strMessage .= "A copy of the message is below: \n\n\n\n".$message;
                    $mailGateway->mailMessageEmail( $strMessage,
                                                    $from,
                                                    $this->settings->get('Support Email'),
                                                    $this->settings->get('Alternate Support Address'),
                                                    '',
                                                    $strSubject,
                                                    3,
                                                    0,
                                                    $fileattach,
                                                    $filename);
                }
            } else if ($this->settings->get('Support E-mail') == $from) {
                return 0;
            } elseif ($this->settings->get('Bounce Back Template') != "") {
                $mailGateway->mailMessageEmail( $this->settings->get('Bounce Back Template'),
                                                $this->settings->get('Support E-mail'),
                                                $this->settings->get('Support E-mail'),
                                                $from,
                                                '',
                                                'Support request failure');
            } else {
    
                //we are going to tell the admin something is wrong
                $admins = $this->getAllAdminOfType('2');
                foreach($admins as $adminName=>$adminEmail)
                {
                    if ($adminEmail == $this->settings->get('Support E-mail')) continue;
                    $strMessage = "Your Support Desk is not fully configured. You need to fill out either a ";
                    $strMessage .="Alternate Support Address or fill in a Bounce back message\n";
                    $strMessage .="Both of these options could not be found when trying to handle the following support email: \n\n\n";
                    $strMessage .= $email;
                    $mailGateway->mailMessageEmail( $strMessage,
                                                    $this->settings->get('Support E-mail'),
                                                    $this->settings->get('Support E-mail'),
                                                    $adminEmail,
                                                    '',
                                                    "Support Desk not configured",
                                                    3,
                                                    0,
                                                    $fileattach,
                                                    $filename);
                }
            }
        }
    }
    
    /**
     * Determine whether to send the autoreply or not.  We do this to avoid autoresponder loops.
     * Works by checking to see if the last five E-mails that opened a new ticket came from the same
     * E-mail address and if they were all within a few minutes.
     * 
     * @param String $from The E-mail address that the new ticket is coming from.
     * @return True if we should send an autoreply, false otherwise.
     */
    function checkAutoresponder($from)
    {
        $sendAutoReply = false;
        $lastFive = $this->settings->get('E-mail Piping Last Five');
        if ($lastFive != "") {
            $lastFiveArr = @unserialize($lastFive);
            $count = count($lastFiveArr);
            if ($count < 5) {
                $sendAutoReply = true;
                $lastFiveArr[$count]['address'] = $from;
                $lastFiveArr[$count]['time'] = time();
            } else {
                $newLastFiveArr = array();
                for ($i = 0; $i < $count; $i++) {
                    if ($lastFiveArr[$i]['address'] != $from || (time() - $lastFiveArr[$i]['time']) > 30) {
                        $sendAutoReply = true;
                    }
                    if ($i > 0) {
                        $newLastFiveArr[$i - 1]['address'] = $lastFiveArr[$i]['address'];
                        $newLastFiveArr[$i - 1]['time'] = $lastFiveArr[$i]['time'];
                    }
                }
                $newLastFiveArr[$count - 1]['address'] = $from;
                $newLastFiveArr[$count - 1]['time'] = time();
                $lastFiveArr = $newLastFiveArr;
            }
        } else {
            $sendAutoReply = true;
            $lastFiveArr = array();
            $lastFiveArr[0]['address'] = $from;
            $lastFiveArr[0]['time'] = time();
        }
        $this->settings->updateValue('E-mail Piping Last Five', serialize($lastFiveArr));
        
        return $sendAutoReply;
    }
    
    
}

?>
