A flexible and robust Laravel package that provides comprehensive flagging functionality for Eloquent models with polymorphic relationships and sophisticated multi-table architecture.
Everything you need for a complete flagging system in Laravel
Any model can flag any other model with polymorphic relationships
Support for like, follow, favorite, bookmark, upvote, downvote, and custom types
Four-table design for optimal performance and flexibility
Get started with Flagable in just a few steps
composer require sowailem/flagable
The package will automatically register its service provider and facade through Laravel's auto-discovery feature.
php artisan migrate
To populate the database with default flag types (like, follow, favorite, bookmark, upvote, downvote):
php artisan db:seed --class="Sowailem\Flagable\Database\Seeders\FlagTypeSeeder"
Learn how to implement flagging in your Laravel models
Add the Flagable trait to models that can be flagged:
<?php
use Sowailem\Flagable\Traits\Flagable;
class Post extends Model
{
use Flagable;
// Your model code...
}
Add the CanFlag trait to models that can flag others:
<?php
use Sowailem\Flagable\Traits\CanFlag;
class User extends Model
{
use CanFlag;
// Your model code...
}
// User flags a post as "like"
$user = User::find(1);
$post = Post::find(1);
$user->flag($post, 'like');
// User removes like from post
$user->unflag($post, 'like');
// Check if user has liked the post
if ($user->hasFlagged($post, 'like')) {
echo "User has liked this post";
}
// Get total likes for a post
$likeCount = $post->flagCount('like');
// Get all flags count (all types)
$totalFlags = $post->flagCount();
// Get all posts liked by user (using trait method)
$likedPosts = $user->flags('like');
// Get all bookmarked posts (using facade)
$bookmarks = Flag::getFlags($user, 'bookmark');
// Get all entities flagged by user (any type)
$allFlags = $user->flags();
Complete reference for all available methods and traits
Add this trait to models that can flag other models.
Flags a model with the specified flag type.
$flagable - The model to be flagged$flagTypeName - The type of flag (e.g., 'like', 'follow')
Removes a flag from a model.
$flagable - The model to unflag$flagTypeName - The type of flag to remove
Checks if the model has flagged another model.
$flagable - The model to check$flagTypeName - Optional flag type to check (null checks all types)
Returns a collection of all entities flagged by this model.
$flagTypeName - Optional flag type to filter by (null returns all flagged entities)
// Get all posts liked by user
$likedPosts = $user->flags('like');
// Get all entities flagged by user (any type)
$allFlags = $user->flags();
Returns a morphMany relationship to all flags created by this model (for advanced queries).
Add this trait to models that can be flagged by other models.
Checks if this model is flagged by another model.
$flagger - The model that might have flagged this one$flagTypeName - Optional flag type to check
Returns the total number of flags for this model.
$flagTypeName - Optional flag type to count (null counts all types)
Returns all models that have flagged this model with a specific flag type.
$flagTypeName - The flag type to search for$flaggerModel - The class name of the flagger model
Returns a hasManyThrough relationship to all flags for this model.
Static methods available through the Flag facade for direct access to flagging functionality.
Returns a collection of all entities flagged by the specified model.
$flagger - The model that created the flags$flagTypeName - Optional flag type to filter by (null returns all flagged entities)
use Sowailem\Flagable\Facades\Flag;
// Get all posts bookmarked by user
$bookmarks = Flag::getFlags($user, 'bookmark');
// Get all entities flagged by user (any type)
$allFlags = Flag::getFlags($user);
Note: The Flag facade also provides static access to all other flagging methods like flag(), unflag(), isFlaggedBy(), getFlagCount(), and getFlaggers().
The package comes with these pre-defined flag types:
Understanding the sophisticated four-table design
The Flagable package uses a sophisticated four-table architecture that provides optimal performance, flexibility, and data integrity. This design allows for efficient querying while maintaining clean relationships between different entities.
Stores all available flag types (like, follow, favorite, etc.)
Stores model class names that can be flagged
Links flag types with target models (junction table)
Stores individual flag records with polymorphic relationships
Here's how the system works when a User likes a Post:
System ensures "like" exists in flag_types table
System ensures "App\Models\Post" exists in flag_targets table
System creates link between "like" type and "Post" target in flag_links table
System creates the actual flag record in flags table with User's polymorphic relationship