• Модуль: tasks
  • Путь к файлу: ~/bitrix/modules/tasks/lib/internals/database/tree.php
  • Класс: BitrixTasksInternalsDataBaseis
  • Вызов: is::moveLink
static function moveLink($id, $parentId, $behaviour = array('CREATE_PARENT_NODE_ON_NOTFOUND' => true))
{
	$id = 				Assert::expectIntegerPositive($id, '$id');
	$parentId = 		Assert::expectIntegerNonNegative($parentId, '$parentId'); // 0 allowed - means "detach into a separate branch"
	if(!is_array($behaviour))
		$behaviour = array();
	if(!isset($behaviour['CREATE_PARENT_NODE_ON_NOTFOUND']))
		$behaviour['CREATE_PARENT_NODE_ON_NOTFOUND'] = true;

	$parentColName = 	static::getPARENTIDColumnName();
	$idColName = 		static::getIDColumnName();

	if(!static::checkNodeExists($id))
	{
		throw new TreeTargetNodeNotFoundException(false, array('NODES' => array($id, $parentId)));
	}

	$dbConnection = MainHttpApplication::getConnection();

	if($parentId > 0)
	{
		if(!static::checkNodeExists($parentId))
		{
			if($behaviour['CREATE_PARENT_NODE_ON_NOTFOUND'])
			{
				if(!static::add(array($parentColName => $parentId, $idColName => $parentId))->isSuccess())
				{
					throw new TreeException('Can not create node', array('NODES' => array($parentId)));
				}
			}
			else
			{
				throw new TreeParentNodeNotFoundException(false, array('NODES' => array($parentId)));
			}
		}

		if(static::checkLinkExists($id, $parentId))
		{
			throw new TreeLinkExistsException(false, array('NODES' => array($id, $parentId)));
		}

		$check = $dbConnection->query("select ".$idColName." from ".static::getTableName()." where ".$parentColName." = '".intval($id)."' and ".$idColName." = '".intval($parentId)."'")->fetch();
		if(is_array($check))
		{
			throw new MainArgumentException('Can not move tree inside itself');
		}
	}

	// TODO: rewrite this using deleteLink() and createLink()

	// detach subtree
	$dbConnection->query("delete 
		from ".static::getTableName()." 
		where 
			".$idColName." in (
				".Helper::getTemporaryTableSubQuerySql(static::getSubTreeSql($id), $idColName)."
			) 
			and
			".$parentColName." in (
				".Helper::getTemporaryTableSubQuerySql(static::getPathToNodeSql($id), $parentColName)."
			)
			and 
			".$idColName." != ".$parentColName./*exclude links to selves*/"
			and
			".$parentColName." != '".intval($id)./*exclude link to root node of a tree being detached*/"'
	");

	if($parentId > 0)
	{
		// reattach subtree to other path
		$res = static::getPathToNode($parentId, array('select' => array('ID' => $parentColName)));
		while($item = $res->fetch())
		{
			$dbConnection->query(
				"insert into ".static::getTableName()." 
					
					(".$parentColName.", ".$idColName.", ".static::getDIRECTColumnName().") 
					
					select 
						'".$item['ID']."',
						T.".$idColName.",

						".(
							$item['ID'] == $parentId
							?
							"
							CASE 
								WHEN 
									T.".$idColName." = '".$id."'
								THEN
									'1'
								ELSE
									'0'
							END
							"
							:
							"'0'"
						)."
					from 
						".static::getTableName()." T 
					where 
						".$parentColName." = '".intval($id)."'"
			);
		}
	}

	return array('RESULT' => true);
}