Make Laravel Eloquent models read-only after they're locked. Prevents updates and deletes based on a "locked" attribute. Includes a trait and required interface to clearly define and enforce lockable models.
This package can be installed through Composer:
$ composer require testmonitor/eloquent-lockableNo need to publish anything — just use the trait and you’re good to go.
First, make sure to add a locked column to your model's table:
Schema::table('invoices', function (Blueprint $table) {
$table->boolean('locked')->default(false);
});Next, implement the Lockable trait and interface:
use Illuminate\Database\Eloquent\Model;
use TestMonitor\Lockable\Traits\Lockable;
use TestMonitor\Lockable\Contracts\IsLockable;
class Invoice extends Model implements IsLockable
{
use Lockable;
}That's it!
Now you can start locking and unlocking models:
$invoice->markLocked();
$invoice->markUnlocked();
$invoice->isLocked(); // true or falseTrying to update or delete a locked model will throw a ModelLockedException.
try {
$invoice->update(['amount' => 999]);
} catch (ModelLockedException $exception) {
$model = $exception->getModel();
}Temporarily lock or unlock a model using a callback:
$invoice->whileLocked(function ($model) {
// Model is locked inside this closure
});
$invoice->whileUnlocked(function ($model) {
// Temporarily unlocked
});These automatically restore the original lock state — even if an exception is thrown.
Convenient query scopes are provided to filter locked and unlocked models:
Invoice::locked()->get();
Invoice::unlocked()->get();These are local scopes and can be used just like any other Eloquent scope.
Want to use a different column like archived or readonly?
Override the getLockColumn() method in your model:
public function getLockColumn(): string
{
return 'archived';
}If you want to allow deletion of locked models, override the canDeleteWhenLocked() method in your model:
public function canDeleteWhenLocked(): bool
{
return true;
}Sometimes, you may want to allow certain attributes to be changed. To do this, override the getLockExceptions() method in your model:
public function getLockExceptions(): array
{
return ['note'];
}Only the attributes listed in getLockExceptions() may be modified while the model is locked.
The package contains integration tests. You can run them using PHPUnit.
$ vendor/bin/phpunit
Refer to CHANGELOG for more information.
Refer to CONTRIBUTING for contributing details.
The MIT License (MIT). Refer to the License for more information.