18 if (!is_array($arOrder))
22 if (!is_array($arSelect))
24 foreach (array_keys($arSelect) as $index)
26 if (!is_string($arSelect[$index]))
28 unset($arSelect[$index]);
43 $needUfManager = self::checkUfFields($arOrder,
$arFilter, $arSelect);
45 if ($needUfManager && !$iblockFilterExist)
47 trigger_error(
"Parameters of the CIBlockSection::GetList contains user fields, but arFilter has no IBLOCK_ID field.", E_USER_WARNING);
51 $userFieldsSelect = $arSelect;
52 if (!in_array(
"UF_*", $userFieldsSelect))
54 if (!empty($arOrder) && is_array($arOrder))
56 foreach (array_keys($arOrder) as $userFieldName)
58 if (!in_array($userFieldName, $userFieldsSelect))
59 $userFieldsSelect[] = $userFieldName;
61 unset($userFieldName);
67 $obUserFieldsSql->SetSelect($userFieldsSelect);
69 $obUserFieldsSql->SetOrder($arOrder);
71 unset($userFieldsSelect);
74 $useSubsections = !(isset(
$arFilter[
"ELEMENT_SUBSECTIONS"]) &&
$arFilter[
"ELEMENT_SUBSECTIONS"]==
"N");
78 $arJoinProps =
array();
79 $bJoinFlatProp =
false;
83 $bCheckPermissions = !(isset(
$arFilter[
"CHECK_PERMISSIONS"]) &&
$arFilter[
"CHECK_PERMISSIONS"] ===
"N");
84 $bIsAdmin = is_object(
$USER) &&
$USER->IsAdmin();
85 $permissionsBy =
null;
86 if ($bCheckPermissions && isset(
$arFilter[
'PERMISSIONS_BY']))
88 $permissionsBy = (int)
$arFilter[
'PERMISSIONS_BY'];
89 if ($permissionsBy < 0)
90 $permissionsBy =
null;
92 if($bCheckPermissions && ($permissionsBy !==
null || !$bIsAdmin))
94 $arFilter[
"MIN_PERMISSION"] ??= CIBlockRights::PUBLIC_READ;
95 $arSqlSearch[] = self::_check_rights_sql(
$arFilter[
"MIN_PERMISSION"], $permissionsBy);
97 unset($permissionsBy);
102 foreach(
$val as $propID=>$propVAL)
104 $res = CIBlock::MkOperationFilter($propID);
105 $propID =
$res[
"FIELD"];
106 $cOperationType =
$res[
"OPERATION"];
107 if($db_prop = CIBlockProperty::GetPropertyArray($propID, CIBlock::_MergeIBArrays(
$arFilter[
"IBLOCK_ID"],
$arFilter[
"IBLOCK_CODE"])))
112 && $db_prop[
"MULTIPLE"] ==
"N"
116 if (isset($arJoinProps[$db_prop[
"ID"]]))
118 $iPropCnt = $arJoinProps[$db_prop[
"ID"]][
"iPropCnt"];
123 $iPropCnt =
count($arJoinProps);
126 if(!is_array($propVAL))
127 $propVAL = Array($propVAL);
129 if($db_prop[
"PROPERTY_TYPE"]==
"N" || $db_prop[
"PROPERTY_TYPE"]==
"G" || $db_prop[
"PROPERTY_TYPE"]==
"E")
133 $r = CIBlock::FilterCreate(
"FPS.PROPERTY_".$db_prop[
"ORIG_ID"], $propVAL,
"number", $cOperationType);
134 $bJoinFlatProp = $db_prop[
"IBLOCK_ID"];
138 $r = CIBlock::FilterCreate(
"FPV".$iPropCnt.
".VALUE_NUM", $propVAL,
"number", $cOperationType);
145 $r = CIBlock::FilterCreate(
"FPS.PROPERTY_".$db_prop[
"ORIG_ID"], $propVAL,
"string", $cOperationType);
146 $bJoinFlatProp = $db_prop[
"IBLOCK_ID"];
150 $r = CIBlock::FilterCreate(
"FPV".$iPropCnt.
".VALUE", $propVAL,
"string", $cOperationType);
158 $db_prop[
"iPropCnt"] = $iPropCnt;
159 $arJoinProps[$db_prop[
"ID"]] = $db_prop;
168 foreach($arSqlSearch as $r)
170 $strSqlSearch .=
"\n\t\t\t\tAND (".$r.
") ";
172 if(isset($obUserFieldsSql))
174 $r = $obUserFieldsSql->GetFilter();
176 $strSqlSearch .=
"\n\t\t\t\tAND (".$r.
") ";
180 foreach($arJoinProps as $propID=>$db_prop)
182 if($db_prop[
"VERSION"]==2)
183 $strTable =
"b_iblock_element_prop_m".$db_prop[
"IBLOCK_ID"];
185 $strTable =
"b_iblock_element_property";
186 $i = $db_prop[
"iPropCnt"];
188 LEFT JOIN b_iblock_property FP".$i.
" ON FP".
$i.
".IBLOCK_ID=B.ID AND
189 ".((int)$propID>0?
" FP".$i.
".ID=".(int)$propID.
" ":
" FP".
$i.
".CODE='".
$DB->ForSQL($propID, 200).
"' ").
"
190 LEFT JOIN ".$strTable.
" FPV".
$i.
" ON FP".
$i.
".ID=FPV".
$i.
".IBLOCK_PROPERTY_ID AND FPV".
$i.
".IBLOCK_ELEMENT_ID=BE.ID ";
194 LEFT JOIN b_iblock_element_prop_s".$bJoinFlatProp.
" FPS ON FPS.IBLOCK_ELEMENT_ID = BE.ID
200 "XML_ID" =>
"BS.XML_ID",
201 "EXTERNAL_ID" =>
"BS.XML_ID",
202 "IBLOCK_ID" =>
"BS.IBLOCK_ID",
203 "IBLOCK_SECTION_ID" =>
"BS.IBLOCK_SECTION_ID",
204 "TIMESTAMP_X" =>
$DB->DateToCharFunction(
"BS.TIMESTAMP_X"),
205 "TIMESTAMP_X_UNIX" =>
'UNIX_TIMESTAMP(BS.TIMESTAMP_X)',
208 "ACTIVE" =>
"BS.ACTIVE",
209 "GLOBAL_ACTIVE" =>
"BS.GLOBAL_ACTIVE",
210 "PICTURE" =>
"BS.PICTURE",
211 "DESCRIPTION" =>
"BS.DESCRIPTION",
212 "DESCRIPTION_TYPE" =>
"BS.DESCRIPTION_TYPE",
213 "LEFT_MARGIN" =>
"BS.LEFT_MARGIN",
214 "RIGHT_MARGIN" =>
"BS.RIGHT_MARGIN",
215 "DEPTH_LEVEL" =>
"BS.DEPTH_LEVEL",
216 "SEARCHABLE_CONTENT" =>
"BS.SEARCHABLE_CONTENT",
217 "MODIFIED_BY" =>
"BS.MODIFIED_BY",
218 "DATE_CREATE" =>
$DB->DateToCharFunction(
"BS.DATE_CREATE"),
219 "DATE_CREATE_UNIX" =>
'UNIX_TIMESTAMP(BS.DATE_CREATE)',
220 "CREATED_BY" =>
"BS.CREATED_BY",
221 "DETAIL_PICTURE" =>
"BS.DETAIL_PICTURE",
222 "TMP_ID" =>
"BS.TMP_ID",
224 "LIST_PAGE_URL" =>
"B.LIST_PAGE_URL",
225 "SECTION_PAGE_URL" =>
"B.SECTION_PAGE_URL",
226 "IBLOCK_TYPE_ID" =>
"B.IBLOCK_TYPE_ID",
227 "IBLOCK_CODE" =>
"B.CODE",
228 "IBLOCK_EXTERNAL_ID" =>
"B.XML_ID",
229 "SOCNET_GROUP_ID" =>
"BS.SOCNET_GROUP_ID",
232 $arSqlSelect =
array();
233 foreach($arSelect as $field)
235 $field = mb_strtoupper($field);
237 $arSqlSelect[$field] =
$arFields[$field].
" AS ".$field;
240 if(isset($arSqlSelect[
'DESCRIPTION']))
241 $arSqlSelect[
"DESCRIPTION_TYPE"] =
$arFields[
"DESCRIPTION_TYPE"].
" AS DESCRIPTION_TYPE";
243 if(isset($arSqlSelect[
'LIST_PAGE_URL']) || isset($arSqlSelect[
'SECTION_PAGE_URL']))
245 $arSqlSelect[
"ID"] =
$arFields[
"ID"].
" AS ID";
246 $arSqlSelect[
"CODE"] =
$arFields[
"CODE"].
" AS CODE";
247 $arSqlSelect[
"EXTERNAL_ID"] =
$arFields[
"EXTERNAL_ID"].
" AS EXTERNAL_ID";
248 $arSqlSelect[
"IBLOCK_TYPE_ID"] =
$arFields[
"IBLOCK_TYPE_ID"].
" AS IBLOCK_TYPE_ID";
249 $arSqlSelect[
"IBLOCK_ID"] =
$arFields[
"IBLOCK_ID"].
" AS IBLOCK_ID";
250 $arSqlSelect[
"IBLOCK_CODE"] =
$arFields[
"IBLOCK_CODE"].
" AS IBLOCK_CODE";
251 $arSqlSelect[
"IBLOCK_EXTERNAL_ID"] =
$arFields[
"IBLOCK_EXTERNAL_ID"].
" AS IBLOCK_EXTERNAL_ID";
252 $arSqlSelect[
"GLOBAL_ACTIVE"] =
$arFields[
"GLOBAL_ACTIVE"].
" AS GLOBAL_ACTIVE";
256 $additionalSelect =
array();
257 $arSqlOrder =
array();
258 foreach($arOrder as $by=>
$order)
260 $by = mb_strtolower($by);
261 if(isset($arSqlOrder[$by]))
270 $arSqlOrder[$by] =
" BS.ID ".$order.
" ";
271 $additionalSelect[
"ID"] =
$arFields[
"ID"].
" AS ID";
274 $arSqlOrder[$by] =
" BS.IBLOCK_SECTION_ID ".$order.
" ";
275 $additionalSelect[
"IBLOCK_SECTION_ID"] =
$arFields[
"IBLOCK_SECTION_ID"].
" AS IBLOCK_SECTION_ID";
278 $arSqlOrder[$by] =
" BS.NAME ".$order.
" ";
279 $additionalSelect[
"NAME"] =
$arFields[
"NAME"].
" AS NAME";
282 $arSqlOrder[$by] =
" BS.CODE ".$order.
" ";
283 $additionalSelect[
"CODE"] =
$arFields[
"CODE"].
" AS CODE";
287 $arSqlOrder[$by] =
" BS.XML_ID ".$order.
" ";
288 $additionalSelect[
"XML_ID"] =
$arFields[
"XML_ID"].
" AS XML_ID";
291 $arSqlOrder[$by] =
" BS.ACTIVE ".$order.
" ";
292 $additionalSelect[
"ACTIVE"] =
$arFields[
"ACTIVE"].
" AS ACTIVE";
295 $arSqlOrder[$by] =
" BS.LEFT_MARGIN ".$order.
" ";
296 $additionalSelect[
"LEFT_MARGIN"] =
$arFields[
"LEFT_MARGIN"].
" AS LEFT_MARGIN";
299 $arSqlOrder[$by] =
" BS.DEPTH_LEVEL ".$order.
" ";
300 $additionalSelect[
"DEPTH_LEVEL"] =
$arFields[
"DEPTH_LEVEL"].
" AS DEPTH_LEVEL";
303 $arSqlOrder[$by] =
" BS.SORT ".$order.
" ";
304 $additionalSelect[
"SORT"] =
$arFields[
"SORT"].
" AS SORT";
307 $arSqlOrder[$by] =
" BS.DATE_CREATE ".$order.
" ";
308 $additionalSelect[
"DATE_CREATE"] =
$arFields[
"DATE_CREATE"].
" AS DATE_CREATE";
311 $arSqlOrder[$by] =
" BS.CREATED_BY ".$order.
" ";
312 $additionalSelect[
"CREATED_BY"] =
$arFields[
"CREATED_BY"].
" AS CREATED_BY";
315 $arSqlOrder[$by] =
" BS.MODIFIED_BY ".$order.
" ";
316 $additionalSelect[
"MODIFIED_BY"] =
$arFields[
"MODIFIED_BY"].
" AS MODIFIED_BY";
319 if ($bIncCnt && $by ==
"element_cnt")
321 $arSqlOrder[$by] =
" ELEMENT_CNT ".$order.
" ";
323 elseif (isset($obUserFieldsSql) && $s = $obUserFieldsSql->GetOrder($by))
325 $arSqlOrder[$by] =
" ".$s.
" ".
$order.
" ";
330 $arSqlOrder[$by] =
" BS.TIMESTAMP_X ".$order.
" ";
331 $additionalSelect[
"TIMESTAMP_X_SORT"] =
"BS.TIMESTAMP_X AS TSX_TMP";
335 if (!empty($additionalSelect) && !empty($arSqlSelect))
337 foreach ($additionalSelect as
$key => $value)
338 $arSqlSelect[
$key] = $value;
341 if(!empty($arSqlSelect))
342 $sSelect = implode(
",\n", $arSqlSelect);
349 B.CODE as IBLOCK_CODE,
350 B.XML_ID as IBLOCK_EXTERNAL_ID,
351 BS.XML_ID as EXTERNAL_ID,
352 ".$DB->DateToCharFunction(
"BS.TIMESTAMP_X").
" as TIMESTAMP_X,
353 ".
$DB->DateToCharFunction(
"BS.DATE_CREATE").
" as DATE_CREATE
358 $strSelect = $sSelect.(isset($obUserFieldsSql)? $obUserFieldsSql->GetSelect():
"");
360 FROM b_iblock_section BS
361 INNER JOIN b_iblock B ON BS.IBLOCK_ID = B.ID
362 ".(isset($obUserFieldsSql)? $obUserFieldsSql->GetJoin(
"BS.ID"):
"").
"
364 " INNER JOIN b_iblock_section BSTEMP ON BSTEMP.IBLOCK_ID = BS.IBLOCK_ID
365 LEFT JOIN b_iblock_section_element BSE ON BSE.IBLOCK_SECTION_ID=BSTEMP.ID
366 LEFT JOIN b_iblock_element BE ON (BSE.IBLOCK_ELEMENT_ID=BE.ID
367 AND ((BE.WF_STATUS_ID=1 AND BE.WF_PARENT_ELEMENT_ID IS NULL )
368 AND BE.IBLOCK_ID = BS.IBLOCK_ID
369 ".($allElements ?
" OR BE.WF_NEW='Y' ":
"").
")
372 AND (BE.ACTIVE_TO >= ".$DB->CurrentTimeFunction().
" OR BE.ACTIVE_TO IS NULL)
373 AND (BE.ACTIVE_FROM <= ".
$DB->CurrentTimeFunction().
" OR BE.ACTIVE_FROM IS NULL)"
379 " AND BSTEMP.LEFT_MARGIN >= BS.LEFT_MARGIN
380 AND BSTEMP.RIGHT_MARGIN <= BS.RIGHT_MARGIN "
389 $strSelect = $sSelect.
",COUNT(DISTINCT BE.ID) as ELEMENT_CNT".(isset($obUserFieldsSql)? $obUserFieldsSql->GetSelect():
"");
391 FROM b_iblock_section BS
392 INNER JOIN b_iblock B ON BS.IBLOCK_ID = B.ID
393 ".(isset($obUserFieldsSql)? $obUserFieldsSql->GetJoin(
"BS.ID"):
"").
"
394 ".(!$useSubsections ?
395 " LEFT JOIN b_iblock_section_element BSE ON BSE.IBLOCK_SECTION_ID=BS.ID "
397 " INNER JOIN b_iblock_section BSTEMP ON BSTEMP.IBLOCK_ID = BS.IBLOCK_ID
398 LEFT JOIN b_iblock_section_element BSE ON BSE.IBLOCK_SECTION_ID=BSTEMP.ID "
400 LEFT JOIN b_iblock_element BE ON (BSE.IBLOCK_ELEMENT_ID=BE.ID
401 AND ((BE.WF_STATUS_ID=1 AND BE.WF_PARENT_ELEMENT_ID IS NULL )
402 AND BE.IBLOCK_ID = BS.IBLOCK_ID
403 ".($allElements ?
" OR BE.WF_NEW='Y' ":
"").
")
406 AND (BE.ACTIVE_TO >= ".$DB->CurrentTimeFunction().
" OR BE.ACTIVE_TO IS NULL)
407 AND (BE.ACTIVE_FROM <= ".
$DB->CurrentTimeFunction().
" OR BE.ACTIVE_FROM IS NULL)"
415 " AND BSTEMP.IBLOCK_ID = BS.IBLOCK_ID
416 AND BSTEMP.LEFT_MARGIN >= BS.LEFT_MARGIN
417 AND BSTEMP.RIGHT_MARGIN <= BS.RIGHT_MARGIN
418 ".($activeElements ?
"AND BSTEMP.GLOBAL_ACTIVE = 'Y'":
"").
"
423 $strGroupBy =
"GROUP BY BS.ID, B.ID";
426 if(!empty($arSqlOrder))
427 $strSqlOrder =
"\n\t\t\t\tORDER BY ".implode(
", ", $arSqlOrder);
431 if(is_array($arNavStartParams))
433 $nTopCount = (int)($arNavStartParams[
'nTopCount'] ?? 0);
437 "SELECT DISTINCT ".$strSelect.$strSql.$strGroupBy.$strSqlOrder,
440 if($iblockFilterExist)
447 $res_cnt =
$DB->Query(
"SELECT COUNT(DISTINCT BS.ID) as C ".$strSql);
448 $res_cnt = $res_cnt->Fetch();
450 if($iblockFilterExist)
454 $res->NavQuery(
"SELECT DISTINCT ".$strSelect.$strSql.$strGroupBy.$strSqlOrder, $res_cnt[
"C"], $arNavStartParams);
459 $res =
$DB->Query(
"SELECT DISTINCT ".$strSelect.$strSql.$strGroupBy.$strSqlOrder);
460 if($iblockFilterExist)
467 if($iblockFilterExist)
481 $strUpdate =
$DB->PrepareUpdate(
"b_iblock_section",
$arFields,
"iblock",
false,
"BS");
482 if ($strUpdate ==
"")
495 $res = CIBlock::MkOperationFilter(
$key);
496 if(preg_match(
"/^UF_/",
$res[
"FIELD"]))
498 trigger_error(
"arFilter parameter of the CIBlockSection::GetList contains user fields, but has no IBLOCK_ID field.", E_USER_WARNING);
504 $arJoinProps =
array();
505 $bJoinFlatProp =
false;
509 $bCheckPermissions = !array_key_exists(
"CHECK_PERMISSIONS",
$arFilter) ||
$arFilter[
"CHECK_PERMISSIONS"]!==
"N";
510 $bIsAdmin = is_object(
$USER) &&
$USER->IsAdmin();
511 $permissionsBy =
null;
512 if ($bCheckPermissions && isset(
$arFilter[
'PERMISSIONS_BY']))
514 $permissionsBy = (int)
$arFilter[
'PERMISSIONS_BY'];
515 if ($permissionsBy < 0)
516 $permissionsBy =
null;
518 if($bCheckPermissions && ($permissionsBy !==
null || !$bIsAdmin))
520 $arFilter[
"MIN_PERMISSION"] ??= CIBlockRights::PUBLIC_READ;
521 $arSqlSearch[] = self::_check_rights_sql(
$arFilter[
"MIN_PERMISSION"], $permissionsBy);
523 unset($permissionsBy);
525 if(array_key_exists(
"PROPERTY",
$arFilter))
528 foreach(
$val as $propID=>$propVAL)
530 $res = CIBlock::MkOperationFilter($propID);
531 $propID =
$res[
"FIELD"];
532 $cOperationType =
$res[
"OPERATION"];
533 if($db_prop = CIBlockProperty::GetPropertyArray($propID, CIBlock::_MergeIBArrays(
$arFilter[
"IBLOCK_ID"],
$arFilter[
"IBLOCK_CODE"])))
537 if(array_key_exists($db_prop[
"ID"], $arJoinProps))
538 $iPropCnt = $arJoinProps[$db_prop[
"ID"]];
539 elseif($db_prop[
"VERSION"]!=2 || $db_prop[
"MULTIPLE"]==
"Y")
542 $iPropCnt=
count($arJoinProps);
545 if(!is_array($propVAL))
546 $propVAL = Array($propVAL);
548 if($db_prop[
"PROPERTY_TYPE"]==
"N" || $db_prop[
"PROPERTY_TYPE"]==
"G" || $db_prop[
"PROPERTY_TYPE"]==
"E")
550 if($db_prop[
"VERSION"]==2 && $db_prop[
"MULTIPLE"]==
"N")
552 $r = CIBlock::FilterCreate(
"FPS.PROPERTY_".$db_prop[
"ORIG_ID"], $propVAL,
"number", $cOperationType);
553 $bJoinFlatProp = $db_prop[
"IBLOCK_ID"];
556 $r = CIBlock::FilterCreate(
"FPV".$iPropCnt.
".VALUE_NUM", $propVAL,
"number", $cOperationType);
560 if($db_prop[
"VERSION"]==2 && $db_prop[
"MULTIPLE"]==
"N")
562 $r = CIBlock::FilterCreate(
"FPS.PROPERTY_".$db_prop[
"ORIG_ID"], $propVAL,
"string", $cOperationType);
563 $bJoinFlatProp = $db_prop[
"IBLOCK_ID"];
566 $r = CIBlock::FilterCreate(
"FPV".$iPropCnt.
".VALUE", $propVAL,
"string", $cOperationType);
573 $db_prop[
"iPropCnt"] = $iPropCnt;
574 $arJoinProps[$db_prop[
"ID"]] = $db_prop;
583 foreach($arSqlSearch as $r)
585 $strSqlSearch .=
"\n\t\t\t\tAND (".$r.
") ";
587 if(isset($obUserFieldsSql))
589 $r = $obUserFieldsSql->GetFilter();
591 $strSqlSearch .=
"\n\t\t\t\tAND (".$r.
") ";
595 foreach($arJoinProps as $propID=>$db_prop)
597 if($db_prop[
"VERSION"]==2)
598 $strTable =
"b_iblock_element_prop_m".$db_prop[
"IBLOCK_ID"];
600 $strTable =
"b_iblock_element_property";
601 $i = $db_prop[
"iPropCnt"];
603 LEFT JOIN b_iblock_property FP".$i.
" ON FP".
$i.
".IBLOCK_ID=B.ID AND
604 ".((int)$propID>0?
" FP".$i.
".ID=".(int)$propID.
" ":
" FP".
$i.
".CODE='".
$DB->ForSQL($propID, 200).
"' ").
"
605 LEFT JOIN ".$strTable.
" FPV".
$i.
" ON FP".
$i.
".ID=FPV".
$i.
".IBLOCK_PROPERTY_ID AND FPV".
$i.
".IBLOCK_ELEMENT_ID=BE.ID ";
609 LEFT JOIN b_iblock_element_prop_s".$bJoinFlatProp.
" FPS ON FPS.IBLOCK_ELEMENT_ID = BE.ID
615 INNER JOIN b_iblock B ON BS.IBLOCK_ID = B.ID
616 ".(isset($obUserFieldsSql)? $obUserFieldsSql->GetJoin(
"BS.ID"):
"").
"
618 " INNER JOIN b_iblock_section BSTEMP ON BSTEMP.IBLOCK_ID = BS.IBLOCK_ID
619 LEFT JOIN b_iblock_section_element BSE ON BSE.IBLOCK_SECTION_ID=BSTEMP.ID
620 LEFT JOIN b_iblock_element BE ON (BSE.IBLOCK_ELEMENT_ID=BE.ID
621 AND ((BE.WF_STATUS_ID=1 AND BE.WF_PARENT_ELEMENT_ID IS NULL )
622 AND BE.IBLOCK_ID = BS.IBLOCK_ID
623 ".($arFilter[
"CNT_ALL"]==
"Y"?
" OR BE.WF_NEW='Y' ":
"").
")
626 AND (BE.ACTIVE_TO >= ".$DB->CurrentTimeFunction().
" OR BE.ACTIVE_TO IS NULL)
627 AND (BE.ACTIVE_FROM <= ".
$DB->CurrentTimeFunction().
" OR BE.ACTIVE_FROM IS NULL)"
634 " AND BSTEMP.LEFT_MARGIN >= BS.LEFT_MARGIN
635 AND BSTEMP.RIGHT_MARGIN <= BS.RIGHT_MARGIN "
641 return $DB->Query($strSql);