Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Resource Lock Laravel Package

androsamp/filament-resource-lock

View on GitHub
Deep Wiki
Context7

Getting Started

To begin using androsamp/filament-resource-lock, follow these minimal steps:

  1. Install the Package

    composer require androsamp/filament-resource-lock
    php artisan filament-resource-lock:install
    php artisan migrate
    

    This publishes the config, migrations, and assets, and injects the Echo script into your bootstrap.js.

  2. Enable Locking on a Model Add the HasResourceLocks trait to your Eloquent model:

    use Androsamp\FilamentResourceLock\Concerns\HasResourceLocks;
    
    class Customer extends Model
    {
        use HasResourceLocks;
    }
    
  3. Integrate Locking into an Edit Page Add the InteractsWithResourceLock trait to your EditRecord page:

    use Androsamp\FilamentResourceLock\Concerns\InteractsWithResourceLock;
    
    class EditCustomer extends EditRecord
    {
        use InteractsWithResourceLock;
    }
    
  4. Display Lock Status in Tables Add the ResourceLockColumn to your table columns:

    use Androsamp\FilamentResourceLock\Resources\Columns\ResourceLockColumn;
    
    public static function table(Table $table): Table
    {
        return $table->columns([
            ResourceLockColumn::make(),
            // ... other columns
        ]);
    }
    

First Use Case: Test locking by opening a record in two browser tabs. The second tab should show a lock indicator and disable form actions until the lock is released.


Implementation Patterns

Core Workflow

  1. Lock Acquisition When a user opens an EditRecord page, the package automatically attempts to acquire a lock on the record. If another user holds the lock, the UI shows the lock owner and disables form actions.

  2. Lock Management

    • Heartbeat Mode (Default): Uses Livewire’s polling to refresh the lock every ttl_seconds (configurable).
    • Broadcast Mode: Uses Laravel Echo to push lock updates in real-time. Requires configuring Laravel broadcasting (e.g., Pusher, Reverb) and setting 'update_driver' => 'broadcast' in the config.
  3. Collaboration Actions

    • Request Unlock: If enabled in config (permission.ask_to_unblock), a locked-out user can request the lock owner to release it.
    • Save and Unlock: If enabled, the lock owner can save changes and release the lock in one action.
  4. Audit History (Optional) Enable auditing in the config (audit.enabled = true) to track changes. Add the HasResourceAudit trait to your EditRecord page and include the audit action in getHeaderActions():

    use Androsamp\FilamentResourceLock\Concerns\HasResourceAudit;
    
    class EditProduct extends EditRecord
    {
        use InteractsWithResourceLock, HasResourceAudit;
    
        protected function getHeaderActions(): array
        {
            return [
                $this->getAuditHistoryAction(),
                // ... other actions
            ];
        }
    }
    

Integration Tips

  • Custom Fields in Audit Diffs Extend the HasAuditDiffPreview trait for custom fields to render diffs properly:

    use Androsamp\FilamentResourceLock\Forms\Concerns\HasAuditDiffPreview;
    
    class CustomField extends Field
    {
        use HasAuditDiffPreview;
    
        protected function setUp(): void
        {
            $this->auditDiffPreviewUsing(function ($state) {
                return '<p class="text-sm">' . e($state) . '</p>';
            });
        }
    }
    
  • Override save() for Audit Compatibility If you override save() in your EditRecord page, ensure you call the audit sync methods:

    public function save(bool $shouldRedirect = true): void
    {
        $this->syncResourceAuditBeforeSave();
        parent::save($shouldRedirect);
        $this->syncResourceAuditAfterSave();
    }
    
  • Broadcast Configuration For broadcast mode, ensure your bootstrap.js includes the Echo script published by the package and configure Laravel’s broadcasting driver (e.g., Reverb, Pusher). Update the config:

    'update_driver' => 'broadcast',
    'transports' => [
        'broadcast' => [
            'channel_prefix' => 'filament-resource-lock',
            'event' => 'filament-resource-lock-updated',
            'renew_interval_seconds' => 5,
        ],
    ],
    
  • Permissions Customize permissions in the config to control who can request unlocks or save-and-unlock:

    'permission' => [
        'save_and_unlock' => [
            'enabled' => true,
            'permission' => 'custom.permission.save_and_unlock',
        ],
        'ask_to_unblock' => [
            'enabled' => false, // Disable if not needed
        ],
    ],
    
  • Soft Release Route The package registers a signed route (filament-resource-lock.release) for handling lock release during tab closure. Ensure APP_URL is correctly set to avoid validation issues.


Gotchas and Tips

Pitfalls

  1. Overriding save() Without Audit Sync If you override the save() method in your EditRecord page without calling syncResourceAuditBeforeSave() and syncResourceAuditAfterSave(), audit history will not work. Always wrap your custom save logic with these calls:

    public function save(): void
    {
        $this->syncResourceAuditBeforeSave();
        // Custom save logic here
        $this->syncResourceAuditAfterSave();
    }
    
  2. Broadcast Mode Without Echo Setup If you enable broadcast mode ('update_driver' => 'broadcast') but forget to configure Laravel broadcasting (e.g., missing .env settings for BROADCAST_DRIVER) or publish the Echo script, lock updates will fail silently. Verify:

    • Laravel broadcasting is properly configured (e.g., Reverb/Pusher).
    • The Echo script (resources/js/filament-resource-lock/echo.js) is included in your bootstrap.js.
    • The window.Echo object is available globally.
  3. Lock TTL Too Short If ttl_seconds in the config is too short (e.g., < 10), users may experience frequent lock expirations during editing, leading to frustration. Test with a value like 30 for interactive workflows.

  4. Audit Table Bloat The audit feature stores snapshots of record states. If max_entries_per_resource is set too high (or omitted), the resource_lock_audits table may grow uncontrollably. Monitor table size and adjust the limit:

    'audit' => [
        'max_entries_per_resource' => 100, // Limit to 100 entries per resource
    ],
    
  5. Permission Policy Conflicts If you define custom permissions (e.g., 'permission' => 'custom.save_and_unlock') but the user lacks the corresponding gate/policy, the action will be disabled. Test permissions thoroughly:

    Gate::define('custom.save_and_unlock', function ($user) {
        return $user->can('manage_customers');
    });
    
  6. Soft Release Route Issues The signed route (filament-resource-lock.release) may fail if APP_URL is misconfigured (e.g., http vs https, or incorrect domain). Test the route manually:

    php artisan route:list | grep "filament-resource-lock.release"
    

    Ensure the URL generated by the route matches your app’s base URL.

  7. Livewire Heartbeat Conflicts If you’re using other Livewire components with custom heartbeat intervals, conflicts may arise. Ensure the package’s heartbeat (default: every 10 seconds) aligns with your app’s needs. Adjust in the config:

    'heartbeat_interval_seconds' => 15,
    

Debugging Tips

  1. Check Lock Status Inspect the resource_locks table directly to verify lock records:

    SELECT * FROM resource_locks WHERE resource_id = [ID];
    

    Look for locked_at, expires_at, and user_id fields.

  2. Enable Broadcast Logging For broadcast mode, enable Laravel Echo logging to debug connection issues:

    'logging' => [
        'enabled' => true,
        'channel' => 'private-filament-resource-lock',
    ],
    

    Check Laravel logs for Echo events like filament-resource-lock-updated.

  3. Audit Diff Rendering If custom field diffs don’t render, verify the auditDiffPreviewUsing callback returns valid HTML. Use browser dev tools to inspect the rendered diff modal.

  4. Permission Debugging Use Laravel’s authorize() method to debug permission issues:

    if (auth()->user()->can('filament-resource-lock.save_and_unlock')) {
        // Action allowed
    }
    
  5. Soft Release Grace Period If locks aren’t releasing properly on tab close, adjust `release

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui