├── .github
└── workflows
│ ├── update-changelog.yml
│ └── tests.yml
├── src
├── Contracts
│ └── HasReaction.php
├── Events
│ ├── RemoveReactionEvent.php
│ ├── RemoveAllReactionEvent.php
│ └── StoreReactionEvent.php
├── Enums
│ └── LaravelReactionTypeEnum.php
├── Providers
│ └── LaravelReactionServiceProvider.php
├── Models
│ └── Reaction.php
└── Traits
│ ├── Reactor.php
│ └── Reactable.php
├── phpunit.xml
├── config
└── laravel-reaction.php
├── LICENSE
├── database
└── migrations
│ └── 2024_09_21_112229_create_reactions_table.php
├── composer.json
├── CHANGELOG.md
└── README.md
/.github/workflows/update-changelog.yml:
--------------------------------------------------------------------------------
1 | name: update changelog
2 |
3 | on:
4 | release:
5 | types: [released]
6 |
7 | permissions: {}
8 |
9 | jobs:
10 | update:
11 | permissions:
12 | contents: write
13 | uses: laravel/.github/.github/workflows/update-changelog.yml@main
14 |
--------------------------------------------------------------------------------
/src/Contracts/HasReaction.php:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 | ./tests
10 |
11 |
12 |
13 |
14 | ./src
15 | ./config
16 | ./database
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/config/laravel-reaction.php:
--------------------------------------------------------------------------------
1 | 'reactions',
8 |
9 | 'user' => [
10 | /*
11 | * User model.
12 | */
13 | 'model' => 'App\Models\User',
14 |
15 | /*
16 | * Foreign Key column name.
17 | */
18 | 'foreign_key' => 'user_id',
19 |
20 | /*
21 | * Users table name.
22 | */
23 | 'table' => 'users',
24 |
25 | /*
26 | * The correct guard.
27 | */
28 | 'guard' => 'web',
29 |
30 | /*
31 | * If you are using uuid or ulid you can change it for the type of foreign_key.
32 | *
33 | * When you are using ulid or uuid, you need to add related traits into the models.
34 | */
35 | 'foreign_key_type' => 'id', // uuid, ulid, id
36 | ]
37 | ];
38 |
--------------------------------------------------------------------------------
/src/Providers/LaravelReactionServiceProvider.php:
--------------------------------------------------------------------------------
1 | loadMigrationsFrom(__DIR__ . '/../../database/migrations');
15 | $this->mergeConfigFrom(__DIR__ . '/../../config/laravel-reaction.php', 'laravel-reactions');
16 | }
17 |
18 | public function boot(): void
19 | {
20 | $this->publishes([
21 | __DIR__ . '/../../config/laravel-reaction.php' => config_path('laravel-reaction.php'),
22 | ], 'laravel-reactions-config');
23 |
24 | $this->publishes([
25 | __DIR__ . '/../../database/migrations/' => database_path('migrations')
26 | ], 'laravel-reactions-migrations');
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2025 Milwad Khosravi (Binafy)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
--------------------------------------------------------------------------------
/src/Models/Reaction.php:
--------------------------------------------------------------------------------
1 | setTable(config('laravel-reactions.table', 'reactions'));
31 | }
32 |
33 | // Relations
34 |
35 | /**
36 | * Reactable morph relation.
37 | */
38 | public function reactable(): \Illuminate\Database\Eloquent\Relations\MorphTo
39 | {
40 | return $this->morphTo();
41 | }
42 |
43 | /**
44 | * Relation one-to-many, User model.
45 | */
46 | public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo
47 | {
48 | return $this->belongsTo(
49 | config('laravel-reactions.user.model'),
50 | config('laravel-reactions.user.foreign_key'),
51 | );
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/database/migrations/2024_09_21_112229_create_reactions_table.php:
--------------------------------------------------------------------------------
1 | id();
16 |
17 | $userForeignType = config('laravel-reactions.user.foreign_key_type', 'id');
18 | $userForeignName = config('laravel-reactions.user.foreign_key');
19 | $userForeignTableName = config('laravel-reactions.user.table');
20 |
21 | if ($userForeignType === 'ulid') {
22 | $table->foreignUlid($userForeignName)
23 | ->nullable()
24 | ->constrained($userForeignTableName)
25 | ->nullOnDelete();
26 | } else if ($userForeignType === 'uuid') {
27 | $table->foreignUuid($userForeignName)
28 | ->nullable()
29 | ->constrained($userForeignTableName)
30 | ->nullOnDelete();
31 | } else {
32 | $table->foreignId($userForeignName)
33 | ->nullable()
34 | ->constrained($userForeignTableName)
35 | ->nullOnDelete();
36 | }
37 |
38 | $table->morphs('reactable');
39 | $table->string('type');
40 | $table->string('ip')->nullable();
41 |
42 | $table->unique([$userForeignName, 'reactable_type', 'reactable_id', 'ip'], 'reaction_user_name_per_ip');
43 |
44 | $table->timestamps();
45 | });
46 | }
47 |
48 | /**
49 | * Reverse the migrations.
50 | */
51 | public function down(): void
52 | {
53 | Schema::dropIfExists(config('laravel-reactions.table', 'reactions'));
54 | }
55 | };
56 |
--------------------------------------------------------------------------------
/.github/workflows/tests.yml:
--------------------------------------------------------------------------------
1 | name: "Run Tests"
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | test:
7 | runs-on: ubuntu-latest
8 | strategy:
9 | fail-fast: false
10 | matrix:
11 | php: [8.1, 8.2, 8.3, 8.4]
12 | laravel: [10.*, 11.*, 12.*]
13 | dependency-version: [prefer-lowest, prefer-stable]
14 | include:
15 | - laravel: 12.*
16 | testbench: 10.*
17 | pest-plugin-laravel: 3.1.0
18 |
19 | - laravel: 11.*
20 | testbench: 9.*
21 | pest-plugin-laravel: 2.3.0
22 |
23 | - laravel: 10.*
24 | testbench: 8.*
25 | pest-plugin-laravel: 2.0.0
26 |
27 | exclude:
28 | - laravel: 12.*
29 | php: 8.1
30 |
31 | - laravel: 11.*
32 | php: 8.1
33 |
34 | - laravel: 10.*
35 | php: 8.4
36 |
37 | name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }}
38 |
39 | steps:
40 | - name: Checkout code
41 | uses: actions/checkout@v4
42 |
43 | - name: Setup PHP
44 | uses: shivammathur/setup-php@v2
45 | with:
46 | php-version: ${{ matrix.php }}
47 | extensions: curl, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, iconv
48 | coverage: none
49 |
50 | - name: Install dependencies
51 | run: |
52 | composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" "pestphp/pest-plugin-laravel:${{ matrix.pest-plugin-laravel }}" --no-interaction --no-update
53 | composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction
54 | - name: Execute tests
55 | run: vendor/bin/pest
56 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "binafy/laravel-reactions",
3 | "description": "Laravel Reactions is a simple and flexible package that allows you to add reaction functionality to any Eloquent model",
4 | "keywords": [
5 | "laravel reactions",
6 | "laravel-reactions",
7 | "binafy/laravel-reactions",
8 | "binafy",
9 | "milwad",
10 | "milwad khosravi",
11 | "fun developer",
12 | "laravel reactions package",
13 | "laravel reactions github",
14 | "laravel",
15 | "laravel library",
16 | "reaction",
17 | "reactions",
18 | "like",
19 | "love",
20 | "clap",
21 | "eloquent",
22 | "laravel reaction eloquent"
23 | ],
24 | "type": "library",
25 | "license": "MIT",
26 | "homepage": "https://github.com/binafy/laravel-reactions",
27 | "minimum-stability": "dev",
28 | "autoload": {
29 | "psr-4": {
30 | "Binafy\\LaravelReaction\\": "src/"
31 | }
32 | },
33 | "autoload-dev": {
34 | "psr-4": {
35 | "Tests\\": "tests/"
36 | }
37 | },
38 | "authors": [
39 | {
40 | "name": "Milwad Khosravi",
41 | "email": "milwad.dev@gmail.com",
42 | "role": "author",
43 | "homepage": "https://github.com/milwad-dev"
44 | },
45 | {
46 | "name": "Binafy",
47 | "role": "owner",
48 | "homepage": "https://github.com/binafy"
49 | }
50 | ],
51 | "require": {
52 | "php": "^8.1",
53 | "laravel/framework": "^10.0|^11.0|^12.0"
54 | },
55 | "require-dev": {
56 | "pestphp/pest-plugin-laravel": "^1.4.0|^2.0.0|^3.1.0",
57 | "orchestra/testbench": "^8.0|^9.0|^10.0"
58 | },
59 | "config": {
60 | "sort-packages": true,
61 | "allow-plugins": {
62 | "pestphp/pest-plugin": true
63 | }
64 | },
65 | "scripts": {
66 | "test": "vendor/bin/pest",
67 | "test-coverage": "vendor/bin/pest --coverage-html ./coverage"
68 | },
69 | "extra": {
70 | "laravel": {
71 | "providers": [
72 | "Binafy\\LaravelReaction\\Providers\\LaravelReactionServiceProvider"
73 | ]
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/Traits/Reactor.php:
--------------------------------------------------------------------------------
1 | value;
26 | }
27 |
28 | // Store reaction
29 | $reaction = $reactable->reactions()->firstOrCreate([
30 | $userForeignName => $this->getKey(),
31 | 'type' => $type,
32 | 'reactable_id' => $reactable->getKey(),
33 | 'reactable_type' => $reactable::class,
34 | ]);
35 |
36 | // Dispatch event
37 | StoreReactionEvent::dispatch($reaction);
38 |
39 | return $reaction;
40 | }
41 |
42 | /**
43 | * Remove reactions if exists.
44 | */
45 | public function removeReactions(HasReaction $reactable): bool
46 | {
47 | $userForeignName = config('laravel-relations.user.foreign_key', 'user_id');
48 |
49 | $reactable->reactions()
50 | ->where([$userForeignName => $this->getKey()])
51 | ->delete();
52 |
53 | // Dispatch event
54 | RemoveAllReactionEvent::dispatch();
55 |
56 | return true;
57 | }
58 |
59 | /**
60 | * Remove reaction if exists.
61 | */
62 | public function removeReaction(string|LaravelReactionTypeEnum $type, HasReaction $reactable): bool
63 | {
64 | $userForeignName = config('laravel-relations.user.foreign_key', 'user_id');
65 |
66 | if ($type instanceof LaravelReactionTypeEnum) {
67 | $type = $type->value;
68 | }
69 |
70 | $reactable = $reactable->reactions()
71 | ->where([$userForeignName => $this->getKey(), 'type' => $type])
72 | ->first();
73 |
74 | if (!$reactable) {
75 | return false;
76 | }
77 |
78 | $reactable->delete();
79 |
80 | // Dispatch event
81 | RemoveReactionEvent::dispatch();
82 |
83 | return true;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/Traits/Reactable.php:
--------------------------------------------------------------------------------
1 | morphMany(Reaction::class, 'reactable');
20 | }
21 |
22 | /**
23 | * React to reactable.
24 | */
25 | public function reaction(string|LaravelReactionTypeEnum $type, User|null $user = null): Reaction
26 | {
27 | if (is_null($user)) {
28 | $user = auth()->user();
29 | }
30 |
31 | return $user->reaction($type, $this);
32 | }
33 |
34 | /**
35 | * Remove reaction if exists.
36 | */
37 | public function removeReaction(string|LaravelReactionTypeEnum $type, User|null $user = null): bool
38 | {
39 | if (is_null($user)) {
40 | $user = auth()->user();
41 | }
42 |
43 | return $user->removeReaction($type, $this);
44 | }
45 |
46 | /**
47 | * Remove all reactions if exists.
48 | */
49 | public function removeReactions(User|null $user = null): bool
50 | {
51 | if (is_null($user)) {
52 | $user = auth()->user();
53 | }
54 |
55 | return $user->removeReactions($this);
56 | }
57 |
58 | /**
59 | * Check reactable is reacted by the user.
60 | */
61 | public function isReacted(User|null $user = null): bool
62 | {
63 | if (is_null($user)) {
64 | $user = auth()->user();
65 | }
66 |
67 | return $this->reactions()->whereBelongsTo($user)->exists();
68 | }
69 |
70 | /**
71 | * Get react count by type.
72 | */
73 | public function getReactCountByType(string|LaravelReactionTypeEnum $type): int
74 | {
75 | return $this->reactions()->where('type', $type)->count();
76 | }
77 |
78 | /**
79 | * Get reactions with count.
80 | */
81 | public function getReactionsWithCount(): \Illuminate\Support\Collection
82 | {
83 | return $this
84 | ->reactions()
85 | ->groupBy('type')
86 | ->selectRaw('type, count(id) as total')
87 | ->get()
88 | ->mapWithKeys(fn (Reaction $reaction) => [$reaction->type => $reaction->total]);
89 | }
90 |
91 | /**
92 | * Get all reactors.
93 | */
94 | public function getReactors(): \Illuminate\Support\Collection
95 | {
96 | return $this
97 | ->reactions()
98 | ->get()
99 | ->map(fn (Reaction $reaction) => $reaction->user);
100 | }
101 |
102 | // Attributes
103 |
104 | /**
105 | * Get is_reacted attribute.
106 | */
107 | public function getIsReactedAttribute(): bool
108 | {
109 | return $this->isReacted();
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2024 Milwad Khosravi (Binafy)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
11 | ## v1.0.0 - 2025-07-17
12 |
13 | **Full Changelog**: https://github.com/binafy/laravel-reactions/compare/v0.9.0...v1.0.0
14 |
15 | ## v0.9.0 - 2025-07-17
16 |
17 | ### What's Changed
18 |
19 | * Add event by [@milwad-dev](https://github.com/milwad-dev) in https://github.com/binafy/laravel-reactions/pull/6
20 |
21 | **Full Changelog**: https://github.com/binafy/laravel-reactions/compare/v0.8.0...v0.9.0
22 |
23 | ## v0.8.0 - 2025-07-17
24 |
25 | ### What's Changed
26 |
27 | * Readme by [@milwad-dev](https://github.com/milwad-dev) in https://github.com/binafy/laravel-reactions/pull/5
28 |
29 | **Full Changelog**: https://github.com/binafy/laravel-reactions/compare/v0.7.0...v0.8.0
30 |
31 | ## v0.7.0 - 2025-07-16
32 |
33 | ### What's Changed
34 |
35 | * Laravel 12 by [@milwad-dev](https://github.com/milwad-dev) in https://github.com/binafy/laravel-reactions/pull/4
36 |
37 | **Full Changelog**: https://github.com/binafy/laravel-reactions/compare/v0.6.0...v0.7.0
38 |
39 | ## v0.6.0 - 2025-07-16
40 |
41 | ### What's Changed
42 |
43 | * Improve composer by [@milwad-dev](https://github.com/milwad-dev) in https://github.com/binafy/laravel-reactions/pull/3
44 |
45 | **Full Changelog**: https://github.com/binafy/laravel-reactions/compare/v0.5.0...v0.6.0
46 |
47 | ## v0.5.0 - 2025-07-16
48 |
49 | ### What's Changed
50 |
51 | * Add `getReactors` method by [@milwad-dev](https://github.com/milwad-dev) in https://github.com/binafy/laravel-reactions/pull/2
52 |
53 | **Full Changelog**: https://github.com/binafy/laravel-reactions/compare/v0.4.0...v0.5.0
54 |
55 | ## v0.4.0 - 2025-07-16
56 |
57 | ### What's Changed
58 |
59 | * Add `getReactionsWithCount` method to Reactable by [@milwad-dev](https://github.com/milwad-dev) in https://github.com/binafy/laravel-reactions/pull/1
60 |
61 | ### New Contributors
62 |
63 | * [@milwad-dev](https://github.com/milwad-dev) made their first contribution in https://github.com/binafy/laravel-reactions/pull/1
64 |
65 | **Full Changelog**: https://github.com/binafy/laravel-reactions/compare/v0.3.0...v0.4.0
66 |
67 | ## v0.3.0 - 2025-07-16
68 |
69 | **Full Changelog**: https://github.com/binafy/laravel-reactions/compare/v0.2.1...v0.3.0
70 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Laravel Reactions
2 |
3 |
4 |
5 | [](https://packagist.org/packages/binafy/laravel-reactions)
6 | [](https://packagist.org/packages/binafy/laravel-reactions)
7 | [](https://packagist.org/packages/binafy/laravel-reactions)
8 | [](https://packagist.org/packages/binafy/laravel-reactions)
9 | [](https://github.com/binafy/laravel-reactions/actions/workflows/tests.yml)
10 | [](https://deepwiki.com/binafy/laravel-reactions)
11 |
12 | ## Introduction
13 |
14 | Laravel Reactions is a simple and flexible package that enables you to add reaction functionality (such as 👍, ❤️, 😂, etc.) to any Eloquent model in your Laravel application. Whether you're building a social network, blog, or forum, this package makes it easy for users to express themselves through customizable reactions.
15 |
16 | 🔧 Features:
17 |
18 | - Add reactions to any model (e.g., posts, comments, messages)
19 | - Multiple reaction types (like, love, laugh, etc.)
20 | - Easy API for adding/removing reactions
21 | - Track who reacted and how
22 | - Eloquent relationships for seamless integration
23 | - Built-in support for custom reaction types
24 | - Lightweight and easy to customize
25 |
26 | ## Installation
27 |
28 | - ```PHP >= 8.1```
29 | - ```Laravel >= 10.0```
30 |
31 | You can install the package with Composer:
32 |
33 | ```bash
34 | composer require binafy/laravel-reactions
35 | ```
36 |
37 | ## Publish
38 |
39 | If you want to publish a config file, you can use this command:
40 |
41 | ```shell
42 | php artisan vendor:publish --tag="laravel-reactions-config"
43 | ```
44 |
45 | If you want to publish the migrations, you can use this command:
46 |
47 | ```shell
48 | php artisan vendor:publish --tag="laravel-reactions-migrations"
49 | ```
50 |
51 | For convenience, you can use this command to publish config, migration, and ... files:
52 |
53 | ```shell
54 | php artisan vendor:publish --provider="Binafy\LaravelReaction\Providers\LaravelReactionServiceProvider"
55 | ```
56 |
57 | ## Usage
58 |
59 | ### Setting Up Your Models
60 |
61 | Before using reactions, your models need the appropriate traits. User models require the Reactor trait to create reactions, while content models require the Reactable trait to receive reactions.
62 |
63 | #### User Model Setup
64 |
65 | ```php
66 | use Binafy\LaravelReaction\Traits\Reactor;
67 |
68 | class User extends Authenticatable
69 | {
70 | use Reactor;
71 | }
72 | ```
73 |
74 | #### Content Model Setup
75 |
76 | ```php
77 | use Binafy\LaravelReaction\Contracts\HasReaction;
78 | use Binafy\LaravelReaction\Traits\Reactable;
79 |
80 | class Post extends Model implements HasReaction
81 | {
82 | use Reactable;
83 | }
84 | ```
85 |
86 | ### Creating Reactions
87 |
88 | There are multiple ways to create reactions depending on your application's needs. You can create reactions from the user perspective or from the reactable content perspective.
89 |
90 | #### From User Models
91 |
92 | Users can react to any reactable content using the `reaction()` method from the `Reactor` trait:
93 |
94 | ```php
95 | use Binafy\LaravelReaction\Enums\LaravelReactionTypeEnum;
96 |
97 | $user = User::find(1);
98 | $post = Post::find(1);
99 |
100 | // Using enum reaction types
101 | $user->reaction(LaravelReactionTypeEnum::REACTION_ANGRY, $post);
102 |
103 | // Using custom string reaction types
104 | $user->reaction('love', $post);
105 | ```
106 |
107 | #### From Reactable Models
108 |
109 | Reactable content can also initiate reactions, which is useful when you want to handle reactions from the content's perspective:
110 |
111 | ```php
112 | $post = Post::find(1);
113 | $user = User::find(1);
114 |
115 | // Specify the user explicitly
116 | $post->reaction('like', $user);
117 |
118 | // Use the currently authenticated user
119 | $post->reaction('like'); // Uses auth()->user()
120 | ```
121 |
122 | ### Checking Reactions
123 |
124 | You can check whether content has been reacted to by specific users using the `isReacted()` method:
125 |
126 | ```php
127 | $post = Post::find(1);
128 | $user = User::find(1);
129 |
130 | // Check if a specific user reacted
131 | if ($post->isReacted($user)) {
132 | echo "User has reacted to this post";
133 | }
134 |
135 | // Check if the currently authenticated user reacted
136 | if ($post->isReacted()) {
137 | echo "You have reacted to this post";
138 | }
139 | ```
140 |
141 | ### Basic Reaction Queries
142 |
143 | The `Reactable` trait provides several methods for querying reaction data:
144 |
145 | #### Counting Reactions by Type
146 |
147 | ```php
148 | $post = Post::find(1);
149 |
150 | // Count specific reaction type
151 | $likeCount = $post->getReactCountByType('like');
152 | $angryCount = $post->getReactCountByType(LaravelReactionTypeEnum::REACTION_ANGRY);
153 | ```
154 |
155 | #### Getting All Reaction Counts
156 |
157 | ```php
158 | $post = Post::find(1);
159 |
160 | // Returns collection with type => count pairs
161 | $reactionCounts = $post->getReactionsWithCount();
162 | // Example result: ['like' => 5, 'love' => 3, 'angry' => 1]
163 | ```
164 |
165 | #### Getting Reactors
166 |
167 | ```php
168 | $post = Post::find(1);
169 |
170 | // Get all users who reacted to this post
171 | $reactors = $post->getReactors();
172 | ```
173 |
174 | ### Removing Reactions
175 |
176 | Reactions can be removed either by type or completely:
177 |
178 | #### Remove Specific Reaction Type
179 |
180 | ```php
181 | $user = User::find(1);
182 | $post = Post::find(1);
183 |
184 | // Remove specific reaction type
185 | $user->removeReaction('like', $post);
186 |
187 | // Or from the reactable side
188 | $post->removeReaction('like', $user);
189 | $post->removeReaction('like'); // For authenticated user
190 | ```
191 |
192 | #### Remove All Reactions
193 |
194 | ```php
195 | $user = User::find(1);
196 | $post = Post::find(1);
197 |
198 | // Remove all reactions by the user on this post
199 | $user->removeReactions($post);
200 |
201 | // Or from the reactable side
202 | $post->removeReactions($user);
203 | $post->removeReactions(); // For authenticated user
204 | ```
205 |
206 | ### Events
207 |
208 | | Event | Description |
209 | |--------------------------|---------------------------|
210 | | `StoreReactionEvent` | When store new reaction |
211 | | `RemoveReactionEvent` | When remove a reaction |
212 | | `RemoveAllReactionEvent` | When remove all reactions |
213 |
214 | ## Contributors
215 |
216 | Thanks to all the people who contributed. [Contributors](https://github.com/binafy/laravel-reactions/graphs/contributors).
217 |
218 |
219 |
220 | ## Security
221 |
222 | If you discover any security-related issues, please email `binafy23@gmail.com` instead of using the issue tracker.
223 |
224 | ## Changelog
225 |
226 | The changelog can be found in the `CHANGELOG.md` file of the GitHub repository.
227 |
228 | ## License
229 |
230 | The MIT License (MIT). Please see [License File](https://github.com/binafy/laravel-reactions/blob/1.x/LICENSE) for more information.
231 |
232 | ## Star History
233 |
234 | [](https://star-history.com/#binafy/laravel-reactions&Date)
235 |
236 | ## Donate
237 |
238 | If this package is helpful for you, you can buy a coffee for me :) ❤️
239 |
240 | - Iranian Gateway: https://daramet.com/milwad_khosravi
241 | - Paypal Gateway: SOON
242 | - MetaMask Address: `0xf208a562c5a93DEf8450b656c3dbc1d0a53BDE58`
243 |
--------------------------------------------------------------------------------