Laravel Likeable simplifies management of Eloquent model's likes & dislikes. Make any model likeable & dislikeable in a minute!
- Features
- Installation
- Usage
- Extending
- Change log
- Contributing
- Testing
- Continuous Integration
- Release Process
- Security
- Contributors
- Alternatives
- License
- About Turahe
- âś… Designed to work with Laravel Eloquent models
- âś… Using contracts to keep high customization capabilities
- âś… Using traits to get functionality out of the box
- âś… Most part of the logic is handled by the
LikeableService - âś… Has Artisan command
likeable:recount {model?} {type?}to re-fetch likes counters - âś… Likeable model can have Likes and Dislikes
- âś… Likes and Dislikes for one model are mutually exclusive
- âś… Get Likeable models ordered by likes count
- âś… Events for
like,unlike,dislike,undislikemethods - âś… Comprehensive test coverage (79 tests, 0 failures)
- âś… Following PHP Standard Recommendations:
- âś… Fully tested with PHPUnit
- âś… Continuous Integration with GitHub Actions
- âś… Code style checks with PHP CS Fixer
- âś… Static analysis with Larastan
- âś… Automated release workflows with conventional commits
- âś… Semantic versioning and changelog generation
First, pull in the package through Composer.
$ composer require turahe/laravel-likeableIf you are using Laravel 5.5+ you can skip the register package part.
Include the service provider within app/config/app.php.
'providers' => [
Turahe\Likeable\LikeableServiceProvider::class,
],At last, you need to publish and run database migrations.
$ php artisan vendor:publish --provider="Turahe\Likeable\LikeableServiceProvider" --tag=migrations
$ php artisan migrateUse Likeable contract in model which will get likes behavior and implement it or just use Likeable trait.
use Turahe\Likeable\Contracts\Likeable as LikeableContract;
use Turahe\Likeable\Traits\Likeable;
use Illuminate\Database\Eloquent\Model;
class Article extends Model implements LikeableContract
{
use Likeable;
}$article->like(); // current user
$article->like($user->id);$article->unlike(); // current user
$article->unlike($user->id);$article->likeToggle(); // current user
$article->likeToggle($user->id);$article->likesCount;$article->likesCounter;$article->likes();$article->likes;$article->liked; // current user
$article->liked(); // current user
$article->liked($user->id);Checks in eager loaded relations likes & likesAndDislikes first.
$article->collectLikers();$article->removeLikes();$article->dislike(); // current user
$article->dislike($user->id);$article->undislike(); // current user
$article->undislike($user->id);$article->dislikeToggle(); // current user
$article->dislikeToggle($user->id);$article->dislikesCount;$article->dislikesCounter;$article->dislikes();$article->dislikes;$article->disliked; // current user
$article->disliked(); // current user
$article->disliked($user->id);Checks in eager loaded relations dislikes & likesAndDislikes first.
$article->collectDislikers();$article->removeDislikes();$article->likesDiffDislikesCount;$article->likesAndDislikes();$article->likesAndDislikes;Article::whereLikedBy($user->id)
->with('likesCounter') // Allow eager load (optional)
->get();Article::whereDislikedBy($user->id)
->with('dislikesCounter') // Allow eager load (optional)
->get();$sortedArticles = Article::orderByLikesCount()->get();
$sortedArticles = Article::orderByLikesCount('asc')->get();Uses desc as default order direction.
$sortedArticles = Article::orderByDislikesCount()->get();
$sortedArticles = Article::orderByDislikesCount('asc')->get();Uses desc as default order direction.
On each like added \Turahe\Likeable\Events\ModelWasLiked event is fired.
On each like removed \Turahe\Likeable\Events\ModelWasUnliked event is fired.
On each dislike added \Turahe\Likeable\Events\ModelWasDisliked event is fired.
On each dislike removed \Turahe\Likeable\Events\ModelWasUndisliked event is fired.
$ php artisan likeable:recount$ php artisan likeable:recount --model="article"$ php artisan likeable:recount --model="App\Models\Article"$ php artisan likeable:recount --type="like"$ php artisan likeable:recount --model="article" --type="like"$ php artisan likeable:recount --model="App\Models\Article" --type="like"$ php artisan likeable:recount --type="dislike"$ php artisan likeable:recount --model="article" --type="dislike"$ php artisan likeable:recount --model="App\Models\Article" --type="dislike"You can override core classes of package with your own implementations:
Models\LikeModels\LikeCounterServices\LikeableService
Note: Don't forget that all custom models must implement original models interfaces.
To make it you should use container binding interfaces to implementations in your application service providers.
$this->app->bind(
\Turahe\Likeable\Contracts\Like::class,
\App\Models\CustomLike::class
);$this->app->singleton(
\Turahe\Likeable\Contracts\LikeableService::class,
\App\Services\CustomService::class
);After that your CustomLike and CustomService classes will be instantiable with helper method app().
$model = app(\Turahe\Likeable\Contracts\Like::class);
$service = app(\Turahe\Likeable\Contracts\LikeableService::class);Please see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details.
This package includes comprehensive test coverage with 79 tests covering all functionality:
- Common Use Tests - Basic like/unlike functionality
- Counter Tests - Like/dislike counter management
- Dislike Tests - Dislike-specific functionality
- Enum Tests - LikeType enum functionality
- Event Tests - Event dispatching
- Exception Tests - Custom exception handling
- Service Tests - Service layer functionality
- Toggle Tests - Like/dislike toggle operations
- Console Command Tests - Artisan command functionality
You can run the tests with:
$ vendor/bin/phpunitOr use the composer script:
$ composer testRun tests with coverage:
$ composer test:coverageThis will generate HTML coverage reports in the coverage-html directory.
This package uses GitHub Actions for continuous integration. The CI pipeline includes:
- PHP Versions: 8.3, 8.4
- Laravel Versions: 11.x, 12.x
- Test Coverage: Generated for PHP 8.3+ + Laravel 11/12.x
- Tests: Runs the full test suite across all PHP/Laravel combinations with code coverage
- Static Analysis: Code style checking with PHP CS Fixer and Larastan across all PHP/Laravel combinations
- Lint: PHP syntax validation
- Coverage: Detailed code coverage reporting with HTML reports
You can run the same checks locally:
# Run all checks
$ composer check
# Run specific checks
$ composer test # Run tests
$ composer test:coverage # Run tests with coverage
$ composer lint # Check code style
$ composer analyse # Run static analysisCode coverage reports are generated and uploaded to Codecov.
This package uses automated release workflows for version management and deployment.
- Trigger: Pushes to
mainbranch with conventional commits - Actions:
- Runs tests, static analysis, and linting
- Updates
CHANGELOG.mdwith new entries - Creates release preparation PRs for new features
- Follows Conventional Commits format
- Trigger: Pushing tags with
v*pattern (e.g.,v1.2.3) - Actions:
- Validates code quality (tests, analysis, linting)
- Generates changelog from git history
- Creates GitHub release with assets
- Uploads
composer.json,CHANGELOG.md, andREADME.mdas release assets
- Prepare Changes: Ensure all changes follow conventional commit format
- Create Tag: Create and push a new version tag
git tag v1.2.3 git push origin v1.2.3
- Automated Process: The release workflow will automatically:
- Run all quality checks
- Generate release notes
- Create GitHub release
- Upload release assets
This project follows the Conventional Commits specification:
feat:- New features (triggers release preparation)fix:- Bug fixesdocs:- Documentation changesstyle:- Code style changesrefactor:- Code refactoringperf:- Performance improvementstest:- Test additions or changesbuild:- Build system changesci:- CI/CD changeschore:- Maintenance tasks
If you discover any security related issues, please email wachid@outlook.com instead of using the issue tracker.
- Nur Wachid - Initial work
- spatie/laravel-likes - A simple package to add likes to Eloquent models
- rtconner/laravel-likeable - Likeable trait for Laravel Eloquent models
The MIT License (MIT). Please see License File for more information.
Turahe is a software development company focused on creating high-quality Laravel packages and applications. Visit us at turahe.id.