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 +847 -100 3.0.93.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' );
56 - $this->_addAction( 'admin_footer', 'renderTempaltes' );
57 - $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 8 );
64 + $this->_addAction( 'enqueue_block_editor_assets', 'enqueueMediaScripts' );
65 + $this->_addAction( 'admin_footer', 'renderTemplates' );
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,18 +345,27 @@
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 - 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 );
353 +
354 + // Load all the assets for the different libraries we support.
355 + $deps = array(
356 + Visualizer_Render_Sidebar_Google::enqueue_assets( array( 'media-editor' ) ),
357 + Visualizer_Render_Sidebar_Type_DataTable_Tabular::enqueue_assets( array( 'media-editor' ) ),
358 + );
359 +
360 + wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', $deps, Visualizer_Plugin::VERSION, true );
219 361 wp_enqueue_script( 'visualizer-media-collection', VISUALIZER_ABSURL . 'js/media/collection.js', array( 'visualizer-media-model' ), Visualizer_Plugin::VERSION, true );
220 362 wp_enqueue_script( 'visualizer-media-controller', VISUALIZER_ABSURL . 'js/media/controller.js', array( 'visualizer-media-collection' ), Visualizer_Plugin::VERSION, true );
221 363 wp_enqueue_script( 'visualizer-media-view', VISUALIZER_ABSURL . 'js/media/view.js', array( 'visualizer-media-controller' ), Visualizer_Plugin::VERSION, true );
222 364 wp_localize_script(
223 - 'visualizer-media-view', 'visualizer', array(
365 + 'visualizer-media-view',
366 + 'visualizer',
367 + array(
224 368 'i10n' => array(
225 369 'insert' => __( 'Insert', 'visualizer' ),
226 370 ),
227 371 )
@@ -260,9 +404,9 @@
260 404 'filters' => $chart_types,
261 405 'types' => array_keys( $chart_types ),
262 406 ),
263 407 'nonce' => wp_create_nonce(),
264 - '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' ) ) ),
265 409 );
266 410
267 411 return $strings;
268 412 }
@@ -275,9 +419,9 @@
275 419 * @static
276 420 * @access private
277 421 * @return array The associated array of chart types with localized names.
278 422 */
279 - public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false, $add_select = false ) {
423 + public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false, $add_select = false, $where = null ) {
280 424 $additional = array();
281 425 if ( $add_select ) {
282 426 $additional['select'] = array(
283 427 'name' => esc_html__( 'All', 'visualizer' ),
@@ -284,59 +428,102 @@
284 428 'enabled' => true,
285 429 );
286 430 }
287 431
432 + $enabled = self::proFeaturesLocked();
433 +
288 434 $types = array_merge(
289 - $additional, array(
435 + $additional,
436 + array(
437 + 'tabular' => array(
438 + 'name' => esc_html__( 'Table', 'visualizer' ),
439 + 'enabled' => true,
440 + 'supports' => $enabled ? array( 'Google Charts', 'DataTable' ) : array( 'DataTable' ),
441 + ),
290 442 'pie' => array(
291 - 'name' => esc_html__( 'Pie', 'visualizer' ),
443 + 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
292 444 'enabled' => true,
445 + 'supports' => array( 'Google Charts', 'ChartJS' ),
293 446 ),
294 447 'line' => array(
295 448 'name' => esc_html__( 'Line', 'visualizer' ),
296 449 'enabled' => true,
450 + 'supports' => array( 'Google Charts', 'ChartJS' ),
297 451 ),
452 + 'bar' => array(
453 + 'name' => esc_html__( 'Bar', 'visualizer' ),
454 + 'enabled' => true,
455 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
456 + ),
298 457 'area' => array(
299 458 'name' => esc_html__( 'Area', 'visualizer' ),
300 - '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/',
301 463 ),
302 464 'geo' => array(
303 465 'name' => esc_html__( 'Geo', 'visualizer' ),
304 - 'enabled' => true,
466 + 'enabled' => $enabled,
467 + 'supports' => array( 'Google Charts' ),
468 + 'demo_url' => 'https://demo.themeisle.com/visualizer/geo-chart/',
305 469 ),
306 - 'bar' => array(
307 - 'name' => esc_html__( 'Bar', 'visualizer' ),
308 - 'enabled' => true,
309 - ),
310 470 'column' => array(
311 471 'name' => esc_html__( 'Column', 'visualizer' ),
312 - 'enabled' => true,
472 + 'enabled' => $enabled,
473 + 'supports' => array( 'Google Charts', 'ChartJS' ),
474 + 'demo_url' => 'https://demo.themeisle.com/visualizer/column-chart/',
313 475 ),
314 - 'gauge' => array(
315 - 'name' => esc_html__( 'Gauge', 'visualizer' ),
316 - 'enabled' => true,
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/',
317 482 ),
318 483 'scatter' => array(
319 484 'name' => esc_html__( 'Scatter', 'visualizer' ),
320 - 'enabled' => true,
485 + 'enabled' => $enabled,
486 + 'supports' => array( 'Google Charts' ),
487 + 'demo_url' => 'https://demo.themeisle.com/visualizer/scatter-chart/',
321 488 ),
489 + 'gauge' => array(
490 + 'name' => esc_html__( 'Gauge', 'visualizer' ),
491 + 'enabled' => $enabled,
492 + 'supports' => array( 'Google Charts' ),
493 + 'demo_url' => 'https://demo.themeisle.com/visualizer/gauge-chart/',
494 + ),
322 495 'candlestick' => array(
323 496 'name' => esc_html__( 'Candlestick', 'visualizer' ),
324 - 'enabled' => true,
497 + 'enabled' => $enabled,
498 + 'supports' => array( 'Google Charts' ),
499 + 'demo_url' => 'https://demo.themeisle.com/visualizer/candlestick-chart/',
325 500 ),
326 501 // pro types
327 - 'table' => array(
328 - 'name' => esc_html__( 'Table', 'visualizer' ),
329 - 'enabled' => false,
330 - ),
331 502 'timeline' => array(
332 503 'name' => esc_html__( 'Timeline', 'visualizer' ),
333 504 'enabled' => false,
505 + 'supports' => array( 'Google Charts', 'ChartJS' ),
506 + 'demo_url' => 'https://demo.themeisle.com/visualizer/timeline-chart/',
334 507 ),
335 508 'combo' => array(
336 509 'name' => esc_html__( 'Combo', 'visualizer' ),
337 510 'enabled' => false,
511 + 'supports' => array( 'Google Charts' ),
512 + 'demo_url' => 'https://demo.themeisle.com/visualizer/combo-chart/',
338 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 + ),
339 526 )
340 527 );
341 528 $types = apply_filters( 'visualizer_pro_chart_types', $types );
342 529 if ( $enabledOnly ) {
@@ -345,8 +532,12 @@
345 532 if ( ! is_array( $array ) ) {
346 533 // support for old pro
347 534 $array = array( 'enabled' => true, 'name' => $array );
348 535 }
536 + // backward compatibility for PRO before v1.9.0
537 + if ( ! array_key_exists( 'supports', $array ) ) {
538 + $array['supports'] = array( 'Google Charts' );
539 + }
349 540 if ( ! $array['enabled'] ) {
350 541 continue;
351 542 }
352 543 $filtered[ $type ] = $array;
@@ -359,13 +550,74 @@
359 550 if ( ! is_array( $array ) ) {
360 551 // support for old pro
361 552 $array = array( 'enabled' => true, 'name' => $array );
362 553 }
554 + // backward compatibility for PRO before v1.9.0
555 + if ( ! array_key_exists( 'supports', $array ) ) {
556 + $array['supports'] = array( 'Google Charts' );
557 + }
363 558 $doubleD[ $type ] = $array['name'];
364 559 }
365 560 $types = $doubleD;
366 561 }
367 562
563 + return self::handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where );
564 + }
565 +
566 + /**
567 + * Handle (soon-to-be) deprecated charts.
568 + */
569 + private static function handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where ) {
570 + $deprecated = array();
571 +
572 + switch ( $where ) {
573 + case 'types':
574 + // fall-through
575 + case 'library':
576 + // if a user has a Gauge/Candlestick chart, then let them keep using it.
577 + if ( ! Visualizer_Module::is_pro() ) {
578 + if ( ! self::hasChartType( 'gauge' ) ) {
579 + if ( $get2Darray ) {
580 + $deprecated[] = 'gauge';
581 + } else {
582 + $types['gauge']['enabled'] = false;
583 + }
584 + }
585 + if ( ! self::hasChartType( 'candlestick' ) ) {
586 + if ( $get2Darray ) {
587 + $deprecated[] = 'candlestick';
588 + } else {
589 + $types['candlestick']['enabled'] = false;
590 + }
591 + }
592 + }
593 + break;
594 + default:
595 + // if a user has a Gauge/Candlestick chart, then let them keep using it.
596 + if ( ! Visualizer_Module::is_pro() ) {
597 + if ( ! self::hasChartType( 'gauge' ) ) {
598 + if ( $get2Darray ) {
599 + $deprecated[] = 'gauge';
600 + } else {
601 + $types['gauge']['enabled'] = false;
602 + }
603 + }
604 + if ( ! self::hasChartType( 'candlestick' ) ) {
605 + if ( $get2Darray ) {
606 + $deprecated[] = 'candlestick';
607 + } else {
608 + $types['candlestick']['enabled'] = false;
609 + }
610 + }
611 + }
612 + }
613 +
614 + if ( $deprecated ) {
615 + foreach ( $deprecated as $type ) {
616 + unset( $types[ $type ] );
617 + }
618 + }
619 +
368 620 return $types;
369 621 }
370 622
371 623 /**
@@ -375,11 +627,11 @@
375 627 * @global string $pagenow The name of the current page.
376 628 *
377 629 * @access public
378 630 */
379 - public function renderTempaltes() {
631 + public function renderTemplates() {
380 632 global $pagenow;
381 - if ( 'post.php' != $pagenow && 'post-new.php' != $pagenow ) {
633 + if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
382 634 return;
383 635 }
384 636 $render = new Visualizer_Render_Templates();
385 637 $render->render();
@@ -397,30 +649,61 @@
397 649 *
398 650 * @param string $suffix The current page suffix.
399 651 */
400 652 public function enqueueLibraryScripts( $suffix ) {
401 - if ( $suffix == $this->_libraryPage ) {
402 - wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
403 - $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
404 - 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 + }
405 681 wp_enqueue_script(
406 - 'visualizer-library', VISUALIZER_ABSURL . 'js/library.js', array(
407 - 'jquery',
408 - 'media-views',
409 - ), Visualizer_Plugin::VERSION, true
682 + "visualizer-render-$library",
683 + VISUALIZER_ABSURL . 'js/render-facade.js',
684 + apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
685 + Visualizer_Plugin::VERSION,
686 + true
410 687 );
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 - );
419 688 }
689 +
690 + do_action( 'themeisle_internal_page', VISUALIZER_DIRNAME, 'library' );
420 691 }
421 692
422 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;
701 + }
702 + do_action( 'themeisle_internal_page', VISUALIZER_DIRNAME, 'support' );
703 + }
704 +
705 + /**
423 706 * Adds visualizer tab for media upload tabs array.
424 707 *
425 708 * @since 1.0.0
426 709 *
@@ -443,24 +726,192 @@
443 726 *
444 727 * @access public
445 728 */
446 729 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 );
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' ) );
450 762 }
451 763
452 764 /**
453 - * Renders visualizer library page.
454 - *
455 - * @since 1.0.0
456 - *
457 - * @access public
765 + * Handle get pro plugin submenu.
458 766 */
459 - public function renderLibraryPage() {
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 + /**
900 + * Get the instance of WP_Query that fetches the charts as per the given criteria.
901 + */
902 + private function getQuery() {
903 + static $q;
904 + if ( ! is_null( $q ) ) {
905 + return $q;
906 + }
907 +
460 908 // get current page
461 909 $page = filter_input(
462 - INPUT_GET, 'vpage', FILTER_VALIDATE_INT, array(
910 + INPUT_GET,
911 + 'vpage',
912 + FILTER_VALIDATE_INT,
913 + array(
463 914 'options' => array(
464 915 'min_range' => 1,
465 916 'default' => 1,
466 917 ),
@@ -465,29 +916,34 @@
465 916 'default' => 1,
466 917 ),
467 918 )
468 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 +
469 935 // the initial query arguments to fetch charts
470 936 $query_args = array(
471 937 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
472 - 'posts_per_page' => 6,
938 + 'posts_per_page' => $per_page,
473 939 'paged' => $page,
474 940 );
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 - }
941 +
942 + $this->getDisplayFilters( $query_args );
943 +
488 944 // Added by Ash/Upwork
489 - $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
490 946 if ( $filterByMeta ) {
491 947 $query = array(
492 948 'key' => Visualizer_Plugin::CF_SETTINGS,
493 949 'value' => $filterByMeta,
@@ -496,56 +952,159 @@
496 952 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
497 953 $meta[] = $query;
498 954 $query_args['meta_query'] = $meta;
499 955 }
500 - // Added by Ash/Upwork
501 - // fetch charts
956 + $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
957 + return $q;
958 + }
959 +
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 + /**
973 + * Renders visualizer library page.
974 + *
975 + * @since 1.0.0
976 + *
977 + * @access public
978 + */
979 + public function renderLibraryPage() {
502 980 $charts = array();
503 - $query = new WP_Query( $query_args );
981 + $query = $this->getQuery();
982 +
983 + // get current page
984 + $page = filter_input(
985 + INPUT_GET,
986 + 'vpage',
987 + FILTER_VALIDATE_INT,
988 + array(
989 + 'options' => array(
990 + 'min_range' => 1,
991 + 'default' => 1,
992 + ),
993 + )
994 + );
995 + // add chart type filter to the query arguments
996 + $filter = filter_input( INPUT_GET, 'type' );
997 + if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) ) {
998 + $filter = 'all';
999 + }
1000 +
1001 + $css = '';
504 1002 while ( $query->have_posts() ) {
505 1003 $chart = $query->next_post();
506 1004
507 1005 // 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 1006 $chart = $this->handleExistingRevisions( $chart->ID, $chart );
1007 + // refresh a "live" db query chart.
1008 + $chart = apply_filters( 'visualizer_schedule_refresh_chart', $chart, $chart->ID, false );
509 1009
1010 + $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
1011 +
510 1012 // fetch and update settings
511 1013 $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 );
1014 +
1015 + $settings = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $settings, $chart->ID, $type );
1016 + if ( ! empty( $atts['settings'] ) ) {
1017 + $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
1018 + }
1019 +
1020 + if ( $settings ) {
1021 + unset( $settings['height'], $settings['width'], $settings['chartArea'] );
1022 + }
1023 +
514 1024 $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 );
1025 + $data = self::get_chart_data( $chart, $type );
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 +
1039 + $library = $this->load_chart_type( $chart->ID );
1040 +
1041 + $id = 'visualizer-' . $chart->ID;
1042 + $arguments = $this->get_inline_custom_css( $id, $settings );
1043 + if ( ! empty( $arguments ) ) {
1044 + $css .= $arguments[0];
1045 + $settings = $arguments[1];
1046 + }
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 +
516 1055 // add chart to the array
517 - $charts[ 'visualizer-' . $chart->ID ] = array(
1056 + $charts[ $id ] = array(
518 1057 'id' => $chart->ID,
519 1058 'type' => $type,
520 1059 'series' => $series,
521 1060 'settings' => $settings,
522 1061 'data' => $data,
1062 + 'library' => $library,
523 1063 );
524 1064 }
525 1065 // enqueue charts array
526 1066 $ajaxurl = admin_url( 'admin-ajax.php' );
1067 +
527 1068 wp_localize_script(
528 - 'visualizer-library', 'visualizer', array(
1069 + 'visualizer-library',
1070 + 'visualizer',
1071 + array(
529 1072 'language' => $this->get_language(),
530 1073 'map_api_key' => get_option( 'visualizer-map-api-key' ),
531 1074 'charts' => $charts,
532 1075 '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
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 + )
540 1088 ),
541 - 'edit' => add_query_arg(
542 - array(
543 - 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
544 - 'library' => 'yes',
545 - ), $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 + )
546 1098 ),
547 1099 ),
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(),
548 1107 )
549 1108 );
550 1109 // render library page
551 1110 $render = new Visualizer_Render_Library();
@@ -550,12 +1109,13 @@
550 1109 // render library page
551 1110 $render = new Visualizer_Render_Library();
552 1111 $render->charts = $charts;
553 1112 $render->type = $filter;
554 - $render->types = self::_getChartTypesLocalized();
1113 + $render->types = self::_getChartTypesLocalized( false, false, false, true );
1114 + $render->custom_css = $css;
555 1115 $render->pagination = paginate_links(
556 1116 array(
557 - 'base' => add_query_arg( 'vpage', '%#%' ),
1117 + 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
558 1118 'format' => '',
559 1119 'current' => $page,
560 1120 'total' => $query->max_num_pages,
561 1121 'type' => 'array',
@@ -560,8 +1120,9 @@
560 1120 'total' => $query->max_num_pages,
561 1121 'type' => 'array',
562 1122 )
563 1123 );
1124 +
564 1125 $render->render();
565 1126 }
566 1127
567 1128 /**
@@ -576,14 +1137,14 @@
576 1137 *
577 1138 * @return array Updated array of action links.
578 1139 */
579 1140 public function getPluginActionLinks( $links, $file ) {
580 - if ( $file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1141 + if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
581 1142 array_unshift(
582 1143 $links,
583 1144 sprintf(
584 1145 '<a href="%s">%s</a>',
585 - admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ),
1146 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
586 1147 esc_html__( 'Library', 'visualizer' )
587 1148 )
588 1149 );
589 1150 }
@@ -603,18 +1164,18 @@
603 1164 *
604 1165 * @return array Updated array of plugin meta links.
605 1166 */
606 1167 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
607 - if ( $plugin_file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1168 + if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
608 1169 // knowledge base link
609 1170 $plugin_meta[] = sprintf(
610 - '<a href="https://github.com/codeinwp/visualizer/wiki" target="_blank">%s</a>',
611 - esc_html__( 'Knowledge Base', 'visualizer' )
1171 + '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1172 + esc_html__( 'Docs', 'visualizer' )
612 1173 );
613 1174 // flattr link
614 1175 $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' )
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' )
617 1178 );
618 1179 }
619 1180
620 1181 return $plugin_meta;
@@ -619,5 +1180,191 @@
619 1180
620 1181 return $plugin_meta;
621 1182 }
622 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 + }
623 1370 }