easydot / nested-categories
v1.0.0
2023-01-06 12:47 UTC
Requires
- easydot/batch-update: 1.0.0
Requires (Dev)
- phpunit/phpunit: ^9.5
README
从 denis-kisel/nested-categories 分支复制
此库提供优化常用分类功能的工具,例如: 分类树
、导航路径
、子分类项
通过一个 SQL 查询实现
支持
mysql5.7.22+
laravel
php8.0+
安装包
通过 composer 安装
composer require easydot/nested-categories
安装或升级分类表
如果您还没有分类表,请安装它
# Created table 'categories'
php artisan nested-category:install
#Or specify table name
php artisan nested-category:install --table-name=categories
如果您已经有了分类表,只需升级它
假设您的表有以下字段:id
、parent_id
#Specify model to upgrade
php artisan nested-category:upgrade App\\Models\\Category
配置
将特质 NestableCategory
添加到分类模型中
use Easydot\NestedCategory\NestableCategory; class Category extends Model { use NestableCategory; .... }
添加 path
到可填充字段或设置为受保护字段
class Category extends Model { .... protected $fillable = ['path']; .... } #OR class Category extends Model { .... protected $guarded = []; .... }
[可选]
将特质 AutoRebuildNested
添加到分类模型,以便在事件 created
、updated
、deleted
后自动重建分类结构。但是,它在批量操作后不会自动重建(请参阅 重建结构)。
后台使用一个查询重建整个表
use Easydot\NestedCategory\NestableCategory; use Easydot\NestedCategory\AutoRebuildNested; class Category extends Model { use NestableCategory, AutoRebuildNested; .... } #The same $category->save(); $category->rebuild(); $category->update(); $category->rebuild(); $category->delete(); $category->rebuild();
用法
树形数组
$result = Category::asArrayTree(); dump($result) //Output: [ 'id' => 1, 'parent_id' => NULL, 'name' => 'Parent', 'children' => [ [ 'id' => 2, 'parent_id' => 1, 'name' => 'Child1', 'children' => [] ], [ 'id' => 3, 'parent_id' => 1, 'name' => 'Child2', 'children' => [] ] ] ] # Specify needed fields $result = Category::asArrayTree(fields: ['name', 'order']); dump($result) //Output: [ 'name' => 'Parent', 'order' => 0, 'children' => [ [ 'name' => 'Child1', 'order' => 0, 'children' => [] ], [ 'name' => 'Child2', 'order' => 1, 'children' => [] ] ] ] # Specify cache time(minutes or DateTimeInterface) $result = Category::asArrayTree(cacheTTL: 10); //Cached data $result = Category::asArrayTree(cacheTTL: 10); //Data from previous cache $result = Category::asArrayTree(); //Data without cache # Get array of objects $result = Category::asArrayTree(associative: false); dump($result) //Output: [ { name: 'Parent', order: 0, children: [{...}] }, .... ]
导航路径
后端使用一个 SQL 查询处理 N 个嵌套分类
$category = Category::find(2) dump($category->breadcrumbs()); //Output Collection { array:2 [ Category {id: 1, ...}, Category {id: 2, ...}, ] }
叶/子分类项(嵌套产品、帖子、播客等)
输入表:categories
(id, parent_id, name), products
(id, category_id, name).
后端使用一个 SQL 查询处理嵌套叶
ParentCategory(id: 1)
│ Product_1
│ Product_2
│
└───ChildCategory_1(id: 2)
│ │ Product_3
│ │ Product_4
│ │
│ └───ChildCategory_1_1(id: 3)
│ │ Product_5
│ │ Product_6
│
└───ChildCategory_2(id: 4)
│ Product_7
│ Product_8
#GetAllProducts
$products = Category::find(1)->leafs(App\Models\Product::class)->get();
dump($products->count());
//Output: 8
#In Models\Category .... public nestedProducts() :Builder { return $this->leafs(Product::class) } public nestedPosts() :Builder { return $this->leafs(Post::class) } .... #Client Code $products = Category::find(1)->nestedProducts()->where('name', 'like', '%some%')->get(); $products = Category::first()->nestedPosts()->count();
重建结构
在批量 CRUD 操作后重建分类结构后,需要使用 rebuild
方法。或者您可以在单一操作后使用特质 AutoRebuildNested
(请参阅 配置)。
后台使用一个查询重建整个表
# Inserts Category::insert([ ['id' => 1, 'parent_id' => null], ['id' => 2, 'parent_id' => 1], ['id' => 3, 'parent_id' => 2], ..... ]) Category::rebuild(); # Delete Category::where('is_active', false)->delete(); Category::rebuild();
附加命令
# Rebuild specify category
php artisan nested-category:rebuild App\\Models\\Category
测试
cd vendor/easydot/nested-categories
vendor/bin/phpunit test