• Модуль: 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;
}