Procházet zdrojové kódy

Related objects:
- moved to OQL
- added capacity to set a default value based on the related objects (during the creation wizard)

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@314 a333f486-631f-4898-b8df-5754b55c2be0

romainq před 15 roky
rodič
revize
f8bceb6e03

+ 1 - 1
application/uilinkswizard.class.inc.php

@@ -285,7 +285,7 @@ class UILinksWizard
 			foreach($this->m_aEditableFields as $sFieldCode)
 			{
 				$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sFieldCode);
-				$aRow[$sFieldCode] = cmdbAbstractObject::GetFormElementForField($oP, $this->m_sClass, $sFieldCode, $oAttDef, '' /* TO DO/ call GetDefaultValue */, '' /* DisplayValue */, '' /* id */, $sNameSuffix);
+				$aRow[$sFieldCode] = cmdbAbstractObject::GetFormElementForField($oP, $this->m_sClass, $sFieldCode, $oAttDef, '' /* TO DO/ call GetDefaultValue($oObject->ToArgs()) */, '' /* DisplayValue */, '' /* id */, $sNameSuffix);
 			}
 		}
 		foreach(MetaModel::GetZListItems($this->m_sLinkedClass, 'list') as $sFieldCode)

+ 8 - 8
application/uiwizard.class.inc.php

@@ -59,7 +59,7 @@ class UIWizard
 				}
 				
 				$sFieldFlag = (($iOptions & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE)) || (!$oAttDef->IsNullAllowed()) )? ' <span class="hilite">*</span>' : '';
-				$oDefaultValuesSet = $oAttDef->GetDefaultValue(); // @@@ TO DO: get the object's current value if the object exists
+				$oDefaultValuesSet = $oAttDef->GetDefaultValue(/* $oObject->ToArgs() */); // @@@ TO DO: get the object's current value if the object exists
 				$sHTMLValue = cmdbAbstractObject::GetFormElementForField($this->m_oPage, $this->m_sClass, $sAttCode, $oAttDef, $oDefaultValuesSet, '', "att_$iMaxInputId", '', $iOptions, $aArgs);
 				$aFieldsMap[$iMaxInputId] = $sAttCode;
 				$aDetails[] = array('label' => $oAttDef->GetLabel().$sFieldFlag, 'value' => "<div id=\"field_$iMaxInputId\">$sHTMLValue</div>");
@@ -165,7 +165,7 @@ $sJSHandlerCode
 			$aFields = array();
 			foreach($aStates[$this->m_sTargetState]['attribute_list'] as $sAttCode => $iOptions)
 			{
-				if ( (isset($aMandatoryAttributes[$sAttCode])) && 
+				if ( (isset($aMandatoryAttributes[$sAttCode])) && 
 					 ($aMandatoryAttributes[$sAttCode] & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT)) )
 				{
 					$aMandatoryAttributes[$sAttCode] |= $iOptions;
@@ -176,16 +176,16 @@ $sJSHandlerCode
 				}
 			}
 		}
-        
-		// Check all the fields that *must* be included in the wizard
-		// i.e. all mandatory, must-change or must-prompt fields that are
-		// not also read-only or hidden.
-		// Some fields may be required (null not allowed) from the database
+        
+		// Check all the fields that *must* be included in the wizard
+		// i.e. all mandatory, must-change or must-prompt fields that are
+		// not also read-only or hidden.
+		// Some fields may be required (null not allowed) from the database
 		// perspective, but hidden or read-only from the user interface perspective 
 		$aFields = array();
 		foreach($aMandatoryAttributes as $sAttCode => $iOptions)
 		{
-			if ( ($iOptions & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT)) &&
+			if ( ($iOptions & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT)) &&
 				 !($iOptions & (OPT_ATT_READONLY | OPT_ATT_HIDDEN)) )
 			{
 				$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);

+ 5 - 15
core/attributedef.class.inc.php

@@ -241,28 +241,18 @@ class AttributeLinkedSet extends AttributeDefinition
 		//       
 		if (($this->IsParam('default_value')) && array_key_exists('this', $aArgs))
 		{
-			$oSet = $this->Get('default_value');
-			return $oSet->GetValues($aArgs);
+echo "### this est la <br/>\n";
+			$aValues = $this->Get('default_value')->GetValues($aArgs);
+			$oSet = DBObjectSet::FromArray($this->Get('linked_class'), $aValues);
+			return $oSet;
 		}
 		else
 		{
+echo "### this manque a l'appel<br/>\n";
 			return DBObjectSet::FromScratch($this->Get('linked_class'));
 		}
 	}
 
-	public function GetSupportedRelations()
-	{
-		if (array_key_exists('supported_relations', $this->m_aParams))
-		{
-			$aSupportedRelations = $this->Get('supported_relations');
-			return $aSupportedRelations;
-		}
-		else
-		{
-			return array();
-		}
-	}
-
 	public function GetLinkedClass() {return $this->Get('linked_class');}
 	public function GetExtKeyToMe() {return $this->Get('ext_key_to_me');}
 

+ 10 - 36
core/dbobject.class.php

@@ -229,7 +229,7 @@ abstract class DBObject
 	}
 	
 	public function Set($sAttCode, $value)
-	{
+	{
 		if ($sAttCode == 'finalclass')
 		{
 			// Ignore it - this attribute is set upon object creation and that's it
@@ -665,6 +665,11 @@ abstract class DBObject
 		}
 		return $this->m_iKey;
 	}
+
+	// To be optionaly overloaded
+	public function OnInsert()
+	{
+	}
 	
 	// Insert of record for the new object into the database
 	// Returns the key of the newly created object
@@ -680,6 +685,7 @@ abstract class DBObject
 
 		// Ensure the update of the values (we are accessing the data directly)
 		$this->ComputeFields();
+		$this->OnInsert();
 
 		if ($this->m_iKey < 0)
 		{
@@ -878,7 +884,7 @@ abstract class DBObject
 	}
 
 	// Make standard context arguments
-	public function ToArgs($sArgName)
+	public function ToArgs($sArgName = 'this')
 	{
 		$aScalarArgs = array();
 		$aScalarArgs[$sArgName] = $this->GetKey();
@@ -904,38 +910,6 @@ abstract class DBObject
 	
 	public function GetRelatedObjects($sRelCode, $iMaxDepth = 99, &$aResults = array())
 	{
-		foreach (MetaModel::GetLinkedSets($sClass) as $sAttCode => $oAttDef)
-		{
-			$aSupportedRelations = $oAttDef->GetSupportedRelations();
-			if (!array_key_exists($sRelCode, $aSupportedRelations)) continue; //skip
-
-			$bPropagate = true; // #@# Todo: discuss that setting
-			$iDepth = $bPropagate ? $iMaxDepth - 1 : 0;
-
-			$oNeighbors = $this->Get($sAttCode);
-			while ($oObj = $oObjSet->Fetch())
-			{
-				$sRootClass = MetaModel::GetRootClass(get_class($oObj));
-				$sObjKey = $oObj->GetKey();
-				if (array_key_exists($sRootClass, $aResults))
-				{
-					if (array_key_exists($sObjKey, $aResults[$sRootClass]))
-					{
-						continue; // already visited, skip
-					}
-				}
-
-				$aResults[$sRootClass][$sObjKey] = $oObj;
-				if ($iDepth > 0)
-				{
-					$oObj->GetRelatedObjects($sRelCode, $iDepth, $aResults);
-				}
-			}
-		}
-		
-		return;
-		
-		// #@# todo : Discuss the Relations and the way they are defined (do we deprecate the queries ? what are the properties -e.g. depth- and where do we set them ?)
 		foreach (MetaModel::EnumRelationQueries(get_class($this), $sRelCode) as $sDummy => $aQueryInfo)
 		{
 			MetaModel::DbgTrace("object=".$this->GetKey().", depth=$iMaxDepth, rel=".$aQueryInfo["sQuery"]);
@@ -945,8 +919,8 @@ abstract class DBObject
 
 			$iDepth = $bPropagate ? $iMaxDepth - 1 : 0;
 
-			$oFlt = DBObjectSearch::FromSibusQL($sQuery, array(), $this);
-			$oObjSet = new DBObjectSet($oFlt);
+			$oFlt = DBObjectSearch::FromOQL($sQuery);
+			$oObjSet = new DBObjectSet($oFlt, array(), $this->ToArgs());
 			while ($oObj = $oObjSet->Fetch())
 			{
 				$sRootClass = MetaModel::GetRootClass(get_class($oObj));

+ 1 - 1
core/dbobjectsearch.class.php

@@ -933,7 +933,7 @@ class DBObjectSearch
 
 		if (preg_match('@^\\s*SELECT@', $sQuery))
 		{
-			return self::FromOQL($sQuery, $aParams, $oObject);
+			return self::FromOQL($sQuery);
 		}
 
 		$iSepPos = strpos($sQuery, ":");

+ 20 - 1
core/dbobjectset.class.php

@@ -81,6 +81,22 @@ class DBObjectSet
 		return $oRetSet;
 	} 
 
+	static public function FromLinkSet($oObject, $sLinkSetAttCode, $sExtKeyToRemote)
+	{
+		$oLinkAttCode = MetaModel::GetAttributeDef(get_class($oObject), $sLinkSetAttCode);
+		$oExtKeyAttDef = MetaModel::GetAttributeDef($oLinkAttCode->GetLinkedClass(), $sExtKeyToRemote);
+		$sTargetClass = $oExtKeyAttDef->GetTargetClass();
+
+		$oLinkSet = $oObject->Get($sLinkSetAttCode);
+		$aTargets = array();
+		while ($oLink = $oLinkSet->Fetch())
+		{
+			$aTargets[] = MetaModel::GetObject($sTargetClass, $oLink->Get($sExtKeyToRemote));
+		}
+
+		return self::FromArray($sTargetClass, $aTargets);
+	} 
+
 	public function ToArray($bWithId = true)
 	{
 		$aRet = array();
@@ -263,11 +279,14 @@ class DBObjectSet
 
 	public function GetRelatedObjects($sRelCode, $iMaxDepth = 99)
 	{
+		$aRelatedObjs = array();
+
 		$aVisited = array(); // optimization for consecutive calls of MetaModel::GetRelatedObjects
 		$this->Seek(0);
 		while ($oObject = $this->Fetch())
 		{
-			$aRelatedObjs = $oObject->GetRelatedObjects($sRelCode, $iMaxDepth, $aVisited);
+			// #@# todo - actually merge !
+			$aRelatedObjs = array_merge_recursive($aRelatedObjs, $oObject->GetRelatedObjects($sRelCode, $iMaxDepth, $aVisited));
 		}
 		return $aRelatedObjs;
 	}

+ 33 - 4
core/valuesetdef.class.inc.php

@@ -126,16 +126,25 @@ class ValueSetObjects extends ValueSetDefinition
  * @since       1.0
  * @version     $itopversion$
  */
-class ValueSetRelatedObjects extends ValueSetDefinition
+class ValueSetRelatedObjectsFromLinkSet extends ValueSetDefinition
 {
+	protected $m_sLinkSetAttCode;
+	protected $m_sExtKeyToRemote;
 	protected $m_sRelationCode;
 	protected $m_iMaxDepth;
+	protected $m_sTargetClass;
+	protected $m_sTargetExtKey;
 //	protected $m_aOrderBy;
 
-	public function __construct($sRelationCode, $iMaxDepth = 99)
+	public function __construct($sLinkSetAttCode, $sExtKeyToRemote, $sRelationCode, $iMaxDepth, $sTargetClass, $sTargetLinkClass, $sTargetExtKey)
 	{
+		$this->m_sLinkSetAttCode = $sLinkSetAttCode;
+		$this->m_sExtKeyToRemote = $sExtKeyToRemote;
 		$this->m_sRelationCode = $sRelationCode;
 		$this->m_iMaxDepth = $iMaxDepth;
+		$this->m_sTargetClass = $sTargetClass;
+		$this->m_sTargetLinkClass = $sTargetLinkClass;
+		$this->m_sTargetExtKey = $sTargetExtKey;
 //		$this->m_aOrderBy = $aOrderBy;
 	}
 
@@ -150,11 +159,31 @@ class ValueSetRelatedObjects extends ValueSetDefinition
 
 		$oTarget = $aArgs['this->object()'];
 
-		$oTargetNeighbors = $oTarget->GetRelatedObjects($this->m_sRelationCode, $this->m_iMaxDepth);
-		while ($oObject = $oTargetNeighbors->Fetch())
+		// Nodes from which we will start the search for neighbourhood
+		$oNodes = DBObjectSet::FromLinkSet($oTarget, $this->m_sLinkSetAttCode, $this->m_sExtKeyToRemote);
+
+		// Neighbours, whatever their class
+		$aRelated = $oNodes->GetRelatedObjects($this->m_sRelationCode, $this->m_iMaxDepth);
+
+		$sRootClass = MetaModel::GetRootClass($this->m_sTargetClass);
+		if (array_key_exists($sRootClass, $aRelated))
 		{
+			$aLinksToCreate = array();
+			foreach($aRelated[$sRootClass] as $iKey => $oObject)
+			{
+				if (MetaModel::IsParentClass($this->m_sTargetClass, get_class($oObject)))
+				{
+					$oNewLink = MetaModel::NewObject($this->m_sTargetLinkClass);
+					$oNewLink->Set($this->m_sTargetExtKey, $iKey);
+					//$oNewLink->Set('role', 'concerned by an impacted CI');
+
+					$aLinksToCreate[] = $oNewLink;
+				}
+			}
+			$oSetToCreate = DBObjectSet::FromArray($this->m_sTargetLinkClass, $aLinksToCreate);
 			$this->m_aValues[$oObject->GetKey()] = $oObject->GetAsHTML($oObject->GetName());
 		}
+
 		return true;
 	}