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
ivyforms / backend / src / Common / Helpers / McpHelpers / McpMultiPageHelper.php

McpMultiPageHelper.php in The Innovative Form Builder – IvyForms 1.5, at backend/src/Common/Helpers/McpHelpers/McpMultiPageHelper.php

248 lines 7.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * @copyright © Melograno Venture Studio. All rights reserved.
5 * @licence See COPYING.md for license details.
6 */
7
8 namespace IvyForms\Common\Helpers\McpHelpers;
9
10 use IvyForms\Services\API\IvyFormsAPI;
11 use IvyForms\Services\Translations\BackendStrings;
12
13 /**
14 * Multipage form helpers for IvyForms MCP abilities.
15 */
16 class McpMultiPageHelper
17 {
18 /**
19 * @return array<string, mixed>|null Error payload when Pro is inactive.
20 */
21 public static function proRequiredError(int $formId): ?array
22 {
23 if (IvyFormsAPI::isProPluginActive()) {
24 return null;
25 }
26
27 return McpMultiPagePersistenceHelper::errorResponse(
28 $formId,
29 self::multipageStrings()['multipage_pro_required']
30 );
31 }
32
33 /**
34 * Configure multipage structure (pages + optional progress indicator) on an existing form.
35 *
36 * @param array<string, mixed> $input
37 * @return array<string, mixed>
38 */
39 public static function setupMultipageForm(array $input): array
40 {
41 $formId = (int) ($input['formId'] ?? 0);
42 $validationError = McpMultiPagePersistenceHelper::validateFormIdAndPro($formId);
43 if ($validationError !== null) {
44 return $validationError;
45 }
46
47 $pageInputs = $input['pages'] ?? [];
48 if (!is_array($pageInputs) || $pageInputs === []) {
49 return McpMultiPagePersistenceHelper::errorResponse(
50 $formId,
51 self::multipageStrings()['at_least_one_page_required']
52 );
53 }
54
55 $form = McpMultiPagePersistenceHelper::loadFormOrNull($formId);
56 if ($form === null) {
57 return McpMultiPagePersistenceHelper::errorResponse(
58 $formId,
59 McpMultiPagePersistenceHelper::formNotFoundMessage($formId)
60 );
61 }
62
63 $builtPages = McpMultiPagePagesHelper::buildPagesFromInput($pageInputs);
64 if ($builtPages === []) {
65 return McpMultiPagePersistenceHelper::errorResponse(
66 $formId,
67 self::multipageStrings()['no_valid_page_definitions']
68 );
69 }
70
71 $form['pages'] = $builtPages;
72 $form = McpMultiPagePagesHelper::mergeProgressIndicator($form, $input);
73
74 $validPageIds = McpMultiPagePagesHelper::collectPageIds($builtPages);
75 $form['fields'] = McpMultiPagePagesHelper::applyFieldPageAssignments(
76 $form['fields'] ?? [],
77 $input['fieldAssignments'] ?? [],
78 $validPageIds,
79 (string) $builtPages[0]['id']
80 );
81
82 return McpMultiPagePersistenceHelper::persistForm(
83 $formId,
84 $form,
85 self::multipageStrings()['multipage_configured_successfully']
86 );
87 }
88
89 /**
90 * Append a page to an existing multipage form.
91 *
92 * @param array<string, mixed> $input
93 * @return array<string, mixed>
94 */
95 public static function addFormPage(array $input): array
96 {
97 $formId = (int) ($input['formId'] ?? 0);
98 $validationError = McpMultiPagePersistenceHelper::validateFormIdAndPro($formId);
99 if ($validationError !== null) {
100 return $validationError;
101 }
102
103 $label = sanitize_text_field((string) ($input['label'] ?? ''));
104 if ($label === '') {
105 return McpMultiPagePersistenceHelper::errorResponse(
106 $formId,
107 self::multipageStrings()['page_label_required']
108 );
109 }
110
111 $form = McpMultiPagePersistenceHelper::loadFormOrNull($formId);
112 if ($form === null) {
113 return McpMultiPagePersistenceHelper::errorResponse(
114 $formId,
115 McpMultiPagePersistenceHelper::formNotFoundMessage($formId)
116 );
117 }
118
119 $existingPages = McpMultiPagePagesHelper::stripFieldsFromPages($form['pages'] ?? []);
120 if ($existingPages === []) {
121 $existingPages = McpMultiPagePagesHelper::defaultFirstPage();
122 }
123
124 $newPage = [
125 'id' => 'mcp_page_' . wp_generate_password(8, false, false),
126 'label' => $label,
127 'closable' => true,
128 ];
129
130 $insertAfterPageId = sanitize_text_field((string) ($input['insertAfterPageId'] ?? ''));
131 $form['pages'] = McpMultiPagePagesHelper::insertPage($existingPages, $newPage, $insertAfterPageId);
132 $form = McpMultiPagePagesHelper::mergeProgressIndicator($form, []);
133
134 $result = McpMultiPagePersistenceHelper::persistForm(
135 $formId,
136 $form,
137 self::multipageStrings()['form_page_added_successfully']
138 );
139
140 return McpMultiPagePagesHelper::enrichResultWithAddedPage($result, $label);
141 }
142
143 /**
144 * @param array<string, mixed> $field
145 */
146 public static function applyPageIdToField(array &$field, string $pageId): void
147 {
148 $field['pageId'] = $pageId;
149
150 if (!isset($field['settings']) || !is_array($field['settings'])) {
151 $field['settings'] = [];
152 }
153
154 $field['settings']['pageId'] = $pageId;
155 }
156
157 /**
158 * @param array<string, mixed> $field
159 */
160 public static function extractFieldPageId(array $field): ?string
161 {
162 $pageId = isset($field['pageId']) ? sanitize_text_field((string) $field['pageId']) : '';
163 if ($pageId !== '') {
164 return $pageId;
165 }
166
167 if (isset($field['settings']) && is_array($field['settings'])) {
168 $settingsPageId = sanitize_text_field((string) ($field['settings']['pageId'] ?? ''));
169 if ($settingsPageId !== '') {
170 return $settingsPageId;
171 }
172 }
173
174 return null;
175 }
176
177 /**
178 * @param array<string, mixed> $form
179 */
180 public static function resolveDefaultPageIdForForm(array $form): ?string
181 {
182 $pages = $form['pages'] ?? [];
183 if (!is_array($pages) || $pages === []) {
184 return null;
185 }
186
187 $firstPage = $pages[0] ?? null;
188 if (!is_array($firstPage)) {
189 return 'page_1';
190 }
191
192 $pageId = sanitize_text_field((string) ($firstPage['id'] ?? ''));
193 return $pageId !== '' ? $pageId : 'page_1';
194 }
195
196 /**
197 * @param array<string, mixed> $form
198 */
199 public static function normalizePageIdForForm(string $rawPageId, array $form): ?string
200 {
201 $pageId = sanitize_text_field($rawPageId);
202 if ($pageId === '') {
203 return self::resolveDefaultPageIdForForm($form);
204 }
205
206 $pages = $form['pages'] ?? [];
207 if (!is_array($pages) || $pages === []) {
208 return $pageId;
209 }
210
211 $validPageIds = McpMultiPagePagesHelper::collectPageIds($pages);
212 if (in_array($pageId, $validPageIds, true)) {
213 return $pageId;
214 }
215
216 if (preg_match('/^page_(\d+)$/', $pageId, $matches) === 1) {
217 $index = (int) $matches[1] - 1;
218 if (isset($validPageIds[$index])) {
219 return $validPageIds[$index];
220 }
221 }
222
223 return null;
224 }
225
226 /**
227 * @return array<string, mixed>
228 */
229 public static function defaultProgressIndicator(): array
230 {
231 return [
232 'type' => 'progress-bar',
233 'showPageTitles' => true,
234 'hidePageNumbers' => false,
235 'hideConnectingLines' => false,
236 ];
237 }
238
239 /**
240 * @return array<string, string>
241 */
242 private static function multipageStrings(): array
243 {
244 /** @var array<string, string> */
245 return BackendStrings::getMcpMultipageStrings();
246 }
247 }
248