Skip to content
Модуль bitrix для работы с деревьями Nested Set
PHP
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
install
lang/ru
lib
LICENSE
README.md
include.php

README.md

Данная версия модуля является устаревшей.

Классы для работы с иерархическими структурами Nested Sets и Closure Table объединены в новом модуле https://github.com/DimMount/dimmount.treetables

Модуль bars46.nstree

Модуль содержит класс NSDataManager, унаследованный от Bitrix\Main\Entity\DataManager, позволяющий работать с деревьями Nested Set через API ORM Битрикс.

Для работы с деревом необходимо создать класс-наследник от NSDataManager.

Метод getMap() обязательно должен содержать поля:

  • ID - Идентификатор записи, первичный ключ
  • PARENT_ID - Идентификатор родительской записи
  • LEFT_MARGIN - левый ключ
  • RIGHT_MARGIN - правый ключ
  • DEPTH_LEVEL - уровень вложенности
  • SORT - сортировка

Дополнительно поддерживаютя поля:

  • ACTIVE - флаг активности
  • GLOBAL_ACTIVE - флаг активности всего узла, устанавливается автоматически

Примеры

Пример ORM-класса находится в файле lib/nstest.php

Добавление новой записи в корень дерева

Bars46\NSTree\NSTestTable::add(
    array(
        'NAME' => 'ROOT ROW'
    )
);

Добавление записи в существующую ветку

Bars46\NSTree\NSTestTable::add(
    array(
        'PARENT_ID' => $parent_node_id,
        'NAME' => 'CHILD ROW'
    )
);

Перемещение записи или целой ветки в новую ветку

Bars46\NSTree\NSTestTable::update(
    $id,
    array(
        'PARENT_ID' => $new_parent_node_id
    )
);

Получение всего упорядоченного дерева, начиная от корня

$res = Bars46\NSTree\NSTestTable::getList(
    array(
        'select' => array(
            'ID',
            'NAME'
        ),
        'order' => array(
            'LEFT_MARGIN' => 'ASC'
        )
    )
);

Получение только корневых элементов

$res = Bars46\NSTree\NSTestTable::getList(
    array(
        'select' => array(
            'ID',
            'NAME'
        ),
        'filter' => array(
            '=DEPTH_LEVEL' => 1
        ),
        'order' => array(
            'LEFT_MARGIN' => 'ASC'
        )
    )
);

Получение всех потомков конкретной ветки дерева

$node = Bars46\NSTree\NSTestTable::getRow(
    array(
        'select' => array(
            'LEFT_MARGIN',
            'RIGHT_MARGIN'
        ),
        'filter' => array(
            '=ID' => $node_id
        )
    )
);
$res = Bars46\NSTree\NSTestTable::getList(
    array(
        'select' => array(
            'ID',
            'NAME'
        ),
        'filter' => array(
            '>LEFT_MARGIN' => $node['LEFT_MARGIN'],
            '<RIGHT_MARGIN' => $node['RIGHT_MARGIN']
        ),
        'order' => array(
            'LEFT_MARGIN' => 'ASC'
        )
    )
);

Получение всех предков конкретной ветки дерева

$node = Bars46\NSTree\NSTestTable::getRow(
    array(
        'select' => array(
            'LEFT_MARGIN',
            'RIGHT_MARGIN'
        ),
        'filter' => array(
            '=ID' => $node_id
        )
    )
);
$res = Bars46\NSTree\NSTestTable::getList(
    array(
        'select' => array(
            'ID',
            'NAME'
        ),
        'filter' => array(
            '<LEFT_MARGIN' => $node['LEFT_MARGIN'],
            '>RIGHT_MARGIN' => $node['RIGHT_MARGIN']
        ),
        'order' => array(
            'LEFT_MARGIN' => 'ASC'
        )
    )
);

Транзакции

Во избежание разрушения структуры дерева при совместном доступе желательно блокировать таблицу на запись и откатывать изменения при возникновении ошибок. Для этого служат методы lockTable() и unlockTable()

$connection = Bitrix\Main\Application::getConnection();
Bars46\NSTree\NSTestTable::lockTable();
try {
    Bars46\NSTree\NSTestTable::add(
        array(
            'PARENT_ID' => $parent_node_id,
            'NAME' => 'CHILD ROW'
        )
    );
    $connection->commitTransaction();
} catch (\Exception $e) {
    $connection->rollbackTransaction();
    Bars46\NSTree\NSTestTable::unlockTable();
    echo($e->getMessage() . "\n");
}
You can’t perform that action at this time.