- Модуль: tasks
- Путь к файлу: ~/bitrix/modules/tasks/lib/checklist/internals/checklisttree.php
- Класс: BitrixTasksCheckListInternalsCheckListTree
- Вызов: CheckListTree::attach
static function attach($id, $parentId = 0, array $parameters = [])
{
$result = static::canAttach($id, $parentId);
$replaces = [
'#ID#' => $id,
'#PARENT_ID#' => $parentId,
];
if ($result->isSuccess())
{
// check if link is already exists
if ($parentId && static::isPathExist($parentId, $id, ['DIRECT' => true]))
{
$result = static::addErrorToResult($result, $replaces, __METHOD__, 'PATH_EXISTS');
return $result;
}
if (static::isNodeExist($id))
{
if ($parameters['NEW_NODE'] ?? null)
{
$result = static::addErrorToResult($result, $replaces, __METHOD__, 'EXISTING_NODE_ADDING');
}
else
{
// we should do detach node from the previous point, if any
$detachResult = static::detach($id);
$result->loadErrors($detachResult->getErrors());
}
}
// if !$parentId, then it behaves like detach()
if ($parentId && $result->isSuccess())
{
$connection = Application::getConnection();
$tableName = static::getTableName();
$parentColumnName = static::getParentNodeColumnName();
$childColumnName = static::getNodeColumnName();
$levelColumnName = static::getLevelColumnName();
// attach to a new point
static::ensureNodeExists($parentId);
static::ensureNodeExists($id);
// now link each item of path to $parentId with each item of subtree of $id
$connection->query("
INSERT INTO {$tableName} (PARENT_ID, CHILD_ID, LEVEL)
SELECT P.{$parentColumnName},
CH.{$childColumnName},
P.{$levelColumnName} + CH.{$levelColumnName} + 1 AS {$levelColumnName}
FROM {$tableName} P
CROSS JOIN (
SELECT {$id} AS {$childColumnName}, 0 AS {$levelColumnName}
UNION
SELECT CH1.{$childColumnName}, CH2.{$levelColumnName} + 1 AS {$levelColumnName}
FROM {$tableName} CH1
LEFT JOIN {$tableName} CH2 ON CH1.{$parentColumnName} = CH2.{$childColumnName}
WHERE CH2.{$parentColumnName} = {$id} AND CH1.{$levelColumnName} = 1
) CH
WHERE P.{$childColumnName} = {$parentId}
");
}
}
return $result;
}