PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.11.14
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.11.14
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 +701 -115 3.1.33.11.14 View file →
@@ -40,8 +40,16 @@
40 40 */
41 41 private $_libraryPage;
42 42
43 43 /**
44 + * Support page suffix.
45 + *
46 + * @access private
47 + * @var string
48 + */
49 + private $_supportPage;
50 +
51 + /**
44 52 * Constructor.
45 53 *
46 54 * @since 1.0.0
47 55 *
@@ -52,26 +60,138 @@
52 60 public function __construct( Visualizer_Plugin $plugin ) {
53 61 parent::__construct( $plugin );
54 62 $this->_addAction( 'load-post.php', 'enqueueMediaScripts' );
55 63 $this->_addAction( 'load-post-new.php', 'enqueueMediaScripts' );
64 + $this->_addAction( 'enqueue_block_editor_assets', 'enqueueMediaScripts' );
56 65 $this->_addAction( 'admin_footer', 'renderTemplates' );
57 - $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 8 );
66 + $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 0 );
67 + $this->_addAction( 'admin_enqueue_scripts', 'enqueue_support_page' );
58 68 $this->_addAction( 'admin_menu', 'registerAdminMenu' );
59 69 $this->_addFilter( 'media_view_strings', 'setupMediaViewStrings' );
60 70 $this->_addFilter( 'plugin_action_links', 'getPluginActionLinks', 10, 2 );
71 + $this->_addFilter( 'plugin_row_meta', 'getPluginMetaLinks', 10, 2 );
61 72 $this->_addFilter( 'visualizer_logger_data', 'getLoggerData' );
62 - $this->_addFilter( 'visualizer_get_chart_counts', 'getChartCountsByTypeAndMeta' );
63 73 $this->_addFilter( 'visualizer_feedback_review_trigger', 'feedbackReviewTrigger' );
74 + $this->_addFilter( 'themeisle_sdk_blackfriday_data', 'add_black_friday_data' );
64 75
76 + // screen pagination
77 + $this->_addFilter( 'set-screen-option', 'setScreenOptions', 10, 3 );
78 +
65 79 // revision support.
66 80 $this->_addFilter( 'wp_revisions_to_keep', 'limitRevisions', null, 10, 2 );
67 81 $this->_addAction( '_wp_put_post_revision', 'addRevision', null, 10, 1 );
68 82 $this->_addAction( 'wp_restore_post_revision', 'restoreRevision', null, 10, 2 );
69 83
84 + $this->_addAction( 'visualizer_chart_schedules_spl', 'addSplChartSchedules', null, 10, 3 );
85 +
70 86 $this->_addAction( 'admin_init', 'init' );
87 +
88 + $this->_addAction( 'visualizer_chart_languages', 'addMultilingualSupport' );
89 +
90 + $this->_addFilter( 'admin_footer_text', 'render_review_notice' );
91 +
92 + if ( ! defined( 'TI_CYPRESS_TESTING' ) ) {
93 + $this->_addFilter( 'themeisle-sdk/survey/' . VISUALIZER_DIRNAME, 'get_survey_metadata', 10, 2 );
94 + }
95 +
96 + if ( defined( 'TI_CYPRESS_TESTING' ) ) {
97 + $this->load_cypress_hooks();
98 + }
99 +
71 100 }
101 + /**
102 + * Display review notice.
103 + */
104 + public function render_review_notice( $footer_text ) {
105 + $current_screen = get_current_screen();
72 106
107 + $visualizer_page_ids = ['toplevel_page_visualizer', 'visualizer_page_viz-support', 'visualizer_page_ti-about-visualizer' ];
108 +
109 + if ( ! empty( $current_screen ) && isset( $current_screen->id ) ) {
110 + foreach ( $visualizer_page_ids as $page_to_check ) {
111 + if ( strpos( $current_screen->id, $page_to_check ) !== false ) {
112 + $footer_text = sprintf(
113 + // translators: %1$s - the name of the plugin (Visualizer), %2$s - message (You can help us by leaving a), %3$s - HTML entity code.
114 + __( 'Enjoying %1$s? %2$s %3$s rating. Thank you for being so supportive!', 'visualizer' ),
115 + '<b>Visualizer</b>',
116 + esc_html__( 'You can help us by leaving a', 'visualizer' ),
117 + '<a href="https://wordpress.org/support/plugin/visualizer/reviews/" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
118 + );
119 + break;
120 + }
121 + }
122 + }
123 +
124 + return $footer_text;
125 + }
126 +
127 +
73 128 /**
129 + * Define the hooks that are needed for cypress.
130 + *
131 + * @since 3.4.0
132 + * @access private
133 + */
134 + private function load_cypress_hooks() {
135 + // all charts should load on the same page without pagination.
136 + add_filter(
137 + 'visualizer_query_args', function( $args ) {
138 + $args['posts_per_page'] = 20;
139 + return $args;
140 + }, 10, 1
141 + );
142 + }
143 +
144 + /**
145 + * Add disabled `optgroup` schedules to the drop downs.
146 + *
147 + * @since ?
148 + *
149 + * @access public
150 + *
151 + * @param string $feature The feature for which to add schedules.
152 + * @param int $chart_id The chart ID.
153 + * @param int $plan The plan number.
154 + */
155 + public function addSplChartSchedules( $feature, $chart_id, $plan ) {
156 + if ( apply_filters( 'visualizer_is_business', false ) ) {
157 + return;
158 + }
159 +
160 + $is_new_personal = apply_filters( 'visualizer_is_new_personal', false );
161 +
162 + $hours = array(
163 + '0.16' => __( '10 minutes', 'visualizer' ),
164 + '1' => __( 'Each hour', 'visualizer' ),
165 + '12' => __( 'Each 12 hours', 'visualizer' ),
166 + '24' => __( 'Each day', 'visualizer' ),
167 + '72' => __( 'Each 3 days', 'visualizer' ),
168 + );
169 +
170 + switch ( $feature ) {
171 + case 'json':
172 + case 'csv':
173 + // no more schedules if pro is already active.
174 + if ( Visualizer_Module::is_pro() && ! $is_new_personal ) {
175 + return;
176 + }
177 + break;
178 + case 'wp':
179 + // fall-through.
180 + case 'db':
181 + break;
182 + default:
183 + return;
184 + }
185 +
186 + echo '<optgroup disabled label="' . __( 'Upgrade required', 'visualizer' ) . '">';
187 + foreach ( $hours as $hour => $desc ) {
188 + echo '<option disabled>' . $desc . '</option>';
189 + }
190 + echo '</optgroup>';
191 + }
192 +
193 + /**
74 194 * No limits on revisions.
75 195 */
76 196 public function limitRevisions( $num, $post ) {
77 197 if ( Visualizer_Plugin::CPT_VISUALIZER === $post->post_type ) {
@@ -132,16 +252,31 @@
132 252 *
133 253 * @access public
134 254 */
135 255 public function init() {
256 + // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
136 257 if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' == get_user_option( 'rich_editing' ) ) {
137 258 $this->_addFilter( 'mce_external_languages', 'add_tinymce_lang', 10, 1 );
138 259 $this->_addFilter( 'mce_external_plugins', 'tinymce_plugin', 10, 1 );
139 260 $this->_addFilter( 'mce_buttons', 'register_mce_button', 10, 1 );
261 + $this->_addFilter( 'tiny_mce_before_init', 'get_strings_for_block', 10, 1 );
140 262 }
141 263 }
142 264
143 265 /**
266 + * Add the strings required for the TinyMCE buttons for the classic block (not the classic editor).
267 + *
268 + * @since ?
269 + * @access friendly
270 + */
271 + function get_strings_for_block( $settings ) {
272 + $class = new Visualizer_Module_Language();
273 + $strings = $class->get_strings();
274 + $array = array( 'visualizer_tinymce_plugin' => json_encode( $strings ) );
275 + return array_merge( $settings, $array );
276 + }
277 +
278 + /**
144 279 * Load plugin translation for - TinyMCE API
145 280 *
146 281 * @access public
147 282 * @param array $arr The tinymce_lang array.
@@ -210,15 +345,17 @@
210 345 * @access public
211 346 */
212 347 public function enqueueMediaScripts() {
213 348 global $typenow;
214 - if ( post_type_supports( $typenow, 'editor' ) ) {
349 + global $current_screen;
350 +
351 + if ( post_type_supports( $typenow, 'editor' ) || $current_screen->id === 'widgets' || $current_screen->id === 'customize' ) {
215 352 wp_enqueue_style( 'visualizer-media', VISUALIZER_ABSURL . 'css/media.css', array( 'media-views' ), Visualizer_Plugin::VERSION );
216 353
217 354 // Load all the assets for the different libraries we support.
218 355 $deps = array(
219 356 Visualizer_Render_Sidebar_Google::enqueue_assets( array( 'media-editor' ) ),
220 - Visualizer_Render_Sidebar_Type_DataTable::enqueue_assets( array( 'media-editor' ) ),
357 + Visualizer_Render_Sidebar_Type_DataTable_Tabular::enqueue_assets( array( 'media-editor' ) ),
221 358 );
222 359
223 360 wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', $deps, Visualizer_Plugin::VERSION, true );
224 361 wp_enqueue_script( 'visualizer-media-collection', VISUALIZER_ABSURL . 'js/media/collection.js', array( 'visualizer-media-model' ), Visualizer_Plugin::VERSION, true );
@@ -267,9 +404,9 @@
267 404 'filters' => $chart_types,
268 405 'types' => array_keys( $chart_types ),
269 406 ),
270 407 'nonce' => wp_create_nonce(),
271 - 'buildurl' => add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ),
408 + 'buildurl' => esc_url( add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ) ),
272 409 );
273 410
274 411 return $strings;
275 412 }
@@ -291,64 +428,102 @@
291 428 'enabled' => true,
292 429 );
293 430 }
294 431
432 + $enabled = self::proFeaturesLocked();
433 +
295 434 $types = array_merge(
296 435 $additional,
297 436 array(
298 - 'dataTable' => array(
299 - 'name' => esc_html__( 'Table (New)', 'visualizer' ),
437 + 'tabular' => array(
438 + 'name' => esc_html__( 'Table', 'visualizer' ),
300 439 'enabled' => true,
440 + 'supports' => $enabled ? array( 'Google Charts', 'DataTable' ) : array( 'DataTable' ),
301 441 ),
302 442 'pie' => array(
303 - 'name' => esc_html__( 'Pie', 'visualizer' ),
443 + 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
304 444 'enabled' => true,
445 + 'supports' => array( 'Google Charts', 'ChartJS' ),
305 446 ),
306 447 'line' => array(
307 448 'name' => esc_html__( 'Line', 'visualizer' ),
308 449 'enabled' => true,
450 + 'supports' => array( 'Google Charts', 'ChartJS' ),
309 451 ),
452 + 'bar' => array(
453 + 'name' => esc_html__( 'Bar', 'visualizer' ),
454 + 'enabled' => true,
455 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
456 + ),
310 457 'area' => array(
311 458 'name' => esc_html__( 'Area', 'visualizer' ),
312 - 'enabled' => true,
459 + 'enabled' => $enabled,
460 + // in ChartJS, the fill option is used to make Line chart an area: https://www.chartjs.org/docs/latest/charts/area.html
461 + 'supports' => array( 'Google Charts' ),
462 + 'demo_url' => 'https://demo.themeisle.com/visualizer/area-chart/',
313 463 ),
314 464 'geo' => array(
315 465 'name' => esc_html__( 'Geo', 'visualizer' ),
316 - 'enabled' => true,
466 + 'enabled' => $enabled,
467 + 'supports' => array( 'Google Charts' ),
468 + 'demo_url' => 'https://demo.themeisle.com/visualizer/geo-chart/',
317 469 ),
318 - 'bar' => array(
319 - 'name' => esc_html__( 'Bar', 'visualizer' ),
320 - 'enabled' => true,
321 - ),
322 470 'column' => array(
323 471 'name' => esc_html__( 'Column', 'visualizer' ),
324 - 'enabled' => true,
472 + 'enabled' => $enabled,
473 + 'supports' => array( 'Google Charts', 'ChartJS' ),
474 + 'demo_url' => 'https://demo.themeisle.com/visualizer/column-chart/',
325 475 ),
476 + 'bubble' => array(
477 + 'name' => esc_html__( 'Bubble', 'visualizer' ),
478 + 'enabled' => $enabled,
479 + // chartjs' bubble is ugly looking (and it won't work off the default bubble.csv) so it is being excluded for the time being.
480 + 'supports' => array( 'Google Charts' ),
481 + 'demo_url' => 'https://demo.themeisle.com/visualizer/bubble-chart/',
482 + ),
326 483 'scatter' => array(
327 484 'name' => esc_html__( 'Scatter', 'visualizer' ),
328 - 'enabled' => true,
485 + 'enabled' => $enabled,
486 + 'supports' => array( 'Google Charts' ),
487 + 'demo_url' => 'https://demo.themeisle.com/visualizer/scatter-chart/',
329 488 ),
330 489 'gauge' => array(
331 490 'name' => esc_html__( 'Gauge', 'visualizer' ),
332 - 'enabled' => true,
491 + 'enabled' => $enabled,
492 + 'supports' => array( 'Google Charts' ),
493 + 'demo_url' => 'https://demo.themeisle.com/visualizer/gauge-chart/',
333 494 ),
334 495 'candlestick' => array(
335 496 'name' => esc_html__( 'Candlestick', 'visualizer' ),
336 - 'enabled' => true,
497 + 'enabled' => $enabled,
498 + 'supports' => array( 'Google Charts' ),
499 + 'demo_url' => 'https://demo.themeisle.com/visualizer/candlestick-chart/',
337 500 ),
338 501 // pro types
339 - 'table' => array(
340 - 'name' => esc_html__( 'Table (Deprecated)', 'visualizer' ),
341 - 'enabled' => false,
342 - ),
343 502 'timeline' => array(
344 503 'name' => esc_html__( 'Timeline', 'visualizer' ),
345 504 'enabled' => false,
505 + 'supports' => array( 'Google Charts', 'ChartJS' ),
506 + 'demo_url' => 'https://demo.themeisle.com/visualizer/timeline-chart/',
346 507 ),
347 508 'combo' => array(
348 509 'name' => esc_html__( 'Combo', 'visualizer' ),
349 510 'enabled' => false,
511 + 'supports' => array( 'Google Charts' ),
512 + 'demo_url' => 'https://demo.themeisle.com/visualizer/combo-chart/',
350 513 ),
514 + 'polarArea' => array(
515 + 'name' => esc_html__( 'Polar Area', 'visualizer' ),
516 + 'enabled' => false,
517 + 'supports' => array( 'ChartJS' ),
518 + 'demo_url' => 'https://demo.themeisle.com/visualizer/polar-area-chart/',
519 + ),
520 + 'radar' => array(
521 + 'name' => esc_html__( 'Radar/Spider', 'visualizer' ),
522 + 'enabled' => false,
523 + 'supports' => array( 'ChartJS' ),
524 + 'demo_url' => 'https://demo.themeisle.com/visualizer/radar-spider-chart/',
525 + ),
351 526 )
352 527 );
353 528 $types = apply_filters( 'visualizer_pro_chart_types', $types );
354 529 if ( $enabledOnly ) {
@@ -357,8 +532,12 @@
357 532 if ( ! is_array( $array ) ) {
358 533 // support for old pro
359 534 $array = array( 'enabled' => true, 'name' => $array );
360 535 }
536 + // backward compatibility for PRO before v1.9.0
537 + if ( ! array_key_exists( 'supports', $array ) ) {
538 + $array['supports'] = array( 'Google Charts' );
539 + }
361 540 if ( ! $array['enabled'] ) {
362 541 continue;
363 542 }
364 543 $filtered[ $type ] = $array;
@@ -371,8 +550,12 @@
371 550 if ( ! is_array( $array ) ) {
372 551 // support for old pro
373 552 $array = array( 'enabled' => true, 'name' => $array );
374 553 }
554 + // backward compatibility for PRO before v1.9.0
555 + if ( ! array_key_exists( 'supports', $array ) ) {
556 + $array['supports'] = array( 'Google Charts' );
557 + }
375 558 $doubleD[ $type ] = $array['name'];
376 559 }
377 560 $types = $doubleD;
378 561 }
@@ -386,21 +569,13 @@
386 569 private static function handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where ) {
387 570 $deprecated = array();
388 571
389 572 switch ( $where ) {
573 + case 'types':
574 + // fall-through
390 575 case 'library':
391 - // if the user has a Google Table chart, show it as deprecated otherwise remove the option from the library.
392 - if ( ! self::hasChartType( 'table' ) ) {
393 - $deprecated[] = 'table';
394 - if ( $get2Darray ) {
395 - $types['dataTable'] = esc_html__( 'Table', 'visualizer' );
396 - } else {
397 - $types['dataTable']['name'] = esc_html__( 'Table', 'visualizer' );
398 - }
399 - }
400 -
401 576 // if a user has a Gauge/Candlestick chart, then let them keep using it.
402 - if ( ! VISUALIZER_PRO ) {
577 + if ( ! Visualizer_Module::is_pro() ) {
403 578 if ( ! self::hasChartType( 'gauge' ) ) {
404 579 if ( $get2Darray ) {
405 580 $deprecated[] = 'gauge';
406 581 } else {
@@ -416,20 +591,10 @@
416 591 }
417 592 }
418 593 break;
419 594 default:
420 - // remove the option to create a Google Table chart.
421 - $deprecated[] = 'table';
422 -
423 - // rename the new table chart type.
424 - if ( $get2Darray ) {
425 - $types['dataTable'] = esc_html__( 'Table', 'visualizer' );
426 - } else {
427 - $types['dataTable']['name'] = esc_html__( 'Table', 'visualizer' );
428 - }
429 -
430 595 // if a user has a Gauge/Candlestick chart, then let them keep using it.
431 - if ( ! VISUALIZER_PRO ) {
596 + if ( ! Visualizer_Module::is_pro() ) {
432 597 if ( ! self::hasChartType( 'gauge' ) ) {
433 598 if ( $get2Darray ) {
434 599 $deprecated[] = 'gauge';
435 600 } else {
@@ -464,9 +629,9 @@
464 629 * @access public
465 630 */
466 631 public function renderTemplates() {
467 632 global $pagenow;
468 - if ( 'post.php' != $pagenow && 'post-new.php' != $pagenow ) {
633 + if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
469 634 return;
470 635 }
471 636 $render = new Visualizer_Render_Templates();
472 637 $render->render();
@@ -484,41 +649,58 @@
484 649 *
485 650 * @param string $suffix The current page suffix.
486 651 */
487 652 public function enqueueLibraryScripts( $suffix ) {
488 - if ( $suffix == $this->_libraryPage ) {
489 - wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
490 - $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
491 - wp_enqueue_media();
653 + if ( $suffix !== $this->_libraryPage ) {
654 + return;
655 + }
656 +
657 + wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
658 + $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
659 + wp_enqueue_media();
660 + wp_enqueue_script(
661 + 'visualizer-library',
662 + VISUALIZER_ABSURL . 'js/library.js',
663 + array(
664 + 'jquery',
665 + 'media-views',
666 + 'clipboard',
667 + ),
668 + Visualizer_Plugin::VERSION,
669 + true
670 + );
671 +
672 + wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
673 +
674 + $query = $this->getQuery();
675 + while ( $query->have_posts() ) {
676 + $chart = $query->next_post();
677 + $library = $this->load_chart_type( $chart->ID );
678 + if ( is_null( $library ) ) {
679 + continue;
680 + }
492 681 wp_enqueue_script(
493 - 'visualizer-library',
494 - VISUALIZER_ABSURL . 'js/library.js',
495 - array(
496 - 'jquery',
497 - 'media-views',
498 - ),
682 + "visualizer-render-$library",
683 + VISUALIZER_ABSURL . 'js/render-facade.js',
684 + apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
499 685 Visualizer_Plugin::VERSION,
500 686 true
501 687 );
688 + }
502 689
503 - wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
690 + do_action( 'themeisle_internal_page', VISUALIZER_DIRNAME, 'library' );
691 + }
504 692
505 - $query = $this->getQuery();
506 - while ( $query->have_posts() ) {
507 - $chart = $query->next_post();
508 - $library = $this->load_chart_type( $chart->ID );
509 - if ( is_null( $library ) ) {
510 - continue;
511 - }
512 - wp_enqueue_script(
513 - "visualizer-render-$library",
514 - VISUALIZER_ABSURL . 'js/render-facade.js',
515 - apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
516 - Visualizer_Plugin::VERSION,
517 - true
518 - );
519 - }
693 + /**
694 + * Enqueue script for support page.
695 + *
696 + * @param string $hook_suffix Current hook.
697 + */
698 + public function enqueue_support_page( $hook_suffix ) {
699 + if ( $this->_supportPage !== $hook_suffix ) {
700 + return;
520 701 }
702 + do_action( 'themeisle_internal_page', VISUALIZER_DIRNAME, 'support' );
521 703 }
522 704
523 705 /**
524 706 * Adds visualizer tab for media upload tabs array.
@@ -544,14 +726,178 @@
544 726 *
545 727 * @access public
546 728 */
547 729 public function registerAdminMenu() {
548 - $title = esc_html__( 'Visualizer Library', 'visualizer' );
549 - $callback = array( $this, 'renderLibraryPage' );
550 - $this->_libraryPage = add_submenu_page( 'upload.php', $title, $title, 'edit_posts', Visualizer_Plugin::NAME, $callback );
730 + $svg_base64_icon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNzdweCIgaGVpZ2h0PSI3N3B4IiB2aWV3Qm94PSIwIDAgNzcgNzciIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjYgKDY3NDkxKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Db21iaW5lZCBTaGFwZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxnIGlkPSJQcm9kdWN0LVBhZ2UiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJXb3JkUHJlc3MtcGx1Z2lucyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE5MC4wMDAwMDAsIC00MzUuMDAwMDAwKSIgZmlsbD0iIzM5QzNEMiI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMjguNSw1MTIgQzIwNy4yMzcwMzcsNTEyIDE5MCw0OTQuNzYyOTYzIDE5MCw0NzMuNSBDMTkwLDQ1Mi4yMzcwMzcgMjA3LjIzNzAzNyw0MzUgMjI4LjUsNDM1IEMyNDkuNzYyOTYzLDQzNSAyNjcsNDUyLjIzNzAzNyAyNjcsNDczLjUgQzI2Nyw0OTQuNzYyOTYzIDI0OS43NjI5NjMsNTEyIDIyOC41LDUxMiBaIE0yNDYuODQzNzUsNDgzLjU5MjA1OSBMMjE1LjYyNSw0ODMuNTkyMDU5IEwyMTUuNjI1LDQ2MC44MjY1NDQgQzIxNS42MjUsNDYwLjE2NDU0NyAyMTUuMTA3NTc4LDQ1OS42MjgzNTkgMjE0LjQ2ODc1LDQ1OS42MjgzNTkgTDIxMi4xNTYyNSw0NTkuNjI4MzU5IEMyMTEuNTE3NDIyLDQ1OS42MjgzNTkgMjExLDQ2MC4xNjQ1NDcgMjExLDQ2MC44MjY1NDQgTDIxMSw0ODUuOTg4NDI5IEMyMTEsNDg3LjMxMTY3NCAyMTIuMDM1NTY2LDQ4OC4zODQ3OTggMjEzLjMxMjUsNDg4LjM4NDc5OCBMMjQ2Ljg0Mzc1LDQ4OC4zODQ3OTggQzI0Ny40ODI1NzgsNDg4LjM4NDc5OCAyNDgsNDg3Ljg0ODYxMSAyNDgsNDg3LjE4NjYxMyBMMjQ4LDQ4NC43OTAyNDQgQzI0OCw0ODQuMTI4MjQ2IDI0Ny40ODI1NzgsNDgzLjU5MjA1OSAyNDYuODQzNzUsNDgzLjU5MjA1OSBaIE0yNDQuNTMxMjUsNDYyLjAyNDcyOSBMMjM1Ljk5OTU3LDQ2Mi4wMjQ3MjkgQzIzNC40NTQ1MzEsNDYyLjAyNDcyOSAyMzMuNjgwNTY2LDQ2My45NjA1NDcgMjM0Ljc3MzIyMyw0NjUuMDkyODMyIEwyMzcuMTE0NjI5LDQ2Ny41MTkxNTYgTDIzMS44MTI1LDQ3My4wMTQzMzIgTDIyNi41MTAzNzEsNDY3LjUxOTkwNSBDMjI1LjYwNzA1MSw0NjYuNTgzODIzIDIyNC4xNDI5NDksNDY2LjU4MzgyMyAyMjMuMjQwMzUyLDQ2Ny41MTk5MDUgTDIxOC4yNzY0MjYsNDcyLjY2Mzg2MyBDMjE3LjgyNDc2Niw0NzMuMTMxOTA0IDIxNy44MjQ3NjYsNDczLjg5MDUwNSAyMTguMjc2NDI2LDQ3NC4zNTg1NDYgTDIxOS45MTEwNzQsNDc2LjA1MjQ4IEMyMjAuMzYyNzM0LDQ3Ni41MjA1MjEgMjIxLjA5NDc4NSw0NzYuNTIwNTIxIDIyMS41NDY0NDUsNDc2LjA1MjQ4IEwyMjQuODc1LDQ3Mi42MDI0NTYgTDIzMC4xNzcxMjksNDc4LjA5Njg4MyBDMjMxLjA4MDQ0OSw0NzkuMDMyOTY1IDIzMi41NDQ1NTEsNDc5LjAzMjk2NSAyMzMuNDQ3MTQ4LDQ3OC4wOTY4ODMgTDI0MC4zODQ2NDgsNDcwLjkwNzc3MyBMMjQyLjcyNjA1NSw0NzMuMzM0MDk4IEMyNDMuODE4NzExLDQ3NC40NjYzODIgMjQ1LjY4Njc3Nyw0NzMuNjY0MzQ3IDI0NS42ODY3NzcsNDcyLjA2MzI3MyBMMjQ1LjY4Njc3Nyw0NjMuMjIyOTE0IEMyNDUuNjg3NSw0NjIuNTYwOTE3IDI0NS4xNzAwNzgsNDYyLjAyNDcyOSAyNDQuNTMxMjUsNDYyLjAyNDcyOSBaIiBpZD0iQ29tYmluZWQtU2hhcGUiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==';
731 +
732 + $this->_libraryPage = add_menu_page( __( 'Visualizer', 'visualizer' ), __( 'Visualizer', 'visualizer' ), 'edit_posts', Visualizer_Plugin::NAME, array( $this, 'renderLibraryPage' ), $svg_base64_icon, 99.7666 );
733 +
734 + add_submenu_page(
735 + Visualizer_Plugin::NAME,
736 + __( 'Chart Library', 'visualizer' ),
737 + __( 'Chart Library', 'visualizer' ),
738 + 'edit_posts',
739 + 'admin.php?page=' . Visualizer_Plugin::NAME
740 + );
741 + add_submenu_page(
742 + Visualizer_Plugin::NAME,
743 + __( 'Add New Chart', 'visualizer' ),
744 + __( 'Add New Chart', 'visualizer' ),
745 + 'edit_posts',
746 + 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew'
747 + );
748 +
749 + $this->_supportPage = add_submenu_page(
750 + Visualizer_Plugin::NAME,
751 + __( 'Support', 'visualizer' ),
752 + __( '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>',
753 + 'edit_posts',
754 + 'viz-support',
755 + array( $this, 'renderSupportPage' )
756 + );
757 +
758 + remove_submenu_page( Visualizer_Plugin::NAME, Visualizer_Plugin::NAME );
759 +
760 + add_action( "load-{$this->_libraryPage}", array( $this, 'addScreenOptions' ) );
761 + add_action( 'admin_footer', array( $this, 'handleGetProSubMenu' ) );
551 762 }
552 763
553 764 /**
765 + * Handle get pro plugin submenu.
766 + */
767 + public function handleGetProSubMenu() {
768 + if ( ! Visualizer_Module::is_pro() ) {
769 + ?>
770 + <style type="text/css">
771 + #toplevel_page_visualizer ul.wp-submenu li:last-child {
772 + background: #FF7E65;
773 + font-size: 14px;
774 + font-weight: 600;
775 + color: #fff;
776 + }
777 + #toplevel_page_visualizer ul.wp-submenu li:last-child > a > span {
778 + color: #fff !important;
779 + }
780 + #toplevel_page_visualizer ul.wp-submenu li:last-child > a:hover {
781 + box-shadow: inherit;
782 + }
783 + </style>
784 + <?php
785 + if ( get_option( 'visualizer_fresh_install', false ) ) {
786 + ?>
787 + <style type="text/css">
788 + #toplevel_page_visualizer ul.wp-submenu li.wp-first-item + li + li + li {
789 + display: none;
790 + }
791 + </style>
792 + <?php
793 + }
794 + }
795 + }
796 +
797 + /**
798 + * Adds the screen options for pagination.
799 + */
800 + function addScreenOptions() {
801 + $screen = get_current_screen();
802 +
803 + // bail if it's some other page.
804 + if ( ! is_object( $screen ) || $screen->id !== $this->_libraryPage ) {
805 + return;
806 + }
807 +
808 + $args = array(
809 + 'label' => __( 'Number of charts per page:', 'visualizer' ),
810 + 'default' => 6,
811 + 'option' => 'visualizer_library_per_page',
812 + );
813 + add_screen_option( 'per_page', $args );
814 + }
815 +
816 + /**
817 + * Returns the screen option for pagination.
818 + */
819 + function setScreenOptions( $status, $option, $value ) {
820 + if ( 'visualizer_library_per_page' === $option ) {
821 + return $value;
822 + }
823 + }
824 +
825 + /**
826 + * Adds the display filters to be used in the meta_query while displaying the charts.
827 + */
828 + private function getDisplayFilters( &$query_args ) {
829 + $query = array();
830 + global $sitepress;
831 + if ( Visualizer_Module::is_pro() && ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) ) {
832 + $current_lang = icl_get_current_language();
833 + if ( in_array( $current_lang, array( 'all', icl_get_default_language() ), true ) ) {
834 + $query[] = array(
835 + 'key' => 'chart_lang',
836 + 'compare' => 'NOT EXISTS',
837 + );
838 + } else {
839 + $query[] = array(
840 + 'key' => 'chart_lang',
841 + 'value' => $current_lang,
842 + 'compare' => '=',
843 + );
844 + }
845 + }
846 +
847 + // add chart type filter to the query arguments
848 + $type = filter_input( INPUT_GET, 'type' );
849 + if ( $type && in_array( $type, Visualizer_Plugin::getChartTypes(), true ) ) {
850 + $query[] = array(
851 + 'key' => Visualizer_Plugin::CF_CHART_TYPE,
852 + 'value' => $type,
853 + 'compare' => '=',
854 + );
855 + }
856 +
857 + // add chart library filter to the query arguments
858 + $library = filter_input( INPUT_GET, 'library' );
859 + if ( $library ) {
860 + $query[] = array(
861 + 'key' => Visualizer_Plugin::CF_CHART_LIBRARY,
862 + 'value' => $library,
863 + 'compare' => '=',
864 + );
865 + }
866 +
867 + // add date filter to the query arguments
868 + $date = filter_input( INPUT_GET, 'date' );
869 + $possible = array_keys( Visualizer_Plugin::getSupportedDateFilter() );
870 + if ( $date && in_array( $date, $possible, true ) ) {
871 + $query_args['date_query'] = array(
872 + 'after' => "$date -1 day",
873 + 'inclusive' => true,
874 + );
875 + }
876 +
877 + // add source filter to the query arguments
878 + $source = filter_input( INPUT_GET, 'source' );
879 + if ( $source ) {
880 + $source = ucwords( $source );
881 + $source = "Visualizer_Source_{$source}";
882 + $query[] = array(
883 + 'key' => Visualizer_Plugin::CF_SOURCE,
884 + 'value' => $source,
885 + 'compare' => '=',
886 + );
887 + }
888 +
889 + $query_args['meta_query'] = $query;
890 +
891 + $orderby = filter_input( INPUT_GET, 'orderby' );
892 + $order = filter_input( INPUT_GET, 'order' );
893 + if ( $orderby ) {
894 + $query_args['order_by'] = $orderby;
895 + }
896 + $query_args['order'] = empty( $order ) ? 'desc' : $order;
897 + }
898 +
899 + /**
554 900 * Get the instance of WP_Query that fetches the charts as per the given criteria.
555 901 */
556 902 private function getQuery() {
557 903 static $q;
@@ -570,29 +916,34 @@
570 916 'default' => 1,
571 917 ),
572 918 )
573 919 );
920 +
921 + $per_page = 6;
922 + $screen = get_current_screen();
923 + if ( $screen ) {
924 + // retrieve the per_page option
925 + $screen_option = $screen->get_option( 'per_page', 'option' );
926 + // retrieve the value stored for the current user
927 + $user = get_current_user_id();
928 + $per_page = get_user_meta( $user, $screen_option, true );
929 + if ( empty( $per_page ) || $per_page < 1 ) {
930 + // nothing set, get the default value
931 + $per_page = $screen->get_option( 'per_page', 'default' );
932 + }
933 + }
934 +
574 935 // the initial query arguments to fetch charts
575 936 $query_args = array(
576 937 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
577 - 'posts_per_page' => 6,
938 + 'posts_per_page' => $per_page,
578 939 'paged' => $page,
579 940 );
580 - // add chart type filter to the query arguments
581 - $filter = filter_input( INPUT_GET, 'type' );
582 - if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) {
583 - $query_args['meta_query'] = array(
584 - array(
585 - 'key' => Visualizer_Plugin::CF_CHART_TYPE,
586 - 'value' => $filter,
587 - 'compare' => '=',
588 - ),
589 - );
590 - } else {
591 - $filter = 'all';
592 - }
941 +
942 + $this->getDisplayFilters( $query_args );
943 +
593 944 // Added by Ash/Upwork
594 - $filterByMeta = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
945 + $filterByMeta = ! empty( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
595 946 if ( $filterByMeta ) {
596 947 $query = array(
597 948 'key' => Visualizer_Plugin::CF_SETTINGS,
598 949 'value' => $filterByMeta,
@@ -601,13 +952,25 @@
601 952 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
602 953 $meta[] = $query;
603 954 $query_args['meta_query'] = $meta;
604 955 }
605 - $q = new WP_Query( $query_args );
956 + $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
606 957 return $q;
607 958 }
608 959
609 960 /**
961 + * Renders support page.
962 + *
963 + * @since 3.3.0
964 + *
965 + * @access public
966 + */
967 + public function renderSupportPage() {
968 + wp_enqueue_style( 'visualizer-upsell', VISUALIZER_ABSURL . 'css/upsell.css', array(), Visualizer_Plugin::VERSION );
969 + include_once VISUALIZER_ABSPATH . '/templates/support.php';
970 + }
971 +
972 + /**
610 973 * Renders visualizer library page.
611 974 *
612 975 * @since 1.0.0
613 976 *
@@ -630,9 +993,9 @@
630 993 )
631 994 );
632 995 // add chart type filter to the query arguments
633 996 $filter = filter_input( INPUT_GET, 'type' );
634 - if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) ) {
997 + if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) ) {
635 998 $filter = 'all';
636 999 }
637 1000
638 1001 $css = '';
@@ -653,12 +1016,27 @@
653 1016 if ( ! empty( $atts['settings'] ) ) {
654 1017 $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
655 1018 }
656 1019
657 - unset( $settings['height'], $settings['width'] );
1020 + if ( $settings ) {
1021 + unset( $settings['height'], $settings['width'], $settings['chartArea'] );
1022 + }
1023 +
658 1024 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
659 - $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( $chart->post_content ) ), $chart->ID, $type );
1025 + $data = self::get_chart_data( $chart, $type );
660 1026
1027 + // Set default setting series when add manual chart data - Only during first creation.
1028 + if ( isset( $settings['series'] ) && ! empty( $series ) ) {
1029 + $count_series = count( $series ) - count( $settings['series'] );
1030 + if ( $count_series > 1 ) {
1031 + $clone_last_series = end( $settings['series'] );
1032 + $clone_last_series = array_fill_keys( array_keys( $clone_last_series ), '' );
1033 + foreach ( range( 1, $count_series ) as $item ) {
1034 + $settings['series'][] = $clone_last_series;
1035 + }
1036 + }
1037 + }
1038 +
661 1039 $library = $this->load_chart_type( $chart->ID );
662 1040
663 1041 $id = 'visualizer-' . $chart->ID;
664 1042 $arguments = $this->get_inline_custom_css( $id, $settings );
@@ -666,8 +1044,15 @@
666 1044 $css .= $arguments[0];
667 1045 $settings = $arguments[1];
668 1046 }
669 1047
1048 + if ( isset( $settings['controls']['ui']['labelStacking'] ) ) {
1049 + unset( $settings['controls']['ui']['labelStacking'] );
1050 + }
1051 + if ( isset( $settings['controls']['ui']['orientation'] ) ) {
1052 + unset( $settings['controls']['ui']['orientation'] );
1053 + }
1054 +
670 1055 // add chart to the array
671 1056 $charts[ $id ] = array(
672 1057 'id' => $chart->ID,
673 1058 'type' => $type,
@@ -678,8 +1063,9 @@
678 1063 );
679 1064 }
680 1065 // enqueue charts array
681 1066 $ajaxurl = admin_url( 'admin-ajax.php' );
1067 +
682 1068 wp_localize_script(
683 1069 'visualizer-library',
684 1070 'visualizer',
685 1071 array(
@@ -686,26 +1072,39 @@
686 1072 'language' => $this->get_language(),
687 1073 'map_api_key' => get_option( 'visualizer-map-api-key' ),
688 1074 'charts' => $charts,
689 1075 'urls' => array(
690 - 'base' => add_query_arg( 'vpage', false ),
691 - 'create' => add_query_arg(
692 - array(
693 - 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
694 - 'library' => 'yes',
695 - 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
696 - ),
697 - $ajaxurl
1076 + 'base' => esc_url( add_query_arg( array( 'vpage' => false, 'vaction' => false ) ) ),
1077 + 'create' => esc_url(
1078 + add_query_arg(
1079 + array(
1080 + 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
1081 + 'library' => 'yes',
1082 + 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
1083 + 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
1084 + 'vaction' => false,
1085 + ),
1086 + $ajaxurl
1087 + )
698 1088 ),
699 - 'edit' => add_query_arg(
700 - array(
701 - 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
702 - 'library' => 'yes',
703 - ),
704 - $ajaxurl
1089 + 'edit' => esc_url(
1090 + add_query_arg(
1091 + array(
1092 + 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
1093 + 'library' => 'yes',
1094 + 'vaction' => false,
1095 + ),
1096 + $ajaxurl
1097 + )
705 1098 ),
706 1099 ),
707 1100 'page_type' => 'library',
1101 + 'is_front' => false,
1102 + 'i10n' => array(
1103 + 'copied' => __( 'The shortcode has been copied to your clipboard. Hit Ctrl-V/Cmd-V to paste it.', 'visualizer' ),
1104 + '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' ),
1105 + ),
1106 + 'is_pro_user' => Visualizer_Module::is_pro(),
708 1107 )
709 1108 );
710 1109 // render library page
711 1110 $render = new Visualizer_Render_Library();
@@ -714,9 +1113,9 @@
714 1113 $render->types = self::_getChartTypesLocalized( false, false, false, true );
715 1114 $render->custom_css = $css;
716 1115 $render->pagination = paginate_links(
717 1116 array(
718 - 'base' => add_query_arg( 'vpage', '%#%' ),
1117 + 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
719 1118 'format' => '',
720 1119 'current' => $page,
721 1120 'total' => $query->max_num_pages,
722 1121 'type' => 'array',
@@ -721,8 +1120,9 @@
721 1120 'total' => $query->max_num_pages,
722 1121 'type' => 'array',
723 1122 )
724 1123 );
1124 +
725 1125 $render->render();
726 1126 }
727 1127
728 1128 /**
@@ -737,14 +1137,14 @@
737 1137 *
738 1138 * @return array Updated array of action links.
739 1139 */
740 1140 public function getPluginActionLinks( $links, $file ) {
741 - if ( $file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1141 + if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
742 1142 array_unshift(
743 1143 $links,
744 1144 sprintf(
745 1145 '<a href="%s">%s</a>',
746 - admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ),
1146 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
747 1147 esc_html__( 'Library', 'visualizer' )
748 1148 )
749 1149 );
750 1150 }
@@ -764,18 +1164,18 @@
764 1164 *
765 1165 * @return array Updated array of plugin meta links.
766 1166 */
767 1167 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
768 - if ( $plugin_file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1168 + if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
769 1169 // knowledge base link
770 1170 $plugin_meta[] = sprintf(
771 - '<a href="https://github.com/codeinwp/visualizer/wiki" target="_blank">%s</a>',
772 - esc_html__( 'Knowledge Base', 'visualizer' )
1171 + '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1172 + esc_html__( 'Docs', 'visualizer' )
773 1173 );
774 1174 // flattr link
775 1175 $plugin_meta[] = sprintf(
776 - '<a style="color:red" href="https://themeisle.com/plugins/visualizer-charts-and-graphs-pro-addon/" target="_blank">%s</a>',
777 - esc_html__( 'Pro Addon', 'visualizer' )
1176 + '<a style="color:red" href="' . tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'pluginrow' ) . '" target="_blank">%s</a>',
1177 + esc_html__( 'Get Visualizer Pro', 'visualizer' )
778 1178 );
779 1179 }
780 1180
781 1181 return $plugin_meta;
@@ -780,5 +1180,191 @@
780 1180
781 1181 return $plugin_meta;
782 1182 }
783 1183
1184 + /**
1185 + * If check is existing user.
1186 + *
1187 + * @return bool Default false
1188 + */
1189 + public static function proFeaturesLocked() {
1190 + if ( Visualizer_Module::is_pro() ) {
1191 + return true;
1192 + }
1193 + return 'yes' === get_option( 'visualizer-new-user', 'yes' ) ? false : true;
1194 + }
1195 +
1196 + /**
1197 + * Multilingual Support.
1198 + *
1199 + * @param int $chart_id Chart ID.
1200 + * @return bool Default false
1201 + */
1202 + public function addMultilingualSupport( $chart_id ) {
1203 + global $sitepress;
1204 + if ( Visualizer_Module::is_pro() ) {
1205 + return;
1206 + }
1207 + if ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) {
1208 + $language = icl_get_languages();
1209 + $current_lang = icl_get_current_language();
1210 + $default_lang = icl_get_default_language();
1211 + $post_info = wpml_get_language_information( null, $chart_id );
1212 + $translations = array();
1213 + if ( ! empty( $post_info ) && ( $default_lang === $post_info['language_code'] ) ) {
1214 + $trid = $sitepress->get_element_trid( $chart_id, 'post_' . Visualizer_Plugin::CPT_VISUALIZER );
1215 + $translations = $sitepress->get_element_translations( $trid );
1216 + }
1217 + if ( empty( $translations ) ) {
1218 + return;
1219 + }
1220 + ?>
1221 + <hr><div class="visualizer-languages-list only-pro">
1222 + <?php
1223 + foreach ( $language as $lang ) {
1224 + $lang_code = $lang['code'];
1225 + if ( $current_lang !== $lang_code ) {
1226 + ?>
1227 + <a href="javascript:;">
1228 + <img src="<?php echo esc_url( $lang['country_flag_url'] ); ?>" alt="<?php echo esc_attr( $lang['translated_name'] ); ?>">
1229 + </a>
1230 + <?php
1231 + }
1232 + }
1233 + ?>
1234 + <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>
1235 + </div>
1236 + <?php
1237 + }
1238 + }
1239 +
1240 + /**
1241 + * Check chart is enabled or not.
1242 + *
1243 + * @param string $type Chart ID.
1244 + *
1245 + * @return bool Default false
1246 + */
1247 + public static function checkChartStatus( $type ) {
1248 + $types = self::_getChartTypesLocalized( false, false, false, true );
1249 + if ( isset( $types[ $type ] ) ) {
1250 + return ! empty( $types[ $type ]['enabled'] );
1251 + }
1252 + return false;
1253 + }
1254 +
1255 + /**
1256 + * Get the survey metadata.
1257 + *
1258 + * @param array $data The data for survey in Formbricks format.
1259 + * @param string $page_slug The slug of the loaded page.
1260 + *
1261 + * @return array The survey metadata.
1262 + */
1263 + public function get_survey_metadata( $data, $page_slug ) {
1264 + $install_date = get_option( 'visualizer_install', time() );
1265 + $install_days_number = intval( ( time() - $install_date ) / DAY_IN_SECONDS );
1266 +
1267 + $license_status = apply_filters( 'product_visualizer_license_status', 'invalid' );
1268 + $license_plan = apply_filters( 'product_visualizer_license_plan', false );
1269 + $license_key = apply_filters( 'product_visualizer_license_key', false );
1270 +
1271 + $plugin_data = get_plugin_data( VISUALIZER_BASEFILE, false, false );
1272 + $plugin_version = '';
1273 +
1274 + if ( ! empty( $plugin_data['Version'] ) ) {
1275 + $plugin_version = $plugin_data['Version'];
1276 + }
1277 +
1278 + $count_charts_cache_key = 'visualizer_count_charts';
1279 + $charts_number = get_transient( $count_charts_cache_key );
1280 +
1281 + if ( false === $charts_number ) {
1282 + $charts_number = $this->count_charts( 100 );
1283 + set_transient( $count_charts_cache_key, $charts_number, 100 === $charts_number ? WEEK_IN_SECONDS : 6 * HOUR_IN_SECONDS );
1284 + } else {
1285 + $charts_number = strval( $charts_number );
1286 + }
1287 +
1288 + $data = array(
1289 + 'environmentId' => 'cltef8cut1s7wyyfxy3rlxzs5',
1290 + 'attributes' => array(
1291 + 'free_version' => $plugin_version,
1292 + 'pro_version' => defined( 'VISUALIZER_PRO_VERSION' ) ? VISUALIZER_PRO_VERSION : '',
1293 + 'license_status' => $license_status,
1294 + 'install_days_number' => $install_days_number,
1295 + 'charts_number' => $charts_number,
1296 + ),
1297 + );
1298 +
1299 + if ( ! empty( $license_plan ) ) {
1300 + $data['attributes']['plan'] = $license_plan;
1301 + }
1302 +
1303 + if ( ! empty( $license_key ) ) {
1304 + $data['attributes']['license_key'] = apply_filters( 'themeisle_sdk_secret_masking', $license_key );
1305 + }
1306 +
1307 + return $data;
1308 + }
1309 +
1310 + /**
1311 + * Count the charts.
1312 + *
1313 + * @param int $limit The count limit (optional).
1314 + *
1315 + * @return int The number of charts.
1316 + */
1317 + public function count_charts( $limit = -1 ) {
1318 + $args = array(
1319 + 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
1320 + 'post_status' => 'publish',
1321 + 'posts_per_page' => $limit,
1322 + 'fields' => 'ids',
1323 + );
1324 +
1325 + $query = new WP_Query( $args);
1326 + return $query->post_count;
1327 + }
1328 +
1329 + /**
1330 + * Set the black friday data.
1331 + *
1332 + * @param array $configs The configuration array for the loaded products.
1333 + * @return array
1334 + */
1335 + public function add_black_friday_data( $configs ) {
1336 + $config = $configs['default'];
1337 +
1338 + // translators: %1$s - HTML tag, %2$s - discount, %3$s - HTML tag, %4$s - product name.
1339 + $message_template = __( 'Our biggest sale of the year: %1$sup to %2$s OFF%3$s on %4$s. Don\'t miss this limited-time offer.', 'visualizer' );
1340 + $product_label = 'Visualizer';
1341 + $discount = '70%';
1342 +
1343 + $plan = apply_filters( 'product_visualizer_license_plan', 0 );
1344 + $license = apply_filters( 'product_visualizer_license_key', false );
1345 + $is_pro = 0 < $plan;
1346 +
1347 + if ( $is_pro ) {
1348 + // translators: %1$s - HTML tag, %2$s - discount, %3$s - HTML tag, %4$s - product name.
1349 + $message_template = __( 'Get %1$sup to %2$s off%3$s when you upgrade your %4$s plan or renew early.', 'visualizer' );
1350 + $product_label = 'Visualizer Pro';
1351 + $discount = '30%';
1352 + }
1353 +
1354 + $product_label = sprintf( '<strong>%s</strong>', $product_label );
1355 + $url_params = array(
1356 + 'utm_term' => $is_pro ? 'plan-' . $plan : 'free',
1357 + 'lkey' => ! empty( $license ) ? $license : false,
1358 + );
1359 +
1360 + $config['message'] = sprintf( $message_template, '<strong>', $discount, '</strong>', $product_label );
1361 + $config['sale_url'] = add_query_arg(
1362 + $url_params,
1363 + tsdk_translate_link( tsdk_utmify( 'https://themeisle.link/vizualizer-bf', 'bfcm', 'visualizer' ) )
1364 + );
1365 +
1366 + $configs[ VISUALIZER_DIRNAME ] = $config;
1367 +
1368 + return $configs;
1369 + }
784 1370 }