androsamp/filament-resource-lock
Install the package:
composer require androsamp/filament-resource-lock
php artisan filament-resource-lock:install
php artisan migrate
resource_lock and resource_lock_audits tables to your database.Add locking to your model:
use Androsamp\FilamentResourceLock\Concerns\HasResourceLocks;
class Customer extends Model
{
use HasResourceLocks;
}
Enable locking on your EditRecord page:
use Androsamp\FilamentResourceLock\Concerns\InteractsWithResourceLock;
class EditCustomer extends EditRecord
{
use InteractsWithResourceLock;
protected static string $resource = CustomerResource::class;
}
Display lock status in your table:
use Androsamp\FilamentResourceLock\Resources\Columns\ResourceLockColumn;
public static function table(Table $table): Table
{
return $table->columns([
ResourceLockColumn::make(),
// ... other columns
]);
}
Lock Acquisition:
EditRecord page, the package checks for existing locks.Heartbeat vs. Broadcast Modes:
ttl_seconds (configurable) to refresh the lock.'update_driver' => 'heartbeat',
'ttl_seconds' => 20, // Lock expires after 20 seconds of inactivity
wire:navigate.'update_driver' => 'broadcast',
'transports' => [
'broadcast' => [
'channel_prefix' => 'filament-resource-lock',
'event' => 'filament-resource-lock',
],
],
Collaboration Actions:
'permission' => [
'save_and_unlock' => [
'enabled' => true,
'permission' => 'filament-resource-lock.save_and_unlock',
],
'ask_to_unblock' => [
'enabled' => true,
'permission' => 'filament-resource-lock.ask_to_unblock',
],
],
Audit History Integration:
EditRecord page:
use Androsamp\FilamentResourceLock\Concerns\HasResourceAudit;
class EditProduct extends EditRecord
{
use InteractsWithResourceLock, HasResourceAudit;
protected function getHeaderActions(): array
{
return [
$this->getAuditHistoryAction(),
];
}
}
resource_lock_audits table and grouped by lock_cycle_id.Soft Release Handling:
release_grace_seconds (default: 3 seconds).'release_grace_seconds' => 3,
'stale_soft_release_ignore_seconds' => 5, // Ignore stale soft releases older than 5s
Custom Fields in Audit Diffs:
Extend the package to support custom fields by implementing HasAuditDiffPreview:
use Androsamp\FilamentResourceLock\Forms\Concerns\HasAuditDiffPreview;
class MapPicker extends Field
{
use HasAuditDiffPreview;
protected function setUp(): void
{
$this->auditDiffPreviewUsing(function (mixed $state): string {
return '<p class="text-sm">' . e($state['lat'] ?? '-') . ', ' . e($state['lng'] ?? '-') . '</p>';
});
}
}
Storage Backend:
Choose between database (default) or redis for lock storage:
'storage' => [
'driver' => 'redis', // or 'database'
],
Redis is faster for high-concurrency scenarios but requires Redis setup.
Localization:
Override translations in your resources/lang directory:
// config/filament-resource-lock.php
'localization' => [
'path' => resource_path('lang/vendor/filament-resource-lock'),
],
Testing:
Use the LockTestCase trait for unit/integration tests:
use Androsamp\FilamentResourceLock\Testing\LockTestCase;
class CustomerLockTest extends LockTestCase
{
protected function getModel(): string
{
return Customer::class;
}
}
Lock Expiration Issues:
ttl_seconds or release_grace_seconds.config/filament-resource-lock.php:
'ttl_seconds' => 30, // Increase for longer sessions
'release_grace_seconds' => 5, // Give more time for soft releases
Broadcast Mode Failures:
window.Echo in bootstrap.js).resources/js/filament-resource-lock/echo.js is published and aligned with your broker.telescope:install to monitor broadcast events.Audit Data Loss:
save() method in EditRecord that doesn’t call syncResourceAuditBeforeSave()/syncResourceAuditAfterSave().php artisan migrate).save() method includes audit hooks:
public function save(bool $shouldRedirect = true): void
{
$this->syncResourceAuditBeforeSave();
parent::save($shouldRedirect);
$this->syncResourceAuditAfterSave();
}
Permission Denied Errors:
config/filament-resource-lock.php or user lacks the policy.permission.enabled to true for the action.filament-resource-lock.save_and_unlock).Multiple Tabs Issue:
UniqueConstraintViolationException.v2.1.2+ (this was fixed in #12).Soft Release Not Working:
filament-resource-lock.release route isn’t reachable (e.g., APP_URL misconfigured).APP_URL is correct in .env.routes/web.php for signed routes).How can I help you explore Laravel packages today?