PHP 8.3.27
Preview: api.tickets.php Size: 10.36 KB
/home7/doctorbruno/public_html/taeionline.com/support/include/api.tickets.php
<?php

include_once INCLUDE_DIR.'class.api.php';
include_once INCLUDE_DIR.'class.ticket.php';

class TicketApiController extends ApiController {

    # Supported arguments -- anything else is an error. These items will be
    # inspected _after_ the fixup() method of the ApiXxxDataParser classes
    # so that all supported input formats should be supported
    function getRequestStructure($format, $data=null) {
        $supported = array(
            "alert", "autorespond", "source", "topicId",
            "attachments" => array("*" =>
                array("name", "type", "data", "encoding", "size")
            ),
            "message", "ip", "priorityId",
            "system_emails" => array(
                "*" => "*"
            ),
            "thread_entry_recipients" => array (
                "*" => array("to", "cc")
            )
        );
        # Fetch dynamic form field names for the given help topic and add
        # the names to the supported request structure
        if (isset($data['topicId'])
                && ($topic = Topic::lookup($data['topicId']))
                && ($forms = $topic->getForms())) {
            foreach ($forms as $form)
                foreach ($form->getDynamicFields() as $field)
                    $supported[] = $field->get('name');
        }

        # Ticket form fields
        # TODO: Support userId for existing user
        if(($form = TicketForm::getInstance()))
            foreach ($form->getFields() as $field)
                $supported[] = $field->get('name');

        # User form fields
        if(($form = UserForm::getInstance()))
            foreach ($form->getFields() as $field)
                $supported[] = $field->get('name');

        switch ($format) {
            case 'email':
                $supported = array_merge($supported, [
                    'header', 'mid', 'emailId', 'to-email-id', 'ticketId', 'reply-to',
                    'reply-to-name', 'in-reply-to', 'references', 'thread-type', 'system_emails',
                    'mailflags' => ['bounce', 'auto-reply', 'spam', 'viral'],
                    'recipients' => ['*' => ['name', 'email', 'source']]
                ]);
                $supported['attachments']['*'][] = 'cid';
                break;
            case 'json':
            case 'xml':
                $supported = array_merge($supported, [
                    'duedate', 'slaId', 'staffId'
                ]);
                break;
        }

        return $supported;
    }

    /*
     Validate data - overwrites parent's validator for additional validations.
    */
    function validate(&$data, $format, $strict=true) {
        global $ost;

        //Call parent to Validate the structure
        if(!parent::validate($data, $format, $strict) && $strict)
            $this->exerr(400, __('Unexpected or invalid data received'));

        // 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();

        // Nuke attachments IF API files are not allowed.
        if (!$messageField->isAttachmentsEnabled())
            $data['attachments'] = array();

        //Validate attachments: Do error checking... soft fail - set the error and pass on the request.
        if (isset($data['attachments']) && is_array($data['attachments'])) {
            foreach($data['attachments'] as &$file) {
                if ($file['encoding'] && !strcasecmp($file['encoding'], 'base64')) {
                    if(!($file['data'] = base64_decode($file['data'], true)))
                        $file['error'] = sprintf(__('%s: Poorly encoded base64 data'),
                            Format::htmlchars($file['name']));
                }
                // Validate and save immediately
                try {
                    $F = $fileField->uploadAttachment($file);
                    $file['id'] = $F->getId();
                }
                catch (FileUploadError $ex) {
                    $name = $file['name'];
                    $file = array();
                    $file['error'] = Format::htmlchars($name) . ': ' . $ex->getMessage();
                }
            }
            unset($file);
        }

        return true;
    }


    function create($format) {

        if (!($key=$this->requireApiKey()) || !$key->canCreateTickets())
            return $this->exerr(401, __('API key not authorized'));

        $ticket = null;
        if (!strcasecmp($format, 'email')) {
            // Process remotely piped emails - could be a reply...etc.
            $ticket = $this->processEmailRequest();
        } else {
            // Get and Parse request body data for the format
            $ticket = $this->createTicket($this->getRequest($format));
        }



        if ($ticket)
            $this->response(201, $ticket->getNumber());
        else
            $this->exerr(500, _S("unknown error"));

    }

    /* private helper functions */

    function createTicket($data, $source = 'API') {

        # Pull off some meta-data
        $alert       = (bool) (isset($data['alert'])       ? $data['alert']       : true);
        $autorespond = (bool) (isset($data['autorespond']) ? $data['autorespond'] : true);

        // Assign default value to source if not defined, or defined as NULL
        $data['source'] ??= $source;

        // Create the ticket with the data (attempt to anyway)
        $errors = array();
        if (($ticket = Ticket::create($data, $errors, $data['source'],
                        $autorespond, $alert)) &&  !$errors)
            return $ticket;

        // Ticket create failed Bigly - got errors?
        $title = null;
        // Got errors?
        if (count($errors)) {
            // Ticket denied? Say so loudly so it can standout from generic
            // validation errors
            if (isset($errors['errno']) && $errors['errno'] == 403) {
                $title = _S('Ticket denied');
                $error = sprintf("%s: %s\n\n%s",
                        $title, $data['email'], $errors['err']);
            } else {
                // unpack the errors
                $error = Format::array_implode("\n", "\n", $errors);
            }
        } else {
            // unknown reason - default
            $error = _S('unknown error');
        }

        $error = sprintf('%s :%s',
                _S('Unable to create new ticket'), $error);
        return $this->exerr($errors['errno'] ?: 500, $error, $title);
    }

    function processEmailRequest() {
        return $this->processEmail();
    }

    function processEmail($data=false, array $defaults = []) {

        try {
            if (!$data)
                $data = $this->getEmailRequest();
            elseif (!is_array($data))
                $data = $this->parseEmail($data);
        } catch (Exception $ex)  {
            throw new EmailParseError($ex->getMessage());
        }

        $data = array_merge($defaults, $data);
        $seen = false;
        if (($entry = ThreadEntry::lookupByEmailHeaders($data, $seen))
            && ($message = $entry->postEmail($data))
        ) {
            if ($message instanceof ThreadEntry) {
                return $message->getThread()->getObject();
            }
            else if ($seen) {
                // Email has been processed previously
                return $entry->getThread()->getObject();
            }
        }

        // Allow continuation of thread without initial message or note
        elseif (($thread = Thread::lookupByEmailHeaders($data))
            && ($message = $thread->postEmail($data))
        ) {
            return $thread->getObject();
        }

        // All emails which do not appear to be part of an existing thread
        // will always create new "Tickets". All other objects will need to
        // be created via the web interface or the API
        try {
            return $this->createTicket($data, 'Email');
        } catch (TicketApiError $err) {
            // Check if the ticket was denied by a filter or banlist
            if ($err->isDenied() && $data['mid']) {
                // We need to log the Message-Id (mid) so we don't
                // process the same email again in subsequent fetches
                $entry = new ThreadEntry();
                $entry->logEmailHeaders(0, $data['mid']);
                // throw TicketDenied exception so the caller can handle it
                // accordingly
                throw new TicketDenied($err->getMessage());
            } else {
                // otherwise rethrow this bad baby as it is!
                throw $err;
            }
        }
    }
}

//Local email piping controller - no API key required!
class PipeApiController extends TicketApiController {

    // Overwrite grandparent's (ApiController) response method.
    function response($code, $resp) {

        // It's important to use postfix exit codes for local piping instead
        // of HTTP's so the piping script can process them accordingly
        switch($code) {
            case 201: //Success
                $exitcode = 0;
                break;
            case 400:
                $exitcode = 66;
                break;
            case 401: /* permission denied */
            case 403:
                $exitcode = 77;
                break;
            case 415:
            case 416:
            case 417:
            case 501:
                $exitcode = 65;
                break;
            case 503:
                $exitcode = 69;
                break;
            case 500: //Server error.
            default: //Temp (unknown) failure - retry
                $exitcode = 75;
        }
        //We're simply exiting - MTA will take care of the rest based on exit code!
        exit($exitcode);
    }

    static function process($sapi=null) {
        $pipe = new PipeApiController($sapi);
        if (($ticket=$pipe->processEmail()))
           return $pipe->response(201,
                   is_object($ticket) ? $ticket->getNumber() : $ticket);

        return $pipe->exerr(416, __('Request failed - retry again!'));
    }

    static function local() {
        return self::process('cli');
    }
}

class TicketApiError extends Exception {

    // Check if exception is because of denial
    public function isDenied() {
        return ($this->getCode() === 403);
    }
}

class TicketDenied extends Exception {}
class EmailParseError extends Exception {}

?>

Directory Contents

Dirs: 11 × Files: 132
Name Size Perms Modified Actions
cli DIR
- drwxr-xr-x 2026-10-02 10:08:28
Edit Download
client DIR
- drwxr-xr-x 2026-10-02 10:08:28
Edit Download
config DIR
- drwxr-xr-x 2017-09-15 04:26:55
Edit Download
fpdf DIR
- drwxr-xr-x 2026-10-02 10:08:28
Edit Download
i18n DIR
- drwxr-xr-x 2026-10-02 10:08:28
Edit Download
- drwxr-xr-x 2026-10-02 10:08:28
Edit Download
mpdf DIR
- drwxr-xr-x 2026-10-02 10:08:28
Edit Download
pear DIR
- drwxr-xr-x 2026-10-02 10:08:29
Edit Download
plugins DIR
- drwxr-xr-x 2026-10-02 10:08:29
Edit Download
staff DIR
- drwxr-xr-x 2026-10-02 10:08:29
Edit Download
upgrader DIR
- drwxr-xr-x 2026-10-02 10:08:29
Edit Download
14 B lrw-r--r-- 2025-02-04 09:58:56
Edit Download
194.97 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
7.29 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
4.61 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
9.76 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
13.03 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
2.33 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
1006 B lrw-r--r-- 2025-02-04 09:58:56
Edit Download
874 B lrw-r--r-- 2025-02-04 09:58:56
Edit Download
13.84 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
5.10 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
2.93 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
2.05 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
11.73 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
2.15 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
4.29 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
12.72 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
3.20 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
11.62 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
33.87 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
8.81 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
79.70 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
1.66 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
2.24 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
18.33 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
1.06 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
10.36 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
7.76 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
1.45 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
15.31 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
1.49 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
6.95 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
50.73 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
6.44 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
2.58 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
4.07 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
7.08 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
9.05 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
1.73 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
11.14 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
3.41 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
9.48 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
15.39 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
5.65 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
2.65 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
60.36 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
1.15 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
3.60 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
18.92 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
2.38 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
33.21 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
7.12 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
6.23 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
64.98 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
49.00 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
1.69 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
32.92 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
15.05 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
34.59 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
31.90 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
23.67 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
44.30 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
195.58 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
7.16 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
24.28 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
6.90 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
2.71 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
5.80 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
42.00 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
4.05 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
1.55 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
35.76 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
25.75 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
9.72 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
30.99 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
6.42 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
5.20 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
7.50 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
2.30 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
14.15 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
2.39 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
4.04 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
22.45 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
120.90 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
20.64 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
21.86 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
10.59 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
5.53 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
1.21 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
3.83 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
36.13 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
1.81 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
103.51 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
11.76 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
11.27 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
46.28 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
61.66 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
7.27 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
19.25 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
3.55 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
4.16 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
9.11 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
60.21 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
56.21 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
12.31 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
23.45 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
108.96 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
17.08 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
167.39 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
21.94 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
20.06 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
34.79 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
13.76 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
43.40 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
7.55 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
10.07 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
12.94 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
11.93 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
3.23 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
1.15 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
33.71 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
53.53 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
37 B lrw-r--r-- 2025-02-04 09:58:56
Edit Download
44 B lrw-r--r-- 2026-10-02 10:08:28
Edit Download
33.13 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
9.55 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
5.63 KB lr--r--r-- 2017-09-16 04:37:08
Edit Download
6.24 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
6.92 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
31.74 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
19.82 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
8.61 KB lrw-r--r-- 2025-02-04 09:58:56
Edit Download
If ZipArchive is unavailable, a .tar will be created (no compression).