ClosureTable
分支
- L4 支持Laravel 4
 - L5.1 支持Laravel< 5.2
 - L5.3 支持Laravel 5.2-5.3
 - L5.4 支持Laravel 5.4
 - master 适用于任何实际的Laravel版本,因此请小心
 
嗨,这是Laravel的数据库包。它旨在用于需要在数据库中操作分层数据的情况。该包是一个名为Closure Table的着名数据库设计模式的实现。该软件包包括用于模型和迁移的生成器。
安装
要安装软件包,请将以下内容放入composer.json中:
 "require": {
"franzose/closure-table": "4.*"
}
app/config/app.php :
 'providers' => array(
    // ...
    'Franzose\ClosureTable\ClosureTableServiceProvider',
),
设置您的ClosureTable
创建模型和迁移
例如,让我们假设您正在处理页面。您可以使用 artisan 命令自动创建模型和迁移,而无需手动准备所有内容。打开终端并输入以下内容:
php artisan closuretable:make --entity=page
命令的所有选项:
-  --namespace , -ns   [可选] :类的命名空间,由设置 -  entity 和  -  closure 选项,有助于避免这些选项中的名称空间重复
 -  --entity , -e :entity class name;如果使用名称空间名称,那么默认的闭包类名称将以该名称空间
为前缀
	 - --entity-table , -et [可选] :实体表名称
 - --closure , -c [可选] :封闭类名称
 - --closure-table [可选] , -ct :封闭表名称
 -  --models-path , -mdl   [可选] :自定义模型路径
 -  --migrations-path , -mgr   [可选] :自定义迁移路径
 - --use-innodb 和 -i [可选] :创建InnoDB迁移也是可选的。设置这将启用InnoDB引擎。
 
这几乎都是,伙计们! 'dummy'的东西刚刚为你创造。您需要为实体迁移添加一些字段,因为创建的“dummy”仅包含
必填id , parent_id , position 和真实深度列:
-  id  是一个常规的自动增量列
 -  parent_id  列用于简化祖先查询的立即操作,例如简化构建整个树
 -  position  列被封装广泛用于实体可排序
 - 真实深度 列也用于简化查询并减少查询次数
 
默认情况下,实体的闭包表包含以下列:
	
-  Autoincremented identifier 
 - Ancestor column指向父节点
 -  Descendant column指向子节点
 - Depth column在树中显示节点深度
 
它是通过闭合表格模式设计的,所以请记住,您不能删除这四列。
请记住,许多内容都是可自定义的,所以请参阅自定义以获取更多信息。
编码时间
一旦你的模型和数据库表被创建,最后,你可以开始真正的编码。在这里,我将向您展示ClosureTable的具体方法。
直接祖先(父母)
$parent = Page::find(15)->getParent();
祖先
 $page = Page::find(15);
$ancestors = $page->getAncestors();
$ancestors = $page->getAncestorsTree(); // Tree structure
$ancestors = $page->getAncestorsWhere('position', '=', 1);
$hasAncestors = $page->hasAncestors();
$ancestorsNumber = $page->countAncestors();
直系后代(孩子)
 $page = Page::find(15);
$children = $page->getChildren();
$hasChildren = $page->hasChildren();
$childrenNumber = $page->countChildren();
$newChild = new Page(array(
    'title' => 'The title',
    'excerpt' => 'The excerpt',
    'content' => 'The content of a child'
));
$newChild2 = new Page(array(
    'title' => 'The title',
    'excerpt' => 'The excerpt',
    'content' => 'The content of a child'
));
$page->addChild($newChild);
//you can set child position
$page->addChild($newChild, 5);
//you can get the child
$child = $page->addChild($newChild, null, true);
$page->addChildren([$newChild, $newChild2]);
$page->getChildAt(5);
$page->getFirstChild();
$page->getLastChild();
$page->getChildrenRange(0, 2);
$page->removeChild(0);
$page->removeChild(0, true); //force delete
$page->removeChildren(0, 3);
$page->removeChildren(0, 3, true); //force delete
后代
 $page = Page::find(15);
$descendants = $page->getDescendants();
$descendants = $page->getDescendantsWhere('position', '=', 1);
$descendantsTree = $page->getDescendantsTree();
$hasDescendants = $page->hasDescendants();
$descendantsNumber = $page->countDescendants();
邻近
$page = Page::find(15); $first = $page->getFirstSibling(); //or $page->getSiblingAt(0); $last = $page->getLastSibling(); $atpos = $page->getSiblingAt(5); $prevOne = $page->getPrevSibling(); $prevAll = $page->getPrevSiblings(); $hasPrevs = $page->hasPrevSiblings(); $prevsNumber = $page->countPrevSiblings(); $nextOne = $page->getNextSibling(); $nextAll = $page->getNextSiblings(); $hasNext = $page->hasNextSiblings(); $nextNumber = $page->countNextSiblings(); //in both directions $hasSiblings = $page->hasSiblings(); $siblingsNumber = $page->countSiblings(); $sibligns = $page->getSiblingsRange(0, 2); $page->addSibling(new Page); $page->addSibling(new Page, 3); //third position //add and get the sibling $sibling = $page->addSibling(new Page, null, true); $page->addSiblings([new Page, new Page]); $page->addSiblings([new Page, new Page], 5); //insert from fifth position
根(没有祖先的实体)
$roots = Page::getRoots(); $isRoot = Page::find(23)->isRoot(); Page::find(11)->makeRoot(0); //at the moment we always have to set a position when making node a root
整棵树
 $tree = Page::getTree();
$treeByCondition = Page::getTreeWhere('position', '>=', 1);
您处理集合,因此您可以像平常一样控制其项目。 Descendants? 它们已经装好了。
$tree = Page::getTree(); $page = $tree->find(15); $children = $page->getChildren(); $child = $page->getChildAt(3); $grandchildren = $page->getChildAt(3)->getChildren(); //and so on
移动
$page = Page::find(25); $page->moveTo(0, Page::find(14)); $page->moveTo(0, 14);
删除子树
如果出于某种原因不使用外键,则可以手动删除子树。这将删除该页面及其所有后代:
$page = Page::find(34); $page->deleteSubtree(); $page->deleteSubtree(true); //with subtree ancestor $page->deleteSubtree(false, true); //without subtree ancestor and force delete
定制
您可以自定义由ClosureTableartisan 命令创建的类中的默认内容:
- Entity table name:更改受保护的$table 属性。
 - Closure table name:在您的 ClosureTable(例如 PageClosure)中执行相同的操作。
 - Entity's parent_id, position, and real depth column names:分别更改 getParentIdColumn()、getPositionColumn()和getRealDepthColumn()的返回值。
 - Closure table's ancestor, descendant, and depth columns names:分别更改 getAncestorColumn()、getDescendantColumn()和 getDepthColumn() 的返回值。
 


