nook-ru / nstree
允许通过Bitrix ORM API操作Nested Set树
0.1.1
2017-06-26 07:58 UTC
Requires
- php: >=5.3.0
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"); }