nook-ru/nstree

允许通过Bitrix ORM API操作Nested Set树

0.1.1 2017-06-26 07:58 UTC

This package is auto-updated.

Last update: 2024-09-05 15:30:18 UTC


README

包含从Bitrix\Main\Entity\DataManager继承的Citrus\NSTree\DataManager类,允许通过Bitrix ORM API操作Nested Set树。

为了操作树,需要创建一个继承自Citrus\NSTree\DataManager的类。

方法getMap()必须包含以下字段

  • ID - 记录标识符,主键
  • PARENT_ID - 父记录标识符
  • LEFT_MARGIN - 左键
  • RIGHT_MARGIN - 右键
  • DEPTH_LEVEL - 层级深度
  • SORT - 排序

还支持以下字段

  • ACTIVE - 活跃标志
  • GLOBAL_ACTIVE - 整个节点活跃标志,自动设置

示例

ORM类示例位于文件lib/example.php

在树根添加新记录

Citrus\NSTree\ExampleTable::add(
    array(
        'NAME' => 'ROOT ROW'
    )
);

在现有分支添加记录

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

移动记录或整个分支到新分支

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

获取从根开始的所有有序树

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

获取所有根元素

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

获取特定分支的所有后代

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

获取特定分支的所有祖先

$node = Citrus\NSTree\ExampleTable::getRow(
    array(
        'select' => array(
            'LEFT_MARGIN',
            'RIGHT_MARGIN'
        ),
        'filter' => array(
            '=ID' => $node_id
        )
    )
);
$res = Citrus\NSTree\ExampleTable::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();
Citrus\NSTree\ExampleTable::lockTable();
try {
    Citrus\NSTree\ExampleTable::add(
        array(
            'PARENT_ID' => $parent_node_id,
            'NAME' => 'CHILD ROW'
        )
    );
    $connection->commitTransaction();
} catch (\Exception $e) {
    $connection->rollbackTransaction();
    Citrus\NSTree\ExampleTable::unlockTable();
    echo($e->getMessage() . "\n");
}