PluginProbe
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder / 3.3.1
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder v3.3.1
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
bit-form / includes / Core / Integration / IntegrationHandler.php

IntegrationHandler.php in Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder 3.3.1, at includes/Core/Integration/IntegrationHandler.php

723 lines 25.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace BitCode\BitForm\Core\Integration;
4
5 use BitCode\BitForm\Admin\Form\AdminFormManager;
6 use BitCode\BitForm\Admin\Form\Helpers;
7 use BitCode\BitForm\Core\Database\FormEntryLogModel;
8 use BitCode\BitForm\Core\Database\FormEntryModel;
9 use BitCode\BitForm\Core\Database\IntegrationModel;
10 use BitCode\BitForm\Core\Form\FormManager;
11 use BitCode\BitForm\Core\Util\FieldValueHandler;
12 use BitCode\BitForm\Core\Util\Log;
13 use BitCode\BitForm\Core\Util\MailNotifier;
14 use BitCode\BitForm\Frontend\Form\FrontendFormManager;
15
16 final class IntegrationHandler
17 {
18 private $_formID;
19 private static $_integrationModel;
20 private $_user_details;
21
22 /**
23 * Constructor of Integration Handler
24 *
25 * @param Integer $formID If Integration is accessible globally then
26 * $formID will be 0 and category app
27 * @param Array $user_details Details of user accessing data
28 * @return void
29 */
30 public function __construct($formID, $user_details = null)
31 {
32 $this->_formID = $formID;
33 static::$_integrationModel = new IntegrationModel();
34 $this->_user_details = $user_details;
35 }
36
37 public function getAIntegration($integrationID, $integrationCategory = null, $integrationType = null)
38 {
39 $conditions = [
40 'form_id' => $this->_formID,
41 'id' => $integrationID,
42 ];
43 if (!is_null($integrationType)) {
44 $conditions = array_merge($conditions, ['integration_type' => $integrationType]);
45 }
46 if (!is_null($integrationCategory)) {
47 $conditions = array_merge($conditions, ['category' => $integrationCategory]);
48 }
49 return static::$_integrationModel->get(
50 [
51 'id',
52 'integration_name',
53 'integration_type',
54 'integration_details',
55 'status',
56 'form_id',
57 ],
58 $conditions
59 );
60 }
61
62 public function getAllIntegration($integrationCategory = null, $integrationType = null, $status = null, $id = null)
63 {
64 $conditions = [
65 'form_id' => $this->_formID,
66 ];
67 if (!is_null($integrationType)) {
68 $conditions = array_merge($conditions, ['integration_type' => $integrationType]);
69 }
70
71 if (!is_null($integrationCategory)) {
72 $conditions = array_merge($conditions, ['category' => $integrationCategory]);
73 }
74 if (!is_null($status)) {
75 $conditions = array_merge($conditions, ['status' => 1]);
76 }
77 if (!is_null($id)) {
78 $conditions = array_merge($conditions, ['id' => $id]);
79 }
80 return static::$_integrationModel->get(
81 [
82 'id',
83 'form_id',
84 'integration_name',
85 'integration_type',
86 'integration_details',
87 'status',
88 ],
89 $conditions
90 );
91 }
92
93 public function getIntegrationWithoutFormId($integrationCategory = null, $integrationType = null, $status = null, $id = null)
94 {
95 $conditions = [];
96 if (!is_null($integrationType)) {
97 $conditions = array_merge($conditions, ['integration_type' => $integrationType]);
98 }
99
100 if (!is_null($integrationCategory)) {
101 $conditions = array_merge($conditions, ['category' => $integrationCategory]);
102 }
103 if (!is_null($status)) {
104 $conditions = array_merge($conditions, ['status' => 1]);
105 }
106 if (!is_null($id)) {
107 $conditions = array_merge($conditions, ['id' => $id]);
108 }
109 return static::$_integrationModel->get(
110 [
111 'id',
112 'form_id',
113 'integration_name',
114 'integration_type',
115 'integration_details',
116 'status',
117 ],
118 $conditions
119 );
120 }
121
122 public function saveIntegration($integrationName, $integrationType, $integrationDetails, $integrationCategory, $status = null)
123 {
124 if (null === $status) {
125 $status = 1;
126 }
127 return static::$_integrationModel->insert(
128 [
129 'integration_name' => $integrationName,
130 'integration_type' => $integrationType,
131 'integration_details' => $integrationDetails,
132 'category' => $integrationCategory,
133 'form_id' => $this->_formID,
134 'user_id' => $this->_user_details['id'],
135 'user_ip' => $this->_user_details['ip'],
136 'status' => $status,
137 'created_at' => $this->_user_details['time'],
138 'updated_at' => $this->_user_details['time'],
139 ]
140 );
141 }
142
143 public function updateIntegration($integrationID, $integrationName, $integrationType, $integrationDetails, $integrationCategory, $status = null)
144 {
145 if (null === $status) {
146 $status = 1;
147 }
148 return static::$_integrationModel->update(
149 [
150 'integration_name' => $integrationName,
151 'integration_type' => $integrationType,
152 'integration_details' => $integrationDetails,
153 'category' => $integrationCategory,
154 'form_id' => $this->_formID,
155 'user_id' => $this->_user_details['id'],
156 'user_ip' => $this->_user_details['ip'],
157 'status' => $status,
158 'updated_at' => $this->_user_details['time'],
159 ],
160 [
161 'id' => $integrationID,
162 ]
163 );
164 }
165
166 /**
167 * Name-only rename of a connected account row, scoped to
168 * category=connected_integration_apps and this handler's form id (0).
169 * updateIntegration() is unusable here: it overwrites details/type/category/status.
170 */
171 public function renameConnectedApp($integrationID, $integrationName)
172 {
173 $data = ['integration_name' => $integrationName];
174 if (!empty($this->_user_details['time'])) {
175 $data['updated_at'] = $this->_user_details['time'];
176 }
177 return static::$_integrationModel->update(
178 $data,
179 [
180 'id' => $integrationID,
181 'form_id' => $this->_formID,
182 'category' => 'connected_integration_apps',
183 ]
184 );
185 }
186
187 public function updateIntegrationStatus($integrationID, $status)
188 {
189 $data = ['status' => (int) $status];
190 if (!empty($this->_user_details['time'])) {
191 $data['updated_at'] = $this->_user_details['time'];
192 }
193 return static::$_integrationModel->update(
194 $data,
195 [
196 'id' => $integrationID,
197 'form_id' => $this->_formID,
198 ]
199 );
200 }
201
202 public function duplicateAllInAForm($oldFormId)
203 {
204 $integCols = ['integration_name', 'integration_type', 'integration_details', 'category', 'form_id', 'user_id', 'user_ip', 'status', 'created_at', 'updated_at'];
205 $integDupData = [
206 'integration_name',
207 'integration_type',
208 'integration_details',
209 'category',
210 $this->_formID,
211 $this->_user_details['id'],
212 $this->_user_details['ip'],
213 'status',
214 $this->_user_details['time'],
215 $this->_user_details['time'],
216 ];
217 return static::$_integrationModel->duplicate($integCols, $integDupData, ['form_id' => $oldFormId]);
218 }
219
220 public function deleteIntegration($integrationID)
221 {
222 return static::$_integrationModel->delete(
223 [
224 'id' => $integrationID,
225 'form_id' => $this->_formID,
226 ]
227 );
228 }
229
230 public static function replaceFieldWithValue($dataToReplaceField, $fieldValues)
231 {
232 if (empty($dataToReplaceField)) {
233 return false;
234 }
235 if (is_string($dataToReplaceField)) {
236 $dataToReplaceField = static::replaceFieldWithValueHelper($dataToReplaceField, $fieldValues);
237 } elseif (is_array($dataToReplaceField)) {
238 foreach ($dataToReplaceField as $field => $value) {
239 if (is_array($value) && 1 === count($value)) {
240 $dataToReplaceField[$field] = static::replaceFieldWithValueHelper($value[0], $fieldValues);
241 } elseif (is_array($value)) {
242 $dataToReplaceField[$field] = static::replaceFieldWithValue($value, $fieldValues);
243 } else {
244 $dataToReplaceField[$field] = static::replaceFieldWithValueHelper($value, $fieldValues);
245 }
246 }
247 }
248 return $dataToReplaceField;
249 }
250
251 private static function replaceFieldWithValueHelper($stringToReplaceField, $fieldValues)
252 {
253 if (empty($stringToReplaceField)) {
254 return $stringToReplaceField;
255 }
256 $fieldPattern = '/\${\w[^ ${}]*}/';
257 preg_match_all($fieldPattern, $stringToReplaceField, $matchedField);
258 $uniqueFieldsInStr = array_unique($matchedField[0]);
259
260 foreach ($uniqueFieldsInStr as $value) {
261 $fieldName = substr($value, 2, strlen($value) - 3);
262
263 $repeaterArr = explode('.', $fieldName);
264 if (isset($fieldValues[$fieldName])) {
265 $stringToReplaceField = is_string($fieldValues[$fieldName])
266 ? str_replace($value, $fieldValues[$fieldName], $stringToReplaceField)
267 : wp_json_encode($fieldValues[$fieldName]);
268 } elseif (2 === count($repeaterArr) && isset($fieldValues[$repeaterArr[0]])) {
269 $repeaterValues = [];
270 $repeaterFieldValues = $fieldValues[$repeaterArr[0]];
271 foreach ($repeaterFieldValues as $value) {
272 if (isset($value[$repeaterArr[1]])) {
273 $repeaterValues[] = $value[$repeaterArr[1]];
274 }
275 }
276
277 $stringToReplaceField = $repeaterValues;
278 } else {
279 $stringToReplaceField = FieldValueHandler::replaceSmartTagWithValue($value);
280 }
281 }
282 return $stringToReplaceField;
283 }
284
285 public static function updatedHiddenFieldValue($formID)
286 {
287 $hiddenFields = [];
288 $frontendFormManger = FrontendFormManager::getInstance($formID);
289
290 if ($frontendFormManger->isHoneypotActive()) {
291 $str = '_bitform' . '_' . $formID . '_' . time() . '_';
292 $honpotToken = Helpers::honeypotEncryptedToken($str);
293 $hiddenFields[] = [
294 'name' => 'b_h_t',
295 'value' => $honpotToken
296 ];
297 }
298 $csrfTokens = Helpers::csrfEecrypted();
299 $hiddenFields[] = [
300 'name' => 't_identity',
301 'value' => $csrfTokens['t_identity'],
302 ];
303 $hiddenFields[] = [
304 'name' => 'csrf',
305 'value' => $csrfTokens['csrf']
306 ];
307 return $hiddenFields;
308 }
309
310 public static function maybeSetCronForIntegration($workFlowReturnedData, $opType, $isFormRequest = true)
311 {
312 $responseData = [];
313 $entryId = $workFlowReturnedData['triggerData']['entryID'];
314 $responseData['entry_id'] = $entryId;
315 if (isset($workFlowReturnedData['message'])) {
316 $formID = $workFlowReturnedData['triggerData']['formID'];
317 $responseData['message'] = $workFlowReturnedData['message'];
318 $responseData['hidden_fields'] = self::updatedHiddenFieldValue($formID);
319 $responseData['msg_id'] = isset($workFlowReturnedData['msg_id']) ? $workFlowReturnedData['msg_id'] : 0;
320 if (isset($workFlowReturnedData['msg_duration'])) {
321 $responseData['msg_duration'] = $workFlowReturnedData['msg_duration'];
322 }
323 if (isset($workFlowReturnedData['afterSubmit'])) {
324 $responseData['afterSubmit'] = $workFlowReturnedData['afterSubmit'];
325 }
326 }
327 if (isset($workFlowReturnedData['redirectPage'])) {
328 $responseData['redirectPage'] = $workFlowReturnedData['redirectPage'];
329 }
330 if ('update' === $opType && isset($workFlowReturnedData['updatedData'])) {
331 $responseData['updatedData'] = $workFlowReturnedData['updatedData'];
332 }
333 if (isset($workFlowReturnedData['new_nonce'])) {
334 $responseData['new_nonce'] = $workFlowReturnedData['new_nonce'];
335 }
336 if (!isset($workFlowReturnedData['triggerData'])) {
337 return $responseData;
338 }
339
340 $triggerData = $workFlowReturnedData['triggerData'];
341
342 if (!isset($workFlowReturnedData['fields'])) {
343 $workFlowReturnedData['fields'] = isset($workFlowReturnedData['updatedData'])
344 ? $workFlowReturnedData['updatedData']
345 : [];
346 }
347
348 $trnasientData = get_transient("bitform_trigger_transient_{$entryId}");
349 $trnasientData = is_string($trnasientData) ? json_decode($trnasientData) : $trnasientData;
350
351 if (!empty($trnasientData['fields'])) {
352 $workFlowReturnedData['fields'] = array_merge($workFlowReturnedData['fields'], $trnasientData['fields']);
353 }
354
355 if (function_exists('fastcgi_finish_request') || !wp_doing_ajax()) {
356 if (!headers_sent()) {
357 header('Connection: close');
358 $contentType = wp_doing_ajax() || defined('REST_REQUEST') ? 'application/json' : 'text/html';
359 header('Content-Type: ' . $contentType . '; charset=' . get_option('blog_charset'));
360 status_header(200);
361 if (!$isFormRequest) {
362 $response = [
363 'status' => 200,
364 'code' => 4000,
365 'message' => 'Data Added Successfully!!',
366 'success' => true
367 ];
368 } else {
369 $response = [
370 'success' => true,
371 'data' => $responseData,
372 ];
373 }
374 }
375 ob_start();
376 echo wp_doing_ajax() || defined('REST_REQUEST') ? wp_json_encode($response) : esc_html($workFlowReturnedData['message']);
377 ob_end_flush();
378 flush();
379 session_write_close();
380
381 if (isset($workFlowReturnedData['integrationRun']) && !$workFlowReturnedData['integrationRun']) {
382 $entryModel = new FormEntryModel();
383 $updatedStatus = $entryModel->update(
384 [
385 'status' => 2,
386 ],
387 [
388 'form_id' => $triggerData['formID'],
389 'id' => $triggerData['entryID'],
390 ]
391 );
392
393 $triggerData['fields'] = $workFlowReturnedData['fields'];
394 if (!is_wp_error($updatedStatus)) {
395 if ($workFlowReturnedData['dflt_template']) {
396 // $triggerData['fields'] = $workFlowReturnedData['fields'];
397 do_action('bitform_double_optin_confirmation', $workFlowReturnedData['integrationDetails'], $triggerData);
398 } elseif (isset($triggerData['dblOptin'])) {
399 foreach ($triggerData['dblOptin'] as $value) {
400 try {
401 MailNotifier::notify($value, $triggerData['formID'], $triggerData['fields'], $triggerData['entryID'], true, $triggerData['logID']);
402 } catch (\Throwable $mailError) {
403 // response already flushed — a mail failure here must not kill the rest of the run
404 Log::debug_log('[+] Double opt-in mail failed: ' . $mailError->getMessage());
405 }
406 }
407 }
408 }
409 if (function_exists('fastcgi_finish_request')) {
410 fastcgi_finish_request();
411 }
412
413 if (defined('REST_REQUEST') || wp_doing_ajax()) {
414 die;
415 }
416 return $workFlowReturnedData;
417 }
418 if (isset($triggerData['mail']) && !empty($triggerData['mail'])) {
419 $formManager = new AdminFormManager($triggerData['formID']);
420 $formContent = $formManager->getFormContent();
421 $submitted_fields = $formContent->fields;
422 $fieldValueForMail = FieldValueHandler::formatFieldValueForMail($submitted_fields, $workFlowReturnedData['fields']);
423 foreach ($triggerData['mail'] as $value) {
424 try {
425 MailNotifier::notify($value, $triggerData['formID'], $fieldValueForMail, $triggerData['entryID'], false, $triggerData['logID']);
426 } catch (\Throwable $mailError) {
427 // response already flushed — a mail failure here must not skip the integrations below
428 Log::debug_log('[+] Mail notification failed: ' . $mailError->getMessage());
429 }
430 }
431 }
432 do_action('bitforms_exec_integrations', $triggerData['integrations'], $workFlowReturnedData['fields'], $triggerData['formID'], $triggerData['entryID'], $triggerData['logID']);
433
434 if (function_exists('fastcgi_finish_request')) {
435 fastcgi_finish_request();
436 }
437
438 if (defined('REST_REQUEST') || wp_doing_ajax()) {
439 die;
440 }
441 return $workFlowReturnedData;
442 }
443
444 $entryID = $triggerData['entryID'];
445 if (isset($workFlowReturnedData['cron']) && $workFlowReturnedData['cron'] && empty($triggerData['mail']) && isset($workFlowReturnedData['integrationRun']) && $workFlowReturnedData['integrationRun']) {
446 $eventScheuled = wp_schedule_single_event(time(), 'bitforms_exec_integrations', [$triggerData['integrations'], $workFlowReturnedData['fields'], $triggerData['formID'], $triggerData['entryID'], $triggerData['logID']]);
447 $scheduleTime = wp_next_scheduled('bitforms_exec_integrations', [$triggerData['integrations'], $workFlowReturnedData['fields'], $triggerData['formID'], $triggerData['entryID'], $triggerData['logID']]);
448 $responseData['cron'] = get_site_url(null, "/wp-cron.php?doing_wp_cron&{$scheduleTime}");
449 } elseif (!empty($triggerData['integrations']) || !empty($triggerData['mail']) || isset($workFlowReturnedData['integrationRun']) && !$workFlowReturnedData['integrationRun']) {
450 $triggerData['fields'] = $workFlowReturnedData['fields'];
451 if (!$workFlowReturnedData['integrationRun'] && isset($workFlowReturnedData['integrationDetails'])) {
452 $triggerData['dbl_opt_donf'] = $workFlowReturnedData['integrationDetails'];
453 $triggerData['dbl_opt_dflt_template'] = $workFlowReturnedData['dflt_template'];
454 $triggerData['integrationRun'] = $workFlowReturnedData['integrationRun'];
455 }
456
457 // Generate one-time trigger token for security
458 $triggerToken = wp_hash($triggerData['entryID'] . $triggerData['logID'] . time() . wp_rand(), 'nonce');
459 $triggerData['trigger_token'] = $triggerToken;
460
461 set_transient("bitform_trigger_transient_{$entryID}", $triggerData, HOUR_IN_SECONDS);
462 $queuedAt = current_time('mysql');
463 $entryLog = new FormEntryLogModel();
464 $queueuEntry = $entryLog->log_history_insert(
465 [
466 'log_id' => $triggerData['logID'],
467 'integration_id' => 0,
468 'api_type' => wp_json_encode(['type' => 'trigger', 'type_name' => 'Workflow', 'on' => $opType]),
469 'response_type' => 'queued',
470 // 'trigger' is a durable copy of the transient payload: object-cache hosts can
471 // evict the transient (and it expires after 1h), which would otherwise lose the run
472 'response_obj' => wp_json_encode(['status' => 'queued', 'queued_at' => $queuedAt, 'trigger' => $triggerData]),
473 'created_at' => $queuedAt,
474 ]
475 );
476 if (\is_int($queueuEntry)) {
477 // Safety net: the browser-fired bitforms_trigger_workflow request can be lost
478 // (navigation abort, WAF, network drop). This event re-runs the queued workflow;
479 // it no-ops if the browser trigger already claimed the run.
480 wp_schedule_single_event(
481 time() + 2 * MINUTE_IN_SECONDS,
482 'bitforms_reclaim_workflow',
483 [(int) $entryID, (int) $triggerData['formID'], (int) $triggerData['logID'], $queueuEntry]
484 );
485 if (!wp_next_scheduled('bitforms_reclaim_sweep')) {
486 wp_schedule_event(time() + HOUR_IN_SECONDS, 'hourly', 'bitforms_reclaim_sweep');
487 }
488 }
489 $responseData['cronNotOk'] = [
490 $triggerData['entryID'],
491 $triggerData['logID'],
492 $queueuEntry,
493 $triggerToken, // Add one-time token as 4th element
494 ];
495 }
496 return $responseData;
497 }
498
499 public static function repeaterFieldValueFormatter($fieldValues)
500 {
501 $formattedArray = [];
502
503 foreach ($fieldValues as $key => $value) {
504 if (is_array($value)) {
505 foreach ($value as $index => $v) {
506 if (is_array($v)) {
507 foreach ($v as $k1 => $v1) {
508 $formattedArray[$k1][] = $v1;
509 }
510 } else {
511 $formattedArray[$key][] = $v;
512 }
513 }
514 } else {
515 $formattedArray[$key] = $value;
516 }
517 }
518
519 return $formattedArray;
520 }
521
522 /**
523 *
524 * @param mixed $fieldValues
525 * @param mixed $returnRepeaterValue default is array
526 * @param mixed $formID form ID required for string formatting
527 * @return array and repeater field value as array or string
528 */
529 public static function formattedRepeaterValue($fieldValues, $returnRepeaterValue = '', $formID = null)
530 {
531 // get the repeater field and store it in an array
532 $repeaterField = [];
533 foreach ($fieldValues as $key => $value) {
534 if (!preg_match('/\./', $key)) {
535 continue;
536 }
537 $repeaterField[] = $key;
538 }
539
540 // put the value of the child key to the parent repeater field\
541 foreach ($repeaterField as $key) {
542 list($parentKey, $childKey) = explode('.', $key);
543 $repeatValues = isset($fieldValues[$parentKey]) ? $fieldValues[$parentKey] : $key;
544
545 if (!is_array($repeatValues)) {
546 $fieldValues[$key] = $fieldValues[$childKey];
547 continue;
548 }
549
550 foreach ($repeatValues as $value) {
551 if (isset($value[$childKey])) {
552 if (!isset($fieldValues[$key]) || !is_array($fieldValues[$key])) {
553 $fieldValues[$key] = [];
554 }
555 if (!empty($value[$childKey])) {
556 $fieldValues[$key][] = $value[$childKey];
557 }
558 }
559 }
560 }
561
562 // convert the array to string repeater field value
563 if ('string' === $returnRepeaterValue) {
564 $form = new FormManager($formID);
565 foreach ($repeaterField as $key) {
566 if (isset($fieldValues[$key]) && is_array($fieldValues[$key])) {
567 $fieldValues[$key] = implode(', ', self::flattenArray($fieldValues[$key]));
568 }
569 }
570
571 foreach ($fieldValues as $key=>$value) {
572 if (!$form->isRepeaterField($key)) {
573 continue;
574 }
575 $repeaterValues = $fieldValues[$key];
576
577 $newFieldValues = self::constructRepeaterValue($repeaterValues, $formID);
578
579 $fieldValues[$key] = is_array($newFieldValues) ? json_encode(array_values($newFieldValues), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) : $fieldValues[$key];
580 }
581 }
582
583 return $fieldValues;
584 }
585
586 private static function flattenArray($array)
587 {
588 return array_map(function ($val) {
589 if (is_array($val)) {
590 return count($val) > 1 ? ('[' . implode(', ') . ']') : implode(', ', $val);
591 } else {
592 return $val;
593 }
594 }, $array);
595 }
596
597 /**
598 * Replace file field value with web url
599 * @param mixed $fieldValues
600 * @param number $formId
601 * @param number $entryId
602 * @return mixed $fieldValues
603 */
604 public static function handleFileUrl($fieldValues, $formId, $entryId)
605 {
606 if (!$formId || !$entryId) {
607 return $fieldValues;
608 }
609 $form = FormManager::getInstance($formId);
610 $formFields = $form->getFields();
611
612 $fldsIncludeFile = ['file-up', 'advanced-file-up', 'repeater', 'signature'];
613 foreach ($fieldValues as $key =>$value) {
614 $fldTyp = $formFields[$key]['type'] ?? null;
615 if (!in_array($fldTyp, $fldsIncludeFile)) {
616 continue;
617 }
618
619 if ('repeater' === $fldTyp && is_array($value)) {
620 foreach ($value as $rIndex => $rValue) {
621 foreach ($rValue as $subKey=>$subValue) {
622 if (!in_array($formFields[$subKey]['type'], $fldsIncludeFile)) {
623 continue;
624 }
625 // for file fields inside repeater
626 if (is_array($subValue)) {
627 foreach ($subValue as $fileIndex=>$fileValue) {
628 $fieldValues[$key][$rIndex][$subKey][$fileIndex] = self::constructFileUrl($formId, $entryId, $fileValue);
629 }
630 } else {
631 // for signature field inside repeater;
632 $fieldValues[$key][$rIndex][$subKey] = self::constructFileUrl($formId, $entryId, $subValue);
633 }
634 }
635 }
636 }
637
638 if (in_array($fldTyp, ['file-up', 'advanced-file-up', 'signature'], true)) {
639 if (is_array($value)) {
640 foreach ($value as $fldIndex=>$fldValue) {
641 $fieldValues[$key][$fldIndex] = self::constructFileUrl($formId, $entryId, $fldValue);
642 }
643 } else {
644 $fieldValues[$key] = self::constructFileUrl($formId, $entryId, $value);
645 }
646 }
647 }
648
649 return $fieldValues;
650 }
651
652 public static function assignRepeaterFieldValue($fieldValues, $formId)
653 {
654 if (!$formId) {
655 return $fieldValues;
656 }
657 $form = new FormManager($formId);
658 $formFields = $form->getFields();
659
660 foreach ($fieldValues as $key=>$value) {
661 if (!$form->isRepeaterField($key)) {
662 continue;
663 }
664
665 if ('repeater' === $formFields[$key]['type']) {
666 if (is_array($value)) {
667 foreach ($value as $rIndex=>$rValue) {
668 foreach ($rValue as $subKey =>$subValue) {
669 $fieldValues[$subKey] = $subValue;
670 }
671 }
672 }
673 }
674 }
675
676 return $fieldValues;
677 }
678
679 public static function constructRepeaterValue($repeaterValues, $formId)
680 {
681 if (!$formId || !is_array($repeaterValues)) {
682 return $repeaterValues;
683 }
684 $form = FormManager::getInstance($formId);
685 $formFields = $form->getFields();
686 $newRptrValue = [];
687 foreach ($repeaterValues as $key=>$value) {
688 $newRepeatedValue = [];
689 foreach ($value as $rKey =>$rValue) {
690 $fldLbl = isset($formFields[$rKey]) ? $formFields[$rKey]['label'] : $rKey;
691 $newRepeatedValue[$fldLbl] = $rValue;
692 }
693 $newRptrValue[$key] = $newRepeatedValue;
694 }
695
696 return $newRptrValue;
697 }
698
699 private static function constructFileUrl($formId, $entryId, $fileName)
700 {
701 $webPath = Helpers::getWebPathWithEncryptedEntryId($formId, $entryId);
702
703 return rtrim($webPath, '/') . '/' . ltrim($fileName, '/');
704 }
705
706 // private static function constructFileUrl($formId, $entryId, $fileName)
707 // {
708 // $restBaseUrl = get_rest_url();
709 // if (!$restBaseUrl) {
710 // return $fileName;
711 // }
712 // //http://bitlocal.local/wp-json/bitform/v1/bitform-file-download/?formID=1&entryID=16&fileID=bit-form-1005.pdf
713 // $queryParam = build_query([
714 // 'formID' => $formId,
715 // 'entryID' => $entryId,
716 // 'fileID' => $fileName
717 // ]);
718
719 // $path = $restBaseUrl . 'bitform' . '/' . 'v1' . '/' . 'bitform-file-download' . '/' . '?' . $queryParam;
720 // return rtrim($path, '/');
721 // }
722 }
723