Selaa lähdekoodia

Exports: a fields spec can now be an extended attribute code (e.g. location_id->org_id->parent_id->code)

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@3709 a333f486-631f-4898-b8df-5754b55c2be0
romainq 9 vuotta sitten
vanhempi
commit
eaee9c5ddc
2 muutettua tiedostoa jossa 71 lisäystä ja 45 poistoa
  1. 24 22
      core/metamodel.class.php
  2. 47 23
      core/tabularbulkexport.class.inc.php

+ 24 - 22
core/metamodel.class.php

@@ -728,11 +728,22 @@ abstract class MetaModel
 	final static public function GetAttributeDef($sClass, $sAttCode)
 	{
 		self::_check_subclass($sClass);
-		if (!isset(self::$m_aAttribDefs[$sClass][$sAttCode]))
+		if (isset(self::$m_aAttribDefs[$sClass][$sAttCode]))
+		{
+			return self::$m_aAttribDefs[$sClass][$sAttCode];
+		}
+		elseif (($iPos = strpos($sAttCode, '->')) !== false)
+		{
+			$sExtKeyAttCode = substr($sAttCode, 0, $iPos);
+			$sRemoteAttCode = substr($sAttCode, $iPos + 2);
+			$oKeyAttDef = self::GetAttributeDef($sClass, $sExtKeyAttCode);
+			$sRemoteClass = $oKeyAttDef->GetTargetClass();
+			return self::GetAttributeDef($sRemoteClass, $sRemoteAttCode);
+		}
+		else
 		{
 			throw new Exception("Unknown attribute $sAttCode from class $sClass");
 		}
-		return self::$m_aAttribDefs[$sClass][$sAttCode];
 	}
 
 	final static public function GetExternalKeys($sClass)
@@ -841,25 +852,7 @@ abstract class MetaModel
 	public static function GetLabel($sClass, $sAttCodeEx, $bShowMandatory = false)
 	{
 		$sLabel = '';
-		if (preg_match('/(.+)->(.+)/', $sAttCodeEx, $aMatches) > 0)
-		{
-			$sAttribute = $aMatches[1];
-			$sField = $aMatches[2];
-			$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttribute);
-			$sMandatory = ($bShowMandatory && !$oAttDef->IsNullAllowed()) ? '*' : '';
-			if ($oAttDef->IsExternalKey())
-			{
-				$sTargetClass = $oAttDef->GetTargetClass();
-				$oTargetAttDef = MetaModel::GetAttributeDef($sTargetClass, $sField);
-				$sLabel = $oAttDef->GetLabel().$sMandatory.'->'.$oTargetAttDef->GetLabel();
-			}
-			else
-			{
-				// Let's return something displayable... but this should never happen!
-				$sLabel = $oAttDef->GetLabel().$sMandatory.'->'.$aMatches[2];
-			}
-		}
-		else
+		if (($iPos = strpos($sAttCodeEx, '->')) === false)
 		{
 			if ($sAttCodeEx == 'id')
 			{
@@ -867,11 +860,20 @@ abstract class MetaModel
 			}
 			else
 			{
-				$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCodeEx);
+				$oAttDef = self::GetAttributeDef($sClass, $sAttCodeEx);
 				$sMandatory = ($bShowMandatory && !$oAttDef->IsNullAllowed()) ? '*' : '';
 				$sLabel = $oAttDef->GetLabel().$sMandatory;
 			}
 		}
+		else
+		{
+			$sExtKeyAttCode = substr($sAttCodeEx, 0, $iPos);
+			$sRemoteAttCode = substr($sAttCodeEx, $iPos + 2);
+			$oKeyAttDef = MetaModel::GetAttributeDef($sClass, $sExtKeyAttCode);
+			$sRemoteClass = $oKeyAttDef->GetTargetClass();
+			// Recurse
+			$sLabel = self::GetLabel($sClass, $sExtKeyAttCode).'->'.self::GetLabel($sRemoteClass, $sRemoteAttCode);
+		}
 		return $sLabel;
 	}
 

+ 47 - 23
core/tabularbulkexport.class.inc.php

@@ -349,33 +349,21 @@ EOF
 				throw new Exception("You do not have enough permissions to bulk read data of class '$sClass' (alias: $sAlias)");
 			}
 				
-			switch($sAttCode)
+			if ($this->bLocalizeOutput)
 			{
-				case 'id':
-				$sLabel = 'id';
-				$oAttDef = null;
-				break;
-						
-				default:
-				$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
-				if (($oAttDef instanceof AttributeExternalField) || (($oAttDef instanceof AttributeFriendlyName) && ($oAttDef->GetKeyAttCode() != 'id')))
+				try
 				{
-					$oKeyAttDef = MetaModel::GetAttributeDef($sClass, $oAttDef->GetKeyAttCode());
-					$oExtAttDef = MetaModel::GetAttributeDef($oKeyAttDef->GetTargetClass(), $oAttDef->GetExtAttCode());
-					if ($this->bLocalizeOutput)
-					{
-						$sLabel = $oKeyAttDef->GetLabel().'->'.$oExtAttDef->GetLabel();
-					}
-					else
-					{
-						$sLabel =  $oKeyAttDef->GetCode().'->'.$oExtAttDef->GetCode();
-					}						
+					$sLabel = MetaModel::GetLabel($sClass, $sAttCode);
 				}
-				else
+				catch (Exception $e)
 				{
-					$sLabel = $this->bLocalizeOutput ? $oAttDef->GetLabel() : $sAttCode;
+					throw new Exception("Wrong field specification '$sFieldSpec': ".$e->getMessage());
 				}
 			}
+			else
+			{
+				$sLabel = $sAttCode;
+			}
 			if (count($aAuthorizedClasses) > 1)
 			{
 				$sColLabel = $sAlias.'.'.$sLabel;
@@ -404,6 +392,7 @@ EOF
 
 		foreach($this->aStatusInfo['fields'] as $iCol => $aFieldSpec)
 		{
+			$sClass = $aFieldSpec['sClass'];
 			$sAlias = $aFieldSpec['sAlias'];
 			$sAttCode = $aFieldSpec['sAttCode'];
 				
@@ -411,12 +400,47 @@ EOF
 			{
 				$aColumnsToLoad[$sAlias] = array();
 			}
+			// id is not a real attribute code and, moreover, is always loaded
 			if ($sAttCode != 'id')
 			{
-				// id is not a real attribute code and, moreover, is always loaded
-				$aColumnsToLoad[$sAlias][] = $sAttCode;
+				// Extended attributes are not recognized by DBObjectSet::OptimizeColumnLoad
+				if (($iPos = strpos($sAttCode, '->')) === false)
+				{
+					$aColumnsToLoad[$sAlias][] = $sAttCode;
+					$sClass = '???';
+				}
+				else
+				{
+					$sExtKeyAttCode = substr($sAttCode, 0, $iPos);
+					$sRemoteAttCode = substr($sAttCode, $iPos + 2);
+
+					// Load the external key to avoid an object reload!
+					$aColumnsToLoad[$sAlias][] = $sExtKeyAttCode;
+
+					// Load the external field (if any) to avoid getting the remote object (see DBObject::Get that does the same)
+					$oExtFieldAtt = MetaModel::FindExternalField($sClass, $sExtKeyAttCode, $sRemoteAttCode);
+					if (!is_null($oExtFieldAtt))
+					{
+						$aColumnsToLoad[$sAlias][] = $oExtFieldAtt->GetCode();
+					}
+				}
 			}
 		}
+
+		// Add "always loaded attributes"
+		//
+		$aSelectedClasses = $this->oSearch->GetSelectedClasses();
+		foreach ($aSelectedClasses as $sAlias => $sClass)
+		{
+			foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
+			{
+				if ($oAttDef->AlwaysLoadInTables())
+				{
+					$aColumnsToLoad[$sAlias][] = $sAttCode;
+				}
+			}
+		}
+
 		$oSet->OptimizeColumnLoad($aColumnsToLoad);
 	}	 	
 }