- Модуль: iblock
- Путь к файлу: ~/bitrix/modules/iblock/classes/general/iblock.php
- Класс: CAllIBlock
- Вызов: CAllIBlock::FilterCreateEx
static function FilterCreateEx($fname, $vals, $type, &$bFullJoin, $cOperationType=false, $bSkipEmpty = true)
{
/** @global CDatabase $DB */
global $DB;
if(!is_array($vals))
$vals=Array($vals);
if(count($vals)<1)
return "";
if(is_bool($cOperationType))
{
if($cOperationType===true)
$cOperationType = "N";
else
$cOperationType = "E";
}
if($cOperationType=="E") // most req operation
$strOperation = "=";
elseif($cOperationType=="G")
$strOperation = ">";
elseif($cOperationType=="GE")
$strOperation = ">=";
elseif($cOperationType=="LE")
$strOperation = "<=";
elseif($cOperationType=="L")
$strOperation = "<";
elseif($cOperationType=='B')
$strOperation = array('BETWEEN', 'AND');
elseif($cOperationType=='NB')
$strOperation = array('BETWEEN', 'AND');
else
$strOperation = "=";
if($cOperationType=='B' || $cOperationType=='NB')
{
if(count($vals)==2 && !is_array($vals[0]))
$vals = array($vals);
}
$bNegative = mb_substr($cOperationType, 0, 1) == "N";
$bFullJoin = false;
$bWasLeftJoin = false;
$arIn = Array(); //This will gather equality number conditions
$bWasNull = false;
$res = Array();
foreach($vals as $val)
{
if(
!$bSkipEmpty
|| (is_array($strOperation) && is_array($val))
|| (is_bool($val) && $val===false)
|| (string)$val <> ''
)
{
switch ($type)
{
case "string_equal":
if($cOperationType=="?")
{
if((string)$val <> '')
$res[] = GetFilterQuery($fname, $val, "N");
}
elseif($cOperationType=="S" || $cOperationType=="NS")
$res[] = ($cOperationType=="NS"?" ".$fname." IS NULL OR NOT ":"")."(".CIBlock::_Upper($fname)." LIKE ".CIBlock::_Upper("'%".CIBlock::ForLIKE($val)."%'").")";
elseif(($cOperationType=="B" || $cOperationType=="NB") && is_array($val) && count($val)==2)
$res[] = ($cOperationType=="NB"?" ".$fname." IS NULL OR NOT ":"")."(".CIBlock::_Upper($fname)." ".$strOperation[0]." '".CIBlock::_Upper($DB->ForSql($val[0]))."' ".$strOperation[1]." '".CIBlock::_Upper($DB->ForSql($val[1]))."')";
else
{
if((string)$val == '')
$res[] = ($cOperationType=="N"?"NOT":"")."(".$fname." IS NULL OR ".$DB->Length($fname)."<=0)";
else
$res[] = ($cOperationType=="N"?" ".$fname." IS NULL OR NOT ":"")."(".CIBlock::_Upper($fname).$strOperation.CIBlock::_Upper("'".$DB->ForSql($val)."'").")";
}
break;
case "string":
if($cOperationType=="?")
{
if((string)$val <> '')
{
$sr = GetFilterQuery($fname, $val, "Y", array(), ($fname=="BE.SEARCHABLE_CONTENT" || $fname=="BE.DETAIL_TEXT" ? "Y" : "N"));
if($sr != "0")
$res[] = $sr;
}
}
elseif(($cOperationType=="B" || $cOperationType=="NB") && is_array($val) && count($val)==2)
{
$res[] = ($cOperationType=="NB"?" ".$fname." IS NULL OR NOT ":"")."(".CIBlock::_Upper($fname)." ".$strOperation[0]." '".CIBlock::_Upper($DB->ForSql($val[0]))."' ".$strOperation[1]." '".CIBlock::_Upper($DB->ForSql($val[1]))."')";
}
elseif($cOperationType=="S" || $cOperationType=="NS")
$res[] = ($cOperationType=="NS"?" ".$fname." IS NULL OR NOT ":"")."(".CIBlock::_Upper($fname)." LIKE ".CIBlock::_Upper("'%".CIBlock::ForLIKE($val)."%'").")";
elseif($cOperationType=="FTL")
{
$sqlWhere = new CSQLWhere();
$condition = $sqlWhere->matchLike($fname, $val);
if ($condition != '')
$res[] = $condition;
}
else
{
if((string)$val == '')
$res[] = ($bNegative? "NOT": "")."(".$fname." IS NULL OR ".$DB->Length($fname)."<=0)";
else
if($strOperation=="=" && $cOperationType!="I" && $cOperationType!="NI")
$res[] = ($cOperationType=="N"?" ".$fname." IS NULL OR NOT ":"")."(".($DB->type=="ORACLE"?CIBlock::_Upper($fname)." LIKE ".CIBlock::_Upper("'".$DB->ForSqlLike($val)."'")." ESCAPE '\'" : $fname." LIKE '".$DB->ForSqlLike($val)."'").")";
else
$res[] = ($bNegative? " ".$fname." IS NULL OR NOT ": "")."(".($DB->type=="ORACLE"?CIBlock::_Upper($fname)." ".$strOperation." ".CIBlock::_Upper("'".$DB->ForSql($val)."'")." " : $fname." ".$strOperation." '".$DB->ForSql($val)."'").")";
}
break;
case "date":
if(!is_array($val) && $val == '')
{
$res[] = ($cOperationType == "N" ? "NOT" : "") . "(" . $fname . " IS NULL)";
}
elseif (($cOperationType=="B" || $cOperationType=="NB") && is_array($val) && count($val)==2)
{
if (
static::isCorrectFullFormatDate($DB->ForSql($val[0])) &&
static::isCorrectFullFormatDate($DB->ForSql($val[1]))
)
{
$res[] = ($cOperationType == 'NB' ? ' ' . $fname . ' IS NULL OR NOT ' : '')
. '('
. $fname
. ' '
. $strOperation[0]
. ' '
. $DB->CharToDateFunction($DB->ForSql($val[0]), "FULL")
. ' '
. $strOperation[1]
. ' '
. $DB->CharToDateFunction($DB->ForSql($val[1]), "FULL")
. ')';
}
}
else
{
if (static::isCorrectFullFormatDate($DB->ForSql($val)))
{
$res[] = ($bNegative ? " " . $fname . " IS NULL OR NOT " : "")
. "("
. $fname
. " "
. $strOperation
. " "
. $DB->CharToDateFunction($DB->ForSql($val), "FULL")
. ")";
}
}
break;
case "number":
if($val === '' || $val === null || $val === false)
{
$res[] = $fname." IS ".($bNegative? "NOT NULL": " NULL");
$bWasNull = true;
}
elseif($cOperationType=="B" || $cOperationType=="NB")
{
if(is_array($val))
{
if(count($val)==2)
$res[] = ($cOperationType=='NB'?' '.$fname.' IS NULL OR NOT ':'').'('.$fname.' '.$strOperation[0].' ''.DoubleVal($val[0]).'' '.$strOperation[1].' ''.DoubleVal($val[1]).'')';
else
$res[] = ($cOperationType=='NB'?' '.$fname.' IS NULL OR NOT ':'').'('.$fname.' = ''.DoubleVal(array_pop($val[0])).'')';
}
else
{
$res[] = ($cOperationType=='NB'?' '.$fname.' IS NULL OR NOT ':'').'('.$fname.' = ''.DoubleVal($val).'')';
}
}
elseif($bNegative)
{
$res[] = " ".$fname." IS NULL OR NOT (".$fname." ".$strOperation." '".DoubleVal($val)."')";
if($strOperation == '=')
$arIn[] = DoubleVal($val);
}
else
{
$res[] = "(".$fname." ".$strOperation." '".DoubleVal($val)."')";
if($strOperation == '=')
$arIn[] = DoubleVal($val);
}
break;
case "number_above":
if($val === '' || $val === null || $val === false)
$res[] = ($cOperationType=="N"?"NOT":"")."(".$fname." IS NULL)";
else
$res[] = ($cOperationType=="N"?" ".$fname." IS NULL OR NOT ":"")."(".$fname." ".$strOperation." '".$DB->ForSql($val)."')";
break;
case "fulltext":
if($cOperationType=="FT" || $cOperationType=="FTI")
{
$sqlWhere = new CSQLWhere();
$condition = $sqlWhere->match($fname, $val, $cOperationType=="FT");
if ($condition != '')
$res[] = $condition;
}
elseif($cOperationType=="FTL")
{
$sqlWhere = new CSQLWhere();
$condition = $sqlWhere->matchLike($fname, $val);
if ($condition != '')
$res[] = $condition;
}
elseif($cOperationType=="?")
{
if((string)$val <> '')
{
$sr = GetFilterQuery($fname, $val, "Y", array(), ($fname=="BE.SEARCHABLE_CONTENT" || $fname=="BE.DETAIL_TEXT" ? "Y" : "N"));
if($sr != "0")
$res[] = $sr;
}
}
elseif(($cOperationType=="B" || $cOperationType=="NB") && is_array($val) && count($val)==2)
{
$res[] = ($cOperationType=="NB"?" ".$fname." IS NULL OR NOT ":"")."(".CIBlock::_Upper($fname)." ".$strOperation[0]." '".CIBlock::_Upper($DB->ForSql($val[0]))."' ".$strOperation[1]." '".CIBlock::_Upper($DB->ForSql($val[1]))."')";
}
elseif($cOperationType=="S" || $cOperationType=="NS")
$res[] = ($cOperationType=="NS"?" ".$fname." IS NULL OR NOT ":"")."(".CIBlock::_Upper($fname)." LIKE ".CIBlock::_Upper("'%".CIBlock::ForLIKE($val)."%'").")";
else
{
if((string)$val == '')
$res[] = ($bNegative? "NOT": "")."(".$fname." IS NULL OR ".$DB->Length($fname)."<=0)";
else
if($strOperation=="=" && $cOperationType!="I" && $cOperationType!="NI")
$res[] = ($cOperationType=="N"?" ".$fname." IS NULL OR NOT ":"")."(".($DB->type=="ORACLE"?CIBlock::_Upper($fname)." LIKE ".CIBlock::_Upper("'".$DB->ForSqlLike($val)."'")." ESCAPE '\'" : $fname." LIKE '".$DB->ForSqlLike($val)."'").")";
else
$res[] = ($bNegative? " ".$fname." IS NULL OR NOT ": "")."(".($DB->type=="ORACLE"?CIBlock::_Upper($fname)." ".$strOperation." ".CIBlock::_Upper("'".$DB->ForSql($val)."'")." " : $fname." ".$strOperation." '".$DB->ForSql($val)."'").")";
}
break;
}
if((is_array($val) || (string)$val <> '') && !$bNegative)
$bFullJoin = true;
else
$bWasLeftJoin = true;
}
}
$strResult = "";
$cntIn = count($arIn);
if(
!$bWasNull
&& $cntIn > 1
&& (
$cntIn < 2000
|| $DB->type == "MYSQL"
)
)
{
if($bNegative)
$res = array($fname." IS NULL OR NOT (".$fname." IN ('".implode("', '", $arIn)."'))");
else
$res = array($fname." IN ('".implode("', '", $arIn)."')");
}
foreach($res as $i=>$val)
{
if($i>0)
$strResult .= ($bNegative? " AND ": " OR ");
$strResult .= "(".$val.")";
}
if($strResult!="")
$strResult = "(".$strResult.")";
if($bFullJoin && $bWasLeftJoin && !$bNegative)
$bFullJoin = false;
return $strResult;
}