PHPackages                             blendbyte/filament-resource-lock - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. blendbyte/filament-resource-lock

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

blendbyte/filament-resource-lock
================================

Filament Resource Lock is a Filament plugin that adds resource locking functionality to your site.

v2.2.0(1mo ago)61.8k↑388.6%2MITPHPPHP ^8.2CI passing

Since Mar 24Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/blendbyte/filament-resource-lock)[ Packagist](https://packagist.org/packages/blendbyte/filament-resource-lock)[ Docs](https://github.com/blendbyte/filament-resource-lock)[ RSS](/packages/blendbyte-filament-resource-lock/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (7)Dependencies (26)Versions (8)Used By (0)

[![Resource Lock](filament-resource-lock-marketing.jpg)](filament-resource-lock-marketing.jpg)

Resource Lock
=============

[](#resource-lock)

[![Latest Version on Packagist](https://camo.githubusercontent.com/db1ed3a7865cc1a594f66e2332b73b4a9beefbc4ec579ffc0ee16e4b41ed7f65/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f626c656e64627974652f66696c616d656e742d7265736f757263652d6c6f636b2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/blendbyte/filament-resource-lock)[![Tests](https://github.com/blendbyte/filament-resource-lock/actions/workflows/tests.yml/badge.svg)](https://github.com/blendbyte/filament-resource-lock/actions/workflows/tests.yml)[![Static Analysis](https://github.com/blendbyte/filament-resource-lock/actions/workflows/static-analysis.yml/badge.svg)](https://github.com/blendbyte/filament-resource-lock/actions/workflows/static-analysis.yml)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE.md)

Filament Resource Lock is a Filament plugin that adds resource locking functionality to your site. When a user begins editing a resource, it is automatically locked to prevent other users from editing it at the same time. The resource will be automatically unlocked after a set period of time, or when the user saves or discards their changes.

> **Note:** This package is a fork of [kenepa/resource-lock](https://github.com/kenepa/resource-lock), updated for **Filament v5** compatibility. If you are currently using `kenepa/resource-lock`, see the [migration guide](#migrating-from-keneparesource-lock) below.

Installation
------------

[](#installation)

```
composer require blendbyte/filament-resource-lock
```

Then run the installation command to publish and run the migration:

```
php artisan filament-resource-lock:install
```

Register the plugin with a panel:

```
use Blendbyte\FilamentResourceLock\ResourceLockPlugin;
use Filament\Panel;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->plugin(ResourceLockPlugin::make());
}
```

Quick Start
-----------

[](#quick-start)

### 1. Add locks to your model

[](#1-add-locks-to-your-model)

Add the `HasLocks` trait to the model you want to lock:

```
use Blendbyte\FilamentResourceLock\Models\Concerns\HasLocks;

class Post extends Model
{
    use HasFactory;
    use HasLocks;
}
```

### 2. Add locks to your EditRecord page

[](#2-add-locks-to-your-editrecord-page)

Add the `UsesResourceLock` trait to your `EditRecord` page:

```
use Blendbyte\FilamentResourceLock\Resources\Pages\Concerns\UsesResourceLock;

class EditPost extends EditRecord
{
    use UsesResourceLock;

    protected static string $resource = PostResource::class;
}
```

That's it — editing a resource now locks it automatically.

Usage
-----

[](#usage)

### Simple modal resources

[](#simple-modal-resources)

For simple modal resources, use `UsesSimpleResourceLock` instead:

```
use Blendbyte\FilamentResourceLock\Resources\Pages\Concerns\UsesSimpleResourceLock;

class ManagePosts extends ManageRecords
{
    use UsesSimpleResourceLock;

    protected static string $resource = PostResource::class;
}
```

### Relation manager locking

[](#relation-manager-locking)

To lock related records when editing them via a relation manager, add `UsesRelationManagerResourceLock` to your relation manager class. The related model also needs the `HasLocks` trait.

```
use Blendbyte\FilamentResourceLock\Resources\Pages\Concerns\UsesRelationManagerResourceLock;

class PostCommentsRelationManager extends RelationManager
{
    use UsesRelationManagerResourceLock;

    protected static string $relationship = 'comments';
}
```

When a user opens the edit modal for a related record, it is locked for the duration of the edit session and released when the modal is closed.

### Table lock indicators

[](#table-lock-indicators)

Add `ResourceLockColumn` to any resource table to display a visual lock status indicator for each row. It shows a lock icon in **primary** (blue) when the record is locked by the current user, or **danger** (red) when locked by another user. Unlocked records show no icon.

```
use Blendbyte\FilamentResourceLock\Tables\Columns\ResourceLockColumn;

public static function table(Table $table): Table
{
    return $table
        ->columns([
            ResourceLockColumn::make(),
            // other columns...
        ]);
}
```

Add the `WithResourceLockIndicator` trait to the corresponding `ListRecords` page to eager-load the lock relationship and avoid N+1 queries:

```
use Blendbyte\FilamentResourceLock\Resources\Pages\Concerns\WithResourceLockIndicator;

class ListPosts extends ListRecords
{
    use WithResourceLockIndicator;

    protected static string $resource = PostResource::class;
}
```

When `shouldDisplayResourceLockOwner()` is enabled on the plugin, the column tooltip will display the lock owner's name (e.g. *"Locked by John Doe"*). Otherwise it falls back to *"Locked by another user"*.

### Polling (SPA mode)

[](#polling-spa-mode)

To support SPA mode, enable polling-based presence detection in the plugin:

```
->plugin(ResourceLockPlugin::make()
    ->usesPollingToDetectPresence()
    ->presencePollingInterval(10)
    ->lockTimeout(15)
)
```

> **Tip:** Make sure the lock timeout is not lower than the polling interval — otherwise the lock may expire before the next heartbeat is sent.

Additional polling options:

- **`pollingKeepAlive()`** — keeps polling alive when the tab is in the background.
- **`pollingVisible()`** — only polls when the browser tab is visible.

### Resource Lock Manager

[](#resource-lock-manager)

The package includes a UI to view and manage all active and expired locks, and to unlock resources individually or in bulk.

Events
------

[](#events)

The package dispatches Laravel events for every lock lifecycle transition. Events are **enabled by default** and can be consumed by any standard Laravel listener.

EventPayload`ResourceLocked``$lockable`, `$userId``ResourceUnlocked``$lockable`, `$userId``ResourceLockExpired``$lockable`, `$originalUserId``ResourceLockForceUnlocked``$lockable`, `$originalUserId`, `$actorUserId`Register a listener in your `AppServiceProvider` or `EventServiceProvider`:

```
use Blendbyte\FilamentResourceLock\Events\ResourceLocked;
use Blendbyte\FilamentResourceLock\Events\ResourceUnlocked;
use Blendbyte\FilamentResourceLock\Events\ResourceLockForceUnlocked;

Event::listen(ResourceLocked::class, function (ResourceLocked $event) {
    // $event->lockable — the model that was locked
    // $event->userId   — the user who acquired the lock
});
```

To disable all event dispatching:

```
// config/filament-resource-lock.php
'events' => [
    'enabled' => false,
],
```

Or via the plugin fluent API:

```
->plugin(ResourceLockPlugin::make()
    ->enableEvents(false)
)
```

Audit Trail
-----------

[](#audit-trail)

The audit trail records every lock lifecycle event to a `resource_lock_audit` table, giving you a permanent, queryable history of who locked what and when.

Audit logging is **opt-in** (`audit.enabled` defaults to `false`) and requires `events.enabled` to be `true`, as it is powered by the event system.

### Enabling the audit trail

[](#enabling-the-audit-trail)

Publish and run the migration (if not already done via `filament-resource-lock:install`):

```
php artisan vendor:publish --tag="filament-resource-lock-migrations"
php artisan migrate
```

Enable audit logging in your config:

```
// config/filament-resource-lock.php
'audit' => [
    'enabled' => true,
],
```

Or via the plugin fluent API:

```
->plugin(ResourceLockPlugin::make()
    ->enableAudit()
)
```

### Audit resource

[](#audit-resource)

When `audit.enabled` is `true`, a read-only **Lock Audit Log** resource becomes visible in your Filament panel. It displays all recorded events with a colour-coded action badge, filterable by action type and date range.

The audit resource navigation can be customised independently of the lock manager:

```
->plugin(ResourceLockPlugin::make()
    ->enableAudit()
    ->auditNavigationLabel('Lock History')
    ->auditNavigationIcon('heroicon-o-clock')
    ->auditNavigationGroup('Security')
    ->auditNavigationSort(3)
)
```

To restrict who can view the Audit Log resource, enable limited access and specify a gate:

```
->plugin(ResourceLockPlugin::make()
    ->enableAudit()
    ->auditLimitedAccess()
    ->auditGate('view-audit-log')
)
```

Or via config:

```
// config/filament-resource-lock.php
'audit' => [
    'enabled' => true,
    'limited_access' => true,
    'gate' => 'view-audit-log',
],
```

When `limited_access` is `true`, only users for whom `Gate::allows($gate)` returns `true` can view the resource. This works with any standard Laravel gate or [Spatie permissions](https://github.com/spatie/laravel-permission) (`'gate' => 'view audit log'`).

To enable audit logging but hide the built-in resource (e.g. you have a custom UI):

```
// config/filament-resource-lock.php
'audit' => [
    'enabled' => true,
    'should_register_navigation' => false,
],
```

Configuration
-------------

[](#configuration)

### Read-only mode

[](#read-only-mode)

By default, when a user opens a resource that is locked by someone else, a blocking modal is shown. Enable read-only mode to show a warning banner instead, while keeping the page accessible for viewing:

```
->plugin(ResourceLockPlugin::make()
    ->readOnlyWhenLocked()
)
```

When read-only mode is active:

- All form fields are disabled.
- Save, cancel, and delete actions are hidden.
- A persistent warning banner is displayed, optionally showing the lock owner's name when `shouldDisplayResourceLockOwner()` is enabled.
- If the user has permission to force-unlock, they can do so from the banner and immediately take over editing.

Or configure it via the config file:

```
// config/filament-resource-lock.php
'read_only_mode' => [
    'enabled' => true,
],
```

### Per-model lock timeout

[](#per-model-lock-timeout)

Declare a `$lockTimeout` property (in seconds) on any model using `HasLocks` to override the global default for that model:

```
use Blendbyte\FilamentResourceLock\Models\Concerns\HasLocks;

class Post extends Model
{
    use HasLocks;

    protected int $lockTimeout = 30; // seconds, overrides the global default
}
```

The global default (`lock_timeout` in config, or `->lockTimeout()` on the plugin) is used for all models that do not declare their own property.

### Access control

[](#access-control)

Restrict access to the Unlock button or resource manager using a gate or Spatie permission:

```
->plugin(ResourceLockPlugin::make()
    ->limitedAccessToResourceLockManager()
    ->gate('unlock')
)
```

### Custom models

[](#custom-models)

```
->plugin(ResourceLockPlugin::make()
    ->userModel(\App\Models\CustomUser::class)
    ->resourceLockModel(\App\Models\CustomResourceLock::class)
)
```

### Custom lock owner display

[](#custom-lock-owner-display)

Create a custom action class extending `GetResourceLockOwnerAction`:

```
namespace App\Actions;

use Blendbyte\FilamentResourceLock\Actions\GetResourceLockOwnerAction;

class CustomResourceLockOwnerAction extends GetResourceLockOwnerAction
{
    public function execute($userModel): string|null
    {
        return $userModel->email;
    }
}
```

Register it in the plugin:

```
->plugin(ResourceLockPlugin::make()
    ->resourceLockOwnerAction(\App\Actions\CustomResourceLockOwnerAction::class)
)
```

### Overriding the return URL

[](#overriding-the-return-url)

Override `resourceLockReturnUrl()` to change where the Return button redirects:

```
public function resourceLockReturnUrl(): string
{
    return route('dashboard');
}
```

### Scheduled auto-clear

[](#scheduled-auto-clear)

The package automatically registers a scheduled task that runs `filament-resource-lock:clear-expired --force` **every hour**. This is enabled by default (opt-out).

To disable it and manage the schedule yourself:

```
// config/filament-resource-lock.php
'schedule' => [
    'auto_clear_expired' => false,
],
```

Then register it manually with whatever frequency suits your app:

```
// app/Console/Kernel.php  (or a ServiceProvider using Schedule)
$schedule->command('filament-resource-lock:clear-expired --force')->everyThirtyMinutes();
```

> **Note:** Laravel's scheduler requires a cron entry on your server: `* * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1`

Publishing Assets
-----------------

[](#publishing-assets)

```
# Migrations
php artisan vendor:publish --tag="filament-resource-lock-migrations"
php artisan migrate

# Views
php artisan vendor:publish --tag="filament-resource-lock-views"
```

Migrating from kenepa/resource-lock
-----------------------------------

[](#migrating-from-keneparesource-lock)

This fork introduces the following breaking changes:

1. **Composer package** — replace `kenepa/resource-lock` with `blendbyte/filament-resource-lock`
2. **PHP namespace** — find and replace `Kenepa\ResourceLock` with `Blendbyte\FilamentResourceLock` across your application
3. **Config file** — the config was renamed from `resource-lock.php` to `filament-resource-lock.php`. Re-publish if you have a customised config:

    ```
    php artisan vendor:publish --tag="filament-resource-lock-config" --force
    ```
4. **Artisan commands** — command signatures changed from `resource-lock:*` to `filament-resource-lock:*` (e.g. `filament-resource-lock:install`)
5. **Filament version** — this package requires **Filament v5**. The original `kenepa/resource-lock` targets Filament v3/v4.

Quick steps:

```
composer remove kenepa/resource-lock
composer require blendbyte/filament-resource-lock
php artisan filament-resource-lock:install
```

Then update all `use Kenepa\ResourceLock\...` import statements to `use Blendbyte\FilamentResourceLock\...`.

Contributing
------------

[](#contributing)

Please see [GitHub releases](https://github.com/blendbyte/filament-resource-lock/releases) for changelog information.

Maintained by Blendbyte
-----------------------

[](#maintained-by-blendbyte)

 [   ![Blendbyte](https://camo.githubusercontent.com/09962a5684a0b50fb9eb44edfd8f2560be418bc8ce3d23a31f96395f3f14d58e/68747470733a2f2f7777772e626c656e64627974652e636f6d2f6c6f676f5f686f72697a6f6e74616c2e706e67)  ](https://www.blendbyte.com)

 **[Blendbyte](https://www.blendbyte.com)** builds cloud infrastructure, web apps, and developer tools.
 We've been shipping software to production for 20+ years.

 This package runs in our own stack, which is why we keep it maintained.
 Issues and PRs get read. Good ones get merged.

 [blendbyte.com](https://www.blendbyte.com) ·

###  Health Score

50

—

FairBetter than 95% of packages

Maintenance93

Actively maintained with recent releases

Popularity28

Limited adoption so far

Community19

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 50.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~9 days

Total

7

Last Release

36d ago

Major Versions

v1.0.3 → v2.0.02026-04-04

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/69378377?v=4)[Blendbyte](/maintainers/blendbyte)[@blendbyte](https://github.com/blendbyte)

---

Top Contributors

[![Jehizkia](https://avatars.githubusercontent.com/u/8775667?v=4)](https://github.com/Jehizkia "Jehizkia (84 commits)")[![bashgeek](https://avatars.githubusercontent.com/u/4669888?v=4)](https://github.com/bashgeek "bashgeek (54 commits)")[![Hamoi1](https://avatars.githubusercontent.com/u/92602172?v=4)](https://github.com/Hamoi1 "Hamoi1 (7 commits)")[![howdu](https://avatars.githubusercontent.com/u/533658?v=4)](https://github.com/howdu "howdu (4 commits)")[![CodeWithDennis](https://avatars.githubusercontent.com/u/23448484?v=4)](https://github.com/CodeWithDennis "CodeWithDennis (3 commits)")[![atmonshi](https://avatars.githubusercontent.com/u/1952412?v=4)](https://github.com/atmonshi "atmonshi (3 commits)")[![laravel-shift](https://avatars.githubusercontent.com/u/15991828?v=4)](https://github.com/laravel-shift "laravel-shift (1 commits)")[![mohamedsabil83](https://avatars.githubusercontent.com/u/10126040?v=4)](https://github.com/mohamedsabil83 "mohamedsabil83 (1 commits)")[![MunaALB](https://avatars.githubusercontent.com/u/45367528?v=4)](https://github.com/MunaALB "MunaALB (1 commits)")[![OlyaK95](https://avatars.githubusercontent.com/u/129214474?v=4)](https://github.com/OlyaK95 "OlyaK95 (1 commits)")[![stereshko](https://avatars.githubusercontent.com/u/14062824?v=4)](https://github.com/stereshko "stereshko (1 commits)")[![adriaardila](https://avatars.githubusercontent.com/u/2029010?v=4)](https://github.com/adriaardila "adriaardila (1 commits)")[![teloconfesso](https://avatars.githubusercontent.com/u/63561771?v=4)](https://github.com/teloconfesso "teloconfesso (1 commits)")[![balismatz](https://avatars.githubusercontent.com/u/69709689?v=4)](https://github.com/balismatz "balismatz (1 commits)")[![danielbehrendt](https://avatars.githubusercontent.com/u/283437?v=4)](https://github.com/danielbehrendt "danielbehrendt (1 commits)")[![DariusIII](https://avatars.githubusercontent.com/u/3399658?v=4)](https://github.com/DariusIII "DariusIII (1 commits)")[![gerardg](https://avatars.githubusercontent.com/u/20286?v=4)](https://github.com/gerardg "gerardg (1 commits)")[![hamrak](https://avatars.githubusercontent.com/u/5807028?v=4)](https://github.com/hamrak "hamrak (1 commits)")

---

Tags

laravelBlendbytefilament-resource-lock

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/blendbyte-filament-resource-lock/health.svg)

```
[![Health](https://phpackages.com/badges/blendbyte-filament-resource-lock/health.svg)](https://phpackages.com/packages/blendbyte-filament-resource-lock)
```

###  Alternatives

[rawilk/profile-filament-plugin

Profile &amp; MFA starter kit for filament.

3913.7k](/packages/rawilk-profile-filament-plugin)[dotswan/filament-map-picker

Easily pick and retrieve geo-coordinates using a map-based interface in your Filament applications.

128173.7k3](/packages/dotswan-filament-map-picker)[stephenjude/filament-jetstream

A Laravel starter kit built with Filament inspired by Jetstream.

17758.9k2](/packages/stephenjude-filament-jetstream)[stephenjude/filament-debugger

About

104150.5k2](/packages/stephenjude-filament-debugger)[creagia/filament-code-field

A Filamentphp input field to edit or view code data.

57301.3k3](/packages/creagia-filament-code-field)[hydrat/filament-table-layout-toggle

Filament plugin adding a toggle button to tables, allowing user to switch between Grid and Table layouts.

63105.4k2](/packages/hydrat-filament-table-layout-toggle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
