diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php index 111b870a6..af67f46ad 100644 --- a/application/cmdbabstract.class.inc.php +++ b/application/cmdbabstract.class.inc.php @@ -752,7 +752,8 @@ $sHtml = EOF .$sHtml; //$oP->add_ready_script("table.tablesorter( { headers: { 0: {sorter: false}}, widgets: ['myZebra', 'truncatedList']} ).tablesorterPager({container: $('#pager')});\n"); - $sExtraParams = addslashes(str_replace('"', "'", json_encode($aExtraParams))); // JSON encode, change the style of the quotes and escape them + $aArgs = $oSet->GetArgs(); + $sExtraParams = addslashes(str_replace('"', "'", json_encode(array_merge($aExtraParams, $aArgs)))); // JSON encode, change the style of the quotes and escape them $sSelectMode = ''; $sHeaders = ''; if ($bSelectMode) diff --git a/core/cmdbobject.class.inc.php b/core/cmdbobject.class.inc.php index 090a49373..bc6b325be 100644 --- a/core/cmdbobject.class.inc.php +++ b/core/cmdbobject.class.inc.php @@ -498,24 +498,22 @@ class CMDBObjectSet extends DBObjectSet static public function FromScratch($sClass) { $oFilter = new CMDBSearchFilter($sClass); - $oRetSet = new CMDBObjectSet($oFilter); // THE ONLY DIFF IS HERE - // NOTE: THIS DOES NOT WORK IF m_bLoaded is private... - // BUT IT THAT CASE YOU DO NOT GET ANY ERROR !!!!! + $oFilter->AddConditionExpression(new FalseExpression()); + $oRetSet = new self($oFilter); + // NOTE: THIS DOES NOT WORK IF m_bLoaded is private in the base class (and you will not get any error message) $oRetSet->m_bLoaded = true; // no DB load return $oRetSet; } + // create an object set ex nihilo + // input = array of objects static public function FromArray($sClass, $aObjects) { - $oFilter = new CMDBSearchFilter($sClass); - $oRetSet = new CMDBObjectSet($oFilter); // THE ONLY DIFF IS HERE - // NOTE: THIS DOES NOT WORK IF m_bLoaded is private... - // BUT IT THAT CASE YOU DO NOT GET ANY ERROR !!!!! - $oRetSet->m_bLoaded = true; // no DB load - $oRetSet->AddObjectArray($aObjects); + $oRetSet = self::FromScratch($sClass); + $oRetSet->AddObjectArray($aObjects, $sClass); return $oRetSet; } - + static public function FromArrayAssoc($aClasses, $aObjects) { // In a perfect world, we should create a complete tree of DBObjectSearch, diff --git a/core/dbobjectsearch.class.php b/core/dbobjectsearch.class.php index 8d0d4636e..72edb3ac0 100644 --- a/core/dbobjectsearch.class.php +++ b/core/dbobjectsearch.class.php @@ -221,6 +221,11 @@ class DBObjectSearch // ? is that usefull/enough, do I need to rebuild the list after the subqueries ? } + public function MergeConditionExpression($oExpression) + { + $this->m_oSearchCondition = $this->m_oSearchCondition->LogOr($oExpression); + } + public function AddConditionExpression($oExpression) { $this->m_oSearchCondition = $this->m_oSearchCondition->LogAnd($oExpression); @@ -320,6 +325,61 @@ class DBObjectSearch $this->AddConditionExpression($oNewCondition); } + /** + * Specify a condition on external keys or link sets + * @param sAttSpec Can be either an attribute code or extkey->[sAttSpec] or linkset->[sAttSpec] and so on, recursively + * Example: infra_list->ci_id->location_id->country + * @param value The value to match + * @return void + */ + public function AddConditionAdvanced($sAttSpec, $value) + { + $sClass = $this->GetClass(); + + $iPos = strpos($sAttSpec, '->'); + if ($iPos !== false) + { + $sAttCode = substr($sAttSpec, 0, $iPos); + $sSubSpec = substr($sAttSpec, $iPos + 2); + + if (!MetaModel::IsValidAttCode($sClass, $sAttCode)) + { + throw new Exception("Invalid attribute code '$sClass/$sAttCode' in condition specification '$sAttSpec'"); + } + + $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); + if ($oAttDef->IsLinkSet()) + { + $sTargetClass = $oAttDef->GetLinkedClass(); + $sExtKeyToMe = $oAttDef->GetExtKeyToMe(); + + $oNewFilter = new DBObjectSearch($sTargetClass); + $oNewFilter->AddConditionAdvanced($sSubSpec, $value); + + $this->AddCondition_ReferencedBy($oNewFilter, $sExtKeyToMe); + } + elseif ($oAttDef->IsExternalKey(EXTKEY_ABSOLUTE)) + { + $sTargetClass = $oAttDef->GetTargetClass(EXTKEY_ABSOLUTE); + + $oNewFilter = new DBObjectSearch($sTargetClass); + $oNewFilter->AddConditionAdvanced($sSubSpec, $value); + + $this->AddCondition_PointingTo($oNewFilter, $sAttCode); + } + else + { + throw new Exception("Attribute specification '$sAttSpec', '$sAttCode' should be either a link set or an external key"); + } + } + else + { + // $sAttSpec is an attribute code + // + $this->AddCondition($sAttSpec, $value); + } + } + public function AddCondition_FullText($sFullText) { $this->m_aFullText[] = $sFullText; diff --git a/core/dbobjectset.class.php b/core/dbobjectset.class.php index 88cc8a913..654f397f3 100644 --- a/core/dbobjectset.class.php +++ b/core/dbobjectset.class.php @@ -32,6 +32,7 @@ class DBObjectSet { private $m_oFilter; + private $m_aAddedIds; // Ids of objects added private $m_aOrderBy; public $m_bLoaded; private $m_aData; @@ -41,6 +42,7 @@ class DBObjectSet public function __construct(DBObjectSearch $oFilter, $aOrderBy = array(), $aArgs = array(), $aExtendedDataSpec = null, $iLimitCount = 0, $iLimitStart = 0) { $this->m_oFilter = $oFilter; + $this->m_aAddedIds = array(); $this->m_aOrderBy = $aOrderBy; $this->m_aArgs = $aArgs; $this->m_aAttToLoad = null; @@ -128,7 +130,8 @@ class DBObjectSet static public function FromScratch($sClass) { - $oFilter = new CMDBSearchFilter($sClass); + $oFilter = new DBObjectSearch($sClass); + $oFilter->AddConditionExpression(new FalseExpression()); $oRetSet = new self($oFilter); $oRetSet->m_bLoaded = true; // no DB load return $oRetSet; @@ -138,9 +141,7 @@ class DBObjectSet // input = array of objects static public function FromArray($sClass, $aObjects) { - $oFilter = new CMDBSearchFilter($sClass); - $oRetSet = new self($oFilter); - $oRetSet->m_bLoaded = true; // no DB load + $oRetSet = self::FromScratch($sClass); $oRetSet->AddObjectArray($aObjects, $sClass); return $oRetSet; } @@ -268,8 +269,19 @@ class DBObjectSet public function GetFilter() { - // #@# This is false as soon as the set has been manipulated (AddObject...) - return $this->m_oFilter; + if (count($this->m_aAddedIds) == 0) + { + return $this->m_oFilter; + } + else + { + $oFilter = $this->m_oFilter; + $oIdListExpr = ListExpression::FromScalars($this->m_aAddedIds); + $oIdExpr = new FieldExpression('id', $oFilter->GetClassAlias()); + $oIdInList = new BinaryExpression($oIdExpr, 'IN', $oIdListExpr); + $oFilter->MergeConditionExpression($oIdInList); + return $oFilter; + } } public function GetClass() @@ -287,6 +299,11 @@ class DBObjectSet return MetaModel::GetRootClass($this->GetClass()); } + public function GetArgs() + { + return $this->m_aArgs; + } + public function SetLimit($iLimitCount, $iLimitStart = 0) { $this->m_iLimitCount = $iLimitCount; @@ -427,6 +444,7 @@ class DBObjectSet if (!is_null($oObject)) { $this->m_aId2Row[$sClassAlias][$oObject->GetKey()] = $iNextPos; + $this->m_aAddedIds[] = $oObject->GetKey(); } } @@ -442,6 +460,7 @@ class DBObjectSet if (!is_null($oObject)) { $this->m_aId2Row[$sClassAlias][$oObject->GetKey()] = $iNextPos; + $this->m_aAddedIds[] = $oObject->GetKey(); } } } diff --git a/pages/ajax.render.php b/pages/ajax.render.php index a155525f9..0e46e0144 100644 --- a/pages/ajax.render.php +++ b/pages/ajax.render.php @@ -51,7 +51,7 @@ try switch($operation) { case 'pagination': - $sExtraParams = stripslashes(utils::ReadParam('extra_params', '')); + $sExtraParams = stripslashes(utils::ReadParam('extra_param', '')); $aExtraParams = array(); if (!empty($sExtraParams)) {