PluginProbe
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder / 2.15.3
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder v2.15.3
3.3.1 V-3.3.0 3.2.2 3.2.1 3.2.0 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 V3.0.3 V3.0.2 -3.0.1 V_3.0.0 1.1.1 1.1.8 1.2 1.3 1.4 1.4.18 1.5.2 1.9 2.0 2.10.0 2.10.1 All 138 releases
← All changes | includes/Core/WorkFlow/Actions.php +86 -157 3.2.22.15.3 View file →
@@ -1,6 +1,8 @@
1 1 <?php
2 2
3 +?><?php
4 +
3 5 namespace BitCode\BitForm\Core\WorkFlow;
4 6
5 7 use BitCode\BitForm\Core\Integration\IntegrationHandler;
6 8 use BitCode\BitForm\Core\Messages\SuccessMessageHandler;
@@ -14,45 +16,17 @@
14 16 {
15 17 static::$_formID = $formId;
16 18 }
17 19
18 - /**
19 - * Resolve the field key a workflow action points at.
20 - *
21 - * Both arguments come straight out of stored workflow/form JSON, so neither shape is guaranteed
22 - * — hence the runtime checks rather than type hints.
23 - *
24 - * @param mixed $actionDetail one action row decoded from the workflow JSON
25 - * @param mixed $fieldData field map keyed by field name
26 - *
27 - * @return string|null null when the action points at a field the form no longer has
28 - */
29 - private static function resolveFieldKey($actionDetail, $fieldData)
30 - {
31 - if (!is_object($actionDetail) || !isset($actionDetail->field) || !\is_array($fieldData)) {
32 - return null;
33 - }
34 - $field = $actionDetail->field;
35 - if (!\is_string($field) && !\is_int($field)) {
36 - return null;
37 - }
38 - if (!isset($fieldData[$field]) || !\is_array($fieldData[$field]) || !isset($fieldData[$field]['key'])) {
39 - return null;
40 - }
41 - $key = $fieldData[$field]['key'];
42 -
43 - return \is_string($key) || \is_int($key) ? (string) $key : null;
44 - }
45 -
46 20 public function setValue($actionDetail, $fieldData, $fields)
47 21 {
48 - $fk = self::resolveFieldKey($actionDetail, $fieldData);
49 - if (null !== $fk && isset($fields->{$fk}) && !empty($actionDetail->val)) {
50 - $fieldType = isset($fields->{$fk}->typ) ? $fields->{$fk}->typ : '';
51 - $evalMathExpr = preg_match('/month|date/', (string) $fieldType);
52 - $fields->{$fk}->val = '';
53 - $actionValue = Helper::replaceFieldWithValue($actionDetail->val, $fieldData, !(bool) $evalMathExpr);
54 - $fields->{$fk}->val = $actionValue;
22 + if (!empty($actionDetail->val)) {
23 + $actionValue = '';
24 + $fieldType = $fields->{$fieldData[$actionDetail->field]['key']}->typ;
25 + $evalMathExpr = preg_match('/month|date/', $fieldType);
26 + $fields->{$fieldData[$actionDetail->field]['key']}->val = '';
27 + $actionValue = Helper::replaceFieldWithValue($actionDetail->val, $fieldData, !(bool)$evalMathExpr);
28 + $fields->{$fieldData[$actionDetail->field]['key']}->val = $actionValue;
55 29 $fieldData[$actionDetail->field]['value'] = $actionValue;
56 30 }
57 31 return [$fields, $fieldData];
58 32 }
@@ -59,14 +33,13 @@
59 33
60 34 public function getActionValue($actionDetail, $fieldData, $fields)
61 35 {
62 36 $actionValue = '';
63 - $fk = self::resolveFieldKey($actionDetail, $fieldData);
64 - if (null !== $fk && isset($fields->{$fk}) && !empty($actionDetail->val)) {
65 - $fieldType = isset($fields->{$fk}->typ) ? $fields->{$fk}->typ : '';
66 - $evalMathExpr = preg_match('/month|date/', (string) $fieldType);
67 - $fields->{$fk}->val = '';
68 - $actionValue = Helper::replaceFieldWithValue($actionDetail->val, $fieldData, !(bool) $evalMathExpr);
37 + if (!empty($actionDetail->val)) {
38 + $fieldType = $fields->{$fieldData[$actionDetail->field]['key']}->typ;
39 + $evalMathExpr = preg_match('/month|date/', $fieldType);
40 + $fields->{$fieldData[$actionDetail->field]['key']}->val = '';
41 + $actionValue = Helper::replaceFieldWithValue($actionDetail->val, $fieldData, !(bool)$evalMathExpr);
69 42 }
70 43 return $actionValue;
71 44 }
72 45
@@ -72,22 +45,12 @@
72 45
73 46 public function getActiveListIndex($actionDetail, $fieldData, $fields)
74 47 {
75 48 $activeList = $this->getActionValue($actionDetail, $fieldData, $fields);
49 + $optionsList = $fields->{$fieldData[$actionDetail->field]['key']}->optionsList;
76 50 $activeListIndex = 0;
77 - $fk = self::resolveFieldKey($actionDetail, $fieldData);
78 - if (null === $fk || !isset($fields->{$fk}->optionsList)) {
79 - return $activeListIndex;
80 - }
81 - $optionsList = $fields->{$fk}->optionsList;
82 - if (!\is_array($optionsList) && !\is_object($optionsList)) {
83 - return $activeListIndex;
84 - }
85 51 foreach ($optionsList as $key => $optionObj) {
86 52 $valueArr = (array) $optionObj;
87 - if (empty($valueArr)) {
88 - continue;
89 - }
90 53 $listName = array_keys($valueArr)[0];
91 54 if ($listName === $activeList) {
92 55 $activeListIndex = $key;
93 56 break;
@@ -98,16 +61,12 @@
98 61 }
99 62
100 63 public function show($fields, $fieldData, $actionDetail)
101 64 {
102 - $fk = self::resolveFieldKey($actionDetail, $fieldData);
103 - if (null === $fk || !isset($fields->{$fk})) {
104 - return;
65 + $fields->{$fieldData[$actionDetail->field]['key']}->valid->hide = false;
66 + if ('hidden' === $fields->{$fieldData[$actionDetail->field]['key']}->typ) {
67 + $fields->{$fieldData[$actionDetail->field]['key']}->typ = 'text';
105 68 }
106 - Helper::setNestedProperty($fields, "{$fk}->valid->hide", false);
107 - if (isset($fields->{$fk}->typ) && 'hidden' === $fields->{$fk}->typ) {
108 - $fields->{$fk}->typ = 'text';
109 - }
110 69 }
111 70
112 71 public function setFieldProperty($actions, $fieldData, $fields)
113 72 {
@@ -114,74 +73,66 @@
114 73 if (empty($actions)) {
115 74 return [$fields, $fieldData];
116 75 }
117 76 foreach ($actions as $actionDetail) {
118 - // resolveFieldKey() must run *before* $fields is indexed: the old condition built the
119 - // dynamic property name from $fieldData[...]['key'] inside its own isset(), so the missing
120 - // key warned before isset() ever got a chance to short-circuit.
121 - $fk = self::resolveFieldKey($actionDetail, $fieldData);
122 - if (null === $fk || empty($actionDetail->action) || !isset($fields->{$fk}) || empty($fields->{$fk})) {
123 - continue;
77 + if (!empty($actionDetail->action) && !empty($actionDetail->field) && isset($fields->{$fieldData[$actionDetail->field]['key']}) && !empty($fields->{$fieldData[$actionDetail->field]['key']})) {
78 + switch ($actionDetail->action) {
79 + case 'value':
80 + $data = $this->setValue($actionDetail, $fieldData, $fields);
81 + $fields = $data[0];
82 + $fieldData = $data[1];
83 + break;
84 + case 'hide':
85 + $fields->{$fieldData[$actionDetail->field]['key']}->valid->hide = true;
86 + break;
87 + case 'disable':
88 + $fields->{$fieldData[$actionDetail->field]['key']}->valid->disabled = true;
89 + break;
90 + case 'show':
91 + $this->show($fields, $fieldData, $actionDetail);
92 + break;
93 + case 'enable':
94 + $fields->{$fieldData[$actionDetail->field]['key']}->valid->disabled = false;
95 + break;
96 + case 'readonly':
97 + $fields->{$fieldData[$actionDetail->field]['key']}->valid->readonly = true;
98 + break;
99 + case 'writeable':
100 + $fields->{$fieldData[$actionDetail->field]['key']}->valid->readonly = false;
101 + break;
102 + case 'required':
103 + $fields->{$fieldData[$actionDetail->field]['key']}->valid->required = true;
104 + break;
105 + case 'limit':
106 + $fields->{$fieldData[$actionDetail->field]['key']}->valid->limit = true;
107 + break;
108 + case 'min':
109 + $fields->{$fieldData[$actionDetail->field]['key']}->valid->min = true;
110 + break;
111 + case 'max':
112 + $fields->{$fieldData[$actionDetail->field]['key']}->valid->max = true;
113 + break;
114 + case 'activelist':
115 + $fields->{$fieldData[$actionDetail->field]['key']}->config->activeList = $this->getActiveListIndex($actionDetail, $fieldData, $fields);
116 + break;
117 + case 'lbl':
118 + case 'ct':
119 + $fields->{$fieldData[$actionDetail->field]['key']}->lbl = $this->getActionValue($actionDetail, $fieldData, $fields);
120 + break;
121 + case 'sub-titl':
122 + $fields->{$fieldData[$actionDetail->field]['key']}->subtitle = $this->getActionValue($actionDetail, $fieldData, $fields);
123 + break;
124 + case 'hlp-txt':
125 + $fields->{$fieldData[$actionDetail->field]['key']}->helperTxt = $this->getActionValue($actionDetail, $fieldData, $fields);
126 + break;
127 + case 'placeholder':
128 + $fields->{$fieldData[$actionDetail->field]['key']}->ph = $this->getActionValue($actionDetail, $fieldData, $fields);
129 + break;
130 + case 'title':
131 + $fields->{$fieldData[$actionDetail->field]['key']}->title = $this->getActionValue($actionDetail, $fieldData, $fields);
132 + break;
133 + }
124 134 }
125 - switch ($actionDetail->action) {
126 - case 'value':
127 - $data = $this->setValue($actionDetail, $fieldData, $fields);
128 - $fields = $data[0];
129 - $fieldData = $data[1];
130 - break;
131 - case 'hide':
132 - Helper::setNestedProperty($fields, "{$fk}->valid->hide", true);
133 - break;
134 - case 'disable':
135 - Helper::setNestedProperty($fields, "{$fk}->valid->disabled", true);
136 - break;
137 - case 'show':
138 - $this->show($fields, $fieldData, $actionDetail);
139 - break;
140 - case 'enable':
141 - Helper::setNestedProperty($fields, "{$fk}->valid->disabled", false);
142 - break;
143 - case 'readonly':
144 - Helper::setNestedProperty($fields, "{$fk}->valid->readonly", true);
145 - break;
146 - case 'writeable':
147 - Helper::setNestedProperty($fields, "{$fk}->valid->readonly", false);
148 - break;
149 - case 'required':
150 - Helper::setNestedProperty($fields, "{$fk}->valid->required", true);
151 - break;
152 - case 'limit':
153 - Helper::setNestedProperty($fields, "{$fk}->valid->limit", true);
154 - break;
155 - case 'min':
156 - Helper::setNestedProperty($fields, "{$fk}->valid->min", true);
157 - break;
158 - case 'max':
159 - Helper::setNestedProperty($fields, "{$fk}->valid->max", true);
160 - break;
161 - case 'activelist':
162 - // setNestedProperty() creates the intermediate `valid`/`config` object when a legacy
163 - // field JSON does not carry one; the direct writes here used to auto-vivify it and
164 - // emit an undefined-property warning on every run.
165 - Helper::setNestedProperty($fields, "{$fk}->config->activeList", $this->getActiveListIndex($actionDetail, $fieldData, $fields));
166 - break;
167 - case 'lbl':
168 - case 'ct':
169 - $fields->{$fk}->lbl = $this->getActionValue($actionDetail, $fieldData, $fields);
170 - break;
171 - case 'sub-titl':
172 - $fields->{$fk}->subtitle = $this->getActionValue($actionDetail, $fieldData, $fields);
173 - break;
174 - case 'hlp-txt':
175 - $fields->{$fk}->helperTxt = $this->getActionValue($actionDetail, $fieldData, $fields);
176 - break;
177 - case 'placeholder':
178 - $fields->{$fk}->ph = $this->getActionValue($actionDetail, $fieldData, $fields);
179 - break;
180 - case 'title':
181 - $fields->{$fk}->title = $this->getActionValue($actionDetail, $fieldData, $fields);
182 - break;
183 - }
184 135 }
185 136 return [$fields, $fieldData];
186 137 }
187 138
@@ -205,9 +156,9 @@
205 156 }
206 157 return $fieldValue;
207 158 }
208 159
209 - public function setOnFormSuccess($data, $actions, $fieldValue, $entryID)
160 + public function setOnFormSuccess($data, $actions, $fieldValue)
210 161 {
211 162 if (empty($actions)) {
212 163 return $data;
213 164 }
@@ -216,9 +167,9 @@
216 167 $id = $successActionDetail->details->id;
217 168 if (!empty($id)) {
218 169 switch ($successActionDetail->type) {
219 170 case 'successMsg':
220 - $data['workFlowReturnable'] = $this->confirmationMessage($data['workFlowReturnable'], $id, $fieldValue, $entryID);
171 + $data['workFlowReturnable'] = $this->confirmationMessage($data['workFlowReturnable'], $id, $fieldValue);
221 172 break;
222 173 case 'redirectPage':
223 174 $data['workFlowReturnable'] = $this->redirectPage($data['workFlowReturnable'], $id, $fieldValue);
224 175 break;
@@ -244,41 +195,23 @@
244 195 }
245 196 return $data;
246 197 }
247 198
248 - public function confirmationMessage($workFlowReturnable, $successActionDetailId, $fieldValue, $entryID = null)
199 + public function confirmationMessage($workFlowReturnable, $successActionDetailId, $fieldValue)
249 200 {
250 - $id = Utilities::jsonObj($successActionDetailId)->id ?? null;
201 + $id = json_decode($successActionDetailId)->id;
251 202 $messageHandler = new SuccessMessageHandler(static::$_formID);
252 203 $message = $messageHandler->getAMessage($id);
253 204 if (!is_wp_error($message) && !empty($message)) {
254 - $msgConfig = Utilities::jsonObj($message[0]->message_config ?? '');
255 - // Honor enable/disable: a disabled confirmation message is skipped so the default confirmation applies.
256 - if (isset($msgConfig->status) && empty($msgConfig->status)) {
257 - return $workFlowReturnable;
258 - }
259 - $messageContent = $message[0]->message_content;
260 -
261 - // replace pdf link and password
262 - if (class_exists('\BitCode\BitFormPro\Admin\DownloadFile') && !empty($entryID)) {
263 - $downloadFile = new \BitCode\BitFormPro\Admin\DownloadFile();
264 - $messageContent = $downloadFile->replacePdfShortCodeToLink($messageContent, static::$_formID, $entryID);
265 - $messageContent = $downloadFile->replaceShortCodeToPdfPassword($messageContent, static::$_formID, $entryID);
266 - }
267 -
268 - $workFlowReturnable['message'] = Helper::replaceFieldWithValue($messageContent, $fieldValue, true, static::$_formID, true);
269 - if (!empty($workFlowReturnable['message'])) {
205 + $workFlowReturnable['message'] = Helper::replaceFieldWithValue($message[0]->message_content, $fieldValue);
206 + if (!empty($workFlowReturnable['message']) && Utilities::isPro()) {
270 207 $workFlowReturnable['message'] = do_shortcode($workFlowReturnable['message']);
271 208 }
272 209 $workFlowReturnable['msg_id'] = $message[0]->id;
273 - $msgConfig = Utilities::jsonObj($message[0]->message_config ?? '');
274 - if (!empty($msgConfig->autoHide)) {
275 - $workFlowReturnable['msg_duration'] = abs(floatval($msgConfig->duration ?? 0) * 1000);
210 + $msgConfig = json_decode($message[0]->message_config);
211 + if ($msgConfig->autoHide) {
212 + $workFlowReturnable['msg_duration'] = abs(floatval($msgConfig->duration) * 1000);
276 213 }
277 - // expose the form's after-submission behaviour ('reset' | 'hide' | 'keep') to the frontend
278 - if (isset($msgConfig->afterSubmit)) {
279 - $workFlowReturnable['afterSubmit'] = $msgConfig->afterSubmit;
280 - }
281 214 }
282 215 return $workFlowReturnable;
283 216 }
284 217
@@ -283,17 +216,13 @@
283 216 }
284 217
285 218 public function redirectPage($workFlowReturnable, $successActionDetailId, $fieldValue)
286 219 {
287 - $id = Utilities::jsonObj($successActionDetailId)->id ?? null;
220 + $id = json_decode($successActionDetailId)->id;
288 221 $integrationHandler = new IntegrationHandler(static::$_formID);
289 222 $redirectPage = $integrationHandler->getAIntegration($id, 'form', 'redirectPage');
290 223 if (!is_wp_error($redirectPage) && !empty($redirectPage)) {
291 - // Honor enable/disable: a disabled redirect is skipped.
292 - if (isset($redirectPage[0]->status) && empty($redirectPage[0]->status)) {
293 - return $workFlowReturnable;
294 - }
295 - $url = Utilities::jsonObj($redirectPage[0]->integration_details ?? '')->url ?? '';
224 + $url = json_decode($redirectPage[0]->integration_details)->url;
296 225 if (!empty($url)) {
297 226 $url = Helper::replaceFieldWithValue($url, $fieldValue);
298 227 }
299 228 $workFlowReturnable['redirectPage'] = empty($url) ? false : esc_url_raw($url);