PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 1.10.3
Fluent Support – Helpdesk & Customer Support Ticket System v1.10.3
2.4.0 2.3.2 2.3.1 2.3.0 2.2.1 2.2.0 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.4.0 1.4.1 1.4.2 1.4.5 1.4.6 1.4.7 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 All 68 releases
fluent-support / app / Http / Controllers / SettingsController.php

SettingsController.php in Fluent Support – Helpdesk & Customer Support Ticket System 1.10.3, at app/Http/Controllers/SettingsController.php

794 lines 28.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentSupport\App\Http\Controllers;
4
5
6 use FluentSupport\App\Models\MailBox;
7 use FluentSupport\App\Models\Meta;
8 use FluentSupport\App\Models\Product;
9 use FluentSupport\App\Services\EmailNotification\Settings;
10 use FluentSupport\App\Services\Helper;
11 use FluentSupport\Database\Migrations\AIActivityLogsMigrator;
12 use FluentSupport\Framework\Request\Request;
13 use FluentSupport\App\Hooks\Handlers\ReCaptchaHandler;
14
15 /**
16 * SettingsController class is responsible for all settings
17 * This class is responsible for all request related to settings under global settings tab
18 * @package FluentSupport\App\Http\Controllers
19 *
20 * @version 1.0.0
21 */
22 class SettingsController extends Controller
23 {
24 /**
25 * getSettings method will return the settings by settings key
26 * @param Request $request
27 * @return array|array[]
28 */
29 public function getSettings(Request $request)
30 {
31 $settingsKey = $request->getSafe('settings_key', 'sanitize_text_field');
32
33 return (new Settings)->get($settingsKey);
34 }
35
36 /**
37 * getIntegrationSettings method will return the settings for integration
38 * @param Request $request
39 * @return array
40 */
41 public function getIntegrationSettings(Request $request)
42 {
43 $settings = Meta::where('object_type', 'integration_settings')->get();
44 $integrationSettings = [];
45 foreach ($settings as $index => $setting) {
46 $data = Helper::safeUnserialize($setting->value);
47 if (!empty($data['status']) && $data && $data['status'] == 'yes') {
48 $integrationSettings[] = $setting->key;
49 }
50 }
51 return $integrationSettings;
52 }
53
54 /**
55 * saveSettings method will save the requested settings data by setting key
56 * @param Request $request
57 * @return array
58 */
59 public function saveSettings(Request $request)
60 {
61 $settingsKey = $request->getSafe('settings_key', 'sanitize_text_field');
62 $settings = wp_unslash($request->getSafe('settings', null, []));
63 (new Settings)->save($settingsKey, $settings);
64
65 return [
66 'message' => __('Settings has been updated', 'fluent-support')
67 ];
68 }
69
70 /**
71 * getPages method will return the list of pages created in WP
72 * @return array
73 */
74 public function getPages()
75 {
76 return [
77 'pages' => Helper::getWPPages()
78 ];
79 }
80
81 /**
82 * setupPortal method will setup the support portal
83 * @param Request $request
84 * @return array
85 * @throws \FluentSupport\Framework\Validator\ValidationException
86 */
87 public function setupPortal(Request $request)
88 {
89 $mailbox = $request->getSafe('mailbox');
90 $this->validate($mailbox, [
91 'name' => 'required',
92 'email' => 'required|email',
93 'box_type' => 'required'
94 ]);
95
96 $settings = $request->getSafe('global_settings');
97
98 $createPage = $settings['create_portal_page'] == 'yes';
99
100 if (!$createPage && empty($settings['portal_page_id'])) {
101 return $this->sendError([
102 'message' => __('Please select a page or enable create page', 'fluent-support')
103 ]);
104 }
105
106 if ($createPage) {
107 // we have to create the page
108 $page_id = wp_insert_post(
109 array(
110 'comment_status' => 'close',
111 'ping_status' => 'close',
112 'post_author' => get_current_user_id(),
113 'post_title' => __('Support Portal', 'fluent-support'),
114 'post_status' => 'publish',
115 'post_content' => '<!-- wp:shortcode -->[fluent_support_portal]<!-- /wp:shortcode -->',
116 'post_type' => 'page'
117 )
118 );
119 } else {
120 $page_id = intval($settings['portal_page_id']);
121 }
122
123 $newMailBox = MailBox::first();
124 if (!$newMailBox) {
125 $mailbox['is_default'] = 'yes';
126 $mailbox['created_by'] = get_current_user_id();
127 $mailbox['settings']['admin_email_address'] = $mailbox['email'];
128 $newMailBox = MailBox::create($mailbox);
129 }
130
131 $settingsClass = new Settings();
132 $globalSettings = $settingsClass->globalBusinessSettings();
133
134 $globalSettings['portal_page_id'] = $page_id;
135
136 $settingsClass->save('global_business_settings', $globalSettings);
137
138
139 if (defined('WC_PLUGIN_FILE')) {
140 // URL Flash
141 flush_rewrite_rules(false);
142 }
143
144 return [
145 'mailbox' => $newMailBox,
146 'global_settings' => $globalSettings,
147 'mailboxes' => MailBox::select(['id', 'name', 'settings'])->get(),
148 'has_fluentform' => defined('FLUENTFORM')
149 ];
150
151 }
152
153 /**
154 * getFluentCRMSettings method will return the settings for Fluent CRM
155 * @param Request $request
156 * @return array
157 */
158 public function getFluentCRMSettings(Request $request)
159 {
160 if (defined('FLUENTCRM')) {
161 $settingDefault = [
162 'enabled' => 'no',
163 'default_status' => 'subscribed',
164 'assigned_list' => '',
165 'assigned_tags' => []
166 ];
167
168 $settings = Helper::getOption('_fluentcrm_intergration_settings');
169
170 $settings = wp_parse_args($settings, $settingDefault);
171
172 $settingsFields = [
173 'enabled' => [
174 'type' => 'inline-checkbox',
175 'true_label' => 'yes',
176 'false_label' => 'no',
177 'checkbox_label' => __('Enable FluentCRM Integration', 'fluent-support')
178 ],
179 'default_status' => [
180 'type' => 'input-radio',
181 'label' => __('Default status for new contacts', 'fluent-support'),
182 'options' => [
183 [
184 'id' => 'subscribed',
185 'label' => __('Subscribed', 'fluent-support')
186 ],
187 [
188 'id' => 'pending',
189 'label' => __('Pending', 'fluent-support')
190 ]
191 ],
192 'dependency' => [
193 'depends_on' => 'enabled',
194 'operator' => '=',
195 'value' => 'yes'
196 ],
197 'inline_help' => __('Select the default status for new contacts. If you select pending and it\'s a new contact then a double optin email will be sent', 'fluent-support')
198 ],
199 'assigned_list' => [
200 'type' => 'input-options',
201 'label' => __('Add to FluentCRM list (optional)', 'fluent-support'),
202 'options' => \FluentCrm\App\Models\Lists::select(['id', 'title'])->orderBy('title', 'ASC')->get(),
203 'dependency' => [
204 'depends_on' => 'enabled',
205 'operator' => '=',
206 'value' => 'yes'
207 ],
208 ],
209 'assigned_tags' => [
210 'type' => 'input-options',
211 'multiple' => true,
212 'label' => __('Add to Tags', 'fluent-support'),
213 'options' => \FluentCrm\App\Models\Tag::select(['id', 'title'])->orderBy('title', 'ASC')->get(),
214 'dependency' => [
215 'depends_on' => 'enabled',
216 'operator' => '=',
217 'value' => 'yes'
218 ]
219 ]
220 ];
221
222 return [
223 'is_installed' => true,
224 'settings' => $settings,
225 'settings_fields' => $settingsFields,
226 'fluentcrm_logo' => FLUENT_SUPPORT_PLUGIN_URL . 'assets/images/fluentcrm-logo.svg'
227 ];
228 }
229
230 return [
231 'is_installed' => false,
232 'fluentcrm_logo' => FLUENT_SUPPORT_PLUGIN_URL . 'assets/images/fluentcrm-logo.svg'
233 ];
234
235 }
236
237 public function setupInstallation(Request $request)
238 {
239 $installFluentForm = $request->get('install_fluentform', 'no');
240
241 if ($installFluentForm == 'yes' && !defined('FLUENTFORM')) {
242 $this->installFluentForm();
243 }
244
245 $optinEmail = $request->getSafe('optin_email', 'sanitize_text_field', 'no');
246 if ($optinEmail && is_email($optinEmail)) {
247 $this->shareEmail($optinEmail);
248 }
249
250 $shareEssential = $request->getSafe('share_essentials', 'sanitize_text_field', 'no');
251 if ($shareEssential == 'yes') {
252 Helper::updateOption('_share_essential', $shareEssential);
253 }
254
255 return $this->sendSuccess([
256 'message' => __('Installation has been completed', 'fluent-support')
257 ]);
258
259 }
260
261 public function saveReCaptchaSettings(Request $request)
262 {
263 $data = $request->get('reCaptcha');
264
265 if ('clear-reCaptcha-settings' == $data) {
266 if (Meta::where('object_type', '_fs_recaptcha_settings')->delete()) {
267 return $this->sendSuccess([
268 'message' => __('Your reCAPTCHA settings deleted successfully.', 'fluent-support'),
269 ]);
270 }
271
272 return $this->sendError([
273 'message' => __('Unable to delete reCAPTCHA settings, try again', 'fluent-support'),
274 ]);
275 }
276
277 $reCaptchaData = [
278 'reCaptcha_version' => sanitize_text_field($data['reCaptchaVersion']),
279 'siteKey' => sanitize_text_field($data['siteKey']),
280 'secretKey' => sanitize_text_field($data['secretKey']),
281 'formContainingReCaptcha' => array_map('sanitize_text_field', $data['formContainingReCaptcha']),
282 'is_enabled' => sanitize_text_field($data['reCaptchaEnabled'], 'no'),
283 ];
284
285 $previousValue = Meta::where('object_type', '_fs_recaptcha_settings')->first();
286
287 if ($previousValue === $reCaptchaData) {
288 return $this->sendError([
289 'message' => __('Your recaptcha details are already saved.', 'fluent-support'),
290 ]);
291 }
292
293 $verifyReCaptcha = ReCaptchaHandler::validateRecaptcha($data['captchaResponse'], $data['secretKey'], $data['reCaptchaVersion']);
294
295 if (!$verifyReCaptcha) {
296 return $this->sendError([
297 'message' => __('Your reCAPTCHA settings are not valid.', 'fluent-support'),
298 ]);
299 }
300
301 if ($previousValue) {
302 Meta::where('object_type', '_fs_recaptcha_settings')->update([
303 'value' => maybe_serialize($reCaptchaData)
304 ]);
305 return $this->sendSuccess([
306 'message' => __('Your reCAPTCHA settings updated successfully.', 'fluent-support'),
307 ]);
308 } else {
309 Meta::insert([
310 'object_type' => '_fs_recaptcha_settings',
311 'key' => '_fs_recaptcha_data',
312 'value' => maybe_serialize($reCaptchaData)
313 ]);
314 }
315
316 return $this->sendSuccess([
317 'message' => __('Your reCAPTCHA settings added successfully.', 'fluent-support'),
318 ]);
319 }
320
321 public function saveOpenAISettings(Request $request)
322 {
323 $data = $request->get();
324 $data = [
325 'api_key' => sanitize_text_field($data['api_key']),
326 'model' => sanitize_text_field($data['model']),
327 ];
328
329 $response = Helper::authorizeChatGPTAPIKey($data);
330
331 if (is_wp_error($response)) {
332 return $this->sendError([
333 'message' => __('There was an error verifying the API key.', 'fluent-support'),
334 ]);
335 }
336
337 $body = json_decode(wp_remote_retrieve_body($response), true);
338
339 if (isset($body['error'])) {
340 return $this->sendError([
341 'message' => __('Invalid API key. Please provide a valid ChatGPT API key.', 'fluent-support'),
342 ]);
343 }
344
345 try {
346 $isDataSaved = Helper::saveOpenAIData('_fs_openai_settings', '_fs_openai_data', $data);
347 if ($isDataSaved) {
348 AIActivityLogsMigrator::migrate();
349 }
350 return $this->sendSuccess([
351 'message' => __('OpenAI settings have been successfully saved.', 'fluent-support'),
352 ]);
353 } catch (\Exception $e) {
354 // translators: %s is the error message from the exception
355 $translatedMessage = __('An error occurred while saving the settings: %s', 'fluent-support');
356 $errorMessage = sprintf($translatedMessage, $e->getMessage());
357
358 return $this->sendError([
359 'message' => $errorMessage,
360 ]);
361 }
362 }
363
364
365 public function disconnectOpenAI()
366 {
367 $deletedRecords = Meta::where([
368 'object_type' => '_fs_openai_settings',
369 'key' => '_fs_openai_data',
370 ])->delete();
371
372 if ($deletedRecords) {
373 return $this->sendSuccess([
374 'message' => __('OpenAI settings have been successfully disconnected.', 'fluent-support'),
375 ]);
376 } else {
377 return $this->sendError([
378 'message' => __('Failed to disconnect OpenAI settings. No matching records found or an error occurred.', 'fluent-support'),
379 ]);
380 }
381 }
382
383 public function getOpenAISettings()
384 {
385 $chatGPTSettingsData = Meta::where('object_type', '_fs_openai_settings')->first();
386 if ($chatGPTSettingsData) {
387 $settings = Helper::safeUnserialize($chatGPTSettingsData->value);
388 return $this->sendSuccess($settings);
389 }
390
391 return [];
392 }
393
394 public function getReCaptchaSettings()
395 {
396 $reCaptchaSettingsData = Meta::where('object_type', '_fs_recaptcha_settings')->first();
397 if ($reCaptchaSettingsData) {
398 $settings = Helper::safeUnserialize($reCaptchaSettingsData->value);
399 return $this->sendSuccess($settings);
400 }
401
402 return [];
403 }
404
405 private function shareEmail($optinEmail)
406 {
407 $user = get_user_by('ID', get_current_user_id());
408 $data = [
409 'answers' => [
410 'website' => site_url(),
411 'email' => $optinEmail,
412 'first_name' => $user->first_name,
413 'last_name' => $user->last_name,
414 'name' => $user->display_name,
415 'has_fluentform' => defined('FLUENTFORM') ? 'yes' : 'no'
416 ],
417 'questions' => [
418 'website' => 'website',
419 'first_name' => 'first_name',
420 'last_name' => 'last_name',
421 'email' => 'email',
422 'name' => 'name',
423 'has_fluentform' => 'has_fluentform'
424 ],
425 'user' => [
426 'email' => $optinEmail
427 ],
428 'fb_capture' => 1,
429 'form_id' => 77
430 ];
431
432 $url = add_query_arg($data, 'https://wpmanageninja.com/');
433
434 wp_remote_post($url, [
435 'sslverify' => false
436 ]);
437 }
438
439 /**
440 * installFluentCRM method will install Fluent CRM plugin
441 * @return array
442 */
443 public function installFluentCRM()
444 {
445
446 if (defined('FLUENTCRM')) {
447 return [
448 'is_installed' => true,
449 'message' => __('FluentCRM plugin has been installed and activated successfully', 'fluent-support')
450 ];
451 }
452
453 if (!current_user_can('install_plugins')) {
454 return $this->sendError([
455 'message' => __('Sorry! you do not have permission to install plugin', 'fluent-support')
456 ]);
457 }
458
459 $plugin_id = 'fluent-crm';
460 $plugin = [
461 'name' => 'Fluent CRM',
462 'repo-slug' => 'fluent-crm',
463 'file' => 'fluent-crm.php',
464 ];
465
466 $this->backgroundInstaller($plugin, $plugin_id);
467
468 if (defined('FLUENTCRM')) {
469 return [
470 'is_installed' => true,
471 'message' => __('FluentCRM plugin has been installed and activated successfully', 'fluent-support')
472 ];
473 } else {
474 return $this->sendError([
475 'message' => __('Sorry! FluentCRM could not be installed. Please install manually', 'fluent-support')
476 ]);
477 }
478 }
479
480 public function installFluentForm()
481 {
482
483 if (defined('FLUENTFORM')) {
484 return [
485 'is_installed' => true,
486 'message' => __('Fluent Forms plugin has been installed and activated successfully', 'fluent-support')
487 ];
488 }
489
490 if (!current_user_can('install_plugins')) {
491 return $this->sendError([
492 'message' => __('Sorry! you do not have permission to install plugin', 'fluent-support')
493 ]);
494 }
495
496 $plugin_id = 'fluent-crm';
497 $plugin = [
498 'name' => 'Fluent CRM',
499 'repo-slug' => 'fluent-crm',
500 'file' => 'fluent-crm.php',
501 ];
502
503 $this->backgroundInstaller($plugin, $plugin_id);
504
505 if (defined('FLUENTCRM')) {
506 return [
507 'is_installed' => true,
508 'message' => __('Fluent Forms plugin has been installed and activated successfully', 'fluent-support')
509 ];
510 } else {
511 return [
512 'is_installed' => false,
513 'message' => __('Fluent Forms could not be installed', 'fluent-support')
514 ];
515 }
516 }
517
518 private function backgroundInstaller($plugin_to_install, $plugin_id)
519 {
520 if (!empty($plugin_to_install['repo-slug'])) {
521 require_once ABSPATH . 'wp-admin/includes/file.php';
522 require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
523 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
524 require_once ABSPATH . 'wp-admin/includes/plugin.php';
525
526 WP_Filesystem();
527
528 $skin = new \Automatic_Upgrader_Skin();
529 $upgrader = new \WP_Upgrader($skin);
530 $installed_plugins = array_reduce(array_keys(\get_plugins()), array($this, 'associate_plugin_file'), array());
531 $plugin_slug = $plugin_to_install['repo-slug'];
532 $plugin_file = isset($plugin_to_install['file']) ? $plugin_to_install['file'] : $plugin_slug . '.php';
533 $installed = false;
534 $activate = false;
535
536 // See if the plugin is installed already.
537 if (isset($installed_plugins[$plugin_file])) {
538 $installed = true;
539 $activate = !is_plugin_active($installed_plugins[$plugin_file]);
540 }
541
542 // Install this thing!
543 if (!$installed) {
544 // Suppress feedback.
545 ob_start();
546
547 try {
548 $plugin_information = plugins_api(
549 'plugin_information',
550 array(
551 'slug' => $plugin_slug,
552 'fields' => array(
553 'short_description' => false,
554 'sections' => false,
555 'requires' => false,
556 'rating' => false,
557 'ratings' => false,
558 'downloaded' => false,
559 'last_updated' => false,
560 'added' => false,
561 'tags' => false,
562 'homepage' => false,
563 'donate_link' => false,
564 'author_profile' => false,
565 'author' => false,
566 ),
567 )
568 );
569
570 if (is_wp_error($plugin_information)) {
571 throw new \Exception($plugin_information->get_error_message());
572 }
573
574 $package = $plugin_information->download_link;
575 $download = $upgrader->download_package($package);
576
577 if (is_wp_error($download)) {
578 throw new \Exception($download->get_error_message());
579 }
580
581 $working_dir = $upgrader->unpack_package($download, true);
582
583 if (is_wp_error($working_dir)) {
584 throw new \Exception($working_dir->get_error_message());
585 }
586
587 $result = $upgrader->install_package(
588 array(
589 'source' => $working_dir,
590 'destination' => WP_PLUGIN_DIR,
591 'clear_destination' => false,
592 'abort_if_destination_exists' => false,
593 'clear_working' => true,
594 'hook_extra' => array(
595 'type' => 'plugin',
596 'action' => 'install',
597 ),
598 )
599 );
600
601 if (is_wp_error($result)) {
602 throw new \Exception($result->get_error_message());
603 }
604
605 $activate = true;
606
607 } catch (\Exception $e) {
608 }
609
610 // Discard feedback.
611 ob_end_clean();
612 }
613
614 wp_clean_plugins_cache();
615
616 // Activate this thing.
617 if ($activate) {
618 try {
619 $result = activate_plugin($installed ? $installed_plugins[$plugin_file] : $plugin_slug . '/' . $plugin_file);
620
621 if (is_wp_error($result)) {
622 throw new \Exception($result->get_error_message());
623 }
624 } catch (\Exception $e) {
625 }
626 }
627 }
628 }
629
630 private function associate_plugin_file($plugins, $key)
631 {
632 $path = explode('/', $key);
633 $filename = end($path);
634 $plugins[$filename] = $key;
635 return $plugins;
636 }
637
638 public function getRemoteUploadSettings(Request $request)
639 {
640 $dropBoxConfigured = false;
641 $googleDriveConfigured = false;
642
643 if (defined('FLUENTSUPPORTPRO')) {
644 $dropBoxSettings = Helper::getIntegrationOption('dropbox_settings');
645 $dropBoxConfigured = $dropBoxSettings && !empty($dropBoxSettings['access_token']);
646
647 $googleDriveSettings = Helper::getIntegrationOption('google_drive_settings');
648 $googleDriveConfigured = $googleDriveSettings && !empty($googleDriveSettings['access_token']);
649 }
650
651 $drivers = apply_filters('fluent_support/storage_drivers_info', [
652 'local' => [
653 'title' => 'Default WordPress Storage',
654 'is_disabled' => false,
655 'is_configured' => true,
656 'icon' => FLUENT_SUPPORT_PLUGIN_URL . 'assets/images/icons/folder.svg',
657 'description' => __('Upload and store the files to your WordPress File System Storage.', 'fluent-support')
658 ],
659 'dropbox' => [
660 'meta_key' => 'dropbox_settings',
661 'title' => 'Dropbox',
662 'has_config' => true,
663 'is_configured' => $dropBoxConfigured,
664 'require_pro' => !defined('FLUENTSUPPORTPRO'),
665 'icon' => FLUENT_SUPPORT_PLUGIN_URL . 'assets/images/icons/dbox.svg',
666 'description' => __('Upload and store the files to your Dropbox Storage.', 'fluent-support')
667 ],
668 'google_drive' => [
669 'meta_key' => 'google_drive_settings',
670 'title' => 'Google Drive',
671 'has_config' => true,
672 'is_configured' => $googleDriveConfigured,
673 'require_pro' => !defined('FLUENTSUPPORTPRO'),
674 'upgrade_url' => 'https://fluentsupport.com/pricing',
675 'description' => __('Upload and store the files to your Google Drive Storage.', 'fluent-support'),
676 'icon' => FLUENT_SUPPORT_PLUGIN_URL . 'assets/images/icons/drive.svg',
677 ]
678 ]);
679
680 return [
681 'drivers' => $drivers,
682 'enabled_driver' => Helper::getUploadDriverKey()
683 ];
684 }
685
686 public function updateRemoteUploadDriver(Request $request)
687 {
688 $driver = $request->getSafe('driver', 'sanitize_text_field');
689 Helper::updateOption('file_upload_driver', $driver);
690
691 return [
692 'message' => 'Upload driver has been updated successfully',
693 'driver' => $driver
694 ];
695 }
696
697 /**
698 * getIntegrationLogs method will return the integration logs
699 * @return array
700 */
701 public function integrationStatuses()
702 {
703 return [
704 'connections' => Helper::getIntegrationStatuses()
705 ];
706 }
707
708 public function getSettingsMenu()
709 {
710 return Helper::getGlobalSettingsMenu();
711 }
712
713 public function getFluentBotSettings()
714 {
715 $meta = Meta::where([
716 'object_type' => 'fluent_bot_settings',
717 'object_id' => 1,
718 'key' => '_fs_fluent_bot_config'
719 ])->first();
720
721 $settings = $meta ? Helper::safeUnserialize($meta->value) : [];
722
723 $productItems = Product::all()->map(function ($product) {
724 return [
725 'id' => $product->id,
726 'title' => $product->title
727 ];
728 })->values()->all();
729
730 return array_merge([
731 'generalApiKey' => '',
732 'generalBotId' => '',
733 'isEnabled' => false,
734 'productMappings' => [],
735 'products' => $productItems
736 ], $settings, [
737 'products' => $productItems
738 ]);
739 }
740
741 public function saveFluentBotSettings(Request $request)
742 {
743 $data = [
744 'generalApiKey' => $request->getSafe('generalApiKey', 'sanitize_text_field'),
745 'generalBotId' => $request->getSafe('generalBotId', 'sanitize_text_field'),
746 'isEnabled' => $request->getSafe('isEnabled', 'sanitize_text_field'),
747 'productMappings' => []
748 ];
749
750 $productMappings = (array) $request->get('productMappings', []);
751
752 foreach ($productMappings as $mapping) {
753 if (!is_array($mapping)) {
754 continue;
755 }
756
757 $data['productMappings'][] = [
758 'productId' => intval($mapping['productId'] ?? 0),
759 'productTitle' => sanitize_text_field($mapping['productTitle'] ?? ''),
760 'apiKey' => sanitize_text_field($mapping['apiKey'] ?? ''),
761 'botId' => sanitize_text_field($mapping['botId'] ?? ''),
762 ];
763 }
764
765 $serialized = maybe_serialize($data);
766
767 $existing = Meta::where([
768 'object_type' => 'fluent_bot_settings',
769 'object_id' => 1,
770 'key' => '_fs_fluent_bot_config'
771 ])->first();
772
773 if ($existing) {
774 $existing->update(['value' => $serialized]);
775 } else {
776 Meta::create([
777 'object_type' => 'fluent_bot_settings',
778 'object_id' => 1,
779 'key' => '_fs_fluent_bot_config',
780 'value' => $serialized
781 ]);
782
783 AIActivityLogsMigrator::migrate();
784 }
785
786 return [
787 'success' => true,
788 'message' => 'Settings saved successfully',
789 'data' => $data
790 ];
791 }
792
793 }
794