zgldh/laravel-taggable

基于 summerblue/laravel-taggable 进行扩展,以满足 Laravel 5.4 的需求。

5.3.0 2017-06-18 10:26 UTC

This package is auto-updated.

Last update: 2024-08-29 04:31:22 UTC


README

介绍

使用 Taggable Trait 为 Laravel Eloquent 模型提供标签支持。

本项目扩展了 rtconner/laravel-tagging,特别为中文用户添加以下功能

  • 标签名称唯一,并使用 tag_id 进行数据查询。
  • 添加对 etrepat/baum 的支持,以处理复杂的标签树;
  • 使用 overtrue/pinyin 支持中文拼音缩略名;
  • 全面的测试覆盖率。

注意:本项目仅测试并旨在仅支持 5.1 LTS。

❤️ 本项目由 @Summer 维护,他是 The EST Group 的成员。

中文文档和讨论请见这里:https://phphub.org/topics/2123

Baum Nested Sets

集成 etrepat/baum,什么是 Nested Sets?

Nested Sets 是一种智能的方式来实现有序树,它允许进行快速的非递归查询。例如,您可以在单个查询中获取节点的所有后代,无论树有多深。

$root = Tag::create(['name' => 'Root']);

// Create Child Tag
$child1 = $root->children()->create(['name' => 'Child1']);

$child = Tag::create(['name' => 'Child2']);
$child->makeChildOf($root);

// Batch create Tag Tree
$tagTree = [
	'name' => 'RootTag',
	'children' => [
		['name' => 'L1Child1',
			'children' => [
				['name' => 'L2Child1'],
				['name' => 'L2Child1'],
				['name' => 'L2Child1'],
			]
		],
		['name' => 'L1Child2'],
		['name' => 'L1Child3'],
	]
];

Tag::buildTree($tagTree);

请参考官方项目以获取更多高级用法 - etrepat/baum

标签名称规则

  • 任何特殊字符和空格将被替换为 -
  • 自动智能缩略名生成,生成中文拼音缩略名,例如:标签 -> biao-qian,当存在冲突时会添加随机值。

标签名称规范器:$normalize_string = EstGroupe\Taggable\Util::tagName($name)

Tag::create(['标签名']);
// name: 标签名
// slug: biao-qian-ming

Tag::create(['表签名']);
// name: 表签名
// slug: biao-qian-ming-3243 (3243 is random string)

Tag::create(['标签 名']);
// name: 标签-名
// slug: biao-qian-ming

Tag::create(['标签!名']);
// name: 标签-名
// slug: biao-qian-ming

安装:

使用 Composer 安装包

composer require estgroupe/laravel-taggable "5.1.*"

配置和迁移

修改 config/app.php 中的 providers 数组

'providers' => array(
	\EstGroupe\Taggable\Providers\TaggingServiceProvider::class,
);
php artisan vendor:publish --provider="EstGroupe\Taggable\Providers\TaggingServiceProvider"
php artisan migrate

请仔细查看文件:config/taggable.php

创建自己的 Tag.php

这是可选的,但建议使用自己的 Tag 模型

<?php namespace App\Models;

use EstGroupe\Taggable\Model\Tag as TaggableTag;

class Tag extends TaggableTag
{
	// Model code go here
}

修改 config/taggable.php 文件:

	'tag_model'=>'\App\Models\Tag',

添加 Taggable Trait

<?php namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use EstGroupe\Taggable\Taggable;

class Article extends \Illuminate\Database\Eloquent\Model {
	use Taggable;
}

is_tagged 标签

Taggable 可以跟踪模型的 Tagged Status 状态

// `no`
$article->is_tagged

// `yes`
$article->tag('Tag1');
$article->is_tagged;

// `no`
$article->unTag();
$article->is_tagged

// This is fast
$taggedArticles = Article::where('is_tagged', 'yes')->get()

首先修改 config/taggable.php

'is_tagged_label_enable' => true,

is_tagged 字段添加到您模型的迁移文件中

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateArticlesTable extends Migration {

	public function up()
	{
		Schema::create('weibo_statuses', function(Blueprint $table) {
            $table->increments('id');
            ...
			// Add this line
			$table->enum('is_tagged', array('yes', 'no'))->default('no');
			...
            $table->timestamps();
        });
	}
}

建议 标签

如果您想要有“建议”标签并使其突出,则可以使用此小功能。

这很简单。您只需将数据库中的 'suggest' 字段设置为 true 即可。

$tag = EstGroupe\Taggable\Model\Tag::where('slug', '=', 'blog')->first();
$tag->suggest = true;
$tag->save();

然后您可以在需要时获取建议标签列表。

$suggestedTags = EstGroupe\Taggable\Model\Tag::suggested()->get();

重写 Util 类?

如何重写 Util 类?

您需要创建自己的服务提供者。它可能看起来像这样。

namespace My\Project\Providers;

use EstGroupe\Taggable\Providers\TaggingServiceProvider as ServiceProvider;
use EstGroupe\Taggable\Contracts\TaggingUtility;

class TaggingServiceProvider extends ServiceProvider {

	/**
	 * Register the service provider.
	 *
	 * @return void
	 */
	public function register()
	{
		$this->app->singleton(TaggingUtility::class, function () {
			return new MyNewUtilClass;
		});
	}

}

注意:其中 MyNewUtilClass 是您编写的类。您的新 Util 类显然需要实现 EstGroupe\Taggable\Contracts\TaggingUtility 接口。

使用

$article = Article::with('tags')->first(); // eager load

// Get all the article tagged tags
foreach($article->tags as $tag) {
	echo $tag->name . ' with url slug of ' . $tag->slug;
}

// Tag some tag/tags
$article->tag('Gardening'); // attach the tag
$article->tag('Gardening, Floral'); // attach the tag
$article->tag(['Gardening', 'Floral']); // attach the tag
$article->tag('Gardening', 'Floral'); // attach the tag

// Using tag_id batch tag
$article->tagWithTagIds([1,2,3]);

// Remove tags
$article->untag('Cooking');  // remove Cooking tag
$article->untag(); 				// remove all tags

// Retag
$article->retag(['Fruit', 'Fish']); // delete current tags and save new tags
$article->retag('Fruit', 'Fish');
$article->retag('Fruit, Fish');

$tagged = $article->tagged; // return Collection of rows tagged to article
$tags = $article->tags; // return Collection the actual tags (is slower than using tagged)

// Get array of related tag names
$article->tagNames();

// Fetch articles with any tag listed
Article::withAnyTag('Gardening, Cooking')->get();
Article::withAnyTag(['Gardening','Cooking'])->get(); // different syntax, same result as above
Article::withAnyTag('Gardening','Cooking')->get(); // different syntax, same result as above

// Only fetch articles with all the tags
Article::withAllTags('Gardening, Cooking')->get();
Article::withAllTags(['Gardening', 'Cooking'])->get();
Article::withAllTags('Gardening', 'Cooking')->get();

// Return all tags used more than twice
EstGroupe\Taggable\Model\Tag::where('count', '>', 2)->get();

// Return collection of all existing tags on any articles
Article::existingTags();

EstGroupe\Taggable\Model\Tag 具有以下功能

// By tag slug
Tag::byTagSlug('biao-qian-ming')->first();

// By tag name
Tag::byTagName('tag1')->first();

// Using names
Tag::byTagNames(['tag1', 'tag12', 'tag13'])->first();

// Using Tag ids array
Tag::byTagIds([1,23])->first();

// Using name to get tag ids array
$ids = Tag::idsByNames(['标签名', '标签2', '标签3'])->all();
// [1,2,3]

标签事件

Taggable trait 提供两个事件

EstGroupe\Taggable\Events\TagAdded;

EstGroupe\Taggable\Events\TagRemoved;

您可以根据需要监听它:

\Event::listen(EstGroupe\Taggable\Events\TagAdded::class, function($article){
	\Log::debug($article->title . ' was tagged');
});

单元测试

常用的用法在 tests/CommonUsageTest.php 文件中进行测试。

运行测试

composer install
vendor/bin/phpunit --verbose

感谢