-
-
Notifications
You must be signed in to change notification settings - Fork 623
Expand file tree
/
Copy pathFormController.php
More file actions
125 lines (102 loc) · 4.06 KB
/
FormController.php
File metadata and controls
125 lines (102 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<?php
namespace Statamic\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\MessageBag;
use Illuminate\Validation\ValidationException;
use Statamic\Contracts\Forms\Submission;
use Statamic\Exceptions\SilentFormFailureException;
use Statamic\Facades\Form;
use Statamic\Facades\Site;
use Statamic\Forms\Exceptions\FileContentTypeRequiredException;
use Statamic\Forms\SubmitForm;
use Statamic\Support\Arr;
use Statamic\Support\Str;
use Symfony\Component\HttpFoundation\RedirectResponse;
class FormController extends Controller
{
/**
* Handle a form submission request.
*
* @return mixed
*/
public function submit(Request $request, $form, SubmitForm $submitForm)
{
$site = Site::findByUrl(URL::previous()) ?? Site::default();
$this->validateContentType($request, $form);
$params = collect($request->all())
->filter(fn ($value, string $key) => Str::startsWith($key, '_'))
->all();
try {
$submission = $submitForm->submit(
form: $form,
data: $request->all(),
files: $request->allFiles(),
site: $site,
);
return $this->formSuccess($params, $submission);
} catch (SilentFormFailureException $e) {
return $this->formSuccess($params, $e->submission(), silentFailure: true);
} catch (ValidationException $e) {
return $this->formFailure($params, $e->errors(), $form->handle());
}
}
private function validateContentType(Request $request, $form): void
{
$type = Str::before($request->headers->get('CONTENT_TYPE'), ';');
if ($type !== 'multipart/form-data' && $form->hasFiles() && $request->allFiles()) {
throw new FileContentTypeRequiredException;
}
}
private function formFailure(array $params, array $errors, string $form): Response|RedirectResponse
{
$request = request();
if ($request->ajax()) {
return response([
'errors' => (new MessageBag($errors))->all(),
'error' => collect($errors)->map(function ($errors, $field) {
return $errors[0];
})->all(),
], 400);
}
if ($request->isPrecognitive() || $request->wantsJson()) {
throw ValidationException::withMessages($errors);
}
$redirect = Arr::get($params, '_error_redirect');
$response = $redirect && ! \Statamic\Facades\URL::isExternalToApplication($redirect)
? redirect($redirect)
: back();
return $response->withInput()->withErrors($errors, 'form.'.$form);
}
private function formSuccess(array $params, Submission $submission, bool $silentFailure = false): Response|RedirectResponse
{
$redirect = $this->formSuccessRedirect($params, $submission);
if (request()->ajax() || request()->wantsJson()) {
return response([
'success' => true,
'submission_created' => ! $silentFailure,
'submission' => $submission->data(),
'redirect' => $redirect,
]);
}
$response = $redirect ? redirect($redirect) : back();
if (! \Statamic\Facades\URL::isExternal($redirect)) {
session()->flash("form.{$submission->form()->handle()}.success", __('Submission successful.'));
session()->flash("form.{$submission->form()->handle()}.submission_created", ! $silentFailure);
session()->flash('submission', $submission);
}
return $response;
}
private function formSuccessRedirect(array $params, Submission $submission): ?string
{
if ($redirect = Form::getSubmissionRedirect($submission)) {
return $redirect;
}
$redirect = Arr::get($params, '_redirect');
if ($redirect && \Statamic\Facades\URL::isExternalToApplication($redirect)) {
return null;
}
return $redirect;
}
}