PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.11.7
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.11.7
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 3.10.4 All 148 releases
← All changes | classes/Visualizer/Module/Admin.php +772 -95 3.0.83.11.7 View file →
@@ -52,26 +52,131 @@
52 52 public function __construct( Visualizer_Plugin $plugin ) {
53 53 parent::__construct( $plugin );
54 54 $this->_addAction( 'load-post.php', 'enqueueMediaScripts' );
55 55 $this->_addAction( 'load-post-new.php', 'enqueueMediaScripts' );
56 - $this->_addAction( 'admin_footer', 'renderTempaltes' );
57 - $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 8 );
56 + $this->_addAction( 'enqueue_block_editor_assets', 'enqueueMediaScripts' );
57 + $this->_addAction( 'admin_footer', 'renderTemplates' );
58 + $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 0 );
58 59 $this->_addAction( 'admin_menu', 'registerAdminMenu' );
59 60 $this->_addFilter( 'media_view_strings', 'setupMediaViewStrings' );
60 61 $this->_addFilter( 'plugin_action_links', 'getPluginActionLinks', 10, 2 );
62 + $this->_addFilter( 'plugin_row_meta', 'getPluginMetaLinks', 10, 2 );
61 63 $this->_addFilter( 'visualizer_logger_data', 'getLoggerData' );
62 - $this->_addFilter( 'visualizer_get_chart_counts', 'getChartCountsByTypeAndMeta' );
63 64 $this->_addFilter( 'visualizer_feedback_review_trigger', 'feedbackReviewTrigger' );
64 65
66 + // screen pagination
67 + $this->_addFilter( 'set-screen-option', 'setScreenOptions', 10, 3 );
68 +
65 69 // revision support.
66 70 $this->_addFilter( 'wp_revisions_to_keep', 'limitRevisions', null, 10, 2 );
67 71 $this->_addAction( '_wp_put_post_revision', 'addRevision', null, 10, 1 );
68 72 $this->_addAction( 'wp_restore_post_revision', 'restoreRevision', null, 10, 2 );
69 73
74 + $this->_addAction( 'visualizer_chart_schedules_spl', 'addSplChartSchedules', null, 10, 3 );
75 +
70 76 $this->_addAction( 'admin_init', 'init' );
77 +
78 + $this->_addAction( 'visualizer_chart_languages', 'addMultilingualSupport' );
79 +
80 + $this->_addFilter( 'admin_footer_text', 'render_review_notice' );
81 +
82 + if ( defined( 'TI_CYPRESS_TESTING' ) ) {
83 + $this->load_cypress_hooks();
84 + }
85 +
71 86 }
87 + /**
88 + * Display review notice.
89 + */
90 + public function render_review_notice( $footer_text ) {
91 + $current_screen = get_current_screen();
72 92
93 + $visualizer_page_ids = ['toplevel_page_visualizer', 'visualizer_page_viz-support', 'visualizer_page_ti-about-visualizer' ];
94 +
95 + if ( ! empty( $current_screen ) && isset( $current_screen->id ) ) {
96 + foreach ( $visualizer_page_ids as $page_to_check ) {
97 + if ( strpos( $current_screen->id, $page_to_check ) !== false ) {
98 + $footer_text = sprintf(
99 + __( 'Enjoying %1$s? %2$s %3$s rating. Thank you for being so supportive!', 'visualizer' ),
100 + '<b>Visualizer</b>',
101 + esc_html__( 'You can help us by leaving a', 'visualizer' ),
102 + '<a href="https://wordpress.org/support/plugin/visualizer/reviews/" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
103 + );
104 + break;
105 + }
106 + }
107 + }
108 +
109 + return $footer_text;
110 + }
111 +
112 +
73 113 /**
114 + * Define the hooks that are needed for cypress.
115 + *
116 + * @since 3.4.0
117 + * @access private
118 + */
119 + private function load_cypress_hooks() {
120 + // all charts should load on the same page without pagination.
121 + add_filter(
122 + 'visualizer_query_args', function( $args ) {
123 + $args['posts_per_page'] = 20;
124 + return $args;
125 + }, 10, 1
126 + );
127 + }
128 +
129 + /**
130 + * Add disabled `optgroup` schedules to the drop downs.
131 + *
132 + * @since ?
133 + *
134 + * @access public
135 + *
136 + * @param string $feature The feature for which to add schedules.
137 + * @param int $chart_id The chart ID.
138 + * @param int $plan The plan number.
139 + */
140 + public function addSplChartSchedules( $feature, $chart_id, $plan ) {
141 + if ( apply_filters( 'visualizer_is_business', false ) ) {
142 + return;
143 + }
144 +
145 + $is_new_personal = apply_filters( 'visualizer_is_new_personal', false );
146 +
147 + $hours = array(
148 + '0.16' => __( '10 minutes', 'visualizer' ),
149 + '1' => __( 'Each hour', 'visualizer' ),
150 + '12' => __( 'Each 12 hours', 'visualizer' ),
151 + '24' => __( 'Each day', 'visualizer' ),
152 + '72' => __( 'Each 3 days', 'visualizer' ),
153 + );
154 +
155 + switch ( $feature ) {
156 + case 'json':
157 + case 'csv':
158 + // no more schedules if pro is already active.
159 + if ( Visualizer_Module::is_pro() && ! $is_new_personal ) {
160 + return;
161 + }
162 + break;
163 + case 'wp':
164 + // fall-through.
165 + case 'db':
166 + break;
167 + default:
168 + return;
169 + }
170 +
171 + echo '<optgroup disabled label="' . __( 'Upgrade required', 'visualizer' ) . '">';
172 + foreach ( $hours as $hour => $desc ) {
173 + echo '<option disabled>' . $desc . '</option>';
174 + }
175 + echo '</optgroup>';
176 + }
177 +
178 + /**
74 179 * No limits on revisions.
75 180 */
76 181 public function limitRevisions( $num, $post ) {
77 182 if ( Visualizer_Plugin::CPT_VISUALIZER === $post->post_type ) {
@@ -132,16 +237,31 @@
132 237 *
133 238 * @access public
134 239 */
135 240 public function init() {
241 + // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
136 242 if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' == get_user_option( 'rich_editing' ) ) {
137 243 $this->_addFilter( 'mce_external_languages', 'add_tinymce_lang', 10, 1 );
138 244 $this->_addFilter( 'mce_external_plugins', 'tinymce_plugin', 10, 1 );
139 245 $this->_addFilter( 'mce_buttons', 'register_mce_button', 10, 1 );
246 + $this->_addFilter( 'tiny_mce_before_init', 'get_strings_for_block', 10, 1 );
140 247 }
141 248 }
142 249
143 250 /**
251 + * Add the strings required for the TinyMCE buttons for the classic block (not the classic editor).
252 + *
253 + * @since ?
254 + * @access friendly
255 + */
256 + function get_strings_for_block( $settings ) {
257 + $class = new Visualizer_Module_Language();
258 + $strings = $class->get_strings();
259 + $array = array( 'visualizer_tinymce_plugin' => json_encode( $strings ) );
260 + return array_merge( $settings, $array );
261 + }
262 +
263 + /**
144 264 * Load plugin translation for - TinyMCE API
145 265 *
146 266 * @access public
147 267 * @param array $arr The tinymce_lang array.
@@ -210,18 +330,27 @@
210 330 * @access public
211 331 */
212 332 public function enqueueMediaScripts() {
213 333 global $typenow;
214 - if ( post_type_supports( $typenow, 'editor' ) ) {
334 + global $current_screen;
335 +
336 + if ( post_type_supports( $typenow, 'editor' ) || $current_screen->id === 'widgets' || $current_screen->id === 'customize' ) {
215 337 wp_enqueue_style( 'visualizer-media', VISUALIZER_ABSURL . 'css/media.css', array( 'media-views' ), Visualizer_Plugin::VERSION );
216 - wp_enqueue_script( 'visualizer-google-jsapi-new', '//www.gstatic.com/charts/loader.js', array( 'media-editor' ), null, true );
217 - wp_enqueue_script( 'visualizer-google-jsapi-old', '//www.google.com/jsapi', array( 'visualizer-google-jsapi-new' ), null, true );
218 - wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', array( 'visualizer-google-jsapi-old' ), Visualizer_Plugin::VERSION, true );
338 +
339 + // Load all the assets for the different libraries we support.
340 + $deps = array(
341 + Visualizer_Render_Sidebar_Google::enqueue_assets( array( 'media-editor' ) ),
342 + Visualizer_Render_Sidebar_Type_DataTable_Tabular::enqueue_assets( array( 'media-editor' ) ),
343 + );
344 +
345 + wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', $deps, Visualizer_Plugin::VERSION, true );
219 346 wp_enqueue_script( 'visualizer-media-collection', VISUALIZER_ABSURL . 'js/media/collection.js', array( 'visualizer-media-model' ), Visualizer_Plugin::VERSION, true );
220 347 wp_enqueue_script( 'visualizer-media-controller', VISUALIZER_ABSURL . 'js/media/controller.js', array( 'visualizer-media-collection' ), Visualizer_Plugin::VERSION, true );
221 348 wp_enqueue_script( 'visualizer-media-view', VISUALIZER_ABSURL . 'js/media/view.js', array( 'visualizer-media-controller' ), Visualizer_Plugin::VERSION, true );
222 349 wp_localize_script(
223 - 'visualizer-media-view', 'visualizer', array(
350 + 'visualizer-media-view',
351 + 'visualizer',
352 + array(
224 353 'i10n' => array(
225 354 'insert' => __( 'Insert', 'visualizer' ),
226 355 ),
227 356 )
@@ -260,9 +389,9 @@
260 389 'filters' => $chart_types,
261 390 'types' => array_keys( $chart_types ),
262 391 ),
263 392 'nonce' => wp_create_nonce(),
264 - 'buildurl' => add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ),
393 + 'buildurl' => esc_url( add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ) ),
265 394 );
266 395
267 396 return $strings;
268 397 }
@@ -275,9 +404,9 @@
275 404 * @static
276 405 * @access private
277 406 * @return array The associated array of chart types with localized names.
278 407 */
279 - public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false, $add_select = false ) {
408 + public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false, $add_select = false, $where = null ) {
280 409 $additional = array();
281 410 if ( $add_select ) {
282 411 $additional['select'] = array(
283 412 'name' => esc_html__( 'All', 'visualizer' ),
@@ -284,59 +413,102 @@
284 413 'enabled' => true,
285 414 );
286 415 }
287 416
417 + $enabled = self::proFeaturesLocked();
418 +
288 419 $types = array_merge(
289 - $additional, array(
420 + $additional,
421 + array(
422 + 'tabular' => array(
423 + 'name' => esc_html__( 'Table', 'visualizer' ),
424 + 'enabled' => true,
425 + 'supports' => $enabled ? array( 'Google Charts', 'DataTable' ) : array( 'DataTable' ),
426 + ),
290 427 'pie' => array(
291 - 'name' => esc_html__( 'Pie', 'visualizer' ),
428 + 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
292 429 'enabled' => true,
430 + 'supports' => array( 'Google Charts', 'ChartJS' ),
293 431 ),
294 432 'line' => array(
295 433 'name' => esc_html__( 'Line', 'visualizer' ),
296 434 'enabled' => true,
435 + 'supports' => array( 'Google Charts', 'ChartJS' ),
297 436 ),
437 + 'bar' => array(
438 + 'name' => esc_html__( 'Bar', 'visualizer' ),
439 + 'enabled' => true,
440 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
441 + ),
298 442 'area' => array(
299 443 'name' => esc_html__( 'Area', 'visualizer' ),
300 - 'enabled' => true,
444 + 'enabled' => $enabled,
445 + // in ChartJS, the fill option is used to make Line chart an area: https://www.chartjs.org/docs/latest/charts/area.html
446 + 'supports' => array( 'Google Charts' ),
447 + 'demo_url' => 'https://demo.themeisle.com/visualizer/area-chart/',
301 448 ),
302 449 'geo' => array(
303 450 'name' => esc_html__( 'Geo', 'visualizer' ),
304 - 'enabled' => true,
451 + 'enabled' => $enabled,
452 + 'supports' => array( 'Google Charts' ),
453 + 'demo_url' => 'https://demo.themeisle.com/visualizer/geo-chart/',
305 454 ),
306 - 'bar' => array(
307 - 'name' => esc_html__( 'Bar', 'visualizer' ),
308 - 'enabled' => true,
309 - ),
310 455 'column' => array(
311 456 'name' => esc_html__( 'Column', 'visualizer' ),
312 - 'enabled' => true,
457 + 'enabled' => $enabled,
458 + 'supports' => array( 'Google Charts', 'ChartJS' ),
459 + 'demo_url' => 'https://demo.themeisle.com/visualizer/column-chart/',
313 460 ),
314 - 'gauge' => array(
315 - 'name' => esc_html__( 'Gauge', 'visualizer' ),
316 - 'enabled' => true,
461 + 'bubble' => array(
462 + 'name' => esc_html__( 'Bubble', 'visualizer' ),
463 + 'enabled' => $enabled,
464 + // chartjs' bubble is ugly looking (and it won't work off the default bubble.csv) so it is being excluded for the time being.
465 + 'supports' => array( 'Google Charts' ),
466 + 'demo_url' => 'https://demo.themeisle.com/visualizer/bubble-chart/',
317 467 ),
318 468 'scatter' => array(
319 469 'name' => esc_html__( 'Scatter', 'visualizer' ),
320 - 'enabled' => true,
470 + 'enabled' => $enabled,
471 + 'supports' => array( 'Google Charts' ),
472 + 'demo_url' => 'https://demo.themeisle.com/visualizer/scatter-chart/',
321 473 ),
474 + 'gauge' => array(
475 + 'name' => esc_html__( 'Gauge', 'visualizer' ),
476 + 'enabled' => $enabled,
477 + 'supports' => array( 'Google Charts' ),
478 + 'demo_url' => 'https://demo.themeisle.com/visualizer/gauge-chart/',
479 + ),
322 480 'candlestick' => array(
323 481 'name' => esc_html__( 'Candlestick', 'visualizer' ),
324 - 'enabled' => true,
482 + 'enabled' => $enabled,
483 + 'supports' => array( 'Google Charts' ),
484 + 'demo_url' => 'https://demo.themeisle.com/visualizer/candlestick-chart/',
325 485 ),
326 486 // pro types
327 - 'table' => array(
328 - 'name' => esc_html__( 'Table', 'visualizer' ),
329 - 'enabled' => false,
330 - ),
331 487 'timeline' => array(
332 488 'name' => esc_html__( 'Timeline', 'visualizer' ),
333 489 'enabled' => false,
490 + 'supports' => array( 'Google Charts', 'ChartJS' ),
491 + 'demo_url' => 'https://demo.themeisle.com/visualizer/timeline-chart/',
334 492 ),
335 493 'combo' => array(
336 494 'name' => esc_html__( 'Combo', 'visualizer' ),
337 495 'enabled' => false,
496 + 'supports' => array( 'Google Charts' ),
497 + 'demo_url' => 'https://demo.themeisle.com/visualizer/combo-chart/',
338 498 ),
499 + 'polarArea' => array(
500 + 'name' => esc_html__( 'Polar Area', 'visualizer' ),
501 + 'enabled' => false,
502 + 'supports' => array( 'ChartJS' ),
503 + 'demo_url' => 'https://demo.themeisle.com/visualizer/polar-area-chart/',
504 + ),
505 + 'radar' => array(
506 + 'name' => esc_html__( 'Radar/Spider', 'visualizer' ),
507 + 'enabled' => false,
508 + 'supports' => array( 'ChartJS' ),
509 + 'demo_url' => 'https://demo.themeisle.com/visualizer/radar-spider-chart/',
510 + ),
339 511 )
340 512 );
341 513 $types = apply_filters( 'visualizer_pro_chart_types', $types );
342 514 if ( $enabledOnly ) {
@@ -345,8 +517,12 @@
345 517 if ( ! is_array( $array ) ) {
346 518 // support for old pro
347 519 $array = array( 'enabled' => true, 'name' => $array );
348 520 }
521 + // backward compatibility for PRO before v1.9.0
522 + if ( ! array_key_exists( 'supports', $array ) ) {
523 + $array['supports'] = array( 'Google Charts' );
524 + }
349 525 if ( ! $array['enabled'] ) {
350 526 continue;
351 527 }
352 528 $filtered[ $type ] = $array;
@@ -359,13 +535,74 @@
359 535 if ( ! is_array( $array ) ) {
360 536 // support for old pro
361 537 $array = array( 'enabled' => true, 'name' => $array );
362 538 }
539 + // backward compatibility for PRO before v1.9.0
540 + if ( ! array_key_exists( 'supports', $array ) ) {
541 + $array['supports'] = array( 'Google Charts' );
542 + }
363 543 $doubleD[ $type ] = $array['name'];
364 544 }
365 545 $types = $doubleD;
366 546 }
367 547
548 + return self::handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where );
549 + }
550 +
551 + /**
552 + * Handle (soon-to-be) deprecated charts.
553 + */
554 + private static function handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where ) {
555 + $deprecated = array();
556 +
557 + switch ( $where ) {
558 + case 'types':
559 + // fall-through
560 + case 'library':
561 + // if a user has a Gauge/Candlestick chart, then let them keep using it.
562 + if ( ! Visualizer_Module::is_pro() ) {
563 + if ( ! self::hasChartType( 'gauge' ) ) {
564 + if ( $get2Darray ) {
565 + $deprecated[] = 'gauge';
566 + } else {
567 + $types['gauge']['enabled'] = false;
568 + }
569 + }
570 + if ( ! self::hasChartType( 'candlestick' ) ) {
571 + if ( $get2Darray ) {
572 + $deprecated[] = 'candlestick';
573 + } else {
574 + $types['candlestick']['enabled'] = false;
575 + }
576 + }
577 + }
578 + break;
579 + default:
580 + // if a user has a Gauge/Candlestick chart, then let them keep using it.
581 + if ( ! Visualizer_Module::is_pro() ) {
582 + if ( ! self::hasChartType( 'gauge' ) ) {
583 + if ( $get2Darray ) {
584 + $deprecated[] = 'gauge';
585 + } else {
586 + $types['gauge']['enabled'] = false;
587 + }
588 + }
589 + if ( ! self::hasChartType( 'candlestick' ) ) {
590 + if ( $get2Darray ) {
591 + $deprecated[] = 'candlestick';
592 + } else {
593 + $types['candlestick']['enabled'] = false;
594 + }
595 + }
596 + }
597 + }
598 +
599 + if ( $deprecated ) {
600 + foreach ( $deprecated as $type ) {
601 + unset( $types[ $type ] );
602 + }
603 + }
604 +
368 605 return $types;
369 606 }
370 607
371 608 /**
@@ -375,11 +612,11 @@
375 612 * @global string $pagenow The name of the current page.
376 613 *
377 614 * @access public
378 615 */
379 - public function renderTempaltes() {
616 + public function renderTemplates() {
380 617 global $pagenow;
381 - if ( 'post.php' != $pagenow && 'post-new.php' != $pagenow ) {
618 + if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
382 619 return;
383 620 }
384 621 $render = new Visualizer_Render_Templates();
385 622 $render->render();
@@ -397,26 +634,41 @@
397 634 *
398 635 * @param string $suffix The current page suffix.
399 636 */
400 637 public function enqueueLibraryScripts( $suffix ) {
401 - if ( $suffix == $this->_libraryPage ) {
638 + if ( $suffix === $this->_libraryPage ) {
402 639 wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
403 640 $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
404 641 wp_enqueue_media();
405 642 wp_enqueue_script(
406 - 'visualizer-library', VISUALIZER_ABSURL . 'js/library.js', array(
643 + 'visualizer-library',
644 + VISUALIZER_ABSURL . 'js/library.js',
645 + array(
407 646 'jquery',
408 647 'media-views',
409 - ), Visualizer_Plugin::VERSION, true
648 + 'clipboard',
649 + ),
650 + Visualizer_Plugin::VERSION,
651 + true
410 652 );
411 - wp_enqueue_script( 'google-jsapi-new', '//www.gstatic.com/charts/loader.js', array(), null, true );
412 - wp_enqueue_script( 'google-jsapi-old', '//www.google.com/jsapi', array( 'google-jsapi-new' ), null, true );
413 - wp_enqueue_script(
414 - 'visualizer-render', VISUALIZER_ABSURL . 'js/render.js', array(
415 - 'google-jsapi-old',
416 - 'visualizer-library',
417 - ), Visualizer_Plugin::VERSION, true
418 - );
653 +
654 + wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
655 +
656 + $query = $this->getQuery();
657 + while ( $query->have_posts() ) {
658 + $chart = $query->next_post();
659 + $library = $this->load_chart_type( $chart->ID );
660 + if ( is_null( $library ) ) {
661 + continue;
662 + }
663 + wp_enqueue_script(
664 + "visualizer-render-$library",
665 + VISUALIZER_ABSURL . 'js/render-facade.js',
666 + apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
667 + Visualizer_Plugin::VERSION,
668 + true
669 + );
670 + }
419 671 }
420 672 }
421 673
422 674 /**
@@ -443,24 +695,191 @@
443 695 *
444 696 * @access public
445 697 */
446 698 public function registerAdminMenu() {
447 - $title = esc_html__( 'Visualizer Library', 'visualizer' );
448 - $callback = array( $this, 'renderLibraryPage' );
449 - $this->_libraryPage = add_submenu_page( 'upload.php', $title, $title, 'edit_posts', Visualizer_Plugin::NAME, $callback );
699 + $svg_base64_icon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNzdweCIgaGVpZ2h0PSI3N3B4IiB2aWV3Qm94PSIwIDAgNzcgNzciIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjYgKDY3NDkxKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Db21iaW5lZCBTaGFwZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxnIGlkPSJQcm9kdWN0LVBhZ2UiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJXb3JkUHJlc3MtcGx1Z2lucyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE5MC4wMDAwMDAsIC00MzUuMDAwMDAwKSIgZmlsbD0iIzM5QzNEMiI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMjguNSw1MTIgQzIwNy4yMzcwMzcsNTEyIDE5MCw0OTQuNzYyOTYzIDE5MCw0NzMuNSBDMTkwLDQ1Mi4yMzcwMzcgMjA3LjIzNzAzNyw0MzUgMjI4LjUsNDM1IEMyNDkuNzYyOTYzLDQzNSAyNjcsNDUyLjIzNzAzNyAyNjcsNDczLjUgQzI2Nyw0OTQuNzYyOTYzIDI0OS43NjI5NjMsNTEyIDIyOC41LDUxMiBaIE0yNDYuODQzNzUsNDgzLjU5MjA1OSBMMjE1LjYyNSw0ODMuNTkyMDU5IEwyMTUuNjI1LDQ2MC44MjY1NDQgQzIxNS42MjUsNDYwLjE2NDU0NyAyMTUuMTA3NTc4LDQ1OS42MjgzNTkgMjE0LjQ2ODc1LDQ1OS42MjgzNTkgTDIxMi4xNTYyNSw0NTkuNjI4MzU5IEMyMTEuNTE3NDIyLDQ1OS42MjgzNTkgMjExLDQ2MC4xNjQ1NDcgMjExLDQ2MC44MjY1NDQgTDIxMSw0ODUuOTg4NDI5IEMyMTEsNDg3LjMxMTY3NCAyMTIuMDM1NTY2LDQ4OC4zODQ3OTggMjEzLjMxMjUsNDg4LjM4NDc5OCBMMjQ2Ljg0Mzc1LDQ4OC4zODQ3OTggQzI0Ny40ODI1NzgsNDg4LjM4NDc5OCAyNDgsNDg3Ljg0ODYxMSAyNDgsNDg3LjE4NjYxMyBMMjQ4LDQ4NC43OTAyNDQgQzI0OCw0ODQuMTI4MjQ2IDI0Ny40ODI1NzgsNDgzLjU5MjA1OSAyNDYuODQzNzUsNDgzLjU5MjA1OSBaIE0yNDQuNTMxMjUsNDYyLjAyNDcyOSBMMjM1Ljk5OTU3LDQ2Mi4wMjQ3MjkgQzIzNC40NTQ1MzEsNDYyLjAyNDcyOSAyMzMuNjgwNTY2LDQ2My45NjA1NDcgMjM0Ljc3MzIyMyw0NjUuMDkyODMyIEwyMzcuMTE0NjI5LDQ2Ny41MTkxNTYgTDIzMS44MTI1LDQ3My4wMTQzMzIgTDIyNi41MTAzNzEsNDY3LjUxOTkwNSBDMjI1LjYwNzA1MSw0NjYuNTgzODIzIDIyNC4xNDI5NDksNDY2LjU4MzgyMyAyMjMuMjQwMzUyLDQ2Ny41MTk5MDUgTDIxOC4yNzY0MjYsNDcyLjY2Mzg2MyBDMjE3LjgyNDc2Niw0NzMuMTMxOTA0IDIxNy44MjQ3NjYsNDczLjg5MDUwNSAyMTguMjc2NDI2LDQ3NC4zNTg1NDYgTDIxOS45MTEwNzQsNDc2LjA1MjQ4IEMyMjAuMzYyNzM0LDQ3Ni41MjA1MjEgMjIxLjA5NDc4NSw0NzYuNTIwNTIxIDIyMS41NDY0NDUsNDc2LjA1MjQ4IEwyMjQuODc1LDQ3Mi42MDI0NTYgTDIzMC4xNzcxMjksNDc4LjA5Njg4MyBDMjMxLjA4MDQ0OSw0NzkuMDMyOTY1IDIzMi41NDQ1NTEsNDc5LjAzMjk2NSAyMzMuNDQ3MTQ4LDQ3OC4wOTY4ODMgTDI0MC4zODQ2NDgsNDcwLjkwNzc3MyBMMjQyLjcyNjA1NSw0NzMuMzM0MDk4IEMyNDMuODE4NzExLDQ3NC40NjYzODIgMjQ1LjY4Njc3Nyw0NzMuNjY0MzQ3IDI0NS42ODY3NzcsNDcyLjA2MzI3MyBMMjQ1LjY4Njc3Nyw0NjMuMjIyOTE0IEMyNDUuNjg3NSw0NjIuNTYwOTE3IDI0NS4xNzAwNzgsNDYyLjAyNDcyOSAyNDQuNTMxMjUsNDYyLjAyNDcyOSBaIiBpZD0iQ29tYmluZWQtU2hhcGUiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==';
700 +
701 + $this->_libraryPage = add_menu_page( __( 'Visualizer', 'visualizer' ), __( 'Visualizer', 'visualizer' ), 'edit_posts', Visualizer_Plugin::NAME, array( $this, 'renderLibraryPage' ), $svg_base64_icon, 99.7666 );
702 +
703 + add_submenu_page(
704 + Visualizer_Plugin::NAME,
705 + __( 'Chart Library', 'visualizer' ),
706 + __( 'Chart Library', 'visualizer' ),
707 + 'edit_posts',
708 + 'admin.php?page=' . Visualizer_Plugin::NAME
709 + );
710 + add_submenu_page(
711 + Visualizer_Plugin::NAME,
712 + __( 'Add New Chart', 'visualizer' ),
713 + __( 'Add New Chart', 'visualizer' ),
714 + 'edit_posts',
715 + 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew'
716 + );
717 + add_submenu_page(
718 + Visualizer_Plugin::NAME,
719 + __( 'Support', 'visualizer' ),
720 + __( '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>',
721 + 'edit_posts',
722 + 'viz-support',
723 + array( $this, 'renderSupportPage' )
724 + );
725 +
726 + remove_submenu_page( Visualizer_Plugin::NAME, Visualizer_Plugin::NAME );
727 +
728 + add_action( "load-{$this->_libraryPage}", array( $this, 'addScreenOptions' ) );
729 + add_action( 'admin_footer', array( $this, 'handleGetProSubMenu' ) );
450 730 }
451 731
452 732 /**
453 - * Renders visualizer library page.
454 - *
455 - * @since 1.0.0
456 - *
457 - * @access public
733 + * Handle get pro plugin submenu.
458 734 */
459 - public function renderLibraryPage() {
735 + public function handleGetProSubMenu() {
736 + if ( ! Visualizer_Module::is_pro() ) {
737 + ?>
738 + <style type="text/css">
739 + #toplevel_page_visualizer ul.wp-submenu li:last-child {
740 + background: #FF7E65;
741 + font-size: 14px;
742 + font-weight: 600;
743 + color: #fff;
744 + }
745 + #toplevel_page_visualizer ul.wp-submenu li:last-child > a > span {
746 + color: #fff !important;
747 + }
748 + #toplevel_page_visualizer ul.wp-submenu li:last-child > a:hover {
749 + box-shadow: inherit;
750 + }
751 + </style>
752 + <?php
753 + if ( get_option( 'visualizer_fresh_install', false ) ) {
754 + ?>
755 + <style type="text/css">
756 + #toplevel_page_visualizer ul.wp-submenu li.wp-first-item + li + li + li {
757 + display: none;
758 + }
759 + </style>
760 + <?php
761 + }
762 + }
763 + }
764 +
765 + /**
766 + * Adds the screen options for pagination.
767 + */
768 + function addScreenOptions() {
769 + $screen = get_current_screen();
770 +
771 + // bail if it's some other page.
772 + if ( ! is_object( $screen ) || $screen->id !== $this->_libraryPage ) {
773 + return;
774 + }
775 +
776 + $args = array(
777 + 'label' => __( 'Number of charts per page:', 'visualizer' ),
778 + 'default' => 6,
779 + 'option' => 'visualizer_library_per_page',
780 + );
781 + add_screen_option( 'per_page', $args );
782 + }
783 +
784 + /**
785 + * Returns the screen option for pagination.
786 + */
787 + function setScreenOptions( $status, $option, $value ) {
788 + if ( 'visualizer_library_per_page' === $option ) {
789 + return $value;
790 + }
791 + }
792 +
793 + /**
794 + * Adds the display filters to be used in the meta_query while displaying the charts.
795 + */
796 + private function getDisplayFilters( &$query_args ) {
797 + $query = array();
798 + global $sitepress;
799 + if ( Visualizer_Module::is_pro() && ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) ) {
800 + $current_lang = icl_get_current_language();
801 + if ( in_array( $current_lang, array( 'all', icl_get_default_language() ), true ) ) {
802 + $query[] = array(
803 + 'key' => 'chart_lang',
804 + 'compare' => 'NOT EXISTS',
805 + );
806 + } else {
807 + $query[] = array(
808 + 'key' => 'chart_lang',
809 + 'value' => $current_lang,
810 + 'compare' => '=',
811 + );
812 + }
813 + }
814 +
815 + // add chart type filter to the query arguments
816 + $type = filter_input( INPUT_GET, 'type' );
817 + if ( $type && in_array( $type, Visualizer_Plugin::getChartTypes(), true ) ) {
818 + $query[] = array(
819 + 'key' => Visualizer_Plugin::CF_CHART_TYPE,
820 + 'value' => $type,
821 + 'compare' => '=',
822 + );
823 + }
824 +
825 + // add chart library filter to the query arguments
826 + $library = filter_input( INPUT_GET, 'library' );
827 + if ( $library ) {
828 + $query[] = array(
829 + 'key' => Visualizer_Plugin::CF_CHART_LIBRARY,
830 + 'value' => $library,
831 + 'compare' => '=',
832 + );
833 + }
834 +
835 + // add date filter to the query arguments
836 + $date = filter_input( INPUT_GET, 'date' );
837 + $possible = array_keys( Visualizer_Plugin::getSupportedDateFilter() );
838 + if ( $date && in_array( $date, $possible, true ) ) {
839 + $query_args['date_query'] = array(
840 + 'after' => "$date -1 day",
841 + 'inclusive' => true,
842 + );
843 + }
844 +
845 + // add source filter to the query arguments
846 + $source = filter_input( INPUT_GET, 'source' );
847 + if ( $source ) {
848 + $source = ucwords( $source );
849 + $source = "Visualizer_Source_{$source}";
850 + $query[] = array(
851 + 'key' => Visualizer_Plugin::CF_SOURCE,
852 + 'value' => $source,
853 + 'compare' => '=',
854 + );
855 + }
856 +
857 + $query_args['meta_query'] = $query;
858 +
859 + $orderby = filter_input( INPUT_GET, 'orderby' );
860 + $order = filter_input( INPUT_GET, 'order' );
861 + if ( $orderby ) {
862 + $query_args['order_by'] = $orderby;
863 + }
864 + $query_args['order'] = empty( $order ) ? 'desc' : $order;
865 + }
866 +
867 + /**
868 + * Get the instance of WP_Query that fetches the charts as per the given criteria.
869 + */
870 + private function getQuery() {
871 + static $q;
872 + if ( ! is_null( $q ) ) {
873 + return $q;
874 + }
875 +
460 876 // get current page
461 877 $page = filter_input(
462 - INPUT_GET, 'vpage', FILTER_VALIDATE_INT, array(
878 + INPUT_GET,
879 + 'vpage',
880 + FILTER_VALIDATE_INT,
881 + array(
463 882 'options' => array(
464 883 'min_range' => 1,
465 884 'default' => 1,
466 885 ),
@@ -465,29 +884,34 @@
465 884 'default' => 1,
466 885 ),
467 886 )
468 887 );
888 +
889 + $per_page = 6;
890 + $screen = get_current_screen();
891 + if ( $screen ) {
892 + // retrieve the per_page option
893 + $screen_option = $screen->get_option( 'per_page', 'option' );
894 + // retrieve the value stored for the current user
895 + $user = get_current_user_id();
896 + $per_page = get_user_meta( $user, $screen_option, true );
897 + if ( empty( $per_page ) || $per_page < 1 ) {
898 + // nothing set, get the default value
899 + $per_page = $screen->get_option( 'per_page', 'default' );
900 + }
901 + }
902 +
469 903 // the initial query arguments to fetch charts
470 904 $query_args = array(
471 905 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
472 - 'posts_per_page' => 6,
906 + 'posts_per_page' => $per_page,
473 907 'paged' => $page,
474 908 );
475 - // add chart type filter to the query arguments
476 - $filter = filter_input( INPUT_GET, 'type' );
477 - if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) {
478 - $query_args['meta_query'] = array(
479 - array(
480 - 'key' => Visualizer_Plugin::CF_CHART_TYPE,
481 - 'value' => $filter,
482 - 'compare' => '=',
483 - ),
484 - );
485 - } else {
486 - $filter = 'all';
487 - }
909 +
910 + $this->getDisplayFilters( $query_args );
911 +
488 912 // Added by Ash/Upwork
489 - $filterByMeta = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
913 + $filterByMeta = ! empty( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
490 914 if ( $filterByMeta ) {
491 915 $query = array(
492 916 'key' => Visualizer_Plugin::CF_SETTINGS,
493 917 'value' => $filterByMeta,
@@ -496,56 +920,160 @@
496 920 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
497 921 $meta[] = $query;
498 922 $query_args['meta_query'] = $meta;
499 923 }
500 - // Added by Ash/Upwork
501 - // fetch charts
924 + $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
925 + return $q;
926 + }
927 +
928 + /**
929 + * Renders support page.
930 + *
931 + * @since 3.3.0
932 + *
933 + * @access public
934 + */
935 + public function renderSupportPage() {
936 + wp_enqueue_style( 'visualizer-upsell', VISUALIZER_ABSURL . 'css/upsell.css', array(), Visualizer_Plugin::VERSION );
937 + $this->load_survey();
938 + include_once VISUALIZER_ABSPATH . '/templates/support.php';
939 + }
940 +
941 + /**
942 + * Renders visualizer library page.
943 + *
944 + * @since 1.0.0
945 + *
946 + * @access public
947 + */
948 + public function renderLibraryPage() {
502 949 $charts = array();
503 - $query = new WP_Query( $query_args );
950 + $query = $this->getQuery();
951 +
952 + // get current page
953 + $page = filter_input(
954 + INPUT_GET,
955 + 'vpage',
956 + FILTER_VALIDATE_INT,
957 + array(
958 + 'options' => array(
959 + 'min_range' => 1,
960 + 'default' => 1,
961 + ),
962 + )
963 + );
964 + // add chart type filter to the query arguments
965 + $filter = filter_input( INPUT_GET, 'type' );
966 + if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) ) {
967 + $filter = 'all';
968 + }
969 +
970 + $css = '';
504 971 while ( $query->have_posts() ) {
505 972 $chart = $query->next_post();
506 973
507 974 // if the user has updated a chart and instead of saving it, has closed the modal. If the user refreshes, they should get the original chart.
508 975 $chart = $this->handleExistingRevisions( $chart->ID, $chart );
976 + // refresh a "live" db query chart.
977 + $chart = apply_filters( 'visualizer_schedule_refresh_chart', $chart, $chart->ID, false );
509 978
979 + $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
980 +
510 981 // fetch and update settings
511 982 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
512 - unset( $settings['height'], $settings['width'] );
513 - $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
983 +
984 + $settings = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $settings, $chart->ID, $type );
985 + if ( ! empty( $atts['settings'] ) ) {
986 + $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
987 + }
988 +
989 + if ( $settings ) {
990 + unset( $settings['height'], $settings['width'], $settings['chartArea'] );
991 + }
992 +
514 993 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
515 - $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( $chart->post_content ) ), $chart->ID, $type );
994 + $data = self::get_chart_data( $chart, $type );
995 +
996 + // Set default setting series when add manual chart data - Only during first creation.
997 + if ( isset( $settings['series'] ) && ! empty( $series ) ) {
998 + $count_series = count( $series ) - count( $settings['series'] );
999 + if ( $count_series > 1 ) {
1000 + $clone_last_series = end( $settings['series'] );
1001 + $clone_last_series = array_fill_keys( array_keys( $clone_last_series ), '' );
1002 + foreach ( range( 1, $count_series ) as $item ) {
1003 + $settings['series'][] = $clone_last_series;
1004 + }
1005 + }
1006 + }
1007 +
1008 + $library = $this->load_chart_type( $chart->ID );
1009 +
1010 + $id = 'visualizer-' . $chart->ID;
1011 + $arguments = $this->get_inline_custom_css( $id, $settings );
1012 + if ( ! empty( $arguments ) ) {
1013 + $css .= $arguments[0];
1014 + $settings = $arguments[1];
1015 + }
1016 +
1017 + if ( isset( $settings['controls']['ui']['labelStacking'] ) ) {
1018 + unset( $settings['controls']['ui']['labelStacking'] );
1019 + }
1020 + if ( isset( $settings['controls']['ui']['orientation'] ) ) {
1021 + unset( $settings['controls']['ui']['orientation'] );
1022 + }
1023 +
516 1024 // add chart to the array
517 - $charts[ 'visualizer-' . $chart->ID ] = array(
1025 + $charts[ $id ] = array(
518 1026 'id' => $chart->ID,
519 1027 'type' => $type,
520 1028 'series' => $series,
521 1029 'settings' => $settings,
522 1030 'data' => $data,
1031 + 'library' => $library,
523 1032 );
524 1033 }
525 1034 // enqueue charts array
526 1035 $ajaxurl = admin_url( 'admin-ajax.php' );
1036 +
527 1037 wp_localize_script(
528 - 'visualizer-library', 'visualizer', array(
1038 + 'visualizer-library',
1039 + 'visualizer',
1040 + array(
529 1041 'language' => $this->get_language(),
530 1042 'map_api_key' => get_option( 'visualizer-map-api-key' ),
531 1043 'charts' => $charts,
532 1044 'urls' => array(
533 - 'base' => add_query_arg( 'vpage', false ),
534 - 'create' => add_query_arg(
535 - array(
536 - 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
537 - 'library' => 'yes',
538 - 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
539 - ), $ajaxurl
1045 + 'base' => esc_url( add_query_arg( array( 'vpage' => false, 'vaction' => false ) ) ),
1046 + 'create' => esc_url(
1047 + add_query_arg(
1048 + array(
1049 + 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
1050 + 'library' => 'yes',
1051 + 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
1052 + 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
1053 + 'vaction' => false,
1054 + ),
1055 + $ajaxurl
1056 + )
540 1057 ),
541 - 'edit' => add_query_arg(
542 - array(
543 - 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
544 - 'library' => 'yes',
545 - ), $ajaxurl
1058 + 'edit' => esc_url(
1059 + add_query_arg(
1060 + array(
1061 + 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
1062 + 'library' => 'yes',
1063 + 'vaction' => false,
1064 + ),
1065 + $ajaxurl
1066 + )
546 1067 ),
547 1068 ),
1069 + 'page_type' => 'library',
1070 + 'is_front' => false,
1071 + 'i10n' => array(
1072 + 'copied' => __( 'The shortcode has been copied to your clipboard. Hit Ctrl-V/Cmd-V to paste it.', 'visualizer' ),
1073 + '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' ),
1074 + ),
1075 + 'is_pro_user' => Visualizer_Module::is_pro(),
548 1076 )
549 1077 );
550 1078 // render library page
551 1079 $render = new Visualizer_Render_Library();
@@ -550,12 +1078,13 @@
550 1078 // render library page
551 1079 $render = new Visualizer_Render_Library();
552 1080 $render->charts = $charts;
553 1081 $render->type = $filter;
554 - $render->types = self::_getChartTypesLocalized();
1082 + $render->types = self::_getChartTypesLocalized( false, false, false, true );
1083 + $render->custom_css = $css;
555 1084 $render->pagination = paginate_links(
556 1085 array(
557 - 'base' => add_query_arg( 'vpage', '%#%' ),
1086 + 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
558 1087 'format' => '',
559 1088 'current' => $page,
560 1089 'total' => $query->max_num_pages,
561 1090 'type' => 'array',
@@ -560,8 +1089,15 @@
560 1089 'total' => $query->max_num_pages,
561 1090 'type' => 'array',
562 1091 )
563 1092 );
1093 +
1094 + $this->load_survey();
1095 +
1096 + if ( ! apply_filters( 'visualizer_is_business', false ) ) {
1097 + do_action( 'themeisle_sdk_load_banner', 'visualizer' );
1098 + }
1099 +
564 1100 $render->render();
565 1101 }
566 1102
567 1103 /**
@@ -576,14 +1112,14 @@
576 1112 *
577 1113 * @return array Updated array of action links.
578 1114 */
579 1115 public function getPluginActionLinks( $links, $file ) {
580 - if ( $file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1116 + if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
581 1117 array_unshift(
582 1118 $links,
583 1119 sprintf(
584 1120 '<a href="%s">%s</a>',
585 - admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ),
1121 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
586 1122 esc_html__( 'Library', 'visualizer' )
587 1123 )
588 1124 );
589 1125 }
@@ -603,18 +1139,18 @@
603 1139 *
604 1140 * @return array Updated array of plugin meta links.
605 1141 */
606 1142 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
607 - if ( $plugin_file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1143 + if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
608 1144 // knowledge base link
609 1145 $plugin_meta[] = sprintf(
610 - '<a href="https://github.com/codeinwp/visualizer/wiki" target="_blank">%s</a>',
611 - esc_html__( 'Knowledge Base', 'visualizer' )
1146 + '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1147 + esc_html__( 'Docs', 'visualizer' )
612 1148 );
613 1149 // flattr link
614 1150 $plugin_meta[] = sprintf(
615 - '<a style="color:red" href="https://themeisle.com/plugins/visualizer-charts-and-graphs-pro-addon/" target="_blank">%s</a>',
616 - esc_html__( 'Pro Addon', 'visualizer' )
1151 + '<a style="color:red" href="' . tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'pluginrow' ) . '" target="_blank">%s</a>',
1152 + esc_html__( 'Get Visualizer Pro', 'visualizer' )
617 1153 );
618 1154 }
619 1155
620 1156 return $plugin_meta;
@@ -619,5 +1155,146 @@
619 1155
620 1156 return $plugin_meta;
621 1157 }
622 1158
1159 + /**
1160 + * If check is existing user.
1161 + *
1162 + * @return bool Default false
1163 + */
1164 + public static function proFeaturesLocked() {
1165 + if ( Visualizer_Module::is_pro() ) {
1166 + return true;
1167 + }
1168 + return 'yes' === get_option( 'visualizer-new-user', 'yes' ) ? false : true;
1169 + }
1170 +
1171 + /**
1172 + * Multilingual Support.
1173 + *
1174 + * @param int $chart_id Chart ID.
1175 + * @return bool Default false
1176 + */
1177 + public function addMultilingualSupport( $chart_id ) {
1178 + global $sitepress;
1179 + if ( Visualizer_Module::is_pro() ) {
1180 + return;
1181 + }
1182 + if ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) {
1183 + $language = icl_get_languages();
1184 + $current_lang = icl_get_current_language();
1185 + $default_lang = icl_get_default_language();
1186 + $post_info = wpml_get_language_information( null, $chart_id );
1187 + $translations = array();
1188 + if ( ! empty( $post_info ) && ( $default_lang === $post_info['language_code'] ) ) {
1189 + $trid = $sitepress->get_element_trid( $chart_id, 'post_' . Visualizer_Plugin::CPT_VISUALIZER );
1190 + $translations = $sitepress->get_element_translations( $trid );
1191 + }
1192 + if ( empty( $translations ) ) {
1193 + return;
1194 + }
1195 + ?>
1196 + <hr><div class="visualizer-languages-list only-pro">
1197 + <?php
1198 + foreach ( $language as $lang ) {
1199 + $lang_code = $lang['code'];
1200 + if ( $current_lang !== $lang_code ) {
1201 + ?>
1202 + <a href="javascript:;">
1203 + <img src="<?php echo esc_url( $lang['country_flag_url'] ); ?>" alt="<?php echo esc_attr( $lang['translated_name'] ); ?>">
1204 + </a>
1205 + <?php
1206 + }
1207 + }
1208 + ?>
1209 + <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>
1210 + </div>
1211 + <?php
1212 + }
1213 + }
1214 +
1215 + /**
1216 + * Check chart is enabled or not.
1217 + *
1218 + * @param string $type Chart ID.
1219 + *
1220 + * @return bool Default false
1221 + */
1222 + public static function checkChartStatus( $type ) {
1223 + $types = self::_getChartTypesLocalized( false, false, false, true );
1224 + if ( isset( $types[ $type ] ) ) {
1225 + return ! empty( $types[ $type ]['enabled'] );
1226 + }
1227 + return false;
1228 + }
1229 +
1230 + /**
1231 + * Get the survey metadata.
1232 + *
1233 + * @return array The survey metadata.
1234 + */
1235 + private function get_survey_metadata() {
1236 + $install_date = get_option( 'visualizer_install', false );
1237 + $install_category = 0;
1238 +
1239 + if ( false !== $install_date ) {
1240 + $days_since_install = round( ( time() - $install_date ) / DAY_IN_SECONDS );
1241 +
1242 + if ( 0 === $days_since_install || 1 === $days_since_install ) {
1243 + $install_category = 0;
1244 + } elseif ( 1 < $days_since_install && 8 > $days_since_install ) {
1245 + $install_category = 7;
1246 + } elseif ( 8 <= $days_since_install && 31 > $days_since_install ) {
1247 + $install_category = 30;
1248 + } elseif ( 30 < $days_since_install && 90 > $days_since_install ) {
1249 + $install_category = 90;
1250 + } elseif ( 90 <= $days_since_install ) {
1251 + $install_category = 91;
1252 + }
1253 + }
1254 +
1255 + $plugin_data = get_plugin_data( VISUALIZER_BASEFILE, false, false );
1256 + $plugin_version = '';
1257 + if ( ! empty( $plugin_data['Version'] ) ) {
1258 + $plugin_version = $plugin_data['Version'];
1259 + }
1260 +
1261 + $user_id = 'visualizer_' . preg_replace( '/[^\w\d]*/', '', get_site_url() ); // Use a normalized version of the site URL as a user ID.
1262 +
1263 + $license_data = get_option( 'visualizer_pro_license_data', false );
1264 + if ( false !== $license_data && isset( $license_data->key ) ) {
1265 + $user_id = 'visualizer_' . $license_data->key;
1266 + }
1267 +
1268 + return array(
1269 + 'userId' => $user_id,
1270 + 'attributes' => array(
1271 + 'days_since_install' => strval( $install_category ),
1272 + 'free_version' => $plugin_version,
1273 + 'pro_version' => defined( 'VISUALIZER_PRO_VERSION' ) ? VISUALIZER_PRO_VERSION : '',
1274 + 'license_status' => apply_filters( 'product_visualizer_license_status', 'invalid' ),
1275 + ),
1276 + );
1277 + }
1278 +
1279 + /**
1280 + * Load the survey.
1281 + */
1282 + private function load_survey() {
1283 +
1284 + if ( defined( 'TI_CYPRESS_TESTING' ) ) {
1285 + return;
1286 + }
1287 +
1288 + $survey_handler = apply_filters( 'themeisle_sdk_dependency_script_handler', 'survey' );
1289 +
1290 + if ( empty( $survey_handler ) ) {
1291 + return;
1292 + }
1293 +
1294 + $metadata = $this->get_survey_metadata();
1295 +
1296 + do_action( 'themeisle_sdk_dependency_enqueue_script', 'survey' );
1297 + wp_enqueue_script( 'visualizer_chart_survey', VISUALIZER_ABSURL . 'js/survey.js', array( $survey_handler ), $metadata['attributes']['free_version'], true );
1298 + wp_localize_script( 'visualizer_chart_survey', 'visualizerSurveyData', $metadata );
1299 + }
623 1300 }