easydot/nested-categories

v1.0.0 2023-01-06 12:47 UTC

This package is auto-updated.

Last update: 2024-09-12 01:45:17 UTC


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

如果您已经有了分类表,只需升级它
假设您的表有以下字段:idparent_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 添加到分类模型,以便在事件 createdupdateddeleted 后自动重建分类结构。但是,它在批量操作后不会自动重建(请参阅 重建结构)。

后台使用一个查询重建整个表

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