Pārlūkot izejas kodu

Fixed bug in CSV import: was not working when using private keys. Also fine tuned the field matching mechanism and now the CSV export/import are 100% symmetric

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@182 a333f486-631f-4898-b8df-5754b55c2be0
romainq 16 gadi atpakaļ
vecāks
revīzija
32e801d839
2 mainītis faili ar 58 papildinājumiem un 29 dzēšanām
  1. 38 17
      core/bulkchange.class.inc.php
  2. 20 12
      pages/csvimport.php

+ 38 - 17
core/bulkchange.class.inc.php

@@ -217,24 +217,20 @@ class RowStatus_Issue extends RowStatus
 
 
 /**
- * BulkChange
- *
- * @package     iTopORM
- * @author      Romain Quetiez <romainquetiez@yahoo.fr>
- * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
- * @link        www.itop.com
- * @since       1.0
- * @version     $itopversion$
- */
+ ** BulkChange *
+ ** @package iTopORM
+ ** @author Romain Quetiez <romainquetiez@yahoo.fr>
+ ** @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ ** @link www.itop.com
+ ** @since 1.0
+ ** @version $itopversion$ */
 class BulkChange
 {
-	protected $m_sClass;
-	protected $m_aData;
-	// Note: hereafter, iCol maybe actually be any acceptable key (string)
+	protected $m_sClass; 
+	protected $m_aData; // Note: hereafter, iCol maybe actually be any acceptable key (string)
 	// #@# todo: rename the variables to sColIndex
-	protected $m_aAttList; // attcode => iCol
-	protected $m_aReconcilKeys;// iCol => attcode
-	protected $m_aExtKeys;	// aExtKeys[sExtKeyAttCode][sExtReconcKeyAttCode] = iCol;
+	protected $m_aAttList; // attcode => iCol protected $m_aReconcilKeys;// iCol => attcode (attcode = 'id' for the pkey) 
+	protected $m_aExtKeys; // aExtKeys[sExtKeyAttCode][sExtReconcKeyAttCode] = iCol;
 
 	public function __construct($sClass, $aData, $aAttList, $aReconcilKeys, $aExtKeys)
 	{
@@ -318,6 +314,9 @@ class BulkChange
 		//
 		foreach ($this->m_aAttList as $sAttCode => $iCol)
 		{
+			// skip the private key, if any
+			if ($sAttCode == 'id') continue;
+
 			if (!$oTargetObj->CheckValue($sAttCode, $aRowData[$iCol]))
 			{
 				$aErrors[$sAttCode] = "Unexpected value";
@@ -333,6 +332,18 @@ class BulkChange
 		$aChangedFields = $oTargetObj->ListChanges();
 		foreach ($this->m_aAttList as $sAttCode => $iCol)
 		{
+			if ($sAttCode == 'id')
+			{
+				if ($aRowData[$iCol] == $oTargetObj->GetKey())
+				{
+					$aResults["col$iCol"]= new CellChangeSpec_Void($aRowData[$iCol]);
+				}
+				else
+				{
+					$aResults["col$iCol"]= new CellChangeSpec_Init($aRowData[$iCol]);
+				}
+				
+			}
 			if (isset($aErrors[$sAttCode]))
 			{
 				$aResults["col$iCol"]= new CellChangeSpec_Issue($oTargetObj->Get($sAttCode), $oTargetObj->GetOriginal($sAttCode), $aErrors[$sAttCode]);
@@ -413,7 +424,7 @@ class BulkChange
 	protected function UpdateObject(&$aResult, $iRow, $oTargetObj, $aRowData, CMDBChange $oChange = null)
 	{
 		$aResult[$iRow] = $this->PrepareObject($oTargetObj, $aRowData, $aErrors);
-	
+
 		// Reporting
 		//
 		if (count($aErrors) > 0)
@@ -471,9 +482,19 @@ class BulkChange
 				// $aResult[$iRow]["__STATUS__"]=> set in UpdateObject
 				break;
 			default:
+				// Found several matches, ambiguous
+				// Render "void" results on any column
+				foreach($this->m_aExtKeys as $sAttCode => $aKeyConfig)
+				{
+					foreach ($aKeyConfig as $sForeignAttCode => $iCol)
+					{
+						$aResult[$iRow]["col$iCol"] = new CellChangeSpec_Void($aRowData[$iCol]);
+					}
+					$aResult[$iRow][$sAttCode] = new CellChangeSpec_Void('n/a');
+				}
 				foreach ($this->m_aAttList as $sAttCode => $iCol)
 				{
-					$aResult[$iRow]["col$iCol"]= $aRowData[$iCol];
+					$aResult[$iRow]["col$iCol"]= new CellChangeSpec_Void($aRowData[$iCol]);
 				}
 				$aResult[$iRow]["__RECONCILIATION__"] = "Found ".$oReconciliationSet->Count()." matches";
 				$aResult[$iRow]["__STATUS__"]= new RowStatus_Issue("ambiguous reconciliation");

+ 20 - 12
pages/csvimport.php

@@ -100,7 +100,7 @@ function ShowTableForm($oPage, $oCSVParser, $sClass)
 				//
 				$aOptions[MakeExtFieldSelectValue($sAttCode, 'id')] = array(
 					'LabelHtml' => "<em>".$oAtt->GetLabel()."</em> (id)",
-					'LabelRef' => $oAtt->GetLabel()." (id)",
+					'LabelRef' => $oAtt->GetLabel(),
 					'IsReconcKey' => MetaModel::IsReconcKey($sClass, $sAttCode),
 					'Tip' => '',
 				);
@@ -204,7 +204,6 @@ function ProcessData($oPage, $sClass, $oCSVParser, $aFieldMap, $aIsReconcKey, CM
 
 	// Setup field mapping: sort out between values and other specific columns
 	//
-	$iPKeyId = null;
 	$aReconcilKeys = array();
 	$aAttList = array();
 	$aExtKeys = array();
@@ -213,8 +212,11 @@ function ProcessData($oPage, $sClass, $oCSVParser, $aFieldMap, $aIsReconcKey, CM
 		$iFieldId = (int) substr($sFieldId, strlen("field"));
 		if ($sColDesc == "id")
 		{
-			// Skip !
-			$iPKeyId = $iFieldId;
+			$aAttList['id'] = $iFieldId;
+			if (array_key_exists($sFieldId, $aIsReconcKey))
+			{
+				$aReconcilKeys['id'] = $iFieldId;
+			}
 		}
 		elseif ($sColDesc == "__none__")
 		{
@@ -244,12 +246,15 @@ function ProcessData($oPage, $sClass, $oCSVParser, $aFieldMap, $aIsReconcKey, CM
 	$aDisplayConfig = array();
 	$aDisplayConfig["__RECONCILIATION__"] = array("label"=>"Reconciliation", "description"=>"");
 	$aDisplayConfig["__STATUS__"] = array("label"=>"Import status", "description"=>"");
-	if (isset($iPKeyId))
+	if (array_key_exists('id', $aAttList))
 	{
-		$aDisplayConfig["col$iPKeyId"] = array("label"=>"<strong>id</strong>", "description"=>"");
+		$sPKeyCol = 'col'.$aAttList['id'];
+		$aDisplayConfig[$sPKeyCol] = array("label"=>"<strong>id</strong>", "description"=>"");
 	}
 	foreach($aReconcilKeys as $sAttCode => $iCol)
 	{
+		if ($sAttCode == 'id') continue;
+
 		$sLabel = MetaModel::GetAttributeDef($sClass, $sAttCode)->GetLabel();
 		$aDisplayConfig["col$iCol"] = array("label"=>"$sLabel", "description"=>"");
 	}
@@ -268,8 +273,11 @@ function ProcessData($oPage, $sClass, $oCSVParser, $aFieldMap, $aIsReconcKey, CM
 	}
 	foreach ($aAttList as $sAttCode => $iCol)
 	{
-		$sLabel = MetaModel::GetAttributeDef($sClass, $sAttCode)->GetLabel();
-		$aDisplayConfig["col$iCol"] = array("label"=>"$sLabel", "description"=>"");
+		if ($sAttCode != 'id')
+		{
+			$sLabel = MetaModel::GetAttributeDef($sClass, $sAttCode)->GetLabel();
+			$aDisplayConfig["col$iCol"] = array("label"=>"$sLabel", "description"=>"");
+		}
 	}
 
 	// Compute the results
@@ -294,12 +302,8 @@ function ProcessData($oPage, $sClass, $oCSVParser, $aFieldMap, $aIsReconcKey, CM
 		{
 			if ($sKey == '__RECONCILIATION__') continue;
 			if ($sKey == '__STATUS__') continue;
-			
 			switch (get_class($value))
 			{
-				case 'CellChangeSpec_Void':
-					$sClass = '';
-					break;
 				case 'CellChangeSpec_Unchanged':
 					$sClass = '';
 					break;
@@ -312,6 +316,10 @@ function ProcessData($oPage, $sClass, $oCSVParser, $aFieldMap, $aIsReconcKey, CM
 				case 'CellChangeSpec_Issue':
 					$sClass = 'csvimport_error';
 					break;
+
+				case 'CellChangeSpec_Void':
+				default:
+					$sClass = '';
 			}
 			if (empty($sClass))
 			{