PluginProbe
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder / 3.2.0
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder v3.2.0
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 2.10.2 All 137 releases
bit-form / includes / Admin / Form / AdminFormHandler.php

AdminFormHandler.php in Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder 3.2.0, at includes/Admin/Form/AdminFormHandler.php

2,995 lines 114.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Handle Form Create,Update,delete Operation
5 *
6 */
7
8 namespace BitCode\BitForm\Admin\Form;
9
10 use BitCode\BitForm\Admin\Form\Template\TemplateProvider;
11 use BitCode\BitForm\Core\Database\EmailTemplateModel;
12 use BitCode\BitForm\Core\Database\FormEntryLogModel;
13 use BitCode\BitForm\Core\Database\FormEntryMetaModel;
14 use BitCode\BitForm\Core\Database\FormEntryModel;
15 use BitCode\BitForm\Core\Database\FormModel;
16 use BitCode\BitForm\Core\Database\IntegrationModel;
17 use BitCode\BitForm\Core\Database\ReportsModel;
18 use BitCode\BitForm\Core\Database\SuccessMessageModel;
19 use BitCode\BitForm\Core\Database\WorkFlowModel;
20 use BitCode\BitForm\Core\Form\FormManager;
21 use BitCode\BitForm\Core\Integration\IntegrationHandler;
22 use BitCode\BitForm\Core\Messages\EmailTemplateHandler;
23 use BitCode\BitForm\Core\Messages\SuccessMessageHandler;
24 use BitCode\BitForm\Core\Migration\MigrationHelper;
25 use BitCode\BitForm\Core\Util\FileHandler;
26 use BitCode\BitForm\Core\Util\FormDuplicateHelper;
27 use BitCode\BitForm\Core\Util\HttpHelper;
28 use BitCode\BitForm\Core\Util\IpTool;
29 use BitCode\BitForm\Core\Util\Log;
30 use BitCode\BitForm\Core\Util\Utilities;
31 use BitCode\BitForm\Core\WorkFlow\WorkFlow;
32 use BitCode\BitForm\Core\WorkFlow\WorkFlowHandler;
33 use WP_Error;
34
35 class AdminFormHandler
36 {
37 private static $formModel;
38 private static $ipTool;
39
40 public function __construct()
41 {
42 static::$formModel = new FormModel();
43 static::$ipTool = new IpTool();
44 }
45
46 public function getTemplate($Request, $post)
47 {
48 $templateName = null;
49 $newFormId = null;
50 if (isset($post->template)) {
51 $templateName = $post->template;
52 $newFormId = $post->newFormId;
53 }
54
55 $templateProvider = new TemplateProvider();
56 $form_content_raw = $templateProvider->getTemplate($templateName, $newFormId);
57 if (!$form_content_raw) {
58 return new WP_Error('template_empty', __('Template not found, by this name: ', 'bit-form') . $templateName);
59 } else {
60 return wp_json_encode(
61 [
62 'id' => 0,
63 'form_content' => $form_content_raw,
64 ]
65 );
66 }
67 }
68
69 public function saveStyleSheet($styles, $sheetName)
70 {
71 $this->createFormStylesDirIfNotExists();
72
73 if (
74 file_exists(BITFORMS_CONTENT_DIR . DIRECTORY_SEPARATOR . 'form-styles')
75 && wp_is_writable(BITFORMS_CONTENT_DIR . DIRECTORY_SEPARATOR . 'form-styles')
76 ) {
77 $filePath = BITFORMS_CONTENT_DIR . DIRECTORY_SEPARATOR . 'form-styles' . DIRECTORY_SEPARATOR . $sheetName;
78 return FileHandler::writeFile($filePath, $styles);
79 }
80 return false;
81 }
82
83 public function saveLayoutStyleSheet($layout, $sheetName, $lay_row_height = 43)
84 {
85 $md_width = 600;
86 $sm_width = 400;
87 $lg_styles = '';
88 $md_styles = '';
89 $sm_styles = '';
90 for ($i = 0; $i < count($layout->lg ?? []); $i++) {
91 $fld = $layout->lg[$i];
92
93 if ($fld->w < 10) {
94 $lay_row_height = 43;
95 } else {
96 $lay_row_height = 2;
97 }
98
99 $class = $fld->i;
100 $lg_g_r_s = $fld->y + 1;
101 $lg_g_c_s = $fld->x + 1;
102 $lg_g_r_e = 1 !== $fld->y ? $fld->h + ($fld->y + 1) : 1;
103 $lg_g_c_e = ($fld->x + 1) + $fld->w;
104 $lg_g_r_span = $lg_g_r_e - $lg_g_r_s;
105 $lg_g_c_span = $lg_g_c_e - $lg_g_c_s;
106 $lg_min_height = $fld->h * $lay_row_height . 'px;';
107
108 $lg_styles .= ".$class { grid-area: $lg_g_r_s / $lg_g_c_s / $lg_g_r_e / $lg_g_c_e ; -ms-grid-row: $lg_g_r_s; -ms-grid-row-span: $lg_g_r_span; -ms-grid-column: $lg_g_c_s; -ms-grid-column-span: $lg_g_c_span; min-height: $lg_min_height; }";
109
110 $fld = $layout->md[$i];
111
112 $class = $fld->i;
113 $md_g_r_s = $fld->y + 1;
114 $md_g_c_s = $fld->x + 1;
115 $md_g_r_e = 1 !== $fld->y ? $fld->h + ($fld->y + 1) : 1;
116 $md_g_c_e = ($fld->x + 1) + $fld->w;
117 $md_g_r_span = $lg_g_r_e - $md_g_r_s;
118 $md_g_c_span = $lg_g_c_e - $md_g_c_s;
119 $md_min_height = $fld->h * $lay_row_height . 'px;';
120
121 $md_styles .= ".$class { grid-area: $md_g_r_s / $md_g_c_s / $md_g_r_e / $md_g_c_e ; -ms-grid-row: $md_g_r_s; -ms-grid-row-span: $md_g_r_span; -ms-grid-column: $md_g_c_s; -ms-grid-column-span: $md_g_c_span; min-height: $md_min_height; }";
122
123 $fld = $layout->sm[$i];
124
125 $class = $fld->i;
126 $sm_g_r_s = $fld->y + 1;
127 $sm_g_c_s = $fld->x + 1;
128 $sm_g_r_e = 1 !== $fld->y ? $fld->h + ($fld->y + 1) : 1;
129 $sm_g_c_e = ($fld->x + 1) + $fld->w;
130 $sm_g_r_span = $sm_g_r_e - $sm_g_r_s;
131 $sm_g_c_span = $sm_g_c_e - $sm_g_c_s;
132 $sm_min_height = $fld->h * $lay_row_height . 'px;';
133
134 $sm_styles .= ".$class { grid-area: $sm_g_r_s / $sm_g_c_s / $sm_g_r_e / $sm_g_c_e ; -ms-grid-row: $sm_g_r_s; -ms-grid-row-span: $sm_g_r_span; -ms-grid-column: $sm_g_c_s; -ms-grid-column-span: $sm_g_c_span; min-height: $sm_min_height; }";
135 }
136 $formStyle = "._frm-g{
137 display: grid;
138 display: -ms-grid;
139 grid-template-columns: repeat( 6 , minmax( 30px , 1fr ));
140 -ms-grid-columns: minmax( 30px , 1fr ) minmax( 30px , 1fr ) minmax( 30px , 1fr ) minmax( 30px , 1fr ) minmax( 30px , 1fr ) minmax( 30px , 1fr );
141 }
142 {$lg_styles}
143 @media only screen and (max-width:{$md_width}px) {
144 ._frm-g {grid-template-columns: repeat( 4 , minmax( 30px , 1fr ));-ms-grid-columns: minmax( 30px , 1fr ) minmax( 30px , 1fr ) minmax( 30px , 1fr ) minmax( 30px , 1fr );}
145 {$md_styles}
146 }
147 @media only screen and (max-width:{$sm_width}px) {
148 ._frm-g {grid-template-columns: repeat( 2 , minmax( 30px , 1fr ));-ms-grid-columns: minmax( 30px , 1fr ) minmax( 30px , 1fr );}
149 {$sm_styles}
150 }";
151
152 $this->createFormStylesDirIfNotExists();
153
154 if (
155 file_exists(BITFORMS_CONTENT_DIR . DIRECTORY_SEPARATOR . 'form-styles')
156 && wp_is_writable(BITFORMS_CONTENT_DIR . DIRECTORY_SEPARATOR . 'form-styles')
157 ) {
158 $filePath = BITFORMS_CONTENT_DIR . DIRECTORY_SEPARATOR . 'form-styles' . DIRECTORY_SEPARATOR . $sheetName;
159 return FileHandler::writeFile($filePath, $formStyle);
160 }
161 return false;
162 }
163
164 public function createFormStylesDirIfNotExists()
165 {
166 if (!file_exists(BITFORMS_UPLOAD_DIR)) {
167 wp_mkdir_p(BITFORMS_UPLOAD_DIR);
168 }
169 if (!file_exists(BITFORMS_CONTENT_DIR . DIRECTORY_SEPARATOR . 'form-styles')) {
170 wp_mkdir_p(BITFORMS_CONTENT_DIR . DIRECTORY_SEPARATOR . 'form-styles');
171 }
172 }
173
174 private function pdfFontDownload($fontName)
175 {
176 if (class_exists('\BitCode\BitFormPro\Admin\AppSetting\Pdf')) {
177 \BitCode\BitFormPro\Admin\AppSetting\Pdf::getInstance()->fontsDownload($fontName);
178 }
179 return false;
180 }
181
182 public function createNewForm($Request, $post)
183 {
184 // wp_send_json_success($post);
185 // exit;
186 if (!isset($post->form_id) || '' === $post->form_id) {
187 return new WP_Error('empty_form', __('Error Occurred, Please Reload', 'bit-form'));
188 }
189
190 $formManager = new AdminFormManager($post->form_id);
191 if ($formManager->isExist()) {
192 return new WP_Error('empty_form', __('Error Occurred, Please Reload', 'bit-form'));
193 }
194
195 if (isset($post->formStyle) && $post->formStyle) {
196 $sheetName = 'bitform-' . $post->form_id . '.css';
197 $this->saveStyleSheet($post->formStyle, $sheetName);
198 }
199
200 if (isset($post->layoutChanged) && $post->layoutChanged) {
201 $sheetName = 'bitform-layout-' . $post->form_id . '.css';
202 $rowHeight = (int) $post->rowHeight;
203 $this->saveLayoutStyleSheet($post->layout, $sheetName, $rowHeight);
204 }
205
206 $fields = wp_unslash($post->fields);
207 $fields = Helpers::replaceFieldsDefaultErrorMsg($fields);
208 // $fields = $post->fields;
209 $layout = wp_unslash($post->layout);
210 $nestedLayout = isset($post->nestedLayouts) ? wp_unslash($post->nestedLayouts) : (object) [];
211 $formInfo = wp_unslash($post->formInfo);
212 $form_name = wp_unslash($post->form_name);
213 $form_name = strlen($form_name) > 50 ? substr($form_name, 0, 50) : $form_name;
214 $formSettings = (object) wp_unslash($post->formSettings);
215 $atomic_class_map = isset($post->atomicClassMap) ? wp_unslash($post->atomicClassMap) : [];
216 $breakpointSize = wp_unslash($post->breakpointSize);
217 $style = $post->style;
218 $themeVars = $post->themeVars;
219 $themeColors = $post->themeColors;
220 $staticStyles = $post->staticStyles;
221 $workFlows = wp_unslash($post->workFlows);
222 $additional = wp_unslash($post->additional);
223 $reports = !empty($post->reports) ? $post->reports : (object) [];
224 $builderSettings = (object) isset($post->builderSettings) ? wp_unslash($post->builderSettings) : [];
225
226 $mailTem = $formSettings->mailTem;
227 $pdfTem = $formSettings->pdfTem;
228 $integrations = $formSettings->integrations;
229 $formPermissions = $formSettings->formPermissions;
230
231 $user_details = static::$ipTool->getUserDetail();
232 if (empty($fields) || empty($layout)) {
233 return new WP_Error(
234 'empty_form',
235 __('Can not save empty form.', 'bit-form')
236 );
237 }
238 if (strlen($form_name) > 50) {
239 return new WP_Error(
240 'empty_form',
241 __('Form Name Should Be Within 50 Characters', 'bit-form')
242 );
243 }
244 // Guard: never persist orphan fields (in fields but in no layout) — they
245 // render nothing yet their validation rules block submission. Covers old
246 // clients and hand-edited imports (importAForm funnels through here).
247 $this->pruneOrphanFields($fields, $nestedLayout, $layout, null, $post);
248 $form_content = [
249 'fields' => $fields,
250 'layout' => $layout,
251 'nestedLayout' => $nestedLayout,
252 'formInfo' => $formInfo,
253 ];
254
255 /* if (!empty($formSettings->submitBtn)) {
256 $form_content = array_merge($form_content, array('buttons' => $formSettings->submitBtn));
257 } */
258 if (!empty($formSettings->theme)) {
259 $form_content = array_merge($form_content, ['theme' => $formSettings->theme]);
260 }
261
262 if (!empty($formSettings->formPermissions)) {
263 $form_content = array_merge($form_content, ['formPermissions' => $formSettings->formPermissions]);
264 }
265
266 if (!empty($additional)) {
267 $form_content = array_merge($form_content, ['additional' => $additional]);
268 }
269 if (!empty($workFlows)) {
270 $workflows = is_string($workFlows) ? json_decode($workFlows) : $workFlows;
271 $workFlowExist = [];
272 foreach ($workflows as $index => $workFlow) {
273 if (in_array($workFlow->action_type, ['always', 'onload'])) {
274 $workFlowExist['onload'] = true;
275 }
276 if ('oninput' === $workFlow->action_type || ('always' === $workFlow->action_type && 'cond' === $workFlow->action_behaviour)) {
277 $workFlowExist['oninput'] = true;
278 }
279 }
280 $form_content = array_merge($form_content, ['workFlowExist' => $workFlowExist]);
281 }
282 $form_content = \wp_json_encode($form_content);
283
284 $builder_helper_state = (object) [
285 'style' => $style,
286 'staticStyles' => $staticStyles,
287 'breakpointSize' => $breakpointSize,
288 'themeVars' => $themeVars,
289 'themeColors' => $themeColors,
290 'builderSettings' => $builderSettings
291 ];
292 $atomic_class_map = \wp_json_encode($atomic_class_map);
293 $fdata = [
294 'id' => $post->form_id,
295 'form_content' => $form_content,
296 'builder_helper_state' => \wp_json_encode($builder_helper_state),
297 'atomic_class_map' => $atomic_class_map,
298 'generated_script_page_ids' => \wp_json_encode((object) []),
299 'user_id' => $user_details['id'],
300 'user_ip' => $user_details['ip'],
301 'user_device' => $user_details['device'],
302 'status' => 1,
303 'form_name' => $form_name,
304 'created_at' => $user_details['time'],
305 'updated_at' => $user_details['time'],
306 ];
307
308 $save_status = static::$formModel->insert($fdata);
309
310 if (is_wp_error($save_status)) {
311 return $save_status;
312 } elseif (!$save_status) {
313 return false;
314 } else {
315 FileHandler::createIndexFile(BITFORMS_UPLOAD_DIR . "/$save_status");
316 $formID = $save_status;
317 do_action('bitform_admin_form_changed');
318 $integartionIDForWorkflow = [];
319 // Confiramtion Message [start]
320 if (!empty($formSettings->confirmation->type->successMsg)) {
321 $successMessages = $formSettings->confirmation->type->successMsg;
322 $successMessageHandler = new SuccessMessageHandler($formID, $user_details);
323 foreach ($successMessages as $messageKey => $messageDetail) {
324 $savedID = $successMessageHandler->saveMessage($messageDetail);
325 if ($savedID) {
326 $msgIdx = empty($messageDetail->id) ? $messageKey : wp_json_encode(['id' => $messageDetail->id]);
327 $integartionIDForWorkflow['successMsg'][$msgIdx] = $savedID;
328 if (!empty($messageDetail->clRef)) {
329 $integartionIDForWorkflow['confirmationCLRef'][$messageDetail->clRef] = $savedID;
330 }
331 $messageDetail->id = $savedID;
332 $style = $this->updateSuccessMessageClassName($style, $messageKey, $savedID);
333 $atomic_class_map = $this->updateSuccessMessageClassName($atomic_class_map, $messageKey, $savedID);
334 }
335 }
336 $builder_helper_state = (object) [
337 'style' => $style,
338 'breakpointSize' => $breakpointSize,
339 'themeVars' => $themeVars,
340 'themeColors' => $themeColors,
341 'builderSettings' => $builderSettings
342 ];
343 $update_status = static::$formModel->update(
344 [
345 'builder_helper_state' => \wp_json_encode($builder_helper_state),
346 'atomic_class_map' => $atomic_class_map,
347 ],
348 [
349 'id' => $formID,
350 ]
351 );
352 if (is_wp_error($update_status)) {
353 return $update_status;
354 }
355 unset($formSettings->confirmation->type->successMsg);
356 }
357 // return $formSettings;
358 // Confiramtion Message [end] */
359 // Email Template [start]
360 if (!empty($mailTem)) {
361 $emailTemplateHandler
362 = new EmailTemplateHandler($formID, $user_details);
363 foreach ($mailTem as $templateKey => $templateDetail) {
364 $savedID = $emailTemplateHandler->saveTemplate($templateDetail);
365 if ($savedID && !is_wp_error($savedID)) {
366 $tempIdx = empty($templateDetail->id) ? $templateKey : wp_json_encode(['id' => $templateDetail->id]);
367 $integartionIDForWorkflow['mailNotify'][$tempIdx] = $savedID;
368 if (!empty($templateDetail->clRef)) {
369 $integartionIDForWorkflow['emailCLRef'][$templateDetail->clRef] = $savedID;
370 }
371 // return the new id (and drop the temp ref) so the frontend reconciles the template
372 $templateDetail->id = $savedID;
373 unset($templateDetail->clRef);
374 }
375 }
376 }
377 // Email Template [end] */
378
379 // PDF Template [start]
380 if (!empty($pdfTem) && class_exists('\BitCode\BitFormPro\Core\Messages\PdfTemplateHandler')) {
381 $pdfTemplateHandler = new \BitCode\BitFormPro\Core\Messages\PdfTemplateHandler($formID);
382 $workFlowString = '';
383 if (!empty($workFlows)) {
384 $workFlowString = wp_json_encode($workFlows);
385 }
386 foreach ($pdfTem as $templateDetail) {
387 $savedID = $pdfTemplateHandler->save($templateDetail);
388
389 $pdfSetting = $templateDetail->setting;
390
391 if (isset($pdfSetting->font->name) && !empty($pdfSetting->font->name)) {
392 $this->pdfFontDownload($pdfSetting->font->name);
393 }
394 if (!empty($workFlowString)) {
395 $workFlowString = str_replace('"pdfId":"{\"id\":\"' . $templateDetail->id . '\"}"', '"pdfId":"{\"id\":\"' . $savedID . '\"}"', $workFlowString);
396 // Multi-PDF: remap ids inside "pdfIds":[...] segments only — email-template ids use
397 // the same {\"id\":N} token shape, so a global replace would corrupt them.
398 $workFlowString = preg_replace_callback(
399 '/"pdfIds":\[[^\]]*\]/',
400 function ($matches) use ($templateDetail, $savedID) {
401 return str_replace('{\"id\":\"' . $templateDetail->id . '\"}', '{\"id\":\"' . $savedID . '\"}', $matches[0]);
402 },
403 $workFlowString
404 );
405 }
406 }
407 if (!empty($workFlowString) && !empty($workFlows)) {
408 $workFlows = json_decode($workFlowString);
409 }
410 }
411 // PDF Template [end] */
412 //Integration [start] */
413 $integrationHandler = new IntegrationHandler($formID, $user_details);
414 if (!empty($formSettings->confirmation->type)) {
415 $allIntegrations = $formSettings->confirmation->type;
416 foreach ($allIntegrations as $integrationType => $integrationGroup) {
417 foreach ($integrationGroup as $singleIntegrationKey => $singleIntegrationDetail) {
418 $integrationStatus = isset($singleIntegrationDetail->status) ? (int) $singleIntegrationDetail->status : 1;
419 // Inline-CL temp ref for a brand-new redirect (reconciled to the real id for workflow rows).
420 $clRef = isset($singleIntegrationDetail->clRef) ? $singleIntegrationDetail->clRef : null;
421 if (is_object($singleIntegrationDetail)) {
422 unset($singleIntegrationDetail->status, $singleIntegrationDetail->clRef);
423 }
424 if (empty($singleIntegrationDetail->details)) {
425 $integrationName = $singleIntegrationDetail->title;
426 unset($singleIntegrationDetail->title, $singleIntegrationDetail->id);
427
428 $integrationDetails = !is_string($singleIntegrationDetail) ?
429 wp_json_encode($singleIntegrationDetail) : $singleIntegrationDetail;
430 } else {
431 $integrationName = $singleIntegrationDetail->title;
432 $integrationDetails = !is_string($singleIntegrationDetail->details) ?
433 wp_json_encode($singleIntegrationDetail->details) : $singleIntegrationDetail->details;
434 }
435 $savedID = $integrationHandler->saveIntegration($integrationName, $integrationType, $integrationDetails, 'form', $integrationStatus);
436 $integIdx = empty($singleIntegrationDetail->id) ? $savedID : wp_json_encode(['id' => $singleIntegrationDetail->id]);
437 $integartionIDForWorkflow[$integrationType][$integIdx] = $savedID;
438 if (!empty($clRef) && 'redirectPage' === $integrationType) {
439 $integartionIDForWorkflow['redirectCLRef'][$clRef] = $savedID;
440 }
441 }
442 }
443 }
444 if (isset($formSettings->formAbandonment)) {
445 $formAbandonment = $formSettings->formAbandonment;
446
447 $integrationName = 'formAbandonment';
448 $integrationType = 'formAbandonment';
449 $abandonmentIntegDetails = wp_json_encode($formAbandonment);
450 $integrationHandler->saveIntegration($integrationName, $integrationType, $abandonmentIntegDetails, 'formAbandonment');
451 }
452 if (!empty($integrations)) {
453 foreach ($integrations as $singleIntegrationKey => $singleIntegrationDetail) {
454 $integrationName = $singleIntegrationDetail->name;
455 unset($singleIntegrationDetail->name);
456 $integrationType = $singleIntegrationDetail->type;
457 unset($singleIntegrationDetail->type);
458 $singleIntegrationDetailID = empty($singleIntegrationDetail->id) ? null : $singleIntegrationDetail->id;
459 unset($singleIntegrationDetail->id);
460 // Inline-CL temp ref for a brand-new integration (reconciled to the real id for workflow rows).
461 $clRef = isset($singleIntegrationDetail->__bf_cl_ref) ? $singleIntegrationDetail->__bf_cl_ref : null;
462 unset($singleIntegrationDetail->__bf_cl_ref);
463 if (empty($singleIntegrationDetail->details)) {
464 $integrationDetails = !is_string($singleIntegrationDetail) ?
465 wp_json_encode($singleIntegrationDetail) : $singleIntegrationDetail;
466 } else {
467 $integrationDetails = !is_string($singleIntegrationDetail->details) ?
468 wp_json_encode($singleIntegrationDetail->details) : $singleIntegrationDetail->details;
469 }
470 $savedID = $integrationHandler->saveIntegration($integrationName, $integrationType, $integrationDetails, 'form');
471 $integIdx = empty($singleIntegrationDetailID) ? $singleIntegrationKey : wp_json_encode(['id' => $singleIntegrationDetailID]);
472 $integartionIDForWorkflow['integ'][$integIdx] = $savedID;
473 if (!empty($clRef) && !is_wp_error($savedID)) {
474 $integartionIDForWorkflow['integrationCLRef'][$clRef] = $savedID;
475 }
476 }
477 }
478 //Integrations [end]
479 //wrokFlows [start]
480 if (!empty($workFlows)) {
481 $workFlowHandler = new WorkFlowHandler($formID, $user_details);
482
483 foreach ($workFlows as $index => $workFlow) {
484 $savedID = $workFlowHandler->saveworkFlow($workFlow, $integartionIDForWorkflow, $index);
485 $newData['workflow'] = 1;
486 }
487
488 // $workflowCount = count($workFlows);
489 // while ($workflowCount) {
490 // $workFlow = $workFlows[--$workflowCount];
491 // $savedID = $workFlowHandler->saveworkFlow($workFlow, $integartionIDForWorkflow);
492 // $newData['workflow'] = 1;
493 // }
494 }
495 //wrokFlows [end]
496 $details = [
497 'report_name' => __('All Entries', 'bit-form'),
498 'hiddenColumns' => ['__user_id', '__user_ip', '__referer', '__user_device', '__created_at', '__updated_at'],
499 'pageSize' => 10,
500 'sortBy' => [],
501 'filters' => [],
502 'globalFilter' => '',
503 'order' => []
504 ];
505 $defaultReport = [
506 'type' => 'table',
507 'category' => 'form',
508 'context' => $formID,
509 'details' => wp_json_encode($details),
510 'isDefault' => (bool) 1,
511 'user_id' => $user_details['id'],
512 'user_ip' => $user_details['ip'],
513 'user_device' => $user_details['device'],
514 'created_at' => $user_details['time'],
515 'updated_at' => $user_details['time'],
516 ];
517 $reportsModel = new ReportsModel();
518 $saveReportId = $reportsModel->insert($defaultReport);
519
520 // }
521 $updated_data = $this->getAForm(['id' => $save_status], null);
522 if (!is_wp_error($saveReportId) && isset($updated_data['form_content'])) {
523 $updated_data['form_content']['report_id'] = $saveReportId;
524 $updated_data['form_content']['is_default'] = 1;
525 }
526 $updated_data['message'] = __('Form Saved successfully', 'bit-form');
527
528 return $updated_data;
529 }
530 }
531
532 public function updateForm($Request, $post)
533 {
534 // return ['checked dta'=>$post];
535 $formId = $post->id;
536 // get the builder_helper_state from the form
537 $builder_helper_state = self::$formModel->get(['builder_helper_state'], ['id' => $formId]);
538 $builder_helper_state = (!is_wp_error($builder_helper_state) && 1 === count($builder_helper_state) && isset($builder_helper_state[0]->builder_helper_state)) ? $builder_helper_state[0]->builder_helper_state : '{}';
539 $builder_helper_state = json_decode($builder_helper_state);
540 if (property_exists($post, 'breakpointSize')) {
541 $builder_helper_state->breakpointSize = $post->breakpointSize;
542 }
543 if (property_exists($post, 'style')) {
544 $builder_helper_state->style = $post->style;
545 }
546 if (property_exists($post, 'staticStyles')) {
547 $builder_helper_state->staticStyles = $post->staticStyles;
548 }
549 if (property_exists($post, 'themeVars')) {
550 $builder_helper_state->themeVars = $post->themeVars;
551 }
552 if (property_exists($post, 'themeColors')) {
553 $builder_helper_state->themeColors = $post->themeColors;
554 }
555 if (property_exists($post, 'builderSettings')) {
556 $builder_helper_state->builderSettings = $post->builderSettings;
557 }
558 if (property_exists($post, 'atomicClassMap')) {
559 $atomic_class_map = \wp_json_encode((object) $post->atomicClassMap);
560 }
561
562 if (property_exists($post, 'fields') && null !== $post->fields && property_exists($post, 'layout') && $post->layout) {
563 $fields = wp_unslash($post->fields);
564 $fields = Helpers::replaceFieldsDefaultErrorMsg($fields);
565 $layout = wp_unslash($post->layout);
566 $nestedLayout = wp_unslash($post->nestedLayouts);
567 $formInfo = wp_unslash($post->formInfo);
568 $formID = wp_unslash($post->id);
569 $form_name = wp_unslash($post->form_name);
570 $formSettings = wp_unslash($post->formSettings);
571 $workFlows = wp_unslash($post->workFlows);
572 $additional = wp_unslash($post->additional);
573 $reports = wp_unslash($post->currentReport);
574 }
575
576 $mailTem = $formSettings->mailTem;
577 $pdfTem = isset($formSettings->pdfTem) ? $formSettings->pdfTem : [];
578 $integrations = $formSettings->integrations;
579
580 $user_details = static::$ipTool->getUserDetail();
581
582 if (empty($fields) || empty($layout) || is_null($formID)) {
583 return new WP_Error('empty_form', 'Can not update empty form.');
584 }
585
586 // Guard: never persist orphan fields (see createNewForm). Fail closed.
587 $this->pruneOrphanFields($fields, $nestedLayout, $layout, $formID, $post);
588
589 $form_content = [
590 'fields' => $fields,
591 'layout' => $layout,
592 'nestedLayout' => $nestedLayout,
593 'formInfo' => $formInfo,
594 ];
595
596 if (isset($post->report_id)) {
597 $form_content['report_id'] = wp_unslash($post->report_id);
598 }
599
600 /* if (!empty($formSettings->submitBtn)) {
601 $form_content = array_merge($form_content, array('buttons' => $formSettings->submitBtn));
602 } */
603 if (!empty($formSettings->theme)) {
604 $form_content = array_merge($form_content, ['theme' => $formSettings->theme]);
605 }
606
607 if (!empty($formSettings->formPermissions)) {
608 $form_content = array_merge($form_content, ['formPermissions' => $formSettings->formPermissions]);
609 }
610 if (!empty($additional)) {
611 $form_content = array_merge($form_content, ['additional' => $additional]);
612 }
613 $integartionIDForWorkflow = [];
614 $newData['settingConfiramation'] = 0;
615 $newData['integation'] = 0;
616 $newData['mailTemplate'] = 0;
617 $newData['workflow'] = 0;
618 $newData['reports'] = 0;
619 $newData['pdfTemplate'] = 0;
620 // Confiramtion Message [start]
621 if (!empty($formSettings->confirmation->type->successMsg)) {
622 $successMessages = $formSettings->confirmation->type->successMsg;
623 $successMessageHandler
624 = new SuccessMessageHandler($formID, $user_details);
625 foreach ($successMessages as $messageKey => $messageDetail) {
626 if (empty($messageDetail->id)) {
627 $savedID = $successMessageHandler->saveMessage($messageDetail);
628 if ($savedID) {
629 $newData['settingConfiramation'] = 1;
630 $integartionIDForWorkflow['successMsg'][$messageKey] = $savedID;
631 if (!empty($messageDetail->clRef)) {
632 $integartionIDForWorkflow['confirmationCLRef'][$messageDetail->clRef] = $savedID;
633 }
634 $messageDetail->id = $savedID;
635 $builder_helper_state->style = $this->updateSuccessMessageClassName($builder_helper_state->style, $messageKey, $savedID);
636 if (isset($atomic_class_map)) {
637 $atomic_class_map = $this->updateSuccessMessageClassName($atomic_class_map, $messageKey, $savedID);
638 }
639 }
640 } else {
641 $successMessageHandler->updateMessage($messageDetail);
642 }
643 }
644 unset($formSettings->confirmation->type->successMsg);
645 }
646 // return $formSettings;
647 // Confirmation Message [end] */
648 // Email Template [start]
649 if (!empty($mailTem)) {
650 $emailTemplateHandler
651 = new EmailTemplateHandler($formID, $user_details);
652 foreach ($mailTem as $templateKey => $templateDetail) {
653 if (empty($templateDetail->id)) {
654 $savedID = $emailTemplateHandler->saveTemplate($templateDetail);
655 if (is_wp_error($savedID) && 'result_empty' === $savedID->get_error_code()) {
656 $newData['mailTemplate'] = 2;
657 } else {
658 $newData['mailTemplate'] = 1;
659 $integartionIDForWorkflow['mailTem'][$templateKey] = $savedID;
660 if (!empty($templateDetail->clRef)) {
661 $integartionIDForWorkflow['emailCLRef'][$templateDetail->clRef] = $savedID;
662 }
663 // return the new id (and drop the temp ref) so the frontend reconciles the template
664 $templateDetail->id = $savedID;
665 unset($templateDetail->clRef);
666 }
667 } else {
668 $emailTemplateHandler->updateTemplate($templateDetail);
669 }
670 }
671 }
672 // return $formSettings;
673 // Email Template [end] */
674 if (!empty($pdfTem) && class_exists('\BitCode\BitFormPro\Core\Messages\PdfTemplateHandler')) {
675 $pdfTemplateHandler = new \BitCode\BitFormPro\Core\Messages\PdfTemplateHandler($formID);
676
677 foreach ($pdfTem as $templateKey => $templateDetail) {
678 if (isset($templateDetail->setting->font->name)) {
679 $this->pdfFontDownload($templateDetail->setting->font->name);
680 }
681
682 $savedID = $pdfTemplateHandler->saveOrUpdate($templateDetail);
683 if (is_wp_error($savedID) && 'result_empty' === $savedID->get_error_code()) {
684 $newData['pdfTemplate'] = 2;
685 } else {
686 $newData['pdfTemplate'] = 1;
687 $integartionIDForWorkflow['pdfTem'][$templateKey] = $savedID;
688 }
689 }
690 }
691 //Integration [start] */
692 $integrationHandler = new IntegrationHandler($formID, $user_details);
693 if (!empty($formSettings->confirmation->type)) {
694 $allIntegrations = $formSettings->confirmation->type;
695 foreach ($allIntegrations as $integrationType => $integrationGroup) {
696 foreach ($integrationGroup as $singleIntegrationKey => $singleIntegrationDetail) {
697 // Redirect (and webhook) enable/disable toggle persists to the integration status column.
698 $integrationStatus = isset($singleIntegrationDetail->status) ? (int) $singleIntegrationDetail->status : 1;
699 // Inline-CL temp ref for a brand-new redirect (reconciled to the real id for workflow rows).
700 $clRef = isset($singleIntegrationDetail->clRef) ? $singleIntegrationDetail->clRef : null;
701 if (is_object($singleIntegrationDetail)) {
702 unset($singleIntegrationDetail->status, $singleIntegrationDetail->clRef);
703 }
704 if (empty($singleIntegrationDetail->details)) {
705 $integrationName = $singleIntegrationDetail->title;
706 unset($singleIntegrationDetail->title);
707 $singleIntegrationDetailID = empty($singleIntegrationDetail->id) ? null : $singleIntegrationDetail->id;
708 unset($singleIntegrationDetail->id);
709 $integrationDetails = !is_string($singleIntegrationDetail) ?
710 wp_json_encode($singleIntegrationDetail) : $singleIntegrationDetail;
711 } else {
712 $singleIntegrationDetailID = empty($singleIntegrationDetail->id) ? null : $singleIntegrationDetail->id;
713 unset($singleIntegrationDetail->id);
714 $integrationName = $singleIntegrationDetail->title;
715 $integrationDetails = !is_string($singleIntegrationDetail->details) ?
716 wp_json_encode($singleIntegrationDetail->details) : $singleIntegrationDetail->details;
717 }
718 if (empty($singleIntegrationDetailID)) {
719 $savedID = $integrationHandler->saveIntegration($integrationName, $integrationType, $integrationDetails, 'form', $integrationStatus);
720 $newData['settingConfiramation'] = 1;
721 $integartionIDForWorkflow[$integrationType][$singleIntegrationKey] = $savedID;
722 if (!empty($clRef) && 'redirectPage' === $integrationType) {
723 $integartionIDForWorkflow['redirectCLRef'][$clRef] = $savedID;
724 }
725 } else {
726 $integrationHandler->updateIntegration($singleIntegrationDetailID, $integrationName, $integrationType, $integrationDetails, 'form', $integrationStatus);
727 }
728 }
729 }
730 }
731 if (!empty($integrations)) {
732 foreach ($integrations as $singleIntegrationKey => $singleIntegrationDetail) {
733 $integrationName = $singleIntegrationDetail->name;
734 unset($singleIntegrationDetail->name);
735 $integrationType = $singleIntegrationDetail->type;
736 unset($singleIntegrationDetail->type);
737 $singleIntegrationDetailID = empty($singleIntegrationDetail->id) ? null : $singleIntegrationDetail->id;
738 unset($singleIntegrationDetail->id);
739 // Inline-CL temp ref for a brand-new integration (reconciled to the real id for workflow rows).
740 $clRef = isset($singleIntegrationDetail->__bf_cl_ref) ? $singleIntegrationDetail->__bf_cl_ref : null;
741 unset($singleIntegrationDetail->__bf_cl_ref);
742 if (empty($singleIntegrationDetail->details)) {
743 $integrationDetails = !is_string($singleIntegrationDetail) ?
744 wp_json_encode($singleIntegrationDetail) : $singleIntegrationDetail;
745 } else {
746 $integrationDetails = !is_string($singleIntegrationDetail->details) ?
747 wp_json_encode($singleIntegrationDetail->details) : $singleIntegrationDetail->details;
748 }
749 if (empty($singleIntegrationDetailID)) {
750 $savedID = $integrationHandler->saveIntegration($integrationName, $integrationType, $integrationDetails, 'form');
751 $integartionIDForWorkflow[$integrationType][$singleIntegrationKey] = $savedID;
752 if (!empty($clRef) && !is_wp_error($savedID)) {
753 $integartionIDForWorkflow['integrationCLRef'][$clRef] = $savedID;
754 }
755 if (is_wp_error($savedID) && 'result_empty' !== $savedID->get_error_code()) {
756 $newData['integation'] = 2;
757 } else {
758 $newData['integation'] = 1;
759 }
760 } else {
761 $integrationHandler->updateIntegration($singleIntegrationDetailID, $integrationName, $integrationType, $integrationDetails, 'form');
762 }
763 }
764 }
765 //Integrations [end]
766 //workFlows [start] */
767 $workFlowExist = [];
768 if (!empty($workFlows)) {
769 $workFlowHandler = new WorkFlowHandler($formID, $user_details);
770 // foreach ($workFlows as $workFlowIndex => $workFlow) {
771 $workflows = is_string($workFlows) ? json_decode($workFlows) : $workFlows;
772
773 foreach ($workflows as $index => $workFlow) {
774 if (in_array($workFlow->action_type, ['always', 'onload'])) {
775 $workFlowExist['onload'] = true;
776 }
777 if ('oninput' === $workFlow->action_type || ('always' === $workFlow->action_type && 'cond' === $workFlow->action_behaviour)) {
778 $workFlowExist['oninput'] = true;
779 }
780 // $integartionIDForWorkflow = apply_filters('bitform_filter_integration_id', $workFlow, $formID, $index);
781 if (empty($workFlow->id)) {
782 $savedID = $workFlowHandler->saveworkFlow($workFlow, $integartionIDForWorkflow, $index);
783 if (is_wp_error($savedID) && 'result_empty' !== $savedID->get_error_code()) {
784 $newData['workflow'] = 2;
785 } else {
786 $newData['workflow'] = 1;
787 }
788 } else {
789 $newData = $workFlowHandler->updateworkFlow($workFlow->id, $workFlow, $integartionIDForWorkflow, $index, $newData);
790 }
791 }
792 }
793 $form_content = array_merge($form_content, ['workFlowExist' => $workFlowExist]);
794 //wrokFlows [end]
795 //reports [start] */
796 if (!empty($reports)) {
797 $reportsModel = new ReportsModel();
798 $fieldNames = [];
799 foreach ($fields as $key => $field) {
800 if (!empty($field->lbl)) {
801 // $name = preg_replace('/[\`\~\!\@\#\$\'\.\s\?\+\-\*\&\|\/\\\!]/', '_', $field->lbl);
802 $fieldNames["$key"] = $field->lbl;
803 }
804 }
805
806 $fieldNames['__user_id'] = __('User', 'bit-form');
807 $fieldNames['__user_ip'] = __('IP address', 'bit-form');
808 // $fieldNames['__user_location'] = __('');
809 $fieldNames['__referer'] = __('Refer URL', 'bit-form');
810 $fieldNames['__user_device'] = __('Device', 'bit-form');
811 $fieldNames['__created_at'] = __('Created Time', 'bit-form');
812 $fieldNames['__updated_at'] = __('Modified Time', 'bit-form');
813
814 $reportIsDefault = null;
815 if (isset($form_content['report_id'])) {
816 $validDateReport = $reportsModel->validateReportFields($reports, $fieldNames);
817 if (isset($reports->isDefault)) {
818 $reportIsDefault = $reports->isDefault;
819 } else {
820 $reportIsDefault = 0;
821 }
822
823 $reportsModel->update(
824 [
825 'type' => 'table',
826 'category' => 'form',
827 'context' => $formID,
828 'details' => is_string($validDateReport) ? $validDateReport : wp_json_encode($validDateReport),
829 'isDefault' => (int) $reportIsDefault,
830 'user_id' => $user_details['id'],
831 'user_ip' => $user_details['ip'],
832 'user_device' => $user_details['device'],
833 'updated_at' => $user_details['time'],
834 ],
835 [
836 'id' => $form_content['report_id'],
837 ]
838 );
839 }
840 }
841 //reports [end]
842 //form abandonment [start]
843 if (!empty($formSettings->formAbandonment)) {
844 $formAbandonment = $formSettings->formAbandonment;
845 // search for existing form abandonment in integration table
846 $abandonmentInteg = $integrationHandler->getAllIntegration('formAbandonment', 'formAbandonment');
847 if (!is_wp_error($abandonmentInteg) && !empty($abandonmentInteg)) {
848 $abandonmentInteg = $abandonmentInteg[0];
849 }
850 if (isset($abandonmentInteg->id)) {
851 $abandonmentIntegID = $abandonmentInteg->id;
852 $abandonmentIntegDetails = wp_json_encode($formAbandonment);
853 $integrationHandler->updateIntegration($abandonmentIntegID, 'formAbandonment', 'formAbandonment', $abandonmentIntegDetails, 'formAbandonment');
854 } else {
855 $abandonmentIntegDetails = wp_json_encode($formAbandonment);
856 $integrationHandler->saveIntegration('formAbandonment', 'formAbandonment', $abandonmentIntegDetails, 'formAbandonment');
857 }
858 }
859 //form abandonment [end]
860 $form_content = wp_json_encode($form_content);
861 $updateData = [
862 'form_name' => $form_name,
863 'form_content' => $form_content,
864 'user_id' => $user_details['id'],
865 'user_ip' => $user_details['ip'],
866 'builder_helper_state' => \wp_json_encode((object) $builder_helper_state),
867 'generated_script_page_ids' => \wp_json_encode((object) []),
868 'user_device' => $user_details['device'],
869 'updated_at' => $user_details['time'],
870 ];
871 if (isset($atomic_class_map)) {
872 $updateData['atomic_class_map'] = $atomic_class_map;
873 }
874 $formUpdateVersion = get_option('bitform_form_update_version');
875 if (!$formUpdateVersion) {
876 $formUpdateVersion = 1;
877 } else {
878 $formUpdateVersion = (int) $formUpdateVersion + 1;
879 }
880 update_option('bitform_form_update_version', $formUpdateVersion);
881 do_action('bitform_admin_form_changed');
882
883 $update_status = static::$formModel->update(
884 $updateData,
885 [
886 'id' => $formID,
887 ]
888 );
889 if (is_wp_error($update_status)) {
890 return $update_status;
891 } elseif (!$update_status) {
892 return new WP_Error('empty_form', __('Form update failed.', 'bit-form'));
893 } else {
894 if (isset($post->deletedFldKey) && is_array($post->deletedFldKey)) {
895 $this->setEmptyMetaValue($post->deletedFldKey);
896 unset($post->deletedFldKey);
897 }
898
899 $updated_data = $this->getAForm(['id' => $formID], null);
900
901 if (0 === $newData['settingConfiramation'] && 0 === $newData['mailTemplate'] && 0 === $newData['integation'] && 0 === $newData['pdfTemplate']) {
902 unset($updated_data['formSettings']);
903 }
904 if (0 === $newData['integation']) {
905 unset($updated_data['integrations']);
906 } elseif (2 === $newData['integation']) {
907 $errorIN = '';
908 $errorIN .= empty($errorIN) ? 'integation' : ', integation';
909 }
910 if (0 === $newData['mailTemplate']) {
911 unset($updated_data['mailTem']);
912 } elseif (2 === $newData['mailTemplate']) {
913 $errorIN .= empty($errorIN) ? 'mailTemplate' : ', mailTemplate';
914 }
915 if (0 === $newData['pdfTemplate']) {
916 unset($updated_data['pdfTem']);
917 } elseif (2 === $newData['pdfTemplate']) {
918 $errorIN .= empty($errorIN) ? 'pdfTemplate' : ', pdfTemplate';
919 }
920 if (0 === $newData['workflow']) {
921 unset($updated_data['workFlows']);
922 } elseif (2 === $newData['workflow']) {
923 $errorIN .= empty($errorIN) ? 'workflow' : ', workflow';
924 }
925 if (2 === $newData['reports']) {
926 $errorIN .= empty($errorIN) ? 'reports' : ', reports';
927 }
928 if (!empty($errorIN)) {
929 /* translators: %s: comma-separated list of areas where error occurred */
930 $updated_data['message'] = sprintf(__('Error Occured in saving %s', 'bit-form'), $errorIN);
931 return new WP_Error('Form update Error.', $updated_data);
932 }
933 if (null !== $reportIsDefault) {
934 $updated_data['form_content']['is_default'] = $reportIsDefault;
935 }
936 $updated_data['message'] = __('Form updated successfully.', 'bit-form');
937 return $updated_data;
938 }
939 }
940
941 /**
942 * Drop orphan fields (present in `fields` but in no layout) from form_content
943 * before persisting, and remove now-childless nestedLayout entries.
944 *
945 * Entry meta is NEVER touched here — only explicit user deletes clear meta
946 * (see setEmptyMetaValue). Fail closed: an unusable/partial layout, or a
947 * client that flagged a failed pre-save layout sync (->skipOrphanPrune),
948 * prunes nothing. Pruned keys are logged, never silently dropped.
949 *
950 * @param object|array $fields by ref; orphan keys removed
951 * @param object|null $nestedLayout by ref; stale container entries removed
952 * @param array|object $layout raw layout (single or multi-step)
953 * @param int|string|null $formID for logging ('new' when absent)
954 * @param object $post raw request; honors ->skipOrphanPrune
955 */
956 private function pruneOrphanFields(&$fields, &$nestedLayout, $layout, $formID, $post)
957 {
958 $formLabel = $formID ? $formID : 'new';
959 if (isset($post->skipOrphanPrune) && $post->skipOrphanPrune) {
960 Log::debug_log('Bit Form: orphan prune skipped (client reported failed layout sync). FormID=' . $formLabel);
961 return;
962 }
963 $orphanFldKeys = FormManager::computeOrphanFieldKeys($layout, $nestedLayout, $fields);
964 // null = unusable/partial layout (fail closed); [] = nothing to prune
965 if (!is_array($orphanFldKeys) || empty($orphanFldKeys)) {
966 return;
967 }
968 Log::debug_log('Bit Form: pruning orphan fields (absent from every layout). FormID=' . $formLabel . ' keys=' . implode(',', $orphanFldKeys));
969 foreach ($orphanFldKeys as $orphanKey) {
970 if (is_object($fields)) {
971 unset($fields->{$orphanKey});
972 } elseif (is_array($fields)) {
973 unset($fields[$orphanKey]);
974 }
975 }
976 // prune stale nestedLayout entries — containers that no longer exist in fields
977 if (is_object($nestedLayout)) {
978 foreach (array_keys(get_object_vars($nestedLayout)) as $nKey) {
979 $parentExists = is_object($fields) ? isset($fields->{$nKey}) : isset($fields[$nKey]);
980 if (!$parentExists) {
981 unset($nestedLayout->{$nKey});
982 }
983 }
984 }
985 }
986
987 public function setEmptyMetaValue($fieldkeys)
988 {
989 global $wpdb;
990 // Placeholders and arguments built dynamically from $fieldkeys; count matches at runtime.
991 $placeholders = implode(',', array_fill(0, \count($fieldkeys), '%s'));
992 $wpdb->query($wpdb->prepare(
993 "UPDATE `{$wpdb->prefix}bitforms_form_entrymeta` SET meta_value = %s WHERE meta_key IN ($placeholders)",
994 '',
995 ...$fieldkeys
996 ));
997 }
998
999 public function changeFormStatus($Request, $post)
1000 {
1001 if (isset($Request['status']) && $Request['id']) {
1002 $status = sanitize_text_field(wp_unslash($Request['status']));
1003 $id = absint(wp_unslash($Request['id']));
1004 } else {
1005 $status = wp_unslash($post->status);
1006 $id = wp_unslash($post->id);
1007 }
1008 $user_details = static::$ipTool->getUserDetail();
1009 // return $post->fields;
1010 $status = 'true' === $status || true === $status ? true : false;
1011 if (!is_bool($status) || is_null($id)) {
1012 // echo $status;
1013 return new WP_Error('status_change', __('Form status change failed.', 'bit-form'));
1014 }
1015 $update_status = static::$formModel->update(
1016 [
1017 'user_id' => $user_details['id'],
1018 'user_ip' => $user_details['ip'],
1019 'user_device' => $user_details['device'],
1020 'status' => $status ? 1 : 0,
1021 'updated_at' => $user_details['time'],
1022 ],
1023 [
1024 'id' => $id,
1025 ]
1026 );
1027 if (is_wp_error($update_status)) {
1028 return $update_status;
1029 } elseif (!$update_status) {
1030 return false;
1031 } else {
1032 return __('Form status changed successfully', 'bit-form');
1033 }
1034 }
1035
1036 public function changeBulkFormStatus($Request, $post)
1037 {
1038 if (isset($Request['status']) && $Request['formID']) {
1039 $status = sanitize_text_field(wp_unslash($Request['status']));
1040 $formID = array_map('absint', wp_unslash($Request['formID']));
1041 } else {
1042 $status = wp_unslash($post->status);
1043 $formID = wp_unslash($post->formID);
1044 }
1045 $user_details = static::$ipTool->getUserDetail();
1046 // return $post->fields;
1047 $status = 'true' === $status || true === $status ? true : false;
1048 if (!is_bool($status) || is_null($formID) || !is_array($formID)) {
1049 // echo $status;
1050 return new WP_Error('status_change', __('Form status change failed.', 'bit-form'));
1051 }
1052 $update_status = static::$formModel->bulkUpdate(
1053 [
1054 'user_id' => $user_details['id'],
1055 'user_ip' => $user_details['ip'],
1056 'user_device' => $user_details['device'],
1057 'status' => $status ? 1 : 0,
1058 'updated_at' => $user_details['time'],
1059 ],
1060 [
1061 'id' => $formID,
1062 ]
1063 );
1064 if (is_wp_error($update_status)) {
1065 return $update_status;
1066 } elseif (!$update_status) {
1067 return false;
1068 } else {
1069 return __('Form status changed successfully', 'bit-form');
1070 }
1071 }
1072
1073 public function getAllForm()
1074 {
1075 global $wpdb;
1076
1077 // Direct query: table name interpolation only (no user input). $wpdb->prepare() cannot parameterize table names.
1078 $allForms = $wpdb->get_results("SELECT forms.id,forms.entries as fm_entries,forms.form_name,forms.status,forms.views,forms.created_at,COUNT(entries.id) as entries
1079 FROM `{$wpdb->prefix}bitforms_form` as forms
1080 LEFT JOIN `{$wpdb->prefix}bitforms_form_entries` as entries ON forms.id = entries.form_id
1081 GROUP BY forms.id");
1082
1083 if (is_wp_error($allForms)) {
1084 return $allForms;
1085 } elseif (!$allForms) {
1086 return [];
1087 } else {
1088 return $allForms;
1089 }
1090 }
1091
1092 public function getAForm($Request, $post)
1093 {
1094 if (!empty($Request['id'])) {
1095 $formID = absint(wp_unslash($Request['id']));
1096 } else {
1097 $formID = wp_unslash($post->id);
1098 }
1099 // return $post->fields;
1100 if (is_null($formID)) {
1101 return new WP_Error('empty_form', __('Form id is empty.', 'bit-form'));
1102 }
1103 $formManager = new AdminFormManager($formID);
1104 if (!$formManager->isExist()) {
1105 return new WP_Error('not_exists', __('Form is not exists.', 'bit-form'));
1106 }
1107 $form_content = $formManager->getFormContent();
1108 $helper_states = $formManager->getFormHelperStates();
1109 if ($formManager->isExist()) {
1110 $form_content_arr = [
1111 'layout' => $form_content->layout,
1112 'nestedLayout' => !empty($form_content->nestedLayout) ? $form_content->nestedLayout : (object) [],
1113 'formInfo' => !empty($form_content->formInfo) ? $form_content->formInfo : (object) ['formName' => $formManager->getFormName()],
1114 'fields' => $form_content->fields,
1115 'form_name' => $formManager->getFormName(),
1116 'workFlowExist' => $form_content->workFlowExist,
1117 'report_id' => isset($form_content->report_id) ? $form_content->report_id : null
1118 ];
1119 $successMessageHandler
1120 = new SuccessMessageHandler($formID);
1121 $successMessages = $successMessageHandler->getAllMessage();
1122 if (!is_wp_error($successMessages)) {
1123 foreach ($successMessages as $sucessMessagekey => $sucessMessagevalue) {
1124 $sucessMessagevalue->message_config = json_decode($sucessMessagevalue->message_config);
1125 $allConfirmation['type']['successMsg'][$sucessMessagekey] =
1126 [
1127 'id' => $sucessMessagevalue->id,
1128 'title' => $sucessMessagevalue->message_title,
1129 'msg' => $sucessMessagevalue->message_content,
1130 'config' => $sucessMessagevalue->message_config,
1131 ];
1132 }
1133 }
1134 $emailTemplateHandler
1135 = new EmailTemplateHandler($formID);
1136 $emailTemplates = $emailTemplateHandler->getAllTemplate();
1137 if (!is_wp_error($emailTemplates)) {
1138 foreach ($emailTemplates as $emailTemplatekey => $emailTemplatevalue) {
1139 $mailTem[] =
1140 [
1141 'id' => $emailTemplatevalue->id,
1142 'title' => $emailTemplatevalue->title,
1143 'sub' => $emailTemplatevalue->sub,
1144 'body' => $emailTemplatevalue->body,
1145 'status' => isset($emailTemplatevalue->status) ? (int) $emailTemplatevalue->status : 1,
1146 'config' => !empty($emailTemplatevalue->config) ? json_decode($emailTemplatevalue->config) : (object) [],
1147 ];
1148 }
1149 }
1150 // get all pdf template
1151 if (class_exists('\BitCode\BitFormPro\Core\Messages\PdfTemplateHandler')) {
1152 $pdfTemplateHandler = new \BitCode\BitFormPro\Core\Messages\PdfTemplateHandler($formID);
1153 $pdfTemplates = $pdfTemplateHandler->getAll();
1154
1155 if (!is_wp_error($pdfTemplates)) {
1156 foreach ($pdfTemplates as $value) {
1157 $pdfTem[] =
1158 [
1159 'id' => $value->id,
1160 'title' => $value->title,
1161 'setting' => json_decode($value->setting),
1162 'pdf_config' => !empty($value->pdf_config) ? json_decode($value->pdf_config) : (object) [
1163 'status' => 1,
1164 'header' => '',
1165 'footer' => '',
1166 ],
1167 'body' => $value->body,
1168 ];
1169 }
1170 }
1171 }
1172
1173 $integrationHandler = new IntegrationHandler($formID);
1174 $formIntegrations = $integrationHandler->getAllIntegration('form');
1175 if (!is_wp_error($formIntegrations)) {
1176 foreach ($formIntegrations as $integrationkey => $integrationValue) {
1177 if ('redirectPage' === $integrationValue->integration_type || 'webHooks' === $integrationValue->integration_type) {
1178 $integrationData = [
1179 'id' => $integrationValue->id,
1180 'title' => $integrationValue->integration_name,
1181 'status' => isset($integrationValue->status) ? (int) $integrationValue->status : 1,
1182 ];
1183 if (!empty($integrationValue->integration_details)) {
1184 $integration_details = (array) json_decode($integrationValue->integration_details);
1185 $integrationData = array_merge($integration_details, $integrationData);
1186 } else {
1187 $integration_details = [
1188 'url' => '',
1189 ];
1190 $integrationData = array_merge($integrationData, $integration_details);
1191 }
1192 $allConfirmation['type'][$integrationValue->integration_type][]
1193 = $integrationData;
1194 } else {
1195 $integrationData = [
1196 'id' => $integrationValue->id,
1197 'name' => $integrationValue->integration_name,
1198 'type' => $integrationValue->integration_type,
1199 ];
1200 $integrations[] = array_merge(
1201 $integrationData,
1202 is_string($integrationValue->integration_details) ?
1203 (array) json_decode($integrationValue->integration_details) :
1204 $integrationValue->integration_details
1205 );
1206 }
1207 }
1208 }
1209
1210 // get form abandonment integration if exist
1211 $formAbandonmentInteg = $integrationHandler->getAllIntegration('formAbandonment', 'formAbandonment');
1212 if (!is_wp_error($formAbandonmentInteg) && !empty($formAbandonmentInteg)) {
1213 $formAbandonmentInteg = $formAbandonmentInteg[0];
1214 if (!empty($formAbandonmentInteg->integration_details)) {
1215 $formAbandonment = json_decode($formAbandonmentInteg->integration_details);
1216 } else {
1217 $formAbandonment = (object) [];
1218 }
1219 } else {
1220 $formAbandonment = (object) [];
1221 }
1222
1223 $settingsContent = [
1224 'formName' => $formManager->getFormName(),
1225 'theme' => isset($form_content->theme) ? $form_content->theme : 'default',
1226 'formPermissions' => isset($form_content->formPermissions) ? $form_content->formPermissions : (object) [],
1227 // 'submitBtn' => $form_content->buttons,
1228 ];
1229
1230 if (!empty($allConfirmation)) {
1231 $confirmation = [
1232 'confirmation' => $allConfirmation,
1233 ];
1234 } else {
1235 $confirmation = [
1236 'confirmation' => ['type' => []],
1237 ];
1238 }
1239 $settingsContent = array_merge($settingsContent, $confirmation);
1240 if (!empty($integrations)) {
1241 $settingsContent = array_merge(
1242 $settingsContent,
1243 [
1244 'integrations' => $integrations,
1245 ]
1246 );
1247 } else {
1248 $settingsContent = array_merge(
1249 $settingsContent,
1250 [
1251 'integrations' => []
1252 ]
1253 );
1254 }
1255
1256 if (!empty($mailTem)) {
1257 $settingsContent = array_merge(
1258 $settingsContent,
1259 [
1260 'mailTem' => $mailTem,
1261 ]
1262 );
1263 } else {
1264 $settingsContent = array_merge(
1265 $settingsContent,
1266 [
1267 'mailTem' => []
1268 ]
1269 );
1270 }
1271
1272 if (!empty($pdfTem)) {
1273 $settingsContent = array_merge(
1274 $settingsContent,
1275 [
1276 'pdfTem' => $pdfTem,
1277 ]
1278 );
1279 } else {
1280 $settingsContent = array_merge(
1281 $settingsContent,
1282 [
1283 'pdfTem' => [],
1284 ]
1285 );
1286 }
1287
1288 if (!empty($formAbandonment)) {
1289 $settingsContent = array_merge(
1290 $settingsContent,
1291 [
1292 'formAbandonment' => $formAbandonment,
1293 ]
1294 );
1295 } else {
1296 $settingsContent = array_merge(
1297 $settingsContent,
1298 [
1299 'formAbandonment' => (object) [],
1300 ]
1301 );
1302 }
1303 $formSettings = [
1304 'formSettings' => $settingsContent,
1305 ];
1306 $data = [
1307 'id' => $formID,
1308 'form_name' => $formManager->getFormName(),
1309 'form_content' => $form_content_arr,
1310 'breakpointSize' => $helper_states->breakpointSize,
1311 'style' => $helper_states->style,
1312 'themeVars' => $helper_states->themeVars,
1313 'themeColors' => $helper_states->themeColors,
1314 'builderSettings' => $helper_states->builderSettings,
1315 'customCode' => FrontEndScriptGenerator::getCustomCodes($formID),
1316 'additional' => empty($form_content->additional) ? [
1317 'enabled' => [
1318 'blocked_ip' => false,
1319 'restrict_form' => false,
1320 'onePerIp' => false,
1321 ],
1322 'settings' => [
1323 'restrict_form' => [
1324 'day' => [],
1325 'date' => [
1326 'from' => null,
1327 'to' => null,
1328 ],
1329 'time' => [
1330 'from' => null,
1331 'to' => null,
1332 ],
1333 ],
1334 'entry_limit' => null,
1335 'blocked_ip' => [],
1336 ],
1337 ] : $form_content->additional,
1338 'created_at' => $formManager->getFormMetaData()['created_at'],
1339 'views' => $formManager->getFormMetaData()['views'],
1340 'entries' => $formManager->getFormMetaData()['entries'],
1341 'status' => $formManager->getFormMetaData()['status'],
1342 ];
1343 $data = array_merge($data, $formSettings);
1344 $workFlowHandler = new WorkFlowHandler($formID);
1345 $workFlows = ['workFlows' => $workFlowHandler->getAllworkFlow()];
1346 $data = array_merge($data, $workFlows);
1347 $reportsModel = new ReportsModel();
1348 $returnedReportData = $reportsModel->get(
1349 [
1350 'id',
1351 'details',
1352 'isDefault',
1353 'type',
1354 ],
1355 [
1356 'category' => 'form',
1357 'context' => $formID,
1358 ]
1359 );
1360
1361 if (!is_wp_error($returnedReportData)) {
1362 $fieldNames = [];
1363 foreach ($formManager->getFieldLabel() as $key => $field) {
1364 $fieldNames[$field['key']] = isset($field->lbl) ? $field->lbl : '';
1365 }
1366 if ($formManager->isGCLIDEnabled()) {
1367 $fieldNames['GCLID'] = 'GCLID';
1368 }
1369 foreach ($returnedReportData as $reportKey => $reportData) {
1370 $reportDetails = $reportsModel->validateReportFields($reportData, $fieldNames);
1371 if (!empty($reportDetails) && is_string($reportDetails)) {
1372 $returnedReportData[$reportKey]->details = json_decode($reportDetails);
1373 } elseif (!empty($reportDetails)) {
1374 $returnedReportData[$reportKey]->details = $reportDetails;
1375 } else {
1376 $returnedReportData[$reportKey]->details = [];
1377 }
1378 if ('1' === (string) $reportData->isDefault) {
1379 $returnedReportData[$reportKey]->details->report_name = __('All Entries', 'bit-form');
1380 }
1381 }
1382 $reports = ['reports' => $returnedReportData];
1383 $data = array_merge($data, $reports);
1384 }
1385
1386 $formFields = $formManager->getFieldLabel();
1387 $data = array_merge($data, ['Labels' => $formFields]);
1388
1389 return $data;
1390 }
1391 }
1392
1393 public function getAFormV1($Request, $post)
1394 {
1395 if (!empty($Request['id'])) {
1396 $formID = absint(wp_unslash($Request['id']));
1397 } else {
1398 $formID = wp_unslash($post->id);
1399 }
1400 // return $post->fields;
1401 if (is_null($formID)) {
1402 return new WP_Error('empty_form', __('Form id is empty.', 'bit-form'));
1403 }
1404 $formManager = new AdminFormManager($formID);
1405 if (!$formManager->isExist()) {
1406 return new WP_Error('not_exists', __('Form is not exists.', 'bit-form'));
1407 }
1408 $form_content = $formManager->getFormContent();
1409 if ($formManager->isExist()) {
1410 $form_content_arr = [
1411 'layout' => $form_content->layout,
1412 'fields' => $form_content->fields,
1413 'form_name' => $formManager->getFormName(),
1414 'workFlowExist' => $form_content->workFlowExist,
1415 'report_id' => isset($form_content->report_id) ? $form_content->report_id : null
1416 ];
1417 $successMessageHandler
1418 = new SuccessMessageHandler($formID);
1419 $successMessages = $successMessageHandler->getAllMessage();
1420 if (!is_wp_error($successMessages)) {
1421 foreach ($successMessages as $sucessMessagekey => $sucessMessagevalue) {
1422 $allConfirmation['type']['successMsg'][$sucessMessagekey] =
1423 [
1424 'id' => $sucessMessagevalue->id,
1425 'title' => $sucessMessagevalue->message_title,
1426 'msg' => $sucessMessagevalue->message_content,
1427 'config' => !empty($sucessMessagevalue->message_config) ? json_decode($sucessMessagevalue->message_config) : (object) [],
1428 ];
1429 }
1430 }
1431 $emailTemplateHandler
1432 = new EmailTemplateHandler($formID);
1433 $emailTemplates = $emailTemplateHandler->getAllTemplate();
1434 if (!is_wp_error($emailTemplates)) {
1435 foreach ($emailTemplates as $emailTemplatekey => $emailTemplatevalue) {
1436 $mailTem[] =
1437 [
1438 'id' => $emailTemplatevalue->id,
1439 'title' => $emailTemplatevalue->title,
1440 'sub' => $emailTemplatevalue->sub,
1441 'body' => $emailTemplatevalue->body,
1442 'status' => isset($emailTemplatevalue->status) ? (int) $emailTemplatevalue->status : 1,
1443 'config' => !empty($emailTemplatevalue->config) ? json_decode($emailTemplatevalue->config) : (object) [],
1444 ];
1445 }
1446 }
1447 $integrationHandler = new IntegrationHandler($formID);
1448 $formIntegrations = $integrationHandler->getAllIntegration('form');
1449 if (!is_wp_error($formIntegrations)) {
1450 foreach ($formIntegrations as $integrationkey => $integrationValue) {
1451 if ('redirectPage' === $integrationValue->integration_type || 'webHooks' === $integrationValue->integration_type) {
1452 $integrationData = [
1453 'id' => $integrationValue->id,
1454 'title' => $integrationValue->integration_name,
1455 'status' => isset($integrationValue->status) ? (int) $integrationValue->status : 1,
1456 ];
1457 if (!empty($integrationValue->integration_details)) {
1458 // var_dump(json_decode($integrationValue->integration_details));
1459 $integration_details = (array) json_decode($integrationValue->integration_details);
1460 $integrationData = array_merge($integration_details, $integrationData);
1461 } else {
1462 $integration_details = [
1463 'url' => '',
1464 ];
1465 $integrationData = array_merge($integrationData, $integration_details);
1466 }
1467 $allConfirmation['type'][$integrationValue->integration_type][]
1468 = $integrationData;
1469 } else {
1470 $integrationData = [
1471 'id' => $integrationValue->id,
1472 'name' => $integrationValue->integration_name,
1473 'type' => $integrationValue->integration_type,
1474 ];
1475 $integrations[] = array_merge(
1476 $integrationData,
1477 is_string($integrationValue->integration_details) ?
1478 (array) json_decode($integrationValue->integration_details) :
1479 $integrationValue->integration_details
1480 );
1481 }
1482 }
1483 }
1484 $settingsContent = [
1485 'formName' => $formManager->getFormName(),
1486 'theme' => $form_content->theme,
1487 // 'submitBtn' => $form_content->buttons,
1488 ];
1489
1490 if (!empty($allConfirmation)) {
1491 $confirmation = [
1492 'confirmation' => $allConfirmation,
1493 ];
1494 } else {
1495 $confirmation = [
1496 'confirmation' => ['type' => []],
1497 ];
1498 }
1499 $settingsContent = array_merge($settingsContent, $confirmation);
1500 if (!empty($integrations)) {
1501 $settingsContent = array_merge(
1502 $settingsContent,
1503 [
1504 'integrations' => $integrations,
1505 ]
1506 );
1507 } else {
1508 $settingsContent = array_merge(
1509 $settingsContent,
1510 [
1511 'integrations' => []
1512 ]
1513 );
1514 }
1515 if (!empty($mailTem)) {
1516 $settingsContent = array_merge(
1517 $settingsContent,
1518 [
1519 'mailTem' => $mailTem,
1520 ]
1521 );
1522 } else {
1523 $settingsContent = array_merge(
1524 $settingsContent,
1525 [
1526 'mailTem' => []
1527 ]
1528 );
1529 }
1530 $formSettings = [
1531 'formSettings' => $settingsContent,
1532 ];
1533 $data = [
1534 'id' => $formID,
1535 'form_name' => $formManager->getFormName(),
1536 'form_content' => $form_content_arr,
1537 'additional' => empty($form_content->additional) ? [
1538 'enabled' => [
1539 'blocked_ip' => false,
1540 'restrict_form' => false,
1541 'onePerIp' => false,
1542 ],
1543 'settings' => [
1544 'restrict_form' => [
1545 'day' => [],
1546 'date' => [
1547 'from' => null,
1548 'to' => null,
1549 ],
1550 'time' => [
1551 'from' => null,
1552 'to' => null,
1553 ],
1554 ],
1555 'entry_limit' => null,
1556 'blocked_ip' => [],
1557 ],
1558 ] : $form_content->additional,
1559 'created_at' => $formManager->getFormMetaData()['created_at'],
1560 'views' => $formManager->getFormMetaData()['views'],
1561 'entries' => $formManager->getFormMetaData()['entries'],
1562 'status' => $formManager->getFormMetaData()['status'],
1563 ];
1564 $data = array_merge($data, $formSettings);
1565 $workFlowHandler = new WorkFlowHandler($formID);
1566 $workFlows = ['workFlows' => $workFlowHandler->getAllworkFlowV1()];
1567 $data = array_merge($data, $workFlows);
1568 $reportsModel = new ReportsModel();
1569 $returnedReportData = $reportsModel->get(
1570 [
1571 'id',
1572 'details',
1573 'isDefault',
1574 'type',
1575 ],
1576 [
1577 'category' => 'form',
1578 'context' => $formID,
1579 ]
1580 );
1581
1582 if (!is_wp_error($returnedReportData)) {
1583 $fieldNames = [];
1584 foreach ($formManager->getFieldLabel() as $key => $field) {
1585 $fieldNames[$field['key']] = isset($field->lbl) ? $field->lbl : '';
1586 }
1587 if ($formManager->isGCLIDEnabled()) {
1588 $fieldNames['GCLID'] = 'GCLID';
1589 }
1590 foreach ($returnedReportData as $reportKey => $reportData) {
1591 $reportDetails = $reportsModel->validateReportFields($reportData, $fieldNames);
1592 if (!empty($reportDetails) && is_string($reportDetails)) {
1593 $returnedReportData[$reportKey]->details = json_decode($reportDetails);
1594 } elseif (!empty($reportDetails)) {
1595 $returnedReportData[$reportKey]->details = $reportDetails;
1596 } else {
1597 $returnedReportData[$reportKey]->details = [];
1598 }
1599 if ('1' === (string) $reportData->isDefault) {
1600 $returnedReportData[$reportKey]->details->report_name = __('All Entries', 'bit-form');
1601 }
1602 }
1603 $reports = ['reports' => $returnedReportData];
1604 $data = array_merge($data, $reports);
1605 }
1606
1607 $formFields = $formManager->getFieldLabel();
1608 $data = array_merge($data, ['Labels' => $formFields]);
1609
1610 return $data;
1611 }
1612 }
1613
1614 public function deleteAForm($Request, $post)
1615 {
1616 if (!empty($Request['id'])) {
1617 $formID = absint(wp_unslash($Request['id']));
1618 } else {
1619 $formID = wp_unslash($post->id);
1620 }
1621 if (is_null($formID)) {
1622 return new WP_Error('empty_form', __('Form id is empty.', 'bit-form'));
1623 }
1624
1625 if (!filter_var($formID, FILTER_VALIDATE_INT)) {
1626 return new WP_Error('invalid_form', __('Form id is invalid.', 'bit-form'));
1627 }
1628
1629 $delete_status = static::$formModel->delete(
1630 [
1631 'id' => $formID,
1632 ]
1633 );
1634 do_action('bitform_admin_form_changed');
1635
1636 $successMessageModel = new SuccessMessageModel();
1637 $deleteMsgStatus = $successMessageModel->delete(['form_id' => $formID]);
1638
1639 $emailTemplateModel = new EmailTemplateModel();
1640 $deleteTemplateStatus = $emailTemplateModel->delete(['form_id' => $formID]);
1641
1642 if (class_exists('\BitCode\BitFormPro\Core\Database\PdfTemplateModel')) {
1643 $pdfTemplateModel = new \BitCode\BitFormPro\Core\Database\PdfTemplateModel();
1644 $deletePdfTemplateStatus = $pdfTemplateModel->delete(['form_id' => $formID]);
1645 }
1646
1647 $integrationModel = new IntegrationModel();
1648 $deleteIntegrationStatus = $integrationModel->delete(['form_id' => $formID]);
1649
1650 $workFlowModel = new WorkFlowModel();
1651 $deleteworkFlowStatus = $workFlowModel->delete(['form_id' => $formID]);
1652
1653 $reportsModel = new ReportsModel();
1654 $deleteReportStatus = $reportsModel->delete(['context' => $formID]);
1655
1656 $formEntryModel = new FormEntryModel();
1657 $returnedEntries = $formEntryModel->get('id', ['form_id' => $formID]);
1658 $entries = [];
1659
1660 // checked namespace exist
1661 if (class_exists('\BitCode\BitFormPro\Admin\BfTable\Table')) {
1662 \BitCode\BitFormPro\Admin\BfTable\Table::deleteTableByFormId($formID);
1663 }
1664
1665 $fileHandler = new FileHandler();
1666 if (file_exists(BITFORMS_UPLOAD_DIR . DIRECTORY_SEPARATOR . $formID)) {
1667 $fileHandler->rmrf(BITFORMS_UPLOAD_DIR . DIRECTORY_SEPARATOR . $formID);
1668 }
1669 if (file_exists(BITFORMS_UPLOAD_DIR . DIRECTORY_SEPARATOR . $formID)) {
1670 $fileHandler->rmrf(BITFORMS_UPLOAD_DIR . DIRECTORY_SEPARATOR . $formID);
1671 }
1672 $formStylePath = BITFORMS_CONTENT_DIR . DIRECTORY_SEPARATOR . 'form-styles';
1673
1674 $formCssPath = $formStylePath . DIRECTORY_SEPARATOR . 'bitform-' . $formID . '.css';
1675 FileHandler::deleteIsFileExists($formCssPath);
1676
1677 $layoutCssPath = $formStylePath . DIRECTORY_SEPARATOR . 'bitform-layout-' . $formID . '.css';
1678 FileHandler::deleteIsFileExists($layoutCssPath);
1679
1680 $customCssPath = $formStylePath . DIRECTORY_SEPARATOR . 'bitform-custom-' . $formID . '.css';
1681 FileHandler::deleteIsFileExists($customCssPath);
1682
1683 $customJSPath = BITFORMS_CONTENT_DIR . DIRECTORY_SEPARATOR . 'form-scripts' . DIRECTORY_SEPARATOR . 'bitform-custom-' . $formID . '.js';
1684 FileHandler::deleteIsFileExists($customJSPath);
1685
1686 $conversationCssPath = $formStylePath . DIRECTORY_SEPARATOR . 'bitform-conversational-' . $formID . '.css';
1687 FileHandler::deleteIsFileExists($conversationCssPath);
1688
1689 return is_wp_error($delete_status) ? $delete_status : __('Form deleted successfully.', 'bit-form');
1690 }
1691
1692 public function deleteBlukForm($Request, $post)
1693 {
1694 if (!empty($Request['formID'])) {
1695 $formID = array_map('absint', wp_unslash($Request['formID']));
1696 } else {
1697 $formID = wp_unslash($post->formID);
1698 }
1699
1700 if (is_null($formID) || !is_array($formID)) {
1701 return new WP_Error('empty_form', __('Form id is empty.', 'bit-form'));
1702 }
1703
1704 if (!Helpers::checkIsIntArr($formID)) {
1705 return new WP_Error('invalid_form', __('Form id is invalid', 'bit-form'));
1706 }
1707
1708 $cssPath = BITFORMS_CONTENT_DIR . DIRECTORY_SEPARATOR . 'form-styles' . DIRECTORY_SEPARATOR;
1709 foreach ($formID as $id) {
1710 $formCssPath = $cssPath . 'bitform-' . $id . '.css';
1711 FileHandler::deleteIsFileExists($formCssPath);
1712
1713 $layoutPath = $cssPath . 'bitform-layout-' . $id . '.css';
1714 FileHandler::deleteIsFileExists($layoutPath);
1715
1716 $bitformCustomPath = $cssPath . 'bitform-' . $id . '-formid' . '.css';
1717 FileHandler::deleteIsFileExists($bitformCustomPath);
1718 }
1719 $delete_status = static::$formModel->bulkDelete(
1720 [
1721 'id' => $formID,
1722 ]
1723 );
1724 do_action('bitform_admin_form_changed');
1725
1726 if (is_wp_error($delete_status)) {
1727 wp_send_json_error($delete_status->get_error_message(), 400);
1728 }
1729
1730 $successMessageModel
1731 = new SuccessMessageModel();
1732 $deleteMsgStatus = $successMessageModel->bulkDelete(['form_id' => $formID]);
1733
1734 $emailTemplateModel = new EmailTemplateModel();
1735 $deleteTemplateStatus = $emailTemplateModel->bulkDelete(['form_id' => $formID]);
1736
1737 if (class_exists('\BitCode\BitFormPro\Core\Database\PdfTemplateModel')) {
1738 $pdfTemplateModel = new \BitCode\BitFormPro\Core\Database\PdfTemplateModel();
1739 $deletePdfTemplateStatus = $pdfTemplateModel->bulkDelete(['form_id' => $formID]);
1740 }
1741
1742 $integrationModel = new IntegrationModel();
1743 $deleteIntegrationStatus = $integrationModel->bulkDelete(['form_id' => $formID]);
1744
1745 $workFlowModel = new WorkFlowModel();
1746 $deleteworkFlowStatus = $workFlowModel->bulkDelete(['form_id' => $formID]);
1747
1748 $reportsModel = new ReportsModel();
1749 $deleteReportStatus = $reportsModel->bulkDelete(['context' => $formID]);
1750
1751 $formEntryModel = new FormEntryModel();
1752 $returnedEntries = $formEntryModel->get('id', ['form_id' => $formID]);
1753
1754 if (class_exists('\BitCode\BitFormPro\Admin\BfTable\Table')) {
1755 \BitCode\BitFormPro\Admin\BfTable\Table::deleteTableByBulkFormId($formID);
1756 }
1757
1758 $entries = [];
1759 foreach ($returnedEntries as $entryKey => $entryInfo) {
1760 if (!empty($entryInfo->id)) {
1761 $entries[] = $entryInfo->id;
1762 }
1763 }
1764 global $wpdb;
1765 $prefix = $wpdb->prefix;
1766 if (count($entries) > 0) {
1767 $deleteEntriesStatus = $formEntryModel->bulkDelete(
1768 [
1769 "`{$prefix}bitforms_form_entries`.`id`" => $entries,
1770 "`{$prefix}bitforms_form_entries`.`form_id`" => $formID,
1771 ]
1772 );
1773 }
1774
1775 // delete entry log and details; table name interpolation only — $wpdb->prepare() parameterizes the form_id value.
1776 $wpdb->query($wpdb->prepare(
1777 "DELETE em, e FROM `{$prefix}bitforms_form_log_details` AS em JOIN `{$prefix}bitforms_form_entry_log` AS e ON em.log_id = e.id WHERE e.form_id = %d",
1778 $formID
1779 ));
1780
1781 $fileHandler = new FileHandler();
1782 foreach ($formID as $fId) {
1783 if (file_exists(BITFORMS_UPLOAD_DIR . DIRECTORY_SEPARATOR . $fId)) {
1784 $fileHandler->rmrf(BITFORMS_UPLOAD_DIR . DIRECTORY_SEPARATOR . $fId);
1785 }
1786 }
1787
1788 return is_wp_error($delete_status) ? $delete_status : __('Forms deleted successfully.', 'bit-form');
1789 }
1790
1791 public function genarateNewLayoutNField($layout, $fields, $oldId, $newId)
1792 {
1793 $newField = (object) [];
1794 foreach ($layout->lg as $ind => $itm) {
1795 $fld_tmp = $fields->{$layout->lg[$ind]->i};
1796 $layout->lg[$ind]->i = str_replace("bf$oldId-", "bf$newId-", $layout->lg[$ind]->i);
1797 $layout->md[$ind]->i = str_replace("bf$oldId-", "bf$newId-", $layout->md[$ind]->i);
1798 $layout->sm[$ind]->i = str_replace("bf$oldId-", "bf$newId-", $layout->sm[$ind]->i);
1799 $newField->{$layout->lg[$ind]->i} = $fld_tmp;
1800 }
1801 return ['layout' => $layout, 'fields' => $newField];
1802 }
1803
1804 public function duplicateAForm($Request, $post)
1805 {
1806 $oldFormId = intval($post->id);
1807 $newFormId = intval($post->newFormId);
1808 if ($oldFormId < 1) {
1809 return new WP_Error('empty_form', __('Form id is empty.', 'bit-form'));
1810 }
1811
1812 $formManager = new AdminFormManager($oldFormId);
1813 if (!$formManager->isExist()) {
1814 return new WP_Error('empty_form', __('Form does not exists.', 'bit-form'));
1815 }
1816
1817 $duplicatedForm = $this->getAForm($Request, $post);
1818 $duplicatedForm['form_name'] = 'Duplicate of ' . $duplicatedForm['form_name'];
1819 $formData = FormDuplicateHelper::createReplica($duplicatedForm, $oldFormId, $newFormId);
1820
1821 /* echo wp_json_encode($formData);
1822 \wp_die(); */
1823 $duplicateResponse = $this->createNewForm(null, $formData);
1824
1825 if (!is_wp_error($duplicateResponse) || (is_wp_error($duplicateResponse) && 'result_empty' === $duplicateResponse->get_error_code())) {
1826 // duplicate stylesheet
1827 $style_dir = BITFORMS_CONTENT_DIR . DIRECTORY_SEPARATOR . 'form-styles' . DIRECTORY_SEPARATOR;
1828 // layout style copy
1829 $styleStr = FileHandler::readFile($style_dir . 'bitform-layout-' . $oldFormId . '.css');
1830 $newStyle = str_replace(".bf$oldFormId-", ".bf$newFormId-", $styleStr);
1831 FileHandler::writeFile($style_dir . "bitform-layout-$newFormId.css", $newStyle);
1832 // style copy
1833 $styleStr = FileHandler::readFile($style_dir . 'bitform-' . $oldFormId . '.css');
1834 $newStyle = str_replace("-$oldFormId", "-$newFormId", $styleStr);
1835 FileHandler::writeFile($style_dir . "bitform-$newFormId.css", $newStyle);
1836 $duplicatedForm = $this->getAForm(null, (object) ['id' => $newFormId]);
1837 $duplicatedForm['message'] = __('Form duplicated successfully', 'bit-form');
1838 return $duplicatedForm;
1839 }
1840 return $duplicateResponse;
1841 }
1842
1843 public function importAForm($post)
1844 {
1845 $oldFormId = !empty($post->formDetail->form_id) ? $post->formDetail->form_id : null;
1846 $newFormId = intval($post->newFormId);
1847 if (!$oldFormId || empty($post->formDetail->fields) || empty($post->formDetail->layout)) {
1848 return new WP_Error('invalid_form', __('Please import a valid json.', 'bit-form'));
1849 }
1850 $importtedForm = (array) $post->formDetail;
1851 $importtedForm['form_content']['fields'] = $importtedForm['fields'];
1852 $importtedForm['form_content']['layout'] = $importtedForm['layout'];
1853 $importtedForm['form_content']['nestedLayout'] = $importtedForm['nestedLayouts'];
1854 $importtedForm['form_content']['formInfo'] = $importtedForm['formInfo'];
1855 unset($importtedForm['fields'], $importtedForm['layout'], $importtedForm['nestedLayout'], $importtedForm['formInfo']);
1856 $formData = FormDuplicateHelper::createReplica((array) $importtedForm, $oldFormId, $newFormId);
1857
1858 if (!empty($importtedForm['rowHeight'])) {
1859 $formData->rowHeight = $importtedForm['rowHeight'];
1860 }
1861
1862 if (!empty($importtedForm['formStyle'])) {
1863 $formData->formStyle = str_replace("-$oldFormId", "-$newFormId", $importtedForm['formStyle']);
1864 $formData->layoutChanged = '-';
1865 }
1866 $importResponse = $this->createNewForm(null, $formData);
1867
1868 $customCode = [];
1869 // add custom js
1870 if (!empty($formData->customCode->customJs)) {
1871 $customJsPath = 'form-scripts';
1872 $fileName = 'bitform-custom-' . $newFormId . '.js';
1873 $customCode['JavaScript'] = $formData->customCode->customJs;
1874 Helpers::saveFile($customJsPath, $fileName, $formData->customCode->customJs, 'w');
1875 }
1876 // add custom css
1877 if (!empty($formData->customCode->customCss)) {
1878 $customCssPath = 'form-styles';
1879 $fileName = 'bitform-custom-' . $newFormId . '.css';
1880 $customCode['CSS'] = $formData->customCode->customCss;
1881 Helpers::saveFile($customCssPath, $fileName, $formData->customCode->customCss, 'w');
1882 }
1883 if (!is_wp_error($importResponse)) {
1884 $importResponse['customCode'] = $customCode;
1885 }
1886 if (!is_wp_error($importResponse) || (is_wp_error($importResponse) && 'result_empty' === $importResponse->get_error_code())) {
1887 $responseData = $this->getAForm(null, (object) ['id' => $newFormId]);
1888 $responseData['customCode'] = $customCode;
1889 $responseData['message'] = __('Form imported successfully.', 'bit-form');
1890 return $responseData;
1891 }
1892 return $importResponse;
1893 }
1894
1895 // public function exportAForm($Request) {
1896 // $oldFormId = intval($Request['id']);
1897 // if ($oldFormId < 1) {
1898 // return new WP_Error('empty_form', __('Form id is empty.', 'bit-form'));
1899 // }
1900 // $formManager = new AdminFormManager($oldFormId);
1901 // if (!$formManager->isExist()) {
1902 // return new WP_Error('empty_form', __('Form does not exists.', 'bit-form'));
1903 // }
1904
1905 // $newFormId = $oldFormId;
1906 // $duplicatedForm = $this->getAForm($Request, (object)['id' => $oldFormId]);
1907 // $formData = FormDuplicateHelper::createReplica($duplicatedForm, $oldFormId, $newFormId);
1908
1909 // $style_dir = BITFORMS_CONTENT_DIR . DIRECTORY_SEPARATOR . 'form-styles' . DIRECTORY_SEPARATOR;
1910 // $mainFormStyle = fopen($style_dir . 'bitform-' . $oldFormId . '.css', 'r');
1911 // $styleStr = fread($mainFormStyle, filesize($style_dir . 'bitform-' . $oldFormId . '.css'));
1912
1913 // $formData->formStyle = str_replace("-$oldFormId", "-$newFormId", $styleStr);
1914 // $formData->layoutChanged = '-';
1915 // $formData->rowHeight = FormDuplicateHelper::calcRowHeight($styleStr, $oldFormId);
1916
1917 // $formJson = wp_json_encode($formData);
1918 // header('Content-Type: application/force-download');
1919 // header('Content-Type: application/octet-stream');
1920 // header('Content-Type: application/download');
1921 // header('Content-Disposition: attachment; filename="bitform_export_' . $oldFormId . '.json"');
1922 // header('Content-Description: File Transfer');
1923 // header('Expires: 0');
1924 // header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
1925 // header('Pragma: public');
1926 // header('Content-Length: ' . strlen($formJson));
1927 // header('Content-Transfer-Encoding: binary ');
1928 // flush();
1929 // echo $formJson;
1930 // die();
1931 // }
1932
1933 public function exportAForm($Request, $post)
1934 {
1935 $oldFormId = intval($post->id);
1936 if ($oldFormId < 1) {
1937 return new WP_Error('empty_form', __('Form id is empty.', 'bit-form'));
1938 }
1939 $formManager = new AdminFormManager($oldFormId);
1940 if (!$formManager->isExist()) {
1941 return new WP_Error('empty_form', __('Form does not exists.', 'bit-form'));
1942 }
1943
1944 $newFormId = $oldFormId;
1945 $duplicatedForm = $this->getAForm($Request, (object) ['id' => $oldFormId]);
1946 $formData = FormDuplicateHelper::createReplica($duplicatedForm, $oldFormId, $newFormId);
1947 // for custom css
1948 $customCssPath = 'form-styles/bitform-custom-' . $newFormId . '.css';
1949 $cssPath = Helpers::generatePathDirOrFile($customCssPath);
1950 $customCssContain = Helpers::fileRead($cssPath);
1951 $formData->customCode = [];
1952 if ('' !== $customCssContain) {
1953 $formData->customCode['customCss'] = $customCssContain;
1954 }
1955 // for custom js
1956 $customJsPath = 'form-scripts/bitform-custom-' . $newFormId . '.js';
1957 $jsPath = Helpers::generatePathDirOrFile($customJsPath);
1958 $customJsContain = Helpers::fileRead($jsPath);
1959 if ('' !== $customJsContain) {
1960 $formData->customCode['customJs'] = $customJsContain;
1961 }
1962 return $formData;
1963 }
1964
1965 public function getFormEntryLabelAndCount($Request, $post)
1966 {
1967 if (!empty($Request['id'])) {
1968 $id = absint(wp_unslash($Request['id']));
1969 } else {
1970 $id = wp_unslash($post->id);
1971 }
1972 if (is_null($id)) {
1973 return new WP_Error('empty_form', __('Form id is empty.', 'bit-form'));
1974 }
1975 $formManager = new AdminFormManager($id);
1976 if (!$formManager->isExist()) {
1977 return new WP_Error('empty_form', __('Form does not exists.', 'bit-form'));
1978 }
1979 $formFields = $formManager->getFieldLabel();
1980 $formEntry = new FormEntryModel();
1981 $count = $formEntry->count(
1982 [
1983 'form_id' => $id,
1984 ]
1985 );
1986 $reportsModel = new ReportsModel();
1987 $returnedReportData = $reportsModel->get(
1988 [
1989 'id',
1990 'details',
1991 'isDefault',
1992 'type',
1993 ],
1994 [
1995 'category' => 'form',
1996 'context' => $id,
1997 ]
1998 );
1999 $labels = [];
2000 if (!is_wp_error($returnedReportData)) {
2001 $fieldNames = [];
2002 foreach ($formFields as $field) {
2003 $fieldNames[$field['key']] = $field['name'];
2004 $labels[$field['key']] = $field;
2005 }
2006 foreach ($returnedReportData as $reportKey => $reportData) {
2007 $reportDetails = $reportsModel->validateReportFields($reportData, $fieldNames);
2008 if (!empty($reportDetails) && is_string($reportDetails)) {
2009 $returnedReportData[$reportKey]->details = json_decode($reportDetails);
2010 } elseif (!empty($reportDetails)) {
2011 $returnedReportData[$reportKey]->details = $reportDetails;
2012 }
2013 }
2014 $response['reports'] = empty($returnedReportData) ? [] : $returnedReportData;
2015 }
2016
2017 $response['count'] = intval($count[0]->count);
2018 $response['Labels'] = $formFields;
2019 $response['fieldDetails'] = $labels;
2020 return $response;
2021 }
2022
2023 public function getFormEntry($Request, $post)
2024 {
2025 if (!empty($Request['id'])) {
2026 $id = absint(wp_unslash($Request['id']));
2027 $offset = isset($Request['offset']) ?
2028 wp_unslash($Request['offset']) : 0;
2029 $pageSize = isset($Request['pageSize']) ?
2030 wp_unslash($Request['pageSize']) : 10;
2031 $queryCondition = isset($Request['queryCondition']) ? wp_unslash($Request['queryCondition']) : ['form_id' => $id];
2032 } else {
2033 $id = wp_unslash($post->id);
2034 $conditions = isset($post->conditions) ? wp_unslash($post->conditions) : [];
2035 $dateBetweenFilter = isset($post->entriesFilterByDate) ? wp_unslash($post->entriesFilterByDate) : [];
2036 $offset = isset($post->offset) ? wp_unslash($post->offset) : 0;
2037 $sortBy = isset($post->sortBy) ? wp_unslash($post->sortBy) : null;
2038 $filters = isset($post->filters) ? wp_unslash($post->filters) : null;
2039 $globalFilter = isset($post->globalFilter) ? wp_unslash($post->globalFilter) : null;
2040 $pageSize = isset($post->pageSize) ?
2041 wp_unslash($post->pageSize) : 10;
2042 $queryCondition = isset($post->queryCondition) ? wp_unslash($post->queryCondition) : ['form_id' => $id];
2043 }
2044 if (is_null($id)) {
2045 return new WP_Error('empty_form', __('Form id is empty.', 'bit-form'));
2046 }
2047 $formManager = new AdminFormManager($id);
2048 if (!$formManager->isExist()) {
2049 return new WP_Error('empty_form', __('Form does not exists', 'bit-form'));
2050 }
2051 $formEntry = new FormEntryModel();
2052 $entries = $formEntry->get(
2053 'id',
2054 $queryCondition,
2055 null,
2056 null,
2057 'created_at',
2058 'DESC'
2059 );
2060 if (is_wp_error($entries)) {
2061 if ('result_empty' === $entries->get_error_code()) {
2062 return [
2063 'count' => 0,
2064 'entries' => [],
2065 ];
2066 }
2067 return $entries;
2068 }
2069 $filter['field'] = $filters;
2070 $filter['global'] = $globalFilter;
2071
2072 $formFields = $formManager->getFieldLabel(true);
2073 $fieldDetails = $formManager->getFields();
2074
2075 $entryMeta = new FormEntryMetaModel();
2076 $formEntries = $entryMeta->getEntryMeta($formFields, $entries, $pageSize, $offset, $filter, $sortBy, $conditions, $dateBetweenFilter);
2077 $customFieldHandler = new CustomFieldHandler();
2078 $formEntries = $customFieldHandler->updatedEntries($formEntries, $fieldDetails);
2079 return $formEntries;
2080 }
2081
2082 public function getSingleEntry($formId, $entryId)
2083 {
2084 $formManager = new AdminFormManager($formId);
2085 if (!$formManager->isExist()) {
2086 return new WP_Error('empty_form', __('Form does not exists', 'bit-form'));
2087 }
2088
2089 $formFields = $formManager->getFieldLabel(true);
2090 $fieldDetails = $formManager->getFields();
2091 $entryMeta = new FormEntryMetaModel();
2092 // $formEntry = new FormEntryModel();
2093
2094 $entries = $entryMeta->getSingleEntryMeta($formFields, $entryId);
2095
2096 if (!is_wp_error($entries)) {
2097 return $entries[0];
2098 }
2099 return new WP_Error('entry_not_fonud', __('Entry Not Found!', 'bit-form'));
2100
2101 // $customFieldHandler = new CustomFieldHandler();
2102 // $formEntries = $customFieldHandler->updatedEntries($formEntries, $fieldDetails);
2103 // return $formEntries;
2104 }
2105
2106 public function getEntriesForReport($Request, $post)
2107 {
2108 if (!empty($Request['id'])) {
2109 $id = absint(wp_unslash($Request['id']));
2110 $offset = isset($Request['offset']) ?
2111 wp_unslash($Request['offset']) : null;
2112 $pageSize = isset($Request['pageSize']) ?
2113 wp_unslash($Request['pageSize']) : null;
2114 } else {
2115 $id = wp_unslash($post->id);
2116 $conditions = isset($post->conditions) ? wp_unslash($post->conditions) : [];
2117 $dateBetweenFilter = isset($post->entriesFilterByDate) ? wp_unslash($post->entriesFilterByDate) : [];
2118 $offset = isset($post->offset) ? wp_unslash($post->offset) : null;
2119 $sortBy = isset($post->sortBy) ? wp_unslash($post->sortBy) : null;
2120 $filters = isset($post->filters) ? wp_unslash($post->filters) : null;
2121 $globalFilter = isset($post->globalFilter) ? wp_unslash($post->globalFilter) : null;
2122 $pageSize = isset($post->pageSize) ?
2123 wp_unslash($post->pageSize) : null;
2124 }
2125 if (is_null($id)) {
2126 return new WP_Error('empty_form', __('Form id is empty.', 'bit-form'));
2127 }
2128 $formManager = new AdminFormManager($id);
2129 if (!$formManager->isExist()) {
2130 return new WP_Error('empty_form', __('Form does not exists', 'bit-form'));
2131 }
2132
2133 $formEntry = new FormEntryModel();
2134 $entries = $formEntry->get(
2135 'id',
2136 [
2137 'form_id' => $id,
2138 ],
2139 null,
2140 null,
2141 'created_at',
2142 'DESC'
2143 );
2144 if (is_wp_error($entries)) {
2145 if ('result_empty' === $entries->get_error_code()) {
2146 return [
2147 'count' => 0,
2148 'entries' => [],
2149 ];
2150 }
2151 return $entries;
2152 }
2153 $filter['field'] = $filters;
2154 $filter['global'] = $globalFilter;
2155
2156 $formFields = $formManager->getFieldLabel(true);
2157 $fieldDetails = $formManager->getFields();
2158
2159 $entryMeta = new FormEntryMetaModel();
2160 $formEntries = $entryMeta->getEntryMeta($formFields, $entries, $pageSize, $offset, $filter, $sortBy, $conditions, $dateBetweenFilter);
2161 $customFieldHandler = new CustomFieldHandler();
2162 $formEntries = $customFieldHandler->updatedEntries($formEntries, $fieldDetails);
2163 $formEntries['entries'] = Helpers::filterNullEntries($formEntries['entries']);
2164 return $formEntries;
2165 }
2166
2167 public function getExportEntry($post)
2168 {
2169 $formId = wp_unslash($post->formId);
2170 $fileFormate = isset($post->fileFormate) ? wp_unslash($post->fileFormate) : null;
2171 $limit = isset($post->limit) ? wp_unslash($post->limit) : null;
2172 $entryCondition = isset($post->filter) ? wp_unslash($post->filter) : null;
2173 $sortBy = isset($post->sort) ? wp_unslash($post->sort) : 'ASC';
2174 $sortByField = isset($post->sortField) ? wp_unslash($post->sortField) : 'bitforms_form_entry_id';
2175 $formFields = json_decode($post->selectedField);
2176 if (is_null($formId)) {
2177 return new WP_Error('empty_form', __('Form id is empty.', 'bit-form'));
2178 }
2179 $formManager = new AdminFormManager($formId);
2180 $fieldLabels = $formManager->getFieldLabel(true);
2181 if (!$formManager->isExist()) {
2182 return new WP_Error('empty_form', __('Form does not exists', 'bit-form'));
2183 }
2184
2185 $formEntry = new FormEntryModel();
2186 $entries = $formEntry->get(
2187 'id',
2188 [
2189 'form_id' => $formId,
2190 ],
2191 null,
2192 null,
2193 'created_at',
2194 'DESC'
2195 );
2196 if (is_wp_error($entries)) {
2197 if ('result_empty' === $entries->get_error_code()) {
2198 return [
2199 'count' => 0,
2200 'entries' => [],
2201 ];
2202 }
2203 return $entries;
2204 }
2205 $entryMeta = new FormEntryMetaModel();
2206 $filter = [];
2207 $formEntries = $entryMeta->getExportEntry($formFields, $entries, $formId, $fieldLabels, $limit, $sortBy, $sortByField, $offset, $entryCondition);
2208 return $formEntries;
2209 }
2210
2211 public function deleteBlukFormEntries($Request, $post)
2212 {
2213 if (!empty($Request['formID'])) {
2214 $formID = absint(wp_unslash($Request['formID']));
2215 $entries = array_map('absint', wp_unslash($Request['entries']));
2216 } else {
2217 $formID = wp_unslash($post->formID);
2218 $entries = wp_unslash($post->entries);
2219 }
2220 if (is_null($formID) || !is_array($entries) || 0 === count($entries)) {
2221 return new WP_Error('empty_form', __('Invalid Form ID or Entries ID.', 'bit-form'));
2222 }
2223
2224 if (!filter_var($formID, FILTER_VALIDATE_INT)) {
2225 return new WP_Error('invalid_form', __('Form id is invalid.', 'bit-form'));
2226 }
2227
2228 if (!Helpers::checkIsIntArr($entries)) {
2229 return new WP_Error('invalid_entries', __('Entries id is invalid', 'bit-form'));
2230 }
2231
2232 $formManager = new AdminFormManager($formID);
2233 if (!$formManager->isExist()) {
2234 return new WP_Error('empty_form', __('Form does not exist.', 'bit-form'));
2235 }
2236 $workFlowRunHelper = new WorkFlow($formID);
2237
2238 $workFlowreturnedOnDelete = $workFlowRunHelper->executeOnDelete(
2239 $formManager,
2240 $formID,
2241 $entries
2242 );
2243
2244 if (isset($workFlowreturnedOnDelete['entries'])) {
2245 if (0 === count($workFlowreturnedOnDelete['entries'])) {
2246 return ['message' => __('Entry Deletetion prevented by workflow', 'bit-form')];
2247 } elseif (count($workFlowreturnedOnDelete['entries']) === count($entries)) {
2248 $message = __('Entry Deleted successfully', 'bit-form');
2249 } else {
2250 $result['prevented'] = array_diff($entries, $workFlowreturnedOnDelete['entries']);
2251 $entries = $workFlowreturnedOnDelete['entries'];
2252 $message = __('Entry Deleted successfully, Some prevented by workflow', 'bit-form');
2253 }
2254 } else {
2255 $message = __('Entry Deleted successfully', 'bit-form');
2256 }
2257 global $wpdb;
2258 $prefix = $wpdb->prefix;
2259 $formEntryModel = new FormEntryModel();
2260 $delete_status = $formEntryModel->bulkDelete(
2261 [
2262 "`{$prefix}bitforms_form_entries`.`id`" => $entries,
2263 "`{$prefix}bitforms_form_entries`.`form_id`" => $formID,
2264 ]
2265 );
2266 if (file_exists(BITFORMS_UPLOAD_DIR . DIRECTORY_SEPARATOR . $formID)) {
2267 $fileHandler = new FileHandler();
2268 foreach ($entries as $enrtyKey => $entryID) {
2269 $fileEntries = $fileHandler->getEntriesFileUploadDir($formID, $entryID);
2270 if (file_exists($fileEntries)) {
2271 $fileHandler->rmrf($fileEntries);
2272 }
2273 }
2274 }
2275 $count = $formEntryModel->count(
2276 [
2277 'form_id' => $formID,
2278 ]
2279 );
2280 $formManager->resetSubmissionCount(intval($count[0]->count));
2281 if (is_wp_error($delete_status)) {
2282 return new WP_Error('entry_not_exists', __('Form entry deletion failed.', 'bit-form'));
2283 }
2284 $result['message'] = $message;
2285 return $result;
2286 }
2287
2288 public function duplicateFormEntry($Request, $post)
2289 {
2290 if (!empty($Request['formID'])) {
2291 $formID = absint(wp_unslash($Request['formID']));
2292 $entries = array_map('absint', wp_unslash($Request['entries']));
2293 } else {
2294 $formID = wp_unslash($post->formID);
2295 $entries = wp_unslash($post->entries);
2296 }
2297 if (is_null($formID) || !is_array($entries) || empty($entries)) {
2298 return new WP_Error('empty_form', __('Form id or entries id is invalid', 'bit-form'));
2299 }
2300
2301 if (!filter_var($formID, FILTER_VALIDATE_INT)) {
2302 return new WP_Error('invalid_form', __('Form id is invalid', 'bit-form'));
2303 }
2304
2305 if (!Helpers::checkIsIntArr($entries)) {
2306 return new WP_Error('invalid_entries', __('Entries id is invalid', 'bit-form'));
2307 }
2308
2309 $formManager = new AdminFormManager($formID);
2310 if (!$formManager->isExist()) {
2311 return new WP_Error('empty_form', __('Form does not exist', 'bit-form'));
2312 }
2313 $formEntryModel = new FormEntryModel();
2314 $entryMeta = new FormEntryMetaModel();
2315 $user_details = static::$ipTool->getUserDetail();
2316 $total_entries = count($entries);
2317 $duplicate_count = 0;
2318 $test = '';
2319 $fileHandler = new FileHandler();
2320 $result = [];
2321 foreach ($entries as $entryIndex => $entryID) {
2322 $duplicatedEntryId = $formEntryModel->insert(
2323 [
2324 'form_id' => $formID,
2325 'user_id' => $user_details['id'],
2326 'user_ip' => $user_details['ip'],
2327 'user_device' => $user_details['device'],
2328 'referer' => 'duplicate of #' . $entryID,
2329 'status' => 1,
2330 'created_at' => $user_details['time'],
2331 ]
2332 );
2333 if ($duplicatedEntryId) {
2334 $duplicate_status = $entryMeta->duplicateEntryMeta(
2335 [
2336 'duplicateID' => $duplicatedEntryId,
2337 'entryID' => $entryID,
2338 ]
2339 );
2340 if ($duplicate_status) {
2341 $result['details'][$entryID] = $duplicatedEntryId;
2342 $duplicate_count = $duplicate_count + 1;
2343 if (file_exists(FileHandler::getEntriesFileUploadDir($formID, $entryID))) {
2344 $fileHandler->cpyr(
2345 FileHandler::getEntriesFileUploadDir($formID, $entryID),
2346 FileHandler::getEntriesFileUploadDir($formID, $duplicatedEntryId)
2347 );
2348 }
2349 }
2350 }
2351 }
2352
2353 $count = $formEntryModel->count(
2354 [
2355 'form_id' => $formID,
2356 ]
2357 );
2358 $formManager->resetSubmissionCount(intval($count[0]->count));
2359 $result['message'] = 1 === count($entries) ? __('Entry Duplicated successfully', 'bit-form') : __('Entries Duplicated successfully', 'bit-form');
2360 return ($total_entries === $duplicate_count) ? $result : false;
2361 }
2362
2363 public function editFormEntry($Request, $post)
2364 {
2365 if (!empty($Request['formID'])) {
2366 $formID = absint(wp_unslash($Request['formID']));
2367 $entryID = absint(wp_unslash($Request['entryID']));
2368 } else {
2369 $formID = wp_unslash($post->formID);
2370 $entryID = wp_unslash($post->entryID);
2371 }
2372 if (is_null($formID) || is_null($entryID)) {
2373 return new WP_Error('empty_form', __('Form id or entries id is invalid', 'bit-form'));
2374 }
2375
2376 $formManager = new AdminFormManager($formID);
2377 if (!$formManager->isExist()) {
2378 return new WP_Error('empty_form', __('Form does not exist', 'bit-form'));
2379 }
2380 $formEntryModel = new FormEntryModel();
2381 $entryMeta = new FormEntryMetaModel();
2382
2383 $formEntry = $formEntryModel->get(
2384 '*',
2385 [
2386 'form_id' => $formID,
2387 'id' => $entryID,
2388 ]
2389 );
2390
2391 if (!$formEntry) {
2392 return new WP_Error('empty_form', __('Form entries does not exist.', 'bit-form'));
2393 }
2394 $formEntryMeta = $entryMeta->get(
2395 [
2396 'meta_key',
2397 'meta_value',
2398 ],
2399 [
2400 'bitforms_form_entry_id' => $entryID,
2401 ]
2402 );
2403 $entries = [];
2404 foreach ($formEntryMeta as $key => $value) {
2405 $entries[$value->meta_key] = $value->meta_value;
2406 }
2407 $formContent = $formManager->getFormContent();
2408 $fieldsKey = $formManager->getFieldsKey();
2409 $form_fields = $formContent->fields;
2410 $layout = $formContent->layout;
2411 foreach ($form_fields as $key => $value) {
2412 // $field_name = preg_replace('/[\`\~\!\@\#\$\'\.\s\?\+\-\*\&\|\/\\!]/', '_', $value->lbl);
2413 if (isset($entries[$key])) {
2414 $form_fields->{$key}->val = $entries[$key];
2415 $form_fields->{$key}->name = $key;
2416 }
2417 }
2418 $workFlowRunHelper = new WorkFlow($formID);
2419 $workFlowreturnedOnLoad = $workFlowRunHelper->executeOnLoad(
2420 'edit',
2421 $form_fields
2422 );
2423 $workFlowreturnedOnUserInput = $workFlowRunHelper->executeOnUserInput(
2424 'edit',
2425 $form_fields
2426 );
2427 if (!empty($workFlowreturnedOnLoad['fields'])) {
2428 $form_fields = $workFlowreturnedOnLoad['fields'];
2429 }
2430 $formData = [
2431 'layout' => $layout,
2432 'fields' => $form_fields,
2433 'conditional' => !empty($workFlowreturnedOnUserInput['conditional']) ? $workFlowreturnedOnUserInput['conditional'] : false,
2434 'fieldToCheck' => !empty($workFlowreturnedOnUserInput['fieldToCheck']) ? $workFlowreturnedOnUserInput['fieldToCheck'] : false,
2435 'fieldToChange' => !empty($workFlowreturnedOnUserInput['fieldToChange']) ? $workFlowreturnedOnUserInput['fieldToChange'] : false,
2436 'fieldsKey' => $fieldsKey,
2437 ];
2438 return $formData;
2439 }
2440
2441 public function updateFormEntry($Request, $post)
2442 {
2443 if (isset($Request['formID'], $Request['entryID'])) {
2444 $formID = absint(wp_unslash($Request['formID']));
2445 $entryID = absint(wp_unslash($Request['entryID']));
2446 unset($Request['action'], $Request['formID'], $Request['entryID']);
2447 }
2448 $formManager = new AdminFormManager($formID);
2449 $formManager->fieldNameReplaceOfPost();
2450 // Called from AdminAjax handler; nonce already verified at AJAX entry before dispatch.
2451 $updatedValue = is_array($post) ? $post : wp_unslash($_POST);
2452
2453 if (is_null($updatedValue) || !is_array($updatedValue)) {
2454 return new WP_Error('empty_data', __('Failed to update, Data is empty.', 'bit-form'));
2455 }
2456
2457 if (is_null($formID) || is_null($entryID)) {
2458 return new WP_Error('empty_data', __('Invalid Form ID or entries ID.', 'bit-form'));
2459 }
2460
2461 if (!$formManager->isExist()) {
2462 return new WP_Error('empty_data', __('Form does not exist.', 'bit-form'));
2463 }
2464 return $formManager->updateFormEntry($updatedValue, $formID, $entryID);
2465 }
2466
2467 public function getLogHistory($Request, $post)
2468 {
2469 if (!empty($Request['formID'])) {
2470 $formID = absint(wp_unslash($Request['formID']));
2471 $entryID = absint(wp_unslash($Request['entryID']));
2472 } else {
2473 $formID = wp_unslash($post->formID);
2474 $entryID = wp_unslash($post->entryID);
2475 }
2476
2477 if (is_null($formID) || is_null($entryID)) {
2478 return new WP_Error('empty_form', __('Invalid Form ID or Entries ID.', 'bit-form'));
2479 }
2480
2481 $formManager = new AdminFormManager($formID);
2482 if (!$formManager->isExist()) {
2483 return new WP_Error('empty_form', __('Form does not exist.', 'bit-form'));
2484 }
2485 $formLogModel = new FormEntryLogModel();
2486
2487 $log_history = $formLogModel->geLogHistory($formID, $entryID);
2488 return $log_history;
2489 }
2490
2491 public function importDataStore($Request, $post)
2492 {
2493 if (!empty($Request['formID'])) {
2494 $formID = absint(wp_unslash($Request['formID']));
2495 } else {
2496 $formID = wp_unslash($post->formID);
2497 }
2498 if (is_null($formID)) {
2499 return new WP_Error('empty_form', __('Invalid Form id or entries id.', 'bit-form'));
2500 }
2501 }
2502
2503 public function getAllWPPages($Request, $post)
2504 {
2505 $pages = get_pages(['post_status' => 'publish', 'sort_column' => 'post_date', 'sort_order' => 'desc']);
2506 $allPages = [];
2507 foreach ($pages as $pageKey => $pageDetails) {
2508 // $allPages[$pageKey]['title'] = $pageDetails->post_title;
2509 // $allPages[$pageKey]['url'] = get_page_link($pageDetails->ID);
2510 $allPages[] = (object) [
2511 'title' => $pageDetails->post_title,
2512 'url' => get_page_link($pageDetails->ID)
2513 ];
2514 }
2515 return $allPages;
2516 }
2517
2518 public function deleteAIntegration($Request, $post)
2519 {
2520 if (!empty($Request['formID']) && !empty($Request['id'])) {
2521 $formID = absint(json_decode(wp_unslash($Request['formID'])));
2522 $id = absint(wp_unslash($Request['id']));
2523 } else {
2524 $formID = wp_unslash($post->formID);
2525 $id = wp_unslash($post->id);
2526 }
2527 if ($formID < 0 || empty($id)) {
2528 return new WP_Error('empty_form', 'Invalid Form ID or Integration ID.');
2529 }
2530
2531 $integrationHandler = new IntegrationHandler($formID);
2532 $delete_status = $integrationHandler->deleteIntegration($id);
2533 if (is_wp_error($delete_status)) {
2534 return $delete_status;
2535 }
2536
2537 return [
2538 'message' => __('Integration deleted', 'bit-form'),
2539 ];
2540 }
2541
2542 public function deleteSuccessMessage($Request, $post)
2543 {
2544 if (!empty($Request['formID']) && !empty($Request['id'])) {
2545 $formID = absint(json_decode(wp_unslash($Request['formID'])));
2546 $id = absint(wp_unslash($Request['id']));
2547 } else {
2548 $formID = wp_unslash($post->formID);
2549 $id = wp_unslash($post->id);
2550 }
2551 if (empty($formID) || empty($id)) {
2552 return new WP_Error('empty_form', 'Invalid Form ID or Message ID.');
2553 }
2554 $successMessageHandler
2555 = new SuccessMessageHandler($formID);
2556 $delete_status = $successMessageHandler->deleteMessage($id);
2557 if (is_wp_error($delete_status)) {
2558 return $delete_status;
2559 }
2560 return [
2561 'message' => __('Message deleted', 'bit-form'),
2562 ];
2563 }
2564
2565 public function deleteAWorkflow($Request, $post)
2566 {
2567 if (!empty($Request['formID']) && !empty($Request['id'])) {
2568 $formID = absint(json_decode(wp_unslash($Request['formID'])));
2569 $id = absint(wp_unslash($Request['id']));
2570 } else {
2571 $formID = wp_unslash($post->formID);
2572 $id = wp_unslash($post->id);
2573 }
2574 if (empty($formID) || empty($id)) {
2575 return new WP_Error('empty_form', 'Invalid Form ID or Workflow ID.');
2576 }
2577 $workFlowHandler = new WorkFlowHandler($formID);
2578 $delete_status = $workFlowHandler->deleteworkFlow($id);
2579 if (is_wp_error($delete_status)) {
2580 return $delete_status;
2581 }
2582 return [
2583 'message' => __('workflow deleted', 'bit-form'),
2584 ];
2585 }
2586
2587 public function deleteAMailTemplate($Request, $post)
2588 {
2589 if (!empty($Request['formID']) && !empty($Request['id'])) {
2590 $formID = absint(json_decode(wp_unslash($Request['formID'])));
2591 $id = absint(wp_unslash($Request['id']));
2592 } else {
2593 $formID = wp_unslash($post->formID);
2594 $id = wp_unslash($post->id);
2595 }
2596 if (empty($formID) || empty($id)) {
2597 return new WP_Error('empty_form', 'Invalid Form ID or Email Template ID.');
2598 }
2599 $emailTemplateHandler = new EmailTemplateHandler($formID);
2600 $delete_status = $emailTemplateHandler->deleteTemplate($id);
2601 if (is_wp_error($delete_status)) {
2602 return $delete_status;
2603 }
2604 return [
2605 'message' => __('Email Template deleted', 'bit-form'),
2606 ];
2607 }
2608
2609 public function duplicateAMailTemplate($Request, $post)
2610 {
2611 if (!empty($Request['formID']) && !empty($Request['id'])) {
2612 $formID = absint(json_decode(wp_unslash($Request['formID'])));
2613 $id = absint(wp_unslash($Request['id']));
2614 } else {
2615 $formID = wp_unslash($post->formID);
2616 $id = wp_unslash($post->id);
2617 }
2618 if (empty($formID) || empty($id)) {
2619 return new WP_Error('empty_form', 'Invalid Form ID or Email Template ID.');
2620 }
2621
2622 if (false === filter_var($id, FILTER_VALIDATE_INT)) {
2623 return new WP_Error('empty_form', 'Invalid Email Template ID.');
2624 }
2625
2626 if (false === filter_var($formID, FILTER_VALIDATE_INT)) {
2627 return new WP_Error('empty_form', 'Invalid Form ID.');
2628 }
2629
2630 $emailTemplateHandler = new EmailTemplateHandler($formID);
2631 $duplicate_status = $emailTemplateHandler->duplicateTemplate($id);
2632 if (is_wp_error($duplicate_status)) {
2633 return $duplicate_status;
2634 }
2635 return [
2636 'message' => __('Email Template duplicated', 'bit-form'),
2637 ];
2638 }
2639
2640 public function setAllFormsReport($Request, $post)
2641 {
2642 $reports = empty($post->reports) ? null : wp_unslash($post->reports);
2643 if (empty($reports)) {
2644 return new WP_Error('empty_report_prefs', 'Report data is Empty, nothing to save or update.');
2645 }
2646 if (!empty($reports)) {
2647 $reportsModel = new ReportsModel();
2648 $user_details = static::$ipTool->getUserDetail();
2649 foreach ($reports as $reportIndex => $report) {
2650 if (empty($report->id)) {
2651 $reportSaveSatus = $reportsModel->insert(
2652 [
2653 'type' => 'table',
2654 'category' => 'app',
2655 'context' => 'allForm',
2656 'details' => is_string($report->details) ? $report->details : wp_json_encode($report->details),
2657 'isDefault' => 1,
2658 'user_id' => $user_details['id'],
2659 'user_ip' => $user_details['ip'],
2660 'user_device' => $user_details['device'],
2661 'created_at' => $user_details['time'],
2662 'updated_at' => $user_details['time'],
2663 ]
2664 );
2665 $newData['reports'] = 1;
2666 } else {
2667 $reportSaveSatus = $reportsModel->update(
2668 [
2669 'type' => 'table',
2670 'category' => 'app',
2671 'context' => 'allForm',
2672 'details' => is_string($report->details) ? $report->details : wp_json_encode($report->details),
2673 'isDefault' => 1,
2674 'user_id' => $user_details['id'],
2675 'user_ip' => $user_details['ip'],
2676 'user_device' => $user_details['device'],
2677 'updated_at' => $user_details['time'],
2678 ],
2679 [
2680 'id' => $report->id,
2681 ]
2682 );
2683 }
2684 }
2685 }
2686 if (is_wp_error($reportSaveSatus)) {
2687 if ('result_empty' === $reportSaveSatus->get_error_code()) {
2688 return new WP_Error('empty_report_prefs', 'Nothing to save or update');
2689 }
2690 return new WP_Error('error_report_prefs', 'Error occured in saving reports');
2691 }
2692 $returnedReportData = $reportsModel->get(
2693 [
2694 'id',
2695 'details',
2696 'isDefault',
2697 'category',
2698 'context',
2699 ],
2700 [
2701 'category' => 'app',
2702 'context' => 'allForm',
2703 ]
2704 );
2705 if (!is_wp_error($returnedReportData)) {
2706 foreach ($returnedReportData as $reportKey => $reportData) {
2707 if (isset($reportData->details) && is_string($reportData->details)) {
2708 $returnedReportData[$reportKey]->details = json_decode($reportData->details);
2709 }
2710 }
2711 $reports = $returnedReportData;
2712 }
2713 return [
2714 'message' => __('Report preferrences saved successfully', 'bit-form'),
2715 'reports' => empty($reports) ? [] : $reports,
2716 ];
2717 }
2718
2719 public function savegReCaptcha($Request, $post)
2720 {
2721 $reCaptcha = $post->reCaptcha;
2722
2723 if (is_null($reCaptcha)) {
2724 return new WP_Error('empty_gcaptchdetails', __('g-ReCAPTCHA details is empty', 'bit-form'));
2725 }
2726 if (is_string($reCaptcha) && !empty(json_decode($reCaptcha)->id)) {
2727 $reCaptcha = json_decode($reCaptcha);
2728 $integrationID = $reCaptcha->id;
2729 unset($reCaptcha->id);
2730 } else {
2731 $integrationID = $reCaptcha->id;
2732 unset($reCaptcha->id);
2733 }
2734 $reCaptcha = wp_json_encode($reCaptcha);
2735
2736 // $integrationName = 'google reCaptcha';
2737 $integrationName = $post->integrationName;
2738
2739 // $integrationType = 'v2' === $post->version ? 'gReCaptcha' : 'gReCaptchaV3';
2740 $integrationType = $post->integrationType;
2741
2742 $integrationDetails = $reCaptcha;
2743 $user_details = static::$ipTool->getUserDetail();
2744 $integrationHandler = new IntegrationHandler(0, $user_details);
2745 $response = [];
2746 if (empty($integrationID)) {
2747 $captchaSaveStatus = $integrationHandler->saveIntegration($integrationName, $integrationType, $integrationDetails, 'app');
2748 $response['id'] = $captchaSaveStatus;
2749 $response['message'] = __('reCAPTCHA saved successfully', 'bit-form');
2750 } else {
2751 $captchaSaveStatus = $integrationHandler->updateIntegration($integrationID, $integrationName, $integrationType, $integrationDetails, 'app');
2752 $response['message'] = __('reCAPTCHA updated successfully', 'bit-form');
2753 }
2754
2755 if (is_wp_error($captchaSaveStatus)) {
2756 return $captchaSaveStatus;
2757 }
2758 return $response;
2759 }
2760
2761 public function savePaymentSetting($Request, $post)
2762 {
2763 if (isset($post->paySetting)) {
2764 $paySetting = $post->paySetting;
2765 }
2766 if (is_null($paySetting)) {
2767 return new WP_Error('empty_gcaptchdetails', __('Setting details is empty', 'bit-form'));
2768 }
2769 if (is_string($paySetting)) {
2770 $paySetting = json_decode($paySetting);
2771 }
2772
2773 $canSave = null;
2774 switch ($paySetting->type) {
2775 case 'PayPal':
2776 $canSave = $this->addWebhookToPaypal($paySetting);
2777 break;
2778 case 'Razorpay':
2779 $canSave = true;
2780 break;
2781 case 'Stripe':
2782 $canSave = $this->addWebhookToStripe($paySetting);
2783 break;
2784 case 'Mollie':
2785 $canSave = true;
2786 break;
2787 default:
2788 $canSave = null;
2789 }
2790 if (is_null($canSave)) {
2791 return new WP_Error('stripe', __('Please re-check your Client ID & Secret', 'bit-form'));
2792 }
2793 $integrationID = null;
2794 if (isset($paySetting->id)) {
2795 $integrationID = $paySetting->id;
2796 unset($paySetting->id);
2797 }
2798 $integrationName = $paySetting->name;
2799 $integrationType = 'payments';
2800 $paySetting = wp_json_encode($paySetting);
2801 $integrationDetails = $paySetting;
2802 $user_details = static::$ipTool->getUserDetail();
2803 $integrationHandler = new IntegrationHandler(0, $user_details);
2804 $response = [];
2805 if (empty($integrationID)) {
2806 $paymentSaveStatus = $integrationHandler->saveIntegration($integrationName, $integrationType, $integrationDetails, 'app');
2807 $response['id'] = $paymentSaveStatus;
2808 $response['message'] = __('Payment setting saved successfully', 'bit-form');
2809 } else {
2810 $paymentSaveStatus = $integrationHandler->updateIntegration($integrationID, $integrationName, $integrationType, $integrationDetails, 'app');
2811 $response['message'] = __('Payment setting updated successfully', 'bit-form');
2812 }
2813
2814 if (is_wp_error($paymentSaveStatus)) {
2815 return $paymentSaveStatus;
2816 }
2817 return $response;
2818 }
2819
2820 private function addWebhookToPaypal($paySetting)
2821 {
2822 $transaction_mode = $paySetting->mode;
2823 $clientId = $paySetting->clientID;
2824 $clientSecret = $paySetting->clientSecret;
2825 $base_url = 'sandbox' === $transaction_mode ? 'https://api-m.sandbox.paypal.com' : 'https://api.paypal.com';
2826 // get all webhooks
2827 $webhooks_url = $base_url . '/v1/notifications/webhooks';
2828 $webhooks_headers = [
2829 'Content-Type' => 'application/json',
2830 'Authorization' => 'Basic ' . base64_encode($clientId . ':' . $clientSecret)
2831 ];
2832 $webhook_url = get_rest_url() . 'bitform/v1/payments/paypal';
2833 // adding webhook
2834 $data = [
2835 'url' => $webhook_url,
2836 'event_types' => [
2837 [
2838 'name' => 'CHECKOUT.ORDER.APPROVED'
2839 ]
2840 ]
2841 ];
2842 $webhook_response = HttpHelper::post($webhooks_url, wp_json_encode($data), $webhooks_headers);
2843 if (is_wp_error($webhook_response) || $webhook_response->error) {
2844 return null;
2845 }
2846 return true;
2847 }
2848
2849 private function addWebhookToStripe($paySetting)
2850 {
2851 $clientSecret = $paySetting->clientSecret;
2852
2853 $create_webhook_url = 'https://api.stripe.com/v1/webhook_endpoints';
2854 $headers = [
2855 'Content-Type' => 'application/x-www-form-urlencoded',
2856 'Authorization' => "Bearer $clientSecret",
2857 ];
2858
2859 $webhook_url = get_rest_url() . 'bitform/v1/payments/stripe';
2860
2861 $apiResponse = HttpHelper::get($create_webhook_url, '', $headers);
2862
2863 if (isset($apiResponse->error)) {
2864 return null;
2865 }
2866 $webhookList = $apiResponse->data;
2867 $webhook_already_exist = false;
2868
2869 foreach ($webhookList as $webhook) {
2870 if ($webhook->url === $webhook_url) {
2871 $webhook_already_exist = true;
2872 break;
2873 }
2874 }
2875
2876 $data = [
2877 'enabled_events[]' => 'payment_intent.succeeded',
2878 'url' => $webhook_url,
2879 ];
2880
2881 if (!$webhook_already_exist) {
2882 $webhook_response = HttpHelper::post($create_webhook_url, $data, $headers);
2883 if (is_wp_error($webhook_response) || (isset($webhook_response->error) && $webhook_response->error)) {
2884 Log::debug_log(['Stripe webhook creation failed' => $webhook_response]);
2885 return null;
2886 }
2887 }
2888 return true;
2889 }
2890
2891 public function builerHelperState($formId)
2892 {
2893 $data = static::$formModel->get(
2894 ['id', 'builder_helper_state'],
2895 ['id' => $formId]
2896 );
2897
2898 if (!is_wp_error($data)) {
2899 foreach ($data as $key => $value) {
2900 if (isset($value->builder_helper_state) && is_string($value->builder_helper_state)) {
2901 $data[$key]->builder_helper_state = json_decode($value->builder_helper_state);
2902 }
2903 }
2904 }
2905
2906 return $data;
2907 }
2908
2909 public function updateGeneratedScriptPageIds()
2910 {
2911 $updateData = [
2912 'generated_script_page_ids' => \wp_json_encode((object) []),
2913 ];
2914 $update_status = static::$formModel->update(
2915 $updateData,
2916 [
2917 'status' => 1
2918 ]
2919 );
2920 if (is_wp_error($update_status)) {
2921 return $update_status;
2922 } elseif (!$update_status) {
2923 return new WP_Error('empty_form', __('Form update failed.', 'bit-form'));
2924 } else {
2925 return true;
2926 }
2927 }
2928
2929 public function replaceAllFormsErrorMessagesByGlobalMessages()
2930 {
2931 try {
2932 $formModel = new FormModel();
2933 $allForms = $formModel->get(['id', 'form_content']);
2934
2935 foreach ($allForms as $form) {
2936 // Decode form_content JSON to stdClass
2937 $formContent = \json_decode($form->form_content);
2938 $fields = $formContent->fields ?? null;
2939 // If decode fails, skip to next
2940 if (!$fields) {
2941 Log::debug_log("Form ID {$form->id}: invalid JSON in form_content");
2942 continue;
2943 }
2944
2945 // Replace default error messages using your helper
2946 $updatedFields = Helpers::replaceFieldsDefaultErrorMsg($fields);
2947
2948 $formContent->fields = $updatedFields;
2949 // Encode back to JSON
2950 $updatedContent = \json_encode($formContent);
2951
2952 if (false === $updatedContent) {
2953 Log::debug_log("Form ID {$form->id}: JSON encoding failed");
2954 continue;
2955 }
2956 // Update form content in DB
2957 $formModel->update(
2958 ['form_content' => $updatedContent], // data to update
2959 ['id' => $form->id] // condition for update
2960 );
2961 }
2962 } catch (\Exception $e) {
2963 Log::debug_log([
2964 'message' => 'Error in updateAllFormsErrorMessagesWithGlobalMessages',
2965 'error' => $e->getMessage(),
2966 ]);
2967 }
2968 }
2969
2970 public function updateSuccessMessageClassName($str, $msgIdx, $msgId)
2971 {
2972 $TEMP_CONF_ID = '_tmp_' . $msgIdx . '_conf_id';
2973 return str_replace($TEMP_CONF_ID, $msgId, $str);
2974 }
2975
2976 public function startMigrationProcess()
2977 {
2978 Utilities::duplicateDbTable('form', 'form_v1');
2979 Utilities::duplicateDbTable('workflows', 'workflows_v1');
2980 Utilities::duplicateDbTable('success_messages', 'success_messages_v1');
2981 MigrationHelper::duplicateV1StyleFiles();
2982 $all_forms = $this->getAllForm();
2983 $v1FormContents = [];
2984 $defaultStyleClass = MigrationHelper::getBitformDefaultStyleClass();
2985 foreach ($all_forms as $form) {
2986 $formContents = $this->getAFormV1(['id' => $form->id], ['id' => $form->id]);
2987 $v1FormContents[] = $formContents;
2988 FrontEndScriptGenerator::saveCssFile("{$form->id}", $defaultStyleClass);
2989 FrontEndScriptGenerator::saveCssFile("{$form->id}-formid", $defaultStyleClass);
2990 }
2991 set_transient('bitforms_v1_form_contents', $v1FormContents);
2992 update_option('bitforms_migrating_to_v2', true);
2993 }
2994 }
2995