Skip to content

Commit c215afa

Browse files
authored
Improve Middleware except (#9)
1 parent e659da8 commit c215afa

File tree

6 files changed

+176
-13
lines changed

6 files changed

+176
-13
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## [1.0.0] - 2025-03-20
4+
5+
### Added
6+
7+
- Improve Middleware except.
38

49
## [0.4.10] - 2025-03-20
510

README.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ Apply the middleware to your web routes by appending it in the `withMiddleware`
4343
})
4444
```
4545

46+
You can also apply the middleware to specific routes or groups:
47+
48+
```php
49+
use Pirsch\Http\Middleware\TrackPageview;
50+
51+
Route::middleware(TrackPageview::class)->group(function () {
52+
Route::get('/', function () {
53+
return view('welcome');
54+
});
55+
});
56+
```
57+
4658
#### Manually
4759
4860
If you want to manually track pageviews instead, you can use the `Pirsch::track()` method.
@@ -69,3 +81,74 @@ Pirsch::track(
6981
],
7082
);
7183
```
84+
85+
### Filter pages
86+
87+
You can configure the `TrackPageview` middleware to exclude specific pages from being tracked.
88+
89+
On a specific rouute, you can exclude pages by adding a `except` property to the middleware class:
90+
91+
```php
92+
use Pirsch\Http\Middleware\TrackPageview;
93+
94+
Route::middleware(TrackPageview::class.':url/to/exclude/*')->group(function () {
95+
Route::get('/', function () {
96+
return view('welcome');
97+
});
98+
});
99+
```
100+
101+
Multiple urls can be excluded by separating them with a comma:
102+
103+
```php
104+
use Pirsch\Http\Middleware\TrackPageview;
105+
106+
Route::middleware(TrackPageview::class.':url/to/exclude/*,url/to/exclude2/*')->group(function () {
107+
Route::get('/', function () {
108+
return view('welcome');
109+
});
110+
});
111+
```
112+
113+
To exclude pages globally, you can create a new middleware that extends the `TrackPageview` middleware and add an `except` property:
114+
115+
```php
116+
namespace App\Http\Middleware;
117+
118+
use Pirsch\Http\Middleware\TrackPageview as Middleware;
119+
120+
class TrackPageview extends Middleware
121+
{
122+
/**
123+
* The URIs that should be excluded from tracking.
124+
*
125+
* @var array<int,string>
126+
*/
127+
protected array $except = [
128+
'url/to/exclude/*',
129+
];
130+
131+
/**
132+
* The Headers that should be excluded from tracking.
133+
*
134+
* @var array<int,string>
135+
*/
136+
protected array $exceptHeaders = [
137+
'X-ExcludedHeader',
138+
];
139+
}
140+
```
141+
142+
- `except` is an array with all URIs paths taht you want to exclude from tracking.
143+
- `exceptHeaders` is an array with all Headers that you want to exclude from tracking.
144+
145+
Then replace the `TrackPageview` middleware with this one on your `bootstrap/app.php` middleware configuration:
146+
147+
```diff
148+
->withMiddleware(function (Middleware $middleware) {
149+
$middleware->web(append: [
150+
- \Pirsch\Http\Middleware\TrackPageview::class,
151+
+ \App\Http\Middleware\TrackPageview::class,
152+
]);
153+
})
154+
```

src/Facades/Pirsch.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ class Pirsch extends Facade
1313
{
1414
protected static function getFacadeAccessor()
1515
{
16-
return 'laravel-pirsch';
16+
return \Pirsch\Facades\Pirsch::class;
1717
}
1818
}

src/Http/Middleware/TrackPageview.php

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,74 @@
99

1010
class TrackPageview
1111
{
12-
public function handle(Request $request, Closure $next): mixed
12+
/**
13+
* The URIs that should be excluded from tracking.
14+
*
15+
* @var array<int,string>
16+
*/
17+
protected array $except = [
18+
'telescope/*',
19+
'horizon/*',
20+
];
21+
22+
/**
23+
* The Headers that should be excluded from tracking.
24+
*
25+
* @var array<int,string>
26+
*/
27+
protected array $exceptHeaders = [
28+
'X-Livewire',
29+
];
30+
31+
/**
32+
* Handle an incoming request.
33+
*/
34+
public function handle(Request $request, Closure $next, string ...$excepts): mixed
1335
{
1436
$response = $next($request);
1537

1638
if ($response instanceof RedirectResponse) {
1739
return $response;
1840
}
1941

20-
if ($request->hasHeader('X-Livewire')) {
21-
return $response;
42+
if (! $this->inExceptArray($request, $excepts) &&
43+
! $this->inExceptHeadersArray($request)
44+
) {
45+
Pirsch::track();
2246
}
2347

24-
if (str_starts_with($request->route()->uri, 'telescope/')) {
25-
return $response;
48+
return $response;
49+
}
50+
51+
/**
52+
* Determine if the request has a header that should not be tracked.
53+
*/
54+
protected function inExceptHeadersArray(Request $request): bool
55+
{
56+
foreach ($this->exceptHeaders as $except) {
57+
if ($request->hasHeader($except)) {
58+
return true;
59+
}
2660
}
2761

28-
Pirsch::track();
62+
return false;
63+
}
2964

30-
return $response;
65+
/**
66+
* Determine if the request has a URI that should not be tracked.
67+
*/
68+
protected function inExceptArray(Request $request, ?array $excepts = null): bool
69+
{
70+
foreach (empty($excepts) ? $this->except : $excepts as $except) {
71+
if ($except !== '/') {
72+
$except = trim($except, '/');
73+
}
74+
75+
if ($request->fullUrlIs($except) || $request->is($except)) {
76+
return true;
77+
}
78+
}
79+
80+
return false;
3181
}
3282
}

src/PirschServiceProvider.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ public function configurePackage(Package $package): void
1616

1717
public function packageRegistered(): void
1818
{
19-
$this->app->bind('laravel-pirsch', fn () => new Pirsch());
19+
$this->app->bind(
20+
\Pirsch\Facades\Pirsch::class,
21+
\Pirsch\Pirsch::class
22+
);
2023
}
2124
}

tests/TrackPageviewTest.php

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
$this->get('/');
2424

25-
Pirsch::shouldNotHaveBeenCalled();
25+
Pirsch::shouldNotHaveReceived('track');
2626
});
2727

2828
it('skips Livewire', function () {
@@ -33,16 +33,38 @@
3333

3434
$this->get('/', ['X-Livewire' => 'true']);
3535

36-
Pirsch::shouldNotHaveBeenCalled();
36+
Pirsch::shouldNotHaveReceived('track');
3737
});
3838

3939
it('skips Telescope', function () {
4040
Pirsch::spy();
4141

4242
Route::middleware(TrackPageview::class)
43-
->get('telescope/test', fn () => 'Hello World');
43+
->get('/telescope/test', fn () => 'Hello World');
4444

4545
$this->get('/telescope/test');
4646

47-
Pirsch::shouldNotHaveBeenCalled();
47+
Pirsch::shouldNotHaveReceived('track');
48+
});
49+
50+
it('skips Horizon', function () {
51+
Pirsch::spy();
52+
53+
Route::middleware(TrackPageview::class)
54+
->get('horizon/test', fn () => 'Hello World');
55+
56+
$this->get('/horizon/test');
57+
58+
Pirsch::shouldNotHaveReceived('track');
59+
});
60+
61+
it('skips parameter except', function () {
62+
Pirsch::spy();
63+
64+
Route::middleware(TrackPageview::class.':myurl/*')
65+
->get('myurl/test', fn () => 'Hello World');
66+
67+
$this->get('/myurl/test');
68+
69+
Pirsch::shouldNotHaveReceived('track');
4870
});

0 commit comments

Comments
 (0)