PluginProbe
The Innovative Form Builder – IvyForms / 1.5
The Innovative Form Builder – IvyForms v1.5
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/AddFormController.php +46 -95 0.3.1 → 1.5 View file →
@@ -1,18 +1,13 @@
1 1 <?php
2 2
3 3 /**
4 - * @copyright © TMS-Plugins. All rights reserved.
4 + * @copyright © Melograno Venture Studio. All rights reserved.
5 5 * @licence See COPYING.md for license details.
6 6 */
7 7
8 8 namespace IvyForms\Controllers\Form;
9 9
10 -// phpcs:disable PSR1.Files.SideEffects
11 -if (!defined('ABSPATH')) {
12 - exit; // Exit if accessed directly
13 -}
14 -
15 10 use IvyForms\Common\Exceptions\ForbiddenException;
16 11 use IvyForms\Common\Exceptions\InvalidArgumentException;
17 12 use IvyForms\Common\Exceptions\QueryExecutionException;
18 13 use IvyForms\Common\Exceptions\ValidationException;
@@ -17,17 +12,9 @@
17 12 use IvyForms\Common\Exceptions\QueryExecutionException;
18 13 use IvyForms\Common\Exceptions\ValidationException;
19 14 use IvyForms\Common\Sanitizer\Sanitizer;
20 15 use IvyForms\Controllers\Controller;
21 -use IvyForms\Factory\Field\FieldFactory;
22 -use IvyForms\Factory\Form\FormFactory;
23 -use IvyForms\Factory\Notification\NotificationFactory;
24 -use IvyForms\Factory\Confirmation\ConfirmationFactory;
25 -use IvyForms\Services\Field\FieldService;
26 -use IvyForms\Services\Form\FormService;
27 -use IvyForms\Services\Notification\NotificationService;
28 -use IvyForms\Services\Confirmation\ConfirmationService;
29 -use IvyForms\Services\Template\BlankFormTemplate;
16 +use IvyForms\Services\Form\FormCreateService;
30 17 use IvyForms\Services\Template\TemplateService;
31 18 use WP_REST_Request;
32 19 use WP_REST_Response;
33 20 use IvyForms\Services\Translations\BackendStrings;
@@ -38,26 +25,17 @@
38 25 * @package IvyForms\Controllers\Form
39 26 */
40 27 class AddFormController extends Controller
41 28 {
42 - private FormService $formService;
43 - private FieldService $fieldService;
44 - private NotificationService $notificationService;
45 - private ConfirmationService $confirmationService;
29 + private FormCreateService $formCreateService;
46 30 private TemplateService $templateService;
47 31
48 32 public function __construct(
49 - FormService $formService,
50 - FieldService $fieldService,
51 - NotificationService $notificationService,
52 - ConfirmationService $confirmationService,
33 + FormCreateService $formCreateService,
53 34 TemplateService $templateService
54 35 ) {
55 - $this->formService = $formService;
56 - $this->fieldService = $fieldService;
57 - $this->notificationService = $notificationService;
58 - $this->confirmationService = $confirmationService;
59 - $this->templateService = $templateService;
36 + $this->formCreateService = $formCreateService;
37 + $this->templateService = $templateService;
60 38 }
61 39
62 40 /**
63 41 * @param WP_REST_Request<array<string, mixed>> $data
@@ -72,9 +50,8 @@
72 50 public function handle(WP_REST_Request $data): WP_REST_Response
73 51 {
74 52 Sanitizer::verifyNonce($data->get_header('X-WP-Nonce'));
75 53
76 - // Check if the form data is provided
77 54 if (empty($data->get_params())) {
78 55 throw new InvalidArgumentException(
79 56 BackendStrings::getExceptionStrings()['invalid_request_data']
80 57 );
@@ -79,86 +56,60 @@
79 56 BackendStrings::getExceptionStrings()['invalid_request_data']
80 57 );
81 58 }
82 59
83 - // TODO Add validation for template_id with Sanitizer
84 - //$templateId = Sanitizer::sanitizeText($data->get_param('id'));
85 60 $templateId = sanitize_text_field($data->get_param('template_id'));
86 61
87 - if (empty($templateId)) {
88 - throw new InvalidArgumentException(
89 - BackendStrings::getTemplateStrings()['template_not_found']
90 - );
62 + $mergedParams = $data->get_params();
63 + $formData = [];
64 + if (!empty($templateId)) {
65 + $formData = $this->templateService->getFormDataFromTemplate($templateId);
91 66 }
92 - $formData = $this->templateService->getFormDataFromTemplate($templateId);
93 - $params = Sanitizer::sanitizeFormData($formData);
94 - $form = FormFactory::create($params);
67 + /**
68 + * Keys the client may override on create. When creating from a template, field
69 + * structure and layout always come from TemplateService — not the builder store.
70 + * Merging frontend fields caused duplicate name/address rows and single-row layout.
71 + *
72 + * @param list<string> $keys
73 + */
74 + $mergeableKeys = apply_filters('ivyforms/form/add/mergeable_keys', [
75 + 'name',
76 + 'description',
77 + 'published',
78 + 'showTitle',
79 + 'showDescription',
80 + 'storeEntries',
81 + 'fields',
82 + 'integrationSettings',
83 + 'styleSettings',
84 + 'formActionButtons',
85 + 'formType',
86 + ]);
95 87
96 - $formId = $this->formService->createForm($form);
97 - if (!$formId) {
98 - throw new QueryExecutionException(
99 - BackendStrings::getAllFormsStrings()['failed_to_create_form']
100 - );
101 - }
102 -
103 - $adminEmail = get_option('admin_email');
104 -
105 - $defaultNotification = [
106 - 'formId' => $formId,
107 - 'name' => BackendStrings::getAllFormsStrings()['admin_notification_email'],
108 - 'sender' => $adminEmail,
109 - 'receiver' => $adminEmail,
110 - 'enabled' => 1,
111 - 'subject' => $params['name'],
112 - 'message' => '{all_data}',
113 - 'smartLogic' => 0,
88 + $templateLockedKeys = [
89 + 'fields',
90 + 'integrationSettings',
91 + 'styleSettings',
92 + 'formActionButtons',
114 93 ];
115 94
116 - $notification = NotificationFactory::create($defaultNotification);
117 - $notificationId = $this->notificationService->createNotification($notification);
95 + foreach ($mergeableKeys as $key) {
96 + if (!array_key_exists($key, $mergedParams)) {
97 + continue;
98 + }
118 99
119 - if (!$notificationId) {
120 - throw new QueryExecutionException(
121 - BackendStrings::getSettingsFormBuilderStrings()['failed_to_create_default_notification']
122 - );
123 - }
100 + if (!empty($templateId) && in_array($key, $templateLockedKeys, true)) {
101 + continue;
102 + }
124 103
125 - $notification->setId($notificationId);
126 -
127 - $defaultConfirmation = [
128 - 'formId' => $formId,
129 - 'type' => 'successMessage',
130 - 'enabled' => 1,
131 - 'showForm' => 0,
132 - 'message' => BackendStrings::getAllFormsStrings()['thanks_reaching'],
133 - 'url' => '',
134 - 'page' => '',
135 - ];
136 -
137 - $confirmation = ConfirmationFactory::create($defaultConfirmation);
138 - $confirmationId = $this->confirmationService->createConfirmation($confirmation);
139 -
140 - if (!$confirmationId) {
141 - throw new QueryExecutionException(
142 - BackendStrings::getSettingsFormBuilderStrings()['failed_to_create_confirmation']
143 - );
104 + $formData[$key] = $mergedParams[$key];
144 105 }
145 106
146 - $confirmation->setId($confirmationId);
107 + $params = Sanitizer::sanitizeFormData($formData);
108 + $created = $this->formCreateService->createFromSanitizedParams($params);
147 109
148 - // Save form fields
149 - if (!empty($params['fields'])) {
150 - foreach ($params['fields'] as $fieldData) {
151 - $fieldData['formId'] = $fieldData['formId'] ?? $formId;
152 - $field = FieldFactory::create($fieldData);
153 - $this->fieldService->addField($field);
154 - }
155 - }
156 -
157 - $form->setId($formId);
158 -
159 110 return new WP_REST_Response([
160 111 'message' => BackendStrings::getCommonStrings()['ok'],
161 - 'data' => array_merge($form->toArray(), ['confirmationId' => $confirmationId])
112 + 'data' => $created,
162 113 ], 200);
163 114 }
164 115 }