whilesmart / eloquent-shareables
Manage shareables
Package info
github.com/whilesmartphp/eloquent-shareables
pkg:composer/whilesmart/eloquent-shareables
Requires
- php: ^8.4
- laravel/framework: ^12.0
Requires (Dev)
- fakerphp/faker: ^1.24
- larastan/larastan: ^3.0
- laravel/pint: ^1.22
- nunomaduro/collision: ^8.8
- orchestra/testbench: ^10.4
- phpmd/phpmd: @stable
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^11.0
- squizlabs/php_codesniffer: ^4.0
- zircote/swagger-php: ^5.1
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-11-03 11:07:07 UTC
README
Share Eloquent resources with users, teams or other model-based audiences. One link can grant different abilities to different recipients. Applications define membership and interpret ability names.
Requires PHP 8.4 and Laravel 12.
Installation
composer require whilesmart/eloquent-shareables:^2.0 php artisan migrate
Migrations load automatically. Publishing them is optional. Publish configuration when customizing models:
php artisan vendor:publish --tag=shareables-config
Recipient admission
Recipient models implement ShareAudience. Add ReceivesShares to remove their audience rows when they are permanently deleted.
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Foundation\Auth\User as AuthenticatableUser; use Whilesmart\Shareables\Contracts\ShareAudience; use Whilesmart\Shareables\Traits\ReceivesShares; class User extends AuthenticatableUser implements ShareAudience { use ReceivesShares; public function admits(?Authenticatable $viewer): bool { return $viewer instanceof self && $this->is($viewer); } }
A team or workspace implements the same contract using its current membership rules. The package does not assume a membership table or role hierarchy.
Resource sharing
Add Whilesmart\Shareables\Traits\Shareable to the resource model, then create a link:
$share = $document->share([$alice, $team], 'reader', createdBy: $alice); $share->setAudience($alice, 'editor'); $abilities = Share::resolveToken($share->token, $viewer);
resolveToken returns every distinct ability admitted by matching audiences. It does not rank abilities. A viewer matching both a user and team audience receives both abilities.
An empty audience list grants nobody access. Public access requires an explicit null audience:
$private = $document->share([], 'reader'); $public = $document->share(null, 'reader');
Removing the final audience makes a link private. It never makes it public.
Link constraints
$share = $document->share($team, 'reader', createdBy: $alice, constraints: [ 'expires_at' => now()->addDay(), 'password' => 'a-passphrase-chosen-by-the-user', 'max_uses' => 10, ]); $abilities = Share::resolveToken($share->token, $viewer, $providedPassword);
Passwords are hashed and hidden from serialization. Token resolution checks expiry, revocation, password and current recipient admission. A successful resolution consumes one use; rejected resolutions consume none. The use limit is checked while locking the link inside a database transaction.
Queries and revocation
$documents = Document::sharedWith($team, 'reader')->get(); $shared = $document->isSharedWith($team, 'reader'); $sharedViaLink = $document->isSharedViaToken($token, $viewer, 'reader', $password); $document->revokeShare($team); $document->revokeAllShares();
Audience queries include active, unprotected links only. They select grants for an audience; the application must authorize the caller's access to that audience. Use token resolution when checking password-protected links or consuming a use allowance.
Revoking an audience keeps other recipients on the same link. Soft-deleting a resource revokes its links, and restoring it does not restore access. Permanently deleting it removes links and their audience rows. Enable foreign keys when using SQLite so audience cleanup cascades.
Host model customization
config/shareables.php allows subclasses of Share and Audience:
'models' => [ 'share' => App\Models\Share::class, 'audience' => App\Models\ShareAudience::class, ],
The configured models use the package's columns and relations. Application-specific membership, authorization, response formatting and financial calculations remain with the host application.
Development
composer test
composer phpcs:test
composer phpmd
composer phpstan
composer pint:test
The package is MIT licensed. See LICENSE.