本文經(jīng)授權(quán)轉(zhuǎn)自 PHPHub 社區(qū)
功能說明
使用最簡便的方式智润,為你的數(shù)據(jù)模型提供強(qiáng)大「打標(biāo)簽」功能心包。
:gift: 項(xiàng)目地址:https://github.com/summerblue/laravel-taggable
本項(xiàng)目修改于 rtconner/laravel-tagging 項(xiàng)目跪腹,增加了一下功能:
- 標(biāo)簽名唯一畏梆;
- 增加 etrepat/baum 依賴闸婴,讓標(biāo)簽支持無限級(jí)別標(biāo)簽嵌套坏挠;
- 中文 slug 拼音自動(dòng)生成支持,感謝超哥的 overtrue/pinyin邪乍;
- 提供完整的測試用例降狠,保證代碼質(zhì)量。
注意: 本項(xiàng)目只支持 5.1 LTS
:heart: 此項(xiàng)目由 The EST Group 團(tuán)隊(duì)的 @Summer 維護(hù)庇楞。
無限級(jí)別標(biāo)簽嵌套
集成 etrepat/baum 讓標(biāo)簽具備從屬關(guān)系榜配。
$root = Tag::create(['name' => 'Root']);
// 創(chuàng)建子標(biāo)簽
$child1 = $root->children()->create(['name' => 'Child1']);
$child = Tag::create(['name' => 'Child2']);
$child->makeChildOf($root);
// 批量構(gòu)建樹
$tagTree = [
'name' => 'RootTag',
'children' => [
['name' => 'L1Child1',
'children' => [
['name' => 'L2Child1'],
['name' => 'L2Child1'],
['name' => 'L2Child1'],
]
],
['name' => 'L1Child2'],
['name' => 'L1Child3'],
]
];
Tag::buildTree($tagTree);
更多關(guān)聯(lián)操作請查看:etrepat/baum 。
標(biāo)簽名稱規(guī)則說明
- 標(biāo)簽名里的特殊符號(hào)和空格會(huì)被
-
替代吕晌; - 智能標(biāo)簽 slug 生成蛋褥,會(huì)生成 name 對(duì)應(yīng)的中文拼音 slug ,如:
標(biāo)簽
->biao-qian
睛驳,拼音一樣的時(shí)候會(huì)被加上隨機(jī)值烙心;
標(biāo)簽名清理使用:
$normalize_string = EstGroupe\Taggable\Util::tagName($name)
。
Tag::create(['標(biāo)簽名']);
// name: 標(biāo)簽名
// slug: biao-qian-ming
Tag::create(['表簽名']);
// name: 表簽名
// slug: biao-qian-ming-3243 (后面 3243 為隨機(jī)乏沸,解決拼音沖突)
Tag::create(['標(biāo)簽 名']);
// name: 標(biāo)簽-名
// slug: biao-qian-ming
Tag::create(['標(biāo)簽!名']);
// name: 標(biāo)簽-名
// slug: biao-qian-ming
安裝說明:
安裝
composer require estgroupe/laravel-taggable "5.1.*"
安裝和執(zhí)行遷移
在 config/app.php
的 providers
數(shù)組中加入:
'providers' => array(
\EstGroupe\Taggable\Providers\TaggingServiceProvider::class,
);
php artisan vendor:publish --provider="EstGroupe\Taggable\Providers\TaggingServiceProvider"
php artisan migrate
請仔細(xì)閱讀
config/tagging.php
文件淫茵。
創(chuàng)建 Tag.php
不是必須的,不過建議你創(chuàng)建自己項(xiàng)目專屬的 Tag.php 文件蹬跃。
<?php namespace App\Models;
use EstGroupe\Taggable\Model\Tag as TaggableTag;
class Tag extends TaggableTag
{
// Model code go here
}
修改 config/tagging.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;
}
「標(biāo)簽狀態(tài)」標(biāo)示
Taggable
能跟蹤模型是否打過標(biāo)簽的狀態(tài):
// `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/tagging.php
文件中:
'is_tagged_label_enable' => true,
然后在你的模型的數(shù)據(jù)庫創(chuàng)建腳本里加上:
<?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();
});
}
}
「推薦標(biāo)簽」標(biāo)示
方便你實(shí)現(xiàn)「推薦標(biāo)簽」功能匙瘪,只需要把 suggest
字段標(biāo)示為 true
:
$tag = EstGroupe\Taggable\Model\Tag::where('slug', '=', 'blog')->first();
$tag->suggest = true;
$tag->save();
即可以用以下方法讀取:
$suggestedTags = EstGroupe\Taggable\Model\Tag::suggested()->get();
重寫 Util 類?
大部分的通用操作都發(fā)生在 Util 類,你想獲取更多的定制權(quán)力丹喻,請創(chuàng)建自己的 Util 類薄货,并注冊服務(wù)提供者:
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
必須實(shí)現(xiàn)EstGroupe\Taggable\Contracts\TaggingUtility
接口。
使用范例
$article = Article::with('tags')->first(); // eager load
// 獲取所有標(biāo)簽
foreach($article->tags as $tag) {
echo $tag->name . ' with url slug of ' . $tag->slug;
}
// 打標(biāo)簽
$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
// 批量通過 tag ids 打標(biāo)簽
$article->tagWithTagIds([1,2,3]);
// 去掉標(biāo)簽
$article->untag('Cooking'); // remove Cooking tag
$article->untag(); // remove all tags
// 重打標(biāo)簽
$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)
// 獲取綁定的標(biāo)簽名稱數(shù)組
$article->tagNames(); // get array of related tag names
// 獲取打了「任意」標(biāo)簽的 Article 對(duì)象
Article::withAnyTag('Gardening, Cooking')->get(); // fetch articles with any tag listed
Article::withAnyTag(['Gardening','Cooking'])->get(); // different syntax, same result as above
Article::withAnyTag('Gardening','Cooking')->get(); // different syntax, same result as above
// 獲取打了「全包含」標(biāo)簽的 Article 對(duì)象
Article::withAllTags('Gardening, Cooking')->get(); // only fetch articles with all the tags
Article::withAllTags(['Gardening', 'Cooking'])->get();
Article::withAllTags('Gardening', 'Cooking')->get();
EstGroupe\Taggable\Model\Tag::where('count', '>', 2)->get(); // return all tags used more than twice
Article::existingTags(); // return collection of all existing tags on any articles
如果你 創(chuàng)建了 Tag.php驻啤,即可使用以下標(biāo)簽讀取功能:
// 通過 slug 獲取標(biāo)簽
Tag::byTagSlug('biao-qian-ming')->first();
// 通過名字獲取標(biāo)簽
Tag::byTagName('標(biāo)簽名')->first();
// 通過名字?jǐn)?shù)組獲取標(biāo)簽數(shù)組
Tag::byTagNames(['標(biāo)簽名', '標(biāo)簽2', '標(biāo)簽3'])->first();
// 通過 Tag ids 數(shù)組獲取標(biāo)簽數(shù)組
Tag::byTagIds([1,2菲驴,3])->first();
// 通過名字?jǐn)?shù)組獲取 ID 數(shù)組
$ids = Tag::idsByNames(['標(biāo)簽名', '標(biāo)簽2', '標(biāo)簽3'])->all();
// [1,2,3]
標(biāo)簽事件
Taggable
trait 提供以下兩個(gè)事件:
EstGroupe\Taggable\Events\TagAdded;
EstGroupe\Taggable\Events\TagRemoved;
監(jiān)聽標(biāo)簽事件:
\Event::listen(EstGroupe\Taggable\Events\TagAdded::class, function($article){
\Log::debug($article->title . ' was tagged');
});
單元測試
基本用例測試請見: tests/CommonUsageTest.php
。
運(yùn)行測試:
composer install
vendor/bin/phpunit --verbose
Thanks
- Special Thanks to: Robert Conner - http://smartersoftware.net
- overtrue/pinyin
- etrepat/baum
- Made with love by The EST Group - http://estgroupe.com/