Installation:
composer require lowerrocklabs/laravel-lockable
Publish the migration (if needed):
php artisan vendor:publish --provider="LowerRockLabs\Lockable\LockableServiceProvider" --tag="migrations"
php artisan migrate
Apply the Trait:
Use the Lockable trait in your Eloquent model:
use LowerRockLabs\Lockable\Traits\Lockable;
class User extends Model
{
use Lockable;
}
First Use Case: Lock/unlock a model instance:
$user = User::find(1);
$user->lock(); // Locks the user
$user->unlock(); // Unlocks the user
Check Lock Status:
if ($user->isLocked()) {
// Handle locked state
}
Locking Logic Integration:
lock()/unlock() in business logic (e.g., admin actions, sensitive operations).$user->lock();
try {
$user->update($request->all());
} finally {
$user->unlock();
}
Permission Integration:
public function update(UpdateUserRequest $request, User $user)
{
if ($user->isLocked()) {
abort(403, 'User is locked');
}
// Proceed with update
}
Query Scoping:
$lockedUsers = User::locked()->get();
$unlockedUsers = User::unlocked()->get();
Soft Locking (Optional):
is_soft_locked column) via a custom trait:
trait SoftLockable {
public function softLock() { /* ... */ }
}
Event-Based Locking:
$user->lock(); // Dispatches `Locking` event
$user->unlock(); // Dispatches `Unlocking` event
EventServiceProvider:
protected $listen = [
'LowerRockLabs\Lockable\Events\Locking' => [
'App\Listeners\LogLockAction',
],
];
Lock Expiry:
locked_at column and auto-unlock logic:
// In a queue job or scheduled task
User::where('locked_at', '<', now()->subHours(1))
->update(['locked_at' => null]);
Multi-Tenant Locking:
$tenantUser = Tenant::find(1)->users()->locked()->get();
Race Conditions:
DB::transaction(function () use ($user) {
$user->lock();
// Critical operations
$user->unlock();
});
Missing Migration:
locked_at column is missing, the trait will throw ColumnNotFoundException. Run migrations first.Caching Issues:
fresh():
$user = User::find(1)->fresh(); // Ensures latest lock status
Over-Permissive Locking:
User::all()->lock()). Use targeted locking.Check Lock Status:
locked_at column in the database:
SELECT locked_at FROM users WHERE id = 1;
Event Debugging:
event(new \LowerRockLabs\Lockable\Events\Locking(User::find(1)));
Query Logging:
\DB::enableQueryLog();
User::locked()->get();
\DB::getQueryLog();
Custom Lock Logic:
lock()/unlock() in your model:
public function lock()
{
$this->locked_at = now()->addHours(2); // Custom expiry
$this->save();
}
Additional Lock Types:
lock_reason):
protected $lockMetadata = ['reason' => null];
public function lock(string $reason = null)
{
$this->lockMetadata['reason'] = $reason;
$this->locked_at = now();
$this->save();
}
API Responses:
return UserResource::make($user)->additional([
'is_locked' => $user->isLocked(),
]);
Livewire Integration:
public function updatedLockStatus()
{
$this->emit('lockStatusChanged', $this->model->isLocked());
}
How can I help you explore Laravel packages today?