浏览代码

Automaticaly insert the "final class" into lists where an external key is pointing to a class that has child classes

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@573 a333f486-631f-4898-b8df-5754b55c2be0
romainq 15 年之前
父节点
当前提交
a2d547d11e
共有 2 个文件被更改,包括 114 次插入51 次删除
  1. 20 2
      core/attributedef.class.inc.php
  2. 94 49
      core/metamodel.class.php

+ 20 - 2
core/attributedef.class.inc.php

@@ -77,7 +77,7 @@ abstract class AttributeDefinition
 
 	protected $m_sCode;
 	private $m_aParams = array();
-	private $m_sHostClass = '!undefined!';
+	protected $m_sHostClass = '!undefined!';
 	protected function Get($sParamName) {return $this->m_aParams[$sParamName];}
 	protected function IsParam($sParamName) {return (array_key_exists($sParamName, $this->m_aParams));}
 
@@ -1357,7 +1357,6 @@ class AttributeExternalKey extends AttributeDBFieldVoid
  */
 class AttributeExternalField extends AttributeDefinition
 {
-
 	static protected function ListExpectedParams()
 	{
 		return array_merge(parent::ListExpectedParams(), array("extkey_attcode", "target_attcode"));
@@ -1373,6 +1372,25 @@ class AttributeExternalField extends AttributeDefinition
 		return $oExtAttDef->GetSQLCol(); 
 	}
 
+	public function GetLabel()
+	{
+		$oRemoteAtt = $this->GetExtAttDef();
+		$sDefault = $oRemoteAtt->GetLabel();
+		return Dict::S('Class:'.$this->m_sHostClass.'/Attribute:'.$this->m_sCode, $sDefault);
+	}
+	public function GetDescription()
+	{
+		$oRemoteAtt = $this->GetExtAttDef();
+		$sDefault = $oRemoteAtt->GetDescription();
+		return Dict::S('Class:'.$this->m_sHostClass.'/Attribute:'.$this->m_sCode.'+', $sDefault);
+	} 
+	public function GetHelpOnEdition()
+	{
+		$oRemoteAtt = $this->GetExtAttDef();
+		$sDefault = $oRemoteAtt->GetHelpOnEdition();
+		return Dict::S('Class:'.$this->m_sHostClass.'/Attribute:'.$this->m_sCode.'?', $sDefault);
+	} 
+
 	public function IsExternalKey($iType = EXTKEY_RELATIVE)
 	{
 		switch($iType)

+ 94 - 49
core/metamodel.class.php

@@ -930,6 +930,57 @@ abstract class MetaModel
 				}
 			}
 		}
+
+		// Add a 'class' attribute/filter to the root classes and their children
+		//
+		foreach(self::EnumRootClasses() as $sRootClass)
+		{
+			if (self::IsStandaloneClass($sRootClass)) continue;
+			
+			$sDbFinalClassField = self::DBGetClassField($sRootClass);
+			if (strlen($sDbFinalClassField) == 0)
+			{
+				$sDbFinalClassField = 'finalclass';
+				self::$m_aClassParams[$sRootClass]["db_finalclass_field"] = 'finalclass';
+			}
+			$oClassAtt = new AttributeFinalClass('finalclass', array(
+					"sql"=>$sDbFinalClassField,
+					"default_value"=>$sRootClass,
+					"is_null_allowed"=>false,
+					"depends_on"=>array()
+			));
+			$oClassAtt->SetHostClass($sRootClass);
+			self::$m_aAttribDefs[$sRootClass]['finalclass'] = $oClassAtt;
+			self::$m_aAttribOrigins[$sRootClass]['finalclass'] = $sRootClass;
+
+			$oClassFlt = new FilterFromAttribute($oClassAtt);
+			self::$m_aFilterDefs[$sRootClass]['finalclass'] = $oClassFlt;
+			self::$m_aFilterOrigins[$sRootClass]['finalclass'] = $sRootClass;
+
+			foreach(self::EnumChildClasses($sRootClass, ENUM_CHILD_CLASSES_EXCLUDETOP) as $sChildClass)
+			{
+				if (array_key_exists('finalclass', self::$m_aAttribDefs[$sChildClass]))
+				{
+					throw new CoreException("Class $sChildClass, 'finalclass' is a reserved keyword, it cannot be used as an attribute code");
+				}
+				if (array_key_exists('finalclass', self::$m_aFilterDefs[$sChildClass]))
+				{
+					throw new CoreException("Class $sChildClass, 'finalclass' is a reserved keyword, it cannot be used as a filter code");
+				}
+				$oCloned = clone $oClassAtt;
+				$oCloned->SetFixedValue($sChildClass);
+				self::$m_aAttribDefs[$sChildClass]['finalclass'] = $oCloned;
+				self::$m_aAttribOrigins[$sChildClass]['finalclass'] = $sRootClass;
+
+				$oClassFlt = new FilterFromAttribute($oClassAtt);
+				self::$m_aFilterDefs[$sChildClass]['finalclass'] = $oClassFlt;
+				self::$m_aFilterOrigins[$sChildClass]['finalclass'] = self::GetRootClass($sChildClass);
+			}
+		}
+
+		// Prepare external fields and filters
+		// Add final class to external keys
+		//
 		foreach (self::GetClasses() as $sClass)
 		{
 			self::$m_aExtKeyFriends[$sClass] = array();
@@ -961,6 +1012,45 @@ abstract class MetaModel
 					// - an external field pointing to an external KEY / FIELD
 					// - an external field pointing to an external field pointing to....
 
+					if ($oAttDef->IsExternalKey())
+					{
+						$sRemoteClass = $oAttDef->GetTargetClass();
+						if (self::HasChildrenClasses($sRemoteClass))
+						{
+							// First, create an external field attribute, that gets the final class
+							$sClassRecallAttCode = $sAttCode.'_finalclass_recall'; 
+							$oClassRecall = new AttributeExternalField($sClassRecallAttCode, array(
+									"allowed_values"=>null,
+									"extkey_attcode"=>$sAttCode,
+									"target_attcode"=>"finalclass",
+									"is_null_allowed"=>true,
+									"depends_on"=>array()
+							));
+							$oClassRecall->SetHostClass($sClass);
+							self::$m_aAttribDefs[$sClass][$sClassRecallAttCode] = $oClassRecall;
+							self::$m_aAttribOrigins[$sClass][$sClassRecallAttCode] = $oClassRecall;
+
+							// Add it to the ZLists where the external key is present
+							foreach(self::$m_aListData[$sClass] as $sListCode => $aAttributes)
+							{
+								if (in_array($sAttCode, $aAttributes))
+								{
+									$aNewList = array();
+									foreach($aAttributes as $iPos => $sAttToDisplay)
+									{
+										if (is_string($sAttToDisplay) && ($sAttToDisplay == $sAttCode))
+										{
+											// Insert the final class right before
+											$aNewList[] = $sClassRecallAttCode;
+										}
+										$aNewList[] = $sAttToDisplay;
+									}
+									self::$m_aListData[$sClass][$sListCode] = $aNewList;
+								}
+							}
+						}
+					}
+
 					// Get the real external key attribute
 					// It will be our reference to determine the other ext fields related to the same ext key
 					$oFinalKeyAttDef = $oAttDef->GetKeyAttDef(EXTKEY_ABSOLUTE);
@@ -1007,53 +1097,6 @@ abstract class MetaModel
 			//	}
 			//}
 		}
-
-		// Add a 'class' attribute/filter to the root classes and their children
-		//
-		foreach(self::EnumRootClasses() as $sRootClass)
-		{
-			if (self::IsStandaloneClass($sRootClass)) continue;
-			
-			$sDbFinalClassField = self::DBGetClassField($sRootClass);
-			if (strlen($sDbFinalClassField) == 0)
-			{
-				$sDbFinalClassField = 'finalclass';
-				self::$m_aClassParams[$sClass]["db_finalclass_field"] = 'finalclass';
-			}
-			$oClassAtt = new AttributeFinalClass('finalclass', array(
-					"sql"=>$sDbFinalClassField,
-					"default_value"=>$sRootClass,
-					"is_null_allowed"=>false,
-					"depends_on"=>array()
-			));
-			$oClassAtt->SetHostClass($sRootClass);
-			self::$m_aAttribDefs[$sRootClass]['finalclass'] = $oClassAtt;
-			self::$m_aAttribOrigins[$sRootClass]['finalclass'] = $sRootClass;
-
-			$oClassFlt = new FilterFromAttribute($oClassAtt);
-			self::$m_aFilterDefs[$sRootClass]['finalclass'] = $oClassFlt;
-			self::$m_aFilterOrigins[$sRootClass]['finalclass'] = $sRootClass;
-
-			foreach(self::EnumChildClasses($sRootClass, ENUM_CHILD_CLASSES_EXCLUDETOP) as $sChildClass)
-			{
-				if (array_key_exists('finalclass', self::$m_aAttribDefs[$sChildClass]))
-				{
-					throw new CoreException("Class $sChildClass, 'finalclass' is a reserved keyword, it cannot be used as an attribute code");
-				}
-				if (array_key_exists('finalclass', self::$m_aFilterDefs[$sChildClass]))
-				{
-					throw new CoreException("Class $sChildClass, 'finalclass' is a reserved keyword, it cannot be used as a filter code");
-				}
-				$oCloned = clone $oClassAtt;
-				$oCloned->SetFixedValue($sChildClass);
-				self::$m_aAttribDefs[$sChildClass]['finalclass'] = $oCloned;
-				self::$m_aAttribOrigins[$sChildClass]['finalclass'] = $sRootClass;
-
-				$oClassFlt = new FilterFromAttribute($oClassAtt);
-				self::$m_aFilterDefs[$sChildClass]['finalclass'] = $oClassFlt;
-				self::$m_aFilterOrigins[$sChildClass]['finalclass'] = self::GetRootClass($sChildClass);
-			}
-		}
 	}
 
 	// To be overriden, must be called for any object class (optimization)
@@ -1369,6 +1412,10 @@ abstract class MetaModel
 		}
 		return $aRes;
 	}
+	public static function HasChildrenClasses($sClass)
+	{
+		return (count(self::$m_aChildClasses[$sClass]) > 0);
+	}
 
 	public static function EnumCategories()
 	{
@@ -3039,8 +3086,6 @@ abstract class MetaModel
 	{
 		self::LoadConfig($sConfigFile);
 		if (self::DBExists())
-// !!!! #@# 
-		//if (true)
 		{
 			CMDBSource::SelectDB(self::$m_sDBName);