PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.10.8
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.10.8
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 +110 -507 4.0.83.10.8 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 *
@@ -70,20 +52,16 @@
70 52 public function __construct( Visualizer_Plugin $plugin ) {
71 53 parent::__construct( $plugin );
72 54 $this->_addAction( 'load-post.php', 'enqueueMediaScripts' );
73 55 $this->_addAction( 'load-post-new.php', 'enqueueMediaScripts' );
74 - $this->_addAction( 'enqueue_block_editor_assets', 'enqueueMediaScripts' );
75 56 $this->_addAction( 'admin_footer', 'renderTemplates' );
76 57 $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 58 $this->_addAction( 'admin_menu', 'registerAdminMenu' );
81 59 $this->_addFilter( 'media_view_strings', 'setupMediaViewStrings' );
82 60 $this->_addFilter( 'plugin_action_links', 'getPluginActionLinks', 10, 2 );
83 61 $this->_addFilter( 'plugin_row_meta', 'getPluginMetaLinks', 10, 2 );
62 + $this->_addFilter( 'visualizer_logger_data', 'getLoggerData' );
84 63 $this->_addFilter( 'visualizer_feedback_review_trigger', 'feedbackReviewTrigger' );
85 - $this->_addFilter( 'themeisle_sdk_blackfriday_data', 'add_black_friday_data' );
86 64
87 65 // screen pagination
88 66 $this->_addFilter( 'set-screen-option', 'setScreenOptions', 10, 3 );
89 67
@@ -97,45 +75,14 @@
97 75 $this->_addAction( 'admin_init', 'init' );
98 76
99 77 $this->_addAction( 'visualizer_chart_languages', 'addMultilingualSupport' );
100 78
101 - $this->_addFilter( 'admin_footer_text', 'render_review_notice' );
102 -
103 - if ( ! defined( 'TI_E2E_TESTING' ) ) {
104 - $this->_addFilter( 'themeisle-sdk/survey/' . VISUALIZER_DIRNAME, 'get_survey_metadata', 10, 2 );
105 - }
106 -
107 - if ( defined( 'TI_E2E_TESTING' ) ) {
79 + if ( defined( 'TI_CYPRESS_TESTING' ) ) {
108 80 $this->load_cypress_hooks();
109 81 }
110 - }
111 - /**
112 - * Display review notice.
113 - */
114 - public function render_review_notice( $footer_text ) {
115 - $current_screen = get_current_screen();
116 82
117 - $visualizer_page_ids = array( 'toplevel_page_visualizer', 'visualizer_page_viz-support', 'visualizer_page_ti-about-visualizer' );
118 -
119 - if ( ! empty( $current_screen ) && isset( $current_screen->id ) ) {
120 - foreach ( $visualizer_page_ids as $page_to_check ) {
121 - if ( strpos( $current_screen->id, $page_to_check ) !== false ) {
122 - $footer_text = sprintf(
123 - // translators: %1$s - the name of the plugin (Visualizer), %2$s - message (You can help us by leaving a), %3$s - HTML entity code.
124 - __( 'Enjoying %1$s? %2$s %3$s rating. Thank you for being so supportive!', 'visualizer' ),
125 - '<b>Visualizer</b>',
126 - esc_html__( 'You can help us by leaving a', 'visualizer' ),
127 - '<a href="https://wordpress.org/support/plugin/visualizer/reviews/#new-post" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
128 - );
129 - break;
130 - }
131 - }
132 - }
133 -
134 - return $footer_text;
135 83 }
136 84
137 -
138 85 /**
139 86 * Define the hooks that are needed for cypress.
140 87 *
141 88 * @since 3.4.0
@@ -143,9 +90,9 @@
143 90 */
144 91 private function load_cypress_hooks() {
145 92 // all charts should load on the same page without pagination.
146 93 add_filter(
147 - 'visualizer_query_args', function ( $args ) {
94 + 'visualizer_query_args', function( $args ) {
148 95 $args['posts_per_page'] = 20;
149 96 return $args;
150 97 }, 10, 1
151 98 );
@@ -166,16 +113,23 @@
166 113 if ( apply_filters( 'visualizer_is_business', false ) ) {
167 114 return;
168 115 }
169 116
170 - $is_new_personal = apply_filters( 'visualizer_is_new_personal', false );
117 + $license = __( 'PRO', 'visualizer' );
118 + if ( Visualizer_Module::is_pro() ) {
119 + switch ( $plan ) {
120 + case 1:
121 + $license = __( 'Developer', 'visualizer' );
122 + break;
123 + }
124 + }
171 125
172 126 $hours = array(
173 - '0.16' => __( '10 minutes', 'visualizer' ),
174 - '1' => __( 'Each hour', 'visualizer' ),
175 - '12' => __( 'Each 12 hours', 'visualizer' ),
176 - '24' => __( 'Each day', 'visualizer' ),
177 - '72' => __( 'Each 3 days', 'visualizer' ),
127 + '0' => __( 'Live', 'visualizer' ),
128 + '1' => __( 'Each hour', 'visualizer' ),
129 + '12' => __( 'Each 12 hours', 'visualizer' ),
130 + '24' => __( 'Each day', 'visualizer' ),
131 + '72' => __( 'Each 3 days', 'visualizer' ),
178 132 );
179 133
180 134 switch ( $feature ) {
181 135 case 'json':
@@ -180,9 +134,9 @@
180 134 switch ( $feature ) {
181 135 case 'json':
182 136 case 'csv':
183 137 // no more schedules if pro is already active.
184 - if ( Visualizer_Module::is_pro() && ! $is_new_personal ) {
138 + if ( Visualizer_Module::is_pro() ) {
185 139 return;
186 140 }
187 141 break;
188 142 case 'wp':
@@ -192,9 +146,9 @@
192 146 default:
193 147 return;
194 148 }
195 149
196 - echo '<optgroup disabled label="' . __( 'Upgrade required', 'visualizer' ) . '">';
150 + echo '<optgroup disabled label="' . sprintf( __( 'More in the %s version', 'visualizer' ), $license ) . '">';
197 151 foreach ( $hours as $hour => $desc ) {
198 152 echo '<option disabled>' . $desc . '</option>';
199 153 }
200 154 echo '</optgroup>';
@@ -221,9 +175,9 @@
221 175
222 176 if ( $meta ) {
223 177 foreach ( $meta as $key => $value ) {
224 178 if ( 0 === strpos( $key, 'visualizer' ) ) {
225 - add_metadata( 'post', $revision_id, $key, self::maybe_decode_content( $value[0] ) );
179 + add_metadata( 'post', $revision_id, $key, maybe_unserialize( $value[0] ) );
226 180 }
227 181 }
228 182 }
229 183 }
@@ -249,9 +203,9 @@
249 203
250 204 if ( $meta ) {
251 205 foreach ( $meta as $key => $value ) {
252 206 if ( 0 === strpos( $key, 'visualizer' ) ) {
253 - add_post_meta( $post_id, $key, self::maybe_decode_content( $value[0] ) );
207 + add_post_meta( $post_id, $key, maybe_unserialize( $value[0] ) );
254 208 }
255 209 }
256 210 }
257 211 }
@@ -262,9 +216,10 @@
262 216 *
263 217 * @access public
264 218 */
265 219 public function init() {
266 - if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' === get_user_option( 'rich_editing' ) ) {
220 + // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
221 + if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' == get_user_option( 'rich_editing' ) ) {
267 222 $this->_addFilter( 'mce_external_languages', 'add_tinymce_lang', 10, 1 );
268 223 $this->_addFilter( 'mce_external_plugins', 'tinymce_plugin', 10, 1 );
269 224 $this->_addFilter( 'mce_buttons', 'register_mce_button', 10, 1 );
270 225 $this->_addFilter( 'tiny_mce_before_init', 'get_strings_for_block', 10, 1 );
@@ -276,9 +231,9 @@
276 231 *
277 232 * @since ?
278 233 * @access friendly
279 234 */
280 - public function get_strings_for_block( $settings ) {
235 + function get_strings_for_block( $settings ) {
281 236 $class = new Visualizer_Module_Language();
282 237 $strings = $class->get_strings();
283 238 $array = array( 'visualizer_tinymce_plugin' => json_encode( $strings ) );
284 239 return array_merge( $settings, $array );
@@ -354,36 +309,11 @@
354 309 * @access public
355 310 */
356 311 public function enqueueMediaScripts() {
357 312 global $typenow;
358 - global $current_screen;
359 -
360 - if ( post_type_supports( $typenow, 'editor' ) || $current_screen->id === 'widgets' || $current_screen->id === 'customize' ) {
313 + if ( post_type_supports( $typenow, 'editor' ) ) {
361 314 wp_enqueue_style( 'visualizer-media', VISUALIZER_ABSURL . 'css/media.css', array( 'media-views' ), Visualizer_Plugin::VERSION );
362 315
363 - $d3_renderer_asset = VISUALIZER_ABSPATH . '/classes/Visualizer/D3Renderer/build/index.asset.php';
364 - if ( file_exists( $d3_renderer_asset ) && ! wp_script_is( 'visualizer-d3-renderer', 'registered' ) ) {
365 - // @phpstan-ignore-next-line
366 - $d3_asset = include $d3_renderer_asset;
367 - wp_register_script(
368 - 'visualizer-d3-renderer',
369 - VISUALIZER_ABSURL . 'classes/Visualizer/D3Renderer/build/index.js',
370 - array_merge( $d3_asset['dependencies'], array( 'jquery' ) ),
371 - $d3_asset['version'],
372 - true
373 - );
374 - }
375 - if ( wp_script_is( 'visualizer-d3-renderer', 'registered' ) ) {
376 - wp_enqueue_script( 'visualizer-d3-renderer' );
377 - wp_localize_script(
378 - 'visualizer-d3-renderer',
379 - 'vizD3Renderer',
380 - array(
381 - 'iframeJsUrl' => VISUALIZER_ABSURL . 'classes/Visualizer/D3Renderer/build/iframe.js',
382 - )
383 - );
384 - }
385 -
386 316 // Load all the assets for the different libraries we support.
387 317 $deps = array(
388 318 Visualizer_Render_Sidebar_Google::enqueue_assets( array( 'media-editor' ) ),
389 319 Visualizer_Render_Sidebar_Type_DataTable_Tabular::enqueue_assets( array( 'media-editor' ) ),
@@ -397,9 +327,9 @@
397 327 'visualizer-media-view',
398 328 'visualizer',
399 329 array(
400 330 'i10n' => array(
401 - 'insert' => __( 'Insert Chart', 'visualizer' ),
331 + 'insert' => __( 'Insert', 'visualizer' ),
402 332 ),
403 333 )
404 334 );
405 335 wp_enqueue_script( 'visualizer-media-toolbar', VISUALIZER_ABSURL . 'js/media/toolbar.js', array( 'visualizer-media-view' ), Visualizer_Plugin::VERSION, true );
@@ -428,9 +358,9 @@
428 358 'controller' => array(
429 359 'title' => esc_html__( 'Visualizations', 'visualizer' ),
430 360 ),
431 361 'routers' => array(
432 - 'library' => esc_html__( 'Insert from Library', 'visualizer' ),
362 + 'library' => esc_html__( 'From Library', 'visualizer' ),
433 363 'create' => esc_html__( 'Create New', 'visualizer' ),
434 364 ),
435 365 'library' => array(
436 366 'filters' => $chart_types,
@@ -435,9 +365,9 @@
435 365 'library' => array(
436 366 'filters' => $chart_types,
437 367 'types' => array_keys( $chart_types ),
438 368 ),
439 - 'nonce' => wp_create_nonce( Visualizer_Plugin::ACTION_GET_CHARTS ),
369 + 'nonce' => wp_create_nonce(),
440 370 'buildurl' => esc_url( add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ) ),
441 371 );
442 372
443 373 return $strings;
@@ -460,9 +390,9 @@
460 390 'enabled' => true,
461 391 );
462 392 }
463 393
464 - $enabled = self::proFeaturesEnabled();
394 + $enabled = self::proFeaturesLocked();
465 395
466 396 $types = array_merge(
467 397 $additional,
468 398 array(
@@ -473,14 +403,14 @@
473 403 ),
474 404 'pie' => array(
475 405 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
476 406 'enabled' => true,
477 - 'supports' => array( 'Google Charts', 'ChartJS' ),
407 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
478 408 ),
479 409 'line' => array(
480 410 'name' => esc_html__( 'Line', 'visualizer' ),
481 411 'enabled' => true,
482 - 'supports' => array( 'Google Charts', 'ChartJS' ),
412 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
483 413 ),
484 414 'bar' => array(
485 415 'name' => esc_html__( 'Bar', 'visualizer' ),
486 416 'enabled' => true,
@@ -490,21 +420,18 @@
490 420 'name' => esc_html__( 'Area', 'visualizer' ),
491 421 'enabled' => $enabled,
492 422 // in ChartJS, the fill option is used to make Line chart an area: https://www.chartjs.org/docs/latest/charts/area.html
493 423 'supports' => array( 'Google Charts' ),
494 - 'demo_url' => 'https://demo.themeisle.com/visualizer/area-chart/',
495 424 ),
496 425 'geo' => array(
497 426 'name' => esc_html__( 'Geo', 'visualizer' ),
498 427 'enabled' => $enabled,
499 428 'supports' => array( 'Google Charts' ),
500 - 'demo_url' => 'https://demo.themeisle.com/visualizer/geo-chart/',
501 429 ),
502 430 'column' => array(
503 431 'name' => esc_html__( 'Column', 'visualizer' ),
504 432 'enabled' => $enabled,
505 433 'supports' => array( 'Google Charts', 'ChartJS' ),
506 - 'demo_url' => 'https://demo.themeisle.com/visualizer/column-chart/',
507 434 ),
508 435 'bubble' => array(
509 436 'name' => esc_html__( 'Bubble', 'visualizer' ),
510 437 'enabled' => $enabled,
@@ -509,27 +436,23 @@
509 436 'name' => esc_html__( 'Bubble', 'visualizer' ),
510 437 'enabled' => $enabled,
511 438 // chartjs' bubble is ugly looking (and it won't work off the default bubble.csv) so it is being excluded for the time being.
512 439 'supports' => array( 'Google Charts' ),
513 - 'demo_url' => 'https://demo.themeisle.com/visualizer/bubble-chart/',
514 440 ),
515 441 'scatter' => array(
516 442 'name' => esc_html__( 'Scatter', 'visualizer' ),
517 443 'enabled' => $enabled,
518 444 'supports' => array( 'Google Charts' ),
519 - 'demo_url' => 'https://demo.themeisle.com/visualizer/scatter-chart/',
520 445 ),
521 446 'gauge' => array(
522 447 'name' => esc_html__( 'Gauge', 'visualizer' ),
523 448 'enabled' => $enabled,
524 449 'supports' => array( 'Google Charts' ),
525 - 'demo_url' => 'https://demo.themeisle.com/visualizer/gauge-chart/',
526 450 ),
527 451 'candlestick' => array(
528 452 'name' => esc_html__( 'Candlestick', 'visualizer' ),
529 453 'enabled' => $enabled,
530 454 'supports' => array( 'Google Charts' ),
531 - 'demo_url' => 'https://demo.themeisle.com/visualizer/candlestick-chart/',
532 455 ),
533 456 // pro types
534 457 'timeline' => array(
535 458 'name' => esc_html__( 'Timeline', 'visualizer' ),
@@ -534,27 +457,23 @@
534 457 'timeline' => array(
535 458 'name' => esc_html__( 'Timeline', 'visualizer' ),
536 459 'enabled' => false,
537 460 'supports' => array( 'Google Charts', 'ChartJS' ),
538 - 'demo_url' => 'https://demo.themeisle.com/visualizer/timeline-chart/',
539 461 ),
540 462 'combo' => array(
541 463 'name' => esc_html__( 'Combo', 'visualizer' ),
542 464 'enabled' => false,
543 465 'supports' => array( 'Google Charts' ),
544 - 'demo_url' => 'https://demo.themeisle.com/visualizer/combo-chart/',
545 466 ),
546 467 'polarArea' => array(
547 468 'name' => esc_html__( 'Polar Area', 'visualizer' ),
548 469 'enabled' => false,
549 470 'supports' => array( 'ChartJS' ),
550 - 'demo_url' => 'https://demo.themeisle.com/visualizer/polar-area-chart/',
551 471 ),
552 472 'radar' => array(
553 473 'name' => esc_html__( 'Radar/Spider', 'visualizer' ),
554 474 'enabled' => false,
555 475 'supports' => array( 'ChartJS' ),
556 - 'demo_url' => 'https://demo.themeisle.com/visualizer/radar-spider-chart/',
557 476 ),
558 477 )
559 478 );
560 479 $types = apply_filters( 'visualizer_pro_chart_types', $types );
@@ -681,159 +600,45 @@
681 600 *
682 601 * @param string $suffix The current page suffix.
683 602 */
684 603 public function enqueueLibraryScripts( $suffix ) {
685 - if ( $suffix !== $this->_libraryPage ) {
686 - return;
687 - }
688 -
689 - wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
690 - $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
691 - wp_enqueue_media();
692 - wp_enqueue_script(
693 - 'visualizer-library',
694 - VISUALIZER_ABSURL . 'js/library.js',
695 - array(
696 - 'jquery',
697 - 'media-views',
698 - 'clipboard',
699 - ),
700 - Visualizer_Plugin::VERSION,
701 - true
702 - );
703 -
704 - wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
705 -
706 - $has_d3 = false;
707 - $query = $this->getQuery();
708 - while ( $query->have_posts() ) {
709 - $chart = $query->next_post();
710 - $library = $this->load_chart_type( $chart->ID );
711 - if ( is_null( $library ) ) {
712 - continue;
713 - }
604 + if ( $suffix === $this->_libraryPage ) {
605 + wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
606 + $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
607 + wp_enqueue_media();
714 608 wp_enqueue_script(
715 - "visualizer-render-$library",
716 - VISUALIZER_ABSURL . 'js/render-facade.js',
717 - apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
609 + 'visualizer-library',
610 + VISUALIZER_ABSURL . 'js/library.js',
611 + array(
612 + 'jquery',
613 + 'media-views',
614 + 'clipboard',
615 + ),
718 616 Visualizer_Plugin::VERSION,
719 617 true
720 618 );
721 - if ( 'd3' === $library ) {
722 - $has_d3 = true;
723 - }
724 - }
725 619
726 - if ( $has_d3 ) {
727 - $d3_renderer_asset = VISUALIZER_ABSPATH . '/classes/Visualizer/D3Renderer/build/index.asset.php';
728 - if ( file_exists( $d3_renderer_asset ) && ! wp_script_is( 'visualizer-d3-renderer', 'registered' ) ) {
729 - /**
730 - * Ignore missing build asset in source checkout.
731 - *
732 - * @phpstan-ignore-next-line
733 - */
734 - $d3_asset = include $d3_renderer_asset;
735 - wp_register_script(
736 - 'visualizer-d3-renderer',
737 - VISUALIZER_ABSURL . 'classes/Visualizer/D3Renderer/build/index.js',
738 - array_merge( $d3_asset['dependencies'], array( 'jquery' ) ),
739 - $d3_asset['version'],
740 - true
741 - );
742 - wp_enqueue_script( 'visualizer-d3-renderer' );
743 - }
744 - wp_localize_script(
745 - 'visualizer-d3-renderer',
746 - 'vizD3Renderer',
747 - array(
748 - 'iframeJsUrl' => VISUALIZER_ABSURL . 'classes/Visualizer/D3Renderer/build/iframe.js',
749 - )
750 - );
751 - }
620 + wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
752 621
753 - $chart_builder_asset = VISUALIZER_ABSPATH . '/classes/Visualizer/ChartBuilder/build/index.asset.php';
754 - if ( file_exists( $chart_builder_asset ) ) {
755 - /**
756 - * Ignore missing build asset in source checkout.
757 - *
758 - * @phpstan-ignore-next-line
759 - */
760 - $asset = include $chart_builder_asset;
761 - $chart_builder_deps = $asset['dependencies'];
762 - if ( ! wp_script_is( 'visualizer-handsontable', 'registered' ) && defined( 'Visualizer_Pro_ABSURL' ) && defined( 'VISUALIZER_PRO_VERSION' ) ) {
763 - wp_register_script(
764 - 'visualizer-handsontable',
765 - Visualizer_Pro_ABSURL . 'vendor/handsontable/dist/handsontable.full.min.js',
766 - array(),
767 - VISUALIZER_PRO_VERSION,
622 + $query = $this->getQuery();
623 + while ( $query->have_posts() ) {
624 + $chart = $query->next_post();
625 + $library = $this->load_chart_type( $chart->ID );
626 + if ( is_null( $library ) ) {
627 + continue;
628 + }
629 + wp_enqueue_script(
630 + "visualizer-render-$library",
631 + VISUALIZER_ABSURL . 'js/render-facade.js',
632 + apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
633 + Visualizer_Plugin::VERSION,
768 634 true
769 635 );
770 636 }
771 - if ( ! wp_style_is( 'visualizer-handsontable', 'registered' ) && defined( 'Visualizer_Pro_ABSURL' ) && defined( 'VISUALIZER_PRO_VERSION' ) ) {
772 - wp_register_style(
773 - 'visualizer-handsontable',
774 - Visualizer_Pro_ABSURL . 'vendor/handsontable/dist/handsontable.full.min.css',
775 - array(),
776 - VISUALIZER_PRO_VERSION
777 - );
778 - }
779 - if ( wp_script_is( 'visualizer-handsontable', 'registered' ) ) {
780 - wp_enqueue_script( 'visualizer-handsontable' );
781 - $chart_builder_deps = array_unique( array_merge( $chart_builder_deps, array( 'visualizer-handsontable' ) ) );
782 - }
783 - if ( wp_style_is( 'visualizer-handsontable', 'registered' ) ) {
784 - wp_enqueue_style( 'visualizer-handsontable' );
785 - }
786 - wp_enqueue_script(
787 - 'visualizer-chart-builder',
788 - VISUALIZER_ABSURL . 'classes/Visualizer/ChartBuilder/build/index.js',
789 - $chart_builder_deps,
790 - $asset['version'],
791 - true
792 - );
793 - wp_enqueue_style(
794 - 'visualizer-chart-builder',
795 - VISUALIZER_ABSURL . 'classes/Visualizer/ChartBuilder/build/style-index.css',
796 - array(),
797 - $asset['version']
798 - );
799 - $chart_builder_css = VISUALIZER_ABSPATH . '/classes/Visualizer/ChartBuilder/build/index.css';
800 - if ( file_exists( $chart_builder_css ) ) {
801 - wp_enqueue_style(
802 - 'visualizer-chart-builder-runtime',
803 - VISUALIZER_ABSURL . 'classes/Visualizer/ChartBuilder/build/index.css',
804 - array( 'visualizer-chart-builder' ),
805 - $asset['version']
806 - );
807 - }
808 - wp_localize_script(
809 - 'visualizer-chart-builder',
810 - 'vizAIBuilder',
811 - array(
812 - 'ajaxUrl' => admin_url( 'admin-ajax.php' ),
813 - 'nonce' => wp_create_nonce( 'visualizer-ai-builder' ),
814 - 'isPro' => Visualizer_Module::is_pro(),
815 - 'upgradeUrl' => tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'aiBuilderUpgrade', 'dataSource' ),
816 - )
817 - );
818 637 }
819 -
820 - do_action( 'themeisle_internal_page', VISUALIZER_DIRNAME, 'library' );
821 638 }
822 639
823 640 /**
824 - * Enqueue script for support page.
825 - *
826 - * @param string $hook_suffix Current hook.
827 - */
828 - public function enqueue_support_page( $hook_suffix ) {
829 - if ( $this->_supportPage !== $hook_suffix ) {
830 - return;
831 - }
832 - do_action( 'themeisle_internal_page', VISUALIZER_DIRNAME, 'support' );
833 - }
834 -
835 - /**
836 641 * Adds visualizer tab for media upload tabs array.
837 642 *
838 643 * @since 1.0.0
839 644 *
@@ -874,20 +679,10 @@
874 679 __( 'Add New Chart', 'visualizer' ),
875 680 'edit_posts',
876 681 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew'
877 682 );
878 -
879 - $this->_settingsPage = add_submenu_page(
683 + add_submenu_page(
880 684 Visualizer_Plugin::NAME,
881 - __( 'Settings', 'visualizer' ),
882 - __( 'Settings', 'visualizer' ),
883 - 'manage_options',
884 - 'viz-settings',
885 - array( $this, 'renderSettingsPage' )
886 - );
887 -
888 - $this->_supportPage = add_submenu_page(
889 - Visualizer_Plugin::NAME,
890 685 __( 'Support', 'visualizer' ),
891 686 __( '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>',
892 687 'edit_posts',
893 688 'viz-support',
@@ -912,9 +707,9 @@
912 707 font-size: 14px;
913 708 font-weight: 600;
914 709 color: #fff;
915 710 }
916 - #toplevel_page_visualizer ul.wp-submenu li:last-child > a > span {
711 + #toplevel_page_visualizer ul.wp-submenu li:last-child > a {
917 712 color: #fff !important;
918 713 }
919 714 #toplevel_page_visualizer ul.wp-submenu li:last-child > a:hover {
920 715 box-shadow: inherit;
@@ -935,9 +730,9 @@
935 730
936 731 /**
937 732 * Adds the screen options for pagination.
938 733 */
939 - public function addScreenOptions() {
734 + function addScreenOptions() {
940 735 $screen = get_current_screen();
941 736
942 737 // bail if it's some other page.
943 738 if ( ! is_object( $screen ) || $screen->id !== $this->_libraryPage ) {
@@ -954,9 +749,9 @@
954 749
955 750 /**
956 751 * Returns the screen option for pagination.
957 752 */
958 - public function setScreenOptions( $status, $option, $value ) {
753 + function setScreenOptions( $status, $option, $value ) {
959 754 if ( 'visualizer_library_per_page' === $option ) {
960 755 return $value;
961 756 }
962 757 }
@@ -1104,95 +899,13 @@
1104 899 * @access public
1105 900 */
1106 901 public function renderSupportPage() {
1107 902 wp_enqueue_style( 'visualizer-upsell', VISUALIZER_ABSURL . 'css/upsell.css', array(), Visualizer_Plugin::VERSION );
903 + $this->load_survey();
1108 904 include_once VISUALIZER_ABSPATH . '/templates/support.php';
1109 905 }
1110 906
1111 907 /**
1112 - * Enqueues scripts/styles for the Settings page.
1113 - *
1114 - * @access public
1115 - */
1116 - public function enqueueSettingsScripts( string $hook_suffix ): void {
1117 - if ( $this->_settingsPage !== $hook_suffix ) {
1118 - return;
1119 - }
1120 - wp_enqueue_style( 'wp-color-picker' );
1121 - wp_enqueue_script( 'wp-color-picker' );
1122 - }
1123 -
1124 - /**
1125 - * Renders the global style settings page.
1126 - *
1127 - * @access public
1128 - */
1129 - public function renderSettingsPage(): void {
1130 - if ( ! current_user_can( 'manage_options' ) ) {
1131 - wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'visualizer' ) );
1132 - }
1133 - $settings = self::getGlobalSettings();
1134 - include_once VISUALIZER_ABSPATH . '/templates/global-settings.php';
1135 - }
1136 -
1137 - /**
1138 - * Returns the global style settings option.
1139 - *
1140 - * @return array<string, string>
1141 - * @access public
1142 - * @static
1143 - */
1144 - public static function getGlobalSettings(): array {
1145 - $defaults = array(
1146 - 'color_primary' => '',
1147 - 'color_secondary' => '',
1148 - 'apply_existing' => '0',
1149 - );
1150 - $saved = get_option( self::OPTION_GLOBAL_SETTINGS, array() );
1151 - return wp_parse_args( $saved, $defaults );
1152 - }
1153 -
1154 - /**
1155 - * Handles saving of the global style settings.
1156 - *
1157 - * @access public
1158 - */
1159 - public function saveGlobalSettings(): void {
1160 - if ( ! current_user_can( 'manage_options' ) ) {
1161 - wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'visualizer' ) );
1162 - }
1163 -
1164 - check_admin_referer( 'visualizer_save_global_settings' );
1165 -
1166 - $color_primary = sanitize_hex_color( wp_unslash( $_POST['visualizer_color_primary'] ?? '' ) );
1167 - $color_secondary = sanitize_hex_color( wp_unslash( $_POST['visualizer_color_secondary'] ?? '' ) );
1168 - $apply_existing = ! empty( $_POST['visualizer_apply_existing'] ) ? '1' : '0';
1169 - $clear = ! empty( $_POST['visualizer_clear_settings'] );
1170 -
1171 - if ( $clear ) {
1172 - delete_option( self::OPTION_GLOBAL_SETTINGS );
1173 - } else {
1174 - $settings = array(
1175 - 'color_primary' => $color_primary ? $color_primary : '',
1176 - 'color_secondary' => $color_secondary ? $color_secondary : '',
1177 - 'apply_existing' => $apply_existing,
1178 - );
1179 - update_option( self::OPTION_GLOBAL_SETTINGS, $settings );
1180 - }
1181 -
1182 - wp_safe_redirect(
1183 - add_query_arg(
1184 - array(
1185 - 'page' => 'viz-settings',
1186 - 'updated' => $clear ? 'cleared' : 'true',
1187 - ),
1188 - admin_url( 'admin.php' )
1189 - )
1190 - );
1191 - exit;
1192 - }
1193 -
1194 - /**
1195 908 * Renders visualizer library page.
1196 909 *
1197 910 * @since 1.0.0
1198 911 *
@@ -1276,9 +989,8 @@
1276 989
1277 990 // add chart to the array
1278 991 $charts[ $id ] = array(
1279 992 'id' => $chart->ID,
1280 - 'title' => $chart->post_title,
1281 993 'type' => $type,
1282 994 'series' => $series,
1283 995 'settings' => $settings,
1284 996 'data' => $data,
@@ -1283,15 +995,11 @@
1283 995 'settings' => $settings,
1284 996 'data' => $data,
1285 997 'library' => $library,
1286 998 );
1287 - if ( 'd3' === $library ) {
1288 - $charts[ $id ]['code'] = get_post_meta( $chart->ID, Visualizer_Module_AIBuilder::CF_D3_CODE, true );
1289 - }
1290 999 }
1291 1000 // enqueue charts array
1292 1001 $ajaxurl = admin_url( 'admin-ajax.php' );
1293 -
1294 1002 wp_localize_script(
1295 1003 'visualizer-library',
1296 1004 'visualizer',
1297 1005 array(
@@ -1328,9 +1036,8 @@
1328 1036 'i10n' => array(
1329 1037 'copied' => __( 'The shortcode has been copied to your clipboard. Hit Ctrl-V/Cmd-V to paste it.', 'visualizer' ),
1330 1038 'conflict' => __( 'We have detected a potential conflict with another component that prevents Visualizer from functioning properly. Please disable any of the following components if they are activated on your instance: Modern Events Calendar plugin, Acronix plugin. In case the aforementioned components are not activated or you continue to see this error message, please disable all other plugins and enable them one by one to find out the component that is causing the conflict.', 'visualizer' ),
1331 1039 ),
1332 - 'is_pro_user' => Visualizer_Module::is_pro(),
1333 1040 )
1334 1041 );
1335 1042 // render library page
1336 1043 $render = new Visualizer_Render_Library();
@@ -1347,8 +1054,10 @@
1347 1054 'type' => 'array',
1348 1055 )
1349 1056 );
1350 1057
1058 + $this->load_survey();
1059 +
1351 1060 $render->render();
1352 1061 }
1353 1062
1354 1063 /**
@@ -1390,36 +1099,19 @@
1390 1099 *
1391 1100 * @return array Updated array of plugin meta links.
1392 1101 */
1393 1102 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
1394 - if ( Visualizer_Module::is_pro() ) {
1395 - return $plugin_meta;
1396 - }
1397 -
1398 - // Also suppress the upsell when Pro is installed but not currently active.
1399 - if ( ! function_exists( 'get_plugins' ) ) {
1400 - require_once ABSPATH . 'wp-admin/includes/plugin.php';
1401 - }
1402 - foreach ( array_keys( get_plugins() ) as $installed_plugin ) {
1403 - if ( false !== strpos( $installed_plugin, 'visualizer-pro' ) ) {
1404 - return $plugin_meta;
1405 - }
1406 - }
1407 -
1408 1103 if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
1409 - $is_black_friday = apply_filters( 'themeisle_sdk_is_black_friday_sale', false );
1410 1104 // knowledge base link
1411 1105 $plugin_meta[] = sprintf(
1412 1106 '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1413 1107 esc_html__( 'Docs', 'visualizer' )
1414 1108 );
1415 - if ( ! $is_black_friday ) {
1416 - // flattr link
1417 - $plugin_meta[] = sprintf(
1418 - '<a style="color:red" href="' . tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'pluginrow' ) . '" target="_blank">%s</a>',
1419 - esc_html__( 'Get Visualizer Pro', 'visualizer' )
1420 - );
1421 - }
1109 + // flattr link
1110 + $plugin_meta[] = sprintf(
1111 + '<a style="color:red" href="' . tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'pluginrow' ) . '" target="_blank">%s</a>',
1112 + esc_html__( 'Pro Addon', 'visualizer' )
1113 + );
1422 1114 }
1423 1115
1424 1116 return $plugin_meta;
1425 1117 }
@@ -1424,39 +1116,17 @@
1424 1116 return $plugin_meta;
1425 1117 }
1426 1118
1427 1119 /**
1428 - * Returns true when premium chart types should be enabled for the current user.
1120 + * If check is existing user.
1429 1121 *
1430 - * Pro 1.9.0+ hooks the 'visualizer_is_pro' filter and returns true only when
1431 - * the license is valid. Pre-1.9.0 Pro defined a Visualizer_Pro class instead;
1432 - * we detect that as a fallback so those legacy installs still work.
1433 - *
1434 - * Passing false as the filter default ensures the constant VISUALIZER_PRO
1435 - * (which is set to true whenever the Pro class exists, regardless of license
1436 - * state) cannot bypass the license check.
1437 - *
1438 - * @return bool
1122 + * @return bool Default false
1439 1123 */
1440 - public static function proFeaturesEnabled() {
1441 - $is_pro_filter = apply_filters( 'visualizer_is_pro', false );
1442 -
1443 - // Pro 1.9.0+: filter is hooked and returns true only with a valid license.
1444 - if ( $is_pro_filter ) {
1124 + public static function proFeaturesLocked() {
1125 + if ( Visualizer_Module::is_pro() ) {
1445 1126 return true;
1446 1127 }
1447 -
1448 - // Pro is installed (active) but the license check above did not pass.
1449 - // Do NOT fall through to the legacy "old user" path — that path exists
1450 - // only for sites that never had Pro installed. If Pro is present but
1451 - // the license is inactive we should lock, regardless of chart history.
1452 - if ( class_exists( 'Visualizer_Pro', false ) ) {
1453 - return false;
1454 - }
1455 -
1456 - // No Pro installed at all: grant legacy access to existing users so
1457 - // their charts are not suddenly broken when they upgrade the free plugin.
1458 - return 'yes' === get_option( 'visualizer-new-user' ) ? false : true;
1128 + return 'yes' === get_option( 'visualizer-new-user', 'yes' ) ? false : true;
1459 1129 }
1460 1130
1461 1131 /**
1462 1132 * Multilingual Support.
@@ -1519,139 +1189,72 @@
1519 1189
1520 1190 /**
1521 1191 * Get the survey metadata.
1522 1192 *
1523 - * @param array $data The data for survey in Formbricks format.
1524 - * @param string $page_slug The slug of the loaded page.
1525 - *
1526 1193 * @return array The survey metadata.
1527 1194 */
1528 - public function get_survey_metadata( $data, $page_slug ) {
1529 - $install_date = get_option( 'visualizer_install', time() );
1530 - $install_days_number = intval( ( time() - $install_date ) / DAY_IN_SECONDS );
1195 + private function get_survey_metadata() {
1196 + $install_date = get_option( 'visualizer_install', false );
1197 + $install_category = 0;
1531 1198
1532 - $license_status = apply_filters( 'product_visualizer_license_status', 'invalid' );
1533 - $license_plan = apply_filters( 'product_visualizer_license_plan', false );
1534 - $license_key = apply_filters( 'product_visualizer_license_key', false );
1199 + if ( false !== $install_date ) {
1200 + $days_since_install = round( ( time() - $install_date ) / DAY_IN_SECONDS );
1535 1201
1202 + if ( 0 === $days_since_install || 1 === $days_since_install ) {
1203 + $install_category = 0;
1204 + } elseif ( 1 < $days_since_install && 8 > $days_since_install ) {
1205 + $install_category = 7;
1206 + } elseif ( 8 <= $days_since_install && 31 > $days_since_install ) {
1207 + $install_category = 30;
1208 + } elseif ( 30 < $days_since_install && 90 > $days_since_install ) {
1209 + $install_category = 90;
1210 + } elseif ( 90 <= $days_since_install ) {
1211 + $install_category = 91;
1212 + }
1213 + }
1214 +
1536 1215 $plugin_data = get_plugin_data( VISUALIZER_BASEFILE, false, false );
1537 1216 $plugin_version = '';
1538 -
1539 1217 if ( ! empty( $plugin_data['Version'] ) ) {
1540 1218 $plugin_version = $plugin_data['Version'];
1541 1219 }
1542 1220
1543 - $count_charts_cache_key = 'visualizer_count_charts';
1544 - $charts_number = get_transient( $count_charts_cache_key );
1221 + $user_id = 'visualizer_' . preg_replace( '/[^\w\d]*/', '', get_site_url() ); // Use a normalized version of the site URL as a user ID.
1545 1222
1546 - if ( false === $charts_number ) {
1547 - $charts_number = $this->count_charts( 100 );
1548 - set_transient( $count_charts_cache_key, $charts_number, 100 === $charts_number ? WEEK_IN_SECONDS : 6 * HOUR_IN_SECONDS );
1549 - } else {
1550 - $charts_number = strval( $charts_number );
1223 + $license_data = get_option( 'visualizer_pro_license_data', false );
1224 + if ( false !== $license_data ) {
1225 + $user_id = 'visualizer_' . $license_data->key;
1551 1226 }
1552 1227
1553 - $data = array(
1554 - 'environmentId' => 'cltef8cut1s7wyyfxy3rlxzs5',
1228 + return array(
1229 + 'userId' => $user_id,
1555 1230 'attributes' => array(
1556 - 'free_version' => $plugin_version,
1557 - 'pro_version' => defined( 'VISUALIZER_PRO_VERSION' ) ? VISUALIZER_PRO_VERSION : '',
1558 - 'license_status' => $license_status,
1559 - 'install_days_number' => $install_days_number,
1560 - 'charts_number' => $charts_number,
1231 + 'days_since_install' => $install_category,
1232 + 'free_version' => $plugin_version,
1233 + 'pro_version' => defined( 'VISUALIZER_PRO_VERSION' ) ? VISUALIZER_PRO_VERSION : '',
1234 + 'license_status' => apply_filters( 'product_visualizer_license_status', 'invalid' ),
1561 1235 ),
1562 1236 );
1563 -
1564 - if ( ! empty( $license_plan ) ) {
1565 - $data['attributes']['plan'] = $license_plan;
1566 - }
1567 -
1568 - if ( ! empty( $license_key ) ) {
1569 - $data['attributes']['license_key'] = apply_filters( 'themeisle_sdk_secret_masking', $license_key );
1570 - }
1571 -
1572 - return $data;
1573 1237 }
1574 1238
1575 1239 /**
1576 - * Count the charts.
1577 - *
1578 - * @param int $limit The count limit (optional).
1579 - *
1580 - * @return int The number of charts.
1240 + * Load the survey.
1581 1241 */
1582 - public function count_charts( $limit = -1 ) {
1583 - $args = array(
1584 - 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
1585 - 'post_status' => 'publish',
1586 - 'posts_per_page' => $limit,
1587 - 'fields' => 'ids',
1588 - );
1242 + private function load_survey() {
1589 1243
1590 - $query = new WP_Query( $args);
1591 - return $query->post_count;
1592 - }
1593 -
1594 - /**
1595 - * Set the black friday data.
1596 - *
1597 - * @param array $configs The configuration array for the loaded products.
1598 - * @return array
1599 - */
1600 - public function add_black_friday_data( $configs ) {
1601 - $config = $configs['default'];
1602 -
1603 - $message = __( 'Database queries, private charts, auto-sync. Go beyond basic charts. Exclusively for existing Visualizer users.', 'visualizer' );
1604 - $cta_label = __( 'Get Visualizer Pro', 'visualizer' );
1605 -
1606 - $plan = apply_filters( 'product_visualizer_license_plan', 0 );
1607 - $license = apply_filters( 'product_visualizer_license_key', false );
1608 - $status = apply_filters( 'product_visualizer_license_status', false );
1609 - $pro_product_slug = defined( 'VISUALIZER_PRO_BASEFILE' ) ? basename( dirname( VISUALIZER_PRO_BASEFILE ) ) : '';
1610 -
1611 - $is_pro = 'valid' === $status;
1612 - $is_expired = 'expired' === $status || 'active-expired' === $status;
1613 -
1614 - if ( $is_pro ) {
1615 - // translators: %s is the discount percentage.
1616 - $config['plugin_meta_message'] = sprintf( __( 'Black Friday Sale - up to %s off', 'visualizer' ), '30%' );
1617 - // translators: %1$s - discount, %2$s - discount.
1618 - $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%' );
1619 - $cta_label = __( 'See your options', 'visualizer' );
1620 - } elseif ( $is_expired ) {
1621 - // translators: %s is the discount percentage.
1622 - $config['upgrade_menu_text'] = sprintf( __( 'BF Sale - %s off', 'visualizer' ), '50%' );
1623 - // translators: %s is the discount percentage.
1624 - $config['plugin_meta_message'] = sprintf( __( 'Black Friday Sale - %s off', 'visualizer' ), '50%' );
1625 - $message = __( 'Your Visualizer Pro features are still here, just locked. Renew at a reduced rate this week.', 'visualizer' );
1626 - $cta_label = __( 'Reactivate now', 'visualizer' );
1627 - } else {
1628 - // translators: %s is the discount percentage.
1629 - $config['plugin_meta_message'] = sprintf( __( 'Black Friday Sale - %s off', 'visualizer' ), '60%' );
1630 - $config['title'] = __( 'Visualizer Pro: 60% off this week', 'visualizer' );
1631 - // translators: %s is the discount percentage.
1632 - $config['upgrade_menu_text'] = sprintf( __( 'BF Sale - %s off', 'visualizer' ), '60%' );
1244 + if ( defined( 'TI_CYPRESS_TESTING' ) ) {
1245 + return;
1633 1246 }
1634 1247
1635 - $url_params = array(
1636 - 'utm_term' => $is_pro ? 'plan-' . $plan : 'free',
1637 - 'lkey' => ! empty( $license ) ? $license : false,
1638 - 'expired' => $is_expired ? '1' : false,
1639 - );
1248 + $survey_handler = apply_filters( 'themeisle_sdk_dependency_script_handler', 'survey' );
1640 1249
1641 - if ( ( $is_pro || $is_expired ) && ! empty( $pro_product_slug ) ) {
1642 - $config['plugin_meta_targets'] = array( $pro_product_slug );
1250 + if ( empty( $survey_handler ) ) {
1251 + return;
1643 1252 }
1644 1253
1645 - $config['message'] = $message;
1646 - $config['cta_label'] = $cta_label;
1254 + $metadata = $this->get_survey_metadata();
1647 1255
1648 - $config['sale_url'] = add_query_arg(
1649 - $url_params,
1650 - tsdk_translate_link( tsdk_utmify( 'https://themeisle.link/vizualizer-bf', 'bfcm', 'visualizer' ) )
1651 - );
1652 -
1653 - $configs[ VISUALIZER_DIRNAME ] = $config;
1654 -
1655 - return $configs;
1256 + do_action( 'themeisle_sdk_dependency_enqueue_script', 'survey' );
1257 + wp_enqueue_script( 'visualizer_chart_survey', VISUALIZER_ABSURL . 'js/survey.js', array( $survey_handler ), $metadata['attributes']['free_version'], true );
1258 + wp_localize_script( 'visualizer_chart_survey', 'visualizerSurveyData', $metadata );
1656 1259 }
1657 1260 }