mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-19 07:12:26 +02:00
(Retrofit from trunk on bahalf of rquetiez) N°436 Core API: Correctly (mathematically!) handle the "allow all data" flag, with UNIONS and INTERSECTIONS. Requires testing
SVN:2.3[4445]
This commit is contained in:
@@ -35,6 +35,11 @@ class DBObjectSearch extends DBSearch
|
|||||||
private $m_aPointingTo;
|
private $m_aPointingTo;
|
||||||
private $m_aReferencedBy;
|
private $m_aReferencedBy;
|
||||||
|
|
||||||
|
// By default, some information may be hidden to the current user
|
||||||
|
// But it may happen that we need to disable that feature
|
||||||
|
protected $m_bAllowAllData = false;
|
||||||
|
protected $m_bDataFiltered = false;
|
||||||
|
|
||||||
public function __construct($sClass, $sClassAlias = null)
|
public function __construct($sClass, $sClassAlias = null)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
@@ -52,6 +57,11 @@ class DBObjectSearch extends DBSearch
|
|||||||
$this->m_aReferencedBy = array();
|
$this->m_aReferencedBy = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function AllowAllData($bAllowAllData = true) {$this->m_bAllowAllData = $bAllowAllData;}
|
||||||
|
public function IsAllDataAllowed() {return $this->m_bAllowAllData;}
|
||||||
|
protected function IsDataFiltered() {return $this->m_bDataFiltered; }
|
||||||
|
protected function SetDataFiltered() {$this->m_bDataFiltered = true;}
|
||||||
|
|
||||||
// Create a search definition that leads to 0 result, still a valid search object
|
// Create a search definition that leads to 0 result, still a valid search object
|
||||||
static public function FromEmptySet($sClass)
|
static public function FromEmptySet($sClass)
|
||||||
{
|
{
|
||||||
@@ -655,6 +665,9 @@ class DBObjectSearch extends DBSearch
|
|||||||
$oLeftFilter = $this->DeepClone();
|
$oLeftFilter = $this->DeepClone();
|
||||||
$oRightFilter = $oRightFilter->DeepClone();
|
$oRightFilter = $oRightFilter->DeepClone();
|
||||||
|
|
||||||
|
$bAllowAllData = ($oLeftFilter->IsAllDataAllowed() && $oRightFilter->IsAllDataAllowed());
|
||||||
|
$oLeftFilter->AllowAllData($bAllowAllData);
|
||||||
|
|
||||||
if ($oLeftFilter->GetClass() != $oRightFilter->GetClass())
|
if ($oLeftFilter->GetClass() != $oRightFilter->GetClass())
|
||||||
{
|
{
|
||||||
if (MetaModel::IsParentClass($oLeftFilter->GetClass(), $oRightFilter->GetClass()))
|
if (MetaModel::IsParentClass($oLeftFilter->GetClass(), $oRightFilter->GetClass()))
|
||||||
@@ -810,7 +823,7 @@ class DBObjectSearch extends DBSearch
|
|||||||
return $this->m_oSearchCondition->ApplyParameters(array_merge($this->m_aParams, $aArgs));
|
return $this->m_oSearchCondition->ApplyParameters(array_merge($this->m_aParams, $aArgs));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function ToOQL($bDevelopParams = false, $aContextParams = null)
|
public function ToOQL($bDevelopParams = false, $aContextParams = null, $bWithAllowAllFlag = false)
|
||||||
{
|
{
|
||||||
// Currently unused, but could be useful later
|
// Currently unused, but could be useful later
|
||||||
$bRetrofitParams = false;
|
$bRetrofitParams = false;
|
||||||
@@ -850,6 +863,10 @@ class DBObjectSearch extends DBSearch
|
|||||||
{
|
{
|
||||||
$sRes .= " AND MATCHES '$sFullText'";
|
$sRes .= " AND MATCHES '$sFullText'";
|
||||||
}
|
}
|
||||||
|
if ($bWithAllowAllFlag && $this->m_bAllowAllData)
|
||||||
|
{
|
||||||
|
$sRes .= " ALLOW ALL DATA";
|
||||||
|
}
|
||||||
return $sRes;
|
return $sRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1131,9 +1148,33 @@ class DBObjectSearch extends DBSearch
|
|||||||
|
|
||||||
public function MakeSQLQuery($aAttToLoad, $bGetCount, $aModifierProperties, $aGroupByExpr = null, $aSelectedClasses = null)
|
public function MakeSQLQuery($aAttToLoad, $bGetCount, $aModifierProperties, $aGroupByExpr = null, $aSelectedClasses = null)
|
||||||
{
|
{
|
||||||
$oBuild = new QueryBuilderContext($this, $aModifierProperties, $aGroupByExpr, $aSelectedClasses);
|
// Hide objects that are not visible to the current user
|
||||||
|
//
|
||||||
|
$oSearch = $this;
|
||||||
|
if (!$this->IsAllDataAllowed() && !$this->IsDataFiltered())
|
||||||
|
{
|
||||||
|
$oVisibleObjects = UserRights::GetSelectFilter($this->GetClass(), $this->GetModifierProperties('UserRightsGetSelectFilter'));
|
||||||
|
if ($oVisibleObjects === false)
|
||||||
|
{
|
||||||
|
// Make sure this is a valid search object, saying NO for all
|
||||||
|
$oVisibleObjects = DBObjectSearch::FromEmptySet($this->GetClass());
|
||||||
|
}
|
||||||
|
if (is_object($oVisibleObjects))
|
||||||
|
{
|
||||||
|
$oVisibleObjects->AllowAllData();
|
||||||
|
$oSearch = $this->Intersect($oVisibleObjects);
|
||||||
|
$oSearch->SetDataFiltered();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// should be true at this point, meaning that no additional filtering
|
||||||
|
// is required
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$oSQLQuery = $this->MakeSQLObjectQuery($oBuild, $aAttToLoad, array());
|
$oBuild = new QueryBuilderContext($oSearch, $aModifierProperties, $aGroupByExpr, $aSelectedClasses);
|
||||||
|
|
||||||
|
$oSQLQuery = $oSearch->MakeSQLObjectQuery($oBuild, $aAttToLoad, array());
|
||||||
$oSQLQuery->SetCondition($oBuild->m_oQBExpressions->GetCondition());
|
$oSQLQuery->SetCondition($oBuild->m_oQBExpressions->GetCondition());
|
||||||
if ($aGroupByExpr)
|
if ($aGroupByExpr)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -42,14 +42,9 @@ abstract class DBSearch
|
|||||||
const JOIN_POINTING_TO = 0;
|
const JOIN_POINTING_TO = 0;
|
||||||
const JOIN_REFERENCED_BY = 1;
|
const JOIN_REFERENCED_BY = 1;
|
||||||
|
|
||||||
protected $m_bDataFiltered = false;
|
|
||||||
protected $m_bNoContextParameters = false;
|
protected $m_bNoContextParameters = false;
|
||||||
protected $m_aModifierProperties = array();
|
protected $m_aModifierProperties = array();
|
||||||
|
|
||||||
// By default, some information may be hidden to the current user
|
|
||||||
// But it may happen that we need to disable that feature
|
|
||||||
protected $m_bAllowAllData = false;
|
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -62,12 +57,11 @@ abstract class DBSearch
|
|||||||
return unserialize(serialize($this)); // Beware this serializes/unserializes the search and its parameters as well
|
return unserialize(serialize($this)); // Beware this serializes/unserializes the search and its parameters as well
|
||||||
}
|
}
|
||||||
|
|
||||||
public function AllowAllData() {$this->m_bAllowAllData = true;}
|
abstract public function AllowAllData();
|
||||||
public function IsAllDataAllowed() {return $this->m_bAllowAllData;}
|
abstract public function IsAllDataAllowed();
|
||||||
|
|
||||||
public function NoContextParameters() {$this->m_bNoContextParameters = true;}
|
public function NoContextParameters() {$this->m_bNoContextParameters = true;}
|
||||||
public function HasContextParameters() {return $this->m_bNoContextParameters;}
|
public function HasContextParameters() {return $this->m_bNoContextParameters;}
|
||||||
public function IsDataFiltered() {return $this->m_bDataFiltered; }
|
|
||||||
public function SetDataFiltered() {$this->m_bDataFiltered = true;}
|
|
||||||
|
|
||||||
public function SetModifierProperty($sPluginClass, $sProperty, $value)
|
public function SetModifierProperty($sPluginClass, $sProperty, $value)
|
||||||
{
|
{
|
||||||
@@ -219,7 +213,7 @@ abstract class DBSearch
|
|||||||
return $oSearchWithAlias;
|
return $oSearchWithAlias;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract public function ToOQL($bDevelopParams = false, $aContextParams = null);
|
abstract public function ToOQL($bDevelopParams = false, $aContextParams = null, $bWithAllowAllFlag = false);
|
||||||
|
|
||||||
static protected $m_aOQLQueries = array();
|
static protected $m_aOQLQueries = array();
|
||||||
|
|
||||||
@@ -492,39 +486,16 @@ abstract class DBSearch
|
|||||||
|
|
||||||
protected function GetSQLQuery($aOrderBy, $aArgs, $aAttToLoad, $aExtendedDataSpec, $iLimitCount, $iLimitStart, $bGetCount, $aGroupByExpr = null)
|
protected function GetSQLQuery($aOrderBy, $aArgs, $aAttToLoad, $aExtendedDataSpec, $iLimitCount, $iLimitStart, $bGetCount, $aGroupByExpr = null)
|
||||||
{
|
{
|
||||||
// Hide objects that are not visible to the current user
|
|
||||||
//
|
|
||||||
$oSearch = $this;
|
|
||||||
if (!$this->IsAllDataAllowed() && !$this->IsDataFiltered())
|
|
||||||
{
|
|
||||||
$oVisibleObjects = UserRights::GetSelectFilter($this->GetClass(), $this->GetModifierProperties('UserRightsGetSelectFilter'));
|
|
||||||
if ($oVisibleObjects === false)
|
|
||||||
{
|
|
||||||
// Make sure this is a valid search object, saying NO for all
|
|
||||||
$oVisibleObjects = DBObjectSearch::FromEmptySet($this->GetClass());
|
|
||||||
}
|
|
||||||
if (is_object($oVisibleObjects))
|
|
||||||
{
|
|
||||||
$oSearch = $this->Intersect($oVisibleObjects);
|
|
||||||
$oSearch->SetDataFiltered();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// should be true at this point, meaning that no additional filtering
|
|
||||||
// is required
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute query modifiers properties (can be set in the search itself, by the context, etc.)
|
// Compute query modifiers properties (can be set in the search itself, by the context, etc.)
|
||||||
//
|
//
|
||||||
$aModifierProperties = MetaModel::MakeModifierProperties($oSearch);
|
$aModifierProperties = MetaModel::MakeModifierProperties($this);
|
||||||
|
|
||||||
// Create a unique cache id
|
// Create a unique cache id
|
||||||
//
|
//
|
||||||
if (self::$m_bQueryCacheEnabled || self::$m_bTraceQueries)
|
if (self::$m_bQueryCacheEnabled || self::$m_bTraceQueries)
|
||||||
{
|
{
|
||||||
// Need to identify the query
|
// Need to identify the query
|
||||||
$sOqlQuery = $oSearch->ToOql();
|
$sOqlQuery = $this->ToOql(false, null, true);
|
||||||
|
|
||||||
if (count($aModifierProperties))
|
if (count($aModifierProperties))
|
||||||
{
|
{
|
||||||
@@ -553,7 +524,7 @@ abstract class DBSearch
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$sOqlQuery = "SELECTING... ".$oSearch->GetClass();
|
$sOqlQuery = "SELECTING... ".$this->GetClass();
|
||||||
$sOqlId = "query id ? n/a";
|
$sOqlId = "query id ? n/a";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,7 +570,7 @@ abstract class DBSearch
|
|||||||
if (!isset($oSQLQuery))
|
if (!isset($oSQLQuery))
|
||||||
{
|
{
|
||||||
$oKPI = new ExecutionKPI();
|
$oKPI = new ExecutionKPI();
|
||||||
$oSQLQuery = $oSearch->MakeSQLQuery($aAttToLoad, $bGetCount, $aModifierProperties, $aGroupByExpr);
|
$oSQLQuery = $this->MakeSQLQuery($aAttToLoad, $bGetCount, $aModifierProperties, $aGroupByExpr);
|
||||||
$oSQLQuery->SetSourceOQL($sOqlQuery);
|
$oSQLQuery->SetSourceOQL($sOqlQuery);
|
||||||
$oKPI->ComputeStats('MakeSQLQuery', $sOqlQuery);
|
$oKPI->ComputeStats('MakeSQLQuery', $sOqlQuery);
|
||||||
|
|
||||||
@@ -624,7 +595,7 @@ abstract class DBSearch
|
|||||||
$aExtendedFields = array();
|
$aExtendedFields = array();
|
||||||
foreach($aExtendedDataSpec['fields'] as $sColumn)
|
foreach($aExtendedDataSpec['fields'] as $sColumn)
|
||||||
{
|
{
|
||||||
$sColRef = $oSearch->GetClassAlias().'_extdata_'.$sColumn;
|
$sColRef = $this->GetClassAlias().'_extdata_'.$sColumn;
|
||||||
$aExtendedFields[$sColRef] = new FieldExpressionResolved($sColumn, $sTableAlias);
|
$aExtendedFields[$sColRef] = new FieldExpressionResolved($sColumn, $sTableAlias);
|
||||||
}
|
}
|
||||||
$oSQLQueryExt = new SQLObjectQuery($aExtendedDataSpec['table'], $sTableAlias, $aExtendedFields);
|
$oSQLQueryExt = new SQLObjectQuery($aExtendedDataSpec['table'], $sTableAlias, $aExtendedFields);
|
||||||
|
|||||||
@@ -55,6 +55,22 @@ class DBUnionSearch extends DBSearch
|
|||||||
$this->ComputeSelectedClasses();
|
$this->ComputeSelectedClasses();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function AllowAllData()
|
||||||
|
{
|
||||||
|
foreach ($this->aSearches as $oSearch)
|
||||||
|
{
|
||||||
|
$oSearch->AllowAllData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function IsAllDataAllowed()
|
||||||
|
{
|
||||||
|
foreach ($this->aSearches as $oSearch)
|
||||||
|
{
|
||||||
|
if ($oSearch->IsAllDataAllowed() === false) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the lowest common ancestor for each of the selected class
|
* Find the lowest common ancestor for each of the selected class
|
||||||
*/
|
*/
|
||||||
@@ -357,12 +373,12 @@ class DBUnionSearch extends DBSearch
|
|||||||
/**
|
/**
|
||||||
* Overloads for query building
|
* Overloads for query building
|
||||||
*/
|
*/
|
||||||
public function ToOQL($bDevelopParams = false, $aContextParams = null)
|
public function ToOQL($bDevelopParams = false, $aContextParams = null, $bWithAllowAllFlag = false)
|
||||||
{
|
{
|
||||||
$aSubQueries = array();
|
$aSubQueries = array();
|
||||||
foreach ($this->aSearches as $oSearch)
|
foreach ($this->aSearches as $oSearch)
|
||||||
{
|
{
|
||||||
$aSubQueries[] = $oSearch->ToOQL($bDevelopParams, $aContextParams);
|
$aSubQueries[] = $oSearch->ToOQL($bDevelopParams, $aContextParams, $bWithAllowAllFlag);
|
||||||
}
|
}
|
||||||
$sRet = implode(' UNION ', $aSubQueries);
|
$sRet = implode(' UNION ', $aSubQueries);
|
||||||
return $sRet;
|
return $sRet;
|
||||||
|
|||||||
Reference in New Issue
Block a user