mpociot / teamwork
Laravel 5 框架的用户与团队关联
Requires
- php: ^8.0
- laravel/framework: ^9.0|^10.0|^11.0
Requires (Dev)
- doctrine/dbal: ^2.10|^3.5
- illuminate/database: ^9.0|^10.0|^11.0
- mockery/mockery: ^1.5.1
- orchestra/testbench: ^7.0|^8.0|^9.0
This package is auto-updated.
Last update: 2024-09-18 12:16:02 UTC
README
此包支持 Laravel 6 及以上版本。
Teamwork 是为 Laravel 6+ 项目添加用户/团队关联并带有邀请功能的最快、最简单的方法。
安装
composer require mpociot/teamwork
Teamwork
门面将由 Laravel 自动发现。
配置
要发布 Teamwork 的配置和迁移文件,请运行 vendor:publish
命令。
php artisan vendor:publish --provider="Mpociot\Teamwork\TeamworkServiceProvider"
这将创建一个 teamwork.php
文件在您的配置目录中。默认配置应该对您来说已经足够好,但如果您想自定义 Teamwork 将使用的表/模型名称,可以查看它。
用户与团队的关系
运行 migration
命令以生成 Teamwork 所需的所有表格。如果您将用户存储在除 users
之外的其他表中,请确保修改已发布的迁移。
php artisan migrate
迁移后,将创建 3 个新的表格
- teams — 存储团队记录
- team_user — 存储用户和团队之间的多对多关系
- team_invites — 存储电子邮件地址到团队的待处理邀请
您还会注意到,您的用户表中已添加了一个新列 current_team_id
。此列将定义用户当前分配到的团队。
模型
Team
在 app/Team.php
中创建一个 Team 模型,如下所示
<?php namespace App; use Mpociot\Teamwork\TeamworkTeam; class Team extends TeamworkTeam { }
Team
模型有两个主要属性
owner_id
— 指向拥有此团队的User
模型的引用。name
— 团队的人类可读名称。
owner_id
是一个可选属性,在数据库中可为空。
当扩展 TeamworkTeam 时,请记住在 config/teamwork.php
中将 team_model
变量更改为您的新模型。例如:'team_model' => App\Team::class
User
将 UserHasTeams
特性添加到您现有的 User 模型中
<?php namespace App; use Mpociot\Teamwork\Traits\UserHasTeams; class User extends Model { use UserHasTeams; // Add this trait to your model }
这将启用与 Team
的关系,并在您的 User
模型中添加以下方法:teams()
、ownedTeams()
、currentTeam()
、invites()
、isTeamOwner()
、isOwnerOfTeam($team)
、attachTeam($team, $pivotData = [])
、detachTeam($team)
、attachTeams($teams)
、detachTeams($teams)
、switchTeam($team)
。
别忘了运行 composer 自动加载
composer dump-autoload
中间件
如果您想使用中间件来保护当前团队的所有者,只需将中间件提供者添加到您的 app\Http\Kernel.php
文件中。
protected $routeMiddleware = [ ... 'teamowner' => \Mpociot\Teamwork\Middleware\TeamOwner::class, ... ];
之后,您可以在路由文件中使用 teamowner
中间件,如下所示。
Route::get('/owner', function(){ return "Owner of current team."; })->middleware('auth', 'teamowner');
现在只有当认证用户是当前团队的所有者时,才能访问该路由。
此中间件旨在保护只有团队所有者才能编辑/创建/删除该模型的路由
现在您可以开始了。
使用方法
脚手架
为您的 Laravel 项目添加 Team 功能的最简单方法是使用 make:teamwork
命令。
php artisan make:teamwork
此命令将创建所有视图、路由和控制器,使您的项目准备好使用团队功能。
开箱即用,以下部分将为您创建
- 团队列表
- 团队创建/编辑/删除
- 向团队邀请新成员
将其视为 Teamwork 的 make:auth
命令。
要开始,请查看您项目中的新安装的 /teams
路由。
基本概念
让我们从创建两个不同的团队开始。
$team = new Team(); $team->owner_id = User::where('username', '=', 'sebastian')->first()->getKey(); $team->name = 'My awesome team'; $team->save(); $myOtherCompany = new Team(); $myOtherCompany->owner_id = User::where('username', '=', 'marcel')->first()->getKey(); $myOtherCompany->name = 'My other awesome team'; $myOtherCompany->save();
多亏了 UserHasTeams
特性,将团队分配给用户变得超级简单
$user = User::where('username', '=', 'sebastian')->first(); // team attach alias $user->attachTeam($team, $pivotData); // First parameter can be a Team object, array, or id // or eloquent's original technique $user->teams()->attach($team->id); // id only
使用 attachTeam
方法,如果用户没有分配团队,则将自动设置 current_team_id
列。
或者,您还可以使用 UserHasTeams
特性中的 createOwnedTeam
方法。它将为用户创建团队作为所有者,将用户附加到团队并切换到新创建的团队。
// Create user owned team and switch the current team to this new team. $team = $user->createOwnedTeam(['name' => 'My awesome team']); // If user has another current team active, you should pass second parameter as true to force switch to the new team. $team = $user->createOwnedTeam(['name' => 'My awesome team'], true);
该函数将返回您团队模型的新实例。
了解我的团队(们)
用户当前分配的团队可以通过以下方式通过 currentTeam
关系访问
echo "I'm currently in team: " . Auth::user()->currentTeam->name; echo "The team owner is: " . Auth::user()->currentTeam->owner->username; echo "I also have these teams: "; print_r( Auth::user()->teams ); echo "I am the owner of these teams: "; print_r( Auth::user()->ownedTeams ); echo "My team has " . Auth::user()->currentTeam->users->count() . " users.";
Team
模型可以访问以下方法
invites()
— 返回与相关邀请的许多对多关系。users()
— 返回与所有关联到该团队的用户的许多对多关系。owner()
— 返回与拥有此团队的User
模型的单一对一关系。hasUser(User $user)
— 用于确定用户是否为团队成员的辅助函数
团队所有者
如果您需要检查用户是否是团队所有者(无论当前团队是什么),请在 User
模型上使用 isTeamOwner
方法。
if( Auth::user()->isTeamOwner() ) { echo "I'm a team owner. Please let me pay more."; }
此外,如果您需要检查用户是否是特定团队的所有者,请使用
$team = Auth::user()->currentTeam; if( Auth::user()->isOwnerOfTeam( $team ) ) { echo "I'm a specific team owner. Please let me pay even more."; }
isOwnerOfTeam
方法还允许将数组或 ID 作为团队参数。
切换当前团队
如果您的用户是多个团队的成员,您可能希望以某种方式给他们提供访问 切换团队
机制。
这意味着用户有一个“活动”团队,当前分配给用户。所有其他团队仍然保留在关系中!
很高兴我们有 UserHasTeams
特性。
try { Auth::user()->switchTeam( $team_id ); // Or remove a team association at all Auth::user()->switchTeam( null ); } catch( UserNotInTeamException $e ) { // Given team is not allowed for the user }
就像 isOwnerOfTeam
方法一样,switchTeam
也接受团队对象、数组、ID 或 null 作为参数。
邀请他人
如果您是唯一的团队成员,那么最好的团队也毫无用处。
要邀请其他用户加入您的团队,请使用 Teamwork
门面。
Teamwork::inviteToTeam( $email, $team, function( $invite ) { // Send email to user / let them know that they got invited });
您还可以通过提供一个具有 email
属性的对象来发送邀请
$user = Auth::user(); Teamwork::inviteToTeam( $user , $team, function( $invite ) { // Send email to user / let them know that they got invited });
此方法将创建一个 TeamInvite
模型,并通过可调用的第三个参数返回它。
此模型具有以下属性
email
— 被邀请的电子邮件。accept_token
— 用于接受邀请的唯一令牌。deny_token
— 用于拒绝邀请的唯一令牌。
除了这些属性外,该模型还具有以下关系
user()
— 使用email
作为User
模型上的唯一标识符的单一对一关系。team()
— 返回邀请所针对的团队。inviter()
— 返回创建邀请的用户。
注意: inviteToTeam
方法不会检查提供的电子邮件是否已有一个挂起的邀请。要检查挂起的邀请,请在 Teamwork
门面上使用 hasPendingInvite
方法。
示例用法
if( !Teamwork::hasPendingInvite( $request->email, $request->team) ) { Teamwork::inviteToTeam( $request->email, $request->team, function( $invite ) { // Send email to user }); } else { // Return error - user already invited }
接受邀请
一旦您邀请了其他用户加入您的团队,为了接受邀请,请再次使用 Teamwork
门面。
$invite = Teamwork::getInviteFromAcceptToken( $request->token ); // Returns a TeamworkInvite model or null if( $invite ) // valid token found { Teamwork::acceptInvite( $invite ); }
acceptInvite
方法做两件事
- 使用当前认证用户调用
attachTeam
与邀请团队。 - 之后删除邀请。
拒绝邀请
就像接受邀请一样
$invite = Teamwork::getInviteFromDenyToken( $request->token ); // Returns a TeamworkInvite model or null if( $invite ) // valid token found { Teamwork::denyInvite( $invite ); }
denyInvite
方法仅负责从数据库中删除邀请。
附加/分离/邀请事件
如果您需要在将团队从用户中附加/分离或邀请用户后运行其他进程,您可以监听这些事件
\Mpociot\Teamwork\Events\UserJoinedTeam \Mpociot\Teamwork\Events\UserLeftTeam \Mpociot\Teamwork\Events\UserInvitedToTeam
在您的 EventServiceProvider
中添加您的监听器(s)
/** * The event listener mappings for the application. * * @var array */ protected $listen = [ ... \Mpociot\Teamwork\Events\UserJoinedTeam::class => [ App\Listeners\YourJoinedTeamListener::class, ], \Mpociot\Teamwork\Events\UserLeftTeam::class => [ App\Listeners\YourLeftTeamListener::class, ], \Mpociot\Teamwork\Events\UserInvitedToTeam::class => [ App\Listeners\YourUserInvitedToTeamListener::class, ], ];
用户加入团队和用户离开团队事件公开了用户和团队的 ID。在您的监听器中,您可以像这样访问它们
<?php namespace App\Listeners; use Mpociot\Teamwork\Events\UserJoinedTeam; class YourJoinedTeamListener { /** * Create the event listener. * * @return void */ public function __construct() { // } /** * Handle the event. * * @param UserJoinedTeam $event * @return void */ public function handle(UserJoinedTeam $event) { // $user = $event->getUser(); // $teamId = $event->getTeamId(); // Do something with the user and team ID. } }
用户被邀请加入团队事件包含一个邀请对象,可以像这样访问
<?php namespace App\Listeners; use Mpociot\Teamwork\Events\UserInvitedToTeam; class YourUserInvitedToTeamListener { /** * Create the event listener. * * @return void */ public function __construct() { // } /** * Handle the event. * * @param UserInvitedToTeam $event * @return void */ public function handle(UserInvitedToTeam $event) { // $user = $event->getInvite()->user; // $teamId = $event->getTeamId(); // Do something with the user and team ID. } }
将模型限制为当前团队
如果您的模型以某种方式限制在当前团队,您将发现自己会反复编写此查询:Model::where('team_id', auth()->user()->currentTeam->id)->get();
。
为了自动化此过程,您可以让您的模型使用UsedByTeams
特性。此特性将自动将认证用户的当前团队ID追加到所有查询中,并在保存模型时将其添加到名为team_id
的字段。
注意
此假设模型有一个名为
team_id
的字段
使用方法
use Mpociot\Teamwork\Traits\UsedByTeams; class Task extends Model { use UsedByTeams; }
使用此特性时,所有查询将追加WHERE team_id=CURRENT_TEAM_ID
。如果您的应用中有需要检索所有模型,无论它们属于哪个团队的位置,您可以使用allTeams
作用域。
示例
// gets all tasks for the currently active team of the authenticated user Task::all(); // gets all tasks from all teams globally Task::allTeams()->get();
许可证
Teamwork是免费软件,根据MIT许可证条款分发。
《复仇者联盟》图片根据Creative Commons 2.0许可证授权 - 照片来自W_Minshull