Related objects:

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

SVN:trunk[314]
This commit is contained in:
Romain Quetiez
2010-03-09 14:09:51 +00:00
parent 5a09dc6e2b
commit e2524d28d7
7 changed files with 78 additions and 66 deletions

View File

@@ -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)

View File

@@ -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);

View File

@@ -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');}

View File

@@ -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));

View File

@@ -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, ":");

View File

@@ -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;
}

View File

@@ -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;
}