PageRenderTime 43ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/iblock/classes/mysql/iblocksection.php

https://gitlab.com/alexprowars/bitrix
PHP | 679 lines | 612 code | 49 blank | 18 comment | 103 complexity | d0f9e23a81f9651c47606c1c78128226 MD5 | raw file
  1. <?php
  2. use Bitrix\Iblock;
  3. class CIBlockSection extends CAllIBlockSection
  4. {
  5. /**
  6. * @param array $arOrder
  7. * @param array $arFilter
  8. * @param bool $bIncCnt
  9. * @param array $arSelect
  10. * @param array|false $arNavStartParams
  11. * @return CIBlockResult
  12. */
  13. public static function GetList($arOrder=array("SORT"=>"ASC"), $arFilter=array(), $bIncCnt = false, $arSelect = array(), $arNavStartParams=false)
  14. {
  15. global $DB, $USER, $USER_FIELD_MANAGER;
  16. if (!is_array($arOrder))
  17. $arOrder = array();
  18. if (!is_array($arFilter))
  19. $arFilter = array();
  20. if (!is_array($arSelect))
  21. $arSelect = array();
  22. $iblockFilterExist = (isset($arFilter['IBLOCK_ID']) && $arFilter['IBLOCK_ID'] > 0);
  23. $needUfManager = self::checkUfFields($arOrder, $arFilter, $arSelect);
  24. if ($needUfManager && !$iblockFilterExist)
  25. {
  26. trigger_error("Parameters of the CIBlockSection::GetList contains user fields, but arFilter has no IBLOCK_ID field.", E_USER_WARNING);
  27. }
  28. if ($needUfManager)
  29. {
  30. $userFieldsSelect = $arSelect;
  31. if (!in_array("UF_*", $userFieldsSelect))
  32. {
  33. if (!empty($arOrder) && is_array($arOrder))
  34. {
  35. foreach (array_keys($arOrder) as $userFieldName)
  36. {
  37. if (!in_array($userFieldName, $userFieldsSelect))
  38. $userFieldsSelect[] = $userFieldName;
  39. }
  40. unset($userFieldName);
  41. }
  42. }
  43. $obUserFieldsSql = new CUserTypeSQL;
  44. $obUserFieldsSql->SetEntity("IBLOCK_".$arFilter["IBLOCK_ID"]."_SECTION", "BS.ID");
  45. $obUserFieldsSql->SetSelect($userFieldsSelect);
  46. $obUserFieldsSql->SetFilter($arFilter);
  47. $obUserFieldsSql->SetOrder($arOrder);
  48. unset($userFieldsSelect);
  49. }
  50. $arJoinProps = array();
  51. $bJoinFlatProp = false;
  52. $arSqlSearch = CIBlockSection::GetFilter($arFilter);
  53. $bCheckPermissions = !array_key_exists("CHECK_PERMISSIONS", $arFilter) || $arFilter["CHECK_PERMISSIONS"]!=="N";
  54. $bIsAdmin = is_object($USER) && $USER->IsAdmin();
  55. $permissionsBy = null;
  56. if ($bCheckPermissions && isset($arFilter['PERMISSIONS_BY']))
  57. {
  58. $permissionsBy = (int)$arFilter['PERMISSIONS_BY'];
  59. if ($permissionsBy < 0)
  60. $permissionsBy = null;
  61. }
  62. if($bCheckPermissions && ($permissionsBy !== null || !$bIsAdmin))
  63. $arSqlSearch[] = self::_check_rights_sql($arFilter["MIN_PERMISSION"], $permissionsBy);
  64. unset($permissionsBy);
  65. if (!empty($arFilter["PROPERTY"]) && is_array($arFilter["PROPERTY"]))
  66. {
  67. $val = $arFilter["PROPERTY"];
  68. foreach($val as $propID=>$propVAL)
  69. {
  70. $res = CIBlock::MkOperationFilter($propID);
  71. $propID = $res["FIELD"];
  72. $cOperationType = $res["OPERATION"];
  73. if($db_prop = CIBlockProperty::GetPropertyArray($propID, CIBlock::_MergeIBArrays($arFilter["IBLOCK_ID"], $arFilter["IBLOCK_CODE"])))
  74. {
  75. $bSave = false;
  76. $separateSingle = (
  77. $db_prop["VERSION"] == Iblock\IblockTable::PROPERTY_STORAGE_SEPARATE
  78. && $db_prop["MULTIPLE"] == "N"
  79. );
  80. $iPropCnt = -1;
  81. if (isset($arJoinProps[$db_prop["ID"]]))
  82. {
  83. $iPropCnt = $arJoinProps[$db_prop["ID"]]["iPropCnt"];
  84. }
  85. elseif(!$separateSingle)
  86. {
  87. $bSave = true;
  88. $iPropCnt = count($arJoinProps);
  89. }
  90. if(!is_array($propVAL))
  91. $propVAL = Array($propVAL);
  92. if($db_prop["PROPERTY_TYPE"]=="N" || $db_prop["PROPERTY_TYPE"]=="G" || $db_prop["PROPERTY_TYPE"]=="E")
  93. {
  94. if($separateSingle)
  95. {
  96. $r = CIBlock::FilterCreate("FPS.PROPERTY_".$db_prop["ORIG_ID"], $propVAL, "number", $cOperationType);
  97. $bJoinFlatProp = $db_prop["IBLOCK_ID"];
  98. }
  99. else
  100. {
  101. $r = CIBlock::FilterCreate("FPV".$iPropCnt.".VALUE_NUM", $propVAL, "number", $cOperationType);
  102. }
  103. }
  104. else
  105. {
  106. if($separateSingle)
  107. {
  108. $r = CIBlock::FilterCreate("FPS.PROPERTY_".$db_prop["ORIG_ID"], $propVAL, "string", $cOperationType);
  109. $bJoinFlatProp = $db_prop["IBLOCK_ID"];
  110. }
  111. else
  112. {
  113. $r = CIBlock::FilterCreate("FPV".$iPropCnt.".VALUE", $propVAL, "string", $cOperationType);
  114. }
  115. }
  116. if($r != '')
  117. {
  118. if($bSave)
  119. {
  120. $db_prop["iPropCnt"] = $iPropCnt;
  121. $arJoinProps[$db_prop["ID"]] = $db_prop;
  122. }
  123. $arSqlSearch[] = $r;
  124. }
  125. }
  126. }
  127. }
  128. $strSqlSearch = "";
  129. foreach($arSqlSearch as $r)
  130. if($r <> '')
  131. $strSqlSearch .= "\n\t\t\t\tAND (".$r.") ";
  132. if(isset($obUserFieldsSql))
  133. {
  134. $r = $obUserFieldsSql->GetFilter();
  135. if($r <> '')
  136. $strSqlSearch .= "\n\t\t\t\tAND (".$r.") ";
  137. }
  138. $strProp1 = "";
  139. foreach($arJoinProps as $propID=>$db_prop)
  140. {
  141. if($db_prop["VERSION"]==2)
  142. $strTable = "b_iblock_element_prop_m".$db_prop["IBLOCK_ID"];
  143. else
  144. $strTable = "b_iblock_element_property";
  145. $i = $db_prop["iPropCnt"];
  146. $strProp1 .= "
  147. LEFT JOIN b_iblock_property FP".$i." ON FP".$i.".IBLOCK_ID=B.ID AND
  148. ".((int)$propID>0?" FP".$i.".ID=".(int)$propID." ":" FP".$i.".CODE='".$DB->ForSQL($propID, 200)."' ")."
  149. LEFT JOIN ".$strTable." FPV".$i." ON FP".$i.".ID=FPV".$i.".IBLOCK_PROPERTY_ID AND FPV".$i.".IBLOCK_ELEMENT_ID=BE.ID ";
  150. }
  151. if($bJoinFlatProp)
  152. $strProp1 .= "
  153. LEFT JOIN b_iblock_element_prop_s".$bJoinFlatProp." FPS ON FPS.IBLOCK_ELEMENT_ID = BE.ID
  154. ";
  155. $arFields = array(
  156. "ID" => "BS.ID",
  157. "CODE" => "BS.CODE",
  158. "XML_ID" => "BS.XML_ID",
  159. "EXTERNAL_ID" => "BS.XML_ID",
  160. "IBLOCK_ID" => "BS.IBLOCK_ID",
  161. "IBLOCK_SECTION_ID" => "BS.IBLOCK_SECTION_ID",
  162. "TIMESTAMP_X" => $DB->DateToCharFunction("BS.TIMESTAMP_X"),
  163. "TIMESTAMP_X_UNIX" => 'UNIX_TIMESTAMP(BS.TIMESTAMP_X)',
  164. "SORT" => "BS.SORT",
  165. "NAME" => "BS.NAME",
  166. "ACTIVE" => "BS.ACTIVE",
  167. "GLOBAL_ACTIVE" => "BS.GLOBAL_ACTIVE",
  168. "PICTURE" => "BS.PICTURE",
  169. "DESCRIPTION" => "BS.DESCRIPTION",
  170. "DESCRIPTION_TYPE" => "BS.DESCRIPTION_TYPE",
  171. "LEFT_MARGIN" => "BS.LEFT_MARGIN",
  172. "RIGHT_MARGIN" => "BS.RIGHT_MARGIN",
  173. "DEPTH_LEVEL" => "BS.DEPTH_LEVEL",
  174. "SEARCHABLE_CONTENT" => "BS.SEARCHABLE_CONTENT",
  175. "MODIFIED_BY" => "BS.MODIFIED_BY",
  176. "DATE_CREATE" => $DB->DateToCharFunction("BS.DATE_CREATE"),
  177. "DATE_CREATE_UNIX" => 'UNIX_TIMESTAMP(BS.DATE_CREATE)',
  178. "CREATED_BY" => "BS.CREATED_BY",
  179. "DETAIL_PICTURE" => "BS.DETAIL_PICTURE",
  180. "TMP_ID" => "BS.TMP_ID",
  181. "LIST_PAGE_URL" => "B.LIST_PAGE_URL",
  182. "SECTION_PAGE_URL" => "B.SECTION_PAGE_URL",
  183. "IBLOCK_TYPE_ID" => "B.IBLOCK_TYPE_ID",
  184. "IBLOCK_CODE" => "B.CODE",
  185. "IBLOCK_EXTERNAL_ID" => "B.XML_ID",
  186. "SOCNET_GROUP_ID" => "BS.SOCNET_GROUP_ID",
  187. );
  188. $arSqlSelect = array();
  189. foreach($arSelect as $field)
  190. {
  191. $field = mb_strtoupper($field);
  192. if(isset($arFields[$field]))
  193. $arSqlSelect[$field] = $arFields[$field]." AS ".$field;
  194. }
  195. if(isset($arSqlSelect['DESCRIPTION']))
  196. $arSqlSelect["DESCRIPTION_TYPE"] = $arFields["DESCRIPTION_TYPE"]." AS DESCRIPTION_TYPE";
  197. if(isset($arSqlSelect['LIST_PAGE_URL']) || isset($arSqlSelect['SECTION_PAGE_URL']))
  198. {
  199. $arSqlSelect["ID"] = $arFields["ID"]." AS ID";
  200. $arSqlSelect["CODE"] = $arFields["CODE"]." AS CODE";
  201. $arSqlSelect["EXTERNAL_ID"] = $arFields["EXTERNAL_ID"]." AS EXTERNAL_ID";
  202. $arSqlSelect["IBLOCK_TYPE_ID"] = $arFields["IBLOCK_TYPE_ID"]." AS IBLOCK_TYPE_ID";
  203. $arSqlSelect["IBLOCK_ID"] = $arFields["IBLOCK_ID"]." AS IBLOCK_ID";
  204. $arSqlSelect["IBLOCK_CODE"] = $arFields["IBLOCK_CODE"]." AS IBLOCK_CODE";
  205. $arSqlSelect["IBLOCK_EXTERNAL_ID"] = $arFields["IBLOCK_EXTERNAL_ID"]." AS IBLOCK_EXTERNAL_ID";
  206. $arSqlSelect["GLOBAL_ACTIVE"] = $arFields["GLOBAL_ACTIVE"]." AS GLOBAL_ACTIVE";
  207. //$arr["LANG_DIR"],
  208. }
  209. $additionalSelect = array();
  210. $arSqlOrder = array();
  211. foreach($arOrder as $by=>$order)
  212. {
  213. $by = mb_strtolower($by);
  214. if(isset($arSqlOrder[$by]))
  215. continue;
  216. $order = mb_strtolower($order);
  217. if($order!="asc")
  218. $order = "desc";
  219. switch ($by)
  220. {
  221. case "id":
  222. $arSqlOrder[$by] = " BS.ID ".$order." ";
  223. $additionalSelect["ID"] = $arFields["ID"]." AS ID";
  224. break;
  225. case "section":
  226. $arSqlOrder[$by] = " BS.IBLOCK_SECTION_ID ".$order." ";
  227. $additionalSelect["IBLOCK_SECTION_ID"] = $arFields["IBLOCK_SECTION_ID"]." AS IBLOCK_SECTION_ID";
  228. break;
  229. case "name":
  230. $arSqlOrder[$by] = " BS.NAME ".$order." ";
  231. $additionalSelect["NAME"] = $arFields["NAME"]." AS NAME";
  232. break;
  233. case "code":
  234. $arSqlOrder[$by] = " BS.CODE ".$order." ";
  235. $additionalSelect["CODE"] = $arFields["CODE"]." AS CODE";
  236. break;
  237. case "external_id":
  238. case "xml_id":
  239. $arSqlOrder[$by] = " BS.XML_ID ".$order." ";
  240. $additionalSelect["XML_ID"] = $arFields["XML_ID"]." AS XML_ID";
  241. break;
  242. case "active":
  243. $arSqlOrder[$by] = " BS.ACTIVE ".$order." ";
  244. $additionalSelect["ACTIVE"] = $arFields["ACTIVE"]." AS ACTIVE";
  245. break;
  246. case "left_margin":
  247. $arSqlOrder[$by] = " BS.LEFT_MARGIN ".$order." ";
  248. $additionalSelect["LEFT_MARGIN"] = $arFields["LEFT_MARGIN"]." AS LEFT_MARGIN";
  249. break;
  250. case "depth_level":
  251. $arSqlOrder[$by] = " BS.DEPTH_LEVEL ".$order." ";
  252. $additionalSelect["DEPTH_LEVEL"] = $arFields["DEPTH_LEVEL"]." AS DEPTH_LEVEL";
  253. break;
  254. case "sort":
  255. $arSqlOrder[$by] = " BS.SORT ".$order." ";
  256. $additionalSelect["SORT"] = $arFields["SORT"]." AS SORT";
  257. break;
  258. case "created":
  259. $arSqlOrder[$by] = " BS.DATE_CREATE ".$order." ";
  260. $additionalSelect["DATE_CREATE"] = $arFields["DATE_CREATE"]." AS DATE_CREATE";
  261. break;
  262. case "created_by":
  263. $arSqlOrder[$by] = " BS.CREATED_BY ".$order." ";
  264. $additionalSelect["CREATED_BY"] = $arFields["CREATED_BY"]." AS CREATED_BY";
  265. break;
  266. case "modified_by":
  267. $arSqlOrder[$by] = " BS.MODIFIED_BY ".$order." ";
  268. $additionalSelect["MODIFIED_BY"] = $arFields["MODIFIED_BY"]." AS MODIFIED_BY";
  269. break;
  270. default:
  271. if ($bIncCnt && $by == "element_cnt")
  272. {
  273. $arSqlOrder[$by] = " ELEMENT_CNT ".$order." ";
  274. }
  275. elseif (isset($obUserFieldsSql) && $s = $obUserFieldsSql->GetOrder($by))
  276. {
  277. $arSqlOrder[$by] = " ".$s." ".$order." ";
  278. }
  279. else
  280. {
  281. $by = "timestamp_x";
  282. $arSqlOrder[$by] = " BS.TIMESTAMP_X ".$order." ";
  283. $additionalSelect["TIMESTAMP_X_SORT"] = "BS.TIMESTAMP_X AS TSX_TMP";
  284. }
  285. }
  286. }
  287. if (!empty($additionalSelect) && !empty($arSqlSelect))
  288. {
  289. foreach ($additionalSelect as $key => $value)
  290. $arSqlSelect[$key] = $value;
  291. }
  292. if(!empty($arSqlSelect))
  293. $sSelect = implode(",\n", $arSqlSelect);
  294. else
  295. $sSelect = "
  296. BS.*,
  297. B.LIST_PAGE_URL,
  298. B.SECTION_PAGE_URL,
  299. B.IBLOCK_TYPE_ID,
  300. B.CODE as IBLOCK_CODE,
  301. B.XML_ID as IBLOCK_EXTERNAL_ID,
  302. BS.XML_ID as EXTERNAL_ID,
  303. ".$DB->DateToCharFunction("BS.TIMESTAMP_X")." as TIMESTAMP_X,
  304. ".$DB->DateToCharFunction("BS.DATE_CREATE")." as DATE_CREATE
  305. ";
  306. if(!$bIncCnt)
  307. {
  308. $strSelect = $sSelect.(isset($obUserFieldsSql)? $obUserFieldsSql->GetSelect(): "");
  309. $strSql = "
  310. FROM b_iblock_section BS
  311. INNER JOIN b_iblock B ON BS.IBLOCK_ID = B.ID
  312. ".(isset($obUserFieldsSql)? $obUserFieldsSql->GetJoin("BS.ID"): "")."
  313. ".($strProp1 <> ''?
  314. " INNER JOIN b_iblock_section BSTEMP ON BSTEMP.IBLOCK_ID = BS.IBLOCK_ID
  315. LEFT JOIN b_iblock_section_element BSE ON BSE.IBLOCK_SECTION_ID=BSTEMP.ID
  316. LEFT JOIN b_iblock_element BE ON (BSE.IBLOCK_ELEMENT_ID=BE.ID
  317. AND ((BE.WF_STATUS_ID=1 AND BE.WF_PARENT_ELEMENT_ID IS NULL )
  318. AND BE.IBLOCK_ID = BS.IBLOCK_ID
  319. ".($arFilter["CNT_ALL"]=="Y"?" OR BE.WF_NEW='Y' ":"").")
  320. ".($arFilter["CNT_ACTIVE"]=="Y"?
  321. " AND BE.ACTIVE='Y'
  322. AND (BE.ACTIVE_TO >= ".$DB->CurrentTimeFunction()." OR BE.ACTIVE_TO IS NULL)
  323. AND (BE.ACTIVE_FROM <= ".$DB->CurrentTimeFunction()." OR BE.ACTIVE_FROM IS NULL)"
  324. :"").")
  325. ".$strProp1." "
  326. :"")."
  327. WHERE 1=1
  328. ".($strProp1 <> ''?
  329. " AND BSTEMP.LEFT_MARGIN >= BS.LEFT_MARGIN
  330. AND BSTEMP.RIGHT_MARGIN <= BS.RIGHT_MARGIN "
  331. :""
  332. )."
  333. ".$strSqlSearch."
  334. ";
  335. $strGroupBy = "";
  336. }
  337. else
  338. {
  339. $strSelect = $sSelect.",COUNT(DISTINCT BE.ID) as ELEMENT_CNT".(isset($obUserFieldsSql)? $obUserFieldsSql->GetSelect(): "");
  340. $strSql = "
  341. FROM b_iblock_section BS
  342. INNER JOIN b_iblock B ON BS.IBLOCK_ID = B.ID
  343. ".(isset($obUserFieldsSql)? $obUserFieldsSql->GetJoin("BS.ID"): "")."
  344. ".($arFilter["ELEMENT_SUBSECTIONS"]=="N"?
  345. " LEFT JOIN b_iblock_section_element BSE ON BSE.IBLOCK_SECTION_ID=BS.ID "
  346. :
  347. " INNER JOIN b_iblock_section BSTEMP ON BSTEMP.IBLOCK_ID = BS.IBLOCK_ID
  348. LEFT JOIN b_iblock_section_element BSE ON BSE.IBLOCK_SECTION_ID=BSTEMP.ID "
  349. )."
  350. LEFT JOIN b_iblock_element BE ON (BSE.IBLOCK_ELEMENT_ID=BE.ID
  351. AND ((BE.WF_STATUS_ID=1 AND BE.WF_PARENT_ELEMENT_ID IS NULL )
  352. AND BE.IBLOCK_ID = BS.IBLOCK_ID
  353. ".($arFilter["CNT_ALL"]=="Y"?" OR BE.WF_NEW='Y' ":"").")
  354. ".($arFilter["CNT_ACTIVE"]=="Y"?
  355. " AND BE.ACTIVE='Y'
  356. AND (BE.ACTIVE_TO >= ".$DB->CurrentTimeFunction()." OR BE.ACTIVE_TO IS NULL)
  357. AND (BE.ACTIVE_FROM <= ".$DB->CurrentTimeFunction()." OR BE.ACTIVE_FROM IS NULL)"
  358. :"").")
  359. ".$strProp1."
  360. WHERE 1=1
  361. ".($arFilter["ELEMENT_SUBSECTIONS"]=="N"
  362. ?
  363. " "
  364. :
  365. " AND BSTEMP.IBLOCK_ID = BS.IBLOCK_ID
  366. AND BSTEMP.LEFT_MARGIN >= BS.LEFT_MARGIN
  367. AND BSTEMP.RIGHT_MARGIN <= BS.RIGHT_MARGIN
  368. ".($arFilter["CNT_ACTIVE"]=="Y"? "AND BSTEMP.GLOBAL_ACTIVE = 'Y'": "")."
  369. "
  370. )."
  371. ".$strSqlSearch."
  372. ";
  373. $strGroupBy = "GROUP BY BS.ID, B.ID";
  374. }
  375. if(!empty($arSqlOrder))
  376. $strSqlOrder = "\n\t\t\t\tORDER BY ".implode(", ", $arSqlOrder);
  377. else
  378. $strSqlOrder = "";
  379. if(is_array($arNavStartParams))
  380. {
  381. $nTopCount = (int)($arNavStartParams['nTopCount'] ?? 0);
  382. if($nTopCount > 0)
  383. {
  384. $res = $DB->Query($DB->TopSql(
  385. "SELECT DISTINCT ".$strSelect.$strSql.$strGroupBy.$strSqlOrder,
  386. $nTopCount
  387. ));
  388. if($iblockFilterExist)
  389. {
  390. $res->SetUserFields($USER_FIELD_MANAGER->GetUserFields("IBLOCK_".$arFilter["IBLOCK_ID"]."_SECTION"));
  391. }
  392. }
  393. else
  394. {
  395. $res_cnt = $DB->Query("SELECT COUNT(DISTINCT BS.ID) as C ".$strSql);
  396. $res_cnt = $res_cnt->Fetch();
  397. $res = new CDBResult();
  398. if($iblockFilterExist)
  399. {
  400. $res->SetUserFields($USER_FIELD_MANAGER->GetUserFields("IBLOCK_".$arFilter["IBLOCK_ID"]."_SECTION"));
  401. }
  402. $res->NavQuery("SELECT DISTINCT ".$strSelect.$strSql.$strGroupBy.$strSqlOrder, $res_cnt["C"], $arNavStartParams);
  403. }
  404. }
  405. else
  406. {
  407. $res = $DB->Query("SELECT DISTINCT ".$strSelect.$strSql.$strGroupBy.$strSqlOrder, false, "FILE: ".__FILE__."<br> LINE: ".__LINE__);
  408. if($iblockFilterExist)
  409. {
  410. $res->SetUserFields($USER_FIELD_MANAGER->GetUserFields("IBLOCK_".$arFilter["IBLOCK_ID"]."_SECTION"));
  411. }
  412. }
  413. $res = new CIBlockResult($res);
  414. if($iblockFilterExist)
  415. {
  416. $res->SetIBlockTag($arFilter["IBLOCK_ID"]);
  417. }
  418. return $res;
  419. }
  420. ///////////////////////////////////////////////////////////////////
  421. // Update list of sections w/o any events
  422. ///////////////////////////////////////////////////////////////////
  423. protected function UpdateList($arFields, $arFilter = array())
  424. {
  425. global $DB, $USER;
  426. $strUpdate = $DB->PrepareUpdate("b_iblock_section", $arFields, "iblock", false, "BS");
  427. if ($strUpdate == "")
  428. return false;
  429. if(isset($arFilter["IBLOCK_ID"]) && $arFilter["IBLOCK_ID"] > 0)
  430. {
  431. $obUserFieldsSql = new CUserTypeSQL;
  432. $obUserFieldsSql->SetEntity("IBLOCK_".$arFilter["IBLOCK_ID"]."_SECTION", "BS.ID");
  433. $obUserFieldsSql->SetFilter($arFilter);
  434. }
  435. else
  436. {
  437. foreach($arFilter as $key => $val)
  438. {
  439. $res = CIBlock::MkOperationFilter($key);
  440. if(preg_match("/^UF_/", $res["FIELD"]))
  441. {
  442. trigger_error("arFilter parameter of the CIBlockSection::GetList contains user fields, but has no IBLOCK_ID field.", E_USER_WARNING);
  443. break;
  444. }
  445. }
  446. }
  447. $arJoinProps = array();
  448. $bJoinFlatProp = false;
  449. $arSqlSearch = CIBlockSection::GetFilter($arFilter);
  450. $bCheckPermissions = !array_key_exists("CHECK_PERMISSIONS", $arFilter) || $arFilter["CHECK_PERMISSIONS"]!=="N";
  451. $bIsAdmin = is_object($USER) && $USER->IsAdmin();
  452. $permissionsBy = null;
  453. if ($bCheckPermissions && isset($arFilter['PERMISSIONS_BY']))
  454. {
  455. $permissionsBy = (int)$arFilter['PERMISSIONS_BY'];
  456. if ($permissionsBy < 0)
  457. $permissionsBy = null;
  458. }
  459. if($bCheckPermissions && ($permissionsBy !== null || !$bIsAdmin))
  460. $arSqlSearch[] = self::_check_rights_sql($arFilter["MIN_PERMISSION"], $permissionsBy);
  461. unset($permissionsBy);
  462. if(array_key_exists("PROPERTY", $arFilter))
  463. {
  464. $val = $arFilter["PROPERTY"];
  465. foreach($val as $propID=>$propVAL)
  466. {
  467. $res = CIBlock::MkOperationFilter($propID);
  468. $propID = $res["FIELD"];
  469. $cOperationType = $res["OPERATION"];
  470. if($db_prop = CIBlockProperty::GetPropertyArray($propID, CIBlock::_MergeIBArrays($arFilter["IBLOCK_ID"], $arFilter["IBLOCK_CODE"])))
  471. {
  472. $bSave = false;
  473. if(array_key_exists($db_prop["ID"], $arJoinProps))
  474. $iPropCnt = $arJoinProps[$db_prop["ID"]];
  475. elseif($db_prop["VERSION"]!=2 || $db_prop["MULTIPLE"]=="Y")
  476. {
  477. $bSave = true;
  478. $iPropCnt=count($arJoinProps);
  479. }
  480. if(!is_array($propVAL))
  481. $propVAL = Array($propVAL);
  482. if($db_prop["PROPERTY_TYPE"]=="N" || $db_prop["PROPERTY_TYPE"]=="G" || $db_prop["PROPERTY_TYPE"]=="E")
  483. {
  484. if($db_prop["VERSION"]==2 && $db_prop["MULTIPLE"]=="N")
  485. {
  486. $r = CIBlock::FilterCreate("FPS.PROPERTY_".$db_prop["ORIG_ID"], $propVAL, "number", $cOperationType);
  487. $bJoinFlatProp = $db_prop["IBLOCK_ID"];
  488. }
  489. else
  490. $r = CIBlock::FilterCreate("FPV".$iPropCnt.".VALUE_NUM", $propVAL, "number", $cOperationType);
  491. }
  492. else
  493. {
  494. if($db_prop["VERSION"]==2 && $db_prop["MULTIPLE"]=="N")
  495. {
  496. $r = CIBlock::FilterCreate("FPS.PROPERTY_".$db_prop["ORIG_ID"], $propVAL, "string", $cOperationType);
  497. $bJoinFlatProp = $db_prop["IBLOCK_ID"];
  498. }
  499. else
  500. $r = CIBlock::FilterCreate("FPV".$iPropCnt.".VALUE", $propVAL, "string", $cOperationType);
  501. }
  502. if($r <> '')
  503. {
  504. if($bSave)
  505. {
  506. $db_prop["iPropCnt"] = $iPropCnt;
  507. $arJoinProps[$db_prop["ID"]] = $db_prop;
  508. }
  509. $arSqlSearch[] = $r;
  510. }
  511. }
  512. }
  513. }
  514. $strSqlSearch = "";
  515. foreach($arSqlSearch as $r)
  516. if($r <> '')
  517. $strSqlSearch .= "\n\t\t\t\tAND (".$r.") ";
  518. if(isset($obUserFieldsSql))
  519. {
  520. $r = $obUserFieldsSql->GetFilter();
  521. if($r <> '')
  522. $strSqlSearch .= "\n\t\t\t\tAND (".$r.") ";
  523. }
  524. $strProp1 = "";
  525. foreach($arJoinProps as $propID=>$db_prop)
  526. {
  527. if($db_prop["VERSION"]==2)
  528. $strTable = "b_iblock_element_prop_m".$db_prop["IBLOCK_ID"];
  529. else
  530. $strTable = "b_iblock_element_property";
  531. $i = $db_prop["iPropCnt"];
  532. $strProp1 .= "
  533. LEFT JOIN b_iblock_property FP".$i." ON FP".$i.".IBLOCK_ID=B.ID AND
  534. ".((int)$propID>0?" FP".$i.".ID=".(int)$propID." ":" FP".$i.".CODE='".$DB->ForSQL($propID, 200)."' ")."
  535. LEFT JOIN ".$strTable." FPV".$i." ON FP".$i.".ID=FPV".$i.".IBLOCK_PROPERTY_ID AND FPV".$i.".IBLOCK_ELEMENT_ID=BE.ID ";
  536. }
  537. if($bJoinFlatProp)
  538. $strProp1 .= "
  539. LEFT JOIN b_iblock_element_prop_s".$bJoinFlatProp." FPS ON FPS.IBLOCK_ELEMENT_ID = BE.ID
  540. ";
  541. $strSql = "
  542. UPDATE
  543. b_iblock_section BS
  544. INNER JOIN b_iblock B ON BS.IBLOCK_ID = B.ID
  545. ".(isset($obUserFieldsSql)? $obUserFieldsSql->GetJoin("BS.ID"): "")."
  546. ".($strProp1 <> ''?
  547. " INNER JOIN b_iblock_section BSTEMP ON BSTEMP.IBLOCK_ID = BS.IBLOCK_ID
  548. LEFT JOIN b_iblock_section_element BSE ON BSE.IBLOCK_SECTION_ID=BSTEMP.ID
  549. LEFT JOIN b_iblock_element BE ON (BSE.IBLOCK_ELEMENT_ID=BE.ID
  550. AND ((BE.WF_STATUS_ID=1 AND BE.WF_PARENT_ELEMENT_ID IS NULL )
  551. AND BE.IBLOCK_ID = BS.IBLOCK_ID
  552. ".($arFilter["CNT_ALL"]=="Y"?" OR BE.WF_NEW='Y' ":"").")
  553. ".($arFilter["CNT_ACTIVE"]=="Y"?
  554. " AND BE.ACTIVE='Y'
  555. AND (BE.ACTIVE_TO >= ".$DB->CurrentTimeFunction()." OR BE.ACTIVE_TO IS NULL)
  556. AND (BE.ACTIVE_FROM <= ".$DB->CurrentTimeFunction()." OR BE.ACTIVE_FROM IS NULL)"
  557. :"").")
  558. ".$strProp1." "
  559. :"")."
  560. SET ".$strUpdate."
  561. WHERE 1=1
  562. ".($strProp1 <> ''?
  563. " AND BSTEMP.LEFT_MARGIN >= BS.LEFT_MARGIN
  564. AND BSTEMP.RIGHT_MARGIN <= BS.RIGHT_MARGIN "
  565. :""
  566. )."
  567. ".$strSqlSearch."
  568. ";
  569. return $DB->Query($strSql, false, "FILE: ".__FILE__."<br> LINE: ".__LINE__);
  570. }
  571. /**
  572. * @param array $order
  573. * @param array $filter
  574. * @param array $select
  575. * @return bool
  576. */
  577. private static function checkUfFields(array $order, array $filter, array $select): bool
  578. {
  579. $result = false;
  580. $parsed = array();
  581. if (!empty($select))
  582. {
  583. if (in_array('UF_*', $select))
  584. {
  585. $result = true;
  586. }
  587. else
  588. {
  589. foreach ($select as $field)
  590. {
  591. if (preg_match('/^UF_/', $field, $parsed))
  592. {
  593. $result = true;
  594. break;
  595. }
  596. }
  597. unset($field);
  598. }
  599. }
  600. if (!$result && !empty($filter))
  601. {
  602. $filter = array_keys($filter);
  603. foreach ($filter as $key)
  604. {
  605. $field = CIBlock::MkOperationFilter($key);
  606. if (preg_match('/^UF_/', $field['FIELD'], $parsed))
  607. {
  608. $result = true;
  609. break;
  610. }
  611. }
  612. unset($field, $key);
  613. }
  614. if (!$result && !empty($order))
  615. {
  616. $order = array_keys($order);
  617. foreach ($order as $field)
  618. {
  619. if (preg_match('/^UF_/', $field, $parsed))
  620. {
  621. $result = true;
  622. break;
  623. }
  624. }
  625. unset($field);
  626. }
  627. unset($parced);
  628. return $result;
  629. }
  630. }