Add InlineImages via REST/JSON

The requirement is to be able to add InlineImages into the description of a ticket via REST-API.

It is possible to manage it via REST API but it is not that easy.

Create a in-line Image

All the inline images are stored in the object InlineImage.

To create a new one you need as well to specify

  • the related object (here the Ticket) as the creation required the item_class, the item_id and the item_org_id which host the inline image
  • the secret which is a protection to avoid unwanted download.
    • The secret is generated using this function in the core part of iTop :
  Set('secret', sprintf('%06x', mt_rand(0, 0xFFFFFF))); 
  • You have to use base64 encoding for the data section, which is the in-line image itself.

So once you now the ticket id and ticket class you can use a REST call like below (PHP array)

    [operation] => core/create
    [comment] => Automatic creation of attachment blah blah...
    [class] => InlineImage
    [output_fields] => id, secret
    [fields] => Array
        (
            [item_class] => UserRequest
            [item_id] => 91
            [item_org_id] => 3
            [secret] => testsecret
            [contents] => Array
                (
                    [data] => iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAIAAAC0tAIdAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACmSURBVChTfZHRDYMwDESzQ2fqhHx3C3ao+MkW/WlnaFxfzk7sEnE6JHJ+NgaKZN2zLHVN2ssfkae0Da7FQ5PRk/ve4Hcx19Ie6CEGuh/6vMgNhwanHVUNbt73lUDbYJ+6pg8b3+m2RehsVPdMXyvQY+OVkB+Rrv64lUjb3nq+aCA6v4leRqtfaIgimr53atBy9PlfUhoh3fFCNDmErv9FWR6ylBL5AREbmHBnFj5lAAAAAElFTkSuQmCC
                )
        )

Update Ticket description

Then you must update your ticket field using a field with inline image (Description or caselog)

  • for this you have to insert the following pattern that is used by javascript to display the image:
<p><img src="http://my-itop/pages/ajax.document.php?operation=download_inlineimage&amp;id=30&amp;s=testsecret" style="height:49px;width:256px" data-img-id="30" data-img-secret="testsecret"></p>
  • src put the url of your iTop.
  • id and data-img-id correspond to the inline image id
  • s and data-img-secret correspond to the secret value.
  • style height:49px;width:256px - 🚧 ???

Be cautious, no delimiter for id and s values, but delimiters are required for data-img-id and data-img-secret

Basic script

Below a basic php script to test this.

<?php
 
/**
 * Helper to execute an HTTP POST request
 *
 * @param $sUrl
 * @param $aData
 * @param null $sOptionnalHeaders
 * @param null $aResponseHeaders
 * @param array $aCurlOptions
 *
 * @return bool|false|string
 * @throws \Exception
 */
function DoPostRequest($sUrl, $aData, $sOptionnalHeaders = null, &$aResponseHeaders = null, $aCurlOptions = array())
{
        // $sOptionnalHeaders is a string containing additional HTTP headers that you would like to send in your request.
 
        if (function_exists('curl_init'))
        {
                // If cURL is available, let's use it, since it provides a greater control over the various HTTP/SSL options
                // For instance fopen does not allow to work around the bug: http://stackoverflow.com/questions/18191672/php-curl-ssl-routinesssl23-get-server-helloreason1112
                // by setting the SSLVERSION to 3 as done below.
                $aHTTPHeaders = array();
                if ($sOptionnalHeaders !== null)
                {
                        $aHeaders = explode("\n", $sOptionnalHeaders);
                        // N°3267 - Webservices: Fix optional headers not being taken into account
                        //          See https://www.php.net/curl_setopt CURLOPT_HTTPHEADER
                        $aHTTPHeaders = array();
                        foreach($aHeaders as $sHeaderString)
                        {
                                $aHTTPHeaders[] = trim($sHeaderString);
                        }
                }
                // Default options, can be overloaded/extended with the 4th parameter of this method, see above $aCurlOptions
                $aOptions = array(
                        CURLOPT_RETURNTRANSFER  => true,     // return the content of the request
                        CURLOPT_HEADER                  => false,    // don't return the headers in the output
                        CURLOPT_FOLLOWLOCATION  => true,     // follow redirects
                        CURLOPT_ENCODING                => "",       // handle all encodings
                        CURLOPT_USERAGENT               => "spider", // who am i
                        CURLOPT_AUTOREFERER             => true,     // set referer on redirect
                        CURLOPT_CONNECTTIMEOUT  => 120,      // timeout on connect
                        CURLOPT_TIMEOUT                 => 120,      // timeout on response
                        CURLOPT_MAXREDIRS               => 10,       // stop after 10 redirects
                        CURLOPT_SSL_VERIFYHOST  => 0,      // Disabled SSL Cert checks
                        CURLOPT_SSL_VERIFYPEER  => 0,      // Disabled SSL Cert checks
                        // SSLV3 (CURL_SSLVERSION_SSLv3 = 3) is now considered as obsolete/dangerous: http://disablessl3.com/#why
                        // but it used to be a MUST to prevent a strange SSL error: http://stackoverflow.com/questions/18191672/php-curl-ssl-routinesssl23-get-server-helloreason1112
                        // CURLOPT_SSLVERSION         => 3,
                        CURLOPT_POST                    => count($aData),
                        CURLOPT_POSTFIELDS              => http_build_query($aData),
                        CURLOPT_HTTPHEADER              => $aHTTPHeaders,
                );
                $aAllOptions = $aCurlOptions + $aOptions;
                $ch = curl_init($sUrl);
                curl_setopt_array($ch, $aAllOptions);
                $response = curl_exec($ch);
                $iErr = curl_errno($ch);
                $sErrMsg = curl_error( $ch );
                if ($iErr !== 0)
                {
                        throw new Exception("Problem opening URL: $sUrl, $sErrMsg");
                }
                if (is_array($aResponseHeaders))
                {
                        $aHeaders = curl_getinfo($ch);
                        foreach($aHeaders as $sCode => $sValue)
                        {
                                $sName = str_replace(' ' , '-', ucwords(str_replace('_', ' ', $sCode))); // Transform "content_type" into "Content-Type"
                                $aResponseHeaders[$sName] = $sValue;
                        }
                }
                curl_close( $ch );
        }
        else
        {
                // cURL is not available let's try with streams and fopen...
 
                $sData = http_build_query($aData);
                $aParams = array('http' => array(
                        'method' => 'POST',
                        'content' => $sData,
                        'header'=> "Content-type: application/x-www-form-urlencoded\r\nContent-Length: ".strlen($sData)."\r\n",
                ));
                if ($sOptionnalHeaders !== null)
                {
                        $aParams['http']['header'] .= $sOptionnalHeaders;
                }
                $ctx = stream_context_create($aParams);
 
                $fp = @fopen($sUrl, 'rb', false, $ctx);
                if (!$fp)
                {
                        global $php_errormsg;
                        if (isset($php_errormsg))
                        {
                                throw new Exception("Wrong URL: $sUrl, $php_errormsg");
                        }
                        elseif ((strtolower(substr($sUrl, 0, 5)) == 'https') && !extension_loaded('openssl'))
                        {
                                throw new Exception("Cannot connect to $sUrl: missing module 'openssl'");
                        }
                        else
                        {
                                throw new Exception("Wrong URL: $sUrl");
                        }
                }
                $response = @stream_get_contents($fp);
                if ($response === false)
                {
                        throw new Exception("Problem reading data from $sUrl, $php_errormsg");
                }
                if (is_array($aResponseHeaders))
                {
                        $aMeta = stream_get_meta_data($fp);
                        $aHeaders = $aMeta['wrapper_data'];
                        foreach($aHeaders as $sHeaderString)
                        {
                                if(preg_match('/^([^:]+): (.+)$/', $sHeaderString, $aMatches))
                                {
                                        $aResponseHeaders[$aMatches[1]] = trim($aMatches[2]);
                                }
                        }
                }
        }
        return $response;
}
 
////////////////////////////////////////////////////////////////////////////////
//
// Main program
//
////////////////////////////////////////////////////////////////////////////////
 
// Define the operations to perform (one operation per call the rest service)
//
 
$aOperation1 = array(
                'operation' => 'core/create', // operation code
                'comment' => 'Automatic creation of attachment blah blah...', // comment recorded in the change tracking log
                'class' => 'InlineImage',
                'output_fields' => 'id, secret', // list of fields to show in the results (* or a,b,c)
                // Values for the object to create
                'fields' => array(
                        'item_class' => 'UserRequest',
                        'item_id' => 91,
                        'item_org_id' => 3,
                        'secret' => 'testsecret',
                        'contents' => array(
                                'data' => 'iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAIAAAC0tAIdAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACmSURBVChTfZHRDYMwDESzQ2fqhHx3C3ao+MkW/WlnaFxfzk7sEnE6JHJ+NgaKZN2zLHVN2ssfkae0Da7FQ5PRk/ve4Hcx19Ie6CEGuh/6vMgNhwanHVUNbt73lUDbYJ+6pg8b3+m2RehsVPdMXyvQY+OVkB+Rrv64lUjb3nq+aCA6v4leRqtfaIgimr53atBy9PlfUhoh3fFCNDmErv9FWR6ylBL5AREbmHBnFj5lAAAAAElFTkSuQmCC',
//                            'filename' => 'myself.png',
//                            'mimetype' => 'image/png'
                        ),
                ),
);
 
if (false)
{
        echo "Please edit the sample script and configure the server URL";
        exit;
}
else
{
        $sUrl = "http://localhost/marketing3.0/webservices/rest.php?version=1.3";
}
 
$aData = array();
$aData['auth_user'] = 'admin';
$aData['auth_pwd'] = 'admin';
 
 
        echo "Creating InlineImage\n";
        //echo "Operation #$iOp: ".$aOperation['operation']."\n";
        $aData['json_data'] = json_encode($aOperation1);
 
        echo "--------------------------------------\n";
        echo "Input:\n";
        print_r($aOperation1);
        $aResults = null;
        try
        {
                $response = DoPostRequest($sUrl, $aData);
                $aResults = json_decode($response, true);
        }
        catch (Exception $e)
        {
                $response = $e->getMessage();
        }
        if ($aResults)
        {
                echo "--------------------------------------\n";
                echo "Successfull InlineImage Creation";
                $iInlineImageKey = current($aResults['objects'])['key'];
        }
        else
        {
                echo "ERROR rest.php replied:\n";
                echo $response;
        }
 
        $aData = array();
        $aData['auth_user'] = 'admin';
        $aData['auth_pwd'] = 'admin';
        echo "Updating Ticket\n";
$aOperation2 =
        array(
                'operation' => 'core/update', // operation code
                'comment' => 'Synchronization from blah...', // comment recorded in the change tracking log
                'class' => 'UserRequest',
                'key' => 91,
                'output_fields' => 'id, friendlyname', // list of fields to show in the results (* or a,b,c)
                // Values for the object to create
                'fields' => array(
                        'description' => '
                        <p>Test</p>
 
<p><img src="http://192.168.56.102/marketing3.0/pages/ajax.document.php?operation=download_inlineimage&amp;id='.$iInlineImageKey.'&amp;s=testsecret" style="height:49px;width:256px" data-img-id="'.$iInlineImageKey.'" data-img-secret="testsecret"></p>
 
<p>Fin Test</p>
                        '
                ),
        );
        //echo "Operation #$iOp: ".$aOperation['operation']."\n";
        $aData['json_data'] = json_encode($aOperation2);
 
        echo "--------------------------------------\n";
        echo "Input:\n";
        print_r($aOperation2);
        $aResults = null;
        try
        {
                $response = DoPostRequest($sUrl, $aData);
                $aResults = json_decode($response, true);
        }
        catch (Exception $e)
        {
                $response = $e->getMessage();
        }
        if ($aResults)
        {
                echo "--------------------------------------\n";
                echo "Successfull Ticket update";
                print_r($aResults);
        }
        else
        {
                echo "ERROR rest.php replied:\n";
                echo $response;
        }
latest/advancedtopics/rest-inline.txt · Last modified: 2024/09/10 10:25 by 127.0.0.1
Back to top
Contact us