PageRenderTime 22ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/components/bitrix/catalog.section.list/component.php

https://gitlab.com/alexprowars/bitrix
PHP | 516 lines | 451 code | 48 blank | 17 comment | 83 complexity | 7493f0a37171a5674d59cfaf59d80a22 MD5 | raw file
  1. <?php
  2. if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();
  3. /** @var CBitrixComponent $this */
  4. /** @var array $arParams */
  5. /** @var array $arResult */
  6. /** @var string $componentPath */
  7. /** @var string $componentName */
  8. /** @var string $componentTemplate */
  9. /** @global CDatabase $DB */
  10. /** @global CUser $USER */
  11. /** @global CMain $APPLICATION */
  12. use Bitrix\Main\Loader;
  13. use Bitrix\Main\Localization\Loc;
  14. use Bitrix\Iblock;
  15. /*************************************************************************
  16. Processing of received parameters
  17. *************************************************************************/
  18. if (!isset($arParams["CACHE_TIME"]))
  19. {
  20. $arParams["CACHE_TIME"] = 36000000;
  21. }
  22. $arParams["IBLOCK_TYPE"] = trim($arParams["IBLOCK_TYPE"] ?? '');
  23. $arParams["IBLOCK_ID"] = (int)($arParams["IBLOCK_ID"] ?? 0);
  24. $arParams["SECTION_ID"] = (int)($arParams["SECTION_ID"] ?? 0);
  25. $arParams["SECTION_CODE"] = trim($arParams["SECTION_CODE"] ?? '');
  26. $arParams["SECTION_URL"] = trim($arParams["SECTION_URL"] ?? '');
  27. $arParams["TOP_DEPTH"] = (int)($arParams["TOP_DEPTH"] ?? 0);
  28. if($arParams["TOP_DEPTH"] <= 0)
  29. {
  30. $arParams["TOP_DEPTH"] = 2;
  31. }
  32. $arParams["COUNT_ELEMENTS"] = !(isset($arParams["COUNT_ELEMENTS"]) && $arParams["COUNT_ELEMENTS"] === "N");
  33. if (!isset($arParams["COUNT_ELEMENTS_FILTER"]))
  34. {
  35. $arParams["COUNT_ELEMENTS_FILTER"] = "CNT_ACTIVE";
  36. }
  37. if (
  38. $arParams["COUNT_ELEMENTS_FILTER"] !== "CNT_ALL"
  39. && $arParams["COUNT_ELEMENTS_FILTER"] !== "CNT_ACTIVE"
  40. && $arParams["COUNT_ELEMENTS_FILTER"] !== "CNT_AVAILABLE"
  41. )
  42. {
  43. $arParams["COUNT_ELEMENTS_FILTER"] = "CNT_ALL";
  44. }
  45. $arParams["ADD_SECTIONS_CHAIN"] = !(isset($arParams["ADD_SECTIONS_CHAIN"]) && $arParams["ADD_SECTIONS_CHAIN"] === "N"); //Turn on by default
  46. if (
  47. empty($arParams["FILTER_NAME"])
  48. || !preg_match("/^[A-Za-z_][A-Za-z01-9_]*$/", $arParams["FILTER_NAME"])
  49. )
  50. {
  51. $arrFilter = array();
  52. }
  53. else
  54. {
  55. global ${$arParams["FILTER_NAME"]};
  56. $arrFilter = ${$arParams["FILTER_NAME"]};
  57. if(!is_array($arrFilter))
  58. {
  59. $arrFilter = [];
  60. }
  61. }
  62. $arParams["CACHE_FILTER"] = isset($arParams["CACHE_FILTER"]) && $arParams["CACHE_FILTER"] == "Y";
  63. if(!$arParams["CACHE_FILTER"] && !empty($arrFilter))
  64. {
  65. $arParams["CACHE_TIME"] = 0;
  66. }
  67. $arParams['SHOW_TITLE'] = ($arParams['SHOW_TITLE'] ?? 'N') === 'Y';
  68. $arResult["SECTIONS"] = array();
  69. /*************************************************************************
  70. Work with cache
  71. *************************************************************************/
  72. if ($this->startResultCache(
  73. false,
  74. array($arrFilter, ($arParams["CACHE_GROUPS"]==="N"? false: $USER->GetGroups()))
  75. ))
  76. {
  77. if (!Loader::includeModule("iblock"))
  78. {
  79. $this->abortResultCache();
  80. ShowError(Loc::getMessage("IBLOCK_MODULE_NOT_INSTALLED"));
  81. return;
  82. }
  83. $existIblock = Iblock\IblockSiteTable::getList(array(
  84. 'select' => array('IBLOCK_ID'),
  85. 'filter' => array(
  86. '=IBLOCK_ID' => $arParams['IBLOCK_ID'],
  87. '=SITE_ID' => SITE_ID,
  88. '=IBLOCK.ACTIVE' => 'Y',
  89. ),
  90. ))->fetch();
  91. if (empty($existIblock))
  92. {
  93. $this->abortResultCache();
  94. return;
  95. }
  96. $countTitleSuffix = '_ELEMENT';
  97. if (Loader::includeModule('catalog'))
  98. {
  99. $catalog = CCatalogSku::GetInfoByIBlock($arParams['IBLOCK_ID']);
  100. if (!empty($catalog))
  101. {
  102. $countTitleSuffix = '_PRODUCT';
  103. }
  104. }
  105. $arFilter = array(
  106. "ACTIVE" => "Y",
  107. "GLOBAL_ACTIVE" => "Y",
  108. "IBLOCK_ID" => $arParams["IBLOCK_ID"],
  109. );
  110. $arSelect = array();
  111. if (!empty($arParams["SECTION_FIELDS"]) && is_array($arParams["SECTION_FIELDS"]))
  112. {
  113. foreach($arParams["SECTION_FIELDS"] as &$field)
  114. {
  115. if (!empty($field) && is_string($field))
  116. {
  117. $arSelect[] = $field;
  118. }
  119. }
  120. unset($field);
  121. }
  122. if (!empty($arSelect))
  123. {
  124. $arSelect = array_merge(
  125. $arSelect,
  126. array(
  127. "ID",
  128. "NAME",
  129. "LEFT_MARGIN",
  130. "RIGHT_MARGIN",
  131. "DEPTH_LEVEL",
  132. "IBLOCK_ID",
  133. "IBLOCK_SECTION_ID",
  134. "LIST_PAGE_URL",
  135. "SECTION_PAGE_URL"
  136. )
  137. );
  138. }
  139. $boolPicture = empty($arSelect) || in_array('PICTURE', $arSelect);
  140. if (!empty($arParams["SECTION_USER_FIELDS"]) && is_array($arParams["SECTION_USER_FIELDS"]))
  141. {
  142. foreach($arParams["SECTION_USER_FIELDS"] as &$field)
  143. {
  144. if(is_string($field) && preg_match("/^UF_/", $field))
  145. {
  146. $arSelect[] = $field;
  147. }
  148. }
  149. unset($field);
  150. }
  151. $arSelect = array_unique($arSelect);
  152. $arResult["SECTION"] = false;
  153. $intSectionDepth = 0;
  154. if($arParams["SECTION_ID"]>0)
  155. {
  156. $arFilter["ID"] = $arParams["SECTION_ID"];
  157. $rsSections = CIBlockSection::GetList(array(), $arFilter, false, $arSelect);
  158. $rsSections->SetUrlTemplates("", $arParams["SECTION_URL"]);
  159. $arResult["SECTION"] = $rsSections->GetNext();
  160. }
  161. elseif ($arParams["SECTION_CODE"] !== '')
  162. {
  163. $arFilter["=CODE"] = $arParams["SECTION_CODE"];
  164. $rsSections = CIBlockSection::GetList(array(), $arFilter, false, $arSelect);
  165. $rsSections->SetUrlTemplates("", $arParams["SECTION_URL"]);
  166. $arResult["SECTION"] = $rsSections->GetNext();
  167. }
  168. if (is_array($arResult["SECTION"]))
  169. {
  170. $arResult["SECTION"]["~ELEMENT_CNT"] = null;
  171. $arResult["SECTION"]["ELEMENT_CNT"] = null;
  172. unset($arFilter["ID"]);
  173. unset($arFilter["=CODE"]);
  174. $arFilter["LEFT_MARGIN"] = $arResult["SECTION"]["LEFT_MARGIN"] + 1;
  175. $arFilter["RIGHT_MARGIN"] = $arResult["SECTION"]["RIGHT_MARGIN"];
  176. $arFilter["<="."DEPTH_LEVEL"] = $arResult["SECTION"]["DEPTH_LEVEL"] + $arParams["TOP_DEPTH"];
  177. $ipropValues = new \Bitrix\Iblock\InheritedProperty\SectionValues($arResult["SECTION"]["IBLOCK_ID"], $arResult["SECTION"]["ID"]);
  178. $arResult["SECTION"]["IPROPERTY_VALUES"] = $ipropValues->getValues();
  179. $arResult["SECTION"]["PATH"] = array();
  180. $rsPath = CIBlockSection::GetNavChain(
  181. $arResult["SECTION"]["IBLOCK_ID"],
  182. $arResult["SECTION"]["ID"],
  183. array(
  184. "ID", "CODE", "XML_ID", "EXTERNAL_ID", "IBLOCK_ID",
  185. "IBLOCK_SECTION_ID", "SORT", "NAME", "ACTIVE",
  186. "DEPTH_LEVEL", "SECTION_PAGE_URL"
  187. )
  188. );
  189. $rsPath->SetUrlTemplates("", $arParams["SECTION_URL"]);
  190. while($arPath = $rsPath->GetNext())
  191. {
  192. if ($arParams["ADD_SECTIONS_CHAIN"])
  193. {
  194. $ipropValues = new \Bitrix\Iblock\InheritedProperty\SectionValues($arParams["IBLOCK_ID"], $arPath["ID"]);
  195. $arPath["IPROPERTY_VALUES"] = $ipropValues->getValues();
  196. }
  197. $arResult["SECTION"]["PATH"][]=$arPath;
  198. }
  199. }
  200. else
  201. {
  202. $arResult["SECTION"] = array(
  203. "ID" => 0,
  204. "DEPTH_LEVEL" => 0,
  205. );
  206. $arFilter["<="."DEPTH_LEVEL"] = $arParams["TOP_DEPTH"];
  207. }
  208. $intSectionDepth = $arResult["SECTION"]['DEPTH_LEVEL'];
  209. $sectionFilter = array_merge($arrFilter, $arFilter);
  210. $elementCountFilter = array(
  211. "IBLOCK_ID" => $arParams["IBLOCK_ID"],
  212. "CHECK_PERMISSIONS" => "Y",
  213. "MIN_PERMISSION" => "R",
  214. "INCLUDE_SUBSECTIONS" => (isset($sectionFilter["ELEMENT_SUBSECTIONS"]) && $sectionFilter["ELEMENT_SUBSECTIONS"] == "N" ? "N" : "Y")
  215. );
  216. if (!empty($sectionFilter['PROPERTY']) && is_array($sectionFilter['PROPERTY']))
  217. {
  218. foreach (array_keys($sectionFilter['PROPERTY']) as $propertyId)
  219. {
  220. $field = CIBlock::MkOperationFilter($propertyId);
  221. $elementCountFilter[$field['PREFIX'].'PROPERTY_'.$field['FIELD']] = $sectionFilter['PROPERTY'][$propertyId];
  222. }
  223. unset($field, $propertyId, $value);
  224. }
  225. switch ($arParams["COUNT_ELEMENTS_FILTER"])
  226. {
  227. case "CNT_ALL":
  228. break;
  229. case "CNT_ACTIVE":
  230. $elementCountFilter["ACTIVE"] = "Y";
  231. $elementCountFilter["ACTIVE_DATE"] = "Y";
  232. break;
  233. case "CNT_AVAILABLE":
  234. $elementCountFilter["ACTIVE"] = "Y";
  235. $elementCountFilter["ACTIVE_DATE"] = "Y";
  236. $elementCountFilter["AVAILABLE"] = "Y";
  237. break;
  238. }
  239. if ($arParams["COUNT_ELEMENTS"] && $arResult['SECTION']['ID'] > 0)
  240. {
  241. $elementFilter = $elementCountFilter;
  242. $elementFilter['SECTION_ID'] = $arResult['SECTION']['ID'];
  243. if ($arResult['SECTION']['RIGHT_MARGIN'] == ($arResult['SECTION']['LEFT_MARGIN'] + 1))
  244. {
  245. $elementFilter['INCLUDE_SUBSECTIONS'] = 'N';
  246. }
  247. $arResult["SECTION"]["~ELEMENT_CNT"] = CIBlockElement::GetList(array(), $elementFilter, array());
  248. $arResult["SECTION"]["ELEMENT_CNT"] = $arResult["SECTION"]["~ELEMENT_CNT"];
  249. if (!empty($arResult["SECTION"]["ELEMENT_CNT"]))
  250. {
  251. $count = (int)$arResult["SECTION"]["ELEMENT_CNT"];
  252. $val = ($count < 100 ? $count : $count % 100);
  253. $dec = $val % 10;
  254. if ($val == 0)
  255. {
  256. $messageId = 'CP_BCSL_MESS_COUNT_ZERO';
  257. }
  258. elseif ($val == 1)
  259. {
  260. $messageId = 'CP_BCSL_MESS_COUNT_ONE';
  261. }
  262. elseif ($val >= 10 && $val <= 20)
  263. {
  264. $messageId = 'CP_BCSL_MESS_COUNT_TEN';
  265. }
  266. elseif ($dec == 1)
  267. {
  268. $messageId = 'CP_BCSL_MESS_COUNT_MOD_ONE';
  269. }
  270. elseif (2 <= $dec && $dec <= 4)
  271. {
  272. $messageId = 'CP_BCSL_MESS_COUNT_MOD_TWO';
  273. }
  274. else
  275. {
  276. $messageId = 'CP_BCSL_MESS_COUNT_OTHER';
  277. }
  278. $messageId .= $countTitleSuffix;
  279. $arResult["SECTION"]['ELEMENT_CNT_TITLE'] = Loc::getMessage($messageId, ['#VALUE#' => $count]);
  280. }
  281. }
  282. //ORDER BY
  283. $arSort = array();
  284. if (!empty($this->arParams['CUSTOM_SECTION_SORT']) && is_array($this->arParams['CUSTOM_SECTION_SORT']))
  285. {
  286. foreach ($this->arParams['CUSTOM_SECTION_SORT'] as $field => $value)
  287. {
  288. if (!is_string($value))
  289. {
  290. continue;
  291. }
  292. $field = strtoupper($field);
  293. if (isset($arSort[$field]))
  294. {
  295. continue;
  296. }
  297. if (!preg_match('/^(asc|desc|nulls)(,asc|,desc|,nulls)?$/i', $value))
  298. {
  299. continue;
  300. }
  301. $arSort[$field] = $value;
  302. }
  303. unset($field, $value);
  304. }
  305. if (empty($arSort))
  306. {
  307. $arSort = array(
  308. "LEFT_MARGIN" => "ASC",
  309. );
  310. }
  311. //EXECUTE
  312. $rsSections = CIBlockSection::GetList($arSort, $sectionFilter, false, $arSelect);
  313. $rsSections->SetUrlTemplates("", $arParams["SECTION_URL"]);
  314. while($arSection = $rsSections->GetNext())
  315. {
  316. \Bitrix\Iblock\InheritedProperty\SectionValues::queue($arSection["IBLOCK_ID"], $arSection["ID"]);
  317. $arSection['RELATIVE_DEPTH_LEVEL'] = $arSection['DEPTH_LEVEL'] - $intSectionDepth;
  318. $arButtons = CIBlock::GetPanelButtons(
  319. $arSection["IBLOCK_ID"],
  320. 0,
  321. $arSection["ID"],
  322. array("SESSID"=>false, "CATALOG"=>true)
  323. );
  324. $arSection["EDIT_LINK"] = $arButtons["edit"]["edit_section"]["ACTION_URL"];
  325. $arSection["DELETE_LINK"] = $arButtons["edit"]["delete_section"]["ACTION_URL"];
  326. $arSection["~ELEMENT_CNT"] = null;
  327. $arSection["ELEMENT_CNT"] = null;
  328. $arSection['ELEMENT_CNT_TITLE'] = '';
  329. $arResult["SECTIONS"][]=$arSection;
  330. }
  331. foreach ($arResult["SECTIONS"] as &$arSection)
  332. {
  333. $ipropValues = new \Bitrix\Iblock\InheritedProperty\SectionValues($arSection["IBLOCK_ID"], $arSection["ID"]);
  334. $arSection["IPROPERTY_VALUES"] = $ipropValues->getValues();
  335. if ($boolPicture)
  336. {
  337. \Bitrix\Iblock\Component\Tools::getFieldImageData(
  338. $arSection,
  339. array('PICTURE'),
  340. \Bitrix\Iblock\Component\Tools::IPROPERTY_ENTITY_SECTION,
  341. 'IPROPERTY_VALUES'
  342. );
  343. }
  344. if ($arParams["COUNT_ELEMENTS"])
  345. {
  346. $elementFilter = $elementCountFilter;
  347. $elementFilter["SECTION_ID"] = $arSection["ID"];
  348. if ($arSection['RIGHT_MARGIN'] == ($arSection['LEFT_MARGIN'] + 1))
  349. {
  350. $elementFilter['INCLUDE_SUBSECTIONS'] = 'N';
  351. }
  352. $arSection["~ELEMENT_CNT"] = CIBlockElement::GetList(array(), $elementFilter, array());
  353. $arSection["ELEMENT_CNT"] = $arSection["~ELEMENT_CNT"];
  354. if (!empty($arSection["ELEMENT_CNT"]))
  355. {
  356. $count = (int)$arSection["ELEMENT_CNT"];
  357. $val = ($count < 100 ? $count : $count % 100);
  358. $dec = $val % 10;
  359. if ($val == 0)
  360. {
  361. $messageId = 'CP_BCSL_MESS_COUNT_ZERO';
  362. }
  363. elseif ($val == 1)
  364. {
  365. $messageId = 'CP_BCSL_MESS_COUNT_ONE';
  366. }
  367. elseif ($val >= 10 && $val <= 20)
  368. {
  369. $messageId = 'CP_BCSL_MESS_COUNT_TEN';
  370. }
  371. elseif ($dec == 1)
  372. {
  373. $messageId = 'CP_BCSL_MESS_COUNT_MOD_ONE';
  374. }
  375. elseif (2 <= $dec && $dec <= 4)
  376. {
  377. $messageId = 'CP_BCSL_MESS_COUNT_MOD_TWO';
  378. }
  379. else
  380. {
  381. $messageId = 'CP_BCSL_MESS_COUNT_OTHER';
  382. }
  383. $messageId .= $countTitleSuffix;
  384. $arSection['ELEMENT_CNT_TITLE'] = Loc::getMessage($messageId, ['#VALUE#' => $count]);
  385. }
  386. }
  387. }
  388. unset($arSection);
  389. $arResult["SECTIONS_COUNT"] = count($arResult["SECTIONS"]);
  390. $this->setResultCacheKeys(array(
  391. "SECTIONS_COUNT",
  392. "SECTION",
  393. ));
  394. $this->includeComponentTemplate();
  395. }
  396. if ($arResult["SECTIONS_COUNT"] > 0 || isset($arResult["SECTION"]))
  397. {
  398. if(
  399. $USER->IsAuthorized()
  400. && $APPLICATION->GetShowIncludeAreas()
  401. && Loader::includeModule("iblock")
  402. )
  403. {
  404. $UrlDeleteSectionButton = "";
  405. if (isset($arResult["SECTION"]) && $arResult["SECTION"]['IBLOCK_SECTION_ID'] > 0)
  406. {
  407. $rsSection = CIBlockSection::GetList(
  408. array(),
  409. array("=ID" => $arResult["SECTION"]['IBLOCK_SECTION_ID']),
  410. false,
  411. array("SECTION_PAGE_URL")
  412. );
  413. $rsSection->SetUrlTemplates("", $arParams["SECTION_URL"]);
  414. $arSection = $rsSection->GetNext();
  415. $UrlDeleteSectionButton = $arSection["SECTION_PAGE_URL"];
  416. }
  417. if (empty($UrlDeleteSectionButton))
  418. {
  419. $url_template = CIBlock::GetArrayByID($arParams["IBLOCK_ID"], "LIST_PAGE_URL");
  420. $arIBlock = CIBlock::GetArrayByID($arParams["IBLOCK_ID"]);
  421. $arIBlock["IBLOCK_CODE"] = $arIBlock["CODE"];
  422. $UrlDeleteSectionButton = CIBlock::ReplaceDetailUrl($url_template, $arIBlock, true, false);
  423. }
  424. $arReturnUrl = array(
  425. "add_section" => (
  426. '' != $arParams["SECTION_URL"]?
  427. $arParams["SECTION_URL"]:
  428. CIBlock::GetArrayByID($arParams["IBLOCK_ID"], "SECTION_PAGE_URL")
  429. ),
  430. "add_element" => (
  431. '' != $arParams["SECTION_URL"]?
  432. $arParams["SECTION_URL"]:
  433. CIBlock::GetArrayByID($arParams["IBLOCK_ID"], "SECTION_PAGE_URL")
  434. ),
  435. "delete_section" => $UrlDeleteSectionButton,
  436. );
  437. $arButtons = CIBlock::GetPanelButtons(
  438. $arParams["IBLOCK_ID"],
  439. 0,
  440. $arResult["SECTION"]["ID"],
  441. array("RETURN_URL" => $arReturnUrl, "CATALOG"=>true)
  442. );
  443. $this->addIncludeAreaIcons(CIBlock::GetComponentMenu($APPLICATION->GetPublicShowMode(), $arButtons));
  444. }
  445. if($arParams["ADD_SECTIONS_CHAIN"] && isset($arResult["SECTION"]) && is_array($arResult["SECTION"]["PATH"]))
  446. {
  447. foreach($arResult["SECTION"]["PATH"] as $arPath)
  448. {
  449. if (
  450. isset($arPath["IPROPERTY_VALUES"]["SECTION_PAGE_TITLE"])
  451. && $arPath["IPROPERTY_VALUES"]["SECTION_PAGE_TITLE"] !== ""
  452. )
  453. {
  454. $APPLICATION->AddChainItem(
  455. $arPath["IPROPERTY_VALUES"]["SECTION_PAGE_TITLE"],
  456. $arPath["~SECTION_PAGE_URL"]
  457. );
  458. }
  459. else
  460. {
  461. $APPLICATION->AddChainItem(
  462. $arPath["NAME"],
  463. $arPath["~SECTION_PAGE_URL"]
  464. );
  465. }
  466. }
  467. }
  468. }