Fasáda Teams
Teams je vstupný bod pre všetko, čo balík robí. Práca s konkrétnym tímom ide cez Teams::for($team), ktorý vráti handle s jedným sub-accessorom pre každú oblasť; operácie naprieč tímami — prijatie pozvánky cez kód, upratovanie, slovník rolí a oprávnení — sú priamo na fasáde:
use RoundlyConsulting\Teams\DataTransferObjects\CreateTeamData;
use RoundlyConsulting\Teams\Facades\Teams;
// Create a team; the owner joins with the configured owner role.
$team = Teams::create(new CreateTeamData(name: 'Acme', owner: $owner));
// Members
Teams::for($team)->members()->add($alice, 'admin', expiresAt: now()->addYear());
Teams::for($team)->members()->changeRole($alice, 'editor'); // throws MemberNotFoundException for a non-member
Teams::for($team)->members()->remove($bob); // bool
Teams::for($team)->members()->all(); // Collection<Member>
Teams::for($team)->members()->has($alice); // bool
Teams::for($team)->members()->find($alice); // ?Member
// Invites
$invite = Teams::for($team)->invites()->create(role: 'member', email: '[email protected]', maxUses: 1);
Teams::for($team)->invites()->resend($invite); // rotate code, extend expiry
Teams::for($team)->invites()->revoke($invite); // bool
Teams::for($team)->invites()->pending(); // Collection<Invite>
Teams::invites()->accept($invite, $user, email: $user->email); // email must match an email-targeted invite
Teams::invites()->accept('the-code', $user); // a link invite (no email) by its code
// Join requests
$request = Teams::for($team)->joinRequests()->open($user, requestedRole: 'member', message: 'Hi');
Teams::for($team)->joinRequests()->approve($request, by: $admin, role: 'member');
Teams::for($team)->joinRequests()->deny($request, by: $admin);
Teams::for($team)->joinRequests()->pending(); // Collection<JoinRequest>
// Per-team roles, ownership, settings and the companion packages
Teams::for($team)->roles()->define('editor', 'Editor', ['posts.edit']);
Teams::for($team)->roles()->all(); // effective role map
Teams::for($team)->transferOwnershipTo($alice); // Team
Teams::for($team)->settings(); // TeamSettings (options package)
Teams::for($team)->contacts(); // ContactBook (contacts package)
Teams::for($team)->addresses(); // AddressBook (addresses package)
Teams::for($team)->connections(); // PendingConnection (connections package)
Teams::for($team)->team(); // the scoped Team model
// Global vocabulary and housekeeping
Teams::roles()->register('admin', 'Admin', ['*']);
Teams::permissions()->register('posts.publish', 'Publish posts', group: 'Content');
Teams::invites()->prune(); // int
Teams::members()->expiring(days: 7); // Collection<Member>, read-only
Teams::members()->notifyExpiring(days: 7); // fires MembershipExpiringSoon
Teams::members()->prune(); // int
Teams::joinRequests()->expire(); // int — auto-decline expired pending requestsMetódy fasády
| Metóda | Vracia | Poznámka |
|---|---|---|
create(CreateTeamData $data) | Team | Vlastníka pridá s rolou roles.owner. |
for(Team $team) | TeamHandle | Handle pre jeden tím — pozrite ďalšiu tabuľku. |
invites() | Invites | accept(), find(), prune() |
members() | Members | expiring(), notifyExpiring(), prune() |
joinRequests() | JoinRequests | expire() |
roles() | RoleProvider | Nastavený driver rolí: register(), find(), all(). |
permissions() | PermissionRegistry | register(), group(), find(), all(), fromRoles() |
fake() | TeamsFake | Zaznamenávajúci fake — pozrite Testovanie. |
Handle tímu
Teams::for($team) vráti TeamHandle. Každý zápis vracia svoj výsledok — Member, Invite, bool — nie handle, takže sa volania nereťazia:
| Teams::for($team)->… | Vracia | Poznámka |
|---|---|---|
members()->add($member, $role, $meta = [], $expiresAt = null) | Member | Idempotentné; obnoví odobraté či expirované členstvo; rešpektuje limit miest. |
members()->remove($member) | bool | Soft delete; pre nečlena false. |
members()->changeRole($member, $role) | Member | Pre nečlena vyhodí MemberNotFoundException. |
members()->all() / has($m) / find($m) | Collection / bool / ?Member | all() vráti aj expirované členstvá. |
invites()->create($role, $expiresAt, $email, $invitedBy, $meta, $maxUses = 1) | Invite | Pozrite Pozvánky. |
invites()->resend($invite) / revoke($invite) | Invite / bool | Pozvánku iného tímu odmietne. |
invites()->pending() | Collection<Invite> | Nevypršané pozvánky tímu. |
joinRequests()->open($requester, $requestedRole, $message, $meta, $expiresAt) | JoinRequest | Rešpektuje pravidlo vstupu; aktívnych členov odmietne; kým čaká, je idempotentné. |
joinRequests()->approve($request, by:, role:) / deny($request, by:) | Member / JoinRequest | Odmietne žiadosť iného tímu aj už vybavenú žiadosť. |
joinRequests()->requireApprovalFrom() / rule() / quorum() | nový handle | Pripraví schvaľovanie viacerými adminmi pre ďalšie open(). |
joinRequests()->pending() | Collection<JoinRequest> | |
roles()->define($key, $name, $permissions = [], $description = '') | TeamRole | Rola upravená pre tím, upsert podľa (tím, kľúč). |
roles()->all() / find($key) | array / ?Role | Globálne roly zlúčené s úpravami tohto tímu. |
transferOwnershipTo($owner) | Team | Všetko alebo nič; pôvodného vlastníka zníži na roles.admin. |
settings() | TeamSettings | Pozrite Nastavenia tímu. |
contacts() / addresses() / connections() | ContactBook / AddressBook / PendingConnection | Pozrite Integrácie. |
team() | Team | Samotný model tímu. |
Rozsah tímu ako bezpečnostná hranica
Handle z Teams::for($teamA) odmietne riadky, ktoré patria inému tímu, ešte predtým, než sa čokoľvek vykoná. Controller si tak môže vziať tím z routy a pozvánku či žiadosť zo vstupu používateľa bez ďalšej kontroly vlastníctva:
| Volanie s riadkom iného tímu | Vyhodí |
|---|---|
invites()->resend($invite) / revoke($invite) | InviteNotFoundException |
joinRequests()->approve($request, …) / deny($request, …) | JoinRequestNotFoundException |
members()->changeRole($nonMember, …) | MemberNotFoundException |
use RoundlyConsulting\Teams\Exceptions\InviteNotFoundException;
use RoundlyConsulting\Teams\Facades\Teams;
// The team comes from the route, the invite from user input — no extra ownership check.
try {
Teams::for($team)->invites()->revoke($invite);
} catch (InviteNotFoundException) {
// "Invite #42 does not belong to this team." — nothing ran, nothing was recorded
}Skratky na modeloch
Pomocné metódy modelov delegujú na ten istý manager, takže sa správajú — a Teams::fake() ich zaznamená — presne ako volania cez handle:
| Metóda modelu | To isté ako |
|---|---|
$team->addMember($m, $role, $meta, $expiresAt) | Teams::for($team)->members()->add(…) |
$team->removeMember($m) | Teams::for($team)->members()->remove($m) |
$team->invite($role, $expiresAt, $email, $invitedBy, $meta, $maxUses) | Teams::for($team)->invites()->create(…) |
$team->defineRole($key, $name, $permissions, $description) | Teams::for($team)->roles()->define(…) |
$team->roles() | Teams::for($team)->roles()->all() |
$invite->acceptBy($member, $email) | Teams::invites()->accept($invite, $member, $email) |
$invite->resend() / revoke() | Teams::for($invite->team)->invites()->resend/revoke($invite) |
$membership->removeFromTeam() | Teams::for($membership->team)->members()->remove(…) |
Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.