cuneytyuksel/laravelcategorizable

实现嵌套结构层次分类系统,用于Eloquent模型。

1.0 2023-05-23 22:21 UTC

This package is auto-updated.

Last update: 2024-09-24 01:15:49 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

致谢