public function MkFilter($arFilter, &$arJoinProps, &$arAddWhereFields, $level = 0, $bPropertyLeftJoin = false)
{
global $DB, $USER;
$connection = BitrixMainApplication::getConnection();
$helper = $connection->getSqlHelper();
$catalogIncluded = Loader::includeModule('catalog');
$catalogFields = array();
$arSqlSearch = Array();
$permSQL = "";
$arSectionFilter = Array(
"LOGIC" => "",
"BE" => array(),
"BS" => array(),
);
if (!is_array($arFilter))
$arFilter = array();
foreach($arFilter as $key=>$val)
{
$key = mb_strtoupper($key);
$p = mb_strpos($key, "PROPERTY_");
if($p!==false && ($p<4))
{
$arFilter[mb_substr($key, 0, $p)."PROPERTY"][mb_substr($key, $p + 9)] = $val;
unset($arFilter[$key]);
}
else
{
$p = strpos($key, 'SUBQUERY');
if ($p !== false && $p <4)
{
if (!empty($val) && is_array($val))
{
$arFilter[substr($key, 0, $p).'ID'] = static::SubQuery(
$val['FIELD'],
$val['FILTER']
);
}
unset($arFilter[$key]);
}
}
}
if (isset($arFilter["LOGIC"]) && $arFilter["LOGIC"] == "OR")
{
$Logic = "OR";
unset($arFilter["LOGIC"]);
$bPropertyLeftJoin = true;
}
else
{
$Logic = "AND";
}
if ($Logic === "AND" && $level === 0 && isset($arFilter["IBLOCK_ID"]))
{
$f = new BitrixIblockPropertyIndexQueryBuilder($arFilter["IBLOCK_ID"]);
if ($f->isValid())
{
$arJoinProps["FC"] = $f->getFilterSql($arFilter, $arSqlSearch);
$arJoinProps["FC_DISTINCT"] = $f->getDistinct();
}
}
foreach($arFilter as $orig_key => $val)
{
$res = CIBlock::MkOperationFilter($orig_key);
$key = $res["FIELD"];
$cOperationType = $res["OPERATION"];
//it was done before $key = strtoupper($key);
switch($key."")
{
case "ACTIVE":
case "DETAIL_TEXT_TYPE":
case "PREVIEW_TEXT_TYPE":
$arSqlSearch[] = CIBlock::FilterCreateEx("BE.".$key, $val, "string_equal", $bFullJoinTmp, $cOperationType);
break;
case "NAME":
case "XML_ID":
case "TMP_ID":
case "DETAIL_TEXT":
case "PREVIEW_TEXT":
case "CODE":
case "TAGS":
case "WF_COMMENTS":
$arSqlSearch[] = CIBlock::FilterCreateEx("BE.".$key, $val, "string", $bFullJoinTmp, $cOperationType);
break;
case "SEARCHABLE_CONTENT":
if ($DB->IndexExists("b_iblock_element", array("SEARCHABLE_CONTENT")))
{
$arSqlSearch[] = CIBlock::FilterCreateEx("BE.".$key, $val, "fulltext", $bFullJoinTmp, $cOperationType);
}
else
{
if ($cOperationType == "FT")
$cOperationType = "FTL";
elseif ($cOperationType == "FTI")
$cOperationType = "E";
$arSqlSearch[] = CIBlock::FilterCreateEx("BE.".$key, $val, "string", $bFullJoinTmp, $cOperationType);
}
break;
case "ID":
if(is_object($val))
{
/** @var CIBlockElement $val */
$val->prepareSql(array($val->strField), $val->arFilter, false, false);
$arSqlSearch[] = 'BE.'.$key.(mb_substr($cOperationType, 0, 1) == "N"? ' NOT': '').' IN (
SELECT '.$val->sSelect.'
FROM '.$val->sFrom.'
WHERE 1=1
'.$val->sWhere.'
)'
;
}
else
{
$arSqlSearch[] = CIBlock::FilterCreateEx("BE.".$key, $val, "number", $bFullJoinTmp, $cOperationType);
}
break;
case "SHOW_COUNTER":
case "WF_PARENT_ELEMENT_ID":
case "WF_STATUS_ID":
case "SORT":
case "CREATED_BY":
case "MODIFIED_BY":
case "PREVIEW_PICTURE":
case "DETAIL_PICTURE":
case "IBLOCK_ID":
case "IBLOCK_SECTION_ID":
$arSqlSearch[] = CIBlock::FilterCreateEx("BE.".$key, $val, "number", $bFullJoinTmp, $cOperationType);
break;
case "TIMESTAMP_X":
case "DATE_CREATE":
case "SHOW_COUNTER_START":
$sqlSearch = CIBlock::FilterCreateEx("BE.".$key, $val, "date", $bFullJoinTmp, $cOperationType);
if($sqlSearch <> '')
{
$arSqlSearch[] = $sqlSearch;
}
break;
case "EXTERNAL_ID":
$arSqlSearch[] = CIBlock::FilterCreateEx("BE.XML_ID", $val, "string", $bFullJoinTmp, $cOperationType);
break;
case "IBLOCK_TYPE":
$arSqlSearch[] = CIBlock::FilterCreateEx("B.IBLOCK_TYPE_ID", $val, "string", $bFullJoinTmp, $cOperationType);
break;
case "CHECK_PERMISSIONS":
if ($val == 'Y')
{
$arFilter['MIN_PERMISSION'] ??= CIBlockRights::PUBLIC_READ;
$permissionsBy = null;
if (isset($arFilter['PERMISSIONS_BY']))
{
$permissionsBy = (int)$arFilter['PERMISSIONS_BY'];
if ($permissionsBy < 0)
$permissionsBy = null;
}
if ($permissionsBy !== null)
$permSQL = self::_check_rights_sql($arFilter["MIN_PERMISSION"], $permissionsBy);
elseif (!is_object($USER) || !$USER->IsAdmin())
$permSQL = self::_check_rights_sql($arFilter["MIN_PERMISSION"]);
unset($permissionsBy);
}
break;
case "CHECK_BP_PERMISSIONS":
if(IsModuleInstalled('bizproc') && (!is_object($USER) || !$USER->IsAdmin()))
{
if(is_array($val))
{
$MODULE_ID = $DB->ForSQL($val["MODULE_ID"]);
$ENTITY = $DB->ForSQL($val["ENTITY"]);
$PERMISSION = $DB->ForSQL($val["PERMISSION"]);
$arUserGroups = array();
if(is_array($val["GROUPS"]))
{
$USER_ID = intval($val["USER_ID"]);
foreach($val["GROUPS"] as $GROUP_ID)
{
$GROUP_ID = intval($GROUP_ID);
if($GROUP_ID)
$arUserGroups[$GROUP_ID] = $GROUP_ID;
}
}
else
{
$USER_ID = 0;
}
}
else
{
$MODULE_ID = "iblock";
$ENTITY = "CIBlockDocument";
$PERMISSION = $val;
$arUserGroups = false;
$USER_ID = 0;
}
if($PERMISSION == "read" || $PERMISSION == "write")
{
if(!is_array($arUserGroups) && is_object($USER))
{
$USER_ID = intval($USER->GetID());
$arUserGroups = $USER->GetUserGroupArray();
}
if(!is_array($arUserGroups) || count($arUserGroups) <= 0)
$arUserGroups = array(2);
$arSqlSearch[] = "EXISTS (
SELECT S.DOCUMENT_ID_INT
FROM
b_bp_workflow_state S
INNER JOIN b_bp_workflow_permissions P ON S.ID = P.WORKFLOW_ID
WHERE
S.DOCUMENT_ID_INT = BE.ID
AND S.MODULE_ID = '$MODULE_ID'
AND S.ENTITY = '$ENTITY'
AND P.PERMISSION = '$PERMISSION'
AND (
P.OBJECT_ID IN ('".implode("', '", $arUserGroups)."')
OR (P.OBJECT_ID = 'Author' AND BE.CREATED_BY = $USER_ID)
OR (P.OBJECT_ID = ".$DB->Concat("'USER_'", "'$USER_ID'").")
)
)";
}
}
break;
case "CHECK_BP_VIRTUAL_PERMISSIONS":
if (
IsModuleInstalled('bizproc')
&& (!is_object($USER) || !$USER->IsAdmin())
)
{
if (!in_array($val, array("read", "create", "admin")))
$val = "admin";
$userId = is_object($USER)? (int)$USER->GetID(): 0;
$arUserGroups = is_object($USER)? $USER->GetUserGroupArray(): false;
if (!is_array($arUserGroups) || empty($arUserGroups))
$arUserGroups = array(2);
$arSqlSearch[] = "EXISTS (
SELECT S.DOCUMENT_ID_INT
FROM b_bp_workflow_state S
INNER JOIN b_bp_workflow_permissions P ON S.ID = P.WORKFLOW_ID
WHERE S.DOCUMENT_ID_INT = BE.ID
AND S.MODULE_ID = 'bizproc'
AND S.ENTITY = 'CBPVirtualDocument'
AND
(P.PERMISSION = '".$val."'
AND (
P.OBJECT_ID IN ('".implode("', '", $arUserGroups)."')
OR (P.OBJECT_ID = 'Author' AND BE.CREATED_BY = ".$userId.")
OR (P.OBJECT_ID = ".$DB->Concat("'USER_'", "'".$userId."'").")
)
)
)";
}
break;
case "LID":
case "SITE_ID":
case "IBLOCK_LID":
case "IBLOCK_SITE_ID":
$flt = CIBlock::FilterCreateEx("SITE_ID", $val, "string_equal", $bFullJoinTmp, $cOperationType);
if ($flt !== '')
$arSqlSearch[] = ($cOperationType == "N" ? "NOT " : "")."EXISTS (
SELECT IBLOCK_ID FROM b_iblock_site WHERE IBLOCK_ID = B.ID
AND ".$flt."
)";
break;
case "DATE_ACTIVE_FROM":
$sqlSearch = CIBlock::FilterCreateEx("BE.ACTIVE_FROM", $val, "date", $bFullJoinTmp, $cOperationType);
if ($sqlSearch <> '')
{
$arSqlSearch[] = $sqlSearch;
}
break;
case "DATE_ACTIVE_TO":
$sqlSearch = CIBlock::FilterCreateEx("BE.ACTIVE_TO", $val, "date", $bFullJoinTmp, $cOperationType);
if ($sqlSearch <> '')
{
$arSqlSearch[] = $sqlSearch;
}
break;
case "IBLOCK_ACTIVE":
$arSqlSearch[] = CIBlock::FilterCreateEx("B.ACTIVE", $val, "string_equal", $bFullJoinTmp, $cOperationType);
break;
case "IBLOCK_CODE":
$arSqlSearch[] = CIBlock::FilterCreateEx("B.CODE", $val, "string", $bFullJoinTmp, $cOperationType);
break;
case "ID_ABOVE":
$arSqlSearch[] = CIBlock::FilterCreateEx("BE.ID", $val, "number_above", $bFullJoinTmp, $cOperationType);
break;
case "ID_LESS":
$arSqlSearch[] = CIBlock::FilterCreateEx("BE.ID", $val, "number_less", $bFullJoinTmp, $cOperationType);
break;
case "ACTIVE_FROM":
$val = (string)$val;
if ($val !== '')
{
$isCorrect = CIBlock::isCorrectFullFormatDate($DB->ForSql($val));
if ($isCorrect)
{
$arSqlSearch[] = "(BE.ACTIVE_FROM "
. ($cOperationType == "N" ? "<" : ">=")
. $DB->CharToDateFunction($DB->ForSql($val), "FULL")
. ($cOperationType == "N" ? "" : " OR BE.ACTIVE_FROM IS NULL")
. ")";
}
}
break;
case "ACTIVE_TO":
$val = (string)$val;
if ($val !== '')
{
$isCorrect = CIBlock::isCorrectFullFormatDate($DB->ForSql($val));
if ($isCorrect)
{
$arSqlSearch[] = "(BE.ACTIVE_TO "
. ($cOperationType == "N" ? ">" : "<=")
. $DB->CharToDateFunction($DB->ForSql($val), "FULL")
. ($cOperationType == "N" ? "" : " OR BE.ACTIVE_TO IS NULL")
. ")";
}
}
break;
case "ACTIVE_DATE":
$val = (string)$val;
if($val !== '')
$arSqlSearch[] = ($cOperationType=="N"?" NOT":"")."((BE.ACTIVE_TO >= ".$DB->GetNowFunction()." OR BE.ACTIVE_TO IS NULL) AND (BE.ACTIVE_FROM <= ".$DB->GetNowFunction()." OR BE.ACTIVE_FROM IS NULL))";
break;
case "DATE_MODIFY_FROM":
$val = (string)$val;
if ($val !== '')
{
$isCorrect = CIBlock::isCorrectFullFormatDate($DB->ForSql($val));
if ($isCorrect)
{
$arSqlSearch[] = "(BE.TIMESTAMP_X " .
($cOperationType == "N" ? "<" : ">=") . $DB->CharToDateFunction($DB->ForSql($val), "FULL") .
($cOperationType == "N" ? "" : " OR BE.TIMESTAMP_X IS NULL") . ")";
}
}
break;
case "DATE_MODIFY_TO":
$val = (string)$val;
if ($val !== '')
{
$isCorrect = CIBlock::isCorrectFullFormatDate($DB->ForSql($val));
if ($isCorrect)
{
$arSqlSearch[] = "(BE.TIMESTAMP_X " .
($cOperationType == "N" ? ">" : "<=") . $DB->CharToDateFunction($DB->ForSql($val), "FULL") .
($cOperationType == "N" ? "" : " OR BE.TIMESTAMP_X IS NULL") . ")";
}
}
break;
case "WF_NEW":
if($val=="Y" || $val=="N")
$arSqlSearch[] = CIBlock::FilterCreateEx("BE.WF_NEW", "Y", "string_equal", $bFullJoinTmp, ($val=="Y"?false:true), false);
break;
case "MODIFIED_USER_ID":
$arSqlSearch[] = CIBlock::FilterCreateEx("BE.MODIFIED_BY", $val, "number", $bFullJoinTmp, $cOperationType);
break;
case "CREATED_USER_ID":
$arSqlSearch[] = CIBlock::FilterCreateEx("BE.CREATED_BY", $val, "number", $bFullJoinTmp, $cOperationType);
break;
case "RATING_USER_ID":
$arSqlSearch[] = CIBlock::FilterCreateEx("RVV.USER_ID", $val, "number", $bFullJoinTmp, $cOperationType);
$arJoinProps["RVV"] = array(
"bFullJoin" => $bFullJoinTmp,
);
break;
case "WF_STATUS":
$arSqlSearch[] = CIBlock::FilterCreateEx("BE.WF_STATUS_ID", $val, "number", $bFullJoinTmp, $cOperationType);
break;
case "WF_LOCK_STATUS":
if($val <> '')
{
$USER_ID = is_object($USER)? intval($USER->GetID()): 0;
$lockInterval = COption::GetOptionInt("workflow", "MAX_LOCK_TIME", 60) * 60;
$arSqlSearch[] = "case when BE.WF_DATE_LOCK is null then 'green' when " . $helper->addSecondsToDateTime($lockInterval, 'BE.WF_DATE_LOCK') . " < " . $helper->getCurrentDateTimeFunction() . " then 'green' when BE.WF_LOCKED_BY = " . $USER_ID . " then 'yellow' else 'red' end) = '" . $DB->ForSql($val) . "'";
}
break;
case "WF_LAST_STATUS_ID":
$arSqlSearch[] = "exists (
select
history.ID
from
b_iblock_element history
where
history.WF_PARENT_ELEMENT_ID = BE.ID
and history.WF_STATUS_ID = ".intval($val)."
and history.ID = (
select max(history0.ID) LAST_ID
from b_iblock_element history0
where history0.WF_PARENT_ELEMENT_ID = BE.ID
)
)
";
break;
case "SECTION_ACTIVE":
if($arFilter["INCLUDE_SUBSECTIONS"]==="Y")
$arSectionFilter["BS"][] = "BSubS.ACTIVE = 'Y'";
else
$arSectionFilter["BS"][] = "BS.ACTIVE = 'Y'";
break;
case "SECTION_GLOBAL_ACTIVE":
if($arFilter["INCLUDE_SUBSECTIONS"]==="Y")
$arSectionFilter["BS"][] = "BSubS.GLOBAL_ACTIVE = 'Y'";
else
$arSectionFilter["BS"][] = "BS.GLOBAL_ACTIVE = 'Y'";
break;
case "SUBSECTION":
if (!is_array($val))
$val=Array($val);
//Find out margins of sections
$arUnknownMargins = array();
foreach($val as $i=>$section)
{
if(!is_array($section))
$arUnknownMargins[intval($section)] = intval($section);
}
if (!empty($arUnknownMargins))
{
$rs = $DB->Query("SELECT ID, LEFT_MARGIN, RIGHT_MARGIN FROM b_iblock_section WHERE ID in (".implode(", ", $arUnknownMargins).")");
while($ar = $rs->Fetch())
{
$arUnknownMargins[intval($ar["ID"])] = array(
intval($ar["LEFT_MARGIN"]),
intval($ar["RIGHT_MARGIN"]),
);
}
foreach($val as $i=>$section)
{
if(!is_array($section))
$val[$i] = $arUnknownMargins[intval($section)];
}
}
//Now sort them out
$arMargins = array();
foreach($val as $i=>$section)
{
if(is_array($section) && (count($section) == 2))
{
$left = intval($section[0]);
$right = intval($section[1]);
if($left > 0 && $right > 0)
$arMargins[$left] = $right;
}
}
ksort($arMargins);
//Remove subsubsections of the sections
$prev_right = 0;
foreach($arMargins as $left => $right)
{
if($right <= $prev_right)
unset($arMargins[$left]);
else
$prev_right = $right;
}
if(isset($arFilter["INCLUDE_SUBSECTIONS"]) && $arFilter["INCLUDE_SUBSECTIONS"] === "Y")
$bsAlias = "BSubS";
else
$bsAlias = "BS";
$res = "";
foreach($arMargins as $left => $right)
{
if($res!="")
$res .= ($cOperationType=="N"?" AND ":" OR ");
$res .= ($cOperationType == "N"? " NOT ": " ")."($bsAlias.LEFT_MARGIN >= ".$left." AND $bsAlias.RIGHT_MARGIN <= ".$right.")n";;
}
if($res!="")
$arSectionFilter["BS"][] = "(".$res.")";
break;
case "SECTION_ID":
if(!is_array($val))
$val = array($val);
$arSections = array();
foreach($val as $section_id)
{
$section_id = (int)$section_id;
$arSections[$section_id] = $section_id;
}
if($cOperationType=="N")
{
if (isset($arSections[0]))
{
$arSectionFilter["BE"][] = "BE.IN_SECTIONS<>'N'";
$arSectionFilter["LOGIC"] = "AND";
unset($arSections[0]);
if(!empty($arSections))
$arSectionFilter["BS"][] = "BS.ID NOT IN (".implode(", ", $arSections).")";
}
elseif(!empty($arSections))
{
$arSectionFilter["BE"][] = "BE.IN_SECTIONS='N'";
$arSectionFilter["LOGIC"] = "OR";
$arSectionFilter["BS"][] = "BS.ID NOT IN (".implode(", ", $arSections).")";
}
}
else
{
if (isset($arSections[0]))
{
$allSections = (
isset($arFilter["INCLUDE_SUBSECTIONS"])
&& $arFilter["INCLUDE_SUBSECTIONS"] === "Y"
&& count($arSections) == 1
);
if (!$allSections)
{
$arSectionFilter["BE"][] = "BE.IN_SECTIONS='N'";
$arSectionFilter["LOGIC"] = "OR";
}
unset($arSections[0]);
}
if(!empty($arSections))
$arSectionFilter["BS"][] = "BS.ID IN (".implode(", ", $arSections).")";
}
break;
case "SECTION_CODE":
if(!is_array($val))
$val = array($val);
$arSections = array();
foreach($val as $section_code)
{
$section_code = $DB->ForSql($section_code);
$arSections[$section_code] = $section_code;
}
if($cOperationType=="N")
{
if(array_key_exists("", $arSections))
{
$arSectionFilter["BE"][] = "BE.IN_SECTIONS<>'N'";
$arSectionFilter["LOGIC"] = "AND";
unset($arSections[""]);
if(!empty($arSections))
$arSectionFilter["BS"][] = "BS.CODE NOT IN ('".implode("', '", $arSections)."')";
}
elseif(!empty($arSections))
{
$arSectionFilter["BE"][] = "BE.IN_SECTIONS='N'";
$arSectionFilter["LOGIC"] = "OR";
$arSectionFilter["BS"][] = "BS.CODE NOT IN ('".implode("', '", $arSections)."')";
}
}
else
{
if(array_key_exists("", $arSections))
{
$arSectionFilter["BE"][] = "BE.IN_SECTIONS='N'";
$arSectionFilter["LOGIC"] = "OR";
unset($arSections[""]);
}
if(!empty($arSections))
$arSectionFilter["BS"][] = "BS.CODE IN ('".implode("', '", $arSections)."')";
}
break;
case "PROPERTY":
$iblockIds = CIBlock::_MergeIBArrays(
$arFilter["IBLOCK_ID"] ?? false,
$arFilter["IBLOCK_CODE"] ?? false,
$arFilter["~IBLOCK_ID"] ?? false,
$arFilter["~IBLOCK_CODE"] ?? false
);
foreach($val as $propID=>$propVAL)
{
$res = CIBlock::MkOperationFilter($propID);
$res["LOGIC"] = $Logic;
$res["LEFT_JOIN"] = $bPropertyLeftJoin;
if(preg_match("/^([^.]+)\.([^.]+)$/", $res["FIELD"], $arMatch))
{
$db_prop = CIBlockProperty::GetPropertyArray($arMatch[1], $iblockIds);
if(is_array($db_prop) && $db_prop["PROPERTY_TYPE"] == "E")
{
$res["FIELD"] = $arMatch;
CIBlockElement::MkPropertyFilter($res, $cOperationType, $propVAL, $db_prop, $arJoinProps, $arSqlSearch);
}
}
else
{
$db_prop = CIBlockProperty::GetPropertyArray($res["FIELD"], $iblockIds);
if ($db_prop)
{
CIBlockElement::MkPropertyFilter($res, $cOperationType, $propVAL, $db_prop, $arJoinProps, $arSqlSearch);
}
}
}
unset($iblockIds);
break;
default:
if(is_numeric($orig_key))
{
if (is_array($val))
{
//Here is hint for better property resolution:
if (!isset($val["~IBLOCK_ID"]))
{
if (isset($arFilter["IBLOCK_ID"]))
$val["~IBLOCK_ID"] = $arFilter["IBLOCK_ID"];
elseif (isset($arFilter["~IBLOCK_ID"]))
$val["~IBLOCK_ID"] = $arFilter["~IBLOCK_ID"];
}
if (!isset($val["~IBLOCK_CODE"]))
{
if (isset($arFilter["IBLOCK_CODE"]))
$val["~IBLOCK_CODE"] = $arFilter["IBLOCK_CODE"];
elseif (isset($arFilter["~IBLOCK_CODE"]))
$val["~IBLOCK_CODE"] = $arFilter["~IBLOCK_CODE"];
}
//Subfilter process
$arSubSqlSearch = CIBlockElement::MkFilter($val, $arJoinProps, $arAddWhereFields, $level + 1, $bPropertyLeftJoin);
if(trim($arSubSqlSearch[0], "nt") <> '')
{
$arSqlSearch[] = str_replace("nttt", "ntttt", $arSubSqlSearch[0]);
}
}
}
elseif ($catalogIncluded && CProductQueryBuilder::isValidField($key))
{
$catalogFields[$orig_key] = $val;
$arAddWhereFields[$orig_key] = $val;
}
break;
}
}
if ($catalogIncluded && !empty($catalogFields))
{
$catalogQueryResult = CProductQueryBuilder::makeFilter($catalogFields);
// catalog join set in CIBlockElement::prepareSql
if (!empty($catalogQueryResult) && !empty($catalogQueryResult['filter']))
$arSqlSearch = array_merge($arSqlSearch, $catalogQueryResult['filter']);
unset($catalogQueryResult);
}
unset($catalogFields);
//SECTION sub filter
$sWhere = "";
foreach($arSectionFilter["BS"] as $strFilter)
{
if ($strFilter !== '')
{
if ($sWhere !== '')
$sWhere .= " ".$Logic." ";
$sWhere .= "(".$strFilter.")";
}
}
$bINCLUDE_SUBSECTIONS = isset($arFilter["INCLUDE_SUBSECTIONS"]) && $arFilter["INCLUDE_SUBSECTIONS"] === "Y";
if($sWhere !== '')
{
$sectionScope = "";
if (isset($arFilter["SECTION_SCOPE"]))
{
if ($arFilter["SECTION_SCOPE"] == "IBLOCK")
$sectionScope = "AND BSE.ADDITIONAL_PROPERTY_ID IS NULL";
elseif ($arFilter["SECTION_SCOPE"] == "PROPERTY")
$sectionScope = "AND BSE.ADDITIONAL_PROPERTY_ID IS NOT NULL";
elseif (preg_match("/^PROPERTY_(\d+)$/", $arFilter["SECTION_SCOPE"], $match))
$sectionScope = "AND BSE.ADDITIONAL_PROPERTY_ID = ".$match[1];
}
//Try to convert correlated subquery to join subquery
if($level == 0 && $Logic == "AND" && !count($arSectionFilter["BE"]))
{
$arJoinProps["BES"] .= " INNER JOIN (
SELECT DISTINCT BSE.IBLOCK_ELEMENT_ID
FROM b_iblock_section_element BSE
".($bINCLUDE_SUBSECTIONS? "
INNER JOIN b_iblock_section BSubS ON BSE.IBLOCK_SECTION_ID = BSubS.ID
INNER JOIN b_iblock_section BS ON (BSubS.IBLOCK_ID=BS.IBLOCK_ID
AND BSubS.LEFT_MARGIN>=BS.LEFT_MARGIN
AND BSubS.RIGHT_MARGIN<=BS.RIGHT_MARGIN)
" : "
INNER JOIN b_iblock_section BS ON BSE.IBLOCK_SECTION_ID = BS.ID
")."
WHERE (".$sWhere.")$sectionScope
) BES ON BES.IBLOCK_ELEMENT_ID = BE.IDn";
}
else
{
$arSqlSearch[] = "(".(count($arSectionFilter["BE"])? implode(" ".$arSectionFilter["LOGIC"]." ", $arSectionFilter["BE"])." ".$arSectionFilter["LOGIC"]: "")." EXISTS (
SELECT BSE.IBLOCK_ELEMENT_ID
FROM b_iblock_section_element BSE
".($bINCLUDE_SUBSECTIONS? "
INNER JOIN b_iblock_section BSubS ON BSE.IBLOCK_SECTION_ID = BSubS.ID
INNER JOIN b_iblock_section BS ON (BSubS.IBLOCK_ID=BS.IBLOCK_ID
AND BSubS.LEFT_MARGIN>=BS.LEFT_MARGIN
AND BSubS.RIGHT_MARGIN<=BS.RIGHT_MARGIN)
" : "
INNER JOIN b_iblock_section BS ON BSE.IBLOCK_SECTION_ID = BS.ID
")."
WHERE BSE.IBLOCK_ELEMENT_ID = BE.ID
AND (".$sWhere.")$sectionScope
))";
}
}
elseif(!empty($arSectionFilter["BE"]))
{
foreach($arSectionFilter["BE"] as $strFilter)
$arSqlSearch[] = $strFilter;
}
$sWhere = "";
foreach($arSqlSearch as $strFilter)
{
if(trim($strFilter, "nt") !== '')
{
if ($sWhere !== '')
$sWhere .= "ntttt".$Logic." ";
else
$sWhere .= "ntttt";
$sWhere .= "(".$strFilter.")";
}
}
$arSqlSearch = array("nttt".$sWhere."nttt");
$SHOW_BP_NEW = "";
$SHOW_NEW = isset($arFilter["SHOW_NEW"]) && $arFilter["SHOW_NEW"]=="Y"? "Y": "N";
if(
$SHOW_NEW == "Y"
&& isset($arFilter["SHOW_BP_NEW"])
&& is_array($arFilter["SHOW_BP_NEW"])
&& IsModuleInstalled('bizproc')
&& (!is_object($USER) || !$USER->IsAdmin())
)
{
$MODULE_ID = $DB->ForSQL($arFilter["SHOW_BP_NEW"]["MODULE_ID"]);
$ENTITY = $DB->ForSQL($arFilter["SHOW_BP_NEW"]["ENTITY"]);
$PERMISSION = $DB->ForSQL($arFilter["SHOW_BP_NEW"]["PERMISSION"]);
$arUserGroups = array();
if(is_array($arFilter["SHOW_BP_NEW"]["GROUPS"]))
{
$USER_ID = intval($arFilter["SHOW_BP_NEW"]["USER_ID"]);
foreach($arFilter["SHOW_BP_NEW"]["GROUPS"] as $GROUP_ID)
{
$GROUP_ID = intval($GROUP_ID);
if($GROUP_ID)
$arUserGroups[$GROUP_ID] = $GROUP_ID;
}
}
else
{
$USER_ID = false;
$arUserGroups = false;
}
if($PERMISSION == "read" || $PERMISSION == "write")
{
if(!is_array($arUserGroups))
{
$USER_ID = is_object($USER)? (int)$USER->GetID(): 0;
if(is_object($USER))
$arUserGroups = $USER->GetUserGroupArray();
}
if(!is_array($arUserGroups) || empty($arUserGroups))
$arUserGroups = array(2);
$SHOW_BP_NEW = " AND EXISTS (
SELECT S.DOCUMENT_ID_INT
FROM
b_bp_workflow_state S
INNER JOIN b_bp_workflow_permissions P ON S.ID = P.WORKFLOW_ID
WHERE
S.DOCUMENT_ID_INT = BE.ID
AND S.MODULE_ID = '$MODULE_ID'
AND S.ENTITY = '$ENTITY'
AND P.PERMISSION = '$PERMISSION'
AND (
P.OBJECT_ID IN ('".implode("', '", $arUserGroups)."')
OR (P.OBJECT_ID = 'Author' AND BE.CREATED_BY = $USER_ID)
OR (P.OBJECT_ID = ".$DB->Concat("'USER_'", "'$USER_ID'").")
)
)";
}
}
if(!isset($arFilter["SHOW_HISTORY"]) || $arFilter["SHOW_HISTORY"] != "Y")
$arSqlSearch[] = "((BE.WF_STATUS_ID=1 AND BE.WF_PARENT_ELEMENT_ID IS NULL)".($SHOW_NEW == "Y"? " OR (BE.WF_NEW='Y'".$SHOW_BP_NEW.")": "").")";
if($permSQL)
$arSqlSearch[] = $permSQL;
if(isset($this) && is_object($this) && isset($this->subQueryProp))
{
//Subquery list value should not be null
$this->MkPropertyFilter(
CIBlock::MkOperationFilter("!".mb_substr($this->strField, 9))
,"NE"
,false
,$this->subQueryProp, $arJoinProps, $arSqlSearch
);
}
return $arSqlSearch;
}