定制 offload-project/laravel-invite-only 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

offload-project/laravel-invite-only

最新稳定版本:v1.0.0

Composer 安装命令:

composer require offload-project/laravel-invite-only

包简介

A Laravel package for managing user invitations with polymorphic relationships, token-based access, scheduled reminders, and event-driven notifications.

README 文档

README

Latest Version on Packagist GitHub Tests Action Status Total Downloads

Laravel Invite Only

A Laravel package for managing user invitations with polymorphic relationships, token-based access, scheduled reminders, and event-driven notifications.

Features

  • Polymorphic invitations - Invite users to any model (teams, organizations, projects, etc.)
  • Token-based secure links - Shareable invitation URLs with secure tokens
  • Status tracking - Track pending, accepted, declined, expired, and cancelled invitations
  • Automatic reminders - Scheduled command to send reminder emails
  • Resend invitations - Easily resend invitation emails
  • Cancel with notification - Cancel invitations with optional email notification
  • Event-driven - Events fired for all invitation lifecycle changes
  • Configurable - Customize expiration, reminders, notifications, and routes

Requirements

  • PHP 8.4+
  • Laravel 11.0 or 12.0

Installation

composer require offload-project/laravel-invite-only

Publish the configuration and migrations:

php artisan vendor:publish --tag="invite-only-config"
php artisan vendor:publish --tag="invite-only-migrations"
php artisan migrate

Configuration

The configuration file config/invite-only.php allows you to customize:

return [
    // Database table name
    'table' => 'invitations',

    // User model for relationships
    'user_model' => App\Models\User::class,

    // Invitation expiration
    'expiration' => [
        'enabled' => true,
        'days' => 7,
    ],

    // Reminder settings
    'reminders' => [
        'enabled' => true,
        'after_days' => [3, 5],  // Send reminders after 3 and 5 days
        'max_reminders' => 2,
    ],

    // Custom notification classes
    'notifications' => [
        'invitation' => InvitationSent::class,
        'reminder' => InvitationReminder::class,
        'cancelled' => InvitationCancelledNotification::class,
        'accepted' => InvitationAcceptedNotification::class,
    ],

    // Route settings
    'routes' => [
        'enabled' => true,
        'prefix' => 'invitations',
        'middleware' => ['web'],
    ],

    // Redirect URLs after actions
    'redirect' => [
        'accepted' => '/',
        'declined' => '/',
        'expired' => '/',
    ],
];

Usage

Basic Usage with Facade

use OffloadProject\InviteOnly\Facades\InviteOnly;

// Create a standalone invitation
$invitation = InviteOnly::invite('user@example.com');

// Create an invitation for a specific model (team, organization, etc.)
$invitation = InviteOnly::invite('user@example.com', $team, [
    'role' => 'member',
    'metadata' => ['department' => 'Engineering'],
    'invited_by' => $currentUser,
]);

// Accept an invitation
$invitation = InviteOnly::accept($token, $user);

// Decline an invitation
$invitation = InviteOnly::decline($token);

// Cancel an invitation (with optional notification)
InviteOnly::cancel($invitation, notify: true);

// Resend an invitation
InviteOnly::resend($invitation);

// Find invitations
$invitation = InviteOnly::find($token);
$invitation = InviteOnly::findByEmail('user@example.com', $team);

// Query invitations
$pending = InviteOnly::pending($team);
$accepted = InviteOnly::accepted($team);
$expired = InviteOnly::expired();

Using Traits

HasInvitations Trait (for Team, Organization, etc.)

Add the HasInvitations trait to models that can have invitations:

use OffloadProject\InviteOnly\Traits\HasInvitations;

class Team extends Model
{
    use HasInvitations;
}

Then use the convenient methods:

// Invite a user to the team
$team->invite('user@example.com', [
    'role' => 'admin',
    'invited_by' => $currentUser,
]);

// Get pending invitations
$pending = $team->pendingInvitations();

// Get accepted invitations
$accepted = $team->acceptedInvitations();

// Check if email has pending invitation
if ($team->hasInvitationFor('user@example.com')) {
    // ...
}

// Cancel invitation by email
$team->cancelInvitation('user@example.com', notify: true);

// Resend invitation
$team->resendInvitation('user@example.com');

// Get invitation statistics
$stats = $team->getInvitationStats();
// ['total' => 10, 'pending' => 3, 'accepted' => 5, 'declined' => 1, 'expired' => 1, 'cancelled' => 0]

CanBeInvited Trait (for User model)

Add the CanBeInvited trait to your User model:

use OffloadProject\InviteOnly\Traits\CanBeInvited;

class User extends Authenticatable
{
    use CanBeInvited;
}

Then use the convenient methods:

// Get all invitations received by this user's email
$invitations = $user->receivedInvitations;

// Get invitations this user has accepted
$accepted = $user->acceptedInvitations;

// Get invitations sent by this user
$sent = $user->sentInvitations;

// Accept an invitation
$invitation = $user->acceptInvitation($token);

// Decline an invitation
$invitation = $user->declineInvitation($token);

// Check for pending invitations
if ($user->hasPendingInvitation($team)) {
    // ...
}

// Get all pending invitations
$pending = $user->getPendingInvitations();

Scheduled Reminders

Add the reminder command to your scheduler in routes/console.php:

use Illuminate\Support\Facades\Schedule;

Schedule::command('invite-only:send-reminders --mark-expired')->daily();

This will:

  • Send reminder emails based on your reminders.after_days configuration
  • Optionally mark expired invitations when using --mark-expired

Events

The package fires events for all invitation lifecycle changes:

Event Payload Description
InvitationCreated $invitation When a new invitation is created
InvitationAccepted $invitation, $user When an invitation is accepted
InvitationDeclined $invitation When an invitation is declined
InvitationCancelled $invitation When an invitation is cancelled
InvitationExpired $invitation When an invitation is marked as expired

Listen to these events in your EventServiceProvider:

use OffloadProject\InviteOnly\Events\InvitationAccepted;

protected $listen = [
    InvitationAccepted::class => [
        AddUserToTeamListener::class,
    ],
];

Custom Notifications

You can customize notifications by extending the default classes or creating your own:

// config/invite-only.php
'notifications' => [
    'invitation' => App\Notifications\CustomInvitationNotification::class,
    // ...
],

Set a notification to null to disable it:

'notifications' => [
    'reminder' => null,  // Disable reminder notifications
],

Routes

The package registers the following routes by default:

Method URI Name Description
GET /invitations/{token} invitations.show View/redirect invitation
POST /invitations/{token}/accept invitations.accept Accept invitation
POST /invitations/{token}/decline invitations.decline Decline invitation

You can disable automatic route registration and define your own:

// config/invite-only.php
'routes' => [
    'enabled' => false,
],

Invitation Model

The Invitation model provides many helpful methods:

// Status checks
$invitation->isPending();
$invitation->isAccepted();
$invitation->isDeclined();
$invitation->isExpired();
$invitation->isCancelled();
$invitation->isValid();  // pending AND not expired

// Get URLs
$invitation->getAcceptUrl();
$invitation->getDeclineUrl();

// Relationships
$invitation->invitable;      // The model being invited to (Team, etc.)
$invitation->inviter;        // User who sent the invitation
$invitation->acceptedByUser; // User who accepted

// Query scopes
Invitation::pending()->get();
Invitation::accepted()->get();
Invitation::valid()->get();
Invitation::forEmail('user@example.com')->get();
Invitation::forInvitable($team)->get();

Testing

composer test

Static Analysis

composer analyse

Code Style

composer pint

License

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

统计信息

  • 总下载量: 250
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 1
  • 依赖项目数: 2
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-12-28