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
← All changes | backend/src/Common/Helpers/EntryHelper.php +65 -37 0.9.1 → 1.5.1 View file →
@@ -1,29 +1,14 @@
1 1 <?php
2 2
3 3 namespace IvyForms\Common\Helpers;
4 4
5 -// phpcs:disable PSR1.Files.SideEffects
6 -if (!defined('ABSPATH')) {
7 - exit; // Exit if accessed directly
8 -}
9 -
10 5 use IvyForms\Entity\Entry\Entry;
6 +use IvyForms\Services\Security\Common\IpDetectionService;
11 7
12 8 class EntryHelper
13 9 {
14 10 /**
15 - * Get the client IP address.
16 - *
17 - * @return string|null
18 - */
19 - public static function getClientIpAddress(): ?string
20 - {
21 - $ip = filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP);
22 - return $ip ?: null;
23 - }
24 -
25 - /**
26 11 * Get the user agent string.
27 12 *
28 13 * @return string
29 14 */
@@ -77,9 +62,9 @@
77 62 return [
78 63 'formId' => $formId,
79 64 'userId' => get_current_user_id() ?: null,
80 65 'status' => Entry::DEFAULT_STATUS,
81 - 'ipAddress' => self::getClientIpAddress(),
66 + 'ipAddress' => IpDetectionService::getUserIpAddress(),
82 67 'userAgent' => self::getUserAgent(),
83 68 'sourceURL' => self::getSourceURL(),
84 69 ];
85 70 }
@@ -98,15 +83,22 @@
98 83 ?int $parentId,
99 84 array $submissionData,
100 85 array $parentSubfieldKeys
101 86 ) {
102 - if ($parentId && isset($parentSubfieldKeys[$fieldId])) {
103 - $subKey = $parentSubfieldKeys[$fieldId];
104 - if (isset($submissionData[$parentId][$subKey])) {
105 - return $submissionData[$parentId][$subKey];
106 - }
87 + if (!$parentId || !isset($parentSubfieldKeys[$fieldId])) {
88 + return null;
107 89 }
108 - return null;
90 +
91 + $subKey = $parentSubfieldKeys[$fieldId];
92 + $parentValue = self::decodeSubmissionValue($submissionData[$parentId] ?? []);
93 +
94 + if (!isset($parentValue[$subKey])) {
95 + return null;
96 + }
97 +
98 + $val = $parentValue[$subKey];
99 +
100 + return is_array($val) ? implode(', ', $val) : $val;
109 101 }
110 102
111 103 /**
112 104 * Get the compound field value by combining child field values.
@@ -122,24 +114,44 @@
122 114 array $parentChildrenMap,
123 115 array $parentSubfieldKeys,
124 116 array $submissionData
125 117 ): string {
118 + if (empty($parentChildrenMap[$fieldId])) {
119 + return '';
120 + }
121 +
122 + $parentValue = self::decodeSubmissionValue($submissionData[$fieldId] ?? []);
126 123 $childValues = [];
127 - if (!empty($parentChildrenMap[$fieldId])) {
128 - foreach ($parentChildrenMap[$fieldId] as $childId) {
129 - $subKey = $parentSubfieldKeys[$childId] ?? null;
130 - if ($subKey && isset($submissionData[$fieldId][$subKey])) {
131 - $val = $submissionData[$fieldId][$subKey];
132 - if ($val !== '') {
133 - $childValues[] = $val;
134 - }
135 - }
124 +
125 + foreach ($parentChildrenMap[$fieldId] as $childId) {
126 + $subKey = $parentSubfieldKeys[$childId] ?? null;
127 + if ($subKey !== null && isset($parentValue[$subKey]) && $parentValue[$subKey] !== '') {
128 + $val = $parentValue[$subKey];
129 + $childValues[] = is_array($val) ? implode(', ', $val) : $val;
136 130 }
137 131 }
132 +
138 133 return implode(' ', $childValues);
139 134 }
140 135
141 136 /**
137 + * Decode a submission value into an array.
138 + * Handles JSON strings (e.g., Likert submissions) and ensures an array is returned.
139 + *
140 + * @param mixed $value
141 + * @return array<string, mixed>
142 + */
143 + public static function decodeSubmissionValue($value): array
144 + {
145 + if (is_string($value)) {
146 + $decoded = json_decode($value, true);
147 + return is_array($decoded) ? $decoded : [];
148 + }
149 +
150 + return is_array($value) ? $value : [];
151 + }
152 +
153 + /**
142 154 * Get the default field value from submission data.
143 155 *
144 156 * @param int $fieldId
145 157 * @param array<int|string, mixed> $submissionData
@@ -172,18 +184,34 @@
172 184 * Build subfield key map for each parent.
173 185 *
174 186 * @param array<int, array<int>> $parentChildrenMap
175 187 * @param array<mixed> $submissionData
188 + * @param array<int, object> $formFields
176 189 * @return array<int, string|null>
177 190 */
178 - public static function buildParentSubfieldKeys(array $parentChildrenMap, array $submissionData): array
179 - {
191 + public static function buildParentSubfieldKeys(
192 + array $parentChildrenMap,
193 + array $submissionData,
194 + array $formFields = []
195 + ): array {
196 + $fieldById = [];
197 + foreach ($formFields as $field) {
198 + if (method_exists($field, 'getId')) {
199 + $fieldById[$field->getId()] = $field;
200 + }
201 + }
202 +
180 203 $parentSubfieldKeys = [];
181 204 foreach ($parentChildrenMap as $parentId => $childIds) {
182 - $parentValue = $submissionData[$parentId] ?? [];
205 + $parentValue = self::decodeSubmissionValue($submissionData[$parentId] ?? []);
183 206 $keys = array_keys($parentValue);
184 - foreach ($childIds as $i => $childId) {
185 - $parentSubfieldKeys[$childId] = $keys[$i] ?? null;
207 + $orderedChildIds = NameFieldKeyHelper::sortChildIdsByDisplayOrder($childIds, $fieldById);
208 + foreach ($orderedChildIds as $i => $childId) {
209 + $subKey = NameFieldKeyHelper::resolveStoredNameSubfieldKey($fieldById[$childId] ?? null);
210 + if ($subKey === null) {
211 + $subKey = $keys[$i] ?? null;
212 + }
213 + $parentSubfieldKeys[$childId] = $subKey;
186 214 }
187 215 }
188 216 return $parentSubfieldKeys;
189 217 }