PHPackages                             sofa/model-locking - 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. [Database &amp; ORM](/categories/database)
4. /
5. sofa/model-locking

ActiveLibrary[Database &amp; ORM](/categories/database)

sofa/model-locking
==================

Pseudo pessimistic model locking with broadcasted events for Laravel Eloquent ORM.

v7.0(6y ago)5048.0k28[3 PRs](https://github.com/jarektkaczyk/model-locking/pulls)MITPHPPHP &gt;=7.0.0

Since Sep 4Pushed 5y ago2 watchersCompare

[ Source](https://github.com/jarektkaczyk/model-locking)[ Packagist](https://packagist.org/packages/sofa/model-locking)[ RSS](/packages/sofa-model-locking/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (3)Versions (22)Used By (0)

Sofa/ModelLocking
=================

[](#sofamodellocking)

[![Build Status](https://camo.githubusercontent.com/892767b696f7fd0dcf03c9269e8815a372b78ba89600570b0ab416ad8b97fdfa/68747470733a2f2f7472617669732d63692e6f72672f6a6172656b746b61637a796b2f6d6f64656c2d6c6f636b696e672e737667)](https://travis-ci.org/jarektkaczyk/model-locking) [![Coverage Status](https://camo.githubusercontent.com/4a9e25f9226f4d21e0a91edd2bbaa1d28084cd47c79c601dd67e53c703a28d7f/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6a6172656b746b61637a796b2f6d6f64656c2d6c6f636b696e672f62616467652e737667)](https://coveralls.io/r/jarektkaczyk/model-locking) [![Downloads](https://camo.githubusercontent.com/aa0fed05af8cf5c1448cca3efd1581f2fb832a5b4f5170ce818556c95429dc91/68747470733a2f2f706f7365722e707567782e6f72672f736f66612f6d6f64656c2d6c6f636b696e672f646f776e6c6f616473)](https://packagist.org/packages/sofa/model-locking) [![stable](https://camo.githubusercontent.com/612733407e9da063dfb7dff57bb00a211262a0d5f1c7912570e7ab57d68fedfc/68747470733a2f2f706f7365722e707567782e6f72672f736f66612f6d6f64656c2d6c6f636b696e672f762f737461626c652e737667)](https://packagist.org/packages/sofa/model-locking)

Pseudo pessimistic model locking for the [Eloquent ORM (Laravel 5.3+)](https://laravel.com/docs/5.3/eloquent).

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

[](#installation)

Package goes along with Laravel (Illuminate) versioning for your convenience:

Laravel / Illuminate **5.3+**:

1. require package: `composer require sofa/model-locking:"~5.3"`
2. if you're using Laravel 5.1 - 5.4, add to your `config/app.php` under `providers`: `Sofa\ModelLocking\ServiceProvider::class,`,
    if you're using Laravel 5.5+ the service provider will register itself automatically
3. publish package assets: `php artisan vendor:publish --provider="Sofa\ModelLocking\ServiceProvider"`
4. create model locks table by running `php artisan migrate`
5. add trait `use \Sofa\ModelLocking\Locking` to the model that should offer locking
6. OPTIONALLY customize package config in `config/model_locking.php`

Usage
-----

[](#usage)

Basic example:

```
// controller
public function edit(Post $post)
{
    if ($post->isLocked()) {
        return response([
            'status' => 'locked',
            'message' => 'Resource you are trying to access is locked',
            'lock_expiration' => $post->lockedUntil(),
        ], 423);
    }

    return view('posts.edit', compact('post'));
}

public function update(Post $post)
{
    if ($post->isAccessible(request('lock_token'))) {
        return redirect()->back()
                         ->withErrors(['danger' => 'Resource you are trying to update is locked']);
    }

    $post->update(request()->all());
    // broadcasts ModelUnlocked event, so you can push notification
    // to the user who tried to access locked post.
    $post->unlock();

    return redirect('posts.index');
}

public function requestUnlock(Post $post)
{
    if ($post->isAccessible()) {
        $token = $post->lock('5 minutes', auth()->user());

        return response([
            'status' => 'unlocked',
            'message' => 'Resource is now locked by you',
            'lock_expiration' => $post->lockedUntil(),
            'lock_token' => $token,
        ]);
    }

    // broadcasts ModelUnlockRequested event, so you can push
    // notification to the user who locked the resource.
    $post->requestUnlock(auth()->user(), request('unlock_message'));
}

// app/Console/Kernel - it will remove expired locks
//                      AND fire ModelUnlocked event for all of them
$schedule->command('locks:flush')->everyMinute();

// Available broadcasting events:
// new ModelLocked($post)
// new ModelUnlocked($post)
// new ModelUnlockRequested($post, $requesting_user, $request_message)
```

soon more in-depth info, meanwhile take a look at the specs:

```
  /\ /\__ _| |__ | | __ _ _ __
 / //_/ _` | '_ \| |/ _` | '_ \
/ __ \ (_| | | | | | (_| | | | |
\/  \/\__,_|_| |_|_|\__,_|_| |_|

Sofa\ModelLocking\Locking
  ✔ it checks if active lock for model exists
  ✔ it checks if existing lock is still active
  ✔ it gets user who locked model
  ✔ it gets null as timestamp and user if model is not locked
  ✔ it sets by default authenticated user as one who is locking the model
  ✔ it unlocks the model on demand
  ✔ it lets you request unlock of a locked model
  ✔ it allows setting lock shortening when unlock request is made
  ✔ it verifies if model can be accessed with provided token
  ✔ it allows passing user_id as locking user
  ✔ it allows passing user instance as only param to `lock` method
  Lock duration precedence
    ✔ it locks the model for provided time by given user
    ✔ it next takes `lock_duration` property if set on the model
    ✔ it then falls back to the config
    ✔ it finally gets the default value: 5 minutes
  Fires broadcasting events to make push notifications a cinch
    ✔ it fires event when model is being locked
    ✔ it fires event when model is being unlocked
    ✔ it fires event when unlock request is made, with optional: requesting user and his message

Executed 23 of 23 PASS in 0.337 seconds
```

Contribution
------------

[](#contribution)

All contributions are welcome, PRs must be **tested** (using [kahlan](http://kahlan.readthedocs.io)) and **PSR-2 compliant**.

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity39

Limited adoption so far

Community18

Small or concentrated contributor base

Maturity67

Established project with proven stability

 Bus Factor1

Top contributor holds 70.8% 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 ~66 days

Recently: every ~193 days

Total

21

Last Release

2225d ago

Major Versions

v5.7.1 → v7.02020-04-14

PHP version history (3 changes)v5.3PHP &gt;=5.6.4

v5.1PHP &gt;=5.5.9

5.5.x-devPHP &gt;=7.0.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/34d383bf50d6c73fc747d89a5efacd41ccecc9695aec04148a7c04fc00ef26e7?d=identicon)[jarektkaczyk](/maintainers/jarektkaczyk)

---

Top Contributors

[![jarektkaczyk](https://avatars.githubusercontent.com/u/6928818?v=4)](https://github.com/jarektkaczyk "jarektkaczyk (17 commits)")[![Braunson](https://avatars.githubusercontent.com/u/577273?v=4)](https://github.com/Braunson "Braunson (3 commits)")[![pawelmysior](https://avatars.githubusercontent.com/u/11052725?v=4)](https://github.com/pawelmysior "pawelmysior (3 commits)")[![mlantz](https://avatars.githubusercontent.com/u/1065551?v=4)](https://github.com/mlantz "mlantz (1 commits)")

---

Tags

laravelormeloquentlockingactive-recordpessimistic-lockmodel lock

### Embed Badge

![Health badge](/badges/sofa-model-locking/health.svg)

```
[![Health](https://phpackages.com/badges/sofa-model-locking/health.svg)](https://phpackages.com/packages/sofa-model-locking)
```

###  Alternatives

[proai/eloquent-versioning

An extension for the Eloquent ORM to support versioning.

7125.9k](/packages/proai-eloquent-versioning)[sbarre/eloquent-versioned

Add transparent versioning to Laravel 5.2's Eloquent ORM

301.1k](/packages/sbarre-eloquent-versioned)[chocofamilyme/laravel-tarantool

A Tarantool based Eloquent ORM and Query builder for Laravel

182.3k](/packages/chocofamilyme-laravel-tarantool)[andreagroferreira/laravel-sync-tracker

A Laravel package for tracking entity synchronization status between systems

113.0k](/packages/andreagroferreira-laravel-sync-tracker)

PHPackages © 2026

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