oliuz/teamwork
Composer 安装命令:
composer require oliuz/teamwork
包简介
User to Team associations for the Laravel Framework
README 文档
README
Teamwork is the fastest and easiest method to add a User / Team association with Invites to your Laravel project.
Contents
Installation
For Laravel ^8.0|^9.0
"oliuz/teamwork": "^9.0"
Add the version you need to your composer.json. Then run composer install or composer update.
(or run composer require oliuz/teamwork if you prefere that)
The Teamwork Facade will be installed automatically within the Service Provider.
Configuration
To publish Teamwork's configuration and migration files, run the vendor:publish command.
php artisan vendor:publish --provider="Mpociot\Teamwork\TeamworkServiceProvider"
This will create a teamwork.php in your config directory.
The default configuration should work just fine for you, but you can take a look at it, if you want to customize the table / model names Teamwork will use.
User relation to teams
Run the migration command, to generate all tables needed for Teamwork.
If your users are stored in a different table other than users be sure to modify the published migration.
php artisan migrate
After the migration, 3 new tables will be created:
- teams — stores team records
- team_user — stores many-to-many relations between users and teams
- team_invites — stores pending invites for email addresses to teams
You will also notice that a new column current_team_id has been added to your users table.
This column will define the Team, the user is currently assigned to.
Models
User
Add the UserHasTeams trait to your existing User model:
<?php namespace App; use Mpociot\Teamwork\Traits\UserHasTeams; class User extends Model { use UserHasTeams; // Add this trait to your model }
This will enable the relation with Team and add the following methods teams(), ownedTeams() currentTeam(), invites(), isTeamOwner(), isOwnerOfTeam($team), attachTeam($team, $pivotData = []), detachTeam($team), attachTeams($teams), detachTeams($teams), switchTeam($team), isOwnerAuth(), isOwnerAuthCheck() within your User model.
Don't forget to dump composer autoload
composer dump-autoload
Middleware
If you would like to use the middleware to protect to current team owner then just add the middleware provider to your app\Http\Kernel.php file.
protected $routeMiddleware = [ ... 'teamowner' => \Mpociot\Teamwork\Middleware\TeamOwner::class, ... ];
Afterwards you can use the teamowner middleware in your routes file like so.
Route::get('/owner', function(){ return "Owner of current team."; })->middleware('auth', 'teamowner');
Now only if the authenticated user is the owner of the current team can access that route.
This middleware is aimed to protect routes where only the owner of the team can edit/create/delete that model
And you are ready to go.
Usage
Scaffolding
The easiest way to give your new Laravel project Team abilities is by using the make:teamwork command.
php artisan make:teamwork
This command will create all views, routes, model and controllers to make your new project team-ready.
Out of the box, the following parts will be created for you:
- Team listing
- Team creation / editing / deletion
- Invite new members to teams
- Team model
Imagine it as a the make:auth command for Teamwork.
To get started, take a look at the new installed /teams route in your project.
Basic concepts
Let's start by creating two different 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();
Now thanks to the UserHasTeams trait, assigning the Teams to the user is uber easy:
$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
By using the attachTeam method, if the User has no Teams assigned, the current_team_id column will automatically be set.
Get to know my team(s)
The currently assigned Team of a user can be accessed through the currentTeam relation like this:
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.";
The Team model has access to these methods:
invites()— Returns a many-to-many relation to associated invitations.users()— Returns a many-to-many relation with all users associated to this team.owner()— Returns a one-to-one relation with the User model that owns this team.hasUser(User $user)— Helper function to determine if a user is a teammember
Team owner
If you need to check if the User is a team owner (regardless of the current team) use the isTeamOwner() method on the User model.
if( Auth::user()->isTeamOwner() ) { echo "I'm a team owner. Please let me pay more."; }
Additionally if you need to check if the user is the owner of a specific team, use:
$team = Auth::user()->currentTeam; if( Auth::user()->isOwnerOfTeam( $team ) ) { echo "I'm a specific team owner. Please let me pay even more."; }
The isOwnerOfTeam method also allows an array or id as team parameter.
Switching the current team
If your Users are members of multiple teams you might want to give them access to a switch team mechanic in some way.
This means that the user has one "active" team, that is currently assigned to the user. All other teams still remain attached to the relation!
Glad we have the UserHasTeams trait.
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 }
Just like the isOwnerOfTeam method, switchTeam accepts a Team object, array, id or null as a parameter.
Inviting others
The best team is of no avail if you're the only team member.
To invite other users to your teams, use the Teamwork facade.
Teamwork::inviteToTeam( $email, $team, function( $invite ) { // Send email to user / let them know that they got invited });
You can also send invites by providing an object with an email property like:
$user = Auth::user(); Teamwork::inviteToTeam( $user , $team, function( $invite ) { // Send email to user / let them know that they got invited });
This method will create a TeamInvite model and return it in the callable third parameter.
This model has these attributes:
email— The email that was invited.accept_token— Unique token used to accept the invite.deny_token— Unique token used to deny the invite.
In addition to these attributes, the model has these relations:
user()— one-to-one relation using theemailas a unique identifier on the User model.team()— one-to-one relation return the Team, that invite was aiming for.inviter()— one-to-one relation return the User, that created the invite.
Note:
The inviteToTeam method will not check if the given email already has a pending invite. To check for pending invites use the hasPendingInvite method on the Teamwork facade.
Example usage:
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 }
Accepting invites
Once you invited other users to join your team, in order to accept the invitation use the Teamwork facade once again.
$invite = Teamwork::getInviteFromAcceptToken( $request->token ); // Returns a TeamworkInvite model or null if( $invite ) // valid token found { Teamwork::acceptInvite( $invite ); }
The acceptInvite method does two thing:
- Call
attachTeamwith the invite-team on the currently authenticated user. - Delete the invitation afterwards.
Denying invites
Just like accepting invites:
$invite = Teamwork::getInviteFromDenyToken( $request->token ); // Returns a TeamworkInvite model or null if( $invite ) // valid token found { Teamwork::denyInvite( $invite ); }
The denyInvite method is only responsible for deleting the invitation from the database.
Attaching/Detaching/Invite Events
If you need to run additional processes after attaching/detaching a team from a user or inviting a user, you can Listen for these events:
\Mpociot\Teamwork\Events\UserJoinedTeam \Mpociot\Teamwork\Events\UserLeftTeam \Mpociot\Teamwork\Events\UserInvitedToTeam
In your EventServiceProvider add your listener(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, ], ];
The UserJoinedTeam and UserLeftTeam event exposes the User and Team's ID. In your listener, you can access them like so:
<?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. } }
The UserInvitedToTeam event contains an invite object which could be accessed like this:
<?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. } }
Limit Models to current Team
If your models are somehow limited to the current team you will find yourself writing this query over and over again: Model::where('team_id', auth()->user()->currentTeam->id)->get();.
To automate this process, you can let your models use the UsedByTeams trait. This trait will automatically append the current team id of the authenticated user to all queries and will also add it to a field called team_id when saving the models.
Note:
This assumes that the model has a field called
team_id
Usage
use Mpociot\Teamwork\Traits\UsedByTeams; class Task extends Model { use UsedByTeams; }
When using this trait, all queries will append WHERE team_id=CURRENT_TEAM_ID.
If theres a place in your app, where you really want to retrieve all models, no matter what team they belong to, you can use the allTeams scope.
Example:
// gets all tasks for the currently active team of the authenticated user Task::all(); // gets all tasks from all teams globally Task::allTeams()->get();
License
Teamwork is free software distributed under the terms of the MIT license.
'Marvel Avengers' image licensed under Creative Commons 2.0 - Photo from W_Minshull
oliuz/teamwork 适用场景与选型建议
oliuz/teamwork 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 14.5k 次下载、GitHub Stars 达 39, 最近一次更新时间为 2019 年 03 月 11 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「Invite」 「Teams」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 oliuz/teamwork 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 oliuz/teamwork 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 oliuz/teamwork 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A simple PHP package for sending messages to Microsoft Teams
Remove personal team forcing from Laravel Jetstream
Easy invite new users to your slack group
Enterprise invite-by-code, referral, rewards, waitlist & anti-abuse system for Laravel — multi-tenant, concurrency-safe, idempotent, GDPR-ready.
This package provides a flexible way to add Role-based Permissions to Laravel
Monolog handler for sending log messages to Microsoft Teams channels via Workflows.
统计信息
- 总下载量: 14.5k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 39
- 点击次数: 15
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2019-03-11