public function PrepareGetList(
&$arIblockElementFields,
&$arJoinProps,
&$arSelectFields,
&$sSelect,
&$arAddSelectFields,
&$arFilter,
&$sWhere,
&$sSectionWhere,
&$arAddWhereFields,
&$arGroupBy,
&$sGroupBy,
&$arOrder,
&$arSqlOrder,
&$arAddOrderByFields
)
{
if(
is_array($arSelectFields)
&& (in_array("DETAIL_PAGE_URL", $arSelectFields) || in_array("CANONICAL_PAGE_URL", $arSelectFields))
&& !in_array("LANG_DIR", $arSelectFields)
)
{
$arSelectFields[] = "LANG_DIR";
}
global $DB;
if((!is_array($arSelectFields) && $arSelectFields=="") || count($arSelectFields)<=0 || $arSelectFields===false)
$arSelectFields = Array("*");
if(is_bool($arGroupBy) && $arGroupBy!==false)
$arGroupBy = Array();
if(is_array($arGroupBy) && count($arGroupBy)==0)
$this->bOnlyCount = true;
$iPropCnt = 0;
$arJoinProps = Array(
"FP" => array(
//CNT
//bFullJoin
),
"FPV" => array(
//CNT
//IBLOCK_ID
//MULTIPLE
//VERSION
//JOIN
//bFullJoin
),
"FPS" => array(
//
),
"FPEN" => array(
//CNT
//MULTIPLE
//VERSION
//ORIG_ID
//JOIN
//bFullJoin
),
"BE" => array(
//CNT
//MULTIPLE
//VERSION
//ORIG_ID
//JOIN
//bJoinIBlock
//bJoinSection
),
"BE_FP" => array(
//CNT
//JOIN
//bFullJoin
),
"BE_FPV" => array(
//CNT
//IBLOCK_ID
//MULTIPLE
//VERSION
//JOIN
//BE_JOIN
//bFullJoin
),
"BE_FPS" => array(
//CNT
//JOIN
),
"BE_FPEN" => array(
//CNT
//MULTIPLE
//VERSION
//ORIG_ID
//JOIN
//bFullJoin
),
"BES" => "",
"RV" => false,
"RVU" => false,
"RVV" => false,
"FC" => "",
);
$this->arIBlockMultProps = Array();
$this->arIBlockAllProps = Array();
$this->arIBlockNumProps = Array();
$bWasGroup = false;
//********************************ORDER BY PART***********************************************
$iblockIds = CIBlock::_MergeIBArrays(
$arFilter["IBLOCK_ID"] ?? false,
$arFilter["IBLOCK_CODE"] ?? false,
);
$orderAlias = array(
'EXTERNAL_ID' => 'XML_ID',
'DATE_ACTIVE_FROM' => 'ACTIVE_FROM',
'DATE_ACTIVE_TO' => 'ACTIVE_TO'
);
$arSqlOrder = Array();
$arAddOrderByFields = Array();
$iOrdNum = -1;
if(!is_array($arOrder))
$arOrder = Array();
foreach($arOrder as $by=>$order)
{
$by_orig = $by;
$by = mb_strtoupper($by);
//Remove aliases
if (isset($orderAlias[$by]))
$by = $orderAlias[$by];
if (isset($arSqlOrder[$by]))
continue;
if ($this->catalogIncluded && CProductQueryBuilder::isValidField($by))
{
$iOrdNum++;
$arAddOrderByFields[$iOrdNum] = Array($by=>$order);
//Reserve for future fill
$arSqlOrder[$iOrdNum] = false;
}
else
{
if($by == "ID") $arSqlOrder[$by] = $this->getIdOrder($order);
elseif($by == "NAME") $arSqlOrder[$by] = CIBlock::_Order("BE.NAME", $order, "desc", false);
elseif($by == "STATUS") $arSqlOrder[$by] = CIBlock::_Order("BE.WF_STATUS_ID", $order, "desc");
elseif($by == "XML_ID") $arSqlOrder[$by] = CIBlock::_Order("BE.XML_ID", $order, "desc");
elseif($by == "CODE") $arSqlOrder[$by] = CIBlock::_Order("BE.CODE", $order, "desc");
elseif($by == "TAGS") $arSqlOrder[$by] = CIBlock::_Order("BE.TAGS", $order, "desc");
elseif($by == "TIMESTAMP_X") $arSqlOrder[$by] = CIBlock::_Order("BE.TIMESTAMP_X", $order, "desc");
elseif($by == "CREATED") $arSqlOrder[$by] = CIBlock::_Order("BE.DATE_CREATE", $order, "desc");
elseif($by == "CREATED_DATE") $arSqlOrder[$by] = CIBlock::_Order($DB->DateFormatToDB("YYYY.MM.DD", "BE.DATE_CREATE"), $order, "desc");
elseif($by == "IBLOCK_ID") $arSqlOrder[$by] = CIBlock::_Order("BE.IBLOCK_ID", $order, "desc");
elseif($by == "MODIFIED_BY") $arSqlOrder[$by] = CIBlock::_Order("BE.MODIFIED_BY", $order, "desc");
elseif($by == "CREATED_BY") $arSqlOrder[$by] = CIBlock::_Order("BE.CREATED_BY", $order, "desc");
elseif($by == "ACTIVE") $arSqlOrder[$by] = CIBlock::_Order("BE.ACTIVE", $order, "desc");
elseif($by == "ACTIVE_FROM") $arSqlOrder[$by] = CIBlock::_Order("BE.ACTIVE_FROM", $order, "desc");
elseif($by == "ACTIVE_TO") $arSqlOrder[$by] = CIBlock::_Order("BE.ACTIVE_TO", $order, "desc");
elseif($by == "SORT") $arSqlOrder[$by] = CIBlock::_Order("BE.SORT", $order, "desc");
elseif($by == "IBLOCK_SECTION_ID") $arSqlOrder[$by] = CIBlock::_Order("BE.IBLOCK_SECTION_ID", $order, "desc");
elseif($by == "SHOW_COUNTER") $arSqlOrder[$by] = CIBlock::_Order("BE.SHOW_COUNTER", $order, "desc");
elseif($by == "SHOW_COUNTER_START") $arSqlOrder[$by] = CIBlock::_Order("BE.SHOW_COUNTER_START", $order, "desc");
elseif($by == "RAND") $arSqlOrder[$by] = CIBlockElement::GetRandFunction();
elseif($by == "SHOWS") $arSqlOrder[$by] = CIBlock::_Order(CIBlockElement::GetShowedFunction(), $order, "desc", false);
elseif($by == "HAS_PREVIEW_PICTURE") $arSqlOrder[$by] = CIBlock::_Order(CIBlock::_NotEmpty("BE.PREVIEW_PICTURE"), $order, "desc", false);
elseif($by == "HAS_DETAIL_PICTURE") $arSqlOrder[$by] = CIBlock::_Order(CIBlock::_NotEmpty("BE.DETAIL_PICTURE"), $order, "desc", false);
elseif($by == "RATING_TOTAL_VALUE")
{
$arSqlOrder[$by] = CIBlock::_Order("RV.TOTAL_VALUE", $order, "desc");
$arJoinProps["RV"] = true;
}
elseif($by == "CNT")
{
if (!empty($arGroupBy) && is_array($arGroupBy))
{
$arSqlOrder[$by] = ' '.CIBlock::_Order('CNT', $order, 'desc', false).' ';
}
}
elseif(mb_substr($by, 0, 9) == "PROPERTY_")
{
$propID = mb_strtoupper(mb_substr($by_orig, 9));
if(preg_match("/^([^.]+)\.([^.]+)$/", $propID, $arMatch))
{
$db_prop = CIBlockProperty::GetPropertyArray($arMatch[1], $iblockIds);
if(is_array($db_prop) && $db_prop["PROPERTY_TYPE"] == "E")
CIBlockElement::MkPropertyOrder($arMatch, $order, false, $db_prop, $arJoinProps, $arSqlOrder);
}
else
{
if($db_prop = CIBlockProperty::GetPropertyArray($propID, $iblockIds))
CIBlockElement::MkPropertyOrder($by, $order, false, $db_prop, $arJoinProps, $arSqlOrder);
}
}
elseif(mb_substr($by, 0, 13) == "PROPERTYSORT_")
{
$propID = mb_strtoupper(mb_substr($by_orig, 13));
if(preg_match("/^([^.]+)\.([^.]+)$/", $propID, $arMatch))
{
$db_prop = CIBlockProperty::GetPropertyArray($arMatch[1], $iblockIds);
if(is_array($db_prop) && $db_prop["PROPERTY_TYPE"] == "E")
CIBlockElement::MkPropertyOrder($arMatch, $order, true, $db_prop, $arJoinProps, $arSqlOrder);
}
else
{
if($db_prop = CIBlockProperty::GetPropertyArray($propID, $iblockIds))
CIBlockElement::MkPropertyOrder($by, $order, true, $db_prop, $arJoinProps, $arSqlOrder);
}
}
else
{
$by = "ID";
if(!isset($arSqlOrder[$by]))
$arSqlOrder[$by] = CIBlock::_Order("BE.ID", $order, "desc");
}
//Check if have to add select field in order to correctly sort
if (isset($arSqlOrder[$by]) && is_array($arSqlOrder[$by]))
{
if (!empty($arGroupBy) && is_array($arGroupBy))
$arGroupBy[] = $arSqlOrder[$by][1];
else
$arSelectFields[] = $arSqlOrder[$by][1];
// COLUMN ALIAS COLUMN EXPRESSION
$arIblockElementFields[$arSqlOrder[$by][1]] = $arSqlOrder[$by][0];
// ORDER EXPRESSION
$arSqlOrder[$by] = $arSqlOrder[$by][2];
}
}
//Add order by fields to the select list
//in order to avoid sql errors
if (!empty($arGroupBy) && is_array($arGroupBy))
{
if ($by == "STATUS")
{
$arGroupBy[] = "WF_STATUS_ID";
}
elseif ($by == "CREATED")
{
$arGroupBy[] = "DATE_CREATE";
}
elseif ($by == "SHOWS")
{
$arGroupBy[] = "SHOW_COUNTER";
$arGroupBy[] = "SHOW_COUNTER_START_X";
}
else
{
$arGroupBy[] = $by;
}
}
else
{
if ($by == "STATUS")
{
$arSelectFields[] = "WF_STATUS_ID";
}
elseif ($by == "CREATED")
{
$arSelectFields[] = "DATE_CREATE";
}
elseif ($by == "SHOWS")
{
$arSelectFields[] = "SHOW_COUNTER";
$arSelectFields[] = "SHOW_COUNTER_START_X";
}
else
{
$arSelectFields[] = $by;
}
}
}
//*************************GROUP BY PART****************************
$sGroupBy = "";
if(!empty($arGroupBy) && is_array($arGroupBy))
{
$arSelectFields = $arGroupBy;
$bWasGroup = true;
foreach($arSelectFields as $key=>$val)
{
$val = mb_strtoupper($val);
if(array_key_exists($val, $arIblockElementFields))
{
$sGroupBy.=",".preg_replace("/(s+ASs+[A-Z_]+)/i", "", $arIblockElementFields[$val]);
}
elseif(mb_substr($val, 0, 9) == "PROPERTY_")
{
$PR_ID = mb_strtoupper(mb_substr($val, 9));
if($db_prop = CIBlockProperty::GetPropertyArray($PR_ID, $iblockIds))
$sGroupBy .= CIBlockElement::MkPropertyGroup($db_prop, $arJoinProps);
}
elseif(mb_substr($val, 0, 13) == "PROPERTYSORT_")
{
$PR_ID = mb_strtoupper(mb_substr($val, 13));
if($db_prop = CIBlockProperty::GetPropertyArray($PR_ID, $iblockIds))
$sGroupBy .= CIBlockElement::MkPropertyGroup($db_prop, $arJoinProps, true);
}
}
if($sGroupBy!="")
$sGroupBy = " GROUP BY ".mb_substr($sGroupBy, 1)." ";
}
//*************************SELECT PART****************************
$arAddSelectFields = Array();
if($this->bOnlyCount)
{
$sSelect = "COUNT(%%_DISTINCT_%% BE.ID) as CNT ";
}
else
{
$sSelect = "";
$arDisplayedColumns = array();
$bStar = false;
foreach($arSelectFields as $key=>$val)
{
$val = mb_strtoupper($val);
if(array_key_exists($val, $arIblockElementFields))
{
if(isset($arDisplayedColumns[$val]))
continue;
$arDisplayedColumns[$val] = true;
$arSelectFields[$key] = $val;
$sSelect.=",".$arIblockElementFields[$val]." as ".$val;
}
elseif($val == "PROPERTY_*" && !$bWasGroup)
{
//We have to analyze arFilter IBLOCK_ID and IBLOCK_CODE
//in a way to be shure we will get properties of the ONE IBLOCK ONLY!
$arPropertyFilter = array(
"ACTIVE"=>"Y",
"VERSION"=>2,
);
if(array_key_exists("IBLOCK_ID", $arFilter))
{
if(is_array($arFilter["IBLOCK_ID"]) && count($arFilter["IBLOCK_ID"])==1)
$arPropertyFilter["IBLOCK_ID"] = $arFilter["IBLOCK_ID"][0];
elseif(!is_array($arFilter["IBLOCK_ID"]) && intval($arFilter["IBLOCK_ID"])>0)
$arPropertyFilter["IBLOCK_ID"] = $arFilter["IBLOCK_ID"];
}
if(!array_key_exists("IBLOCK_ID", $arPropertyFilter))
{
if(array_key_exists("IBLOCK_CODE", $arFilter))
{
if(is_array($arFilter["IBLOCK_CODE"]) && count($arFilter["IBLOCK_CODE"])==1)
$arPropertyFilter["IBLOCK_CODE"] = $arFilter["IBLOCK_CODE"][0];
elseif(!is_array($arFilter["IBLOCK_CODE"]) && $arFilter["IBLOCK_CODE"] <> '')
$arPropertyFilter["IBLOCK_CODE"] = $arFilter["IBLOCK_CODE"];
else
continue;
}
else
continue;
}
$rs_prop = CIBlockProperty::GetList(array("sort"=>"asc"), $arPropertyFilter);
while($db_prop = $rs_prop->Fetch())
$this->arIBlockAllProps[]=$db_prop;
$iblock_id = false;
foreach($this->arIBlockAllProps as $db_prop)
{
if($db_prop["USER_TYPE"]!="")
{
$arUserType = CIBlockProperty::GetUserType($db_prop["USER_TYPE"]);
if(array_key_exists("ConvertFromDB", $arUserType))
$this->arIBlockConvProps["PROPERTY_".$db_prop["ID"]] = array(
"ConvertFromDB"=>$arUserType["ConvertFromDB"],
"PROPERTY"=>$db_prop,
);
}
$db_prop["ORIG_ID"] = $db_prop["ID"];
if($db_prop["MULTIPLE"]=="Y")
$this->arIBlockMultProps["PROPERTY_".$db_prop["ID"]] = $db_prop;
$iblock_id = $db_prop["IBLOCK_ID"];
}
if($iblock_id!==false)
{
if(!array_key_exists($iblock_id, $arJoinProps["FPS"]))
$arJoinProps["FPS"][$iblock_id] = count($arJoinProps["FPS"]);
$iPropCnt = $arJoinProps["FPS"][$iblock_id];
$sSelect .= ", FPS".$iPropCnt.".*";
}
}
elseif(mb_substr($val, 0, 9) == "PROPERTY_")
{
$PR_ID = mb_strtoupper($val);
if(isset($arDisplayedColumns[$PR_ID]))
continue;
$arDisplayedColumns[$PR_ID] = true;
$PR_ID = mb_substr($PR_ID, 9);
$iblockIds = CIBlock::_MergeIBArrays(
$arFilter["IBLOCK_ID"] ?? false,
$arFilter["IBLOCK_CODE"] ?? false
);
if(preg_match("/^([^.]+)\.([^.]+)$/", $PR_ID, $arMatch))
{
$db_prop = CIBlockProperty::GetPropertyArray($arMatch[1], $iblockIds);
if (is_array($db_prop) && $db_prop["PROPERTY_TYPE"] == "E")
{
$this->MkPropertySelect($arMatch, $db_prop, $arJoinProps, $bWasGroup, $sGroupBy, $sSelect);
}
}
else
{
$db_prop = CIBlockProperty::GetPropertyArray($PR_ID, $iblockIds);
if ($db_prop)
{
$this->MkPropertySelect($PR_ID, $db_prop, $arJoinProps, $bWasGroup, $sGroupBy, $sSelect);
}
}
}
elseif(mb_substr($val, 0, 13) == "PROPERTYSORT_")
{
$PR_ID = mb_strtoupper($val);
if(isset($arDisplayedColumns[$PR_ID]))
continue;
$arDisplayedColumns[$PR_ID] = true;
$PR_ID = mb_substr($PR_ID, 13);
if(preg_match("/^([^.]+)\.([^.]+)$/", $PR_ID, $arMatch))
{
$db_prop = CIBlockProperty::GetPropertyArray($arMatch[1], $iblockIds);
if(is_array($db_prop) && $db_prop["PROPERTY_TYPE"] == "E")
$this->MkPropertySelect($arMatch, $db_prop, $arJoinProps, $bWasGroup, $sGroupBy, $sSelect, true);
}
else
{
if($db_prop = CIBlockProperty::GetPropertyArray($PR_ID, $iblockIds))
$this->MkPropertySelect($PR_ID, $db_prop, $arJoinProps, $bWasGroup, $sGroupBy, $sSelect, true);
}
}
elseif($val == "*")
{
$bStar = true;
}
elseif ($this->catalogIncluded && CProductQueryBuilder::isValidField($val))
{
$arAddSelectFields[] = $val;
}
elseif(
$val == "RATING_TOTAL_VALUE"
|| $val == "RATING_TOTAL_VOTES"
|| $val == "RATING_TOTAL_POSITIVE_VOTES"
|| $val == "RATING_TOTAL_NEGATIVE_VOTES"
)
{
if(isset($arDisplayedColumns[$val]))
continue;
$arDisplayedColumns[$val] = true;
$arSelectFields[$key] = $val;
$sSelect.=",".preg_replace("/^RATING_/", "RV.", $val)." as ".$val;
$arJoinProps["RV"] = true;
}
elseif($val == "RATING_USER_VOTE_VALUE")
{
if(isset($arDisplayedColumns[$val]))
continue;
$arDisplayedColumns[$val] = true;
$arSelectFields[$key] = $val;
//if(isset($USER) && is_object($USER))
if ($this->userExists)
{
$sSelect.=",".$DB->IsNull('RVU.VALUE', '0')." as ".$val;
$arJoinProps["RVU"] = true;
}
else
{
$sSelect.=",0 as ".$val;
}
}
}
if($bStar)
{
foreach($arIblockElementFields as $key=>$val)
{
if(isset($arDisplayedColumns[$key]))
continue;
$arDisplayedColumns[$key] = true;
$arSelectFields[]=$key;
$sSelect.=",".$val." as ".$key;
}
}
elseif($sGroupBy=="")
{
//Try to add missing fields for correct URL translation (only then no grouping)
if(isset($arDisplayedColumns["DETAIL_PAGE_URL"]))
$arAddFields = array("LANG_DIR", "ID", "CODE", "EXTERNAL_ID", "IBLOCK_SECTION_ID", "IBLOCK_TYPE_ID", "IBLOCK_ID", "IBLOCK_CODE", "IBLOCK_EXTERNAL_ID", "LID");
elseif(isset($arDisplayedColumns["CANONICAL_PAGE_URL"]))
$arAddFields = array("LANG_DIR", "ID", "CODE", "EXTERNAL_ID", "IBLOCK_SECTION_ID", "IBLOCK_TYPE_ID", "IBLOCK_ID", "IBLOCK_CODE", "IBLOCK_EXTERNAL_ID", "LID");
elseif(isset($arDisplayedColumns["SECTION_PAGE_URL"]))
$arAddFields = array("LANG_DIR", "ID", "CODE", "EXTERNAL_ID", "IBLOCK_SECTION_ID", "IBLOCK_TYPE_ID", "IBLOCK_ID", "IBLOCK_CODE", "IBLOCK_EXTERNAL_ID", "LID");
elseif(isset($arDisplayedColumns["LIST_PAGE_URL"]))
$arAddFields = array("LANG_DIR", "IBLOCK_TYPE_ID", "IBLOCK_ID", "IBLOCK_CODE", "IBLOCK_EXTERNAL_ID", "LID");
else
$arAddFields = array();
//Try to add missing fields for correct PREVIEW and DETAIL text formatting
if(isset($arDisplayedColumns["DETAIL_TEXT"]))
$arAddFields[] = "DETAIL_TEXT_TYPE";
if(isset($arDisplayedColumns["PREVIEW_TEXT"]))
$arAddFields[] = "PREVIEW_TEXT_TYPE";
foreach($arAddFields as $key)
{
if(isset($arDisplayedColumns[$key]))
continue;
$arDisplayedColumns[$key] = true;
$arSelectFields[]=$key;
$sSelect.=",".$arIblockElementFields[$key]." as ".$key;
}
}
if($sGroupBy!="")
$sSelect = mb_substr($sSelect, 1).", COUNT(%%_DISTINCT_%% BE.ID) as CNT ";
elseif($sSelect !== '')
$sSelect = "%%_DISTINCT_%% ".mb_substr($sSelect, 1)." ";
}
//*********************WHERE PART*********************
$arAddWhereFields = Array();
if(is_array($arFilter) && isset($arFilter["CATALOG"]))
{
$arAddWhereFields = $arFilter["CATALOG"];
unset($arFilter["CATALOG"]);
}
$arSqlSearch = CIBlockElement::MkFilter($arFilter, $arJoinProps, $arAddWhereFields);
$this->bDistinct = false;
$sSectionWhere = "";
$sWhere = "";
foreach ($arSqlSearch as $condition)
if (trim($condition, "nt") !== '')
$sWhere .= "ntttAND (".$condition.")";
}