PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.4.0
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.4.0
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 +128 -858 4.0.53.4.0 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,25 +52,18 @@
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 - $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' );
57 + $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 8 );
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 );
84 62 $this->_addFilter( 'visualizer_logger_data', 'getLoggerData' );
63 + $this->_addFilter( 'visualizer_get_chart_counts', 'getChartCountsByTypeAndMeta' );
85 64 $this->_addFilter( 'visualizer_feedback_review_trigger', 'feedbackReviewTrigger' );
86 - $this->_addFilter( 'themeisle_sdk_blackfriday_data', 'add_black_friday_data' );
87 65
88 - // screen pagination
89 - $this->_addFilter( 'set-screen-option', 'setScreenOptions', 10, 3 );
90 -
91 66 // revision support.
92 67 $this->_addFilter( 'wp_revisions_to_keep', 'limitRevisions', null, 10, 2 );
93 68 $this->_addAction( '_wp_put_post_revision', 'addRevision', null, 10, 1 );
94 69 $this->_addAction( 'wp_restore_post_revision', 'restoreRevision', null, 10, 2 );
@@ -95,65 +70,12 @@
95 70
96 71 $this->_addAction( 'visualizer_chart_schedules_spl', 'addSplChartSchedules', null, 10, 3 );
97 72
98 73 $this->_addAction( 'admin_init', 'init' );
99 -
100 - $this->_addAction( 'visualizer_chart_languages', 'addMultilingualSupport' );
101 -
102 - $this->_addFilter( 'admin_footer_text', 'render_review_notice' );
103 -
104 - if ( ! defined( 'TI_E2E_TESTING' ) ) {
105 - $this->_addFilter( 'themeisle-sdk/survey/' . VISUALIZER_DIRNAME, 'get_survey_metadata', 10, 2 );
106 - }
107 -
108 - if ( defined( 'TI_E2E_TESTING' ) ) {
109 - $this->load_cypress_hooks();
110 - }
111 74 }
112 - /**
113 - * Display review notice.
114 - */
115 - public function render_review_notice( $footer_text ) {
116 - $current_screen = get_current_screen();
117 75
118 - $visualizer_page_ids = array( 'toplevel_page_visualizer', 'visualizer_page_viz-support', 'visualizer_page_ti-about-visualizer' );
119 76
120 - if ( ! empty( $current_screen ) && isset( $current_screen->id ) ) {
121 - foreach ( $visualizer_page_ids as $page_to_check ) {
122 - if ( strpos( $current_screen->id, $page_to_check ) !== false ) {
123 - $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 - __( 'Enjoying %1$s? %2$s %3$s rating. Thank you for being so supportive!', 'visualizer' ),
126 - '<b>Visualizer</b>',
127 - 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>'
129 - );
130 - break;
131 - }
132 - }
133 - }
134 -
135 - return $footer_text;
136 - }
137 -
138 -
139 77 /**
140 - * Define the hooks that are needed for cypress.
141 - *
142 - * @since 3.4.0
143 - * @access private
144 - */
145 - private function load_cypress_hooks() {
146 - // all charts should load on the same page without pagination.
147 - add_filter(
148 - 'visualizer_query_args', function ( $args ) {
149 - $args['posts_per_page'] = 20;
150 - return $args;
151 - }, 10, 1
152 - );
153 - }
154 -
155 - /**
156 78 * Add disabled `optgroup` schedules to the drop downs.
157 79 *
158 80 * @since ?
159 81 *
@@ -167,16 +89,23 @@
167 89 if ( apply_filters( 'visualizer_is_business', false ) ) {
168 90 return;
169 91 }
170 92
171 - $is_new_personal = apply_filters( 'visualizer_is_new_personal', false );
93 + $license = __( 'PRO', 'visualizer' );
94 + if ( Visualizer_Module::is_pro() ) {
95 + switch ( $plan ) {
96 + case 1:
97 + $license = __( 'Developer', 'visualizer' );
98 + break;
99 + }
100 + }
172 101
173 102 $hours = array(
174 - '0.16' => __( '10 minutes', 'visualizer' ),
175 - '1' => __( 'Each hour', 'visualizer' ),
176 - '12' => __( 'Each 12 hours', 'visualizer' ),
177 - '24' => __( 'Each day', 'visualizer' ),
178 - '72' => __( 'Each 3 days', 'visualizer' ),
103 + '0' => __( 'Live', 'visualizer' ),
104 + '1' => __( 'Each hour', 'visualizer' ),
105 + '12' => __( 'Each 12 hours', 'visualizer' ),
106 + '24' => __( 'Each day', 'visualizer' ),
107 + '72' => __( 'Each 3 days', 'visualizer' ),
179 108 );
180 109
181 110 switch ( $feature ) {
182 111 case 'json':
@@ -181,9 +110,9 @@
181 110 switch ( $feature ) {
182 111 case 'json':
183 112 case 'csv':
184 113 // no more schedules if pro is already active.
185 - if ( Visualizer_Module::is_pro() && ! $is_new_personal ) {
114 + if ( Visualizer_Module::is_pro() ) {
186 115 return;
187 116 }
188 117 break;
189 118 case 'wp':
@@ -193,9 +122,9 @@
193 122 default:
194 123 return;
195 124 }
196 125
197 - echo '<optgroup disabled label="' . __( 'Upgrade required', 'visualizer' ) . '">';
126 + echo '<optgroup disabled label="' . sprintf( __( 'More in the %s version', 'visualizer' ), $license ) . '">';
198 127 foreach ( $hours as $hour => $desc ) {
199 128 echo '<option disabled>' . $desc . '</option>';
200 129 }
201 130 echo '</optgroup>';
@@ -263,30 +192,17 @@
263 192 *
264 193 * @access public
265 194 */
266 195 public function init() {
267 - if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' === get_user_option( 'rich_editing' ) ) {
196 + // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
197 + if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' == get_user_option( 'rich_editing' ) ) {
268 198 $this->_addFilter( 'mce_external_languages', 'add_tinymce_lang', 10, 1 );
269 199 $this->_addFilter( 'mce_external_plugins', 'tinymce_plugin', 10, 1 );
270 200 $this->_addFilter( 'mce_buttons', 'register_mce_button', 10, 1 );
271 - $this->_addFilter( 'tiny_mce_before_init', 'get_strings_for_block', 10, 1 );
272 201 }
273 202 }
274 203
275 204 /**
276 - * Add the strings required for the TinyMCE buttons for the classic block (not the classic editor).
277 - *
278 - * @since ?
279 - * @access friendly
280 - */
281 - public function get_strings_for_block( $settings ) {
282 - $class = new Visualizer_Module_Language();
283 - $strings = $class->get_strings();
284 - $array = array( 'visualizer_tinymce_plugin' => json_encode( $strings ) );
285 - return array_merge( $settings, $array );
286 - }
287 -
288 - /**
289 205 * Load plugin translation for - TinyMCE API
290 206 *
291 207 * @access public
292 208 * @param array $arr The tinymce_lang array.
@@ -355,40 +271,15 @@
355 271 * @access public
356 272 */
357 273 public function enqueueMediaScripts() {
358 274 global $typenow;
359 - global $current_screen;
360 -
361 - if ( post_type_supports( $typenow, 'editor' ) || $current_screen->id === 'widgets' || $current_screen->id === 'customize' ) {
275 + if ( post_type_supports( $typenow, 'editor' ) ) {
362 276 wp_enqueue_style( 'visualizer-media', VISUALIZER_ABSURL . 'css/media.css', array( 'media-views' ), Visualizer_Plugin::VERSION );
363 277
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 278 // Load all the assets for the different libraries we support.
388 279 $deps = array(
389 280 Visualizer_Render_Sidebar_Google::enqueue_assets( array( 'media-editor' ) ),
390 - Visualizer_Render_Sidebar_Type_DataTable_Tabular::enqueue_assets( array( 'media-editor' ) ),
281 + Visualizer_Render_Sidebar_Type_DataTable_DataTable::enqueue_assets( array( 'media-editor' ) ),
391 282 );
392 283
393 284 wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', $deps, Visualizer_Plugin::VERSION, true );
394 285 wp_enqueue_script( 'visualizer-media-collection', VISUALIZER_ABSURL . 'js/media/collection.js', array( 'visualizer-media-model' ), Visualizer_Plugin::VERSION, true );
@@ -398,9 +289,9 @@
398 289 'visualizer-media-view',
399 290 'visualizer',
400 291 array(
401 292 'i10n' => array(
402 - 'insert' => __( 'Insert Chart', 'visualizer' ),
293 + 'insert' => __( 'Insert', 'visualizer' ),
403 294 ),
404 295 )
405 296 );
406 297 wp_enqueue_script( 'visualizer-media-toolbar', VISUALIZER_ABSURL . 'js/media/toolbar.js', array( 'visualizer-media-view' ), Visualizer_Plugin::VERSION, true );
@@ -429,9 +320,9 @@
429 320 'controller' => array(
430 321 'title' => esc_html__( 'Visualizations', 'visualizer' ),
431 322 ),
432 323 'routers' => array(
433 - 'library' => esc_html__( 'Insert from Library', 'visualizer' ),
324 + 'library' => esc_html__( 'From Library', 'visualizer' ),
434 325 'create' => esc_html__( 'Create New', 'visualizer' ),
435 326 ),
436 327 'library' => array(
437 328 'filters' => $chart_types,
@@ -437,9 +328,9 @@
437 328 'filters' => $chart_types,
438 329 'types' => array_keys( $chart_types ),
439 330 ),
440 331 'nonce' => wp_create_nonce(),
441 - 'buildurl' => esc_url( add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ) ),
332 + 'buildurl' => add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ),
442 333 );
443 334
444 335 return $strings;
445 336 }
@@ -461,17 +352,15 @@
461 352 'enabled' => true,
462 353 );
463 354 }
464 355
465 - $enabled = self::proFeaturesEnabled();
466 -
467 356 $types = array_merge(
468 357 $additional,
469 358 array(
470 - 'tabular' => array(
359 + 'dataTable' => array(
471 360 'name' => esc_html__( 'Table', 'visualizer' ),
472 361 'enabled' => true,
473 - 'supports' => $enabled ? array( 'Google Charts', 'DataTable' ) : array( 'DataTable' ),
362 + 'supports' => array( 'DataTable' ),
474 363 ),
475 364 'pie' => array(
476 365 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
477 366 'enabled' => true,
@@ -481,81 +370,75 @@
481 370 'name' => esc_html__( 'Line', 'visualizer' ),
482 371 'enabled' => true,
483 372 'supports' => array( 'Google Charts', 'ChartJS' ),
484 373 ),
485 - 'bar' => array(
486 - 'name' => esc_html__( 'Bar', 'visualizer' ),
487 - 'enabled' => true,
488 - 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
489 - ),
490 374 'area' => array(
491 375 'name' => esc_html__( 'Area', 'visualizer' ),
492 - 'enabled' => $enabled,
376 + 'enabled' => true,
493 377 // in ChartJS, the fill option is used to make Line chart an area: https://www.chartjs.org/docs/latest/charts/area.html
494 378 'supports' => array( 'Google Charts' ),
495 - 'demo_url' => 'https://demo.themeisle.com/visualizer/area-chart/',
496 379 ),
497 380 'geo' => array(
498 381 'name' => esc_html__( 'Geo', 'visualizer' ),
499 - 'enabled' => $enabled,
382 + 'enabled' => true,
500 383 'supports' => array( 'Google Charts' ),
501 - 'demo_url' => 'https://demo.themeisle.com/visualizer/geo-chart/',
502 384 ),
385 + 'bar' => array(
386 + 'name' => esc_html__( 'Bar', 'visualizer' ),
387 + 'enabled' => true,
388 + 'supports' => array( 'Google Charts', 'ChartJS' ),
389 + ),
503 390 'column' => array(
504 391 'name' => esc_html__( 'Column', 'visualizer' ),
505 - 'enabled' => $enabled,
392 + 'enabled' => true,
506 393 'supports' => array( 'Google Charts', 'ChartJS' ),
507 - 'demo_url' => 'https://demo.themeisle.com/visualizer/column-chart/',
508 394 ),
509 395 'bubble' => array(
510 396 'name' => esc_html__( 'Bubble', 'visualizer' ),
511 - 'enabled' => $enabled,
397 + 'enabled' => true,
512 398 // 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 399 'supports' => array( 'Google Charts' ),
514 - 'demo_url' => 'https://demo.themeisle.com/visualizer/bubble-chart/',
515 400 ),
516 401 'scatter' => array(
517 402 'name' => esc_html__( 'Scatter', 'visualizer' ),
518 - 'enabled' => $enabled,
403 + 'enabled' => true,
519 404 'supports' => array( 'Google Charts' ),
520 - 'demo_url' => 'https://demo.themeisle.com/visualizer/scatter-chart/',
521 405 ),
522 406 'gauge' => array(
523 407 'name' => esc_html__( 'Gauge', 'visualizer' ),
524 - 'enabled' => $enabled,
408 + 'enabled' => true,
525 409 'supports' => array( 'Google Charts' ),
526 - 'demo_url' => 'https://demo.themeisle.com/visualizer/gauge-chart/',
527 410 ),
528 411 'candlestick' => array(
529 412 'name' => esc_html__( 'Candlestick', 'visualizer' ),
530 - 'enabled' => $enabled,
413 + 'enabled' => true,
531 414 'supports' => array( 'Google Charts' ),
532 - 'demo_url' => 'https://demo.themeisle.com/visualizer/candlestick-chart/',
533 415 ),
534 416 // pro types
417 + 'table' => array(
418 + 'name' => esc_html__( 'Table (Deprecated)', 'visualizer' ),
419 + 'enabled' => false,
420 + 'supports' => array( 'Google Charts' ),
421 + ),
535 422 'timeline' => array(
536 423 'name' => esc_html__( 'Timeline', 'visualizer' ),
537 424 'enabled' => false,
538 425 'supports' => array( 'Google Charts', 'ChartJS' ),
539 - 'demo_url' => 'https://demo.themeisle.com/visualizer/timeline-chart/',
540 426 ),
541 427 'combo' => array(
542 428 'name' => esc_html__( 'Combo', 'visualizer' ),
543 429 'enabled' => false,
544 430 'supports' => array( 'Google Charts' ),
545 - 'demo_url' => 'https://demo.themeisle.com/visualizer/combo-chart/',
546 431 ),
547 432 'polarArea' => array(
548 433 'name' => esc_html__( 'Polar Area', 'visualizer' ),
549 434 'enabled' => false,
550 435 'supports' => array( 'ChartJS' ),
551 - 'demo_url' => 'https://demo.themeisle.com/visualizer/polar-area-chart/',
552 436 ),
553 437 'radar' => array(
554 438 'name' => esc_html__( 'Radar/Spider', 'visualizer' ),
555 439 'enabled' => false,
556 440 'supports' => array( 'ChartJS' ),
557 - 'demo_url' => 'https://demo.themeisle.com/visualizer/radar-spider-chart/',
558 441 ),
559 442 )
560 443 );
561 444 $types = apply_filters( 'visualizer_pro_chart_types', $types );
@@ -605,8 +488,18 @@
605 488 switch ( $where ) {
606 489 case 'types':
607 490 // fall-through
608 491 case 'library':
492 + // if the user has a Google Table chart, show it as deprecated otherwise remove the option from the library.
493 + if ( ! self::hasChartType( 'table' ) ) {
494 + $deprecated[] = 'table';
495 + if ( $get2Darray ) {
496 + $types['dataTable'] = esc_html__( 'Table', 'visualizer' );
497 + } else {
498 + $types['dataTable']['name'] = esc_html__( 'Table', 'visualizer' );
499 + }
500 + }
501 +
609 502 // if a user has a Gauge/Candlestick chart, then let them keep using it.
610 503 if ( ! Visualizer_Module::is_pro() ) {
611 504 if ( ! self::hasChartType( 'gauge' ) ) {
612 505 if ( $get2Darray ) {
@@ -624,8 +517,18 @@
624 517 }
625 518 }
626 519 break;
627 520 default:
521 + // remove the option to create a Google Table chart.
522 + $deprecated[] = 'table';
523 +
524 + // rename the new table chart type.
525 + if ( $get2Darray ) {
526 + $types['dataTable'] = esc_html__( 'Table', 'visualizer' );
527 + } else {
528 + $types['dataTable']['name'] = esc_html__( 'Table', 'visualizer' );
529 + }
530 +
628 531 // if a user has a Gauge/Candlestick chart, then let them keep using it.
629 532 if ( ! Visualizer_Module::is_pro() ) {
630 533 if ( ! self::hasChartType( 'gauge' ) ) {
631 534 if ( $get2Darray ) {
@@ -682,159 +585,44 @@
682 585 *
683 586 * @param string $suffix The current page suffix.
684 587 */
685 588 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 - }
589 + if ( $suffix === $this->_libraryPage ) {
590 + wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
591 + $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
592 + wp_enqueue_media();
715 593 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 ),
594 + 'visualizer-library',
595 + VISUALIZER_ABSURL . 'js/library.js',
596 + array(
597 + 'jquery',
598 + 'media-views',
599 + ),
719 600 Visualizer_Plugin::VERSION,
720 601 true
721 602 );
722 - if ( 'd3' === $library ) {
723 - $has_d3 = true;
724 - }
725 - }
726 603
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 - }
604 + wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
753 605
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,
606 + $query = $this->getQuery();
607 + while ( $query->have_posts() ) {
608 + $chart = $query->next_post();
609 + $library = $this->load_chart_type( $chart->ID );
610 + if ( is_null( $library ) ) {
611 + continue;
612 + }
613 + wp_enqueue_script(
614 + "visualizer-render-$library",
615 + VISUALIZER_ABSURL . 'js/render-facade.js',
616 + apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
617 + Visualizer_Plugin::VERSION,
769 618 true
770 619 );
771 620 }
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 621 }
820 -
821 - do_action( 'themeisle_internal_page', VISUALIZER_DIRNAME, 'library' );
822 622 }
823 623
824 624 /**
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 625 * Adds visualizer tab for media upload tabs array.
838 626 *
839 627 * @since 1.0.0
840 628 *
@@ -866,9 +654,9 @@
866 654 Visualizer_Plugin::NAME,
867 655 __( 'Chart Library', 'visualizer' ),
868 656 __( 'Chart Library', 'visualizer' ),
869 657 'edit_posts',
870 - 'admin.php?page=' . Visualizer_Plugin::NAME
658 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME )
871 659 );
872 660 add_submenu_page(
873 661 Visualizer_Plugin::NAME,
874 662 __( 'Add New Chart', 'visualizer' ),
@@ -873,22 +661,12 @@
873 661 Visualizer_Plugin::NAME,
874 662 __( 'Add New Chart', 'visualizer' ),
875 663 __( 'Add New Chart', 'visualizer' ),
876 664 'edit_posts',
877 - 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew'
665 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew' )
878 666 );
879 -
880 - $this->_settingsPage = add_submenu_page(
667 + add_submenu_page(
881 668 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 669 __( 'Support', 'visualizer' ),
892 670 __( '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 671 'edit_posts',
894 672 'viz-support',
@@ -893,151 +671,12 @@
893 671 'edit_posts',
894 672 'viz-support',
895 673 array( $this, 'renderSupportPage' )
896 674 );
897 -
898 675 remove_submenu_page( Visualizer_Plugin::NAME, Visualizer_Plugin::NAME );
899 -
900 - add_action( "load-{$this->_libraryPage}", array( $this, 'addScreenOptions' ) );
901 - add_action( 'admin_footer', array( $this, 'handleGetProSubMenu' ) );
902 676 }
903 677
904 678 /**
905 - * Handle get pro plugin submenu.
906 - */
907 - public function handleGetProSubMenu() {
908 - if ( ! Visualizer_Module::is_pro() ) {
909 - ?>
910 - <style type="text/css">
911 - #toplevel_page_visualizer ul.wp-submenu li:last-child {
912 - background: #FF7E65;
913 - font-size: 14px;
914 - font-weight: 600;
915 - color: #fff;
916 - }
917 - #toplevel_page_visualizer ul.wp-submenu li:last-child > a > span {
918 - color: #fff !important;
919 - }
920 - #toplevel_page_visualizer ul.wp-submenu li:last-child > a:hover {
921 - box-shadow: inherit;
922 - }
923 - </style>
924 - <?php
925 - if ( get_option( 'visualizer_fresh_install', false ) ) {
926 - ?>
927 - <style type="text/css">
928 - #toplevel_page_visualizer ul.wp-submenu li.wp-first-item + li + li + li {
929 - display: none;
930 - }
931 - </style>
932 - <?php
933 - }
934 - }
935 - }
936 -
937 - /**
938 - * Adds the screen options for pagination.
939 - */
940 - public function addScreenOptions() {
941 - $screen = get_current_screen();
942 -
943 - // bail if it's some other page.
944 - if ( ! is_object( $screen ) || $screen->id !== $this->_libraryPage ) {
945 - return;
946 - }
947 -
948 - $args = array(
949 - 'label' => __( 'Number of charts per page:', 'visualizer' ),
950 - 'default' => 6,
951 - 'option' => 'visualizer_library_per_page',
952 - );
953 - add_screen_option( 'per_page', $args );
954 - }
955 -
956 - /**
957 - * Returns the screen option for pagination.
958 - */
959 - public function setScreenOptions( $status, $option, $value ) {
960 - if ( 'visualizer_library_per_page' === $option ) {
961 - return $value;
962 - }
963 - }
964 -
965 - /**
966 - * Adds the display filters to be used in the meta_query while displaying the charts.
967 - */
968 - private function getDisplayFilters( &$query_args ) {
969 - $query = array();
970 - global $sitepress;
971 - if ( Visualizer_Module::is_pro() && ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) ) {
972 - $current_lang = icl_get_current_language();
973 - if ( in_array( $current_lang, array( 'all', icl_get_default_language() ), true ) ) {
974 - $query[] = array(
975 - 'key' => 'chart_lang',
976 - 'compare' => 'NOT EXISTS',
977 - );
978 - } else {
979 - $query[] = array(
980 - 'key' => 'chart_lang',
981 - 'value' => $current_lang,
982 - 'compare' => '=',
983 - );
984 - }
985 - }
986 -
987 - // add chart type filter to the query arguments
988 - $type = filter_input( INPUT_GET, 'type' );
989 - if ( $type && in_array( $type, Visualizer_Plugin::getChartTypes(), true ) ) {
990 - $query[] = array(
991 - 'key' => Visualizer_Plugin::CF_CHART_TYPE,
992 - 'value' => $type,
993 - 'compare' => '=',
994 - );
995 - }
996 -
997 - // add chart library filter to the query arguments
998 - $library = filter_input( INPUT_GET, 'library' );
999 - if ( $library ) {
1000 - $query[] = array(
1001 - 'key' => Visualizer_Plugin::CF_CHART_LIBRARY,
1002 - 'value' => $library,
1003 - 'compare' => '=',
1004 - );
1005 - }
1006 -
1007 - // add date filter to the query arguments
1008 - $date = filter_input( INPUT_GET, 'date' );
1009 - $possible = array_keys( Visualizer_Plugin::getSupportedDateFilter() );
1010 - if ( $date && in_array( $date, $possible, true ) ) {
1011 - $query_args['date_query'] = array(
1012 - 'after' => "$date -1 day",
1013 - 'inclusive' => true,
1014 - );
1015 - }
1016 -
1017 - // add source filter to the query arguments
1018 - $source = filter_input( INPUT_GET, 'source' );
1019 - if ( $source ) {
1020 - $source = ucwords( $source );
1021 - $source = "Visualizer_Source_{$source}";
1022 - $query[] = array(
1023 - 'key' => Visualizer_Plugin::CF_SOURCE,
1024 - 'value' => $source,
1025 - 'compare' => '=',
1026 - );
1027 - }
1028 -
1029 - $query_args['meta_query'] = $query;
1030 -
1031 - $orderby = filter_input( INPUT_GET, 'orderby' );
1032 - $order = filter_input( INPUT_GET, 'order' );
1033 - if ( $orderby ) {
1034 - $query_args['order_by'] = $orderby;
1035 - }
1036 - $query_args['order'] = empty( $order ) ? 'desc' : $order;
1037 - }
1038 -
1039 - /**
1040 679 * Get the instance of WP_Query that fetches the charts as per the given criteria.
1041 680 */
1042 681 private function getQuery() {
1043 682 static $q;
@@ -1056,34 +695,29 @@
1056 695 'default' => 1,
1057 696 ),
1058 697 )
1059 698 );
1060 -
1061 - $per_page = 6;
1062 - $screen = get_current_screen();
1063 - if ( $screen ) {
1064 - // retrieve the per_page option
1065 - $screen_option = $screen->get_option( 'per_page', 'option' );
1066 - // retrieve the value stored for the current user
1067 - $user = get_current_user_id();
1068 - $per_page = get_user_meta( $user, $screen_option, true );
1069 - if ( empty( $per_page ) || $per_page < 1 ) {
1070 - // nothing set, get the default value
1071 - $per_page = $screen->get_option( 'per_page', 'default' );
1072 - }
1073 - }
1074 -
1075 699 // the initial query arguments to fetch charts
1076 700 $query_args = array(
1077 701 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
1078 - 'posts_per_page' => $per_page,
702 + 'posts_per_page' => 6,
1079 703 'paged' => $page,
1080 704 );
1081 -
1082 - $this->getDisplayFilters( $query_args );
1083 -
705 + // add chart type filter to the query arguments
706 + $filter = filter_input( INPUT_GET, 'type' );
707 + if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) {
708 + $query_args['meta_query'] = array(
709 + array(
710 + 'key' => Visualizer_Plugin::CF_CHART_TYPE,
711 + 'value' => $filter,
712 + 'compare' => '=',
713 + ),
714 + );
715 + } else {
716 + $filter = 'all';
717 + }
1084 718 // Added by Ash/Upwork
1085 - $filterByMeta = ! empty( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
719 + $filterByMeta = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
1086 720 if ( $filterByMeta ) {
1087 721 $query = array(
1088 722 'key' => Visualizer_Plugin::CF_SETTINGS,
1089 723 'value' => $filterByMeta,
@@ -1092,9 +726,9 @@
1092 726 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
1093 727 $meta[] = $query;
1094 728 $query_args['meta_query'] = $meta;
1095 729 }
1096 - $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
730 + $q = new WP_Query( $query_args );
1097 731 return $q;
1098 732 }
1099 733
1100 734 /**
@@ -1109,91 +743,8 @@
1109 743 include_once VISUALIZER_ABSPATH . '/templates/support.php';
1110 744 }
1111 745
1112 746 /**
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 747 * Renders visualizer library page.
1197 748 *
1198 749 * @since 1.0.0
1199 750 *
@@ -1244,22 +795,10 @@
1244 795 unset( $settings['height'], $settings['width'], $settings['chartArea'] );
1245 796 }
1246 797
1247 798 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
1248 - $data = self::get_chart_data( $chart, $type );
799 + $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( $chart->post_content ) ), $chart->ID, $type );
1249 800
1250 - // Set default setting series when add manual chart data - Only during first creation.
1251 - if ( isset( $settings['series'] ) && ! empty( $series ) ) {
1252 - $count_series = count( $series ) - count( $settings['series'] );
1253 - if ( $count_series > 1 ) {
1254 - $clone_last_series = end( $settings['series'] );
1255 - $clone_last_series = array_fill_keys( array_keys( $clone_last_series ), '' );
1256 - foreach ( range( 1, $count_series ) as $item ) {
1257 - $settings['series'][] = $clone_last_series;
1258 - }
1259 - }
1260 - }
1261 -
1262 801 $library = $this->load_chart_type( $chart->ID );
1263 802
1264 803 $id = 'visualizer-' . $chart->ID;
1265 804 $arguments = $this->get_inline_custom_css( $id, $settings );
@@ -1267,19 +806,11 @@
1267 806 $css .= $arguments[0];
1268 807 $settings = $arguments[1];
1269 808 }
1270 809
1271 - if ( isset( $settings['controls']['ui']['labelStacking'] ) ) {
1272 - unset( $settings['controls']['ui']['labelStacking'] );
1273 - }
1274 - if ( isset( $settings['controls']['ui']['orientation'] ) ) {
1275 - unset( $settings['controls']['ui']['orientation'] );
1276 - }
1277 -
1278 810 // add chart to the array
1279 811 $charts[ $id ] = array(
1280 812 'id' => $chart->ID,
1281 - 'title' => $chart->post_title,
1282 813 'type' => $type,
1283 814 'series' => $series,
1284 815 'settings' => $settings,
1285 816 'data' => $data,
@@ -1284,15 +815,11 @@
1284 815 'settings' => $settings,
1285 816 'data' => $data,
1286 817 'library' => $library,
1287 818 );
1288 - if ( 'd3' === $library ) {
1289 - $charts[ $id ]['code'] = get_post_meta( $chart->ID, Visualizer_Module_AIBuilder::CF_D3_CODE, true );
1290 - }
1291 819 }
1292 820 // enqueue charts array
1293 821 $ajaxurl = admin_url( 'admin-ajax.php' );
1294 -
1295 822 wp_localize_script(
1296 823 'visualizer-library',
1297 824 'visualizer',
1298 825 array(
@@ -1299,39 +826,30 @@
1299 826 'language' => $this->get_language(),
1300 827 'map_api_key' => get_option( 'visualizer-map-api-key' ),
1301 828 'charts' => $charts,
1302 829 'urls' => array(
1303 - 'base' => esc_url( add_query_arg( array( 'vpage' => false, 'vaction' => false ) ) ),
1304 - 'create' => esc_url(
1305 - add_query_arg(
1306 - array(
1307 - 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
1308 - 'library' => 'yes',
1309 - 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
1310 - 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
1311 - 'vaction' => false,
1312 - ),
1313 - $ajaxurl
1314 - )
830 + 'base' => add_query_arg( array( 'vpage' => false, 'vaction' => false ) ),
831 + 'create' => add_query_arg(
832 + array(
833 + 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
834 + 'library' => 'yes',
835 + 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
836 + 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
837 + 'vaction' => false,
838 + ),
839 + $ajaxurl
1315 840 ),
1316 - 'edit' => esc_url(
1317 - add_query_arg(
1318 - array(
1319 - 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
1320 - 'library' => 'yes',
1321 - 'vaction' => false,
1322 - ),
1323 - $ajaxurl
1324 - )
841 + 'edit' => add_query_arg(
842 + array(
843 + 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
844 + 'library' => 'yes',
845 + 'vaction' => false,
846 + ),
847 + $ajaxurl
1325 848 ),
1326 849 ),
1327 850 'page_type' => 'library',
1328 851 'is_front' => false,
1329 - 'i10n' => array(
1330 - 'copied' => __( 'The shortcode has been copied to your clipboard. Hit Ctrl-V/Cmd-V to paste it.', 'visualizer' ),
1331 - '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' ),
1332 - ),
1333 - 'is_pro_user' => Visualizer_Module::is_pro(),
1334 852 )
1335 853 );
1336 854 // render library page
1337 855 $render = new Visualizer_Render_Library();
@@ -1347,9 +865,8 @@
1347 865 'total' => $query->max_num_pages,
1348 866 'type' => 'array',
1349 867 )
1350 868 );
1351 -
1352 869 $render->render();
1353 870 }
1354 871
1355 872 /**
@@ -1391,268 +908,21 @@
1391 908 *
1392 909 * @return array Updated array of plugin meta links.
1393 910 */
1394 911 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 912 if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
1410 - $is_black_friday = apply_filters( 'themeisle_sdk_is_black_friday_sale', false );
1411 913 // knowledge base link
1412 914 $plugin_meta[] = sprintf(
1413 915 '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1414 916 esc_html__( 'Docs', 'visualizer' )
1415 917 );
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 - }
918 + // flattr link
919 + $plugin_meta[] = sprintf(
920 + '<a style="color:red" href="' . Visualizer_Plugin::PRO_TEASER_URL . '" target="_blank">%s</a>',
921 + esc_html__( 'Pro Addon', 'visualizer' )
922 + );
1423 923 }
1424 924
1425 925 return $plugin_meta;
1426 926 }
1427 927
1428 - /**
1429 - * Returns true when premium chart types should be enabled for the current user.
1430 - *
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
1440 - */
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 ) {
1446 - return true;
1447 - }
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;
1460 - }
1461 -
1462 - /**
1463 - * Multilingual Support.
1464 - *
1465 - * @param int $chart_id Chart ID.
1466 - * @return bool Default false
1467 - */
1468 - public function addMultilingualSupport( $chart_id ) {
1469 - global $sitepress;
1470 - if ( Visualizer_Module::is_pro() ) {
1471 - return;
1472 - }
1473 - if ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) {
1474 - $language = icl_get_languages();
1475 - $current_lang = icl_get_current_language();
1476 - $default_lang = icl_get_default_language();
1477 - $post_info = wpml_get_language_information( null, $chart_id );
1478 - $translations = array();
1479 - if ( ! empty( $post_info ) && ( $default_lang === $post_info['language_code'] ) ) {
1480 - $trid = $sitepress->get_element_trid( $chart_id, 'post_' . Visualizer_Plugin::CPT_VISUALIZER );
1481 - $translations = $sitepress->get_element_translations( $trid );
1482 - }
1483 - if ( empty( $translations ) ) {
1484 - return;
1485 - }
1486 - ?>
1487 - <hr><div class="visualizer-languages-list only-pro">
1488 - <?php
1489 - foreach ( $language as $lang ) {
1490 - $lang_code = $lang['code'];
1491 - if ( $current_lang !== $lang_code ) {
1492 - ?>
1493 - <a href="javascript:;">
1494 - <img src="<?php echo esc_url( $lang['country_flag_url'] ); ?>" alt="<?php echo esc_attr( $lang['translated_name'] ); ?>">
1495 - </a>
1496 - <?php
1497 - }
1498 - }
1499 - ?>
1500 - <a href="<?php echo tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'wpml-support', 'visualizer_render_char' ); ?>"target="_blank"><?php esc_html_e( 'Upgrade to PRO to active this translation for charts', 'visualizer' ); ?></a>
1501 - </div>
1502 - <?php
1503 - }
1504 - }
1505 -
1506 - /**
1507 - * Check chart is enabled or not.
1508 - *
1509 - * @param string $type Chart ID.
1510 - *
1511 - * @return bool Default false
1512 - */
1513 - public static function checkChartStatus( $type ) {
1514 - $types = self::_getChartTypesLocalized( false, false, false, true );
1515 - if ( isset( $types[ $type ] ) ) {
1516 - return ! empty( $types[ $type ]['enabled'] );
1517 - }
1518 - return false;
1519 - }
1520 -
1521 - /**
1522 - * Get the survey metadata.
1523 - *
1524 - * @param array $data The data for survey in Formbricks format.
1525 - * @param string $page_slug The slug of the loaded page.
1526 - *
1527 - * @return array The survey metadata.
1528 - */
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 );
1532 -
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 );
1536 -
1537 - $plugin_data = get_plugin_data( VISUALIZER_BASEFILE, false, false );
1538 - $plugin_version = '';
1539 -
1540 - if ( ! empty( $plugin_data['Version'] ) ) {
1541 - $plugin_version = $plugin_data['Version'];
1542 - }
1543 -
1544 - $count_charts_cache_key = 'visualizer_count_charts';
1545 - $charts_number = get_transient( $count_charts_cache_key );
1546 -
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 );
1552 - }
1553 -
1554 - $data = array(
1555 - 'environmentId' => 'cltef8cut1s7wyyfxy3rlxzs5',
1556 - '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,
1562 - ),
1563 - );
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 - }
1575 -
1576 - /**
1577 - * Count the charts.
1578 - *
1579 - * @param int $limit The count limit (optional).
1580 - *
1581 - * @return int The number of charts.
1582 - */
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 - );
1590 -
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%' );
1634 - }
1635 -
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 - );
1641 -
1642 - if ( ( $is_pro || $is_expired ) && ! empty( $pro_product_slug ) ) {
1643 - $config['plugin_meta_targets'] = array( $pro_product_slug );
1644 - }
1645 -
1646 - $config['message'] = $message;
1647 - $config['cta_label'] = $cta_label;
1648 -
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;
1657 - }
1658 928 }