PluginProbe
The Innovative Form Builder – IvyForms / 1.0
The Innovative Form Builder – IvyForms v1.0
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 / Entry / Managers / EntryFieldValueManager.php

EntryFieldValueManager.php in The Innovative Form Builder – IvyForms 1.0, at backend/src/Services/Entry/Managers/EntryFieldValueManager.php

241 lines 8.3 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\Entry\Managers;
4
5 use IvyForms\Common\Helpers\DateTimeHelper\DateTimeHelper;
6 use IvyForms\Common\Helpers\EntryHelper;
7 use IvyForms\Services\Field\FieldService;
8
9 /**
10 * Handles field value formatting and resolution.
11 * Responsible for converting field values for display and processing submission data.
12 */
13 class EntryFieldValueManager
14 {
15 private FieldService $fieldService;
16
17 public function __construct(FieldService $fieldService)
18 {
19 $this->fieldService = $fieldService;
20 }
21
22 /**
23 * Format entry fields with values converted for frontend display.
24 * (e.g., timestamp → HH:MM for time fields)
25 *
26 * @param array<int, array<string, mixed>> $entryFields
27 * @param bool $skipFormatting
28 * @return array<int, array<string, mixed>>
29 * @SuppressWarnings(PHPMD)
30 */
31 public function formatForFrontend(array $entryFields, bool $skipFormatting = false): array
32 {
33 $fieldsById = $this->buildFieldsMap($entryFields);
34
35 // Format each entry field value based on field type
36 foreach ($entryFields as &$entryField) {
37 $fieldId = (int)$entryField['fieldId'];
38 if (!isset($fieldsById[$fieldId])) {
39 continue;
40 }
41
42 $field = $fieldsById[$fieldId];
43 $fieldType = strtolower($field->getType());
44 $value = $entryField['fieldValue'];
45
46 $entryField['fieldValue'] = $this->formatFieldValue($fieldType, $value, $skipFormatting);
47 }
48
49 return $entryFields;
50 }
51
52 /**
53 * Resolve the value for a field based on its type and parent/child relationship.
54 *
55 * @param object $field
56 * @param array<mixed> $submissionData
57 * @param array<int, array<int>> $parentChildrenMap
58 * @param array<int, string|null> $parentSubfieldKeys
59 * @return mixed
60 */
61 public function resolveFieldValue(
62 object $field,
63 array $submissionData,
64 array $parentChildrenMap,
65 array $parentSubfieldKeys
66 ) {
67 $fieldId = $field->getId();
68 $fieldType = $field->getType();
69 $parentId = method_exists($field, 'getParentId') ? $field->getParentId() : null;
70
71 $parentValue = $this->getParentSubfieldValue($fieldId, $parentId, $submissionData, $parentSubfieldKeys);
72 if ($parentValue !== null) {
73 return $parentValue;
74 }
75
76 /**
77 * Filters the resolved field value before standard processing.
78 * Allows field-type-specific value resolution (e.g., password hashing).
79 *
80 * @since 0.1.0
81 *
82 * @param mixed|null $value The resolved value (null to continue with default processing).
83 * @param object $field The field object.
84 * @param mixed[] $submissionData The submission data array.
85 * @param mixed[] $parentChildrenMap Map of parent to children field relationships.
86 * @param mixed[] $parentSubfieldKeys Map of parent subfield keys.
87 * @return mixed The resolved field value or null to continue default processing.
88 */
89 $customValue = apply_filters(
90 'ivyforms/entry/field/resolve_value',
91 null,
92 $field,
93 $submissionData,
94 $parentChildrenMap,
95 $parentSubfieldKeys
96 );
97
98 /**
99 * Filters the resolved field value for a specific field type.
100 * Allows dynamic hook registration per field type (e.g., 'ivyforms/entry/field/resolve_value/password').
101 *
102 * @since 0.1.0
103 *
104 * @param mixed|null $value The resolved value (null to continue with default processing).
105 * @param object $field The field object.
106 * @param mixed[] $submissionData The submission data array.
107 * @param mixed[] $parentChildrenMap Map of parent to children field relationships.
108 * @param mixed[] $parentSubfieldKeys Map of parent subfield keys.
109 * @return mixed The resolved field value or null to continue default processing.
110 */
111 $customValue = apply_filters(
112 "ivyforms/entry/field/resolve_value/{$fieldType}",
113 $customValue,
114 $field,
115 $submissionData,
116 $parentChildrenMap,
117 $parentSubfieldKeys
118 );
119
120 if ($customValue !== null) {
121 return $customValue;
122 }
123
124 if (in_array($fieldType, ['name', 'address'], true) && ($parentId === null || $parentId === 0)) {
125 return $this->getCompoundFieldValue($fieldId, $parentChildrenMap, $parentSubfieldKeys, $submissionData);
126 }
127
128 if ($fieldType === 'time') {
129 $value = EntryHelper::getDefaultFieldValue($fieldId, $submissionData);
130 return DateTimeHelper::normalizeTimeValue($value);
131 }
132
133 if ($fieldType === 'date') {
134 $value = EntryHelper::getDefaultFieldValue($fieldId, $submissionData);
135 return DateTimeHelper::normalizeDateValue($value);
136 }
137
138 return EntryHelper::getDefaultFieldValue($fieldId, $submissionData);
139 }
140
141 /**
142 * Build a map of field entities indexed by field ID.
143 *
144 * @param array<int, array<string, mixed>> $entryFields
145 * @return array<int, object>
146 */
147 private function buildFieldsMap(array $entryFields): array
148 {
149 // Extract unique field IDs from entry fields
150 $fieldIds = array_unique(array_column($entryFields, 'fieldId'));
151 if (empty($fieldIds)) {
152 return [];
153 }
154
155 // Single query to load only needed fields
156 return $this->fieldService->getFieldsByIds($fieldIds);
157 }
158
159 /**
160 * Format field value based on field type.
161 *
162 * @param string $fieldType
163 * @param mixed $value
164 * @param bool $skipFormatting
165 * @return mixed
166 * @SuppressWarnings(PHPMD)
167 */
168 private function formatFieldValue(string $fieldType, $value, bool $skipFormatting = false)
169 {
170 // Convert timestamp to HH:MM format for time fields
171 if ($fieldType === 'time' && is_numeric($value)) {
172 $value = DateTimeHelper::timestampToTime((int)$value);
173 }
174
175 // Convert timestamp to date format for date fields
176 if ($fieldType === 'date' && is_numeric($value)) {
177 $value = DateTimeHelper::timestampToDate((int)$value);
178 }
179
180 /**
181 * Filters the formatted field value for frontend display.
182 * Allows field-type-specific formatting.
183 *
184 * @since 0.1.0
185 *
186 * @param mixed $value The field value to format.
187 * @param string $fieldType The field type (lowercase).
188 * @return mixed The formatted field value.
189 */
190 $value = apply_filters('ivyforms/entry/field/format_value', $value, $fieldType);
191
192 /**
193 * Filters the formatted field value for a specific field type.
194 * Allows dynamic hook registration per field type.
195 *
196 * @since 0.1.0
197 *
198 * @param mixed $value The field value to format.
199 * @param bool $skipFormatting Whether the field value should be formatted.
200 * @return mixed The formatted field value.
201 */
202 return apply_filters("ivyforms/entry/field/format_value/{$fieldType}", $value, $skipFormatting);
203 }
204
205 /**
206 * Get the value of a parent subfield.
207 *
208 * @param int $fieldId
209 * @param int|null $parentId
210 * @param array<int|string, mixed> $submissionData
211 * @param array<int, string|null> $parentSubfieldKeys
212 * @return mixed|null
213 */
214 private function getParentSubfieldValue(
215 int $fieldId,
216 ?int $parentId,
217 array $submissionData,
218 array $parentSubfieldKeys
219 ) {
220 return EntryHelper::getParentSubfieldValue($fieldId, $parentId, $submissionData, $parentSubfieldKeys);
221 }
222
223 /**
224 * Get the compound field value by combining child field values.
225 *
226 * @param int $fieldId
227 * @param array<int, array<int>> $parentChildrenMap
228 * @param array<int, string|null> $parentSubfieldKeys
229 * @param array<int|string, mixed> $submissionData
230 * @return string
231 */
232 private function getCompoundFieldValue(
233 int $fieldId,
234 array $parentChildrenMap,
235 array $parentSubfieldKeys,
236 array $submissionData
237 ): string {
238 return EntryHelper::getCompoundFieldValue($fieldId, $parentChildrenMap, $parentSubfieldKeys, $submissionData);
239 }
240 }
241