PluginProbe
The Innovative Form Builder – IvyForms / 1.5.1
The Innovative Form Builder – IvyForms v1.5.1
1.5.1 1.5 1.4.1 1.4 trunk 0.1.2 0.2 0.2.1 0.3 0.3.1 0.4 0.5 0.6 0.6.1 0.6.1-backup 0.6.1.1 0.7 0.8 0.8.1 0.8.2 0.9 0.9.1 1.0 1.1 1.1.1 All 27 releases
← All changes | backend/src/Controllers/Form/FormSubmissionController.php +32 -142 1.0 → 1.5.1 View file →
@@ -10,21 +10,13 @@
10 10 use IvyForms\Common\Exceptions\ForbiddenException;
11 11 use IvyForms\Common\Exceptions\InvalidArgumentException;
12 12 use IvyForms\Common\Exceptions\NotFoundException;
13 13 use IvyForms\Common\Exceptions\ValidationException;
14 -use IvyForms\Common\Helpers\EntryHelper;
15 14 use IvyForms\Common\Sanitizer\Sanitizer;
16 15 use IvyForms\Controllers\Controller;
17 -use IvyForms\Factory\Entry\EntryFactory;
18 -use IvyForms\Services\Confirmation\ConfirmationService;
19 -use IvyForms\Services\Entry\EntryService;
20 -use IvyForms\Services\Field\FieldService;
21 -use IvyForms\Services\Field\FieldType;
22 -use IvyForms\Services\Form\FormService;
23 -use IvyForms\Services\Mailer\MailerService;
24 -use IvyForms\Services\Notification\NotificationService;
25 -use IvyForms\Services\Placeholder\PlaceholderService;
26 -use IvyForms\Services\Security\SecurityService;
16 +use IvyForms\Infrastructure\WP\REST\SubmissionMultipartReader;
17 +use IvyForms\Services\Submission\FormSubmissionService;
18 +use IvyForms\Services\Submission\SubmissionPayloadParser;
27 19 use IvyForms\Services\Translations\BackendStrings;
28 20 use WP_REST_Request;
29 21 use WP_REST_Response;
30 22
@@ -34,32 +26,13 @@
34 26 * @package IvyForms\Controllers\Form
35 27 */
36 28 class FormSubmissionController extends Controller
37 29 {
38 - private FormService $formService;
39 - private FieldService $fieldService;
40 - private NotificationService $notificationService;
41 - private MailerService $mailerService;
42 - private EntryService $entryService;
43 - private SecurityService $securityService;
44 - private ConfirmationService $confirmationService;
30 + private FormSubmissionService $formSubmissionService;
45 31
46 - public function __construct(
47 - FormService $formService,
48 - FieldService $fieldService,
49 - NotificationService $notificationService,
50 - MailerService $mailerService,
51 - EntryService $entryService,
52 - SecurityService $securityService,
53 - ConfirmationService $confirmationService
54 - ) {
55 - $this->formService = $formService;
56 - $this->fieldService = $fieldService;
57 - $this->notificationService = $notificationService;
58 - $this->mailerService = $mailerService;
59 - $this->entryService = $entryService;
60 - $this->securityService = $securityService;
61 - $this->confirmationService = $confirmationService;
32 + public function __construct(FormSubmissionService $formSubmissionService)
33 + {
34 + $this->formSubmissionService = $formSubmissionService;
62 35 }
63 36
64 37 /**
65 38 * @param WP_REST_Request $data
@@ -68,128 +41,45 @@
68 41 *
69 42 * @throws InvalidArgumentException|NotFoundException|ForbiddenException
70 43 * @throws ValidationException
71 44 */
72 - public function handle(WP_REST_Request $data): WP_REST_Response
45 + protected function handle(WP_REST_Request $data): WP_REST_Response
73 46 {
74 47 Sanitizer::verifyNonce($data->get_header('X-WP-Nonce'));
75 48
76 - if (empty($data->get_params())) {
77 - throw new InvalidArgumentException(
78 - BackendStrings::getExceptionStrings()['invalid_request_data']
79 - );
80 - }
49 + $params = SubmissionPayloadParser::parseRequestPayload($data);
50 + $formId = Sanitizer::sanitizeId((int) ($params['formId'] ?? 0));
51 + Sanitizer::verifySubmissionNonce(isset($params['nonce']) ? (string) $params['nonce'] : null, $formId);
81 52
82 - $formId = Sanitizer::sanitizeId($data->get_param('formId'));
83 - Sanitizer::verifySubmissionNonce($data->get_param('nonce'), $formId);
53 + $uploadedFiles = SubmissionMultipartReader::resolveUploadedFiles($data);
54 + $result = $this->formSubmissionService->processSubmission($params, $uploadedFiles);
84 55
85 - if ($formId <= 0) {
86 - throw new InvalidArgumentException(
87 - BackendStrings::getExceptionStrings()['invalid_form_id']
88 - );
56 + if (!empty($result['requires_action'])) {
57 + return new WP_REST_Response([
58 + 'message' => BackendStrings::getCommonStrings()['ok'],
59 + 'data' => [
60 + 'success' => false,
61 + 'requires_action' => true,
62 + 'client_secret' => $result['client_secret'] ?? null,
63 + 'payment_intent_id' => $result['payment_intent_id'] ?? null,
64 + 'payment_method' => $result['payment_method'] ?? 'stripe',
65 + ],
66 + ], 200);
89 67 }
90 68
91 - $form = $this->formService->getFormById($formId);
92 - $formFields = $this->fieldService->getAllFields($form->getId());
93 -
94 - $this->fieldService->validateFieldsType($formFields);
95 -
96 - // Build fieldLabels mapping for placeholders
97 - $fieldLabels = PlaceholderService::buildFieldLabels($formFields);
98 -
99 - // Validate CAPTCHA if present using SecurityService (automatically determines provider and validates)
100 - $this->securityService->validateFormSubmission($data->get_params(), $formFields);
101 -
102 - // Sanitize form submission data based on field types
103 - $submissionData = Sanitizer::sanitizeFormSubmissionData($data->get_params(), $formFields);
104 -
105 - [$isDuplicate, $duplicateErrors] = $this->fieldService->checkDuplicateFieldValues(
106 - $formFields,
107 - $submissionData,
108 - $formId
109 - );
110 - if ($isDuplicate) {
69 + if (!empty($result['payment_error'])) {
111 70 return new WP_REST_Response([
112 - 'data' => [
113 - 'success' => null,
114 - 'entry' => ['stored' => false],
115 - 'confirmation' => null,
116 - 'is_duplicate' => true,
117 - 'duplicate_errors' => $duplicateErrors,
71 + 'message' => (string) (
72 + $result['message'] ?? BackendStrings::getPaymentStrings()['payment_failed']
73 + ),
74 + 'data' => [
75 + 'success' => false,
76 + 'payment_error' => true,
118 77 ],
119 78 ], 200);
120 79 }
121 80
122 - $entryId = null;
123 - $entry = [
124 - 'stored' => false
125 - ];
126 - /**
127 - * Allow to hook before form submission for integrations
128 - * @since 0.1.0
129 - *
130 - * Arguments:
131 - * - int $formId The ID of the form being submitted
132 - * - array $submissionData The form submission data (field values)
133 - * - array $formFields The form field definitions
134 - */
135 - do_action('ivyforms/form/before_submission', $formId, $submissionData, $formFields);
136 -
137 - if ($form->isStoreEntries()) {
138 - $entryData = EntryHelper::buildEntryData($formId);
139 - $entryObj = EntryFactory::create($entryData);
140 - $entryId = $this->entryService->getEntryManager()->createEntry($entryObj);
141 - $this->entryService->getEntryFieldManager()->addEntryFields($formFields, $entryId, $submissionData);
142 - $entry = [
143 - 'stored' => true,
144 - 'id' => $entryId,
145 - ];
146 - }
147 -
148 - // Build field and general entry data for placeholders
149 - $fieldData = PlaceholderService::buildFieldData($formFields, $submissionData);
150 - $generalData = PlaceholderService::buildGeneralData($entryId ?? 0, $submissionData);
151 -
152 - // Use NotificationService for notifications
153 - // Note: Notification messages are sanitized inside processNotifications() method
154 - // to allow signature images with data: URIs (using Sanitizer::sanitizeHtmlContent)
155 - $notificationsResult = $this->notificationService->processNotifications(
156 - $formId,
157 - $submissionData,
158 - $fieldData,
159 - $generalData,
160 - $this->mailerService,
161 - $fieldLabels
162 - );
163 - // Use ConfirmationService for confirmations
164 - $confirmationMessage = $this->confirmationService->processConfirmations(
165 - $formId,
166 - $fieldData,
167 - $generalData,
168 - $fieldLabels
169 - );
170 -
171 - // Sanitize confirmation message HTML to preserve colors and formatting
172 - $safeConfirmationMessage = Sanitizer::sanitizeEditorContent($confirmationMessage);
173 -
174 - /**
175 - * Allow to hook after form submission for integrations
176 - * @since 0.1.0
177 - *
178 - * Arguments:
179 - * - int $formId The ID of the form being submitted
180 - * - array $submissionData The form submission data (field values)
181 - * - array $formFields The form field definitions
182 - * - int|null $entryId The entry ID if entry storage is enabled
183 - */
184 - do_action('ivyforms/form/after_submission', $formId, $submissionData, $formFields, $entryId);
185 -
186 81 return new WP_REST_Response([
187 - 'message' => BackendStrings::getCommonStrings()['ok'],
188 - 'data' => [
189 - 'success' => $notificationsResult,
190 - 'entry' => $entry,
191 - 'confirmation' => $safeConfirmationMessage,
192 - ],
82 + 'data' => $result,
193 83 ], 200);
194 84 }
195 85 }