{"id":20327272,"url":"https://github.com/turahe/laravel-likeable","last_synced_at":"2025-04-11T20:08:03.037Z","repository":{"id":56250440,"uuid":"298268837","full_name":"turahe/laravel-likeable","owner":"turahe","description":"Laravel Likeable simplify management of Eloquent model's likes \u0026 dislikes. Make any model likeable \u0026 dislikeable in a minute!","archived":false,"fork":false,"pushed_at":"2024-08-01T13:54:54.000Z","size":92,"stargazers_count":7,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-10-01T15:48:39.733Z","etag":null,"topics":["dislike","dislike-model","dislikes","dislikes-count","laravel","like","likes-count","recount-likes","simple"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/turahe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-09-24T12:16:10.000Z","updated_at":"2024-08-01T13:54:57.000Z","dependencies_parsed_at":"2022-08-15T15:30:50.179Z","dependency_job_id":null,"html_url":"https://github.com/turahe/laravel-likeable","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turahe%2Flaravel-likeable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turahe%2Flaravel-likeable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turahe%2Flaravel-likeable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turahe%2Flaravel-likeable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/turahe","download_url":"https://codeload.github.com/turahe/laravel-likeable/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224684678,"owners_count":17352584,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dislike","dislike-model","dislikes","dislikes-count","laravel","like","likes-count","recount-likes","simple"],"created_at":"2024-11-14T19:47:06.634Z","updated_at":"2025-04-11T20:08:02.916Z","avatar_url":"https://github.com/turahe.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Introduction\n\n[![Latest Stable Version](https://poser.pugx.org/turahe/laravel-likeable/v)](//packagist.org/packages/turahe/laravel-likeable)\n[![Total Downloads](https://poser.pugx.org/turahe/laravel-likeable/downloads)](//packagist.org/packages/turahe/laravel-likeable)\n[![License](https://poser.pugx.org/turahe/laravel-likeable/license)](//packagist.org/packages/turahe/laravel-likeable)\n[![PHP Composer](https://github.com/turahe/laravel-likeable/actions/workflows/php.yml/badge.svg)](https://github.com/turahe/laravel-likeable/actions/workflows/php.yml)\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/turahe/laravel-likeable/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/turahe/laravel-likeable/?branch=master)\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fturahe%2Flaravel-likeable.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fturahe%2Flaravel-likeable?ref=badge_shield)\n[![StyleCI](https://github.styleci.io/repos/298268837/shield?branch=master)](https://github.styleci.io/repos/298268837?branch=master)\n![PHP Composer](https://github.com/turahe/laravel-likeable/workflows/PHP%20Composer/badge.svg)\n\nLaravel Likeable simplify management of Eloquent model's likes \u0026 dislikes. Make any model `likeable` \u0026 `dislikeable` in a minute!\n\n## Contents\n\n- [Features](#features)\n- [Installation](#installation)\n- [Usage](#usage)\n    - [Prepare likeable model](#prepare-likeable-model)\n    - [Available methods](#available-methods)\n    - [Scopes](#scopes)\n    - [Events](#events)\n    - [Console commands](#console-commands)\n- [Extending](#extending)\n- [Change log](#change-log)\n- [Contributing](#contributing)\n- [Testing](#testing)\n- [Security](#security)\n- [Contributors](#contributors)\n- [Alternatives](#alternatives)\n- [License](#license)\n- [About CyberTurahe](#about-turahe)\n\n## Features\n\n- Designed to work with Laravel Eloquent models.\n- Using contracts to keep high customization capabilities.\n- Using traits to get functionality out of the box.\n- Most part of the logic is handled by the `LikeableService`.\n- Has Artisan command `likeable:recount {model?} {type?}` to re-fetch likes counters.\n- Likeable model can has Likes and Dislikes.\n- Likes and Dislikes for one model are mutually exclusive.\n- Get Likeable models ordered by likes count.\n- Events for `like`, `unlike`, `dislike`, `undislike` methods.\n- Following PHP Standard Recommendations:\n  - [PSR-1 (Basic Coding Standard)](http://www.php-fig.org/psr/psr-1/).\n  - [PSR-2 (Coding Style Guide)](http://www.php-fig.org/psr/psr-2/).\n  - [PSR-4 (Autoloading Standard)](http://www.php-fig.org/psr/psr-4/).\n- Covered with unit tests.\n\n## Installation\n\nFirst, pull in the package through Composer.\n\n```sh\n$ composer require turahe/laravel-likeable\n```\n\n**If you are using Laravel 5.5 you can skip register package part.** \n\n#### Register package on Laravel 5.4 and lower\n\nInclude the service provider within `app/config/app.php`.\n\n```php\n'providers' =\u003e [\n    Turahe\\Likeable\\LikeableServiceProvider::class,\n],\n```\n\n#### Perform Database Migration\n\nAt last, you need to publish and run database migrations.\n\n```sh\n$ php artisan vendor:publish --provider=\"Turahe\\Likeable\\Providers\\LikeableServiceProvider\" --tag=migrations\n$ php artisan migrate\n```\n\n## Usage\n\n### Prepare likeable model\n\nUse `Likeable` contract in model which will get likes behavior and implement it or just use `Likeable` trait. \n\n```php\nuse Turahe\\Likeable\\Contracts\\Likeable as LikeableContract;\nuse Turahe\\Likeable\\Traits\\Likeable;\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass Article extends Model implements LikeableContract\n{\n    use Likeable;\n}\n```\n\n### Available methods\n\n#### Likes\n\n##### Like model\n\n```php\n$article-\u003elike(); // current user\n$article-\u003elike($user-\u003eid);\n```\n\n##### Remove like mark from model\n\n```php\n$article-\u003eunlike(); // current user\n$article-\u003eunlike($user-\u003eid);\n```\n\n##### Toggle like mark of model\n\n```php\n$article-\u003elikeToggle(); // current user\n$article-\u003elikeToggle($user-\u003eid);\n```\n\n##### Get model likes count\n\n```php\n$article-\u003elikesCount;\n```\n\n##### Get model likes counter\n\n```php\n$article-\u003elikesCounter;\n```\n\n##### Get likes relation\n\n```php\n$article-\u003elikes();\n```\n\n##### Get iterable `Illuminate\\Database\\Eloquent\\Collection` of existing model likes\n\n```php\n$article-\u003elikes;\n```\n\n##### Boolean check if user liked model\n\n```php\n$article-\u003eliked; // current user\n$article-\u003eliked(); // current user\n$article-\u003eliked($user-\u003eid);\n```\n\n*Checks in eager loaded relations `likes` \u0026 `likesAndDislikes` first.*\n\n##### Get collection of users who liked model\n\n```php\n$article-\u003ecollectLikers();\n```\n\n##### Delete all likes for model\n\n```php\n$article-\u003eremoveLikes();\n```\n\n#### Dislikes\n\n##### Dislike model\n\n```php\n$article-\u003edislike(); // current user\n$article-\u003edislike($user-\u003eid);\n```\n\n##### Remove dislike mark from model\n\n```php\n$article-\u003eundislike(); // current user\n$article-\u003eundislike($user-\u003eid);\n```\n\n##### Toggle dislike mark of model\n\n```php\n$article-\u003edislikeToggle(); // current user\n$article-\u003edislikeToggle($user-\u003eid);\n```\n\n##### Get model dislikes count\n\n```php\n$article-\u003edislikesCount;\n```\n\n##### Get model dislikes counter\n\n```php\n$article-\u003edislikesCounter;\n```\n\n##### Get dislikes relation\n\n```php\n$article-\u003edislikes();\n```\n\n##### Get iterable `Illuminate\\Database\\Eloquent\\Collection` of existing model dislikes\n\n```php\n$article-\u003edislikes;\n```\n\n##### Boolean check if user disliked model\n\n```php\n$article-\u003edisliked; // current user\n$article-\u003edisliked(); // current user\n$article-\u003edisliked($user-\u003eid);\n```\n\n*Checks in eager loaded relations `dislikes` \u0026 `likesAndDislikes` first.*\n\n##### Get collection of users who disliked model\n\n```php\n$article-\u003ecollectDislikers();\n```\n\n##### Delete all dislikes for model\n\n```php\n$article-\u003eremoveDislikes();\n```\n\n#### Likes and Dislikes\n\n##### Get difference between likes and dislikes\n\n```php\n$article-\u003elikesDiffDislikesCount;\n```\n\n##### Get likes and dislikes relation\n\n```php\n$article-\u003elikesAndDislikes();\n```\n\n##### Get iterable `Illuminate\\Database\\Eloquent\\Collection` of existing model likes and dislikes\n\n```php\n$article-\u003elikesAndDislikes;\n```\n\n### Scopes\n\n##### Find all articles liked by user\n\n```php\nArticle::whereLikedBy($user-\u003eid)\n    -\u003ewith('likesCounter') // Allow eager load (optional)\n    -\u003eget();\n```\n\n##### Find all articles disliked by user\n\n```php\nArticle::whereDislikedBy($user-\u003eid)\n    -\u003ewith('dislikesCounter') // Allow eager load (optional)\n    -\u003eget();\n```\n\n##### Fetch Likeable models by likes count\n\n```php\n$sortedArticles = Article::orderByLikesCount()-\u003eget();\n$sortedArticles = Article::orderByLikesCount('asc')-\u003eget();\n```\n\n*Uses `desc` as default order direction.*\n\n##### Fetch Likeable models by dislikes count\n\n```php\n$sortedArticles = Article::orderByDislikesCount()-\u003eget();\n$sortedArticles = Article::orderByDislikesCount('asc')-\u003eget();\n```\n\n*Uses `desc` as default order direction.*\n\n### Events\n\nOn each like added `\\Turahe\\Likeable\\Events\\ModelWasLiked` event is fired.\n\nOn each like removed `\\Turahe\\Likeable\\Events\\ModelWasUnliked` event is fired.\n\nOn each dislike added `\\Turahe\\Likeable\\Events\\ModelWasDisliked` event is fired.\n\nOn each dislike removed `\\Turahe\\Likeable\\Events\\ModelWasUndisliked` event is fired.\n\n### Console commands\n\n##### Recount likes and dislikes of all model types\n\n```sh\n$ likeable:recount\n```\n\n##### Recount likes and dislikes of concrete model type (using morph map alias)\n\n```sh\n$ likeable:recount --model=\"article\"\n```\n\n##### Recount likes and dislikes of concrete model type (using fully qualified class name)\n\n```sh\n$ likeable:recount --model=\"App\\Models\\Article\"\n```\n\n##### Recount only likes of all model types\n\n```sh\n$ likeable:recount --type=\"like\"\n```\n\n##### Recount only likes of concrete model type (using morph map alias)\n\n```sh\n$ likeable:recount --model=\"article\" --type=\"like\"\n```\n\n##### Recount only likes of concrete model type (using fully qualified class name)\n\n```sh\n$ likeable:recount --model=\"App\\Models\\Article\" --type=\"like\"\n```\n\n##### Recount only dislikes of all model types\n\n```sh\n$ likeable:recount --type=\"dislike\"\n```\n\n##### Recount only dislikes of concrete model type (using morph map alias)\n\n```sh\n$ likeable:recount --model=\"article\" --type=\"dislike\"\n```\n\n##### Recount only dislikes of concrete model type (using fully qualified class name)\n\n```sh\n$ likeable:recount --model=\"App\\Models\\Article\" --type=\"dislike\"\n```\n\n## Extending\n\nYou can override core classes of package with your own implementations:\n\n- `Models\\Like`\n- `Models\\LikeCounter`\n- `Services\\LikeableService`\n\n*Note: Don't forget that all custom models must implement original models interfaces.*\n\nTo make it you should use container [binding interfaces to implementations](https://laravel.com/docs/master/container#binding-interfaces-to-implementations) in your application service providers.\n\n##### Use model class own implementation\n\n```php\n$this-\u003eapp-\u003ebind(\n    \\Turahe\\Likeable\\Contracts\\Like::class,\n    \\App\\Models\\CustomLike::class\n);\n```\n\n##### Use service class own implementation\n\n```php\n$this-\u003eapp-\u003esingleton(\n    \\Turahe\\Likeable\\Contracts\\LikeableService::class,\n    \\App\\Services\\CustomService::class\n);\n```\n\nAfter that your `CustomLike` and `CustomService` classes will be instantiable with helper method `app()`.\n\n```php\n$model = app(\\Turahe\\Likeable\\Contracts\\Like::class);\n$service = app(\\Turahe\\Likeable\\Contracts\\LikeableService::class);\n```\n\n## Change log\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.\n\n## Contributing\n\nPlease see [CONTRIBUTING](CONTRIBUTING.md) for details.\n\n## Testing\n\nYou can run the tests with:\n\n```sh\n$ vendor/bin/phpunit\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fturahe%2Flaravel-likeable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fturahe%2Flaravel-likeable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fturahe%2Flaravel-likeable/lists"}