A Laravel package to handle ownership relationships between Eloquent models. This package provides a simple and flexible way to manage ownership of any model by any other model in your Laravel application.
- Flexible Ownership: Any model can own any other model
- Ownership Transfer: Transfer ownership between different owners
- Ownership History: Keep track of ownership changes over time
- Current Owner: Easily retrieve the current owner of any ownable item
- Bulk Operations: Check ownership status and manage multiple ownables
- Automatic Cleanup: Automatically clean up ownership records when models are deleted
- Facade Support: Use the convenient Owner facade for ownership operations
- PHP ^8.0
- Laravel ^9.0, ^10.0, ^11.0 or ^12.0
Require the package via Composer:
composer require sowailem/ownable
Publish the migration:
php artisan vendor:publish --provider="Sowailem\Ownable\OwnableServiceProvider" --tag="ownable-migrations"
Run the migration:
php artisan migrate
use Sowailem\Ownable\Traits\HasOwnables;
use Sowailem\Ownable\Traits\IsOwnable;
use Sowailem\Ownable\Contracts\Ownable as OwnableContract;
// Owner model (e.g., User)
class User extends Authenticatable implements OwnerContract
{
use HasOwnables;
}
// Ownable model
class Post extends Model implements OwnableContract
{
use IsOwnable;
}
$user = User::first();
$post = Post::first();
// Give ownership
$user->giveOwnershipTo($post);
// Or
$post->ownedBy($user);
// Or using facade
Owner::give($user, $post);
// Check ownership
if ($user->owns($post)) {
// User owns this post
}
// Or
if ($post->isOwnedBy($user)) {
// Post is owned by this user
}
// Or using facade
if (Owner::check($user, $post)) {
// Check ownership using facade
}
// Transfer ownership
$newOwner = User::find(2);
$user->transferOwnership($post, $newOwner);
// Or
$post->transferOwnershipTo($newOwner);
// Or using facade
Owner::transfer($user, $newOwner, $post);
// Get all owned items
$user->ownables()->get();
// Get current owner of an item
$currentOwner = $post->currentOwner();
// Get all owners (including historical)
$allOwners = $post->owners()->get();
// Get only current owners
$currentOwners = $post->owners()->wherePivot('is_current', true)->get();
// Remove ownership
$user->takeOwnershipFrom($post);
Methods available on owner models:
possessions()
- Relationship to ownership recordsownables()
- Relationship to owned itemsowns($ownable)
- Check if owns a specific itemgiveOwnershipTo($ownable)
- Give ownership of an itemtakeOwnershipFrom($ownable)
- Remove ownership of an itemtransferOwnership($ownable, $newOwner)
- Transfer ownership to another owner
Methods available on ownable models:
ownerships()
- Relationship to ownership recordsowners()
- Relationship to ownerscurrentOwner()
- Get the current ownerownedBy($owner)
- Set ownership to a specific ownerisOwnedBy($owner)
- Check if owned by a specific ownertransferOwnershipTo($newOwner)
- Transfer ownership to a new owner
Static methods available via the Owner facade:
Owner::give($owner, $ownable)
- Give ownershipOwner::check($owner, $ownable)
- Check ownershipOwner::transfer($fromOwner, $toOwner, $ownable)
- Transfer ownership
You can publish the configuration file to customize the package behavior:
php artisan vendor:publish --provider="Sowailem\Ownable\OwnableServiceProvider" --tag="ownable-config"
The configuration allows you to customize:
- Default owner model class
- Default ownable model class
- Database table name
The package creates an ownerships
table with the following structure:
id
- Primary keyowner_id
- ID of the owner modelowner_type
- Class name of the owner modelownable_id
- ID of the ownable modelownable_type
- Class name of the ownable modelis_current
- Boolean flag indicating if this is the current ownershipcreated_at
- Timestamp when ownership was createdupdated_at
- Timestamp when ownership was last updated
composer test
Please see CONTRIBUTING for details.
If you discover any security related issues, please email abdullah.sowailem@email.com instead of using the issue tracker.
The MIT License (MIT). Please see License File for more information.