mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°2589 - Infinite loops when logging with a Contact having a non empty TagSet field
This commit is contained in:
@@ -979,7 +979,7 @@ abstract class DBSearch
|
||||
$aAttToLoad = array();
|
||||
$oSQLQuery = $oQueryFilter->GetSQLQuery(array(), $aArgs, $aAttToLoad, null, 0, 0, false, $aGroupByExpr, $aSelectExpr);
|
||||
|
||||
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams());
|
||||
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams(), $this->GetExpectedArguments());
|
||||
try
|
||||
{
|
||||
$bBeautifulSQL = self::$m_bTraceQueries || self::$m_bDebugQuery || self::$m_bIndentQueries;
|
||||
@@ -997,6 +997,10 @@ abstract class DBSearch
|
||||
return $sRes;
|
||||
}
|
||||
|
||||
function GetExpectedArguments()
|
||||
{
|
||||
return $this->GetCriteria()->ListParameters();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a SQL query from the current search
|
||||
@@ -1076,7 +1080,7 @@ abstract class DBSearch
|
||||
else
|
||||
{
|
||||
// The complete list of arguments will include magic arguments (e.g. current_user->attcode)
|
||||
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams());
|
||||
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams(), $this->GetExpectedArguments());
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
@@ -667,6 +667,16 @@ class DBUnionSearch extends DBSearch
|
||||
return $oSQLQuery;
|
||||
}
|
||||
|
||||
function GetExpectedArguments()
|
||||
{
|
||||
$aVariableCriteria = array();
|
||||
foreach ($this->aSearches as $oSearch)
|
||||
{
|
||||
$aVariableCriteria = array_merge($aVariableCriteria, $oSearch->GetExpectedArguments());
|
||||
}
|
||||
|
||||
return $aVariableCriteria;
|
||||
}
|
||||
/**
|
||||
* @return \Expression
|
||||
*/
|
||||
|
||||
@@ -4127,44 +4127,52 @@ abstract class MetaModel
|
||||
*
|
||||
* @param array $aArgs Context arguments (some can be persistent objects)
|
||||
* @param array $aMoreArgs Other query parameters
|
||||
* @param array $aExpectedArgs variables present in the query
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function PrepareQueryArguments($aArgs, $aMoreArgs = array())
|
||||
public static function PrepareQueryArguments($aArgs, $aMoreArgs = array(), $aExpectedArgs = null)
|
||||
{
|
||||
$aScalarArgs = array();
|
||||
foreach(array_merge($aArgs, $aMoreArgs) as $sArgName => $value)
|
||||
if (is_null($aExpectedArgs) || count($aExpectedArgs) > 0 || count($aMoreArgs)>0)
|
||||
{
|
||||
if (self::IsValidObject($value))
|
||||
foreach (array_merge($aArgs, $aMoreArgs) as $sArgName => $value)
|
||||
{
|
||||
if (strpos($sArgName, '->object()') === false)
|
||||
if (self::IsValidObject($value))
|
||||
{
|
||||
// Normalize object arguments
|
||||
$aScalarArgs[$sArgName.'->object()'] = $value;
|
||||
if (strpos($sArgName, '->object()') === false)
|
||||
{
|
||||
// Normalize object arguments
|
||||
$aScalarArgs[$sArgName.'->object()'] = $value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Leave as is
|
||||
$aScalarArgs[$sArgName] = $value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Leave as is
|
||||
$aScalarArgs[$sArgName] = $value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_scalar($value))
|
||||
{
|
||||
$aScalarArgs[$sArgName] = (string)$value;
|
||||
}
|
||||
elseif (is_null($value))
|
||||
{
|
||||
$aScalarArgs[$sArgName] = null;
|
||||
}
|
||||
elseif (is_array($value))
|
||||
{
|
||||
$aScalarArgs[$sArgName] = $value;
|
||||
if (is_scalar($value))
|
||||
{
|
||||
$aScalarArgs[$sArgName] = (string)$value;
|
||||
}
|
||||
elseif (is_null($value))
|
||||
{
|
||||
$aScalarArgs[$sArgName] = null;
|
||||
}
|
||||
elseif (is_array($value))
|
||||
{
|
||||
$aScalarArgs[$sArgName] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return static::AddMagicPlaceholders($aScalarArgs, $aExpectedArgs);
|
||||
}
|
||||
else
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
return static::AddMagicPlaceholders($aScalarArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4172,21 +4180,68 @@ abstract class MetaModel
|
||||
*
|
||||
* @return array of placeholder (or name->object()) => value (or object)
|
||||
*/
|
||||
public static function AddMagicPlaceholders($aPlaceholders)
|
||||
public static function AddMagicPlaceholders($aPlaceholders, $aExpectedArgs = null)
|
||||
{
|
||||
// Add standard magic arguments
|
||||
//
|
||||
$aPlaceholders['current_contact_id'] = UserRights::GetContactId(); // legacy
|
||||
|
||||
$oUser = UserRights::GetUserObject();
|
||||
if (!is_null($oUser))
|
||||
if (is_null($aExpectedArgs))
|
||||
{
|
||||
$aPlaceholders['current_user->object()'] = $oUser;
|
||||
$aPlaceholders['current_contact_id'] = UserRights::GetContactId(); // legacy
|
||||
|
||||
$oContact = UserRights::GetContactObject();
|
||||
if (!is_null($oContact))
|
||||
$oUser = UserRights::GetUserObject();
|
||||
if (!is_null($oUser))
|
||||
{
|
||||
$aPlaceholders['current_contact->object()'] = $oContact;
|
||||
$aPlaceholders['current_user->object()'] = $oUser;
|
||||
|
||||
$oContact = UserRights::GetContactObject();
|
||||
if (!is_null($oContact))
|
||||
{
|
||||
$aPlaceholders['current_contact->object()'] = $oContact;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aCurrentUser = array();
|
||||
$aCurrentContact = array();
|
||||
foreach ($aExpectedArgs as $expression)
|
||||
{
|
||||
$aName = explode('->', $expression->GetName());
|
||||
if ($aName[0] == 'current_contact_id')
|
||||
{
|
||||
$aPlaceholders['current_contact_id'] = UserRights::GetContactId();
|
||||
}
|
||||
if ($aName[0] == 'current_user')
|
||||
{
|
||||
array_push($aCurrentUser, $aName[1]);
|
||||
}
|
||||
if ($aName[0] == 'current_contact')
|
||||
{
|
||||
array_push($aCurrentContact, $aName[1]);
|
||||
}
|
||||
}
|
||||
if (count($aCurrentUser) > 0)
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL("SELECT User WHERE id = :id");
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('id' => UserRights::GetUserId()));
|
||||
$oSet->OptimizeColumnLoad($aCurrentUser);
|
||||
$oUser = $oSet->fetch();
|
||||
$aPlaceholders['current_user->object()'] = $oUser;
|
||||
foreach ($aCurrentUser as $sField)
|
||||
{
|
||||
$aPlaceholders['current_user->'.$sField] = $oUser->Get($sField);
|
||||
}
|
||||
}
|
||||
if (count($aCurrentContact) > 0)
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL("SELECT Contact WHERE id = :id");
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('id' => UserRights::GetContactId()));
|
||||
$oSet->OptimizeColumnLoad($aCurrentContact);
|
||||
$oUser = $oSet->fetch();
|
||||
foreach ($aCurrentContact as $sField)
|
||||
{
|
||||
$aPlaceholders['current_contact->'.$sField] = $oUser->Get($sField);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -158,6 +158,9 @@ abstract class Expression
|
||||
// recursively builds an array of [classAlias][fieldName] => value
|
||||
abstract public function ListConstantFields();
|
||||
|
||||
// recursively builds an array of parameters to give to current request
|
||||
abstract public function ListParameters();
|
||||
|
||||
public function RequiresField($sClass, $sFieldName)
|
||||
{
|
||||
// #@# todo - optimize : this is called quite often when building a single query !
|
||||
@@ -354,6 +357,11 @@ class SQLExpression extends Expression
|
||||
return array();
|
||||
}
|
||||
|
||||
public function ListParameters()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function RenameParam($sOldName, $sNewName)
|
||||
{
|
||||
// Do nothing, since there is nothing to rename
|
||||
@@ -593,6 +601,13 @@ class BinaryExpression extends Expression
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
public function ListParameters()
|
||||
{
|
||||
$aLeft = $this->GetLeftExpr()->ListParameters();
|
||||
$aRight = $this->GetRightExpr()->ListParameters();
|
||||
return array_merge($aLeft, $aRight);
|
||||
}
|
||||
|
||||
public function RenameParam($sOldName, $sNewName)
|
||||
{
|
||||
$this->GetLeftExpr()->RenameParam($sOldName, $sNewName);
|
||||
@@ -934,6 +949,11 @@ class UnaryExpression extends Expression
|
||||
return array();
|
||||
}
|
||||
|
||||
public function ListParameters()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function RenameParam($sOldName, $sNewName)
|
||||
{
|
||||
// Do nothing
|
||||
@@ -1848,6 +1868,12 @@ class VariableExpression extends UnaryExpression
|
||||
}
|
||||
return $oRet;
|
||||
}
|
||||
|
||||
public function ListParameters()
|
||||
{
|
||||
return array($this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Temporary, until we implement functions and expression casting!
|
||||
@@ -2001,6 +2027,16 @@ class ListExpression extends Expression
|
||||
return $aRes;
|
||||
}
|
||||
|
||||
public function ListParameters()
|
||||
{
|
||||
$aRes = array();
|
||||
foreach ($this->m_aExpressions as $oExpr)
|
||||
{
|
||||
$aRes = array_merge($aRes, $oExpr->ListParameters());
|
||||
}
|
||||
return $aRes;
|
||||
}
|
||||
|
||||
public function RenameParam($sOldName, $sNewName)
|
||||
{
|
||||
foreach ($this->m_aExpressions as $key => $oExpr)
|
||||
@@ -2142,6 +2178,11 @@ class NestedQueryExpression extends Expression
|
||||
return $this->m_oNestedQuery->ListConstantFields();
|
||||
}
|
||||
|
||||
public function ListParameters()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function RenameParam($sOldName, $sNewName)
|
||||
{
|
||||
$this->m_oNestedQuery->RenameParam($sOldName, $sNewName);
|
||||
@@ -2289,6 +2330,11 @@ class FunctionExpression extends Expression
|
||||
return $aRes;
|
||||
}
|
||||
|
||||
public function ListParameters()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function RenameParam($sOldName, $sNewName)
|
||||
{
|
||||
foreach ($this->m_aArgs as $key => $oExpr)
|
||||
@@ -2570,6 +2616,11 @@ class IntervalExpression extends Expression
|
||||
return array();
|
||||
}
|
||||
|
||||
public function ListParameters()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function RenameParam($sOldName, $sNewName)
|
||||
{
|
||||
$this->m_oValue->RenameParam($sOldName, $sNewName);
|
||||
@@ -2716,6 +2767,11 @@ class CharConcatExpression extends Expression
|
||||
return $aRes;
|
||||
}
|
||||
|
||||
public function ListParameters()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function RenameParam($sOldName, $sNewName)
|
||||
{
|
||||
foreach ($this->m_aExpressions as $key => $oExpr)
|
||||
|
||||
Reference in New Issue
Block a user