Skip to content
This repository was archived by the owner on Oct 20, 2025. It is now read-only.

Commit 766edf7

Browse files
authored
Errors from redirect (#306)
1 parent a7e8b00 commit 766edf7

File tree

6 files changed

+90
-9
lines changed

6 files changed

+90
-9
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace App\Http\Controllers;
4+
5+
use Illuminate\Http\Request;
6+
7+
class FormRedirectController
8+
{
9+
public function show(Request $request)
10+
{
11+
return view('form.redirect');
12+
}
13+
14+
public function submit()
15+
{
16+
return redirect()->route('form.simple')->withErrors([
17+
'name' => 'Custom validation message from redirect',
18+
]);
19+
}
20+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
@extends('layout')
2+
3+
@section('content')
4+
5+
FormRedirect
6+
7+
<x-splade-form class="form-simple">
8+
<button type="submit">Submit</button>
9+
</x-splade-form>
10+
11+
@endsection

app/routes/web.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use App\Http\Controllers\FileFormController;
1010
use App\Http\Controllers\FilepondController;
1111
use App\Http\Controllers\FormComponentsController;
12+
use App\Http\Controllers\FormRedirectController;
1213
use App\Http\Controllers\FormRelationsController;
1314
use App\Http\Controllers\FormViewController;
1415
use App\Http\Controllers\LazyController;
@@ -92,6 +93,9 @@
9293

9394
Route::view('flash', 'flash')->name('flash');
9495

96+
Route::get('form/redirect', [FormRedirectController::class, 'show'])->name('form.redirect.show');
97+
Route::post('form/redirect', [FormRedirectController::class, 'submit'])->name('form.redirect.submit');
98+
9599
Route::view('form/simple', 'form.simple')->name('form.simple');
96100
Route::post('form/simple', SimpleFormController::class)->name('form.simple.submit');
97101
Route::view('form/emit', 'form.emit')->name('form.emit');

app/tests/Browser/FormTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,18 @@ public function it_can_show_the_errors()
2020
});
2121
}
2222

23+
/** @test */
24+
public function it_can_show_the_errors_from_a_redirect()
25+
{
26+
$this->browse(function (Browser $browser) {
27+
$browser->visit('/form/redirect')
28+
->waitForText('FormRedirect')
29+
->press('Submit')
30+
->waitForText('Custom validation message from redirect')
31+
->assertSee('Custom validation message from redirect');
32+
});
33+
}
34+
2335
/** @test */
2436
public function it_can_submit_data_to_a_get_endpoint()
2537
{

phpstan-baseline.neon

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,11 @@ parameters:
330330
count: 1
331331
path: src/Http/SpladeMiddleware.php
332332

333+
-
334+
message: "#^Parameter \\#1 \\$callback of method Illuminate\\\\Support\\\\Collection\\<int\\|string,array\\<Illuminate\\\\Support\\\\ViewErrorBag\\>\\>\\:\\:each\\(\\) expects callable\\(array\\<Illuminate\\\\Support\\\\ViewErrorBag\\>, int\\|string\\)\\: mixed, Closure\\(Illuminate\\\\Support\\\\ViewErrorBag\\)\\: void given\\.$#"
335+
count: 1
336+
path: src/Http/SpladeMiddleware.php
337+
333338
-
334339
message: "#^Parameter \\#1 \\$key of method Illuminate\\\\Contracts\\\\Session\\\\Session\\:\\:get\\(\\) expects string, array\\<TKey of \\(int\\|string\\), TValue\\>\\|bool given\\.$#"
335340
count: 1

src/Http/SpladeMiddleware.php

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Illuminate\Routing\UrlGenerator;
1111
use Illuminate\Support\Arr;
1212
use Illuminate\Support\Facades\Blade;
13+
use Illuminate\Support\MessageBag;
1314
use Illuminate\Support\Str;
1415
use Illuminate\Support\ViewErrorBag;
1516
use Illuminate\Validation\ValidationException;
@@ -54,8 +55,10 @@ public function handle(Request $request, Closure $next)
5455
$this->splade->resetRehydrateComponentCounter();
5556
$this->splade->resetPersistentLayoutKey();
5657

58+
/** @var Session */
5759
$session = session()->driver();
58-
$session->forget('errors');
60+
61+
$errorsFromRedirect = $session->pull('errors', new ViewErrorBag);
5962

6063
/** @var Response $response */
6164
$response = $next($request);
@@ -74,7 +77,7 @@ public function handle(Request $request, Closure $next)
7477
}
7578

7679
// Gather the required meta data for the app.
77-
$spladeData = $this->spladeData($session);
80+
$spladeData = $this->spladeData($session, $errorsFromRedirect);
7881

7982
// The response should redirect away from the Splade app.
8083
if ($redirect = $this->shouldRedirectsAway($response)) {
@@ -353,26 +356,47 @@ private function parseModalContent(string $content): ?string
353356
/**
354357
* Returns all error messages from the session.
355358
*
356-
* @param \Illuminate\Contracts\Session\Session $session
359+
* @param \Illuminate\Support\ViewErrorBag $viewErrorBag
357360
* @return array
358361
*/
359-
private function allErrorMessages(Session $session): array
362+
private function allErrorMessages(ViewErrorBag $viewErrorBag): array
360363
{
361-
/** @var ViewErrorBag */
362-
$viewErrorBag = $session->get('errors', new ViewErrorBag);
363-
364364
return collect($viewErrorBag->getBags())
365365
->flatMap->getMessages()
366366
->toArray();
367367
}
368368

369+
/**
370+
* Merges all bags from all view errors bags into one.
371+
*
372+
* @param \Illuminate\Support\ViewErrorBag[] ...$viewErrorsBags
373+
* @return \Illuminate\Support\ViewErrorBag
374+
*/
375+
private function mergeViewErrorBags(...$viewErrorsBags): ViewErrorBag
376+
{
377+
$mergedViewBag = new ViewErrorBag;
378+
379+
collect($viewErrorsBags)->each(function (ViewErrorBag $viewErrorBag) use ($mergedViewBag) {
380+
collect($viewErrorBag->getBags())->each(function (MessageBag $bag, string $key) use ($mergedViewBag) {
381+
$mergedBag = $mergedViewBag->hasBag($key)
382+
? $mergedViewBag->getBag($key)
383+
: tap(new MessageBag, fn ($bag) => $mergedViewBag->put($key, $bag));
384+
385+
$mergedBag->merge($bag);
386+
});
387+
});
388+
389+
return $mergedViewBag;
390+
}
391+
369392
/**
370393
* This methods returns all relevant data for a Splade page view.
371394
*
372395
* @param \Illuminate\Contracts\Session\Session $session
396+
* @param \Illuminate\Support\ViewErrorBag $errorsFromRedirect
373397
* @return object
374398
*/
375-
private function spladeData(Session $session): object
399+
private function spladeData(Session $session, ViewErrorBag $errorsFromRedirect): object
376400
{
377401
$flashData = config('splade.share_session_flash_data')
378402
? collect($session->get('_flash.old', []))
@@ -384,12 +408,17 @@ private function spladeData(Session $session): object
384408

385409
$excludeHead = $this->splade->isLazyRequest() || $this->splade->isRehydrateRequest();
386410

411+
$mergedViewErrorBag = $this->mergeViewErrorBags(
412+
$session->get('errors', new ViewErrorBag),
413+
$errorsFromRedirect
414+
);
415+
387416
return (object) [
388417
'head' => $excludeHead ? [] : $this->splade->head()->toArray(),
389418
'modal' => $this->splade->isModalRequest() ? $this->splade->getModalType() : null,
390419
'modalTarget' => $this->splade->getModalTarget() ?: null,
391420
'flash' => (object) $flash,
392-
'errors' => (object) $this->allErrorMessages($session),
421+
'errors' => (object) $this->allErrorMessages($mergedViewErrorBag),
393422
'shared' => (object) Arr::map($this->splade->getShared(), fn ($value) => value($value)),
394423
'toasts' => array_merge(
395424
$session->pull(static::FLASH_TOASTS, []),

0 commit comments

Comments
 (0)