PluginProbe
FireBox – WooCommerce Popup Builder, Exit Intent Popup, Email Optin & Cart Abandonment / 3.1.14
FireBox – WooCommerce Popup Builder, Exit Intent Popup, Email Optin & Cart Abandonment v3.1.14
3.1.14 3.1.13 3.1.12 3.1.11 3.1.10 3.1.9 3.1.8 3.1.7 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 All 123 releases
← All changes | Inc/Core/Controllers/BoxSettings.php +144 -19 1.0.0 → 3.1.14 View file →
@@ -1,12 +1,12 @@
1 1 <?php
2 2 /**
3 3 * @package FireBox
4 - * @version 1.0.0 Free
4 + * @version 3.1.14 Free
5 5 *
6 6 * @author FirePlugins <[email protected]>
7 7 * @link https://www.fireplugins.com
8 - * @copyright Copyright © 2021 FirePlugins All Rights Reserved
8 + * @copyright Copyright © 2026 FirePlugins All Rights Reserved
9 9 * @license GNU GPLv3 <http://www.gnu.org/licenses/gpl.html> or later
10 10 */
11 11
12 12 namespace FireBox\Core\Controllers;
@@ -21,8 +21,10 @@
21 21 use FPFramework\Base\Ui\Tabs;
22 22
23 23 class BoxSettings extends BaseController
24 24 {
25 + protected $action = '';
26 +
25 27 /**
26 28 * The form settings name
27 29 *
28 30 * @var string
@@ -28,8 +30,13 @@
28 30 * @var string
29 31 */
30 32 const settings_name = 'firebox_settings';
31 33
34 + public function __construct()
35 + {
36 + add_action('update_option_firebox_settings', [$this, 'after_update_settings'], 10, 2);
37 + }
38 +
32 39 /**
33 40 * Render the page content
34 41 *
35 42 * @return void
@@ -42,8 +49,25 @@
42 49 // render layout
43 50 firebox()->renderer->admin->render('pages/settings');
44 51 }
45 52
53 + /**
54 + * Stop the usage tracking if the user disables the tracking behavior.
55 + *
56 + * @param array $old_value
57 + * @param array $new_value
58 + *
59 + * @return void
60 + */
61 + public function after_update_settings($old_value, $new_value)
62 + {
63 + if (isset($new_value['usage_tracking']) && !$new_value['usage_tracking'])
64 + {
65 + $tracking = new \FireBox\Core\UsageTracking\SendUsage();
66 + $tracking->stop();
67 + }
68 + }
69 +
46 70 /**
47 71 * Load required media files
48 72 *
49 73 * @return void
@@ -57,9 +81,54 @@
57 81 [],
58 82 FPF_VERSION,
59 83 false
60 84 );
61 - wp_enqueue_script( 'fpf-geoip' );
85 + wp_enqueue_script('fpf-geoip');
86 +
87 + wp_register_script(
88 + 'firebox-settings-integrations',
89 + FBOX_MEDIA_ADMIN_URL . 'js/integrations_settings.js',
90 + [],
91 + FBOX_VERSION,
92 + true
93 + );
94 + wp_enqueue_script('firebox-settings-integrations');
95 +
96 + wp_register_style(
97 + 'firebox-settings-integrations',
98 + FBOX_MEDIA_ADMIN_URL . 'css/integrations_settings.css',
99 + [],
100 + FBOX_VERSION
101 + );
102 + wp_enqueue_style('firebox-settings-integrations');
103 +
104 + $integrations = [];
105 + foreach (\FireBox\Core\Helpers\Integrations::getSettingsManagedIntegrations() as $integration)
106 + {
107 + $integrations[$integration['slug']] = [
108 + 'label' => $integration['label'],
109 + 'connected' => !empty($integration['connected']),
110 + 'locked' => !empty($integration['locked']),
111 + 'connection_type' => isset($integration['connection_type']) ? $integration['connection_type'] : 'api_key',
112 + 'docs_url' => isset($integration['docs_url']) ? $integration['docs_url'] : ''
113 + ];
114 + }
115 +
116 + $data = [
117 + 'ajax_url' => admin_url('admin-ajax.php'),
118 + 'settings_url' => admin_url('admin.php?page=firebox-settings#integrations'),
119 + 'nonce' => wp_create_nonce('fpf_js_nonce'),
120 + 'i18n' => [
121 + 'connected' => firebox()->_('FB_INTEGRATION_CONNECTED'),
122 + 'disconnected' => firebox()->_('FB_INTEGRATION_DISCONNECTED'),
123 + 'could_not_connect' => firebox()->_('FB_INTEGRATION_ERROR_CONNECT'),
124 + 'could_not_disconnect' => firebox()->_('FB_INTEGRATION_ERROR_DISCONNECT'),
125 + 'please_enter_api_key' => fpframework()->_('FPF_PLEASE_ENTER_AN_API_KEY')
126 + ],
127 + 'integrations' => $integrations
128 + ];
129 +
130 + wp_localize_script('firebox-settings-integrations', 'firebox_integrations_settings', $data);
62 131 }
63 132
64 133 /**
65 134 * Callback used to handle the processing of settings.
@@ -70,26 +139,84 @@
70 139 * @return void
71 140 */
72 141 public function processBoxSettings($input)
73 142 {
74 - // create a unique db option to use it on all plugins to fetch the geo license key
75 - $geo_license_key = '';
76 - if (isset($input['geo_license_key']) && !empty($input['geo_license_key']))
143 + if ($this->isAllowedProgrammaticSettingsUpdate())
77 144 {
78 - $geo_license_key = $input['geo_license_key'];
145 + return is_array($input) ? $input : [];
79 146 }
80 - update_option('fpf_geo_license_key', $geo_license_key);
81 147
148 + $input = is_array($input) ? $input : [];
149 + $is_settings_form_submit = isset($_POST['option_page']) && sanitize_text_field(wp_unslash($_POST['option_page'])) === self::settings_name;
150 +
151 + // Allow programmatic updates (e.g. AJAX integration connect/disconnect) without settings form nonce.
152 + if (!$is_settings_form_submit)
153 + {
154 + return $input;
155 + }
156 +
157 + // run a quick security check
158 + if (!check_admin_referer('fpf_form_nonce_firebox_settings', 'fpf_form_nonce_firebox_settings'))
159 + {
160 + return; // get out if we didn't click the Activate button
161 + }
162 +
163 + // Disable usage tracking
164 + if (!isset($input['usage_tracking']))
165 + {
166 + $tracking = new \FireBox\Core\UsageTracking\SendUsage();
167 + $tracking->stop();
168 + }
169 +
82 170
83 171
172 + // Preserve integration keys managed through AJAX connect/disconnect.
173 + $stored_settings = get_option('firebox_settings', []);
174 + $stored_settings = is_array($stored_settings) ? $stored_settings : [];
175 + foreach (\FireBox\Core\Helpers\Integrations::getSettingsKeys() as $key)
176 + {
177 + // Only a stored credential is worth carrying over. The keys are
178 + // seeded empty at install, and copying those in would add a blank
179 + // entry for every integration the site never connected.
180 + if (!array_key_exists($key, $input) && !empty($stored_settings[$key]))
181 + {
182 + $input[$key] = $stored_settings[$key];
183 + }
184 + }
185 +
84 186 // Filters the fields value
85 187 \FPFramework\Helpers\FormHelper::filterFields($input, \FireBox\Core\Admin\Forms\Settings::getSettings());
86 188
87 - add_settings_error( self::settings_name, 'settings_updated', fpframework()->_('FPF_SETTINGS_SAVED'), 'success');
189 + \FPFramework\Libs\AdminNotice::displaySuccess(fpframework()->_('FPF_SETTINGS_SAVED'));
88 190
89 191 return $input;
90 192 }
91 193
194 + /**
195 + * Allow a small set of internal settings updates to bypass the settings-form nonce.
196 + *
197 + * @return bool
198 + */
199 + private function isAllowedProgrammaticSettingsUpdate()
200 + {
201 + if (!wp_doing_ajax())
202 + {
203 + return false;
204 + }
205 +
206 + $action = isset($_REQUEST['action']) ? sanitize_key(wp_unslash($_REQUEST['action'])) : '';
207 +
208 + if ($action === '')
209 + {
210 + return false;
211 + }
212 +
213 + return in_array($action, [
214 + 'firebox_download_key_notice_activate',
215 + 'firebox_enable_usage_tracking',
216 + ], true);
217 + }
218 +
92 219
93 220
94 221 /**
95 222 * What the settings page will contain
@@ -98,9 +225,10 @@
98 225 */
99 226 public function settingsPageContent()
100 227 {
101 228 $fieldsParser = new FieldsParser([
102 - 'fields_name_prefix' => 'firebox_settings'
229 + 'fields_name_prefix' => 'firebox_settings',
230 + 'fields_path' => ['\\FireBox\\Core\\Fields\\']
103 231 ]);
104 232
105 233 $settings = \FireBox\Core\Admin\Forms\Settings::getSettings();
106 234 foreach ($settings['data'] as $key => $value)
@@ -115,17 +243,14 @@
115 243 }
116 244
117 245 // render settings as tabs
118 246 $tabs = new Tabs($settings);
119 - ob_start();
120 - $tabs->render();
121 - $html = ob_get_contents();
122 - ob_end_clean();
123 247
124 248 // render form
125 - $form = new Form($html, [
126 - 'section_name' => self::settings_name,
127 - 'vertical' => true
249 + $form = new Form($tabs->render(), [
250 + 'section_name' => self::settings_name
128 251 ]);
129 - $form->render();
252 +
253 + echo $form->render(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
130 254 }
131 -}
255 +
256 +}