PluginProbe
FireBox – WooCommerce Popup Builder, Exit Intent Popup, Email Optin & Cart Abandonment / 3.1.9
FireBox – WooCommerce Popup Builder, Exit Intent Popup, Email Optin & Cart Abandonment v3.1.9
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 1.1.1 All 122 releases
firebox / Inc / Core / Admin / Admin.php

Admin.php in FireBox – WooCommerce Popup Builder, Exit Intent Popup, Email Optin & Cart Abandonment 3.1.9, at Inc/Core/Admin/Admin.php

1,022 lines 29.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package FireBox
4 * @version 3.1.9 Free
5 *
6 * @author FirePlugins <info@fireplugins.com>
7 * @link https://www.fireplugins.com
8 * @copyright Copyright © 2026 FirePlugins All Rights Reserved
9 * @license GNU GPLv3 <http://www.gnu.org/licenses/gpl.html> or later
10 */
11
12 namespace FireBox\Core\Admin;
13
14 if (!defined('ABSPATH'))
15 {
16 exit; // Exit if accessed directly.
17 }
18
19 class Admin
20 {
21 /**
22 * Admin Page Settings
23 *
24 * @var AdminPageSettings
25 */
26 private $pageSettings;
27
28 /**
29 * Library
30 *
31 * @var Library
32 */
33 public $library;
34
35 /**
36 * Admin constructor
37 */
38 public function __construct()
39 {
40 new \FireBox\Core\Notices\Ajax();
41
42 add_action('admin_init', [$this, 'maybeExportSubmsissions']);
43
44 add_action('admin_head', [$this, 'set_gutenberg_editor_logo']);
45
46 add_action('wp_trash_post', [$this, 'on_campaign_trash'], 10, 2);
47 add_action('untrash_post', [$this, 'on_campaign_untrash'], 10, 2);
48
49
50 add_action('admin_enqueue_scripts', [$this, 'global_backend_assets'], 20);
51
52
53 add_action('current_screen', [$this, 'current_screen']);
54
55 add_action('firebox/admin/content', [$this, 'showNotices'], -5);
56
57 add_action('admin_init', [$this, 'redirectAfterActivation']);
58
59 // init dependencies
60 $this->initDependencies();
61
62 // Admin Page Settings
63 $this->pageSettings = new AdminPageSettings();
64
65 // run actions
66 $this->handleActions();
67
68 // run filters
69 $this->handleFilters();
70
71 add_action('save_post', [$this, 'onSave'], 20);
72 }
73
74 /**
75 * On Save, clear the campaign cookie if closing behavior > when closed is set to "never".
76 *
77 * @param string $post_id
78 *
79 * @return void
80 */
81 public function onSave($post_id)
82 {
83 if (!isset($_POST['post_type']) || $_POST['post_type'] !== 'firebox')
84 {
85 return;
86 }
87
88 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
89 {
90 return;
91 }
92
93 if ($parent_id = wp_is_post_revision($post_id))
94 {
95 $post_id = $parent_id;
96 }
97
98 $meta = get_post_meta($post_id, 'firebox_meta');
99
100 $assign_cookietype = isset($meta[0]['assign_cookietype']) ? $meta[0]['assign_cookietype'] : '';
101
102 if ($assign_cookietype === 'never')
103 {
104 setcookie('firebox_' . $post_id, '', time() - 3600, '/');
105 }
106 }
107
108 /**
109 * Set the FireBox logo in the Gutenberg editor.
110 *
111 * @return void
112 */
113 public function set_gutenberg_editor_logo()
114 {
115 if (get_post_type() !== 'firebox')
116 {
117 return;
118 }
119
120 ?>
121 <style>
122 @media screen and (min-width: 782px) {
123 .editor-header {
124 grid-template: auto / auto minmax(0, max-content) minmax(min-content, 1fr) 60px;
125 }
126
127 .editor-header:has(>.editor-header__center) {
128 grid-template: auto / auto minmax(min-content, 1fr) 2fr minmax(min-content, 1fr) 60px;
129 }
130 }
131 .editor-header__back-button .edit-post-fullscreen-mode-close {
132 background: transparent !important;
133 background-image: url("<?php echo esc_url(FBOX_MEDIA_ADMIN_URL); ?>images/logo_full.svg") !important;
134 background-size: 105px !important;
135 margin-right: 0 !important;
136 margin-left: 17px !important;
137 background-repeat: no-repeat !important;
138 background-position: center center !important;
139 width: 120px !important;
140 }
141 .editor-header__back-button .edit-post-fullscreen-mode-close:before,
142 .editor-header__back-button .edit-post-fullscreen-mode-close:after,
143 .editor-header__back-button img,
144 .editor-header__back-button svg {
145 display: none !important;
146 }
147 </style>
148 <?php
149 }
150
151 public function maybeExportSubmsissions()
152 {
153 if (!isset($_GET['task']) || $_GET['task'] !== 'export')
154 {
155 return;
156 }
157
158 if (!isset($_GET['form_id']))
159 {
160 return;
161 }
162
163 if (!isset($_GET['page']) || $_GET['page'] !== 'firebox-submissions')
164 {
165 return;
166 }
167
168 // Authorization: only users who can view submissions may export them.
169 if (!current_user_can('read_fireboxes'))
170 {
171 return;
172 }
173
174 // CSRF: verify the nonce generated on the submissions list page.
175 check_admin_referer('firebox-export-submissions');
176
177 $form_id = sanitize_text_field(wp_unslash($_GET['form_id']));
178
179 $export = $this->getSubmissionsForExport($form_id);
180
181 if (!$export)
182 {
183 return;
184 }
185
186 $filename = get_temp_dir() . 'submissions_' . $export['name'] . '_' . date('Y-m-d_H-i-s') . '.csv';
187 self::toCSV($export['rows'], $filename);
188
189 // Prompt to download the file
190 error_reporting(0);
191
192 // Send the appropriate headers to force the download in the browser
193 header('Content-Description: File Transfer');
194 header('Content-Type: application/octet-stream');
195 header('Content-Disposition: attachment; filename="' . basename($filename) . '"');
196 header('Expires: 0');
197 header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
198 header('Cache-Control: public', false);
199 header('Pragma: public');
200 header('Content-Length: ' . @filesize($filename));
201
202 // Clear the output buffer and disable output buffering
203 ob_clean();
204 flush();
205
206 readfile($filename);
207
208 unlink($filename);
209
210 exit;
211 }
212
213 /**
214 * Collects and prepares submission rows for CSV export.
215 * Returns the prepared rows (with the resolved form attached) or false.
216 *
217 * @param string $form_id
218 *
219 * @return array|false
220 */
221 protected function getSubmissionsForExport($form_id)
222 {
223 $payload = [
224 'where' => [
225 'form_id' => " = '" . sanitize_key($form_id) . "'",
226 'state' => ' = 1'
227 ],
228 'offset' => 0,
229 'limit' => 99999,
230 'orderby' => 'created_at ASC'
231 ];
232
233 if (!$submissions = firebox()->tables->submission->getResults($payload))
234 {
235 return false;
236 }
237
238 if (!$form = \FireBox\Core\Helpers\Form\Form::getFormByID($form_id, true))
239 {
240 return false;
241 }
242
243 // Fetch all submission meta in chunked IN() queries instead of one query per submission.
244 $submission_ids = wp_list_pluck($submissions, 'id');
245 $meta_by_submission = [];
246
247 foreach (array_chunk($submission_ids, 500) as $id_chunk)
248 {
249 $ids_in = implode(',', array_map('absint', $id_chunk));
250
251 $chunk_meta = firebox()->tables->submissionmeta->getResults([
252 'where' => [
253 'submission_id' => " IN (" . $ids_in . ")"
254 ]
255 ]);
256
257 foreach ($chunk_meta as $meta_item)
258 {
259 $meta_by_submission[$meta_item->submission_id][] = $meta_item;
260 }
261 }
262
263 $prepared = [];
264
265 foreach ($submissions as $item)
266 {
267 $prepared_payload = [
268 'id' => $item->id,
269 'created' => get_date_from_gmt($item->created_at),
270 'state' => $item->state === '1' ? 'Published' : 'Unpublished'
271 ];
272
273 $meta = isset($meta_by_submission[$item->id]) ? $meta_by_submission[$item->id] : [];
274
275 if ($meta && $form['fields'])
276 {
277 foreach ($form['fields'] as $field)
278 {
279 foreach ($meta as $meta_item)
280 {
281 if ($field->getOptionValue('id') === $meta_item->meta_key)
282 {
283 $prepared_payload[$field->getOptionValue('name')] = $field->prepareValue($meta_item->meta_value);
284 }
285 }
286 }
287 }
288
289 $prepared[] = $prepared_payload;
290 }
291
292 return ['name' => $form['name'], 'rows' => $prepared];
293 }
294
295 /**
296 * Create a CSV file with given data
297 *
298 * @param array $data The data to populate the file
299 * @param string $destination The path where the store the CSV file
300 * @param bool $append If true, given data will be appended to the end of the file.
301 * @param boolean $excel_security If enabled, certain row values will be prefixed by a tab to avoid any CSV injection.
302 *
303 * @return void
304 */
305 private static function toCSV($data, $destination, $append = false, $excel_security = true, $check_for_duplicates = true)
306 {
307 $resource = fopen($destination, $append ? 'a+' : 'w');
308
309 if (!$append)
310 {
311 // Support UTF-8 on Microsoft Excel
312 fputs($resource, "\xEF\xBB\xBF");
313
314 // Add column names in the first line
315 fputcsv($resource, array_keys($data[0]), ',', '"', '\\');
316 }
317
318 // Get CSV content
319 $existingRows = [];
320 if ($append && $check_for_duplicates)
321 {
322 while (($existingData = fgetcsv($resource)) !== false)
323 {
324 $existingRows[(int) $existingData[0]] = $existingData;
325 }
326 }
327
328 foreach ($data as $row)
329 {
330 if (!empty($existingRows) && isset($row['id']) && array_key_exists($row['id'], $existingRows))
331 {
332 continue;
333 }
334
335 // Prevent CSV Injection: https://vel.joomla.org/articles/2140-introducing-csv-injection
336 if ($excel_security)
337 {
338 foreach ($row as &$value)
339 {
340 $value = is_array($value) ? implode(', ', $value) : $value;
341
342 $firstChar = substr($value, 0, 1);
343
344 // Prefixe values starting with a =, +, - or @ by a tab character
345 if (in_array($firstChar, array('=', '+', '-', '@')))
346 {
347 $value = ' ' . $value;
348 }
349 }
350 }
351
352 fputcsv($resource, $row, ',', '"', '\\');
353 }
354
355 fclose($resource);
356 }
357
358 /**
359 * Fires when a campaign is trashed.
360 *
361 * @param int $post_id
362 * @param string $previous_status
363 *
364 * @return void
365 */
366 public function on_campaign_trash($post_id, $previous_status)
367 {
368 $post_type = get_post_type($post_id);
369 $post_status = get_post_status($post_id);
370
371 if ($post_type === 'firebox' && $post_status === 'draft')
372 {
373 \FPFramework\Libs\AdminNotice::displaySuccess(firebox()->_('FB_CAMPAIGN_HAS_BEEN_TRASHED'));
374 }
375 }
376
377 /**
378 * Fires when a campaign is untrashed.
379 *
380 * @param int $post_id
381 * @param string $previous_status
382 *
383 * @return void
384 */
385 public function on_campaign_untrash($post_id, $previous_status)
386 {
387 $post_type = get_post_type($post_id);
388 $post_status = get_post_status($post_id);
389
390 if ($post_type === 'firebox' && $post_status === 'trash')
391 {
392 \FPFramework\Libs\AdminNotice::displaySuccess(firebox()->_('FB_CAMPAIGN_HAS_BEEN_RESTORED'));
393 }
394 }
395
396 public function showNotices()
397 {
398 \FireBox\Core\Notices\Notices::getInstance()->show();
399 }
400
401
402 public function global_backend_assets()
403 {
404 wp_register_style(
405 'firebox-admin-lite',
406 FBOX_MEDIA_ADMIN_URL . 'css/lite.css',
407 [],
408 FBOX_VERSION,
409 false
410 );
411 wp_enqueue_style('firebox-admin-lite');
412 }
413
414
415 public function current_screen($screen)
416 {
417 add_action('admin_enqueue_scripts', [$this, 'registerEditorMedia'], 11);
418 add_action('enqueue_block_assets', [$this, 'registerCampaignEditorAssets'], 12);
419
420 // Check for classic editor with firebox post type
421 if (isset($screen->id) && $screen->id === 'firebox' && !$screen->is_block_editor) {
422 add_action('admin_notices', [$this, 'showClassicEditorNotice']);
423 }
424
425 $allowed_pages = [
426 'toplevel_page_firebox',
427 'firebox_page_firebox-campaigns',
428 'firebox_page_firebox-analytics',
429 'firebox_page_firebox-submissions',
430 'firebox_page_firebox-settings',
431 'firebox_page_firebox-import'
432 ];
433
434 if (isset($screen->id) && in_array($screen->id, $allowed_pages))
435 {
436 add_action('admin_enqueue_scripts', [$this, 'registerMediaAdminPages'], 20);
437
438 add_filter('admin_footer_text', [$this, 'admin_footer_text']);
439 }
440 }
441
442 /**
443 * Shows a notice when using classic editor with firebox post type
444 *
445 * @return void
446 */
447 public function showClassicEditorNotice()
448 {
449 ?>
450 <div class="notice notice-warning">
451 <p><?php echo esc_html(firebox()->_('FB_CLASSIC_EDITOR_NOT_SUPPORTED')); ?></p>
452 </div>
453 <?php
454 }
455
456 public function registerEditorMedia()
457 {
458 wp_register_script('firebox-admin-editor', false);
459 wp_enqueue_script('firebox-admin-editor');
460
461 $data = [
462 'media_url' => FBOX_MEDIA_URL,
463 'timezone' => $this->getTimezone(),
464 'license_type' => FBOX_LICENSE_TYPE,
465 'license_plan' => FBOX_LICENSE_PLAN,
466 'langs' => [
467 'LITE' => fpframework()->_('FPF_LITE'),
468 ]
469 ];
470
471 wp_localize_script('firebox-admin-editor', 'fbox_admin_editor_js_object', $data);
472 }
473
474 public function registerCampaignEditorAssets()
475 {
476 if (!is_admin())
477 {
478 return;
479 }
480
481 // Enqueue block editor style only in Gutenberg editor
482 if (!function_exists('get_current_screen'))
483 {
484 return;
485 }
486
487 $screen = get_current_screen();
488 if (!$screen->is_block_editor)
489 {
490 return;
491 }
492
493 wp_enqueue_script(
494 'firebox-helper-store',
495 FBOX_MEDIA_ADMIN_URL . 'js/blocks/helper_store.js',
496 ['wp-data'],
497 FBOX_VERSION,
498 false
499 );
500
501 wp_enqueue_style(
502 'firebox-blocks',
503 FBOX_MEDIA_PUBLIC_URL . 'css/blocks.css',
504 [],
505 FBOX_VERSION
506 );
507
508 $css = '
509 :root {
510 --firebox-editor-background-image: url(' . FBOX_MEDIA_ADMIN_URL . 'images/browser-bg.png);
511 }
512 ';
513 wp_add_inline_style('firebox-blocks', $css);
514
515 if (get_post_type() !== 'firebox')
516 {
517 return;
518 }
519
520 wp_register_script('firebox-campaign-editor', false);
521 wp_enqueue_script('firebox-campaign-editor');
522
523 $data = [
524 'plugins' => [
525 'wpml_active' => \is_plugin_active('sitepress-multilingual-cms/sitepress.php'),
526 'edd_active' => \is_plugin_active('easy-digital-downloads/easy-digital-downloads.php') || \is_plugin_active('easy-digital-downloads-pro/easy-digital-downloads.php'),
527 'woo_active' => \is_plugin_active('woocommerce/woocommerce.php')
528 ],
529 'geolocation_updated' => !\FPFramework\Helpers\Geolocation::geoNeedsUpdate(),
530 'geolocation_update_url' => admin_url('admin.php?page=firebox-settings#geolocation'),
531 'geolocation_city_notice' => (new \FPFramework\Base\Conditions\Conditions\Geo\City())->getValueHint(),
532 'geolocation_country_notice' => (new \FPFramework\Base\Conditions\Conditions\Geo\Country())->getValueHint(),
533 'geolocation_region_notice' => (new \FPFramework\Base\Conditions\Conditions\Geo\Region())->getValueHint(),
534 'geolocation_continent_notice' => (new \FPFramework\Base\Conditions\Conditions\Geo\Continent())->getValueHint(),
535 'countries_list' => \FPFramework\Helpers\CountriesHelper::getCountriesList(),
536 'user_ip' => \FPFramework\Base\User::getIP(),
537 'currency' => $this->getCurrency()
538 ];
539
540 wp_localize_script('firebox-campaign-editor', 'firebox_campaign_editor', $data);
541 }
542
543 /**
544 * Returns the current eCommerce solution's currency.
545 *
546 * @return string
547 */
548 private function getCurrency()
549 {
550 $output = '';
551
552 $eddActive = \is_plugin_active('easy-digital-downloads/easy-digital-downloads.php') || \is_plugin_active('easy-digital-downloads-pro/easy-digital-downloads.php');
553 if ($eddActive)
554 {
555 $output = \edd_get_currency();
556 }
557 else
558 {
559 $wooActive = \is_plugin_active('woocommerce/woocommerce.php');
560 if ($wooActive)
561 {
562 $output = \get_woocommerce_currency();
563 }
564 }
565
566 return $output;
567 }
568
569 public function admin_footer_text()
570 {
571 return;
572 }
573
574 /**
575 * Load admin dependencies.
576 *
577 * @return void
578 */
579 private function initDependencies()
580 {
581 new Media();
582
583 $this->library = firebox()->library;
584 }
585
586 /**
587 * Runs all Admin Actions
588 *
589 * @return void
590 */
591 private function handleActions()
592 {
593 add_action('admin_enqueue_scripts', [$this, 'registerGlobalMedia'], 20);
594
595
596 add_filter('plugin_action_links_' . plugin_basename(FBOX_PLUGIN_BASE_FILE), [$this, 'plugin_action_links']);
597
598 }
599
600 public function registerGlobalMedia()
601 {
602 wp_register_style('firebox-global-admin', false);
603 wp_enqueue_style('firebox-global-admin');
604 $css = '
605 #adminmenu li.toplevel_page_firebox .wp-menu-image {
606 padding: 4px 0 0 0;
607 height: auto;
608 }
609 #adminmenu li.toplevel_page_firebox img {
610 width: 20px !important;
611 padding: 0;
612 padding-top: 3px !important;
613 }
614 ';
615 wp_add_inline_style('firebox-global-admin', $css);
616 }
617
618
619 /**
620 * Adds extra links to the Plugins page in the free version.
621 * - Upgrade to Pro button
622 *
623 * @param array $links
624 *
625 * @return array
626 */
627 public function plugin_action_links($links)
628 {
629 $links = array_merge( $links, array(
630 '<a href="' . sprintf(FBOX_GO_PRO_URL, 'pro') . '" class="firebox-go-pro-link" title="' . fpframework()->_('FPF_UNLOCK_MORE_FEATURES_WITH_PRO_READ_MORE') . '">' . firebox()->_('FB_UPGRADE_20_OFF') . '</a>'
631 ) );
632
633 return $links;
634 }
635
636
637 /**
638 * Runs all Admin Filters
639 *
640 * @return void
641 */
642 private function handleFilters()
643 {
644 add_filter('admin_body_class', [$this, 'setPluginPageBodyClass']);
645 add_filter('plugin_row_meta' , [$this, 'addPluginMetaLinks'], 10, 4);
646 }
647
648 /**
649 * Adds extra links to the plugins page.
650 *
651 * @param array $links
652 * @param string $file
653 * @param array $plugin_data
654 * @param string $status
655 *
656 * @return array
657 */
658 public function addPluginMetaLinks($links, $file, $plugin_data, $status)
659 {
660 if ($file === FBOX_PLUGIN_BASENAME)
661 {
662 $links['rate'] = '<a href="https://wordpress.org/support/plugin/firebox/reviews/#new-post" aria-label="' . esc_attr(firebox()->_('FB_RATE_FIREBOX')) . '" target="_blank">' . esc_html(firebox()->_('FB_RATE_FIREBOX')) . '</a>';
663 $links['support'] = '<a href="' . \FPFramework\Base\Functions::getUTMURL('https://www.fireplugins.com/contact/', '', 'misc', 'support') . '" aria-label="' . esc_attr(fpframework()->_('FPF_SUPPORT')) . '" target="_blank">' . esc_html(fpframework()->_('FPF_SUPPORT')) . '</a>';
664 }
665
666 return $links;
667 }
668
669 /**
670 * Sets a class to the body of the FireBox Admin Pages
671 *
672 * @return string
673 */
674 public function setPluginPageBodyClass($classes)
675 {
676 if (!$this->isPluginPage())
677 {
678 return $classes;
679 }
680
681 $classes .= ' fpf-admin-page fpf-firebox-page';
682
683 if ($this->isControllerPage())
684 {
685 $classes .= ' fpf-controller-page';
686 }
687
688 // Set admin template theme class
689 $fireplugins_theme = isset($_COOKIE['fireplugins_theme']) ? sanitize_key($_COOKIE['fireplugins_theme']) : 'light';
690 $classes .= ' ' . $fireplugins_theme;
691
692 // Set admin template sidebar toggle class
693 $sidebar_state = isset($_COOKIE['fireplugins_sidebar_state']) ? sanitize_key($_COOKIE['fireplugins_sidebar_state']) : 'expand';
694 $classes .= ' ' . ($sidebar_state === 'expand' ? 'fpf-admin-sidebar-expand' : 'fpf-admin-sidebar-shrink');
695
696 return $classes;
697 }
698
699 /**
700 * Checks if we are in a plugin page
701 *
702 * @return boolean
703 */
704 private function isPluginPage()
705 {
706 if (in_array($this->getPageNow(), ['edit.php', 'post-new.php']) && isset($_GET['post_type']) && $_GET['post_type'] == 'firebox') //phpcs:ignore WordPress.Security.NonceVerification.Recommended
707 {
708 return true;
709 }
710
711 if ($this->getPageNow() == 'post.php')
712 {
713 return true;
714 }
715
716 if ($this->isControllerPage())
717 {
718 return true;
719 }
720
721 return false;
722 }
723
724 /**
725 * Whether we are browsing a plugin page from the plugin's menu
726 *
727 * @return boolean
728 */
729 private function isControllerPage()
730 {
731 if (!firebox()->menu)
732 {
733 return false;
734 }
735
736 $current_plugin_page = fpframework()->getPluginPage();
737 $plugin_menu_items = firebox()->menu->getPluginMenuItems();
738
739 // Only set the class to the plugin pages
740 return $this->getPageNow() == 'admin.php' && in_array($current_plugin_page, $plugin_menu_items);
741 }
742
743 /**
744 * Returns page now
745 *
746 * @return string
747 */
748 protected function getPageNow()
749 {
750 global $pagenow;
751 return $pagenow;
752 }
753
754 /**
755 * Registers CSS and JS files
756 *
757 * @return void
758 */
759 public function registerMediaAdminPages()
760 {
761 $this->registerStyles();
762 $this->registerScripts();
763 }
764
765 /**
766 * Register admin styles.
767 *
768 * @return void
769 */
770 public function registerStyles()
771 {
772 // load dashicons
773 wp_enqueue_style('dashicons');
774
775 // firebox main admin css
776 wp_register_style(
777 'firebox-admin',
778 FBOX_MEDIA_ADMIN_URL . 'css/firebox.css',
779 [],
780 FBOX_VERSION,
781 false
782 );
783 wp_enqueue_style('firebox-admin');
784
785 // firebox admin design
786 wp_register_style(
787 'firebox-design-admin',
788 FBOX_MEDIA_ADMIN_URL . 'css/firebox_design.css',
789 [],
790 FBOX_VERSION,
791 false
792 );
793 wp_enqueue_style('firebox-design-admin');
794
795 $css = '
796 :root {
797 --fpf-templates-library-header-logo: url(' . FBOX_MEDIA_ADMIN_URL . 'images/logo.svg);
798 }
799 ';
800 wp_add_inline_style('firebox-admin', $css);
801 }
802
803 /**
804 * Registers admin scripts.
805 *
806 * @return void
807 */
808 public function registerScripts()
809 {
810 wp_register_script('firebox-admin', false);
811 wp_enqueue_script('firebox-admin');
812
813
814
815 $data = array(
816 'campaigns_item_new_url' => admin_url('post-new.php?post_type=firebox'),
817 'campaigns_list_url' => admin_url('admin.php?page=firebox-campaigns'),
818 'campaigns_item_edit_url' => admin_url('post.php?post={{ID}}&action=edit'),
819 'campaigns_item_analytics_url' => admin_url('admin.php?page=firebox-analytics&campaign={{ID}}'),
820 'campaigns_analytics_url' => admin_url('admin.php?page=firebox-analytics'),
821 'submissions_page' => admin_url('admin.php?page=firebox-submissions'),
822 'flags_url' => FBOX_PLUGIN_URL . 'Inc/Framework/media/admin/images/flags/{{FLAG}}.png',
823 'license_type' => FBOX_LICENSE_TYPE,
824 'license_plan' => FBOX_LICENSE_PLAN,
825
826
827 'langs' => [
828 'CAMPAIGN_INFO' => firebox()->_('FB_CAMPAIGN_INFO'),
829 'EDIT_CAMPAIGN' => firebox()->_('FB_EDIT_CAMPAIGN'),
830 'STATUS' => fpframework()->_('FPF_STATUS'),
831 'CREATED' => fpframework()->_('FPF_CREATED'),
832 'LAST_VIEWED' => firebox()->_('FB_LAST_VIEWED'),
833 'ACTIVE' => firebox()->_('FB_ACTIVE'),
834 'DISABLED' => fpframework()->_('FPF_DISABLED'),
835 'ID' => fpframework()->_('FPF_ID'),
836 'CAMPAIGN' => firebox()->_('FB_CAMPAIGN'),
837 'VIEW' => firebox()->_('FB_VIEW'),
838 'VIEWS' => firebox()->_('FB_VIEWS'),
839 'CLICK' => firebox()->_('FB_CLICK'),
840 'CLICKS' => firebox()->_('FB_CLICKS'),
841 'ACTIONS' => firebox()->_('FB_ACTIONS'),
842 'CONVERSION' => firebox()->_('FB_CONVERSION'),
843 'CONVERSIONS' => firebox()->_('FB_CONVERSIONS'),
844 'CONVERSION_RATE' => firebox()->_('FB_CONVERSION_RATE'),
845 'NO_DATA_AVAILABLE' => firebox()->_('FB_NO_DATA_AVAILABLE'),
846 'COUNTRIES' => fpframework()->_('FPF_COUNTRIES'),
847 'FLAG' => fpframework()->_('FPF_FLAG'),
848 'DEVICES' => fpframework()->_('FPF_DEVICES'),
849 'EVENTS' => fpframework()->_('FPF_EVENTS'),
850 'PERCENTAGE_DIFFERENCE_AGAINST_PREVIOUS_PERIOD' => firebox()->_('FB_PERCENTAGE_DIFFERENCE_AGAINST_PREVIOUS_PERIOD'),
851 'NO_CAMPAIGN_DATA_FOUND' => firebox()->_('FB_NO_CAMPAIGN_DATA_FOUND'),
852 'MOST_POPULAR_CAMPAIGNS' => firebox()->_('FB_MOST_POPULAR_CAMPAIGNS'),
853 'TOP_CAMPAIGNS' => firebox()->_('FB_TOP_CAMPAIGNS'),
854 'N/A' => fpframework()->_('FPF_N/A'),
855 'ALL_DAYS' => firebox()->_('FB_ALL_DAYS'),
856 'MONDAY' => firebox()->_('FB_MONDAY'),
857 'TUESDAY' => firebox()->_('FB_TUESDAY'),
858 'WEDNESDAY' => firebox()->_('FB_WEDNESDAY'),
859 'THURSDAY' => firebox()->_('FB_THURSDAY'),
860 'FRIDAY' => firebox()->_('FB_FRIDAY'),
861 'SATURDAY' => firebox()->_('FB_SATURDAY'),
862 'SUNDAY' => firebox()->_('FB_SUNDAY'),
863 'VIEW_HOURS' => firebox()->_('FB_VIEW_HOURS'),
864 'PATHS' => fpframework()->_('FPF_PATHS'),
865 'REFERRERS' => fpframework()->_('FPF_REFERRERS'),
866 'S' => fpframework()->_('FPF_S'),
867 'VIEW_CAMPAIGN_ANALYTICS' => firebox()->_('FB_VIEW_CAMPAIGN_ANALYTICS'),
868 'ACTIVATE' => fpframework()->_('FPF_ACTIVATE'),
869 'DEACTIVATE' => fpframework()->_('FPF_DEACTIVATE'),
870 'EDIT' => fpframework()->_('FPF_EDIT'),
871 'DELETE' => fpframework()->_('FPF_DELETE'),
872 'DUPLICATE' => fpframework()->_('FPF_DUPLICATE'),
873 'ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_CAMPAIGN' => firebox()->_('FB_ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_CAMPAIGN'),
874 'RECENT_CAMPAIGNS' => firebox()->_('FB_RECENT_CAMPAIGNS'),
875 'VIEW_ALL' => firebox()->_('FB_VIEW_ALL'),
876 'YOU_HAVENT_CREATED_ANY_CAMPAIGNS_YET' => firebox()->_('FB_YOU_HAVENT_CREATED_ANY_CAMPAIGNS_YET'),
877 'NEW_CAMPAIGN' => firebox()->_('FB_NEW_CAMPAIGN'),
878 'NUMBER_OF_VIEWS_IN_THE_LAST_30_DAYS' => firebox()->_('FB_NUMBER_OF_VIEWS_IN_THE_LAST_30_DAYS'),
879 'NUMBER_OF_CONVERSIONS_IN_THE_LAST_30_DAYS' => firebox()->_('FB_NUMBER_OF_CONVERSIONS_IN_THE_LAST_30_DAYS'),
880 'CONVERSION_RATE_IN_THE_LAST_30_DAYS' => firebox()->_('FB_CONVERSION_RATE_IN_THE_LAST_30_DAYS'),
881 'LOADING_CAMPAIGNS' => firebox()->_('FB_LOADING_CAMPAIGNS'),
882 'NO_CAMPAIGNS_FOUND' => firebox()->_('FB_NO_CAMPAIGNS_FOUND'),
883 'SEARCH_DOTS' => firebox()->_('FB_SEARCH_DOTS'),
884 'TODAY' => firebox()->_('FB_TODAY'),
885 'YESTERDAY' => firebox()->_('FB_YESTERDAY'),
886 'LAST_7_DAYS' => firebox()->_('FB_LAST_7_DAYS'),
887 'LAST_30_DAYS' => firebox()->_('FB_LAST_30_DAYS'),
888 'LAST_WEEK' => firebox()->_('FB_LAST_WEEK'),
889 'MONTH_TO_DATE' => firebox()->_('FB_MONTH_TO_DATE'),
890 'LAST_MONTH' => firebox()->_('FB_LAST_MONTH'),
891 'YEAR_TO_DATE' => firebox()->_('FB_YEAR_TO_DATE'),
892 'CUSTOM' => firebox()->_('FB_CUSTOM'),
893 'READ_MORE' => firebox()->_('FB_READ_MORE'),
894 'AVG_TIME_OPEN' => firebox()->_('FB_AVG_TIME_OPEN'),
895 'CONVERSION_RATE_TOOLTIP_DESC' => firebox()->_('FB_CONVERSION_RATE_TOOLTIP_DESC'),
896 'CONVERSIONS_TOOLTIP_DESC' => firebox()->_('FB_CONVERSIONS_TOOLTIP_DESC'),
897 'VS_PREVIOUS_PERIOD' => firebox()->_('FB_VS_PREVIOUS_PERIOD'),
898 'VIEWS_TOOLTIP_DESC' => firebox()->_('FB_VIEWS_TOOLTIP_DESC'),
899 'NO' => firebox()->_('FB_NO'),
900 'DATA_AVAILABLE' => firebox()->_('FB_DATA_AVAILABLE'),
901 'PERFORMANCE' => firebox()->_('FB_PERFORMANCE'),
902 'TRENDING_TEMPLATES' => firebox()->_('FB_TRENDING_TEMPLATES'),
903 'THERE_ARE_NO_TRENDING_TEMPLATES_TO_SHOW' => firebox()->_('FB_THERE_ARE_NO_TRENDING_TEMPLATES_TO_SHOW'),
904 'INSERT_TEMPLATE' => firebox()->_('FB_INSERT_TEMPLATE'),
905 'INSERT' => firebox()->_('FB_INSERT'),
906 'VIEW_ALL_ANALYTICS' => firebox()->_('FB_VIEW_ALL_ANALYTICS'),
907 'DAILY' => firebox()->_('FB_DAILY'),
908 'WEEKLY' => firebox()->_('FB_WEEKLY'),
909 'MONTHLY' => firebox()->_('FB_MONTHLY'),
910 'UPGRADE_TO_PRO' => fpframework()->_('FPF_UPGRADE_TO_PRO'),
911 'ALL_CAMPAIGNS' => firebox()->_('FB_ALL_CAMPAIGNS'),
912 'OVERVIEW' => fpframework()->_('FPF_OVERVIEW'),
913 'TO' => fpframework()->_('FPF_TO'),
914 'SHOWING_TOP_30_RESULTS' => firebox()->_('FB_SHOWING_TOP_30_RESULTS'),
915 'DAY_OF_THE_WEEK' => firebox()->_('FB_DAY_OF_THE_WEEK'),
916 'ANALYTICS' => fpframework()->_('FPF_ANALYTICS'),
917 'SALES_FUNNEL' => firebox()->_('FB_SALES_FUNNEL'),
918 'SALES_FUNNEL_LOCKED_COPY' => firebox()->_('FB_SALES_FUNNEL_LOCKED_COPY'),
919 'PURCHASE' => firebox()->_('FB_PURCHASE'),
920 'PURCHASES' => firebox()->_('FB_PURCHASES'),
921 'INTERACTIONS' => firebox()->_('FB_INTERACTIONS'),
922 'FUNNEL_VISUALIZATION' => firebox()->_('FB_FUNNEL_VISUALIZATION'),
923 'OVERALL_CONVERSION_RATE' => firebox()->_('FB_OVERALL_CONVERSION_RATE'),
924 'REVENUE_CONVERSIONS' => firebox()->_('FB_REVENUE_CONVERSIONS'),
925 'LITE' => fpframework()->_('FPF_LITE'),
926 'FREE' => fpframework()->_('FPF_FREE'),
927 'FROM' => firebox()->_('FB_FROM'),
928 'OF' => firebox()->_('FB_OF'),
929 'USERS' => firebox()->_('FB_USERS'),
930 'TOTAL' => firebox()->_('FB_TOTAL'),
931 'TOTAL_POPUP_IMPRESSIONS' => firebox()->_('FB_TOTAL_POPUP_IMPRESSIONS'),
932 'REVENUE' => firebox()->_('FB_REVENUE'),
933 'REVENUE_TOOLTIP_DESC' => firebox()->_('FB_REVENUE_TOOLTIP_DESC'),
934 'VIEW_THROUGH_REVENUE' => firebox()->_('FB_VIEW_THROUGH_REVENUE'),
935 'VIEW_THROUGH_REVENUE_TOOLTIP_DESC' => firebox()->_('FB_VIEW_THROUGH_REVENUE_TOOLTIP_DESC'),
936 'CONVERSION_THROUGH_REVENUE' => firebox()->_('FB_CONVERSION_THROUGH_REVENUE'),
937 'CONVERSION_THROUGH_REVENUE_TOOLTIP_DESC' => firebox()->_('FB_CONVERSION_THROUGH_REVENUE_TOOLTIP_DESC'),
938 'REVENUE_ROI' => firebox()->_('FB_REVENUE_ROI'),
939 'REVENUE_ROI_TOOLTIP_TITLE' => firebox()->_('FB_REVENUE_ROI_TOOLTIP_TITLE'),
940 'REVENUE_ROI_TOTAL_REVENUE_GENERATED' => firebox()->_('FB_REVENUE_ROI_TOTAL_REVENUE_GENERATED'),
941 'REVENUE_ROI_LITE_MESSAGE' => firebox()->_('FB_REVENUE_ROI_LITE_MESSAGE'),
942 'REVENUE_ROI_PRO_MESSAGE' => firebox()->_('FB_REVENUE_ROI_PRO_MESSAGE'),
943 'LAST_4_WEEKS' => firebox()->_('FB_LAST_4_WEEKS'),
944 'LAST_6_MONTHS' => firebox()->_('FB_LAST_6_MONTHS'),
945 'LAST_12_MONTHS' => firebox()->_('FB_LAST_12_MONTHS'),
946 'QUARTER_TO_DATE' => firebox()->_('FB_QUARTER_TO_DATE'),
947 'AVAILABLE_IN_PRO' => firebox()->_('FB_AVAILABLE_IN_PRO'),
948 'PLAN_COST' => firebox()->_('FB_PLAN_COST'),
949 'LIFETIME_REVENUE' => firebox()->_('FB_LIFETIME_REVENUE'),
950 'YOUR_ROI' => firebox()->_('FB_YOUR_ROI'),
951 'UNLOCK_REVENUE_ROI' => firebox()->_('FB_UNLOCK_REVENUE_ROI'),
952 'GROWTH' => firebox()->_('FB_GROWTH'),
953 'AVAILABLE_IN' => firebox()->_('FB_AVAILABLE_IN'),
954 'PRO' => firebox()->_('FB_PRO'),
955 'BASIC' => firebox()->_('FB_BASIC'),
956 'UPGRADE_TO_X' => fpframework()->_('FPF_UPGRADE_TO_X'),
957 'UPGRADE_TO_X_PLAN' => fpframework()->_('FPF_UPGRADE_TO_X_PLAN'),
958 'FEATURE_AVAILABLE_IN_X_PLAN' => firebox()->_('FB_FEATURE_AVAILABLE_IN_X_PLAN'),
959 'SORRY_FEATURE_NOT_AVAILABLE_IN_YOUR_PLAN' => fpframework()->_('FPF_SORRY_FEATURE_NOT_AVAILABLE_IN_YOUR_PLAN'),
960 'PRO_MODAL_IS_PRO_FEATURE' => fpframework()->_('FPF_PRO_MODAL_IS_PRO_FEATURE'),
961 'PRO_MODAL_WERE_SORRY' => fpframework()->_('FPF_PRO_MODAL_WERE_SORRY'),
962 'PRO_MODAL_PERCENTAGE_OFF' => fpframework()->_('FPF_PRO_MODAL_PERCENTAGE_OFF'),
963 'CLICKS_TOOLTIP_DESC' => firebox()->_('FB_CLICKS_TOOLTIP_DESC'),
964 'VIEW_REVENUE' => firebox()->_('FB_VIEW_REVENUE'),
965 'CONVERSION_REVENUE' => firebox()->_('FB_CONVERSION_REVENUE'),
966 ]
967 );
968
969 wp_localize_script('firebox-admin', 'fbox_admin_js_object', $data);
970 }
971
972 /**
973 * Returns the timezone in format: +-XX:XX
974 *
975 * @return string
976 */
977 private function getTimezone()
978 {
979 $offset = get_option('gmt_offset');
980 $hours = (int) $offset;
981 $minutes = abs(($offset - (int) $offset) * 60);
982 return sprintf('%+03d:%02d', $hours, $minutes);
983 }
984
985
986
987
988
989 /**
990 * Redirect to FireBox dashboard after plugin activation
991 *
992 * @return void
993 */
994 public function redirectAfterActivation()
995 {
996 // Check if activation redirect option exists
997 if (!get_option('firebox_activation_redirect'))
998 {
999 return;
1000 }
1001
1002 // Clear the option
1003 delete_option('firebox_activation_redirect');
1004
1005 // Only redirect on the plugins page
1006 if (!isset($_GET['activate'])) //phpcs:ignore WordPress.Security.NonceVerification.Recommended
1007 {
1008 return;
1009 }
1010
1011 // Prevent redirect if activating multiple plugins
1012 if (is_network_admin() || isset($_GET['activate-multi'])) //phpcs:ignore WordPress.Security.NonceVerification.Recommended
1013 {
1014 return;
1015 }
1016
1017 // Redirect to FireBox dashboard
1018 wp_safe_redirect(admin_url('admin.php?page=firebox'));
1019 exit;
1020 }
1021 }
1022