浏览代码

#467 Friendly names not up to date when sending notifications

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@1894 a333f486-631f-4898-b8df-5754b55c2be0
romainq 13 年之前
父节点
当前提交
66deeb277e
共有 2 个文件被更改,包括 81 次插入18 次删除
  1. 2 0
      core/attributedef.class.inc.php
  2. 79 18
      core/dbobject.class.php

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

@@ -3534,6 +3534,8 @@ class AttributeFriendlyName extends AttributeComputedFieldVoid
 
 	public function GetKeyAttCode() {return $this->Get("extkey_attcode");} 
 
+	public function GetExtAttCode() {return 'friendlyname';} 
+
 	public function GetLabel($sDefault = null)
 	{
 		$sLabel = parent::GetLabel('');

+ 79 - 18
core/dbobject.class.php

@@ -80,7 +80,7 @@ abstract class DBObject
 		{
 			$this->m_aCurrValues[$sAttCode] = $oAttDef->GetDefaultValue();
 			$this->m_aOrigValues[$sAttCode] = null;
-			if ($oAttDef->IsExternalField())
+			if ($oAttDef->IsExternalField() || ($oAttDef instanceof AttributeFriendlyName))
 			{
 				// This field has to be read from the DB
 				// Leave the flag unset (optimization) 
@@ -301,31 +301,39 @@ abstract class DBObject
 			$this->Reload();
 		}
 
-		if ($oAttDef->IsExternalKey() && is_object($value))
+		if ($oAttDef->IsExternalKey())
 		{
-			// Setting an external key with a whole object (instead of just an ID)
-			// let's initialize also the external fields that depend on it
-			// (useful when building objects in memory and not from a query)
-			if ( (get_class($value) != $oAttDef->GetTargetClass()) && (!is_subclass_of($value, $oAttDef->GetTargetClass())))
+			if (is_object($value))
 			{
-				throw new CoreUnexpectedValue("Trying to set the value of '$sAttCode', to an object of class '".get_class($value)."', whereas it's an ExtKey to '".$oAttDef->GetTargetClass()."'. Ignored");
+				// Setting an external key with a whole object (instead of just an ID)
+				// let's initialize also the external fields that depend on it
+				// (useful when building objects in memory and not from a query)
+				if ( (get_class($value) != $oAttDef->GetTargetClass()) && (!is_subclass_of($value, $oAttDef->GetTargetClass())))
+				{
+					throw new CoreUnexpectedValue("Trying to set the value of '$sAttCode', to an object of class '".get_class($value)."', whereas it's an ExtKey to '".$oAttDef->GetTargetClass()."'. Ignored");
+				}
+
+				foreach(MetaModel::ListAttributeDefs(get_class($this)) as $sCode => $oDef)
+				{
+					if (($oDef->IsExternalField() || ($oDef instanceof AttributeFriendlyName)) && ($oDef->GetKeyAttCode() == $sAttCode))
+					{
+						$this->m_aCurrValues[$sCode] = $value->Get($oDef->GetExtAttCode());
+					}
+				}
 			}
 			else
 			{
-				// The object has changed, reset caches
-				$this->m_bCheckStatus = null;
-				$this->m_aAsArgs = null;
-
-				$this->m_aCurrValues[$sAttCode] = $value->GetKey();
+				// Setting an external key, but no any other information is available...
+				// Invalidate the corresponding fields so that they get reloaded in case they are needed (See Get())
 				foreach(MetaModel::ListAttributeDefs(get_class($this)) as $sCode => $oDef)
 				{
-					if ($oDef->IsExternalField() && ($oDef->GetKeyAttCode() == $sAttCode))
+					if (($oDef->IsExternalField() || ($oDef instanceof AttributeFriendlyName)) && ($oDef->GetKeyAttCode() == $sAttCode))
 					{
-						$this->m_aCurrValues[$sCode] = $value->Get($oDef->GetExtAttCode());
+						$this->m_aCurrValues[$sCode] = $oDef->GetDefaultValue();
+						unset($this->m_aLoadedAtt[$sCode]);
 					}
 				}
 			}
-			return;
 		}
 		if(!$oAttDef->IsScalar() && !is_object($value))
 		{
@@ -399,11 +407,63 @@ abstract class DBObject
 		{
 			throw new CoreException("Unknown attribute code '$sAttCode' for the class ".get_class($this));
 		}
-		if ($this->m_bIsInDB && !isset($this->m_aLoadedAtt[$sAttCode]) && !$this->m_bDirty)
+
+		if (isset($this->m_aLoadedAtt[$sAttCode]))
+		{
+			// Standard case... we have the information directly
+		}
+		elseif ($this->m_bIsInDB && !$this->m_bDirty)
 		{
-			// #@# non-scalar attributes.... handle that differently
+			// Lazy load (polymorphism): complete by reloading the entire object
+			// #@# non-scalar attributes.... handle that differently?
 			$this->Reload();
 		}
+		elseif ($sAttCode == 'friendlyname')
+		{
+			// The friendly name is not computed and the object is dirty
+			// Todo: implement the computation of the friendly name based on sprintf()
+			// 
+			$this->m_aCurrValues[$sAttCode] = '';
+		}
+		else
+		{
+			// Not loaded... is it related to an external key?
+			$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
+			if ($oAttDef->IsExternalField() || ($oAttDef instanceof AttributeFriendlyName))
+			{
+				// Let's get the object and compute all of the corresponding attributes
+				// (i.e not only the requested attribute)
+				//
+				$sExtKeyAttCode = $oAttDef->GetKeyAttCode();
+
+				if ($iRemote = $this->Get($sExtKeyAttCode))
+				{
+					$oExtKeyAttDef = MetaModel::GetAttributeDef(get_class($this), $sExtKeyAttCode);
+					$oRemote = MetaModel::GetObject($oExtKeyAttDef->GetTargetClass(), $iRemote);
+				}
+				else
+				{
+					$oRemote = null;
+				}
+
+				foreach(MetaModel::ListAttributeDefs(get_class($this)) as $sCode => $oDef)
+				{
+					if (($oDef->IsExternalField() || ($oDef instanceof AttributeFriendlyName)) && ($oDef->GetKeyAttCode() == $sExtKeyAttCode))
+					{
+						if ($oRemote)
+						{
+							$this->m_aCurrValues[$sCode] = $oRemote->Get($oDef->GetExtAttCode());
+						}
+						else
+						{
+							$this->m_aCurrValues[$sCode] = $oDef->GetDefaultValue();
+						}
+						$this->m_aLoadedAtt[$sCode] = true;
+					}
+				}
+			}
+		}
+
 		$value = $this->m_aCurrValues[$sAttCode];
 		if ($value instanceof DBObjectSet)
 		{
@@ -1649,7 +1709,7 @@ abstract class DBObject
 			$aScalarArgs[$sArgName.'->hyperlink()'] = $this->GetHyperlink('iTopStandardURLMaker', false);
 			$aScalarArgs[$sArgName.'->hyperlink(portal)'] = $this->GetHyperlink('PortalURLMaker', false);
 			$aScalarArgs[$sArgName.'->name()'] = $this->GetName();
-		
+
 			$sClass = get_class($this);
 			foreach(MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
 			{
@@ -1669,6 +1729,7 @@ abstract class DBObject
 					$aScalarArgs[$sArgName.'->head('.$sAttCode.')'] = $oCaseLog->GetLatestEntry();
 				}
 			}
+
 			$this->m_aAsArgs = $aScalarArgs;
 			$oKPI->ComputeStats('ToArgs', get_class($this));
 		}