Tag support for Laravel Eloquent models - Taggable Trait

Overview

Laravel Taggable Trait

Latest Stable Version Total Downloads License Build Status Scrutinizer Code Quality

This package is not meant to handle javascript or html in any way. This package handles database storage and read/writes only.

There are no real limits on what characters can be used in a tag. It uses a slug transform to determine if two tags are identical ("sugar-free" and "Sugar Free" would be treated as the same tag). Tag display names are run through Str::title()

composer require rtconner/laravel-tagging

Install and then Run the migrations

The package should auto-discover when you composer update. Then publish the tagging.php and run the database migrations with these commands.

php artisan vendor:publish --provider="Conner\Tagging\Providers\TaggingServiceProvider"
php artisan migrate

Setup your models

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

Quick Sample Usage

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

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

$article->tag('Gardening'); // attach the tag

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

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

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

Article::withAnyTag(['Gardening','Cooking'])->get(); // fetch articles with any tag listed

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

Article::withoutTags(['Gardening', 'Cooking'])->get(); // only fetch articles without all tags listed

Conner\Tagging\Model\Tag::where('count', '>', 2)->get(); // return all tags used more than twice

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

Documentation: More Usage Examples

Documentation: Tag Groups

Documentation: Tagging Events

Documentation: Tag Suggesting

Configure

See config/tagging.php for configuration options.

Lumen Installation

Documentation: Lumen

Credits

Further Reading

Comments
  • [Help wanted] Care to clarify what would be the correct usage for tag groups?

    [Help wanted] Care to clarify what would be the correct usage for tag groups?

    Hello there!

    I'm really glad to see group support for the package! But I do have some difficulty grasping what would be correct usage for groups.

    Currently, I'm attaching tags to some model in a very straightforward way (in this example, I'm storing an article tags):

    if (!empty($request->tags)) {
                $article->tag(explode(', ', $request->tags));
            }
    

    And I would of course use retag to article update. Now, of I wanted to have different group of tags, let's say for an articles model, and for a news model. I would go on and create the corresponding groups from the artisan command then... What?

    I get that I can easily get the tag in a group (Tag::inGroup('MyTagGroup')->get()) but how should I add a tag to an article, or a news? What is clear is that I should get the tags from the group to suggest to the user, then it would be a no brainer (get the correct tags, send them to the user, then when you save, it's the good ones?), but what if they enter a tag that isn't already created?

    Do I really have to get all the tags in the request (like in the use case earlier), check for all of them if they are in the right group, create manually each tags that aren't, then associate tags? It seems a bit counter intuitive, no?

    Could we see a, for example, tag() method that accepts a single or multiple tags as first parameters, and a group as second, so we would make sure the asked for tags are the one set for the wanted group, and that new ones are created in the right group?

    Or do it already exists? Or am I misunderstanding the wanted usage for groups?

    question 
    opened by jpmurray 17
  • Difficulties when trying to install and use the package

    Difficulties when trying to install and use the package

    Hi Rob (or anybody else listening),

    first: Thanks for the package!

    When I follow the steps in the readme the trait does not seem to work out of the box.

    Issues:

    • After following the readme steps I had to copy the migrations to my migrations folder by hand so the tables are created when calling php artisan migrate (maybe intended to do so but not (yet) in the readme)
    • When adding the trait with use Conner\Tagging\TaggableTrait; I get a PHP Fatal error: Trait 'App\Conner\Tagging\TaggableTrait' not found. I worked around it by changing it to use \Conner\Tagging\TaggableTrait;
    • after the change I get another error when trying to call e.g. $mymodel->addTag('mytag'); in one of my database seeders stating: [BadMethodCallException] Call to undefined method Illuminate\Database\Query\Builder::addTag()

    Now I am stuck. Maybe I do something wrong because I am not very experienced with laravel nor with php. So please excuse any bothering with noob questions ... :-)

    Any help would be great. Also I really would like to use your package to save me some time.

    Environment: fresh laravel 5 project on homestead. My models live in the App namespace as by default laravel 5 installation.

    Regards, Thomas

    opened by thomas-boll 15
  • existingTags() not works

    existingTags() not works

        public static function existingTags() {
            return Tagged::distinct()
                ->join('tagging_tags', 'tag_slug', '=', 'tagging_tags.slug')
                ->where('taggable_type', '=', get_called_class())
                ->orderBy('tag_slug', 'ASC')
                ->get(array('tag_slug as slug', 'tag_name as name', 'tagging_tags.count as count'));
        }
    

    I'm sure
    get_called_class() get value '\App\Models\Article' so can not found any record in database 'taggable_type'='Article'

    bug 
    opened by yinsenf 14
  • Why is

    Why is "rtconner/laravel-tagging" abandoned?

    Updating via composer showed me this message:

    Package rtconner/laravel-tagging is abandoned, you should avoid using it. Use spatie/laravel-tags instead. Is rtconner/laravel-tagging is deprecated or moved?

    opened by b00f 13
  • Tag first letter capital

    Tag first letter capital

    Tag first letter becomes capital even I enter in small letters.

    I want tags save as it is in database. if enter capital than save tag as capital in db. if enter small than save tag as small in db.

    Can you please help me out for this?

    opened by virumandaliya 8
  • [question] Table normalization

    [question] Table normalization

    Hi @rtconner ,

    Out of curiosity, why in your table "tagging_tagged" do you have the fields "tag_name" and "tag_slug" and not just a reference ID (ex.: tag_id) to the tag in the table "tagging_tags"?

    It seems to me that your tables aren't properly normalized because the tags information will be duplicated each time content is tagged.

    enhancement 
    opened by FR6 8
  • $article->tag('Gardening'); not work

    $article->tag('Gardening'); not work

    i find this example but not works. $article->tag('Gardening'); // attach the tag

    after i change it to array it works $article->tag(array('Gardening'));

    in tag() i found this code will remove the string

        if(!is_array($tagNames)) {
            $tagNames = func_get_args();
            array_shift($tagNames);
        }
    
    opened by 41410 8
  • Wrong Migrations. config/tagging.php 'primary_keys_type' => 'integer' doesn't work.

    Wrong Migrations. config/tagging.php 'primary_keys_type' => 'integer' doesn't work.

    I'm installing rtconner/laravel-tagging by composer. And "laravel-tagging/migrations/2014_01_07_073615_create_tagged_table.php" looks different than on github. GitHub version: Schema::create('tagging_tagged', function(Blueprint $table) { $table->increments('id'); if(\Config::get('tagging.primary_keys_type') == 'integer') { $table->integer('taggable_id')->unsigned()->index(); } else { $table->string('taggable_id', 36)->index(); } $table->string('taggable_type', 255)->index(); $table->string('tag_name', 255); $table->string('tag_slug', 255)->index(); });

    Composer version: Schema::create('tagging_tagged', function(Blueprint $table) { $table->increments('id'); $table->string('taggable_id', 36)->index(); $table->string('taggable_type', 255)->index(); //$table->morphs('taggable'); $table->string('tag_name', 255); $table->string('tag_slug', 255)->index(); });

    What should I do? Or what shoud you do? ) I would be very thankful if you helped me.

    opened by pechatny 8
  • Untag question

    Untag question

    Hello,

    I'm using this laravel-tagging for the first time and love it so far! I've noticed that when I use untag (e.g. $post->untag($tag);), it doesn't remove it from the tagging_tagged table. Is it supposed to?

    Thanks!

    opened by chloealee 7
  • Add Auto Tagging from Property

    Add Auto Tagging from Property

    Allow setting a property (eg via a form field) to use as basis of retagging or untagging.

    // with $autoTagFromProp = 'tag_names'
    $model->tag_names = 'foo, bar';
    $model->save();
    

    I do something like this sometimes to be able to add the trait to a model and just add a field to a form to implement tagging. This allows me to just set a property of the model and automatically retag or untag it based on that property when just calling Model::save(), rather than calling retag or untag manually.

    Thoughts? Concerns?

    opened by jakejohns 7
  • WithAllTags is slow.

    WithAllTags is slow.

    I'm using withAllTags() on a database with 10000 rows in a table and 53655 rows in tagging_tagged, paginating the results then passing it to the view for me to loop through. It takes around 10 seconds just to return the videos with the specified tags, is there a way to speed this up?

    enhancement 
    opened by alexsnkr 7
  • Get post by tags issue

    Get post by tags issue

    How can we get post from a tag ? Like we can get post tags like : "$post->tags();". My question is "$tag->posts();" get all post by attached tag.

    Let me know how can I do it !

    opened by Almas-Ali 0
  • TaggingUtility::slug does not support UPPERCASE tags

    TaggingUtility::slug does not support UPPERCASE tags

    First off, THANK YOU, this tagging module is very useful and has been extensively implemented in my projects.

    Couple issues I've found and started working on a branch with fixes but got deep in the weeds and realized a few things that I'll just itimize.

    1. line 75 of TaggingUtility references 'delimiter' => config('taggable.delimiter', '-'), should be 'delimiter' => config('tagging.delimiter', '-'),

    2. Adding support for uppercase tags looks like it was started at line 77 but upon further investigation the relationship model of tagging_tagged and tagging_tags relies on the tag_slug match which could become easily broken if one is manipulated without the other.

    3. I changed lowercase to false but in my database the tagging_tagged->tag_slug remains uppercase but tagging_tags->slug becomes Pascal...

    I will continue to work on this and hopefully provide a PR unless you immediately know how to support retaining tags as uppercase.

    Thanks!!!

    opened by visbits 3
  • Specify tag_group_id at Tag::$fillable

    Specify tag_group_id at Tag::$fillable

    Hello. I like the way this package organized, seems it is the most suitable for my intentions. But I encountered with some problems when tried to use it the way I usually build my applications. Most of my API methods vastly use passing IDs of categories, groups, etc. while creating a new entity.

    I tried to use Tag::create() with specified tag_group_id and found this field is not present at $fillable. I didn't like the idea of passing the group name or slug instead of it's ID. Also didn't like the way of loading TagGroup from DB by specified tag_group_id and after that pass its' name to the Tag->setGroup() (~~I also see setGroup() can load other group with the same slug, but this is not an issue I am talking here~~). For the moment I bypassed the existing logic with this:

        public function store(StoreTagRequest $request)
        {
            $tag = Tag::query()->create($request->validated());
            if ($groupId = $request->input('tag_group_id')) {
                $tag->mergeFillable(['tag_group_id'])->update(['tag_group_id' => $groupId]);
            }
    
            $tag->load('group');
            return $this->sendJsonResponse($tag);
        }
    

    The main question: Is there any reason to protect tag_group_id field from assigning right at update() or create()? Something not obvious like any hidden logic about that I do not see at the moment (for example, when record is updated or something like this)?

    opened by kossmoss 2
  • Multiple database issue

    Multiple database issue

    Thank you for creating this project, it's make the project easier to put tags on my project

    I think i found a bug when inserting tags on multiple database on same codebase, i've put use \Conner\Tagging\Taggable; in every model but the tags are stored in only one database with different taggable_type.

    I've tried to hard coded the $this->connection on \Conner\Tagging\Model\Tag to un-inserted database and it's work, i guess the problem is how to make $this->connection = config('tagging.connection') dynamically based on parent Model but i still can't find the solution for this.

    The expected result are stored in separate database that already specified in protected $connection part in Model.

    I hope this information can improve your project.

    Thank You

    opened by semprul57 0
Releases(4.1.4)
Owner
Rob
Rob
A Single Table Inheritance Trait for Eloquent/Laravel

Single Table Inheritance Credit This code is a fork of Nanigans/single-table-inheritance. I've only updated it to work with Laravel 5 Single Table Inh

Peter Haza 15 Feb 17, 2022
A Single Table Inheritance Trait for Eloquent/Laravel

Single Table Inheritance Single Table Inheritance is a trait for Laravel 5.8+ Eloquent models that allows multiple models to be stored in the same dat

Jon Palmer 240 Oct 26, 2022
This package provides a trait that will generate a unique uuid when saving any Eloquent model.

Generate slugs when saving Eloquent models This package provides a trait that will generate a unique uuid when saving any Eloquent model. $model = new

Abdul Kudus 2 Oct 14, 2021
Trait for multilingual resource file support

⚡ Usage This library supports MultilingualResourceTrait which can be used in PluginBase. Multilingual support of resource files is possible using this

PocketMine-MP projects of PresentKim 1 Jun 7, 2022
Package with small support traits and classes for the Laravel Eloquent models

Contains a set of traits for the eloquent model. In future can contain more set of classes/traits for the eloquent database.

Martin Kluska 3 Feb 10, 2022
A simple drop-in solution for providing UUID support for the IDs of your Eloquent models.

Introduction A simple drop-in solution for providing UUID support for the IDs of your Eloquent models. Both v1 and v4 IDs are supported out of the box

GoldSpec Digital 501 Jan 4, 2023
Laravel-tagmanager - An easier way to add Google Tag Manager to your Laravel application.

Laravel TagManager An easier way to add Google Tag Manager to your Laravel application. Including recommended GTM events support. Requirements Laravel

Label84 16 Nov 23, 2022
A Laravel 8 and Livewire 2 demo showing how to search and filter by tags, showing article and video counts for each tag (Polymorphic relationship)

Advanced search and filter with Laravel and Livewire A demo app using Laravel 8 and Livewire 2 showing how to implement a list of articles and tags, v

Sérgio Jardim 19 Aug 29, 2022
Trait for Laravel testing to count/assert about database queries

counts_database_queries Trait for Laravel testing to count/assert about database queries Installing composer require ohffs/counts-database-queries-tra

null 1 Feb 23, 2022
Generate and autoload custom Helpers, Builder Scope, Service class, Trait

laravel-make-extender Generate and autoload custom helpers, It can generate multilevel helpers in the context of the directory. Generate Service class

Limewell 30 Dec 24, 2022
This package provides a trait to run your tests against a MinIO S3 server.

Laravel MinIO Testing Tools This package provides a trait to run your tests against a MinIO S3 server. ?? Blog post: https://protone.media/en/blog/how

Protone Media 7 Oct 12, 2022
Livewire trait (throttling). Limiting request processing speed

Livewire Throttling Installation You can install the package via composer: composer require f1uder/livewire-throttling Usage Livewire component <?php

Fluder 5 Dec 7, 2022
An Eloquent Way To Filter Laravel Models And Their Relationships

Eloquent Filter An Eloquent way to filter Eloquent Models and their relationships Introduction Lets say we want to return a list of users filtered by

Eric Tucker 1.5k Jan 7, 2023
Easy creation of slugs for your Eloquent models in Laravel

Eloquent-Sluggable Easy creation of slugs for your Eloquent models in Laravel. NOTE: These instructions are for the latest version of Laravel. If you

Colin Viebrock 3.6k Dec 30, 2022
Automatically validating Eloquent models for Laravel

Validating, a validation trait for Laravel Validating is a trait for Laravel Eloquent models which ensures that models meet their validation criteria

Dwight Watson 955 Dec 25, 2022
Laravel Ban simplify blocking and banning Eloquent models.

Laravel Ban Introduction Laravel Ban simplify management of Eloquent model's ban. Make any model bannable in a minutes! Use case is not limited to Use

cybercog 879 Dec 30, 2022
cybercog 996 Dec 28, 2022
Preferences for Laravel Eloquent models

Preferences for Laravel Eloquent models Use this library to bind multiple key/value pair preferences to your application's Eloquent models. Preference

Kevin Laude 32 Oct 30, 2022
Laravel package to search through multiple Eloquent models.

Laravel package to search through multiple Eloquent models. Supports sorting, pagination, scoped queries, eager load relationships and searching through single or multiple columns.

Protone Media 845 Jan 1, 2023