- Модуль: tasks
- Путь к файлу: ~/bitrix/modules/tasks/classes/general/task.php
- Класс: CTasks
- Вызов: CTasks::FilterCreate
static function FilterCreate($fname, $vals, $type, &$bFullJoin, $cOperationType = false, $bSkipEmpty = true)
{
global $DB;
if (!is_array($vals))
{
$vals = [$vals];
}
else
{
$vals = array_unique(array_values($vals));
}
if (count($vals) < 1)
{
return "";
}
if (is_bool($cOperationType))
{
if ($cOperationType === true)
{
$cOperationType = "N";
}
else
{
$cOperationType = "E";
}
}
if ($cOperationType == "G")
{
$strOperation = ">";
}
elseif ($cOperationType == "GE")
{
$strOperation = ">=";
}
elseif ($cOperationType == "LE")
{
$strOperation = "<=";
}
elseif ($cOperationType == "L")
{
$strOperation = "<";
}
elseif ($cOperationType === "NI")
{
$strOperation = "!=";
}
else
{
$strOperation = "=";
}
$bFullJoin = false;
$bWasLeftJoin = false;
// special case for array of number
if ($type === 'number' && is_array($vals) && count($vals) > 1 && count($vals) < 80)
{
$vals = implode(', ', array_unique(array_map('intval', $vals)));
$res = $fname . ' ' . ($cOperationType == 'N' ? 'not' : '') . ' in (' . $vals . ')';
// INNER JOIN in this case
if ($cOperationType != "N")
{
$bFullJoin = true;
}
return $res;
}
$res = [];
foreach ($vals as $key => $val)
{
if (($type === 'number') && !$val)
{
$val = 0;
}
if (!$bSkipEmpty || $val === 0 || $val <> '' || (is_bool($val) && $val === false))
{
switch ($type)
{
case "string_equal":
if ($val == '')
{
$res[] = ($cOperationType == "N" ? "NOT" : "") .
"(" .
$fname .
" IS NULL OR " .
$DB->Length($fname) .
"<=0)";
}
else
{
$res[] = "(" .
($cOperationType == "N" ? " " . $fname . " IS NULL OR NOT (" : "") .
$fname .
$strOperation .
"'" .
$DB->ForSql($val) .
"'" .
($cOperationType == "N" ? ")" : "") .
")";
}
break;
case "string":
if ($cOperationType == "?")
{
if ($val === 0 || $val <> '')
{
$res[] = GetFilterQuery($fname, $val, "Y", [], "N");
}
}
elseif ($cOperationType == "S")
{
$res[] = "(UPPER(" . $fname . ") LIKE UPPER('%" . $DB->ForSqlLike($val) . "%'))";
}
elseif ($cOperationType == "NS")
{
$res[] = "(UPPER(" . $fname . ") NOT LIKE UPPER('%" . $DB->ForSqlLike($val) . "%'))";
}
elseif ($cOperationType == "FTL")
{
$sqlWhere = new CSQLWhere();
$res[] = $sqlWhere->matchLike($fname, $val);
}
elseif ($val == '')
{
$res[] = ($cOperationType == "N" ? "NOT" : "") .
"(" .
$fname .
" IS NULL OR " .
$DB->Length($fname) .
"<=0)";
}
else
{
if ($strOperation == "=")
{
$res[] = "(" .
($cOperationType == "N" ? " " . $fname . " IS NULL OR NOT (" : "") .
($fname .
" " .
($strOperation ==
"="
? "LIKE"
: $strOperation) .
" '" .
$DB->ForSqlLike(
$val
) .
"'") .
($cOperationType == "N" ? ")" : "") .
")";
}
else
{
$res[] = "(" .
($cOperationType == "N" ? " " . $fname . " IS NULL OR NOT (" : "") .
($fname .
" " .
$strOperation .
" '" .
$DB->ForSql($val) .
"'") .
($cOperationType == "N" ? ")" : "") .
")";
}
}
break;
case "fulltext":
echo '';
if ($cOperationType == "FT" || $cOperationType == "FTI")
{
$sqlWhere = new CSQLWhere();
$res[] = $sqlWhere->match($fname, $val, $cOperationType == "FT");
}
elseif ($cOperationType == "FTL")
{
$sqlWhere = new CSQLWhere();
$res[] = $sqlWhere->matchLike($fname, $val);
}
elseif ($cOperationType == "?")
{
if ($val === 0 || $val <> '')
{
$sr = GetFilterQuery(
$fname,
$val,
"Y",
[],
($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 ($val == '')
{
$res[] = ($bNegative ? "NOT" : "")
. "("
. $fname
. " IS NULL OR "
. $DB->Length($fname)
. "<=0)";
}
elseif ($strOperation == "=" && $cOperationType != "I" && $cOperationType != "NI")
{
$res[] = ($cOperationType == "N" ? " " . $fname . " IS NULL OR NOT " : "") .
"(" .
($fname .
" LIKE '" .
$DB->ForSqlLike($val) .
"'") .
")";
}
else
{
$res[] = ($bNegative ? " " . $fname . " IS NULL OR NOT " : "") .
"(" .
($fname .
" " .
$strOperation .
" '" .
$DB->ForSql($val) .
"'") .
")";
}
}
break;
case "date":
if ($val == '')
{
$res[] = ($cOperationType == "N" ? "NOT" : "") . "(" . $fname . " IS NULL)";
}
else
{
$res[] = "(" .
($cOperationType == "N" ? " " . $fname . " IS NULL OR NOT (" : "") .
$fname .
" " .
$strOperation .
" " .
$val .
"" .
($cOperationType == "N" ? ")" : "") .
")";
}
break;
case "number":
$isOperationTypeN = $cOperationType === 'N';
if ($vals[$key] === false || strlen($val) <= 0)
{
$res[] = ($isOperationTypeN ? 'NOT' : '') . "({$fname} IS NULL)";
}
else
{
$res[] = "("
. ($isOperationTypeN ? "{$fname} IS NULL OR NOT (" : "")
. "{$fname} {$strOperation} '" . DoubleVal($val) . "'"
. ($isOperationTypeN ? ")" : "")
. ")";
}
break;
case "number_wo_nulls":
$res[] = "(" .
($cOperationType == "N" ? "NOT (" : "") .
$fname .
" " .
$strOperation .
" " .
DoubleVal($val) .
($cOperationType == "N" ? ")" : "") .
")";
break;
case "null_or_zero":
if ($cOperationType == "N")
{
$res[] = "((" . $fname . " IS NOT NULL) AND (" . $fname . " != 0))";
}
else
{
$res[] = "((" . $fname . " IS NULL) OR (" . $fname . " = 0))";
}
break;
case "left_existence":
if ($strOperation != '=')
{
CTaskAssert::logError('Operation type not supported for ' . $fname . ': ' . $strOperation);
}
elseif ($val != 'Y' && $val != 'N' && 0)
{
CTaskAssert::logError('Filter value not supported for ' . $fname . ': ' . $val);
}
else
{
$otNot = $cOperationType == "N";
if (($val == 'Y' && !$otNot) || ($val == 'N' && $otNot))
{
$res[] = "(" . $fname . " IS NOT NULL)";
}
else
{
$res[] = "(" . $fname . " IS NULL)";
}
}
break;
case 'reference':
$val = trim($val);
if (preg_match('#^[a-z0-9_]+(.{1}[a-z0-9_]+)*$#i', $val))
{
if ($cOperationType === 'E')
{
$res[] = '(' . $fname . ' = ' . $DB->ForSql($val) . ')';
}
elseif ($cOperationType === 'N')
{
$res[] = '(' . $fname . ' != ' . $DB->ForSql($val) . ')';
}
elseif ($cOperationType === 'L')
{
$res[] = '(' . $fname . ' < ' . $DB->ForSql($val) . ')';
}
elseif ($cOperationType === 'G')
{
$res[] = '(' . $fname . ' > ' . $DB->ForSql($val) . ')';
}
else
{
CTaskAssert::logError('[0xcf017223] Operation type not supported: ' . $cOperationType);
}
}
else
{
CTaskAssert::logError("Bad reference: " . $fname . " => '" . $val . "'");
}
break;
}
// INNER JOIN in this case
if (($val === 0 || $val <> '') && $cOperationType != "N")
{
$bFullJoin = true;
}
else
{
$bWasLeftJoin = true;
}
}
}
$strResult = "";
for ($i = 0, $resCnt = count($res); $i < $resCnt; $i++)
{
if ($i > 0)
{
$strResult .= ($cOperationType == "N" ? " AND " : " OR ");
}
$strResult .= $res[$i];
}
if (count($res) > 1)
{
$strResult = "(" . $strResult . ")";
}
if ($bFullJoin && $bWasLeftJoin && $cOperationType != "N")
{
$bFullJoin = false;
}
return $strResult;
}