PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.11.4
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.11.4
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 All 149 releases
← All changes | classes/Visualizer/Module/Admin.php +91 -464 4.0.43.11.4 View file →
@@ -29,10 +29,8 @@
29 29 class Visualizer_Module_Admin extends Visualizer_Module {
30 30
31 31 const NAME = __CLASS__;
32 32
33 - const OPTION_GLOBAL_SETTINGS = 'visualizer_global_settings';
34 -
35 33 /**
36 34 * Library page suffix.
37 35 *
38 36 * @since 1.0.0
@@ -42,24 +40,8 @@
42 40 */
43 41 private $_libraryPage;
44 42
45 43 /**
46 - * Support page suffix.
47 - *
48 - * @access private
49 - * @var string
50 - */
51 - private $_supportPage;
52 -
53 - /**
54 - * Settings page suffix.
55 - *
56 - * @access private
57 - * @var string
58 - */
59 - private $_settingsPage;
60 -
61 - /**
62 44 * Constructor.
63 45 *
64 46 * @since 1.0.0
65 47 *
@@ -73,11 +55,8 @@
73 55 $this->_addAction( 'load-post-new.php', 'enqueueMediaScripts' );
74 56 $this->_addAction( 'enqueue_block_editor_assets', 'enqueueMediaScripts' );
75 57 $this->_addAction( 'admin_footer', 'renderTemplates' );
76 58 $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 0 );
77 - $this->_addAction( 'admin_enqueue_scripts', 'enqueue_support_page' );
78 - $this->_addAction( 'admin_enqueue_scripts', 'enqueueSettingsScripts' );
79 - $this->_addAction( 'admin_post_visualizer_save_global_settings', 'saveGlobalSettings' );
80 59 $this->_addAction( 'admin_menu', 'registerAdminMenu' );
81 60 $this->_addFilter( 'media_view_strings', 'setupMediaViewStrings' );
82 61 $this->_addFilter( 'plugin_action_links', 'getPluginActionLinks', 10, 2 );
83 62 $this->_addFilter( 'plugin_row_meta', 'getPluginMetaLinks', 10, 2 );
@@ -82,9 +61,8 @@
82 61 $this->_addFilter( 'plugin_action_links', 'getPluginActionLinks', 10, 2 );
83 62 $this->_addFilter( 'plugin_row_meta', 'getPluginMetaLinks', 10, 2 );
84 63 $this->_addFilter( 'visualizer_logger_data', 'getLoggerData' );
85 64 $this->_addFilter( 'visualizer_feedback_review_trigger', 'feedbackReviewTrigger' );
86 - $this->_addFilter( 'themeisle_sdk_blackfriday_data', 'add_black_friday_data' );
87 65
88 66 // screen pagination
89 67 $this->_addFilter( 'set-screen-option', 'setScreenOptions', 10, 3 );
90 68
@@ -100,15 +78,12 @@
100 78 $this->_addAction( 'visualizer_chart_languages', 'addMultilingualSupport' );
101 79
102 80 $this->_addFilter( 'admin_footer_text', 'render_review_notice' );
103 81
104 - if ( ! defined( 'TI_E2E_TESTING' ) ) {
105 - $this->_addFilter( 'themeisle-sdk/survey/' . VISUALIZER_DIRNAME, 'get_survey_metadata', 10, 2 );
82 + if ( defined( 'TI_CYPRESS_TESTING' ) ) {
83 + $this->load_cypress_hooks();
106 84 }
107 85
108 - if ( defined( 'TI_E2E_TESTING' ) ) {
109 - $this->load_cypress_hooks();
110 - }
111 86 }
112 87 /**
113 88 * Display review notice.
114 89 */
@@ -114,19 +89,18 @@
114 89 */
115 90 public function render_review_notice( $footer_text ) {
116 91 $current_screen = get_current_screen();
117 92
118 - $visualizer_page_ids = array( 'toplevel_page_visualizer', 'visualizer_page_viz-support', 'visualizer_page_ti-about-visualizer' );
93 + $visualizer_page_ids = ['toplevel_page_visualizer', 'visualizer_page_viz-support', 'visualizer_page_ti-about-visualizer' ];
119 94
120 95 if ( ! empty( $current_screen ) && isset( $current_screen->id ) ) {
121 96 foreach ( $visualizer_page_ids as $page_to_check ) {
122 97 if ( strpos( $current_screen->id, $page_to_check ) !== false ) {
123 98 $footer_text = sprintf(
124 - // translators: %1$s - the name of the plugin (Visualizer), %2$s - message (You can help us by leaving a), %3$s - HTML entity code.
125 99 __( 'Enjoying %1$s? %2$s %3$s rating. Thank you for being so supportive!', 'visualizer' ),
126 100 '<b>Visualizer</b>',
127 101 esc_html__( 'You can help us by leaving a', 'visualizer' ),
128 - '<a href="https://wordpress.org/support/plugin/visualizer/reviews/#new-post" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
102 + '<a href="https://wordpress.org/support/plugin/visualizer/reviews/" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
129 103 );
130 104 break;
131 105 }
132 106 }
@@ -144,9 +118,9 @@
144 118 */
145 119 private function load_cypress_hooks() {
146 120 // all charts should load on the same page without pagination.
147 121 add_filter(
148 - 'visualizer_query_args', function ( $args ) {
122 + 'visualizer_query_args', function( $args ) {
149 123 $args['posts_per_page'] = 20;
150 124 return $args;
151 125 }, 10, 1
152 126 );
@@ -263,9 +237,10 @@
263 237 *
264 238 * @access public
265 239 */
266 240 public function init() {
267 - if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' === get_user_option( 'rich_editing' ) ) {
241 + // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
242 + if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' == get_user_option( 'rich_editing' ) ) {
268 243 $this->_addFilter( 'mce_external_languages', 'add_tinymce_lang', 10, 1 );
269 244 $this->_addFilter( 'mce_external_plugins', 'tinymce_plugin', 10, 1 );
270 245 $this->_addFilter( 'mce_buttons', 'register_mce_button', 10, 1 );
271 246 $this->_addFilter( 'tiny_mce_before_init', 'get_strings_for_block', 10, 1 );
@@ -277,9 +252,9 @@
277 252 *
278 253 * @since ?
279 254 * @access friendly
280 255 */
281 - public function get_strings_for_block( $settings ) {
256 + function get_strings_for_block( $settings ) {
282 257 $class = new Visualizer_Module_Language();
283 258 $strings = $class->get_strings();
284 259 $array = array( 'visualizer_tinymce_plugin' => json_encode( $strings ) );
285 260 return array_merge( $settings, $array );
@@ -360,31 +335,8 @@
360 335
361 336 if ( post_type_supports( $typenow, 'editor' ) || $current_screen->id === 'widgets' || $current_screen->id === 'customize' ) {
362 337 wp_enqueue_style( 'visualizer-media', VISUALIZER_ABSURL . 'css/media.css', array( 'media-views' ), Visualizer_Plugin::VERSION );
363 338
364 - $d3_renderer_asset = VISUALIZER_ABSPATH . '/classes/Visualizer/D3Renderer/build/index.asset.php';
365 - if ( file_exists( $d3_renderer_asset ) && ! wp_script_is( 'visualizer-d3-renderer', 'registered' ) ) {
366 - // @phpstan-ignore-next-line
367 - $d3_asset = include $d3_renderer_asset;
368 - wp_register_script(
369 - 'visualizer-d3-renderer',
370 - VISUALIZER_ABSURL . 'classes/Visualizer/D3Renderer/build/index.js',
371 - array_merge( $d3_asset['dependencies'], array( 'jquery' ) ),
372 - $d3_asset['version'],
373 - true
374 - );
375 - }
376 - if ( wp_script_is( 'visualizer-d3-renderer', 'registered' ) ) {
377 - wp_enqueue_script( 'visualizer-d3-renderer' );
378 - wp_localize_script(
379 - 'visualizer-d3-renderer',
380 - 'vizD3Renderer',
381 - array(
382 - 'iframeJsUrl' => VISUALIZER_ABSURL . 'classes/Visualizer/D3Renderer/build/iframe.js',
383 - )
384 - );
385 - }
386 -
387 339 // Load all the assets for the different libraries we support.
388 340 $deps = array(
389 341 Visualizer_Render_Sidebar_Google::enqueue_assets( array( 'media-editor' ) ),
390 342 Visualizer_Render_Sidebar_Type_DataTable_Tabular::enqueue_assets( array( 'media-editor' ) ),
@@ -398,9 +350,9 @@
398 350 'visualizer-media-view',
399 351 'visualizer',
400 352 array(
401 353 'i10n' => array(
402 - 'insert' => __( 'Insert Chart', 'visualizer' ),
354 + 'insert' => __( 'Insert', 'visualizer' ),
403 355 ),
404 356 )
405 357 );
406 358 wp_enqueue_script( 'visualizer-media-toolbar', VISUALIZER_ABSURL . 'js/media/toolbar.js', array( 'visualizer-media-view' ), Visualizer_Plugin::VERSION, true );
@@ -429,9 +381,9 @@
429 381 'controller' => array(
430 382 'title' => esc_html__( 'Visualizations', 'visualizer' ),
431 383 ),
432 384 'routers' => array(
433 - 'library' => esc_html__( 'Insert from Library', 'visualizer' ),
385 + 'library' => esc_html__( 'From Library', 'visualizer' ),
434 386 'create' => esc_html__( 'Create New', 'visualizer' ),
435 387 ),
436 388 'library' => array(
437 389 'filters' => $chart_types,
@@ -461,9 +413,9 @@
461 413 'enabled' => true,
462 414 );
463 415 }
464 416
465 - $enabled = self::proFeaturesEnabled();
417 + $enabled = self::proFeaturesLocked();
466 418
467 419 $types = array_merge(
468 420 $additional,
469 421 array(
@@ -491,21 +443,18 @@
491 443 'name' => esc_html__( 'Area', 'visualizer' ),
492 444 'enabled' => $enabled,
493 445 // in ChartJS, the fill option is used to make Line chart an area: https://www.chartjs.org/docs/latest/charts/area.html
494 446 'supports' => array( 'Google Charts' ),
495 - 'demo_url' => 'https://demo.themeisle.com/visualizer/area-chart/',
496 447 ),
497 448 'geo' => array(
498 449 'name' => esc_html__( 'Geo', 'visualizer' ),
499 450 'enabled' => $enabled,
500 451 'supports' => array( 'Google Charts' ),
501 - 'demo_url' => 'https://demo.themeisle.com/visualizer/geo-chart/',
502 452 ),
503 453 'column' => array(
504 454 'name' => esc_html__( 'Column', 'visualizer' ),
505 455 'enabled' => $enabled,
506 456 'supports' => array( 'Google Charts', 'ChartJS' ),
507 - 'demo_url' => 'https://demo.themeisle.com/visualizer/column-chart/',
508 457 ),
509 458 'bubble' => array(
510 459 'name' => esc_html__( 'Bubble', 'visualizer' ),
511 460 'enabled' => $enabled,
@@ -510,27 +459,23 @@
510 459 'name' => esc_html__( 'Bubble', 'visualizer' ),
511 460 'enabled' => $enabled,
512 461 // chartjs' bubble is ugly looking (and it won't work off the default bubble.csv) so it is being excluded for the time being.
513 462 'supports' => array( 'Google Charts' ),
514 - 'demo_url' => 'https://demo.themeisle.com/visualizer/bubble-chart/',
515 463 ),
516 464 'scatter' => array(
517 465 'name' => esc_html__( 'Scatter', 'visualizer' ),
518 466 'enabled' => $enabled,
519 467 'supports' => array( 'Google Charts' ),
520 - 'demo_url' => 'https://demo.themeisle.com/visualizer/scatter-chart/',
521 468 ),
522 469 'gauge' => array(
523 470 'name' => esc_html__( 'Gauge', 'visualizer' ),
524 471 'enabled' => $enabled,
525 472 'supports' => array( 'Google Charts' ),
526 - 'demo_url' => 'https://demo.themeisle.com/visualizer/gauge-chart/',
527 473 ),
528 474 'candlestick' => array(
529 475 'name' => esc_html__( 'Candlestick', 'visualizer' ),
530 476 'enabled' => $enabled,
531 477 'supports' => array( 'Google Charts' ),
532 - 'demo_url' => 'https://demo.themeisle.com/visualizer/candlestick-chart/',
533 478 ),
534 479 // pro types
535 480 'timeline' => array(
536 481 'name' => esc_html__( 'Timeline', 'visualizer' ),
@@ -535,27 +480,23 @@
535 480 'timeline' => array(
536 481 'name' => esc_html__( 'Timeline', 'visualizer' ),
537 482 'enabled' => false,
538 483 'supports' => array( 'Google Charts', 'ChartJS' ),
539 - 'demo_url' => 'https://demo.themeisle.com/visualizer/timeline-chart/',
540 484 ),
541 485 'combo' => array(
542 486 'name' => esc_html__( 'Combo', 'visualizer' ),
543 487 'enabled' => false,
544 488 'supports' => array( 'Google Charts' ),
545 - 'demo_url' => 'https://demo.themeisle.com/visualizer/combo-chart/',
546 489 ),
547 490 'polarArea' => array(
548 491 'name' => esc_html__( 'Polar Area', 'visualizer' ),
549 492 'enabled' => false,
550 493 'supports' => array( 'ChartJS' ),
551 - 'demo_url' => 'https://demo.themeisle.com/visualizer/polar-area-chart/',
552 494 ),
553 495 'radar' => array(
554 496 'name' => esc_html__( 'Radar/Spider', 'visualizer' ),
555 497 'enabled' => false,
556 498 'supports' => array( 'ChartJS' ),
557 - 'demo_url' => 'https://demo.themeisle.com/visualizer/radar-spider-chart/',
558 499 ),
559 500 )
560 501 );
561 502 $types = apply_filters( 'visualizer_pro_chart_types', $types );
@@ -682,159 +623,45 @@
682 623 *
683 624 * @param string $suffix The current page suffix.
684 625 */
685 626 public function enqueueLibraryScripts( $suffix ) {
686 - if ( $suffix !== $this->_libraryPage ) {
687 - return;
688 - }
689 -
690 - wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
691 - $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
692 - wp_enqueue_media();
693 - wp_enqueue_script(
694 - 'visualizer-library',
695 - VISUALIZER_ABSURL . 'js/library.js',
696 - array(
697 - 'jquery',
698 - 'media-views',
699 - 'clipboard',
700 - ),
701 - Visualizer_Plugin::VERSION,
702 - true
703 - );
704 -
705 - wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
706 -
707 - $has_d3 = false;
708 - $query = $this->getQuery();
709 - while ( $query->have_posts() ) {
710 - $chart = $query->next_post();
711 - $library = $this->load_chart_type( $chart->ID );
712 - if ( is_null( $library ) ) {
713 - continue;
714 - }
627 + if ( $suffix === $this->_libraryPage ) {
628 + wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
629 + $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
630 + wp_enqueue_media();
715 631 wp_enqueue_script(
716 - "visualizer-render-$library",
717 - VISUALIZER_ABSURL . 'js/render-facade.js',
718 - apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
632 + 'visualizer-library',
633 + VISUALIZER_ABSURL . 'js/library.js',
634 + array(
635 + 'jquery',
636 + 'media-views',
637 + 'clipboard',
638 + ),
719 639 Visualizer_Plugin::VERSION,
720 640 true
721 641 );
722 - if ( 'd3' === $library ) {
723 - $has_d3 = true;
724 - }
725 - }
726 642
727 - if ( $has_d3 ) {
728 - $d3_renderer_asset = VISUALIZER_ABSPATH . '/classes/Visualizer/D3Renderer/build/index.asset.php';
729 - if ( file_exists( $d3_renderer_asset ) && ! wp_script_is( 'visualizer-d3-renderer', 'registered' ) ) {
730 - /**
731 - * Ignore missing build asset in source checkout.
732 - *
733 - * @phpstan-ignore-next-line
734 - */
735 - $d3_asset = include $d3_renderer_asset;
736 - wp_register_script(
737 - 'visualizer-d3-renderer',
738 - VISUALIZER_ABSURL . 'classes/Visualizer/D3Renderer/build/index.js',
739 - array_merge( $d3_asset['dependencies'], array( 'jquery' ) ),
740 - $d3_asset['version'],
741 - true
742 - );
743 - wp_enqueue_script( 'visualizer-d3-renderer' );
744 - }
745 - wp_localize_script(
746 - 'visualizer-d3-renderer',
747 - 'vizD3Renderer',
748 - array(
749 - 'iframeJsUrl' => VISUALIZER_ABSURL . 'classes/Visualizer/D3Renderer/build/iframe.js',
750 - )
751 - );
752 - }
643 + wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
753 644
754 - $chart_builder_asset = VISUALIZER_ABSPATH . '/classes/Visualizer/ChartBuilder/build/index.asset.php';
755 - if ( file_exists( $chart_builder_asset ) ) {
756 - /**
757 - * Ignore missing build asset in source checkout.
758 - *
759 - * @phpstan-ignore-next-line
760 - */
761 - $asset = include $chart_builder_asset;
762 - $chart_builder_deps = $asset['dependencies'];
763 - if ( ! wp_script_is( 'visualizer-handsontable', 'registered' ) && defined( 'Visualizer_Pro_ABSURL' ) && defined( 'VISUALIZER_PRO_VERSION' ) ) {
764 - wp_register_script(
765 - 'visualizer-handsontable',
766 - Visualizer_Pro_ABSURL . 'vendor/handsontable/dist/handsontable.full.min.js',
767 - array(),
768 - VISUALIZER_PRO_VERSION,
645 + $query = $this->getQuery();
646 + while ( $query->have_posts() ) {
647 + $chart = $query->next_post();
648 + $library = $this->load_chart_type( $chart->ID );
649 + if ( is_null( $library ) ) {
650 + continue;
651 + }
652 + wp_enqueue_script(
653 + "visualizer-render-$library",
654 + VISUALIZER_ABSURL . 'js/render-facade.js',
655 + apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
656 + Visualizer_Plugin::VERSION,
769 657 true
770 658 );
771 659 }
772 - if ( ! wp_style_is( 'visualizer-handsontable', 'registered' ) && defined( 'Visualizer_Pro_ABSURL' ) && defined( 'VISUALIZER_PRO_VERSION' ) ) {
773 - wp_register_style(
774 - 'visualizer-handsontable',
775 - Visualizer_Pro_ABSURL . 'vendor/handsontable/dist/handsontable.full.min.css',
776 - array(),
777 - VISUALIZER_PRO_VERSION
778 - );
779 - }
780 - if ( wp_script_is( 'visualizer-handsontable', 'registered' ) ) {
781 - wp_enqueue_script( 'visualizer-handsontable' );
782 - $chart_builder_deps = array_unique( array_merge( $chart_builder_deps, array( 'visualizer-handsontable' ) ) );
783 - }
784 - if ( wp_style_is( 'visualizer-handsontable', 'registered' ) ) {
785 - wp_enqueue_style( 'visualizer-handsontable' );
786 - }
787 - wp_enqueue_script(
788 - 'visualizer-chart-builder',
789 - VISUALIZER_ABSURL . 'classes/Visualizer/ChartBuilder/build/index.js',
790 - $chart_builder_deps,
791 - $asset['version'],
792 - true
793 - );
794 - wp_enqueue_style(
795 - 'visualizer-chart-builder',
796 - VISUALIZER_ABSURL . 'classes/Visualizer/ChartBuilder/build/style-index.css',
797 - array(),
798 - $asset['version']
799 - );
800 - $chart_builder_css = VISUALIZER_ABSPATH . '/classes/Visualizer/ChartBuilder/build/index.css';
801 - if ( file_exists( $chart_builder_css ) ) {
802 - wp_enqueue_style(
803 - 'visualizer-chart-builder-runtime',
804 - VISUALIZER_ABSURL . 'classes/Visualizer/ChartBuilder/build/index.css',
805 - array( 'visualizer-chart-builder' ),
806 - $asset['version']
807 - );
808 - }
809 - wp_localize_script(
810 - 'visualizer-chart-builder',
811 - 'vizAIBuilder',
812 - array(
813 - 'ajaxUrl' => admin_url( 'admin-ajax.php' ),
814 - 'nonce' => wp_create_nonce( 'visualizer-ai-builder' ),
815 - 'isPro' => Visualizer_Module::is_pro(),
816 - 'upgradeUrl' => tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'aiBuilderUpgrade', 'dataSource' ),
817 - )
818 - );
819 660 }
820 -
821 - do_action( 'themeisle_internal_page', VISUALIZER_DIRNAME, 'library' );
822 661 }
823 662
824 663 /**
825 - * Enqueue script for support page.
826 - *
827 - * @param string $hook_suffix Current hook.
828 - */
829 - public function enqueue_support_page( $hook_suffix ) {
830 - if ( $this->_supportPage !== $hook_suffix ) {
831 - return;
832 - }
833 - do_action( 'themeisle_internal_page', VISUALIZER_DIRNAME, 'support' );
834 - }
835 -
836 - /**
837 664 * Adds visualizer tab for media upload tabs array.
838 665 *
839 666 * @since 1.0.0
840 667 *
@@ -875,20 +702,10 @@
875 702 __( 'Add New Chart', 'visualizer' ),
876 703 'edit_posts',
877 704 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew'
878 705 );
879 -
880 - $this->_settingsPage = add_submenu_page(
706 + add_submenu_page(
881 707 Visualizer_Plugin::NAME,
882 - __( 'Settings', 'visualizer' ),
883 - __( 'Settings', 'visualizer' ),
884 - 'manage_options',
885 - 'viz-settings',
886 - array( $this, 'renderSettingsPage' )
887 - );
888 -
889 - $this->_supportPage = add_submenu_page(
890 - Visualizer_Plugin::NAME,
891 708 __( 'Support', 'visualizer' ),
892 709 __( 'Support', 'visualizer' ) . '<span class="dashicons dashicons-editor-help more-features-icon" style="width: 17px; height: 17px; margin-left: 4px; color: #ffca54; font-size: 17px; vertical-align: -3px;"></span>',
893 710 'edit_posts',
894 711 'viz-support',
@@ -913,9 +730,9 @@
913 730 font-size: 14px;
914 731 font-weight: 600;
915 732 color: #fff;
916 733 }
917 - #toplevel_page_visualizer ul.wp-submenu li:last-child > a > span {
734 + #toplevel_page_visualizer ul.wp-submenu li:last-child > a {
918 735 color: #fff !important;
919 736 }
920 737 #toplevel_page_visualizer ul.wp-submenu li:last-child > a:hover {
921 738 box-shadow: inherit;
@@ -936,9 +753,9 @@
936 753
937 754 /**
938 755 * Adds the screen options for pagination.
939 756 */
940 - public function addScreenOptions() {
757 + function addScreenOptions() {
941 758 $screen = get_current_screen();
942 759
943 760 // bail if it's some other page.
944 761 if ( ! is_object( $screen ) || $screen->id !== $this->_libraryPage ) {
@@ -955,9 +772,9 @@
955 772
956 773 /**
957 774 * Returns the screen option for pagination.
958 775 */
959 - public function setScreenOptions( $status, $option, $value ) {
776 + function setScreenOptions( $status, $option, $value ) {
960 777 if ( 'visualizer_library_per_page' === $option ) {
961 778 return $value;
962 779 }
963 780 }
@@ -1105,95 +922,13 @@
1105 922 * @access public
1106 923 */
1107 924 public function renderSupportPage() {
1108 925 wp_enqueue_style( 'visualizer-upsell', VISUALIZER_ABSURL . 'css/upsell.css', array(), Visualizer_Plugin::VERSION );
926 + $this->load_survey();
1109 927 include_once VISUALIZER_ABSPATH . '/templates/support.php';
1110 928 }
1111 929
1112 930 /**
1113 - * Enqueues scripts/styles for the Settings page.
1114 - *
1115 - * @access public
1116 - */
1117 - public function enqueueSettingsScripts( string $hook_suffix ): void {
1118 - if ( $this->_settingsPage !== $hook_suffix ) {
1119 - return;
1120 - }
1121 - wp_enqueue_style( 'wp-color-picker' );
1122 - wp_enqueue_script( 'wp-color-picker' );
1123 - }
1124 -
1125 - /**
1126 - * Renders the global style settings page.
1127 - *
1128 - * @access public
1129 - */
1130 - public function renderSettingsPage(): void {
1131 - if ( ! current_user_can( 'manage_options' ) ) {
1132 - wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'visualizer' ) );
1133 - }
1134 - $settings = self::getGlobalSettings();
1135 - include_once VISUALIZER_ABSPATH . '/templates/global-settings.php';
1136 - }
1137 -
1138 - /**
1139 - * Returns the global style settings option.
1140 - *
1141 - * @return array<string, string>
1142 - * @access public
1143 - * @static
1144 - */
1145 - public static function getGlobalSettings(): array {
1146 - $defaults = array(
1147 - 'color_primary' => '',
1148 - 'color_secondary' => '',
1149 - 'apply_existing' => '0',
1150 - );
1151 - $saved = get_option( self::OPTION_GLOBAL_SETTINGS, array() );
1152 - return wp_parse_args( $saved, $defaults );
1153 - }
1154 -
1155 - /**
1156 - * Handles saving of the global style settings.
1157 - *
1158 - * @access public
1159 - */
1160 - public function saveGlobalSettings(): void {
1161 - if ( ! current_user_can( 'manage_options' ) ) {
1162 - wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'visualizer' ) );
1163 - }
1164 -
1165 - check_admin_referer( 'visualizer_save_global_settings' );
1166 -
1167 - $color_primary = sanitize_hex_color( wp_unslash( $_POST['visualizer_color_primary'] ?? '' ) );
1168 - $color_secondary = sanitize_hex_color( wp_unslash( $_POST['visualizer_color_secondary'] ?? '' ) );
1169 - $apply_existing = ! empty( $_POST['visualizer_apply_existing'] ) ? '1' : '0';
1170 - $clear = ! empty( $_POST['visualizer_clear_settings'] );
1171 -
1172 - if ( $clear ) {
1173 - delete_option( self::OPTION_GLOBAL_SETTINGS );
1174 - } else {
1175 - $settings = array(
1176 - 'color_primary' => $color_primary ? $color_primary : '',
1177 - 'color_secondary' => $color_secondary ? $color_secondary : '',
1178 - 'apply_existing' => $apply_existing,
1179 - );
1180 - update_option( self::OPTION_GLOBAL_SETTINGS, $settings );
1181 - }
1182 -
1183 - wp_safe_redirect(
1184 - add_query_arg(
1185 - array(
1186 - 'page' => 'viz-settings',
1187 - 'updated' => $clear ? 'cleared' : 'true',
1188 - ),
1189 - admin_url( 'admin.php' )
1190 - )
1191 - );
1192 - exit;
1193 - }
1194 -
1195 - /**
1196 931 * Renders visualizer library page.
1197 932 *
1198 933 * @since 1.0.0
1199 934 *
@@ -1277,9 +1012,8 @@
1277 1012
1278 1013 // add chart to the array
1279 1014 $charts[ $id ] = array(
1280 1015 'id' => $chart->ID,
1281 - 'title' => $chart->post_title,
1282 1016 'type' => $type,
1283 1017 'series' => $series,
1284 1018 'settings' => $settings,
1285 1019 'data' => $data,
@@ -1284,11 +1018,8 @@
1284 1018 'settings' => $settings,
1285 1019 'data' => $data,
1286 1020 'library' => $library,
1287 1021 );
1288 - if ( 'd3' === $library ) {
1289 - $charts[ $id ]['code'] = get_post_meta( $chart->ID, Visualizer_Module_AIBuilder::CF_D3_CODE, true );
1290 - }
1291 1022 }
1292 1023 // enqueue charts array
1293 1024 $ajaxurl = admin_url( 'admin-ajax.php' );
1294 1025
@@ -1348,8 +1079,10 @@
1348 1079 'type' => 'array',
1349 1080 )
1350 1081 );
1351 1082
1083 + $this->load_survey();
1084 +
1352 1085 $render->render();
1353 1086 }
1354 1087
1355 1088 /**
@@ -1391,36 +1124,19 @@
1391 1124 *
1392 1125 * @return array Updated array of plugin meta links.
1393 1126 */
1394 1127 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
1395 - if ( Visualizer_Module::is_pro() ) {
1396 - return $plugin_meta;
1397 - }
1398 -
1399 - // Also suppress the upsell when Pro is installed but not currently active.
1400 - if ( ! function_exists( 'get_plugins' ) ) {
1401 - require_once ABSPATH . 'wp-admin/includes/plugin.php';
1402 - }
1403 - foreach ( array_keys( get_plugins() ) as $installed_plugin ) {
1404 - if ( false !== strpos( $installed_plugin, 'visualizer-pro' ) ) {
1405 - return $plugin_meta;
1406 - }
1407 - }
1408 -
1409 1128 if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
1410 - $is_black_friday = apply_filters( 'themeisle_sdk_is_black_friday_sale', false );
1411 1129 // knowledge base link
1412 1130 $plugin_meta[] = sprintf(
1413 1131 '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1414 1132 esc_html__( 'Docs', 'visualizer' )
1415 1133 );
1416 - if ( ! $is_black_friday ) {
1417 - // flattr link
1418 - $plugin_meta[] = sprintf(
1419 - '<a style="color:red" href="' . tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'pluginrow' ) . '" target="_blank">%s</a>',
1420 - esc_html__( 'Get Visualizer Pro', 'visualizer' )
1421 - );
1422 - }
1134 + // flattr link
1135 + $plugin_meta[] = sprintf(
1136 + '<a style="color:red" href="' . tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'pluginrow' ) . '" target="_blank">%s</a>',
1137 + esc_html__( 'Pro Addon', 'visualizer' )
1138 + );
1423 1139 }
1424 1140
1425 1141 return $plugin_meta;
1426 1142 }
@@ -1425,39 +1141,17 @@
1425 1141 return $plugin_meta;
1426 1142 }
1427 1143
1428 1144 /**
1429 - * Returns true when premium chart types should be enabled for the current user.
1145 + * If check is existing user.
1430 1146 *
1431 - * Pro 1.9.0+ hooks the 'visualizer_is_pro' filter and returns true only when
1432 - * the license is valid. Pre-1.9.0 Pro defined a Visualizer_Pro class instead;
1433 - * we detect that as a fallback so those legacy installs still work.
1434 - *
1435 - * Passing false as the filter default ensures the constant VISUALIZER_PRO
1436 - * (which is set to true whenever the Pro class exists, regardless of license
1437 - * state) cannot bypass the license check.
1438 - *
1439 - * @return bool
1147 + * @return bool Default false
1440 1148 */
1441 - public static function proFeaturesEnabled() {
1442 - $is_pro_filter = apply_filters( 'visualizer_is_pro', false );
1443 -
1444 - // Pro 1.9.0+: filter is hooked and returns true only with a valid license.
1445 - if ( $is_pro_filter ) {
1149 + public static function proFeaturesLocked() {
1150 + if ( Visualizer_Module::is_pro() ) {
1446 1151 return true;
1447 1152 }
1448 -
1449 - // Pro is installed (active) but the license check above did not pass.
1450 - // Do NOT fall through to the legacy "old user" path — that path exists
1451 - // only for sites that never had Pro installed. If Pro is present but
1452 - // the license is inactive we should lock, regardless of chart history.
1453 - if ( class_exists( 'Visualizer_Pro', false ) ) {
1454 - return false;
1455 - }
1456 -
1457 - // No Pro installed at all: grant legacy access to existing users so
1458 - // their charts are not suddenly broken when they upgrade the free plugin.
1459 - return 'yes' === get_option( 'visualizer-new-user' ) ? false : true;
1153 + return 'yes' === get_option( 'visualizer-new-user', 'yes' ) ? false : true;
1460 1154 }
1461 1155
1462 1156 /**
1463 1157 * Multilingual Support.
@@ -1520,139 +1214,72 @@
1520 1214
1521 1215 /**
1522 1216 * Get the survey metadata.
1523 1217 *
1524 - * @param array $data The data for survey in Formbricks format.
1525 - * @param string $page_slug The slug of the loaded page.
1526 - *
1527 1218 * @return array The survey metadata.
1528 1219 */
1529 - public function get_survey_metadata( $data, $page_slug ) {
1530 - $install_date = get_option( 'visualizer_install', time() );
1531 - $install_days_number = intval( ( time() - $install_date ) / DAY_IN_SECONDS );
1220 + private function get_survey_metadata() {
1221 + $install_date = get_option( 'visualizer_install', false );
1222 + $install_category = 0;
1532 1223
1533 - $license_status = apply_filters( 'product_visualizer_license_status', 'invalid' );
1534 - $license_plan = apply_filters( 'product_visualizer_license_plan', false );
1535 - $license_key = apply_filters( 'product_visualizer_license_key', false );
1224 + if ( false !== $install_date ) {
1225 + $days_since_install = round( ( time() - $install_date ) / DAY_IN_SECONDS );
1536 1226
1227 + if ( 0 === $days_since_install || 1 === $days_since_install ) {
1228 + $install_category = 0;
1229 + } elseif ( 1 < $days_since_install && 8 > $days_since_install ) {
1230 + $install_category = 7;
1231 + } elseif ( 8 <= $days_since_install && 31 > $days_since_install ) {
1232 + $install_category = 30;
1233 + } elseif ( 30 < $days_since_install && 90 > $days_since_install ) {
1234 + $install_category = 90;
1235 + } elseif ( 90 <= $days_since_install ) {
1236 + $install_category = 91;
1237 + }
1238 + }
1239 +
1537 1240 $plugin_data = get_plugin_data( VISUALIZER_BASEFILE, false, false );
1538 1241 $plugin_version = '';
1539 -
1540 1242 if ( ! empty( $plugin_data['Version'] ) ) {
1541 1243 $plugin_version = $plugin_data['Version'];
1542 1244 }
1543 1245
1544 - $count_charts_cache_key = 'visualizer_count_charts';
1545 - $charts_number = get_transient( $count_charts_cache_key );
1246 + $user_id = 'visualizer_' . preg_replace( '/[^\w\d]*/', '', get_site_url() ); // Use a normalized version of the site URL as a user ID.
1546 1247
1547 - if ( false === $charts_number ) {
1548 - $charts_number = $this->count_charts( 100 );
1549 - set_transient( $count_charts_cache_key, $charts_number, 100 === $charts_number ? WEEK_IN_SECONDS : 6 * HOUR_IN_SECONDS );
1550 - } else {
1551 - $charts_number = strval( $charts_number );
1248 + $license_data = get_option( 'visualizer_pro_license_data', false );
1249 + if ( false !== $license_data && isset( $license_data->key ) ) {
1250 + $user_id = 'visualizer_' . $license_data->key;
1552 1251 }
1553 1252
1554 - $data = array(
1555 - 'environmentId' => 'cltef8cut1s7wyyfxy3rlxzs5',
1253 + return array(
1254 + 'userId' => $user_id,
1556 1255 'attributes' => array(
1557 - 'free_version' => $plugin_version,
1558 - 'pro_version' => defined( 'VISUALIZER_PRO_VERSION' ) ? VISUALIZER_PRO_VERSION : '',
1559 - 'license_status' => $license_status,
1560 - 'install_days_number' => $install_days_number,
1561 - 'charts_number' => $charts_number,
1256 + 'days_since_install' => strval( $install_category ),
1257 + 'free_version' => $plugin_version,
1258 + 'pro_version' => defined( 'VISUALIZER_PRO_VERSION' ) ? VISUALIZER_PRO_VERSION : '',
1259 + 'license_status' => apply_filters( 'product_visualizer_license_status', 'invalid' ),
1562 1260 ),
1563 1261 );
1564 -
1565 - if ( ! empty( $license_plan ) ) {
1566 - $data['attributes']['plan'] = $license_plan;
1567 - }
1568 -
1569 - if ( ! empty( $license_key ) ) {
1570 - $data['attributes']['license_key'] = apply_filters( 'themeisle_sdk_secret_masking', $license_key );
1571 - }
1572 -
1573 - return $data;
1574 1262 }
1575 1263
1576 1264 /**
1577 - * Count the charts.
1578 - *
1579 - * @param int $limit The count limit (optional).
1580 - *
1581 - * @return int The number of charts.
1265 + * Load the survey.
1582 1266 */
1583 - public function count_charts( $limit = -1 ) {
1584 - $args = array(
1585 - 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
1586 - 'post_status' => 'publish',
1587 - 'posts_per_page' => $limit,
1588 - 'fields' => 'ids',
1589 - );
1267 + private function load_survey() {
1590 1268
1591 - $query = new WP_Query( $args);
1592 - return $query->post_count;
1593 - }
1594 -
1595 - /**
1596 - * Set the black friday data.
1597 - *
1598 - * @param array $configs The configuration array for the loaded products.
1599 - * @return array
1600 - */
1601 - public function add_black_friday_data( $configs ) {
1602 - $config = $configs['default'];
1603 -
1604 - $message = __( 'Database queries, private charts, auto-sync. Go beyond basic charts. Exclusively for existing Visualizer users.', 'visualizer' );
1605 - $cta_label = __( 'Get Visualizer Pro', 'visualizer' );
1606 -
1607 - $plan = apply_filters( 'product_visualizer_license_plan', 0 );
1608 - $license = apply_filters( 'product_visualizer_license_key', false );
1609 - $status = apply_filters( 'product_visualizer_license_status', false );
1610 - $pro_product_slug = defined( 'VISUALIZER_PRO_BASEFILE' ) ? basename( dirname( VISUALIZER_PRO_BASEFILE ) ) : '';
1611 -
1612 - $is_pro = 'valid' === $status;
1613 - $is_expired = 'expired' === $status || 'active-expired' === $status;
1614 -
1615 - if ( $is_pro ) {
1616 - // translators: %s is the discount percentage.
1617 - $config['plugin_meta_message'] = sprintf( __( 'Black Friday Sale - up to %s off', 'visualizer' ), '30%' );
1618 - // translators: %1$s - discount, %2$s - discount.
1619 - $message = sprintf( __( 'Upgrade your Visualizer Pro plan: %1$s off this week. Already on the plan you need? Renew early and save up to %2$s.', 'visualizer' ), '30%', '20%' );
1620 - $cta_label = __( 'See your options', 'visualizer' );
1621 - } elseif ( $is_expired ) {
1622 - // translators: %s is the discount percentage.
1623 - $config['upgrade_menu_text'] = sprintf( __( 'BF Sale - %s off', 'visualizer' ), '50%' );
1624 - // translators: %s is the discount percentage.
1625 - $config['plugin_meta_message'] = sprintf( __( 'Black Friday Sale - %s off', 'visualizer' ), '50%' );
1626 - $message = __( 'Your Visualizer Pro features are still here, just locked. Renew at a reduced rate this week.', 'visualizer' );
1627 - $cta_label = __( 'Reactivate now', 'visualizer' );
1628 - } else {
1629 - // translators: %s is the discount percentage.
1630 - $config['plugin_meta_message'] = sprintf( __( 'Black Friday Sale - %s off', 'visualizer' ), '60%' );
1631 - $config['title'] = __( 'Visualizer Pro: 60% off this week', 'visualizer' );
1632 - // translators: %s is the discount percentage.
1633 - $config['upgrade_menu_text'] = sprintf( __( 'BF Sale - %s off', 'visualizer' ), '60%' );
1269 + if ( defined( 'TI_CYPRESS_TESTING' ) ) {
1270 + return;
1634 1271 }
1635 1272
1636 - $url_params = array(
1637 - 'utm_term' => $is_pro ? 'plan-' . $plan : 'free',
1638 - 'lkey' => ! empty( $license ) ? $license : false,
1639 - 'expired' => $is_expired ? '1' : false,
1640 - );
1273 + $survey_handler = apply_filters( 'themeisle_sdk_dependency_script_handler', 'survey' );
1641 1274
1642 - if ( ( $is_pro || $is_expired ) && ! empty( $pro_product_slug ) ) {
1643 - $config['plugin_meta_targets'] = array( $pro_product_slug );
1275 + if ( empty( $survey_handler ) ) {
1276 + return;
1644 1277 }
1645 1278
1646 - $config['message'] = $message;
1647 - $config['cta_label'] = $cta_label;
1279 + $metadata = $this->get_survey_metadata();
1648 1280
1649 - $config['sale_url'] = add_query_arg(
1650 - $url_params,
1651 - tsdk_translate_link( tsdk_utmify( 'https://themeisle.link/vizualizer-bf', 'bfcm', 'visualizer' ) )
1652 - );
1653 -
1654 - $configs[ VISUALIZER_DIRNAME ] = $config;
1655 -
1656 - return $configs;
1281 + do_action( 'themeisle_sdk_dependency_enqueue_script', 'survey' );
1282 + wp_enqueue_script( 'visualizer_chart_survey', VISUALIZER_ABSURL . 'js/survey.js', array( $survey_handler ), $metadata['attributes']['free_version'], true );
1283 + wp_localize_script( 'visualizer_chart_survey', 'visualizerSurveyData', $metadata );
1657 1284 }
1658 1285 }