PHP code example of truefanspace / laravel-react-reactions
1. Go to this page and download the library: Download truefanspace/laravel-react-reactions library . Choose the download type require .
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
truefanspace / laravel-react-reactions example snippets
use TrueFans\LaravelReactReactions\Traits\HasReactions;
use TrueFans\LaravelReactReactions\Traits\HasComments;
class Post extends Model
{
use HasReactions, HasComments;
protected $appends = ['reactions_summary', 'user_reaction'];
public function canManageComment($comment): bool
{
// null = creating new comment, Comment instance = editing/deleting
if ($comment === null) {
return auth()->check(); // Anyone can comment
}
// Users can manage their own comments
return $comment->user_id === auth()->id();
}
}
use Illuminate\Support\Facades\DB;
class PostController extends Controller
{
public function index()
{
$userId = auth()->id();
// ✅ OPTIMIZED: Load all posts with reactions in 1 query
$posts = Post::withReactionsData($userId)
->latest()
->get()
->map(fn($post) => [
'id' => $post->id,
'title' => $post->title,
'reactions_summary' => $post->parseReactionsSummary(),
'user_reaction' => $post->parseUserReaction(),
]);
return Inertia::render('Posts/Index', ['posts' => $posts]);
}
public function show(Post $post)
{
$userId = auth()->id();
// ✅ OPTIMIZED: Load all comments with reactions efficiently
$postIds = [$post->id];
// Get comment counts in one query
$commentCounts = Comment::whereIn('commentable_id', $postIds)
->where('commentable_type', Post::class)
->whereNull('parent_id')
->select('commentable_id', DB::raw('count(*) as total'))
->groupBy('commentable_id')
->pluck('total', 'commentable_id');
// Load comments with replies in one query
$comments = Comment::where('commentable_id', $post->id)
->where('commentable_type', Post::class)
->whereNull('parent_id')
->with(['user:id,name,email', 'replies.user:id,name,email'])
->withCount('replies')
->latest()
->take(5)
->get()
->map(fn($comment) => [
'id' => $comment->id,
'content' => $comment->content,
'user' => $comment->user,
'user_id' => $comment->user_id,
'created_at' => $comment->created_at,
'is_edited' => $comment->is_edited,
'can_edit' => $userId === $comment->user_id,
'can_delete' => $userId === $comment->user_id,
'replies_count' => $comment->replies_count,
'replies' => $comment->replies->map(fn($reply) => [
'id' => $reply->id,
'content' => $reply->content,
'user' => $reply->user,
'user_id' => $reply->user_id,
'created_at' => $reply->created_at,
'is_edited' => $reply->is_edited,
'can_edit' => $userId === $reply->user_id,
'can_delete' => $userId === $reply->user_id,
]),
]);
return Inertia::render('Posts/Show', [
'post' => $post,
'comments' => $comments,
'total_comments' => $commentCounts->get($post->id, 0),
]);
}
}
class HandleInertiaRequests extends Middleware
{
public function share(Request $request): array
{
return [
...parent::share($request),
'auth' => [
'user' => $request->user(),
],
'flash' => [
'success' => fn() => $request->session()->get('success'),
'error' => fn() => $request->session()->get('error'),
],
// Share reaction types from config
'reactionTypes' => config('react-reactions.types', []),
];
}
}
// Loading 10 posts = 21 queries (1 + 10*2)
$posts = Post::latest()->get(); // Appended attributes cause N+1
// Loading 10 posts = 1 query
// Loading 1000 posts = still 1 query!
$posts = Post::withReactionsData(auth()->id())
->latest()
->get()
->map(fn($post) => [
'id' => $post->id,
'reactions_summary' => $post->parseReactionsSummary(),
'user_reaction' => $post->parseUserReaction(),
]);
$posts->map(function($post) {
$comments = $post->comments()->get(); // N+1 query
$totalComments = $post->comments()->count(); // Another N+1
});
$postIds = $posts->pluck('id');
// Get all comment counts in 1 query
$commentCounts = Comment::whereIn('commentable_id', $postIds)
->where('commentable_type', Post::class)
->whereNull('parent_id')
->select('commentable_id', DB::raw('count(*) as total'))
->groupBy('commentable_id')
->pluck('total', 'commentable_id');
// Load all comments with replies in 1 query
$allComments = Comment::whereIn('commentable_id', $postIds)
->where('commentable_type', Post::class)
->whereNull('parent_id')
->with(['user', 'replies.user'])
->withCount('replies')
->latest()
->get()
->groupBy('commentable_id');
return [
// Customize reaction types and emojis
'types' => [
'like' => '👍',
'adore' => '🥰', // You can change this to 'love' => '❤️'
'haha' => '😂',
'wow' => '😮',
'sad' => '😢',
'angry' => '😠',
// Add your own:
// 'fire' => '🔥',
// 'celebrate' => '🎉',
],
'comments' => [
'reactions_enabled' => true,
'max_depth' => 3,
'edit_timeout' => 300, // seconds
'per_page' => 10,
],
'notifications' => [
'enabled' => true,
'admin_email' => env('REACTIONS_ADMIN_EMAIL'),
'notify_owner' => true,
'notify_parent_author' => true,
],
];
public function share(Request $request): array
{
return [
...parent::share($request),
'reactionTypes' => config('react-reactions.types', []),
];
}
// Add or update reaction
$model->react(int $userId, string $type): void
// Remove reaction
$model->unreact(int $userId): void
// Get reactions summary
$model->reactionsSummary(): array
// Get user's reaction
$model->userReaction(int $userId): ?string
// Query scope for optimized loading
Model::withReactionsData(?int $userId)
// Parse reactions data (after withReactionsData)
$model->parseReactionsSummary(): array
$model->parseUserReaction(): ?string
// Add a comment
$model->addComment(int $userId, string $content): Comment
// Get comments relationship
$model->comments(): MorphMany
// Check permissions
$model->canManageComment(?Comment $comment): bool
// Add a reply
$comment->addReply(int $userId, string $content): Comment
// Get replies
$comment->replies(): HasMany
// Check permissions
$comment->canEdit(): bool
$comment->canDelete(): bool
// Query scope
Comment::topLevel() // Only top-level comments
bash
php artisan vendor:publish --provider="TrueFans\LaravelReactReactions\LaravelReactReactionsServiceProvider"
bash
# Publish and run migrations
php artisan vendor:publish --tag=react-reactions-migrations
php artisan migrate
# Publish React components (TypeScript)
php artisan vendor:publish --tag=react-reactions-components
# Publish configuration file
php artisan vendor:publish --tag=react-reactions-config
jsx
import Reactions from '@/Components/Reactions/Reactions';
import Comments from '@/Components/Comments/Comments';
export default function PostShow({ post, comments, total_comments }) {
return (
<div>
<h1>{post.title}</h1>
{/* Reactions */}
<Reactions
reactableType="App\\Models\\Post"
reactableId={post.id}
initialReactions={post.reactions_summary}
userReaction={post.user_reaction}
/>
{/* Comments */}
<Comments
commentableType="App\\Models\\Post"
commentableId={post.id}
initialComments={comments}
totalComments={total_comments}
currentUserId={auth.user.id}
/>
</div>
);
}