- Модуль: tasks
- Путь к файлу: ~/bitrix/modules/tasks/lib/internals/database/structure/closuretree.php
- Класс: BitrixTasksInternalsDataBaseStructureClosureTree
- Вызов: ClosureTree::attach
static function attach($id, $parentId = 0, array $settings = array())
{
$result = static::canAttach($id, $parentId);
if($result->isSuccess())
{
// check if link is already on its place
if($parentId && static::isPathExist($parentId, $id, array('DIRECT' => true)))
{
$result->addWarning('PATH_EXISTS', Loc::getMessage('TASKS_CLOSURE_TREE_LINK_EXISTS'));
return $result;
}
if(static::isNodeExist($id))
{
if ($settings['NEW_NODE'] ?? null)
{
$result->addError('NODE_EXISTS', Loc::getMessage('TASKS_CLOSURE_TREE_NODE_EXISTS_BUT_DECLARED_NEW'));
}
else
{
// we should do detach node from the previous point, if any
$dResult = static::detach($id);
$result->adoptErrors($dResult);
}
}
// if !$parentId, then it behaves like detachNode()
if($result->isSuccess() && $parentId)
{
// attach to a new point
static::ensureNodeExists($parentId);
static::ensureNodeExists($id);
$pCName = static::getParentNodeColumnName();
$cName = static::getNodeColumnName();
// now link each item of path to $parentId with each item of subtree of $id
// todo: rewrite this IN SQL
$path = static::getPath($parentId, array(), array('RETURN_ARRAY' => true));
$subTree = static::getSubTree($id, array(), array('RETURN_ARRAY' => true));
$edgeBuffer = array();
foreach($path as $pItem)
{
foreach($subTree as $stItem)
{
$edgeBuffer[] = array(
$pCName => $pItem['__ID'],
$cName => $stItem['__ID'],
'DIRECT' => $pItem['__ID'] == $parentId && $stItem['__ID'] == $id ? 1 : 0
);
}
}
try
{
Helper::insertBatch(static::getTableName(), $edgeBuffer);
}
catch(DBSqlException $e)
{
$result->addException($e, 'Error linking nodes');
}
}
}
return $result;
}