Files
iTop/webservices/import.php

194 lines
5.8 KiB
PHP

<?php
/**
* Import web service
*
* @package iTopORM
* @author Romain Quetiez <romainquetiez@yahoo.fr>
* @author Denis Flaven <denisflave@free.fr>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.itop.com
* @since 1.0
* @version 1.1.1.1 $
*/
//
// Known limitations
// - output still in html, because the errors are not displayed in xml
// - only external fields attributes could be used as reconciliation keys for external keys
// - reconciliation is made on the first column
// - no option to force 'always create' or 'never create'
//
// Known issues
// - ALMOST impossible to troubleshoot when an externl key has a wrong value
// - no character escaping in the xml output (yes !?!?!)
// - not outputing xml when a wrong input is given (class, attribute names)
// - for a bizIncidentTicket you may use the name as the reconciliation key,
// but that attribute is in fact recomputed by the application! An error should be raised somewhere
//
require_once('../application/application.inc.php');
require_once('../application/webpage.class.inc.php');
require_once('../application/csvpage.class.inc.php');
require_once('../application/xmlpage.class.inc.php');
require_once('../application/startup.inc.php');
require_once('../application/loginwebpage.class.inc.php');
class WebServiceException extends Exception
{
}
login_web_page::DoLogin(); // Check user rights and prompt if needed
$oContext = new UserContext();
$oAppContext = new ApplicationContext();
//$iActiveNodeId = utils::ReadParam('menu', -1);
//$currentOrganization = utils::ReadParam('org_id', '');
// Main program
//$oP = new XMLPage("iTop - Bulk import");
$oP = new web_page("iTop - Bulk import");
$oP->add('<warning>This is a prototype, I repeat: PRO-TO-TYPE, therefore it suffers bugs and limitations, documented in the code. Next step: specify...</warning>');
try
{
$sClass = utils::ReadParam('class', '');
$sSep = utils::ReadParam('separator', ';');
$sCSVData = utils::ReadPostedParam('csvdata');
$oCSVParser = new CSVParser($sCSVData);
$oCSVParser->SetSeparator($sSep);
$oCSVParser->SetSkipLines(1);
// Limitation: as the attribute list is in the first line, we can not match external key by an third-party attribute
$sRawFieldList = $oCSVParser->ListFields();
$aAttList = array();
$aExtKeys = array();
foreach($sRawFieldList as $iFieldId => $sFieldName)
{
if (!MetaModel::IsValidAttCode($sClass, $sFieldName))
{
throw new WebServiceException("Unknown attribute '$sFieldName' (class: '$sClass')");
}
$oAtt = MetaModel::GetAttributeDef($sClass, $sFieldName);
if ($oAtt->IsExternalKey())
{
$aExtKeys[$sFieldName]['id'] = $iFieldId;
$aAttList[$sFieldName] = $iFieldId;
}
elseif ($oAtt->IsExternalField())
{
$sExtKeyAttCode = $oAtt->GetKeyAttCode();
$sRemoteAttCode = $oAtt->GetExtAttCode();
$aExtKeys[$sExtKeyAttCode][$sRemoteAttCode] = $iFieldId;
}
else
{
$aAttList[$sFieldName] = $iFieldId;
}
}
// Limitation: the reconciliation key is the first attribute
$aReconcilKeys = array($sRawFieldList[0]);
// print_r($oCSVParser->ListFields());
// print_r($oCSVParser->ToArray($oCSVParser->ListFields()));
$aData = $oCSVParser->ToArray();
$oBulk = new BulkChange(
$sClass,
$aData,
$aAttList,
$aReconcilKeys,
$aExtKeys
);
$oMyChange = MetaModel::NewObject("CMDBChange");
$oMyChange->Set("date", time());
if (UserRights::GetUser() != UserRights::GetRealUser())
{
$sUserString = UserRights::GetRealUser()." on behalf of ".UserRights::GetUser();
}
else
{
$sUserString = UserRights::GetUser();
}
$oMyChange->Set("userinfo", $sUserString.' (bulk load by web service)');
$iChangeId = $oMyChange->DBInsert();
$aRes = $oBulk->Process($oMyChange);
// Setup result presentation
//
$aDisplayConfig = array();
$aDisplayConfig["__RECONCILIATION__"] = array("label"=>"Reconciliation", "description"=>"");
$aDisplayConfig["__STATUS__"] = array("label"=>"Status", "description"=>"");
if (isset($iPKeyId))
{
$aDisplayConfig["col$iPKeyId"] = array("label"=>"<strong>pkey</strong>", "description"=>"");
}
foreach($aReconcilKeys as $iCol => $sAttCode)
{
$sLabel = MetaModel::GetAttributeDef($sClass, $sAttCode)->GetLabel();
$aDisplayConfig["col$iCol"] = array("label"=>"$sLabel", "description"=>"");
}
foreach ($aAttList as $sAttCode => $iCol)
{
$sLabel = MetaModel::GetAttributeDef($sClass, $sAttCode)->GetLabel();
$aDisplayConfig["col$iCol"] = array("label"=>"$sLabel", "description"=>"");
}
$aResultDisp = array(); // to be displayed
foreach($aRes as $iRow => $aRowData)
{
$aRowDisp = array();
$aRowDisp["__RECONCILIATION__"] = $aRowData["__RECONCILIATION__"];
$aRowDisp["__STATUS__"] = $aRowData["__STATUS__"]->GetDescription();
foreach($aRowData as $sKey => $value)
{
if ($sKey == '__RECONCILIATION__') continue;
if ($sKey == '__STATUS__') continue;
switch (get_class($value))
{
case 'CellChangeSpec_Void':
$sClass = '';
break;
case 'CellChangeSpec_Unchanged':
$sClass = '';
break;
case 'CellChangeSpec_Modify':
$sClass = 'csvimport_ok';
break;
case 'CellChangeSpec_Init':
$sClass = 'csvimport_init';
break;
case 'CellChangeSpec_Issue':
$sClass = 'csvimport_error';
break;
}
if (empty($sClass))
{
$aRowDisp[$sKey] = $value->GetDescription();
}
else
{
$aRowDisp[$sKey] = "<div class=\"$sClass\">".$value->GetDescription()."</div>";
}
}
$aResultDisp[$iRow] = $aRowDisp;
}
$oP->table($aDisplayConfig, $aResultDisp);
}
catch(Exception $e)
{
$oP->add('<error>'.((string)$e).'</error>');
}
$oP->output();
?>