PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.13
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.13
6.2.14 6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 3.6.65 All 196 releases
fluentform / app / Http / Controllers / SubmissionController.php

SubmissionController.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 6.2.13, at app/Http/Controllers/SubmissionController.php

287 lines 9.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentForm\App\Http\Controllers;
4
5 use Exception;
6 use FluentForm\App\Models\Submission;
7 use FluentForm\App\Modules\Acl\Acl;
8 use FluentForm\App\Services\Submission\SubmissionService;
9 use FluentForm\Framework\Support\Arr;
10
11 class SubmissionController extends Controller
12 {
13 public function index(SubmissionService $submissionService)
14 {
15 try {
16 $attributes = $this->sanitizeSubmissionAttributes($this->request->all());
17
18 return $this->sendSuccess(
19 $submissionService->get($attributes)
20 );
21 } catch (Exception $e) {
22 return $this->sendError([
23 'message' => $e->getMessage(),
24 ]);
25 }
26 }
27
28 public function find(SubmissionService $submissionService, $submissionId)
29 {
30 try {
31 return $this->sendSuccess(
32 $submissionService->find($submissionId)
33 );
34 } catch (Exception $e) {
35 return $this->sendError([
36 'message' => $e->getMessage(),
37 ]);
38 }
39 }
40
41 public function resources(SubmissionService $submissionService)
42 {
43 try {
44 $attributes = $this->request->all();
45
46 $sanitizeMap = [
47 'form_id' => 'intval',
48 ];
49 $attributes = fluentform_backend_sanitizer($attributes, $sanitizeMap);
50
51 // SECURITY (FINDING-02): this route has no {entry_id} placeholder, so SubmissionPolicy
52 // authorizes the form owning the *request* entry_id, while resources() then reads a
53 // separate form_id — letting a form-scoped user read another form's counts/labels/
54 // fields and (via next/previous) submission rows. Re-verify the caller may view
55 // entries of the form actually being queried.
56 $formId = (int) Arr::get($attributes, 'form_id');
57 if (!$formId || !Acl::hasPermission('fluentform_entries_viewer', $formId)) {
58 return $this->sendError([
59 'message' => __('You do not have permission to view this form\'s entries.', 'fluentform'),
60 ], 403);
61 }
62
63 return $this->sendSuccess(
64 $submissionService->resources($attributes)
65 );
66 } catch (Exception $e) {
67 return $this->sendError([
68 'message' => $e->getMessage(),
69 ]);
70 }
71 }
72
73 public function updateStatus(SubmissionService $submissionService, $submissionId)
74 {
75 try {
76 $attributes = $this->request->all();
77 $attributes['entry_id'] = intval($submissionId);
78 $status = $submissionService->updateStatus($attributes);
79
80 /* translators: %s is the submission status */
81 $message = sprintf(__('The submission has been marked as %s', 'fluentform'), $status);
82
83 return $this->sendSuccess([
84 'message' => $message,
85 'status' => $status,
86 ]);
87 } catch (Exception $e) {
88 return $this->sendError([
89 'message' => $e->getMessage(),
90 ]);
91 }
92 }
93
94 public function toggleIsFavorite(SubmissionService $submissionService, $submissionId)
95 {
96 try {
97 [$message, $isFavourite] = $submissionService->toggleIsFavorite(
98 intval($submissionId)
99 );
100
101 return $this->sendSuccess([
102 'message' => $message,
103 'is_favourite' => $isFavourite,
104 ]);
105 } catch (Exception $e) {
106 return $this->sendError([
107 'message' => $e->getMessage(),
108 ]);
109 }
110 }
111
112 public function handleBulkActions(SubmissionService $submissionService)
113 {
114 try {
115 $message = $submissionService->handleBulkActions($this->request->all());
116
117 return $this->sendSuccess(['message' => $message]);
118 } catch (Exception $e) {
119 return $this->sendError([
120 'message' => $e->getMessage(),
121 ]);
122 }
123 }
124
125 public function remove(SubmissionService $submissionService, $submissionId)
126 {
127 try {
128 $submission = Submission::findOrFail($submissionId);
129 $submissionService->deleteEntries([$submissionId], $submission->form_id);
130 do_action('fluentform/submission_deleted', $submissionId);
131
132 return $this->sendSuccess([
133 'message' => __('Selected submission successfully deleted Permanently', 'fluentform'),
134 ]);
135
136 } catch (Exception $e) {
137 return $this->sendError([
138 'message' => $e->getMessage(),
139 ]);
140 }
141 }
142
143 /**
144 * Get user list for submission page
145 *
146 * @return \WP_REST_Response
147 */
148 public function submissionUsers()
149 {
150 // SECURITY (FINDING-21): don't let a lower-tier user enumerate the whole WP roster here.
151 // Require WP's list_users OR the FF entries-manager permission this feature is built for —
152 // a delegated non-admin manager holds fluentform_manage_entries (and the assign-user UI is
153 // shown only to them) but NOT core list_users, so gating on list_users alone broke them.
154 if (!current_user_can('list_users') && !current_user_can('fluentform_manage_entries')) {
155 return $this->sendError(['message' => __('You do not have permission to list users.', 'fluentform')], 403);
156 }
157 $search = sanitize_text_field($this->request->get('search'));
158 $users = get_users([
159 'search' => "*{$search}*",
160 'number' => 50,
161 ]);
162
163 $formattedUsers = [];
164 foreach ($users as $user) {
165 $formattedUsers[] = [
166 'ID' => $user->ID,
167 'label' => $user->display_name . ' - ' . $user->user_email,
168 ];
169 }
170
171 return $this->sendSuccess([
172 'users' => $formattedUsers,
173 ]);
174 }
175
176 /**
177 * Update User of a submission
178 *
179 * @param SubmissionService $submissionService
180 * @param int $submissionId
181 * @return \WP_REST_Response
182 */
183 public function updateSubmissionUser(SubmissionService $submissionService, $submissionId)
184 {
185 try {
186 $userId = intval($this->request->get('user_id'));
187 $submissionId = intval($submissionId);
188 $response = $submissionService->updateSubmissionUser($userId, $submissionId);
189 return $this->sendSuccess($response);
190 } catch (Exception $e) {
191 return $this->sendError([
192 'message' => $e->getMessage(),
193 ]);
194 }
195 }
196
197 /**
198 * Get All Submissions
199 *
200 * @param Submission $submission
201 * @return \WP_REST_Response
202 */
203 public function all(Submission $submission)
204 {
205 try {
206 $attributes = $this->sanitizeSubmissionAttributes($this->request->all());
207
208 return $this->sendSuccess(
209 $submission->allSubmissions($attributes)
210 );
211 } catch (Exception $e) {
212 return $this->sendError([
213 'message' => $e->getMessage(),
214 ]);
215 }
216 }
217 /**
218 * Get printable content
219 *
220 * @param SubmissionService $submissionService
221 * @return \WP_REST_Response
222 */
223 public function print(SubmissionService $submissionService)
224 {
225 try {
226 $attributes = $this->request->all();
227
228 $sanitizeMap = [
229 'submission_ids' => function ($value) {
230 if (is_array($value)) {
231 return array_map('intval', $value);
232 }
233 return [];
234 },
235 'form_id' => 'intval',
236 ];
237 $attributes = fluentform_backend_sanitizer($attributes, $sanitizeMap);
238
239 // Preserve backward compatibility with any legacy callers that still
240 // send entry_ids, while normalizing to the current submission_ids key.
241 if (empty($attributes['submission_ids']) && isset($attributes['entry_ids'])) {
242 $entryIds = $attributes['entry_ids'];
243 $attributes['submission_ids'] = is_array($entryIds)
244 ? array_map('intval', $entryIds)
245 : [];
246 }
247
248 return $this->sendSuccess(
249 $submissionService->getPrintContent($attributes)
250 );
251 } catch (Exception $e) {
252 return $this->sendError([
253 'message' => $e->getMessage(),
254 ]);
255 }
256 }
257
258 private function sanitizeSubmissionAttributes($attributes)
259 {
260 $sanitizeMap = [
261 'search' => 'sanitize_text_field',
262 'status' => 'sanitize_text_field',
263 'entry_type' => 'sanitize_text_field',
264 'form_id' => 'intval',
265 'per_page' => 'intval',
266 'page' => 'intval',
267 'is_favourite' => 'rest_sanitize_boolean',
268 ];
269
270 $attributes = fluentform_backend_sanitizer($attributes, $sanitizeMap);
271
272 if (isset($attributes['entry_type']) && !isset($attributes['status'])) {
273 $attributes['status'] = $attributes['entry_type'];
274 }
275
276 if (isset($attributes['date_range']) && is_array($attributes['date_range'])) {
277 $attributes['date_range'] = array_map('sanitize_text_field', $attributes['date_range']);
278 }
279
280 if (isset($attributes['payment_statuses']) && is_array($attributes['payment_statuses'])) {
281 $attributes['payment_statuses'] = array_map('sanitize_text_field', $attributes['payment_statuses']);
282 }
283
284 return $attributes;
285 }
286 }
287