php 51 lines · 8 steps

Enforcing upload quotas with Laravel middleware

A middleware that blocks file uploads when a team's incoming bytes would exceed its subscription plan's storage quota.

Explained by highlit
1<?php
2 
3namespace App\Http\Middleware;
4 
5use Closure;
6use Illuminate\Http\Request;
7use Symfony\Component\HttpFoundation\Response;
8 
9class EnforceUploadQuota
10{
11 protected array $planLimits = [
12 'free' => 100 * 1024 * 1024,
13 'pro' => 5 * 1024 * 1024 * 1024,
14 'enterprise' => 100 * 1024 * 1024 * 1024,
15 ];
16 
17 public function handle(Request $request, Closure $next): Response
18 {
19 $team = $request->user()->currentTeam;
20 
21 abort_unless($team, 403, 'You must belong to a team to upload files.');
22 
23 $plan = $team->subscription('default')?->stripe_price
24 ? $team->planName()
25 : 'free';
26 
27 $quota = $this->planLimits[$plan] ?? $this->planLimits['free'];
28 
29 $incoming = collect($request->allFiles())
30 ->flatten()
31 ->sum(fn ($file) => $file->getSize());
32 
33 $projected = $team->storage_used + $incoming;
34 
35 if ($projected > $quota) {
36 $remaining = max(0, $quota - $team->storage_used);
37 
38 return response()->json([
39 'message' => "Upload exceeds your {$plan} plan quota.",
40 'quota_bytes' => $quota,
41 'used_bytes' => $team->storage_used,
42 'remaining_bytes' => $remaining,
43 'upgrade_url' => route('billing.plans'),
44 ], Response::HTTP_PAYMENT_REQUIRED);
45 }
46 
47 $request->attributes->set('upload_bytes', $incoming);
48 
49 return $next($request);
50 }
51}
01 / 01
STEP 01

Walkthrough

Space play ←→ step click any line
Three takeaways
  1. 1Middleware is the right place to reject requests before controllers run wasteful work.
  2. 2Summing incoming file sizes against a known limit lets you fail fast with a precise, actionable error.
  3. 3Passing computed data downstream via request attributes avoids recomputing it in the controller.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Enforcing upload quotas with Laravel middleware — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code