mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°454 - Check data validity during CSV import
* "simulate" phase is more permissive on new hierarchical entries * Better check during "apply" phase SVN:trunk[5000]
This commit is contained in:
@@ -368,6 +368,7 @@ class BulkChange
|
||||
{
|
||||
// Check for additional rules
|
||||
$oReconFilter = $oExtKey->GetAllowedValuesAsFilter(array('this' => $oTargetObj));
|
||||
//$oReconFilter = new DBObjectSearch($oExtKey->GetTargetClass());
|
||||
|
||||
$aCacheKeys = array();
|
||||
foreach ($aKeyConfig as $sForeignAttCode => $iCol)
|
||||
@@ -413,12 +414,13 @@ class BulkChange
|
||||
$oForeignObj = $oExtObjects->Fetch();
|
||||
$iForeignKey = $oForeignObj->GetKey();
|
||||
}
|
||||
$this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey] = array(
|
||||
'c' => $iCount,
|
||||
'k' => $iForeignKey,
|
||||
'oql' => $oReconFilter->ToOql(),
|
||||
'h' => 0, // number of hits on this cache entry
|
||||
);
|
||||
// Cannot cache the entry in this case as the conditions can change...
|
||||
//$this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey] = array(
|
||||
// 'c' => $iCount,
|
||||
// 'k' => $iForeignKey,
|
||||
// 'oql' => $oReconFilter->ToOql(),
|
||||
// 'h' => 0, // number of hits on this cache entry
|
||||
//);
|
||||
}
|
||||
switch($iCount)
|
||||
{
|
||||
@@ -648,6 +650,43 @@ class BulkChange
|
||||
protected function CreateObject(&$aResult, $iRow, $aRowData, CMDBChange $oChange = null)
|
||||
{
|
||||
$oTargetObj = MetaModel::NewObject($this->m_sClass);
|
||||
|
||||
|
||||
// Populate the cache for hierarchical keys (only if in verify mode)
|
||||
if (is_null($oChange))
|
||||
{
|
||||
// 1. determine if a hierarchical key exists
|
||||
foreach($this->m_aExtKeys as $sAttCode => $aKeyConfig)
|
||||
{
|
||||
$oExtKey = MetaModel::GetAttributeDef(get_class($oTargetObj), $sAttCode);
|
||||
if (!$this->IsNullExternalKeySpec($aRowData, $sAttCode) && $oExtKey->IsHierarchicalKey())
|
||||
{
|
||||
// 2. Populate the cache for further checks
|
||||
$aCacheKeys = array();
|
||||
foreach ($aKeyConfig as $sForeignAttCode => $iCol)
|
||||
{
|
||||
// The foreign attribute is one of our reconciliation key
|
||||
if ($sForeignAttCode == 'id')
|
||||
{
|
||||
$value = $aRowData[$iCol];
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = $aRowData[$this->m_aAttList[$sForeignAttCode]];
|
||||
}
|
||||
$aCacheKeys[] = $value;
|
||||
}
|
||||
$sCacheKey = implode('_|_', $aCacheKeys); // Unique key for this query...
|
||||
$this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey] = array(
|
||||
'c' => 1,
|
||||
'k' => -1,
|
||||
'oql' => '',
|
||||
'h' => 0, // number of hits on this cache entry
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$aResult[$iRow] = $this->PrepareObject($oTargetObj, $aRowData, $aErrors);
|
||||
|
||||
if (count($aErrors) > 0)
|
||||
|
||||
@@ -1199,24 +1199,16 @@ abstract class DBObject implements iDisplay
|
||||
}
|
||||
elseif ($oAtt->IsExternalKey())
|
||||
{
|
||||
if (!MetaModel::SkipCheckExtKeys())
|
||||
// Hierachical keys are always tested because an infinite loop can be created.
|
||||
if (!MetaModel::SkipCheckExtKeys() || $oAtt->IsHierarchicalKey())
|
||||
{
|
||||
$sTargetClass = $oAtt->GetTargetClass();
|
||||
$oTargetObj = MetaModel::GetObject($sTargetClass, $toCheck, false /*must be found*/, true /*allow all data*/);
|
||||
if (is_null($oTargetObj))
|
||||
{
|
||||
return "Target object not found ($sTargetClass::$toCheck)";
|
||||
}
|
||||
// Check allowed values
|
||||
$aValues = $oAtt->GetAllowedValues($this->ToArgsForQuery());
|
||||
if (count($aValues) > 0)
|
||||
if (!array_key_exists($toCheck, $aValues))
|
||||
{
|
||||
if (!array_key_exists($toCheck, $aValues))
|
||||
{
|
||||
return "Value not allowed [$toCheck]";
|
||||
}
|
||||
return "Value not allowed [$toCheck]";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ($oAtt->IsScalar())
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user