From 8881ca55665e1993b485314a21c37c2d6a8f1942 Mon Sep 17 00:00:00 2001
From: Milwad <98118400+milwad-dev@users.noreply.github.com>
Date: Fri, 5 Sep 2025 12:38:42 +0330
Subject: [PATCH 01/13] Update VisitMonitoringMiddleware.php
---
src/Middlewares/VisitMonitoringMiddleware.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Middlewares/VisitMonitoringMiddleware.php b/src/Middlewares/VisitMonitoringMiddleware.php
index c95950a..003794e 100644
--- a/src/Middlewares/VisitMonitoringMiddleware.php
+++ b/src/Middlewares/VisitMonitoringMiddleware.php
@@ -25,7 +25,7 @@ public function handle(Request $request, Closure $next): mixed
return $next($request);
}
- $detector = new Detector();
+ $detector = new Detector;
$exceptPages = config('user-monitoring.visit_monitoring.except_pages', []);
if (empty($exceptPages) || !$this->checkIsExceptPages($request->path(), $exceptPages)) {
From b8dd238cbf363c399470b4040a0696eb797bbd37 Mon Sep 17 00:00:00 2001
From: Milwad <98118400+milwad-dev@users.noreply.github.com>
Date: Fri, 5 Sep 2025 12:41:43 +0330
Subject: [PATCH 02/13] Create MonitoringCondition.php
---
src/Contracts/MonitoringCondition.php | 10 ++++++++++
1 file changed, 10 insertions(+)
create mode 100644 src/Contracts/MonitoringCondition.php
diff --git a/src/Contracts/MonitoringCondition.php b/src/Contracts/MonitoringCondition.php
new file mode 100644
index 0000000..a516925
--- /dev/null
+++ b/src/Contracts/MonitoringCondition.php
@@ -0,0 +1,10 @@
+
Date: Fri, 5 Sep 2025 12:46:26 +0330
Subject: [PATCH 03/13] Update user-monitoring.php
---
config/user-monitoring.php | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/config/user-monitoring.php b/config/user-monitoring.php
index 2c9fae4..011845b 100644
--- a/config/user-monitoring.php
+++ b/config/user-monitoring.php
@@ -98,6 +98,26 @@
* Determines whether to store `visits` even when the user is not logged in.
*/
'guest_mode' => true,
+
+ /*
+ | Here you can define one or more conditions that determine whether a visit
+ | should be logged. Each condition must return a boolean (true = log visit,
+ | false = skip logging).
+ |
+ | All conditions are evaluated before monitoring. If any condition returns
+ | false, the visit will NOT be recorded.
+ |
+ | Supported formats:
+ |
+ | 1. Class name (must implement MonitoringCondition interface):
+ | \App\Monitoring\YourCustomCondition::class
+ |
+ | 2. Closure / callback (receives the current Request and authenticated user):
+ | function (Request $request, $user) {
+ | return $user && $user->isAdmin();
+ | }
+ */
+ 'conditions' => [],
],
/*
From 892ed8d2139884c633cfd854e466b2ada54e5c77 Mon Sep 17 00:00:00 2001
From: Milwad <98118400+milwad-dev@users.noreply.github.com>
Date: Fri, 5 Sep 2025 12:47:56 +0330
Subject: [PATCH 04/13] Update VisitMonitoringMiddleware.php
---
src/Middlewares/VisitMonitoringMiddleware.php | 32 +++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/src/Middlewares/VisitMonitoringMiddleware.php b/src/Middlewares/VisitMonitoringMiddleware.php
index 003794e..65b8e35 100644
--- a/src/Middlewares/VisitMonitoringMiddleware.php
+++ b/src/Middlewares/VisitMonitoringMiddleware.php
@@ -2,6 +2,7 @@
namespace Binafy\LaravelUserMonitoring\Middlewares;
+use Binafy\LaravelUserMonitoring\Contracts\MonitoringCondition;
use Binafy\LaravelUserMonitoring\Utills\Detector;
use Binafy\LaravelUserMonitoring\Utills\UserUtils;
use Closure;
@@ -25,6 +26,11 @@ public function handle(Request $request, Closure $next): mixed
return $next($request);
}
+ // Custom conditions from config
+ if (! $this->shouldMonitor($request)) {
+ return $next($request);
+ }
+
$detector = new Detector;
$exceptPages = config('user-monitoring.visit_monitoring.except_pages', []);
@@ -53,4 +59,30 @@ protected function checkIsExceptPages(string $page, array $exceptPages): bool
{
return collect($exceptPages)->contains($page);
}
+
+ /**
+ * Determine if monitoring should be performed for the given request and user.
+ */
+ protected function shouldMonitor(Request $request): bool
+ {
+ $config = config('user-monitoring.visit_monitoring.conditions', []);
+
+ foreach ($config as $condition) {
+ if (is_callable($condition)) {
+ if (! $condition($request)) {
+ return false;
+ }
+ } elseif (is_string($condition)) {
+ $instance = new $condition;
+ if (! $instance instanceof MonitoringCondition) {
+ continue;
+ }
+ if (! $instance->shouldMonitor($request)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
}
From 482c905cb5a562d3a2694aeeaa37e1b5735aee6d Mon Sep 17 00:00:00 2001
From: Milwad <98118400+milwad-dev@users.noreply.github.com>
Date: Fri, 5 Sep 2025 12:48:23 +0330
Subject: [PATCH 05/13] Update user-monitoring.php
---
config/user-monitoring.php | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/config/user-monitoring.php b/config/user-monitoring.php
index 011845b..ca28e76 100644
--- a/config/user-monitoring.php
+++ b/config/user-monitoring.php
@@ -106,16 +106,6 @@
|
| All conditions are evaluated before monitoring. If any condition returns
| false, the visit will NOT be recorded.
- |
- | Supported formats:
- |
- | 1. Class name (must implement MonitoringCondition interface):
- | \App\Monitoring\YourCustomCondition::class
- |
- | 2. Closure / callback (receives the current Request and authenticated user):
- | function (Request $request, $user) {
- | return $user && $user->isAdmin();
- | }
*/
'conditions' => [],
],
From c86ff71f57eb8f6ed92fcf5acaa1039797f33d36 Mon Sep 17 00:00:00 2001
From: Milwad <98118400+milwad-dev@users.noreply.github.com>
Date: Fri, 5 Sep 2025 12:49:06 +0330
Subject: [PATCH 06/13] Update user-monitoring.php
---
config/user-monitoring.php | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/config/user-monitoring.php b/config/user-monitoring.php
index ca28e76..158cfc3 100644
--- a/config/user-monitoring.php
+++ b/config/user-monitoring.php
@@ -146,6 +146,13 @@
* Determines whether to store `actions` even when the user is not logged in.
*/
'guest_mode' => true,
+
+ /*
+ * Here you can define one or more conditions that determine whether an action
+ * should be logged. Each condition must return a boolean (true = log action,
+ * false = skip logging).
+ */
+ 'conditions' => [],
],
/*
From 671533dd87430d57544a22367cf10a77007241ca Mon Sep 17 00:00:00 2001
From: Milwad <98118400+milwad-dev@users.noreply.github.com>
Date: Fri, 5 Sep 2025 12:50:45 +0330
Subject: [PATCH 07/13] Update Actionable.php
---
src/Traits/Actionable.php | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/src/Traits/Actionable.php b/src/Traits/Actionable.php
index be0a177..8a5f7dc 100644
--- a/src/Traits/Actionable.php
+++ b/src/Traits/Actionable.php
@@ -2,9 +2,11 @@
namespace Binafy\LaravelUserMonitoring\Traits;
+use Binafy\LaravelUserMonitoring\Contracts\MonitoringCondition;
use Binafy\LaravelUserMonitoring\Utills\ActionType;
use Binafy\LaravelUserMonitoring\Utills\Detector;
use Binafy\LaravelUserMonitoring\Utills\UserUtils;
+use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
trait Actionable
@@ -20,6 +22,11 @@ protected static function boot(): void
return;
}
+ // Custom conditions from config
+ if (! static::shouldMonitor(request())) {
+ return;
+ }
+
if (config('user-monitoring.action_monitoring.on_store', false)) {
static::created(function (mixed $model) {
static::insertActionMonitoring($model, ActionType::ACTION_STORE);
@@ -94,4 +101,30 @@ private static function getRealIP(): string
? request()->header(config('user-monitoring.real_ip_header'))
: request()->ip();
}
+
+ /**
+ * Determine if monitoring should be performed for the given request and user.
+ */
+ protected static function shouldMonitor(Request $request): bool
+ {
+ $config = config('user-monitoring.action_monitoring.conditions', []);
+
+ foreach ($config as $condition) {
+ if (is_callable($condition)) {
+ if (! $condition($request)) {
+ return false;
+ }
+ } elseif (is_string($condition)) {
+ $instance = new $condition;
+ if (! $instance instanceof MonitoringCondition) {
+ continue;
+ }
+ if (! $instance->shouldMonitor($request)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
}
From 2b5c9f8906189a2a33f02abfb32df3aba1a4d3f8 Mon Sep 17 00:00:00 2001
From: Milwad <98118400+milwad-dev@users.noreply.github.com>
Date: Fri, 5 Sep 2025 12:56:19 +0330
Subject: [PATCH 08/13] add `action is stored when config conditions are true`
test
---
tests/Feature/ActionMonitoringTest.php | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/tests/Feature/ActionMonitoringTest.php b/tests/Feature/ActionMonitoringTest.php
index d7f9092..72089ee 100644
--- a/tests/Feature/ActionMonitoringTest.php
+++ b/tests/Feature/ActionMonitoringTest.php
@@ -4,6 +4,7 @@
use Binafy\LaravelUserMonitoring\Utills\ActionType;
use Binafy\LaravelUserMonitoring\Utills\UserUtils;
use Illuminate\Foundation\Testing\RefreshDatabase;
+use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Tests\SetUp\Models\Product;
use Tests\SetUp\Models\ProductSoftDelete;
@@ -361,3 +362,19 @@
// DB Assertions
assertDatabaseCount(config('user-monitoring.action_monitoring.table'), 2);
});
+
+test('action is stored when config conditions are true', function () {
+ config()->set('user-monitoring.action_monitoring.conditions', [
+ function (Request $request) {
+ return true;
+ },
+ ]);
+
+ Product::query()->create([
+ 'title' => 'milwad',
+ 'description' => 'WE ARE HELPING TO OPEN-SOURCE WORLD'
+ ]);
+
+ // DB Assertions
+ assertDatabaseCount(config('user-monitoring.action_monitoring.table'), 1);
+});
From 02d0a80a3262cf20361362c428b47d7b06eef5a7 Mon Sep 17 00:00:00 2001
From: Milwad <98118400+milwad-dev@users.noreply.github.com>
Date: Fri, 5 Sep 2025 12:56:41 +0330
Subject: [PATCH 09/13] add `action is not stored when config conditions are
false` test
---
tests/Feature/ActionMonitoringTest.php | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/tests/Feature/ActionMonitoringTest.php b/tests/Feature/ActionMonitoringTest.php
index 72089ee..ada2dac 100644
--- a/tests/Feature/ActionMonitoringTest.php
+++ b/tests/Feature/ActionMonitoringTest.php
@@ -378,3 +378,19 @@ function (Request $request) {
// DB Assertions
assertDatabaseCount(config('user-monitoring.action_monitoring.table'), 1);
});
+
+test('action is not stored when config conditions are false', function () {
+ config()->set('user-monitoring.action_monitoring.conditions', [
+ function (Request $request) {
+ return false;
+ },
+ ]);
+
+ Product::query()->create([
+ 'title' => 'milwad',
+ 'description' => 'WE ARE HELPING TO OPEN-SOURCE WORLD'
+ ]);
+
+ // DB Assertions
+ assertDatabaseCount(config('user-monitoring.action_monitoring.table'), 0);
+});
From e62adbf120be694de4a4f592ee68e3e57b7753fa Mon Sep 17 00:00:00 2001
From: Milwad <98118400+milwad-dev@users.noreply.github.com>
Date: Fri, 5 Sep 2025 12:57:38 +0330
Subject: [PATCH 10/13] add `visit monitoring store when config conditions are
true` test
---
tests/Feature/VisitMonitoringTest.php | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/tests/Feature/VisitMonitoringTest.php b/tests/Feature/VisitMonitoringTest.php
index 5e8f532..b6bcb29 100644
--- a/tests/Feature/VisitMonitoringTest.php
+++ b/tests/Feature/VisitMonitoringTest.php
@@ -2,6 +2,7 @@
use Binafy\LaravelUserMonitoring\Models\VisitMonitoring;
use Illuminate\Foundation\Testing\RefreshDatabase;
+use Illuminate\Http\Request;
use Tests\SetUp\Models\User;
use function Pest\Laravel\{actingAs, get};
use function Pest\Laravel\{assertDatabaseCount, assertDatabaseHas, assertDatabaseMissing};
@@ -122,6 +123,20 @@
assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 1);
});
+test('visit monitoring store when config conditions are true', function () {
+ config()->set('user-monitoring.visit_monitoring.conditions', [
+ function (Request $request) {
+ return true;
+ },
+ ]);
+
+ $response = get('/');
+ $response->assertContent('milwad');
+
+ // DB Assertions
+ assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 1);
+});
+
/**
* Create user and return it.
*/
From 47317bbdd12396d00ba6a9b3160a14197971cbf2 Mon Sep 17 00:00:00 2001
From: Milwad <98118400+milwad-dev@users.noreply.github.com>
Date: Fri, 5 Sep 2025 12:58:08 +0330
Subject: [PATCH 11/13] add `visit monitoring is not store when config
conditions are false` test
---
tests/Feature/VisitMonitoringTest.php | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/tests/Feature/VisitMonitoringTest.php b/tests/Feature/VisitMonitoringTest.php
index b6bcb29..35018ea 100644
--- a/tests/Feature/VisitMonitoringTest.php
+++ b/tests/Feature/VisitMonitoringTest.php
@@ -123,7 +123,7 @@
assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 1);
});
-test('visit monitoring store when config conditions are true', function () {
+test('visit monitoring is store when config conditions are true', function () {
config()->set('user-monitoring.visit_monitoring.conditions', [
function (Request $request) {
return true;
@@ -137,6 +137,20 @@ function (Request $request) {
assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 1);
});
+test('visit monitoring is not store when config conditions are false', function () {
+ config()->set('user-monitoring.visit_monitoring.conditions', [
+ function (Request $request) {
+ return false;
+ },
+ ]);
+
+ $response = get('/');
+ $response->assertContent('milwad');
+
+ // DB Assertions
+ assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 0);
+});
+
/**
* Create user and return it.
*/
From 974037ef92233a45776c0b87d927f855e1eb1dfb Mon Sep 17 00:00:00 2001
From: Milwad <98118400+milwad-dev@users.noreply.github.com>
Date: Fri, 5 Sep 2025 13:02:44 +0330
Subject: [PATCH 12/13] add `Visit Monitoring Custom Conditions` to readme
---
README.md | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/README.md b/README.md
index 9a26ad1..7c56760 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,7 @@
- [Views](#visit-monitoring-views)
- [Ajax Requests](#ajax-requests)
- [Visit Monitoring Guest Mode](#visit-monitoring-guest-mode)
+ - [Visit Monitoring Custom Conditions](#visit-monitoring-custom-conditions)
- [Action Monitoring](#action-monitoring)
- [Views](#action-monitoring-views)
- [Reverse Proxy Config](#action-monitoring-reverse-proxy-config)
@@ -366,6 +367,34 @@ When set to `false`, only authenticated user visits will be recorded.
],
```
+
+### Visit Monitoring Custom Conditions
+
+The `Laravel User Monitoring` package allows you to define custom conditions for visit monitoring.
+Conditions give you full control over when a visit should be logged.
+
+#### 🔧 How It Works
+
+- Conditions are checked before a visit is stored.
+- If any condition returns false, the visit will be skipped.
+- You can define conditions as closures or as class-based rules.
+
+```php
+'visit_monitoring' => [
+ 'conditions' => [
+ // Class-based condition (must implement MonitoringCondition interface)
+ \App\Monitoring\YourCustomCondition::class,
+
+ // Closure-based condition (receives the Request and authenticated User)
+ function (Illuminate\Http\Request $request) {
+ $user = $request->user();
+
+ return $user && $user->isAdmin();
+ },
+ ],
+],
+```
+
## Action Monitoring
From 32fde43a4b7b89f9876fd2d7b8339f91b1426929 Mon Sep 17 00:00:00 2001
From: Milwad <98118400+milwad-dev@users.noreply.github.com>
Date: Fri, 5 Sep 2025 13:04:36 +0330
Subject: [PATCH 13/13] add `Action Monitoring Custom Conditions` to readme
---
README.md | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/README.md b/README.md
index 7c56760..d45312d 100644
--- a/README.md
+++ b/README.md
@@ -27,6 +27,7 @@
- [Views](#action-monitoring-views)
- [Reverse Proxy Config](#action-monitoring-reverse-proxy-config)
- [Action Monitoring Guest Mode](#action-monitoring-guest-mode)
+ - [Action Monitoring Custom Conditions](#action-monitoring-custom-conditions)
- [Authentication Monitoring](#authentication-monitoring)
- [Views](#authentication-monitoring-views)
- [How to use in big projects](#how-to-use-in-big-projects)
@@ -486,6 +487,34 @@ When set to `false`, only authenticated user visits will be recorded.
],
```
+
+### Action Monitoring Custom Conditions
+
+The `Laravel User Monitoring` package lets you define custom conditions for action monitoring (create, update, delete events on models).
+Conditions give you control over when model actions should be logged.
+
+#### 🔧 How It Works
+
+- Conditions are checked before an action is stored.
+- If any condition returns false, the action will be skipped.
+- You can define conditions as closures or class-based rules.
+
+```php
+'action_monitoring' => [
+ 'conditions' => [
+ // Class-based condition (must implement MonitoringCondition interface)
+ \App\Monitoring\YourCustomCondition::class,
+
+ // Closure-based condition (receives the Request and authenticated User)
+ function (Illuminate\Http\Request $request) {
+ $user = $request->user();
+
+ return $user && $user->isAdmin();
+ },
+ ],
+],
+```
+
## Authentication Monitoring