alibayat / laravel-categorizable
为 Eloquent 模型实现嵌套结构层次分类系统。
Requires
- php: ^8.0|^8.1|^8.2
- illuminate/database: ^8.40.0|^9.0
- illuminate/support: ^8.40.0|^9.0
- kalnoy/nestedset: ^6.0
- spatie/laravel-sluggable: ^2.2|^3.3
Requires (Dev)
- orchestra/testbench: ^7.0
- phpunit/phpunit: ^9.5
This package is auto-updated.
Last update: 2024-09-29 06:28:23 UTC
README
本包实现了嵌套集合层次结构,使您能够以多态方式对 Eloquent 模型进行分类。只需在模型中使用该特性,即可完成。还有一个 Category
模型,您可以直接使用它或在其选择的模型中扩展它。
要求
- PHP 8+
- Laravel 8+
安装
composer require alibayat/laravel-categorizable
发布并运行迁移
php artisan vendor:publish --provider="AliBayat\LaravelCategorizable\CategorizableServiceProvider"
php artisan migrate
Laravel Categorizable 包将被 Laravel 自动发现。如果没有,请手动在 config/app.php 提供者数组中注册该包。
'providers' => [ ... \AliBayat\LaravelCategorizable\CategorizableServiceProvider::class, ],
设置模型 - 只需在模型中使用特性。
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use AliBayat\LaravelCategorizable\Categorizable; class Post extends Model { use Categorizable; }
用法
首先我们需要创建一些分类来使用。此包依赖于另一个名为 laravel-nestedset 的包,该包负责创建、更新、删除和检索单个或嵌套结构的分类。在这里,我将演示如何创建分类并将一个分类作为另一个分类的子分类。但您也可以查看测试或参考包的仓库以获取完整文档。 https://github.com/lazychaser/laravel-nestedset
use App\Models\Post; use AliBayat\LaravelCategorizable\Category; // first we create a bunch of categories // create categories $backEnd = Category::create(['name' => 'Back End']); $frontEnd = Category::create(['name' => 'Front End']); $php = Category::create(['name' => 'PHP']); // assign "PHP" as a child of "Back End" category $backEnd->appendNode($php); // assuming that we have a post instance $post = Post::first();
多级分类结构
有时您可能希望为不同的模型有不同的分类结构。在这种情况下,您也可以在创建分类时传递一个 type
参数。默认情况下,类型设置为 default
。在具有类型的情况下,您还可以利用 Eloquent 模型作用域轻松过滤分类。
在创建新分类时创建树
还可以将嵌套结构作为 children
属性传递给 create 方法
$categoryWithChildAndGrandchild = Category::create([ 'name' => 'Foo', 'children' => [ [ 'name' => 'Bar', 'children' => [ [ 'name' => 'Baz' ], ], ], ], ]);
将文章附加到分类
$post->attachCategory($php);
将文章从分类中分离
$post->detachCategory($php);
将文章附加到分类列表
$post->syncCategories([ $php, $backEnd ]);
将文章从所有分类中分离
$post->syncCategories([]);
同步附加到文章的分类
$post->syncCategories([$frontEnd]);
检查文章是否附加到指定的分类(布尔值)
// single use case $post->hasCategory($php); // multiple use case $post->hasCategory([ $php, $backEnd ]);
附加到文章的分类列表(数组 [1 => 'BackEnd'])
$post->categoriesList();
附加到文章的分类 ID 列表(数组 [1, 2, 3])
$post->categoriesIds();
获取附加到给定分类的所有文章(MorphToMany)
$categoryPosts = Category::find(1)->entries(Post::class);
获取附加到给定分类及其子分类的所有文章(Builder)
$categoryAndDescendantsPosts = Category::find(1)->allEntries(Post::class);
方法
在基础 Category
模型(或任何扩展此类的其他模型)上,您将能够访问各种方法
$result = Category::ancestorsOf($id); $result = Category::ancestorsAndSelf($id); $result = Category::descendantsOf($id); $result = Category::descendantsAndSelf($id); $result = Category::whereDescendantOf($node)->get(); $result = Category::whereNotDescendantOf($node)->get(); $result = Category::orWhereDescendantOf($node)->get(); $result = Category::orWhereNotDescendantOf($node)->get(); $result = Category::whereDescendantAndSelf($id)->get(); $result = Category::whereDescendantOrSelf($node)->get(); $result = Category::whereAncestorOf($node)->get(); $result = Category::whereAncestorOrSelf($id)->get(); $siblings = Category::find($id)->getSiblings(); $nextSibling = Category::find($id)->getNextSibling(); $nextSiblings = Category::find($id)->getNextSiblings(); $prevSibling = Category::find($id)->getPrevSibling(); $prevSiblings = Category::find($id)->getPrevSiblings(); $withDepth = Category::withDepth()->find($id); $withSpecificDepth = Category::withDepth()->having('depth', '=', 1)->get(); $tree = Category::get()->toTree(); $flatTree = Category::get()->toFlatTree(); $bool = Category::isBroken(); $data = Category::countErrors(); Category::fixTree();
这些方法的完整文档可在 laravel-nestedset
包的 README 中找到。
关系
categories() 关系
$postWithCategories = Post::with('categories')->get();
parent 关系
$categoryWithParent = Category::with('parent')->find(1);
children 关系
$categoryWithChildren = Category::with('children')->find(1);
ancestors 关系
$categoryWithAncestors = Category::with('ancestors')->find(1);
descendants 关系
$categoryWithDescendants = Category::with('descendants')->find(1);
测试
本包包含单元测试和功能测试(共 47 个测试,169 个断言),以确保提供的功能按预期工作。您可以通过以下 composer 命令运行测试
composer test