Releases: EloquentWorks/Fellowship
Release list
v1.0.0 — Initial Stable Release
Laravel Fellowship v1.0.0 🎉
The first stable release of Laravel Fellowship.
Laravel Fellowship provides a complete social-connection system for Laravel applications, including fellowship requests, accepted connections, blocking, mutual fellowships, request expiration, resend cooldowns, lifecycle events, configurable routes, and relationship-management helpers.
This release establishes the package's initial public API and provides a production-focused foundation for adding social relationships to Laravel applications.
✨ Features
- Send fellowship requests
- Accept incoming fellowship requests
- Deny incoming fellowship requests
- Cancel outgoing fellowship requests
- Remove accepted fellowships
- Block and unblock users
- Prevent requests between blocked users
- Retrieve accepted fellowships
- Retrieve incoming pending requests
- Retrieve outgoing pending requests
- Retrieve users blocked by the current user
- Retrieve users who blocked the current user
- Check fellowship status between two users
- Count accepted fellowships
- Find mutual fellowships
- Count mutual fellowships
- Configurable request expiration
- Configurable resend cooldowns
- Optional lifecycle events
- Configurable models and database tables
- Optional package-provided web routes
- Artisan installation and expiration commands
- Transactional relationship updates
- Laravel package auto-discovery
- PHPUnit, PHPStan, and formatting support
- Complete package documentation
🤝 Fellowship Requests
Users can send, accept, deny, and cancel fellowship requests through the HasFellowships trait.
use EloquentWorks\Fellowship\Traits\HasFellowships;
class User extends Authenticatable
{
use HasFellowships;
}Send a fellowship request:
$request = $user->sendFellowshipRequestTo($recipient);Accept an incoming request:
$recipient->acceptFellowshipRequestFrom($user);Deny an incoming request:
$recipient->denyFellowshipRequestFrom($user);Cancel an outgoing request:
$user->cancelFellowshipRequestTo($recipient);Laravel Fellowship prevents:
- Sending requests to yourself
- Duplicate active requests
- Requests between blocked users
- Re-sending requests during the configured cooldown
- Accepting expired requests
- Creating duplicate relationship pairs
✅ Accepted Fellowships
Retrieve a user's accepted fellowships:
$fellowships = $user->fellowships();Count accepted fellowships:
$count = $user->fellowshipsCount();Check whether two users are connected:
$user->isFellowWith($otherUser);Retrieve the relationship status:
$status = $user->fellowshipStatusWith($otherUser);Retrieve the underlying relationship record:
$fellowship = $user->fellowshipWith($otherUser);Remove an accepted fellowship:
$user->removeFellowship($otherUser);👥 Mutual Fellowships
Retrieve mutual fellowships shared by two users:
$mutual = $user->mutualFellowshipsWith($otherUser);Count mutual fellowships:
$count = $user->mutualFellowshipsCountWith($otherUser);These helpers are useful for:
- Social discovery
- Profile pages
- Suggested connections
- Shared-contact displays
- Community and collaboration features
🚫 Blocking
Block another user:
$user->blockUser($otherUser);Unblock a user:
$user->unblockUser($otherUser);Check block direction:
$user->hasBlocked($otherUser);
$user->isBlockedBy($otherUser);Retrieve blocked users:
$blocked = $user->blockedUsers();
$blockedBy = $user->blockedByUsers();Blocking prevents new fellowship requests until the blocking user removes the block.
⏳ Request Expiration
Pending fellowship requests expire automatically according to the configured lifetime:
'expires_after_days' => 30,Disable automatic expiration:
'expires_after_days' => null,Expired requests:
- Are excluded from active pending-request queries
- Cannot be accepted
- Can dispatch a lifecycle event
- Can be processed through the package command
Expire old requests manually:
php artisan fellowship:expireSchedule automatic cleanup:
use Illuminate\Console\Scheduling\Schedule;
protected function schedule(Schedule $schedule): void
{
$schedule->command('fellowship:expire')->daily();
}🔁 Request Cooldowns
Laravel Fellowship can prevent users from immediately re-sending a request after it has been denied, canceled, or expired.
'request_cooldown_days' => 7,Disable cooldown enforcement:
'request_cooldown_days' => null,Applications can check eligibility before presenting a request button:
$user->canSendFellowshipRequestTo($otherUser);📣 Lifecycle Events
Laravel Fellowship can dispatch events for important relationship changes.
Included events cover:
- Fellowship request sent
- Fellowship request accepted
- Fellowship request denied
- Fellowship request canceled
- Fellowship request expired
- Fellowship removed
- User blocked
- User unblocked
Events can power:
- Notifications
- Activity feeds
- Audit logs
- Analytics
- Queued jobs
- Application-specific integrations
Disable package event dispatching:
'dispatch_events' => false,🔒 Transactional Updates
Relationship-changing operations use database transactions and row locking where appropriate.
This protects workflows such as:
Validate relationship
→ Lock existing pair
→ Apply status change
→ Save relationship
→ Dispatch lifecycle event
The package also stores a deterministic pair key for each relationship pair, helping prevent duplicate records regardless of which user initiated the relationship.
🌐 Optional Web Routes
Laravel Fellowship does not force routes into the application automatically.
Register the bundled routes where needed:
use Illuminate\Support\Facades\Route;
Route::fellowship();Default route configuration:
'routes' => [
'prefix' => 'fellowship',
'middleware' => ['web', 'auth'],
'name' => 'fellowship.',
],Applications remain free to use:
- The bundled controller routes
- Custom controllers
- Livewire components
- Inertia actions
- JSON APIs
- Direct model methods
⚙️ Configuration
Publish the configuration file:
php artisan vendor:publish --tag=fellowship-configLaravel Fellowship supports configuration for:
- Fellowship model
- User model
- Users table
- Fellowships table
- Route prefix
- Route middleware
- Route-name prefix
- Route controller
- Request expiration
- Request cooldown
- Lifecycle-event dispatching
🗃️ Database
Publish the package migrations:
php artisan vendor:publish --tag=fellowship-migrationsRun migrations:
php artisan migrateThe relationship record stores information such as:
- Sender ID
- Recipient ID
- Deterministic pair key
- Relationship status
- Acceptance timestamp
- Expiration timestamp
- Creation and update timestamps
Supported lifecycle statuses include:
pending
accepted
denied
canceled
expired
blocked
🛠️ Installation Command
Install the package resources with:
php artisan fellowship:installRun migrations during installation:
php artisan fellowship:install --migrate🧪 Quality and Testing
Laravel Fellowship includes automated coverage for:
- Sending requests
- Duplicate-request prevention
- Accepting requests
- Denying requests
- Canceling requests
- Request expiration
- Resend cooldowns
- Removing fellowships
- Blocking and unblocking
- Block ownership
- Mutual fellowships
- Lifecycle events
- Event configuration
- Web-controller routes
- Artisan commands
- Route registration
- Service-provider behavior
The package includes scripts for:
composer format
composer format:test
composer analyse
composer test
composer quality📚 Documentation
The documentation includes dedicated guides for:
- Installation
- Configuration
- Usage
- API reference
- Routes
- Controller statuses
- Commands
- Events
- Database structure
- Customization
- Testing
- Upgrade guidance
- Frequently asked questions
Start with:
docs/README.md
✅ Supported Versions
- PHP 8.2 or newer
- Laravel 12
- Laravel 13
🚀 Installation
Install Laravel Fellowship through Composer:
composer require eloquent-works/fellowshipInstall package resources and run migrations:
php artisan fellowship:install --migrateAdd the trait to the application's authenticatable model:
use EloquentWorks\Fellowship\Traits\HasFellowships;
class User extends Authenticatable
{
use HasFellowships;
}🧰 Quality Checks
Before releasing or deploying, run:
composer validate --strict
composer audit
composer format:test
composer analyse
composer testOr run the complete package quality suite:
composer quality❤️ Thank You
Thank you for using Laravel Fellowship.
Feedback, bug reports, feature requests, documentation improvements, and pull requests are always welcome.