Laravel Model Locking by HYPERLINK GROUP
You can install the package via composer:
composer require hyperlink/laravel-model-locking
You can publish the config file with:
php artisan vendor:publish --provider="Hylk\Locking\ModelLockingServiceProvider" --tag="model-locking-config"
You can publish the translation files with:
php artisan vendor:publish --provider="Hylk\Locking\ModelLockingServiceProvider" --tag="model-locking-translations"
You can publish the vue-components via:
php artisan vendor:publish --provider="Hylk\Locking\ModelLockingServiceProvider" --tag="model-locking-vue"
Within a model just use the IsLockable
-Trait.
class Post extends Model {
use \Hylk\ModelLocking\IsLockable;
...
}
Additionally you have to extend the database-tables for the Model.
return new class extends Migration {
public function up()
{
Schema::table('posts', function (Blueprint $table) {
$table->lockfields();
});
}
public function down()
{
Schema::table('posts', function (Blueprint $table) {
$table->dropLockfields();
});
}
}
If you want just a simple version of the locking, just use the Traits methods within your controller. HEARTBEAT_LOCK_DURATION
should be set to something like 15 minutes (900 seconds).
class PostController {
public function show(Post $post) {
$post->lock();
}
public function update(Request $request, Post $post) {
$post->update($request->all());
$post->unlock();
}
}
To make sure no locks are missed you should use the locking:release
Artisan command in your scheduler.
Additionally, you should publish the config and set the lock duration to around 15 minutes.
The more advanced approach is to handle the locks via a heartbeat. This only works for Vue
and axios
.
- Publish the vue-components
- register the global HeartbeatManager
import Vue from 'vue'; import HeartbeatManager from './vendor/hylk/laravel-model-locking/heartbeat-manager'; ... window.axios = require('axios'); ... Vue.use(HeartbeatManager);
- register the Listener-Components
- for index-pages
Handle the wished behavior like showing the current locker by the<template> <div> <HeartbeatListener model-class="App\Models\Post" :model-id="model_id" @locked="setLockState" @unlocked="deleteLockState" /> ... </div> </template>
lock
event and delete this information on theunlock
-event.... <span v-if="isLocked(model_id)">Locked by {{ getLock(model_id).locked_by.name }}</span> ...
- register the LockRefresher on your Edit-form.
The
<template> <div> <HeartbeatLockRefresher model-class="App\Models\Post" :model-id="model_id" @lost="reloadRoute()" /> ... </div> </template>
lost
-Event shows if the component tries to render if the model is locked by another user than the logged in.
Variable | Default | Description |
---|---|---|
HEARTBEAT_LOCK_DURATION |
70 | The time in seconds a model is locked. |
MIX_HEARTBEAT_REFRESH |
60 | The time in seconds between the heartbeats. Should be a multiple of the MIX_HEARTBEAT_STATUS -interval. |
MIX_HEARTBEAT_STATUS |
30 | The time in seconds between the heartbeats for status-request (index-Listener). |
MIX_HEARTBEAT_ENABLED |
true | Activates or deactivates the heartbeats. |
Beside the environment variables, there is a middleware
key to determine the middleware(s) used by the heartbeat-route. Default it's set to api
.