From 42404cc2cc2c665297550b3e7a427e441c940d1b Mon Sep 17 00:00:00 2001 From: Mathias Palmqvist Date: Wed, 25 Jun 2025 21:10:11 +0200 Subject: [PATCH 1/6] Cleanup --- database/factories/ModelFactory.php | 19 --------- .../create_plausible_proxy_table.php.stub | 19 --------- routes/api.php | 30 +------------- routes/web.php | 32 +-------------- src/Commands/LaravelPlausibleProxyCommand.php | 19 --------- src/Facades/LaravelPlausibleProxy.php | 16 -------- .../PlausibleEventApiController.php | 41 +++++++++++++++++++ .../PlausibleScriptProxyController.php | 34 +++++++++++++++ src/LaravelPlausibleProxy.php | 5 --- 9 files changed, 79 insertions(+), 136 deletions(-) delete mode 100644 database/factories/ModelFactory.php delete mode 100644 database/migrations/create_plausible_proxy_table.php.stub delete mode 100644 src/Commands/LaravelPlausibleProxyCommand.php delete mode 100644 src/Facades/LaravelPlausibleProxy.php create mode 100644 src/Http/Controllers/PlausibleEventApiController.php create mode 100644 src/Http/Controllers/PlausibleScriptProxyController.php delete mode 100755 src/LaravelPlausibleProxy.php diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php deleted file mode 100644 index 751c682..0000000 --- a/database/factories/ModelFactory.php +++ /dev/null @@ -1,19 +0,0 @@ -id(); - - // add fields - - $table->timestamps(); - }); - } -}; diff --git a/routes/api.php b/routes/api.php index 6799a28..82fb249 100644 --- a/routes/api.php +++ b/routes/api.php @@ -4,32 +4,6 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Validator; +use MattitjaAB\LaravelPlausibleProxy\Http\Controllers\PlausibleEventApiController; -Route::post('api/event', function (Request $request) { - $data = json_decode($request->getContent(), true); - - if (json_last_error() !== JSON_ERROR_NONE) { - return response()->json(['error' => 'Invalid JSON format'], 422); - } - - $validator = Validator::make($data, [ - 'n' => 'required|string', - 'u' => 'required|url', - 'd' => 'required|string', - 'r' => 'nullable|url', - 'm' => 'nullable|string', - 'p' => 'nullable|array', - ]); - - if ($validator->fails()) { - return response()->json(['status' => 'error', 'errors' => $validator->errors()], 422); - } - - $headers = collect($request->headers->all()) - ->mapWithKeys(fn ($value, $key) => [$key => is_array($value) ? implode(', ', $value) : $value]) - ->all(); - - Http::withHeaders($headers)->post(config('plausible-proxy.domain').'/api/event', $data); - - return response()->json(['status' => 'queued']); -}); +Route::post('api/event', PlausibleEventApiController::class); diff --git a/routes/web.php b/routes/web.php index 07f79ce..1978482 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,34 +1,6 @@ header('Content-Type', 'application/javascript') - ->header('Cache-Control', 'public, max-age=86400'); - } - - $response = Http::timeout(5)->get("{$plausibleDomain}/js/script.js"); - - if ($response->successful()) { - $script = $response->body(); - Cache::put('plausible_script_js', $script, now()->addHours(6)); - - return response($script) - ->header('Content-Type', 'application/javascript') - ->header('Cache-Control', 'public, max-age=86400'); - } - - return response('Error fetching Plausible script', 500); -}); - -Route::get('/api/routes', function () { - return response()->json( - collect(Route::getRoutes())->map(fn ($route) => $route->uri()) - ); -}); +Route::get('/js/script.js', PlausibleScriptProxyController::class); \ No newline at end of file diff --git a/src/Commands/LaravelPlausibleProxyCommand.php b/src/Commands/LaravelPlausibleProxyCommand.php deleted file mode 100644 index cc2f549..0000000 --- a/src/Commands/LaravelPlausibleProxyCommand.php +++ /dev/null @@ -1,19 +0,0 @@ -comment('All done'); - - return self::SUCCESS; - } -} diff --git a/src/Facades/LaravelPlausibleProxy.php b/src/Facades/LaravelPlausibleProxy.php deleted file mode 100644 index b72ede7..0000000 --- a/src/Facades/LaravelPlausibleProxy.php +++ /dev/null @@ -1,16 +0,0 @@ -getContent(), true); + + if (json_last_error() !== JSON_ERROR_NONE) { + return response()->json(['error' => 'Invalid JSON format'], 422); + } + + $validator = Validator::make($data, [ + 'n' => 'required|string', + 'u' => 'required|url', + 'd' => 'required|string', + 'r' => 'nullable|url', + 'm' => 'nullable|string', + 'p' => 'nullable|array', + ]); + + if ($validator->fails()) { + return response()->json(['status' => 'error', 'errors' => $validator->errors()], 422); + } + + $headers = collect($request->headers->all()) + ->mapWithKeys(fn ($value, $key) => [$key => is_array($value) ? implode(', ', $value) : $value]) + ->all(); + + Http::withHeaders($headers)->post(config('plausible-proxy.domain').'/api/event', $data); + + return response()->json(['status' => 'queued']); + } +} \ No newline at end of file diff --git a/src/Http/Controllers/PlausibleScriptProxyController.php b/src/Http/Controllers/PlausibleScriptProxyController.php new file mode 100644 index 0000000..c120e72 --- /dev/null +++ b/src/Http/Controllers/PlausibleScriptProxyController.php @@ -0,0 +1,34 @@ +header('Content-Type', 'application/javascript') + ->header('Cache-Control', 'public, max-age=86400'); + } + + $response = Http::timeout(5)->get("{$plausibleDomain}/js/script.js"); + + if ($response->successful()) { + $script = $response->body(); + Cache::put('plausible_script_js', $script, now()->addHours(6)); + + return response($script) + ->header('Content-Type', 'application/javascript') + ->header('Cache-Control', 'public, max-age=86400'); + } + + return response('Error fetching Plausible script', 500); + } +} \ No newline at end of file diff --git a/src/LaravelPlausibleProxy.php b/src/LaravelPlausibleProxy.php deleted file mode 100755 index a72c463..0000000 --- a/src/LaravelPlausibleProxy.php +++ /dev/null @@ -1,5 +0,0 @@ - Date: Wed, 25 Jun 2025 21:21:07 +0200 Subject: [PATCH 2/6] Clean --- .../PlausibleEventApiController.php | 27 ++----------- .../PlausibleScriptProxyController.php | 38 ++++++++++--------- src/Http/Requests/PlausibleEventRequest.php | 25 ++++++++++++ tests/PlausibleProxyTest.php | 2 +- 4 files changed, 51 insertions(+), 41 deletions(-) create mode 100644 src/Http/Requests/PlausibleEventRequest.php diff --git a/src/Http/Controllers/PlausibleEventApiController.php b/src/Http/Controllers/PlausibleEventApiController.php index 1b4ebde..9932092 100644 --- a/src/Http/Controllers/PlausibleEventApiController.php +++ b/src/Http/Controllers/PlausibleEventApiController.php @@ -3,38 +3,19 @@ namespace MattitjaAB\LaravelPlausibleProxy\Http\Controllers; use Illuminate\Http\JsonResponse; -use Illuminate\Http\Request; use Illuminate\Support\Facades\Http; -use Illuminate\Support\Facades\Validator; +use MattitjaAB\LaravelPlausibleProxy\Http\Requests\PlausibleEventRequest; class PlausibleEventApiController { - public function __invoke(Request $request): JsonResponse + public function __invoke(PlausibleEventRequest $request): JsonResponse { - $data = json_decode($request->getContent(), true); - - if (json_last_error() !== JSON_ERROR_NONE) { - return response()->json(['error' => 'Invalid JSON format'], 422); - } - - $validator = Validator::make($data, [ - 'n' => 'required|string', - 'u' => 'required|url', - 'd' => 'required|string', - 'r' => 'nullable|url', - 'm' => 'nullable|string', - 'p' => 'nullable|array', - ]); - - if ($validator->fails()) { - return response()->json(['status' => 'error', 'errors' => $validator->errors()], 422); - } - $headers = collect($request->headers->all()) ->mapWithKeys(fn ($value, $key) => [$key => is_array($value) ? implode(', ', $value) : $value]) ->all(); - Http::withHeaders($headers)->post(config('plausible-proxy.domain').'/api/event', $data); + Http::withHeaders($headers) + ->post(config('plausible-proxy.domain').'/api/event', $request->validated()); return response()->json(['status' => 'queued']); } diff --git a/src/Http/Controllers/PlausibleScriptProxyController.php b/src/Http/Controllers/PlausibleScriptProxyController.php index c120e72..810803b 100644 --- a/src/Http/Controllers/PlausibleScriptProxyController.php +++ b/src/Http/Controllers/PlausibleScriptProxyController.php @@ -2,33 +2,37 @@ namespace MattitjaAB\LaravelPlausibleProxy\Http\Controllers; +use Illuminate\Http\Client\RequestException; use Illuminate\Http\Response; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Http; +use Illuminate\Support\Facades\Log; class PlausibleScriptProxyController { public function __invoke(): Response { - $plausibleDomain = config('plausible-proxy.domain'); + try { + $script = Cache::remember( + key: 'plausible_script_js', + ttl: now()->addHours(6), + callback: function () { + $plausibleDomain = config('plausible-proxy.domain'); - if (Cache::has('plausible_script_js')) { - return response(Cache::get('plausible_script_js')) - ->header('Content-Type', 'application/javascript') - ->header('Cache-Control', 'public, max-age=86400'); + return Http::timeout(5) + ->get("{$plausibleDomain}/js/script.js") + ->throw() + ->body(); + } + ); + } catch (RequestException $e) { + Log::error('Failed to fetch Plausible script: '.$e->getMessage()); + + return response('Error fetching Plausible script', 500); } - $response = Http::timeout(5)->get("{$plausibleDomain}/js/script.js"); - - if ($response->successful()) { - $script = $response->body(); - Cache::put('plausible_script_js', $script, now()->addHours(6)); - - return response($script) - ->header('Content-Type', 'application/javascript') - ->header('Cache-Control', 'public, max-age=86400'); - } - - return response('Error fetching Plausible script', 500); + return response($script) + ->header('Content-Type', 'application/javascript') + ->header('Cache-Control', 'public, max-age=86400'); } } \ No newline at end of file diff --git a/src/Http/Requests/PlausibleEventRequest.php b/src/Http/Requests/PlausibleEventRequest.php new file mode 100644 index 0000000..695186b --- /dev/null +++ b/src/Http/Requests/PlausibleEventRequest.php @@ -0,0 +1,25 @@ + ['required', 'string'], + 'u' => ['required', 'url'], + 'd' => ['required', 'string'], + 'r' => ['nullable', 'url'], + 'm' => ['nullable', 'string'], + 'p' => ['nullable', 'array'], + ]; + } +} \ No newline at end of file diff --git a/tests/PlausibleProxyTest.php b/tests/PlausibleProxyTest.php index be4cbc7..a28f9ec 100644 --- a/tests/PlausibleProxyTest.php +++ b/tests/PlausibleProxyTest.php @@ -46,7 +46,7 @@ it('rejects invalid event data', function () { ]); $response->assertStatus(422) - ->assertJsonStructure(['status', 'errors']); + ->assertJsonValidationErrors(['u' => 'The u field must be a valid URL.']); }); it('accepts valid event data and forwards headers', function () { From 2893ed0bc69990733f52ff9f17764d15e768caa0 Mon Sep 17 00:00:00 2001 From: mathiaspalmqvist <51116221+mathiaspalmqvist@users.noreply.github.com> Date: Wed, 25 Jun 2025 19:27:34 +0000 Subject: [PATCH 3/6] Fix styling --- routes/api.php | 3 --- routes/web.php | 2 +- src/Http/Controllers/PlausibleEventApiController.php | 2 +- src/Http/Controllers/PlausibleScriptProxyController.php | 2 +- src/Http/Requests/PlausibleEventRequest.php | 2 +- 5 files changed, 4 insertions(+), 7 deletions(-) diff --git a/routes/api.php b/routes/api.php index 82fb249..399887d 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,9 +1,6 @@ json(['status' => 'queued']); } -} \ No newline at end of file +} diff --git a/src/Http/Controllers/PlausibleScriptProxyController.php b/src/Http/Controllers/PlausibleScriptProxyController.php index 810803b..580b3f5 100644 --- a/src/Http/Controllers/PlausibleScriptProxyController.php +++ b/src/Http/Controllers/PlausibleScriptProxyController.php @@ -35,4 +35,4 @@ class PlausibleScriptProxyController ->header('Content-Type', 'application/javascript') ->header('Cache-Control', 'public, max-age=86400'); } -} \ No newline at end of file +} diff --git a/src/Http/Requests/PlausibleEventRequest.php b/src/Http/Requests/PlausibleEventRequest.php index 695186b..189a3a0 100644 --- a/src/Http/Requests/PlausibleEventRequest.php +++ b/src/Http/Requests/PlausibleEventRequest.php @@ -22,4 +22,4 @@ class PlausibleEventRequest extends FormRequest 'p' => ['nullable', 'array'], ]; } -} \ No newline at end of file +} From 859dcf99bea47d40edf0bc03600b146364ee84c6 Mon Sep 17 00:00:00 2001 From: Mathias Palmqvist Date: Wed, 25 Jun 2025 21:30:16 +0200 Subject: [PATCH 4/6] Cleanup --- phpstan.neon.dist | 1 - resources/views/.gitkeep | 0 2 files changed, 1 deletion(-) delete mode 100644 resources/views/.gitkeep diff --git a/phpstan.neon.dist b/phpstan.neon.dist index ab1b4c3..4a0559d 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -6,7 +6,6 @@ parameters: paths: - src - config - - database tmpDir: build/phpstan checkOctaneCompatibility: true checkModelProperties: true diff --git a/resources/views/.gitkeep b/resources/views/.gitkeep deleted file mode 100644 index e69de29..0000000 From 8c042b27cf959821517710d715f9a0860e4187df Mon Sep 17 00:00:00 2001 From: Mathias Palmqvist Date: Wed, 25 Jun 2025 21:31:35 +0200 Subject: [PATCH 5/6] WIP --- phpstan.neon.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 4a0559d..b678f5e 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -8,4 +8,4 @@ parameters: - config tmpDir: build/phpstan checkOctaneCompatibility: true - checkModelProperties: true + checkModelProperties: true \ No newline at end of file From cd005727021a20ff361a3a6fc7de082f3bef9fe5 Mon Sep 17 00:00:00 2001 From: Mathias Palmqvist Date: Wed, 25 Jun 2025 21:33:15 +0200 Subject: [PATCH 6/6] WIP --- src/Http/Controllers/PlausibleEventApiController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Http/Controllers/PlausibleEventApiController.php b/src/Http/Controllers/PlausibleEventApiController.php index c9a72ff..011318f 100644 --- a/src/Http/Controllers/PlausibleEventApiController.php +++ b/src/Http/Controllers/PlausibleEventApiController.php @@ -11,7 +11,7 @@ class PlausibleEventApiController public function __invoke(PlausibleEventRequest $request): JsonResponse { $headers = collect($request->headers->all()) - ->mapWithKeys(fn ($value, $key) => [$key => is_array($value) ? implode(', ', $value) : $value]) + ->mapWithKeys(fn ($value, $key) => [$key => implode(', ', $value)]) ->all(); Http::withHeaders($headers)