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&id=30&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&id='.$iInlineImageKey.'&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; }
3_0_0/advancedtopics/rest-inline.txt · Last modified:
2023/03/24 13:55 by 127.0.0.1