• Модуль: sale
  • Путь к файлу: ~/bitrix/modules/sale/lib/location/tree.php
  • Класс: BitrixSaleLocationis
  • Вызов: is::moveSubtree
static function moveSubtree($primary, $primaryDst)
{
	$node = self::getNodeInfo($primary);

	if(!($primaryDst = intval($primaryDst))) // move to root
	{
		$rm = self::getMaxMargin();

		$lDst = $rm + 1;
		$rDst = $rm + 2;
		$dDst = 0;
	}
	else
	{
		$nodeDst = self::getNodeInfo($primaryDst);

		$lDst = intval($nodeDst['LEFT_MARGIN']);
		$rDst = intval($nodeDst['RIGHT_MARGIN']);
		$dDst = intval($nodeDst['DEPTH_LEVEL']);
	}

	$lSub = intval($node['LEFT_MARGIN']);
	$rSub = intval($node['RIGHT_MARGIN']);
	$dSub = intval($node['DEPTH_LEVEL']);

	$tableName = static::getTableName();

	$sql = 	"update ".$tableName." set 

			DEPTH_LEVEL	= 
				case 
					when 
						LEFT_MARGIN between {$lSub} and {$rSub} 
					then 
						DEPTH_LEVEL + ".($dDst - $dSub + 1)."

					else 
						DEPTH_LEVEL 

				end, ";

	// DO NOT switch the column update order in the code below, it WILL NOT work correctly

	// subtree moves upwards along it`s path
	if ($lDst < $lSub && $rDst > $rSub && $dDst < ($dSub - 1))
	{
		$sql .= "

				RIGHT_MARGIN = 
					case 
						when
							RIGHT_MARGIN between ".($rSub + 1)." and ".($rDst - 1)."
						then
							RIGHT_MARGIN - ".($rSub - $lSub + 1)."

						when 
							LEFT_MARGIN between ".$lSub." and ".$rSub."
						then 
							RIGHT_MARGIN + ".((($rDst - $rSub - $dSub + $dDst) / 2) * 2 + $dSub - $dDst - 1)."

						else RIGHT_MARGIN
					end,

				LEFT_MARGIN =
					case 
						when 
							LEFT_MARGIN between ".($rSub + 1)." and ".($rDst - 1)." 
						then 
							LEFT_MARGIN - ".($rSub - $lSub + 1)." 

						when 
							LEFT_MARGIN between ".$lSub." and ".$rSub."
						then 
							LEFT_MARGIN + ".((($rDst - $rSub - $dSub + $dDst) / 2) * 2 + $dSub - $dDst - 1)."

						else 
							LEFT_MARGIN 
					end

				where LEFT_MARGIN between ".($lDst + 1)." and ".($rDst - 1);
	}
	elseif($lDst < $lSub) // subtree moves to the left of it`s path (to the left branch)
	{
		$sql .= "

				LEFT_MARGIN	= 
					case 
						when 
							LEFT_MARGIN between ".$rDst." and ".($lSub-1)."
						then 
							LEFT_MARGIN + ".($rSub - $lSub + 1)."

						when 
							LEFT_MARGIN between ".$lSub." and ".$rSub." 
						then 
							LEFT_MARGIN - ".($lSub - $rDst)."

						else 
							LEFT_MARGIN 
					end, 

				RIGHT_MARGIN = 
					case 
						when 
							RIGHT_MARGIN between ".$rDst." and ".$lSub." 
						then
							RIGHT_MARGIN + ".($rSub - $lSub + 1)."

						when
							RIGHT_MARGIN between ".$lSub." and ".$rSub."
						then
							RIGHT_MARGIN - ".($lSub - $rDst)." 

						else 
							RIGHT_MARGIN
					end 

				where LEFT_MARGIN between ".$lDst." and ".$rSub." or RIGHT_MARGIN between ".$lDst." and ".$rSub;
	}
	else // subtree moves to the right of it`s path (to the right branch)
	{
		$sql .= "

				LEFT_MARGIN	=
					case 
						when 
							LEFT_MARGIN between ".$rSub." and ".$rDst." 
						then 
							LEFT_MARGIN - ".($rSub - $lSub + 1)."

						when 
							LEFT_MARGIN between ".$lSub." and ".$rSub."
						then 
							LEFT_MARGIN + ".($rDst - $rSub - 1)." 
						
						else 
							LEFT_MARGIN 
					end, 

				RIGHT_MARGIN = 
					case 
						when 
							RIGHT_MARGIN between ".($rSub + 1)." and ".($rDst - 1)."
						then RIGHT_MARGIN - ".($rSub - $lSub + 1)."

						when 
							RIGHT_MARGIN between ".$lSub." and ".$rSub."
						then RIGHT_MARGIN + ".($rDst - $rSub - 1)." 

						else RIGHT_MARGIN
				end 

			where LEFT_MARGIN between ".$lSub." and ".$rDst." or RIGHT_MARGIN between ".$lSub." and ".$rDst;
	}

	MainHttpApplication::getConnection()->query($sql);
}