diff --git a/application/displayblock.class.inc.php b/application/displayblock.class.inc.php index 24520875d..f15c7daa7 100644 --- a/application/displayblock.class.inc.php +++ b/application/displayblock.class.inc.php @@ -44,6 +44,7 @@ class DisplayBlock { const TAG_BLOCK = 'itopblock'; protected $m_oFilter; + protected $m_aConditions; // Conditions added to the filter -> avoid duplicate conditions protected $m_sStyle; protected $m_bAsynchronous; protected $m_aParams; @@ -51,7 +52,8 @@ class DisplayBlock public function __construct(DBObjectSearch $oFilter, $sStyle = 'list', $bAsynchronous = false, $aParams = array(), $oSet = null) { - $this->m_oFilter = $oFilter; + $this->m_oFilter = clone $oFilter; + $this->m_aConditions = array(); $this->m_sStyle = $sStyle; $this->m_bAsynchronous = $bAsynchronous; $this->m_aParams = $aParams; @@ -1015,6 +1017,15 @@ EOF */ protected function AddCondition($sFilterCode, $condition) { + // Workaround to an issue revealed whenever a condition on org_id is applied twice (with a hierarchy of organizations) + // Moreover, it keeps the query as simple as possible + if (isset($this->m_aConditions[$sFilterCode]) && $condition == $this->m_aConditions[$sFilterCode]) + { + // Skip + return; + } + $this->m_aConditions[$sFilterCode] = $condition; + $sClass = $this->m_oFilter->GetClass(); $bConditionAdded = false; diff --git a/core/dbobjectsearch.class.php b/core/dbobjectsearch.class.php index df5803262..62cb6d8d4 100644 --- a/core/dbobjectsearch.class.php +++ b/core/dbobjectsearch.class.php @@ -548,24 +548,38 @@ class DBObjectSearch { if ($bTranslateMainAlias) { - $sOrigAlias = $this->GetClassAlias(); + $sOrigAlias = $this->GetFirstJoinedClassAlias(); if (array_key_exists($sOrigAlias, $aClassAliases)) { - $sNewAlias = MetaModel::GenerateUniqueAlias($aClassAliases, $sOrigAlias, $this->GetClass()); -//echo "
Generating a new alias for $sOrigAlias (already used). It is now: $sNewAlias
\n"; - $this->m_aSelectedClasses[$sNewAlias] = $this->GetClass(); - unset($this->m_aSelectedClasses[$sOrigAlias]); - - $this->m_aClasses[$sNewAlias] = $this->GetClass(); - unset($this->m_aClasses[$sOrigAlias]); + $sNewAlias = MetaModel::GenerateUniqueAlias($aClassAliases, $sOrigAlias, $this->GetFirstJoinedClass()); + if (isset($this->m_aSelectedClasses[$sOrigAlias])) + { + $this->m_aSelectedClasses[$sNewAlias] = $this->GetFirstJoinedClass(); + unset($this->m_aSelectedClasses[$sOrigAlias]); + } + + // TEMPORARY ALGORITHM (m_aClasses is not correctly updated, it is not possible to add a subtree onto a subnode) + // Replace the element at the same position (unset + set is not enough because the hash array is ordered) + $aPrevList = $this->m_aClasses; + $this->m_aClasses = array(); + foreach ($aPrevList as $sSomeAlias => $sSomeClass) + { + if ($sSomeAlias == $sOrigAlias) + { + $this->m_aClasses[$sNewAlias] = $sSomeClass; // note: GetFirstJoinedClass now returns '' !!! + } + else + { + $this->m_aClasses[$sSomeAlias] = $sSomeClass; + } + } // Translate the condition expression with the new alias $aAliasTranslation[$sOrigAlias]['*'] = $sNewAlias; } -//echo "Adding the alias ".$this->GetClass()." as ".$this->GetClassAlias()."
\n"; // add the alias into the filter aliases list - $aClassAliases[$this->GetClassAlias()] = $this->GetClass(); + $aClassAliases[$this->GetFirstJoinedClassAlias()] = $this->GetFirstJoinedClass(); } foreach($this->m_aPointingTo as $sExtKeyAttCode=>$aPointingTo) @@ -598,7 +612,6 @@ class DBObjectSearch protected function AddCondition_PointingTo_InNameSpace(DBObjectSearch $oFilter, $sExtKeyAttCode, &$aClassAliases, &$aAliasTranslation, $iOperatorCode) { -//echo "Calling: AddCondition_PointingTo_InNameSpace([
".print_r($aClassAliases, true)."], [
".print_r($aAliasTranslation, true)."]);"; if (!MetaModel::IsValidKeyAttCode($this->GetClass(), $sExtKeyAttCode)) { throw new CoreWarning("The attribute code '$sExtKeyAttCode' is not an external key of the class '{$this->GetClass()}' - the condition will be ignored"); @@ -620,27 +633,19 @@ class DBObjectSearch { if (array_key_exists($oFilter->GetClassAlias(), $this->m_aPointingTo[$sExtKeyAttCode][$iOperatorCode])) { -//echo "
[".__LINE__."]this->m_aPointingTo[$sExtKeyAttCode][$iOperatorCode][".$oFilter->GetFirstJoinedClassAlias()."]:
\n".print_r($this->m_aPointingTo[$sExtKeyAttCode][$iOperatorCode], true).";"; $bSamePointingTo = true; } } } -//echo "
[".__LINE__."]Calling: AddToNameSpace([".implode(',', $aClassAliases)."], [".implode(',', $aAliasTranslation)."]);
"; if ($bSamePointingTo) { -//echo "[".__LINE__."]AddPointingTo: Merging filters for [$sExtKeyAttCode][$iOperatorCode][".$oFilter->GetClassAlias()."]
"; // Same ext key, alias and same operator, merge the filters together -// $sAlias = $oFilter->GetClassAlias(); -//echo "[".__LINE__."]before: AddToNameSpace(aClassAliases[
\n".print_r($aClassAliases, true)."], aAliasTranslation[
\n".print_r($aAliasTranslation, true)."]);"; $oFilter->AddToNamespace($aClassAliases, $aAliasTranslation, true /* Don't translate the main alias */); -//echo "
[".__LINE__."]after: AddToNameSpace(aClassAliases[
\n".print_r($aClassAliases, true)."], aAliasTranslation[
\n".print_r($aAliasTranslation, true)."]);"; -// $this->m_aPointingTo[$sExtKeyAttCode][$iOperatorCode][$sAlias]->MergeWith($oFilter, $aClassAliases, $aAliasTranslation); $this->m_aPointingTo[$sExtKeyAttCode][$iOperatorCode][$oFilter->GetClassAlias()] = $oFilter; } else { -//echo "
[".__LINE__."]AddPointingTo: Adding a new PointingTo filter for [$sExtKeyAttCode][$iOperatorCode][".$oFilter->GetClassAlias()."]
"; $oFilter->AddToNamespace($aClassAliases, $aAliasTranslation); $this->m_aPointingTo[$sExtKeyAttCode][$iOperatorCode][$oFilter->GetClassAlias()] = $oFilter; }