PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.10.7
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.10.7
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 +70 -542 4.0.83.10.7 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 *
@@ -865,9 +670,9 @@
865 670 Visualizer_Plugin::NAME,
866 671 __( 'Chart Library', 'visualizer' ),
867 672 __( 'Chart Library', 'visualizer' ),
868 673 'edit_posts',
869 - 'admin.php?page=' . Visualizer_Plugin::NAME
674 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME )
870 675 );
871 676 add_submenu_page(
872 677 Visualizer_Plugin::NAME,
873 678 __( 'Add New Chart', 'visualizer' ),
@@ -872,22 +677,12 @@
872 677 Visualizer_Plugin::NAME,
873 678 __( 'Add New Chart', 'visualizer' ),
874 679 __( 'Add New Chart', 'visualizer' ),
875 680 'edit_posts',
876 - 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew'
681 + admin_url( '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 }
@@ -1108,91 +903,8 @@
1108 903 include_once VISUALIZER_ABSPATH . '/templates/support.php';
1109 904 }
1110 905
1111 906 /**
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 907 * Renders visualizer library page.
1196 908 *
1197 909 * @since 1.0.0
1198 910 *
@@ -1276,9 +988,8 @@
1276 988
1277 989 // add chart to the array
1278 990 $charts[ $id ] = array(
1279 991 'id' => $chart->ID,
1280 - 'title' => $chart->post_title,
1281 992 'type' => $type,
1282 993 'series' => $series,
1283 994 'settings' => $settings,
1284 995 'data' => $data,
@@ -1283,15 +994,11 @@
1283 994 'settings' => $settings,
1284 995 'data' => $data,
1285 996 'library' => $library,
1286 997 );
1287 - if ( 'd3' === $library ) {
1288 - $charts[ $id ]['code'] = get_post_meta( $chart->ID, Visualizer_Module_AIBuilder::CF_D3_CODE, true );
1289 - }
1290 998 }
1291 999 // enqueue charts array
1292 1000 $ajaxurl = admin_url( 'admin-ajax.php' );
1293 -
1294 1001 wp_localize_script(
1295 1002 'visualizer-library',
1296 1003 'visualizer',
1297 1004 array(
@@ -1328,9 +1035,8 @@
1328 1035 'i10n' => array(
1329 1036 'copied' => __( 'The shortcode has been copied to your clipboard. Hit Ctrl-V/Cmd-V to paste it.', 'visualizer' ),
1330 1037 '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 1038 ),
1332 - 'is_pro_user' => Visualizer_Module::is_pro(),
1333 1039 )
1334 1040 );
1335 1041 // render library page
1336 1042 $render = new Visualizer_Render_Library();
@@ -1346,9 +1052,8 @@
1346 1052 'total' => $query->max_num_pages,
1347 1053 'type' => 'array',
1348 1054 )
1349 1055 );
1350 -
1351 1056 $render->render();
1352 1057 }
1353 1058
1354 1059 /**
@@ -1390,36 +1095,19 @@
1390 1095 *
1391 1096 * @return array Updated array of plugin meta links.
1392 1097 */
1393 1098 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 1099 if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
1409 - $is_black_friday = apply_filters( 'themeisle_sdk_is_black_friday_sale', false );
1410 1100 // knowledge base link
1411 1101 $plugin_meta[] = sprintf(
1412 1102 '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1413 1103 esc_html__( 'Docs', 'visualizer' )
1414 1104 );
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 - }
1105 + // flattr link
1106 + $plugin_meta[] = sprintf(
1107 + '<a style="color:red" href="' . tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'pluginrow' ) . '" target="_blank">%s</a>',
1108 + esc_html__( 'Pro Addon', 'visualizer' )
1109 + );
1422 1110 }
1423 1111
1424 1112 return $plugin_meta;
1425 1113 }
@@ -1424,39 +1112,17 @@
1424 1112 return $plugin_meta;
1425 1113 }
1426 1114
1427 1115 /**
1428 - * Returns true when premium chart types should be enabled for the current user.
1116 + * If check is existing user.
1429 1117 *
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
1118 + * @return bool Default false
1439 1119 */
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 ) {
1120 + public static function proFeaturesLocked() {
1121 + if ( Visualizer_Module::is_pro() ) {
1445 1122 return true;
1446 1123 }
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;
1124 + return 'yes' === get_option( 'visualizer-new-user', 'yes' ) ? false : true;
1459 1125 }
1460 1126
1461 1127 /**
1462 1128 * Multilingual Support.
@@ -1514,144 +1180,6 @@
1514 1180 if ( isset( $types[ $type ] ) ) {
1515 1181 return ! empty( $types[ $type ]['enabled'] );
1516 1182 }
1517 1183 return false;
1518 - }
1519 -
1520 - /**
1521 - * Get the survey metadata.
1522 - *
1523 - * @param array $data The data for survey in Formbricks format.
1524 - * @param string $page_slug The slug of the loaded page.
1525 - *
1526 - * @return array The survey metadata.
1527 - */
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 );
1531 -
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 );
1535 -
1536 - $plugin_data = get_plugin_data( VISUALIZER_BASEFILE, false, false );
1537 - $plugin_version = '';
1538 -
1539 - if ( ! empty( $plugin_data['Version'] ) ) {
1540 - $plugin_version = $plugin_data['Version'];
1541 - }
1542 -
1543 - $count_charts_cache_key = 'visualizer_count_charts';
1544 - $charts_number = get_transient( $count_charts_cache_key );
1545 -
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 );
1551 - }
1552 -
1553 - $data = array(
1554 - 'environmentId' => 'cltef8cut1s7wyyfxy3rlxzs5',
1555 - '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,
1561 - ),
1562 - );
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 - }
1574 -
1575 - /**
1576 - * Count the charts.
1577 - *
1578 - * @param int $limit The count limit (optional).
1579 - *
1580 - * @return int The number of charts.
1581 - */
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 - );
1589 -
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%' );
1633 - }
1634 -
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 - );
1640 -
1641 - if ( ( $is_pro || $is_expired ) && ! empty( $pro_product_slug ) ) {
1642 - $config['plugin_meta_targets'] = array( $pro_product_slug );
1643 - }
1644 -
1645 - $config['message'] = $message;
1646 - $config['cta_label'] = $cta_label;
1647 -
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;
1656 1184 }
1657 1185 }