• Модуль: tasks
  • Путь к файлу: ~/bitrix/modules/tasks/lib/internals/database/tree.php
  • Класс: BitrixTasksInternalsDataBaseto
  • Вызов: to::createLink
static function createLink($id, $parentId, $behaviour = array('LINK_DATA' => array()))
{
	static::applyCreateRestrictions($id, $parentId);

	if(!is_array($behaviour))
	{
		$behaviour = array();
	}

	// check here if there is a link already

	//_dump_r('Create: '.$parentId.' => '.$id.' ('.$behaviour['LINK_DATA']['TYPE'].')');

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

	// delete broken previous links, if any (but not the link to itself)
	$dbConnection = MainHttpApplication::getConnection();
	$dbConnection->query("delete from ".static::getTableName()." where ".$idColName." = '".intval($id)."' and ".$parentColName." != '".intval($id)."'");

	$success = true;
	$lastAddResult = null;

	if($parentId)
	{
		// check if parent exists. if not - add it
		$item = static::getList(array('filter' => array('='.$parentColName => $parentId, '='.$idColName => $parentId), 'select' => array($idColName)))->fetch();
		if(!is_array($item))
		{
			//_dump_r('link: '.$parentId.' => '.$parentId);
			$lastAddResult = parent::add(array($parentColName => $parentId, $idColName => $parentId));
			if(!$lastAddResult->isSuccess())
			{
				$success = false;
			}
		}
	}

	// check if link to itself exists. if not - add it
	$item = static::getList(array('filter' => array('='.$parentColName => $id, '='.$idColName => $id), 'select' => array($idColName)))->fetch();
	if(!is_array($item))
	{
		//_dump_r('link: '.$id.' => '.$id);
		$lastAddResult = parent::add(array($parentColName => $id, $idColName => $id));
		if(!$lastAddResult->isSuccess())
		{
			$success = false;
		}
	}

	$linkedWithParent = false;

	// TODO: the following part could be rewritten using just db-side insert-select

	if($success && $parentId)
	{
		$subtree = array();
		$res = static::getSubTree($id);
		while($item = $res->fetch())
		{
			$subtree[] = $item[$idColName];
		}

		// link each child (including self) to each parent in the path(es)
		$res = static::getPathToNode($parentId, array('select' => array($parentColName)));
		while($item = $res->fetch())
		{
			foreach($subtree as $itemId)
			{
				if($item[$parentColName] == $parentId && $itemId == $id) // special, direct linking to parent
				{
					if(!is_array($behaviour['LINK_DATA']))
					{
						$behaviour['LINK_DATA'] = array();
					}

					$lastAddResult = parent::add(array_merge(array($idColName => $id, $parentColName => $parentId, static::getDIRECTColumnName() => true), $behaviour['LINK_DATA']));
					if(!$lastAddResult->isSuccess())
					{
						$success = false;
						break;
					}
				}
				else
				{
					$lastAddResult = parent::add(array($idColName => $itemId, $parentColName => $item[$parentColName]));
					if(!$lastAddResult->isSuccess())
					{
						$success = false;
						break;
					}
				}
			}
		}
	}

	return array('RESULT' => $success, 'LAST_DB_RESULT' => $lastAddResult);
}