I am attempting to use the JSON API to create tickets with file attachments. Creating tickets with the API works perfectly when there are no attachments, but as soon as I add the attachments field I get an 500 error in response. After digging through some logs, I found the following error in our PHP error log:

  thrown in C:\inetpub\wwwroot\osticket\include\class.forms.php on line 5369
[17-Apr-2024 17:19:42 UTC] PHP Fatal error:  Uncaught TypeError: explode(): Argument #2 ($string) must be of type string, array given in C:\inetpub\wwwroot\osticket\include\class.forms.php:5369
Stack trace:
#0 C:\inetpub\wwwroot\osticket\include\class.forms.php(5369): explode()
#1 C:\inetpub\wwwroot\osticket\include\class.forms.php(4367): FileUploadWidget->getValue()
#2 C:\inetpub\wwwroot\osticket\include\class.forms.php(1385): Widget->parseValue()
#3 C:\inetpub\wwwroot\osticket\include\class.forms.php(686): FormField->getWidget()
#4 C:\inetpub\wwwroot\osticket\include\class.dynamic_forms.php(1356): FormField->getClean()
#5 C:\inetpub\wwwroot\osticket\include\class.dynamic_forms.php(1316): DynamicFormEntry->saveAnswers()
#6 C:\inetpub\wwwroot\osticket\include\class.ticket.php(4392): DynamicFormEntry->save()
#7 C:\inetpub\wwwroot\osticket\include\api.tickets.php(142): Ticket::create()
#8 C:\inetpub\wwwroot\osticket\include\api.tickets.php(117): TicketApiController->createTicket()
#9 C:\inetpub\wwwroot\osticket\include\class.dispatcher.php(153): TicketApiController->create()
#10 C:\inetpub\wwwroot\osticket\include\class.dispatcher.php(40): UrlMatcher->dispatch()
#11 C:\inetpub\wwwroot\osticket\api\http.php(29): Dispatcher->resolve()
#12 {main}
  thrown in C:\inetpub\wwwroot\osticket\include\class.forms.php on line 5369

A sample attachments key/value pair I'm adding looks like this:

"attachments":[{"filename.txt":"data:text/plain;charset=utf-8,This is the content of the attachment"}]

I've seen a couple other forum posts about this for older versions but have not been able to find an adequate solution, any suggestions? Thanks.

  • KevinTheJedi replied to this.
  • KevinTheJedi

    IIS shouldn't be messing with anything, we run similar processes to talk to multiple API's through JSON payloads and it hasn't proved to be an obstacle before.

    I've actually managed to solve the issue myself by manually editing code within \include\class.forms.php to circumvent the error. Following the stack trace the problem is occurring at line 5369:

            if ($_SERVER['REQUEST_METHOD'] == 'POST') {
                $_files = array();
                foreach ($files as $info) {
                    if (@list($id, $name) = explode(',', $info, 2))
                        $_files[$id] = $name;
                }
                $files = $_files;
            }

    Doing a var_dump() of $info inside of the loop revealed that it is an array, which is causing the error inside of explode(). I solved the issue by adding a line to implode (even though it's a bit silly to implode then explode):

            if ($_SERVER['REQUEST_METHOD'] == 'POST') {
                $_files = array();
                foreach ($files as $info) {
                    $info = implode(',', $info);
                    if (@list($id, $name) = explode(',', $info, 2))
                        $_files[$id] = $name;
                }
                $files = $_files;
            }

    After running the exact same JSON payload, the ticket was uploaded successfully with the proper attachment. I'll be doing further testing but it seems like I've managed to duct tape it together for now at least. I'm not sure if $files is meant to be a string instead of an array coming into this function, perhaps some kind of conversion condition failed due to some weird setting in my installation since it works for you without issue, but this is my culprit in any case.

    duffyk

    At a quick glance that appears to be correct, however I'd need to see the full JSON payload to see if it all looks good; JSON is very unforgiving.

    I just retested this to confirm, and below is a working example API call using cURL command:

    curl -H "X-API-KEY: key_here" -d '{"priority": 1, "alert": true, "autorespond": true, "source": "API", "topicId": 1, "name": "First Last", "email": "user@noemail.com", "subject": "Testing API", "message": "data:text/html,<b>Testing API</b>", "attachments": [{"filename.txt": "data:text/plain;charset=utf-8,content of attachment"}]}' http://your_domain.tld/api/tickets.json

    Cheers.

      KevinTheJedi

      Thanks for the response, here is a full example of a JSON payload with no attachments that successfully creates a ticket:

      {"message":"data:text/plain,Use the osTicket API to insert open SRS's into the osTicket system.","subject":"SRS to osTicket","alert":false,"email":"duffyk@email.com","name":"K Duffy","autorespond":false}

      The following JSON is exactly the same but with the attachments added, and throws the 500 error with previously mentioned stack trace:

      {"message":"data:text/plain,Use the osTicket API to insert open SRS's into the osTicket system.","attachments":[{"filename.txt":"data:text/plain;charset=utf-8,This is the content of the attachment"}],"subject":"SRS to osTicket","alert":false,"email":"duffyk@email.com","name":"K Duffy","autorespond":false}

      EDIT: Just realized it may be worth mentioning we have the "Attachments on the Filesystem" plugin installed and enabled in case that is interfering with something. Disabling this from the control panel still causes the 500 error, though.

        duffyk

        Please share a screenshot of your Admin Panel > Dashboard > Information page.

        Cheers.

          KevinTheJedi

          Maybe also worth noting attachments work fine when creating tickets through the web interface, only the API is having the issue.

            duffyk

            That’s quite odd. Can you try installing the missing fileinfo extension for PHP, restart the web server and PHP-FPM (if you’re running it), and retest?

            Cheers.

              KevinTheJedi

              I've installed and enabled this extension:

              Unfortunately I am still receiving the same 500 error and same stack trace in the PHP error log.

                duffyk

                To make 100% sure I just re-pulled latest, retested, and it all worked without issues. So I'm not really sure what is going on in your case. Does IIS mess with the JSON in any way?

                Cheers.

                  KevinTheJedi

                  IIS shouldn't be messing with anything, we run similar processes to talk to multiple API's through JSON payloads and it hasn't proved to be an obstacle before.

                  I've actually managed to solve the issue myself by manually editing code within \include\class.forms.php to circumvent the error. Following the stack trace the problem is occurring at line 5369:

                          if ($_SERVER['REQUEST_METHOD'] == 'POST') {
                              $_files = array();
                              foreach ($files as $info) {
                                  if (@list($id, $name) = explode(',', $info, 2))
                                      $_files[$id] = $name;
                              }
                              $files = $_files;
                          }

                  Doing a var_dump() of $info inside of the loop revealed that it is an array, which is causing the error inside of explode(). I solved the issue by adding a line to implode (even though it's a bit silly to implode then explode):

                          if ($_SERVER['REQUEST_METHOD'] == 'POST') {
                              $_files = array();
                              foreach ($files as $info) {
                                  $info = implode(',', $info);
                                  if (@list($id, $name) = explode(',', $info, 2))
                                      $_files[$id] = $name;
                              }
                              $files = $_files;
                          }

                  After running the exact same JSON payload, the ticket was uploaded successfully with the proper attachment. I'll be doing further testing but it seems like I've managed to duct tape it together for now at least. I'm not sure if $files is meant to be a string instead of an array coming into this function, perhaps some kind of conversion condition failed due to some weird setting in my installation since it works for you without issue, but this is my culprit in any case.

                    duffyk

                    Glad you got it working! I'm assuming this is a server/prerequisite/etc. issue not a system configuration issue as no system configuration would mess with this (I could be wrong though!).

                    Cheers.

                    Write a Reply...