akira/laravel-followable

A lightweight and flexible Laravel package that adds follow/unfollow functionality to Eloquent models. With an intuitive API, it allows users to follow other users, track entities, and manage relationships effortlessly.

Fund package maintenance!
Akira

Installs: 569

Dependents: 0

Suggesters: 0

Security: 0

Stars: 10

Watchers: 1

Forks: 0

Open Issues: 0

pkg:composer/akira/laravel-followable

0.2.1 2025-12-22 23:44 UTC

README

Latest Version on Packagist Total Downloads PHPStan Level License

Laravel Followable is a lightweight and flexible Laravel package that adds follow/unfollow functionality to Eloquent models. With an intuitive API, it allows users to follow other users, track entities, and manage relationships effortlessly.

Features

  • Follow/Unfollow Any Model - Users can follow users, posts, channels, or any Eloquent model
  • Private Accounts - Built-in approval workflow for follow requests
  • Polymorphic Relationships - Follow different types of entities seamlessly
  • Query Scopes - Powerful scopes for filtering and ordering by followers
  • Events - Listen to Followed and UnFollowed events
  • Attach Follow Status - Efficiently add follow status to collections
  • Type-Safe - PHPStan Level 9 with 100% type coverage
  • Performance - Optimized queries with eager loading support
  • Well Tested - Comprehensive test suite with Pest PHP

Requirements

  • PHP 8.3+
  • Laravel 11.x or 12.x

Installation

Install the package via Composer:

composer require akira/laravel-followable

Publish and run the migrations:

php artisan vendor:publish --tag="followable-migrations"
php artisan migrate

Optionally, publish the configuration file:

php artisan vendor:publish --tag="followable-config"

Quick Start

1. Add Traits to Your Models

Add the Follower and Followable traits to your User model:

use Akira\Followable\Concerns\Followable;
use Akira\Followable\Concerns\Follower;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Followable, Follower;
}

2. Follow Users

$user = User::find(1);
$targetUser = User::find(2);

// Follow a user
$user->follow($targetUser);

// Unfollow a user
$user->unfollow($targetUser);

// Toggle follow
$user->toggleFollow($targetUser);

3. Check Follow Status

// Check if following
if ($user->isFollowing($targetUser)) {
    echo "You are following this user";
}

// Check if followed by
if ($targetUser->isFollowedBy($user)) {
    echo "This user follows you";
}

4. Get Followers and Following

// Get all followers
$followers = $user->followers;

// Get all following
$following = $user->followings;

// Count followers
$followersCount = $user->followers()->count();

// Get with pagination
$followers = $user->followers()->paginate(20);

Private Accounts & Approval Workflow

Enable follow request approval by overriding the needsToApproveFollowRequests() method:

class User extends Authenticatable
{
    use Followable, Follower;
    
    public function needsToApproveFollowRequests(): bool
    {
        return $this->is_private;
    }
}

Manage follow requests:

// Check if request is pending
if ($user->hasRequestedToFollow($privateUser)) {
    echo "Your follow request is pending approval";
}

// Accept a follow request
$privateUser->acceptFollowRequestFrom($user);

// Reject a follow request
$privateUser->rejectFollowRequestFrom($user);

// Get pending requests
$pendingFollowers = $user->notApprovedFollowers;

// Get approved followers
$approvedFollowers = $user->approvedFollowers;

Query Scopes

Order users by follower count:

// Most followed users
$popularUsers = User::orderByFollowersCountDesc()->take(10)->get();

// Least followed users
$newUsers = User::orderByFollowersCountAsc()->take(10)->get();

// With additional filters
$topActiveUsers = User::where('is_active', true)
    ->orderByFollowersCountDesc()
    ->paginate(20);

Events

Listen to follow/unfollow events:

use Akira\Followable\Events\Followed;
use Akira\Followable\Events\UnFollowed;

// In EventServiceProvider
protected $listen = [
    Followed::class => [
        SendFollowNotification::class,
    ],
    UnFollowed::class => [
        RemoveFollowNotification::class,
    ],
];

Attach Follow Status

Efficiently add follow status to collections:

$users = User::all();
auth()->user()->attachFollowStatus($users);

foreach ($users as $user) {
    if ($user->has_followed) {
        echo "Following since {$user->followed_at->diffForHumans()}";
    }
}

Documentation

Comprehensive documentation is available in the /docs directory:

View Full Documentation

Testing

Run the test suite:

composer test

Run specific tests:

# Code formatting
composer test:lint

# Static analysis
composer test:types

# Type coverage
composer test:type-coverage

# Unit tests with coverage
composer test:coverage

Configuration

The package can be configured via the config/followable.php file:

return [
    // Use UUIDs instead of auto-incrementing IDs
    'uuids' => false,

    // Custom user foreign key column name
    'user_foreign_key' => 'user_id',

    // Custom table name
    'followables_table' => 'followables',

    // Custom model class
    'followables_model' => \Akira\Followable\Followable::class,
];

Security

If you discover any security-related issues, please email kidiatoliny@akira-io.com instead of using the issue tracker.

Please see SECURITY.md for our security policy.

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for details on:

  • Development setup
  • Coding standards (PSR-12, PHPStan Level 9)
  • Testing requirements
  • Pull request process

Changelog

Please see CHANGELOG for more information on what has changed recently.

Credits

License

The MIT License (MIT). Please see License File for more information.