diff --git a/README.md b/README.md
index c101fed..93c023b 100644
--- a/README.md
+++ b/README.md
@@ -21,9 +21,11 @@
- [Turn ON-OFF](#turn-on-off)
- [Views](#visit-monitoring-views)
- [Ajax Requests](#ajax-requests)
+ - [Visit Monitoring Guest Mode](#visit-monitoring-guest-mode)
- [Action Monitoring](#action-monitoring)
- [Views](#action-monitoring-views)
- [Reverse Proxy Config](#action-monitoring-reverse-proxy-config)
+ - [Action Monitoring Guest Mode](#action-monitoring-guest-mode)
- [Authentication Monitoring](#authentication-monitoring)
- [Views](#authentication-monitoring-views)
- [How to use in big projects](#how-to-use-in-big-projects)
@@ -338,6 +340,27 @@ Maybe you may disable record visits for `Ajax` requests, you can use config to d
When set to false, Ajax requests will not be recorded.
+
+### Visit Monitoring Guest Mode
+
+Determines whether to track and store `visits` for users who are not authenticated (guests).
+When set to `true`, the package will also monitor guest user activity.
+When set to `false`, only authenticated user visits will be recorded.
+
+```php
+/*
+ * Configuration settings for visit monitoring.
+ */
+'visit_monitoring' => [
+ ...
+
+ /*
+ * Determines whether to store `visits` even when the user is not logged in.
+ */
+ 'guest_mode' => true,
+],
+```
+
## Action Monitoring
@@ -385,48 +408,70 @@ If you want to disable some actions like created, you can use the config file:

-
-## Authentication Monitoring
+
+### Action Monitoring Reverse Proxy Config
-Have you ever thought about monitoring the entry and exit of users of your application? Now you can :)
-If you want to monitor users when logging in or logout of your application, you need to migrate the migrations to the config file and change true for monitoring authentication.
+If you are using Reverse Proxy (Nginx or Cloudflare), you can use config to get real IP from a specific header like `X-Real-IP` or `X-Forwarded-For`:
```php
-'authentication_monitoring' => [
+'action_monitoring' => [
...
/*
- * Enable or disable monitoring of user login and logout events.
- * Set to true to track these actions, or false to disable.
+ * If your application is behind a reverse proxy (e.g., Nginx or Cloudflare),
+ * enable this setting to fetch the real client IP from the proxy headers.
*/
- 'on_login' => true,
- 'on_logout' => true,
+ 'use_reverse_proxy_ip' => false,
+
+ /*
+ * The header used by reverse proxies to forward the real client IP.
+ * Common values are 'X-Forwarded-For' or 'X-Real-IP'.
+ */
+ 'real_ip_header' => 'X-Forwarded-For',
],
```
-
-### Action Monitoring Reverse Proxy Config
+
+### Action Monitoring Guest Mode
-If you are using Reverse Proxy (Nginx or Cloudflare), you can use config to get real IP from a specific header like `X-Real-IP` or `X-Forwarded-For`:
+Determines whether to track and store `actions` for users who are not authenticated (guests).
+When set to `true`, the package will also monitor guest user activity.
+When set to `false`, only authenticated user visits will be recorded.
```php
+/*
+ * Configuration settings for action monitoring.
+ */
'action_monitoring' => [
...
/*
- * If your application is behind a reverse proxy (e.g., Nginx or Cloudflare),
- * enable this setting to fetch the real client IP from the proxy headers.
+ * Determines whether to store `actions` even when the user is not logged in.
*/
- 'use_reverse_proxy_ip' => false,
+ 'guest_mode' => true,
+],
+```
+
+
+## Authentication Monitoring
+
+Have you ever thought about monitoring the entry and exit of users of your application? Now you can :)
+If you want to monitor users when logging in or logout of your application, you need to migrate the migrations to the config file and change true for monitoring authentication.
+
+```php
+'authentication_monitoring' => [
+ ...
/*
- * The header used by reverse proxies to forward the real client IP.
- * Common values are 'X-Forwarded-For' or 'X-Real-IP'.
+ * Enable or disable monitoring of user login and logout events.
+ * Set to true to track these actions, or false to disable.
*/
- 'real_ip_header' => 'X-Forwarded-For',
+ 'on_login' => true,
+ 'on_logout' => true,
],
```
+
### Authentication Monitoring Views
diff --git a/config/user-monitoring.php b/config/user-monitoring.php
index fa1c932..2c9fae4 100644
--- a/config/user-monitoring.php
+++ b/config/user-monitoring.php
@@ -93,6 +93,11 @@
* https://laravel.com/docs/scheduling
*/
'delete_days' => 0,
+
+ /*
+ * Determines whether to store `visits` even when the user is not logged in.
+ */
+ 'guest_mode' => true,
],
/*
@@ -126,6 +131,11 @@
* Common values are 'X-Forwarded-For' or 'X-Real-IP'.
*/
'real_ip_header' => 'X-Forwarded-For',
+
+ /*
+ * Determines whether to store `actions` even when the user is not logged in.
+ */
+ 'guest_mode' => true,
],
/*
diff --git a/src/Middlewares/VisitMonitoringMiddleware.php b/src/Middlewares/VisitMonitoringMiddleware.php
index 1c2a34f..c95950a 100644
--- a/src/Middlewares/VisitMonitoringMiddleware.php
+++ b/src/Middlewares/VisitMonitoringMiddleware.php
@@ -21,6 +21,9 @@ public function handle(Request $request, Closure $next): mixed
if (config('user-monitoring.visit_monitoring.ajax_requests', false) === false && $request->ajax()) {
return $next($request);
}
+ if (!config('user-monitoring.visit_monitoring.guest_mode', true) && is_null(UserUtils::getUserId())) {
+ return $next($request);
+ }
$detector = new Detector();
$exceptPages = config('user-monitoring.visit_monitoring.except_pages', []);
diff --git a/src/Providers/LaravelUserMonitoringEventServiceProvider.php b/src/Providers/LaravelUserMonitoringEventServiceProvider.php
index 50adb36..553fb25 100644
--- a/src/Providers/LaravelUserMonitoringEventServiceProvider.php
+++ b/src/Providers/LaravelUserMonitoringEventServiceProvider.php
@@ -14,7 +14,7 @@ class LaravelUserMonitoringEventServiceProvider extends EventServiceProvider
{
public function boot(): void
{
- $detector = new Detector();
+ $detector = new Detector;
$table = config('user-monitoring.authentication_monitoring.table');
// Login Event
diff --git a/src/Traits/Actionable.php b/src/Traits/Actionable.php
index fac1c9a..be0a177 100644
--- a/src/Traits/Actionable.php
+++ b/src/Traits/Actionable.php
@@ -16,6 +16,10 @@ protected static function boot(): void
{
parent::boot();
+ if (!config('user-monitoring.action_monitoring.guest_mode', true) && is_null(UserUtils::getUserId())) {
+ return;
+ }
+
if (config('user-monitoring.action_monitoring.on_store', false)) {
static::created(function (mixed $model) {
static::insertActionMonitoring($model, ActionType::ACTION_STORE);
@@ -87,7 +91,7 @@ private static function insertActionMonitoring(mixed $model, string $actionType)
private static function getRealIP(): string
{
return config('user-monitoring.use_reverse_proxy_ip')
- ? request()->header(config('user-monitoring.real_ip_header')) ?: request()->ip()
+ ? request()->header(config('user-monitoring.real_ip_header'))
: request()->ip();
}
}
diff --git a/tests/Feature/ActionMonitoringTest.php b/tests/Feature/ActionMonitoringTest.php
index 3096c12..d7f9092 100644
--- a/tests/Feature/ActionMonitoringTest.php
+++ b/tests/Feature/ActionMonitoringTest.php
@@ -6,6 +6,7 @@
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Tests\SetUp\Models\Product;
+use Tests\SetUp\Models\ProductSoftDelete;
use function Pest\Laravel\{assertDatabaseCount, assertDatabaseHas};
/*
@@ -226,7 +227,7 @@
$user = createUser();
auth()->login($user);
- $product = \Tests\SetUp\Models\ProductSoftDelete::query()->create([
+ $product = ProductSoftDelete::query()->create([
'title' => 'milwad',
'description' => 'WE ARE HELPING TO OPEN-SOURCE WORLD'
]);
@@ -252,7 +253,7 @@
$user = createUser();
auth()->login($user);
- $product = \Tests\SetUp\Models\ProductSoftDelete::query()->create([
+ $product = ProductSoftDelete::query()->create([
'title' => 'milwad',
'description' => 'WE ARE HELPING TO OPEN-SOURCE WORLD'
]);
@@ -302,3 +303,61 @@
expect($actionMonitoring->getTypeColor())->toBe($colors[$type]);
}
});
+
+test('action not stored when the guest mode is off and user not logged in', function () {
+ config()->set('user-monitoring.action_monitoring.guest_mode', false);
+
+ $product = Product::query()->create([
+ 'title' => 'milwad',
+ 'description' => 'WE ARE HELPING TO OPEN-SOURCE WORLD'
+ ]);
+ $product->delete();
+
+ // DB Assertions
+ assertDatabaseCount(config('user-monitoring.action_monitoring.table'), 0);
+});
+
+test('action stored when the guest mode is on and user not logged in', function () {
+ config()->set('user-monitoring.action_monitoring.guest_mode', true);
+
+ $product = Product::query()->create([
+ 'title' => 'milwad',
+ 'description' => 'WE ARE HELPING TO OPEN-SOURCE WORLD'
+ ]);
+ $product->delete();
+
+ // DB Assertions
+ assertDatabaseCount(config('user-monitoring.action_monitoring.table'), 2);
+});
+
+test('action stored when the guest mode is off and user logged in', function () {
+ config()->set('user-monitoring.action_monitoring.guest_mode', false);
+
+ $user = createUser();
+ auth()->login($user);
+
+ $product = Product::query()->create([
+ 'title' => 'milwad',
+ 'description' => 'WE ARE HELPING TO OPEN-SOURCE WORLD'
+ ]);
+ $product->delete();
+
+ // DB Assertions
+ assertDatabaseCount(config('user-monitoring.action_monitoring.table'), 2);
+});
+
+test('action stored when the guest mode is on and user logged in', function () {
+ config()->set('user-monitoring.action_monitoring.guest_mode', true);
+
+ $user = createUser();
+ auth()->login($user);
+
+ $product = Product::query()->create([
+ 'title' => 'milwad',
+ 'description' => 'WE ARE HELPING TO OPEN-SOURCE WORLD'
+ ]);
+ $product->delete();
+
+ // DB Assertions
+ assertDatabaseCount(config('user-monitoring.action_monitoring.table'), 2);
+});
diff --git a/tests/Feature/VisitMonitoringTest.php b/tests/Feature/VisitMonitoringTest.php
index 91c4433..5e8f532 100644
--- a/tests/Feature/VisitMonitoringTest.php
+++ b/tests/Feature/VisitMonitoringTest.php
@@ -62,7 +62,6 @@
// Ajax
test('visit monitoring store ajax requests', function () {
- \Pest\Laravel\withoutExceptionHandling();
get('/', ['X-Requested-With' => 'XMLHttpRequest']);
// DB Assertions
@@ -80,12 +79,53 @@
assertDatabaseMissing(config('user-monitoring.visit_monitoring.table'), ['page' => 'http:\/\/localhost']);
});
+test('visit monitoring skip store when guest mode is off and user not logged in', function () {
+ config()->set('user-monitoring.visit_monitoring.guest_mode', false);
+
+ $response = get('/');
+ $response->assertContent('milwad');
+
+ // DB Assertions
+ assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 0);
+ assertDatabaseMissing(config('user-monitoring.visit_monitoring.table'), ['page' => 'http:\/\/localhost']);
+});
+
+test('visit monitoring store when guest mode is off and user logged in', function () {
+ config()->set('user-monitoring.visit_monitoring.guest_mode', false);
+
+ $user = createUser();
+ $response = actingAs($user)->get('/');
+ $response->assertContent('milwad');
+
+ // DB Assertions
+ assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 1);
+});
+
+test('visit monitoring store when guest mode is on and user logged in', function () {
+ config()->set('user-monitoring.visit_monitoring.guest_mode', true);
+
+ $user = createUser();
+ $response = actingAs($user)->get('/');
+ $response->assertContent('milwad');
+
+ // DB Assertions
+ assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 1);
+});
+
+test('visit monitoring store when guest mode is on and user not logged in', function () {
+ config()->set('user-monitoring.visit_monitoring.guest_mode', true);
+
+ $response = get('/');
+ $response->assertContent('milwad');
+
+ // DB Assertions
+ assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 1);
+});
+
/**
- * Create user.
- *
- * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model
+ * Create user and return it.
*/
-function createUser()
+function createUser(): \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model
{
return User::query()->create([
'name' => 'milwad',