Добрый вечер. Пытаюсь перенести ветку NS по этой статье:
www.getinfo.ru/article610.html.Для начала выберем ключи следующих узлов:
1. Ключи и уровень перемещаемого узла;
SELECT level, left_key, right_key FROM my_tree WHERE id = $id
Это я делаю так:
public function move($parentId, $leftSibling = null)
Category::find(195)->move(199);
. где 195 - id перемещаемого узла, 199 - id нового родителя.
2. Уровень нового родительского узла (если узел перемещается в "корень" то сразу можно подставить значение 0):
SELECT level FROM my_tree WHERE id = $id_up
Получаем $level_up
Выбираю родителя целиком:
$parent = self::find($parentId);
3. Правый ключ узла за который мы вставляем узел (ветку):
Делаю это так:
if ($this->parentNode()->id == $parent->id)
{
if ($parent->hasChild())
{
if ($leftSibling === null)
{
throw Exception('Sibling not found');
}
$rightKeyNear = $leftSibling->right_key;
}
else
{
$rightKeyNear = $parent->left_key;
}
}
else
{
if ($parent->level == 0)
{
//перемещение в корень
$rightKeyNear = self::max('right_key')->get();
}
else
{
$rightKeyNear = $parent->right_key - 1;
}
}
4. Определяем смещения:
$level_up - $level + 1 = $skew_level - смещение уровня изменяемого узла;
$right_key - $left_key + 1 = $skew_tree - смещение ключей дерева;
У меня $keySkew вместо $skew_tree:
$levelSkew = $parent->level - $this->level + 1;
$keySkew = $this->right_key - $this->left_key + 1;
Выбираем все узлы перемещаемой ветки:
SELECT id FROM my_tree WHERE left_key >= $left_key AND right_key <= $right_key
Получаем $id_edit - список id номеров перемещаемой ветки.
$childIds = self::where('left_key', '>=', $this->left_key)->where('right_key', '<=', $this->right_key)->lists('id');
Так же требуется определить: в какую область перемещается узел, для этого сравниваем $right_key и $right_key_near, если $right_key_near больше, то узел перемещается в облась вышестоящих узлов, иначе - нижестоящих (почему существует разделение описано ниже).
if ($rightKeyNear > $this->right_key)
{
echo 'up';
$editSkew = $rightKeyNear - $this->left_key + 1;
// UPDATE my_tree SET right_key = right_key + $skew_tree WHERE right_key < $left_key AND right_key > $right_key_near
self::where('right_key', '<', $this->left_key)->where('right_key', '>', $rightKeyNear)->update(array('right_key' => DB::raw('`right_key` + (' . $keySkew . ')')));
// UPDATE my_tree SET left_key = left_key + $skew_tree WHERE left_key < $left_key AND left_key > $right_key_near
self::where('left_key', '<', $this->left_key)->where('left_key', '>', $rightKeyNear)->update(array('left_key' => DB::raw('`left_key` - (' . $keySkew . ')')));
}
else
{
echo 'down';
$editSkew = $rightKeyNear - $this->left_key - $keySkew + 1;
// UPDATE my_tree SET right_key = right_key - $skew_tree WHERE right_key > $right_key AND right_key <= $right_key_near
self::where('right_key', '>', $this->right_key)->where('right_key', '<=', $rightKeyNear)->update(array('right_key' => DB::raw('`right_key` - (' . $keySkew . ')')));
// UPDATE my_tree SET left_key = left_key - $skew_tree WHERE left_key < $left_key AND left_key > $right_key_near
self::where('left_key', '<', $this->left_key)->where('left_key', '>', $rightKeyNear)->update(array('left_key' => DB::raw('`left_key` - (' . $keySkew . ')')));
}
// UPDATE my_tree SET left_key = left_key + $skew_edit, right_key = right_key + $skew_edit, level = level + $skew_level WHERE id IN ($id_edit)
self::whereIn('id', $childIds)->update(array('left_key' => DB::raw('`left_key` + (' . $editSkew . ')'), 'right_key' => DB::raw('`right_key` + (' . $editSkew . ')'), 'level' => DB::raw('`level` + (' . $levelSkew . ')')));
Код целиком:
pastebin.com/t9BJ2tDr
Проблема в том, что ветка почему-то не перемещается. Пожалуйста, укажите на ошибки.