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
ivyforms / backend / src / Services / Ai / AiFormCompoundFieldExpander.php

AiFormCompoundFieldExpander.php in The Innovative Form Builder – IvyForms 1.5.1, at backend/src/Services/Ai/AiFormCompoundFieldExpander.php

229 lines 6.6 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 LICENCE.md for license details.
6 */
7
8 namespace IvyForms\Services\Ai;
9
10 use IvyForms\Common\Helpers\McpHelpers\McpFieldPayloadHelper;
11
12 /**
13 * Expands compound AI field parents (name, address, likert) into child rows.
14 */
15 class AiFormCompoundFieldExpander
16 {
17 /**
18 * @return array{children: list<array<string, mixed>>, nextId: int}
19 */
20 public function expand(
21 string $type,
22 int $parentFieldIndex,
23 bool $parentRequired,
24 int $nextId,
25 ?string $pageId = null
26 ): array {
27 if ($type === 'likert') {
28 return $this->expandLikert($parentFieldIndex, $nextId, $pageId);
29 }
30
31 if ($type === 'name') {
32 return $this->expandName($parentFieldIndex, $parentRequired, $nextId, $pageId);
33 }
34
35 if ($type === 'address') {
36 return $this->expandAddress($parentFieldIndex, $parentRequired, $nextId, $pageId);
37 }
38
39 return [
40 'children' => [],
41 'nextId' => $nextId,
42 ];
43 }
44
45 /**
46 * @return array{children: list<array<string, mixed>>, nextId: int}
47 */
48 private function expandName(
49 int $parentFieldIndex,
50 bool $parentRequired,
51 int $nextId,
52 ?string $pageId
53 ): array {
54 $rawChildren = McpFieldPayloadHelper::compoundChildFields(
55 'name',
56 0,
57 $parentFieldIndex,
58 $parentFieldIndex
59 );
60
61 $children = [];
62 foreach ($rawChildren as $index => $child) {
63 if (!is_array($child)) {
64 continue;
65 }
66
67 $settings = $this->decodeSettings($child['settings'] ?? null);
68 $nameFieldType = (string) ($settings['nameFieldType'] ?? ('nameField' . ($index + 1)));
69 $child = $this->baseChild($child, $nextId++, $parentFieldIndex, $index, $pageId);
70 $child['nameFieldType'] = $nameFieldType;
71 $child['required'] = $parentRequired;
72 $child['settings'] = array_merge(
73 is_array($child['settings'] ?? null) ? $child['settings'] : [],
74 [
75 'nameFieldType' => $nameFieldType,
76 'subFieldIndex' => $index,
77 ]
78 );
79 $children[] = $child;
80 }
81
82 return [
83 'children' => $children,
84 'nextId' => $nextId,
85 ];
86 }
87
88 /**
89 * @return array{children: list<array<string, mixed>>, nextId: int}
90 */
91 private function expandAddress(
92 int $parentFieldIndex,
93 bool $parentRequired,
94 int $nextId,
95 ?string $pageId
96 ): array {
97 $rawChildren = McpFieldPayloadHelper::compoundChildFields(
98 'address',
99 0,
100 $parentFieldIndex,
101 $parentFieldIndex
102 );
103 $defaults = ['streetAddress', 'addressLine2', 'city', 'state', 'zip', 'country'];
104
105 $children = [];
106 foreach ($rawChildren as $index => $child) {
107 if (!is_array($child)) {
108 continue;
109 }
110
111 $settings = $this->decodeSettings($child['settings'] ?? null);
112 $addressType = (string) (
113 $settings['addressFieldType']
114 ?? $settings['type']
115 ?? $child['addressType']
116 ?? ($defaults[$index] ?? ('addressPart' . ($index + 1)))
117 );
118
119 $child = $this->baseChild($child, $nextId++, $parentFieldIndex, $index, $pageId);
120 $child['addressType'] = $addressType;
121 $child['required'] = $addressType === 'addressLine2' ? false : $parentRequired;
122 $child['visible'] = true;
123 $child['settings'] = array_merge(
124 is_array($child['settings'] ?? null) ? $child['settings'] : [],
125 [
126 'type' => $addressType,
127 'hideLabel' => false,
128 'description' => '',
129 'placeholder' => (string) ($child['placeholder'] ?? ''),
130 'requiredMessage' => '',
131 'visible' => true,
132 ]
133 );
134 $children[] = $child;
135 }
136
137 return [
138 'children' => $children,
139 'nextId' => $nextId,
140 ];
141 }
142
143 /**
144 * @return array{children: list<array<string, mixed>>, nextId: int}
145 */
146 private function expandLikert(int $parentFieldIndex, int $nextId, ?string $pageId): array
147 {
148 $defaultRows = [
149 ['label' => __('Statement 1', 'ivyforms'), 'value' => 'statement_1'],
150 ['label' => __('Statement 2', 'ivyforms'), 'value' => 'statement_2'],
151 ['label' => __('Statement 3', 'ivyforms'), 'value' => 'statement_3'],
152 ];
153
154 $rawChildren = McpFieldPayloadHelper::likertRowChildFields(
155 $defaultRows,
156 0,
157 $parentFieldIndex,
158 $parentFieldIndex
159 );
160
161 $children = [];
162 foreach ($rawChildren as $index => $child) {
163 if (!is_array($child)) {
164 continue;
165 }
166
167 $child = $this->baseChild($child, $nextId++, $parentFieldIndex, $index, $pageId);
168 $children[] = $child;
169 }
170
171 return [
172 'children' => $children,
173 'nextId' => $nextId,
174 ];
175 }
176
177 /**
178 * @param array<string, mixed> $child
179 *
180 * @return array<string, mixed>
181 */
182 private function baseChild(
183 array $child,
184 int $id,
185 int $parentFieldIndex,
186 int $index,
187 ?string $pageId
188 ): array {
189 $child['id'] = $id;
190 $child['parentId'] = 0;
191 $child['fieldIndex'] = $parentFieldIndex;
192 $child['position'] = $parentFieldIndex;
193 $child['subFieldIndex'] = $index;
194 $child['rowIndex'] = 0;
195 $child['columnIndex'] = 0;
196 $child['width'] = 100;
197
198 if ($pageId !== null && $pageId !== '') {
199 $child['pageId'] = $pageId;
200 $child['settings'] = array_merge(
201 is_array($child['settings'] ?? null) ? $child['settings'] : [],
202 ['pageId' => $pageId]
203 );
204 }
205
206 return $child;
207 }
208
209 /**
210 * @param mixed $settings
211 *
212 * @return array<string, mixed>
213 */
214 private function decodeSettings($settings): array
215 {
216 if (is_array($settings)) {
217 return $settings;
218 }
219
220 if (!is_string($settings) || $settings === '') {
221 return [];
222 }
223
224 $decoded = json_decode($settings, true);
225
226 return is_array($decoded) ? $decoded : [];
227 }
228 }
229