• Модуль: iblock
  • Путь к файлу: ~/bitrix/modules/iblock/classes/general/iblocksection.php
  • Класс: CAllIBlockSection
  • Вызов: CAllIBlockSection::recountTreeAfterAdd
static function recountTreeAfterAdd($arFields)
{
	global $DB;

	$ID = (int)$arFields['ID'];
	$IBLOCK_ID = (int)$arFields['IBLOCK_ID'];

	$arParent = false;
	if ($arFields["IBLOCK_SECTION_ID"] !== false)
	{
		$strSql = "
			SELECT BS.ID, BS.ACTIVE, BS.GLOBAL_ACTIVE, BS.DEPTH_LEVEL, BS.LEFT_MARGIN, BS.RIGHT_MARGIN
			FROM b_iblock_section BS
			WHERE BS.IBLOCK_ID = ".$IBLOCK_ID."
			AND BS.ID = ".$arFields["IBLOCK_SECTION_ID"]."
		";
		$rsParent = $DB->Query($strSql);
		$arParent = $rsParent->Fetch();
	}

	$NAME = $arFields["NAME"];
	$SORT = (int)$arFields["SORT"];

	//Find rightmost child of the parent
	$strSql = "
		SELECT BS.ID, BS.RIGHT_MARGIN, BS.GLOBAL_ACTIVE, BS.DEPTH_LEVEL
		FROM b_iblock_section BS
		WHERE BS.IBLOCK_ID = ".$IBLOCK_ID."
		AND ".($arFields["IBLOCK_SECTION_ID"] !== false ? "BS.IBLOCK_SECTION_ID=".$arFields["IBLOCK_SECTION_ID"] : "BS.IBLOCK_SECTION_ID IS NULL")."
		AND (
			(BS.SORT < ".$SORT.")
			OR (BS.SORT = ".$SORT." AND BS.NAME < '".$DB->ForSQL($NAME)."')
		)
		AND BS.ID <> ".$ID."
		ORDER BY BS.SORT DESC, BS.NAME DESC
	";
	$rsChild = $DB->Query($strSql);

	if ($arChild = $rsChild->Fetch())
	{
		//We found the left neighbour
		$arUpdate = array(
			"LEFT_MARGIN" => (int)$arChild["RIGHT_MARGIN"] + 1,
			"RIGHT_MARGIN" => (int)$arChild["RIGHT_MARGIN"] + 2,
			"DEPTH_LEVEL" => (int)$arChild["DEPTH_LEVEL"],
		);

		//in case we adding active section
		if ($arFields["ACTIVE"] != "N")
		{
			//Look up GLOBAL_ACTIVE of the parent
			//if none then take our own
			if ($arParent)//We must inherit active from the parent
			{
				$arUpdate["GLOBAL_ACTIVE"] = $arParent["GLOBAL_ACTIVE"] == "Y" ? "Y" : "N";
			}
			else //No parent was found take our own
			{
				$arUpdate["GLOBAL_ACTIVE"] = "Y";
			}
		}
		else
		{
			$arUpdate["GLOBAL_ACTIVE"] = "N";
		}
	}
	else
	{
		//If we have parent, when take its left_margin
		if ($arParent)
		{
			$arUpdate = array(
				"LEFT_MARGIN" => (int)$arParent["LEFT_MARGIN"] + 1,
				"RIGHT_MARGIN" => (int)$arParent["LEFT_MARGIN"] + 2,
				"GLOBAL_ACTIVE" => ($arParent["GLOBAL_ACTIVE"] == "Y") && ($arFields["ACTIVE"] != "N") ? "Y" : "N",
				"DEPTH_LEVEL" => (int)$arParent["DEPTH_LEVEL"] + 1,
			);
		}
		else
		{
			//We are only one/leftmost section in the iblock.
			$arUpdate = array(
				"LEFT_MARGIN" => 1,
				"RIGHT_MARGIN" => 2,
				"GLOBAL_ACTIVE" => $arFields["ACTIVE"] != "N" ? "Y" : "N",
				"DEPTH_LEVEL" => 1,
			);
		}
	}

	$DB->Query("
		UPDATE b_iblock_section SET
			TIMESTAMP_X=".($DB->type == "ORACLE" ? "NULL" : "TIMESTAMP_X")."
			,LEFT_MARGIN = ".$arUpdate["LEFT_MARGIN"]."
			,RIGHT_MARGIN = ".$arUpdate["RIGHT_MARGIN"]."
			,DEPTH_LEVEL = ".$arUpdate["DEPTH_LEVEL"]."
			,GLOBAL_ACTIVE = '".$arUpdate["GLOBAL_ACTIVE"]."'
		WHERE
			ID = ".$ID."
	");

	$DB->Query("
		UPDATE b_iblock_section SET
			TIMESTAMP_X=".($DB->type == "ORACLE" ? "NULL" : "TIMESTAMP_X")."
			,LEFT_MARGIN = LEFT_MARGIN + 2
			,RIGHT_MARGIN = RIGHT_MARGIN + 2
		WHERE
			IBLOCK_ID = ".$IBLOCK_ID."
			AND LEFT_MARGIN >= ".$arUpdate["LEFT_MARGIN"]."
			AND ID <> ".$ID."
	");

	if ($arParent)
	{
		$DB->Query("
			UPDATE b_iblock_section SET
				TIMESTAMP_X=".($DB->type == "ORACLE" ? "NULL" : "TIMESTAMP_X")."
				,RIGHT_MARGIN = RIGHT_MARGIN + 2
			WHERE
				IBLOCK_ID = ".$IBLOCK_ID."
				AND LEFT_MARGIN <= ".$arParent["LEFT_MARGIN"]."
				AND RIGHT_MARGIN >= ".$arParent["RIGHT_MARGIN"]."
		");
	}
}