PluginProbe
The Innovative Form Builder – IvyForms / 1.4
The Innovative Form Builder – IvyForms v1.4
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 / Submission / SubmissionIntegrationFieldValueResolver.php

SubmissionIntegrationFieldValueResolver.php in The Innovative Form Builder – IvyForms 1.4, at backend/src/Services/Submission/SubmissionIntegrationFieldValueResolver.php

225 lines 6.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace IvyForms\Services\Submission;
4
5 /**
6 * Resolves raw submission values for integration payloads (field id keys, subfields, compounds).
7 *
8 * @package IvyForms\Services\Submission
9 */
10 final class SubmissionIntegrationFieldValueResolver
11 {
12 /**
13 * Resolve field value (mirrors entry system logic).
14 *
15 * @param object $field The field object
16 * @param array<int|string, mixed> $submissionData Submission data keyed by field id
17 * (preferred) or legacy field index
18 * @param array<int, string|null> $parentSubfieldKeys Map of child field IDs to subfield keys
19 * @param array<int, int> $fieldIdToIndex Map of field IDs to field indices
20 * @return mixed The resolved field value
21 */
22 public function resolveFieldValue(
23 object $field,
24 array $submissionData,
25 array $parentSubfieldKeys,
26 array $fieldIdToIndex
27 ) {
28 $parentId = method_exists($field, 'getParentId') ? $field->getParentId() : null;
29 $fieldId = $field->getId();
30
31 if ($this->isResolvableSubfield($parentId, $fieldId, $parentSubfieldKeys)) {
32 return $this->resolveSubfieldValue(
33 (int) $parentId,
34 $fieldId,
35 $parentSubfieldKeys,
36 $fieldIdToIndex,
37 $submissionData
38 );
39 }
40
41 $fieldIndex = $fieldIdToIndex[$fieldId] ?? null;
42 $compoundValue = $this->resolveCompoundFieldValue(
43 $field->getType(),
44 $parentId,
45 $fieldIndex,
46 $submissionData,
47 $fieldId
48 );
49
50 if (is_array($compoundValue)) {
51 return $compoundValue;
52 }
53
54 $byFieldId = $this->submissionValueForFieldIdKeys($submissionData, $fieldId);
55 if ($byFieldId !== null) {
56 return $byFieldId;
57 }
58
59 if ($fieldIndex !== null && array_key_exists($fieldIndex, $submissionData)) {
60 return $submissionData[$fieldIndex];
61 }
62
63 return '';
64 }
65
66 /**
67 * @param array<int|string, mixed> $submissionData
68 * @return mixed|null Null when neither int nor string field id key exists
69 */
70 private function submissionValueForFieldIdKeys(array $submissionData, int $fieldId)
71 {
72 if (array_key_exists($fieldId, $submissionData)) {
73 return $submissionData[$fieldId];
74 }
75
76 $fieldIdKey = (string)$fieldId;
77 if (array_key_exists($fieldIdKey, $submissionData)) {
78 return $submissionData[$fieldIdKey];
79 }
80
81 return null;
82 }
83
84 /**
85 * Resolve subfield value from parent field.
86 *
87 * Call only when isResolvableSubfield() is true so boolean false submissions are not
88 * confused with an "unresolved" sentinel.
89 *
90 * @param int $parentId Parent field id (> 0)
91 * @param int $fieldId
92 * @param array<int, string|null> $parentSubfieldKeys
93 * @param array<int, int> $fieldIdToIndex
94 * @param array<int|string, mixed> $submissionData
95 * @return mixed|null Null when subfield key is empty or value is missing in submission data
96 */
97 private function resolveSubfieldValue(
98 int $parentId,
99 int $fieldId,
100 array $parentSubfieldKeys,
101 array $fieldIdToIndex,
102 array $submissionData
103 ) {
104 $subKey = $parentSubfieldKeys[$fieldId];
105 if ($subKey === null || $subKey === '') {
106 return null;
107 }
108
109 return $this->pickSubfieldSubmissionValue($parentId, $subKey, $fieldIdToIndex, $submissionData);
110 }
111
112 /**
113 * @param array<int, string|null> $parentSubfieldKeys
114 */
115 private function isResolvableSubfield(?int $parentId, int $fieldId, array $parentSubfieldKeys): bool
116 {
117 return $parentId !== null && $parentId > 0 && isset($parentSubfieldKeys[$fieldId]);
118 }
119
120 /**
121 * @param array<int, int> $fieldIdToIndex
122 * @param array<int|string, mixed> $submissionData
123 * @return mixed|null
124 */
125 private function pickSubfieldSubmissionValue(
126 int $parentId,
127 string $subKey,
128 array $fieldIdToIndex,
129 array $submissionData
130 ) {
131 if ($this->submissionParentHasSubfieldKey($submissionData, $parentId, $subKey)) {
132 return $submissionData[$parentId][$subKey];
133 }
134
135 return $this->readSubfieldFromLegacyParentRow($parentId, $subKey, $fieldIdToIndex, $submissionData);
136 }
137
138 /**
139 * @param array<int|string, mixed> $submissionData
140 */
141 private function submissionParentHasSubfieldKey(array $submissionData, int $parentId, string $subKey): bool
142 {
143 $parentRow = $submissionData[$parentId] ?? null;
144
145 return is_array($parentRow) && array_key_exists($subKey, $parentRow);
146 }
147
148 /**
149 * @param array<int, int> $fieldIdToIndex
150 * @param array<int|string, mixed> $submissionData
151 * @return mixed|null
152 */
153 private function readSubfieldFromLegacyParentRow(
154 int $parentId,
155 string $subKey,
156 array $fieldIdToIndex,
157 array $submissionData
158 ) {
159 $parentFieldIndex = $fieldIdToIndex[$parentId] ?? null;
160 if ($parentFieldIndex === null) {
161 return null;
162 }
163
164 $legacyRow = $submissionData[$parentFieldIndex] ?? null;
165 if (!is_array($legacyRow) || !array_key_exists($subKey, $legacyRow)) {
166 return null;
167 }
168
169 return $legacyRow[$subKey];
170 }
171
172 /**
173 * Resolve compound field value (name, address).
174 *
175 * @param string $fieldType
176 * @param int|null $parentId
177 * @param int|null $fieldIndex
178 * @param array<int|string, mixed> $submissionData
179 * @param int $fieldId Compound field (name/address) database id
180 * @return array<mixed>|null
181 */
182 private function resolveCompoundFieldValue(
183 string $fieldType,
184 ?int $parentId,
185 ?int $fieldIndex,
186 array $submissionData,
187 int $fieldId
188 ) {
189 if (!$this->isCompoundRootField($fieldType, $parentId)) {
190 return null;
191 }
192
193 return $this->compoundFieldArrayFromSubmission($submissionData, $fieldId, $fieldIndex);
194 }
195
196 private function isCompoundRootField(string $fieldType, ?int $parentId): bool
197 {
198 if (!in_array($fieldType, ['name', 'address'], true)) {
199 return false;
200 }
201
202 return $parentId === null || $parentId === 0;
203 }
204
205 /**
206 * @param array<int|string, mixed> $submissionData
207 * @return array<mixed>|null
208 */
209 private function compoundFieldArrayFromSubmission(
210 array $submissionData,
211 int $fieldId,
212 ?int $fieldIndex
213 ) {
214 if (isset($submissionData[$fieldId]) && is_array($submissionData[$fieldId])) {
215 return $submissionData[$fieldId];
216 }
217
218 if ($fieldIndex !== null && isset($submissionData[$fieldIndex]) && is_array($submissionData[$fieldIndex])) {
219 return $submissionData[$fieldIndex];
220 }
221
222 return null;
223 }
224 }
225