PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.4.1
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.4.1
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 +133 -848 4.0.83.4.1 View file →
@@ -29,10 +29,8 @@
29 29 class Visualizer_Module_Admin extends Visualizer_Module {
30 30
31 31 const NAME = __CLASS__;
32 32
33 - const OPTION_GLOBAL_SETTINGS = 'visualizer_global_settings';
34 -
35 33 /**
36 34 * Library page suffix.
37 35 *
38 36 * @since 1.0.0
@@ -42,24 +40,8 @@
42 40 */
43 41 private $_libraryPage;
44 42
45 43 /**
46 - * Support page suffix.
47 - *
48 - * @access private
49 - * @var string
50 - */
51 - private $_supportPage;
52 -
53 - /**
54 - * Settings page suffix.
55 - *
56 - * @access private
57 - * @var string
58 - */
59 - private $_settingsPage;
60 -
61 - /**
62 44 * Constructor.
63 45 *
64 46 * @since 1.0.0
65 47 *
@@ -70,24 +52,18 @@
70 52 public function __construct( Visualizer_Plugin $plugin ) {
71 53 parent::__construct( $plugin );
72 54 $this->_addAction( 'load-post.php', 'enqueueMediaScripts' );
73 55 $this->_addAction( 'load-post-new.php', 'enqueueMediaScripts' );
74 - $this->_addAction( 'enqueue_block_editor_assets', 'enqueueMediaScripts' );
75 56 $this->_addAction( 'admin_footer', 'renderTemplates' );
76 - $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 0 );
77 - $this->_addAction( 'admin_enqueue_scripts', 'enqueue_support_page' );
78 - $this->_addAction( 'admin_enqueue_scripts', 'enqueueSettingsScripts' );
79 - $this->_addAction( 'admin_post_visualizer_save_global_settings', 'saveGlobalSettings' );
57 + $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 8 );
80 58 $this->_addAction( 'admin_menu', 'registerAdminMenu' );
81 59 $this->_addFilter( 'media_view_strings', 'setupMediaViewStrings' );
82 60 $this->_addFilter( 'plugin_action_links', 'getPluginActionLinks', 10, 2 );
83 61 $this->_addFilter( 'plugin_row_meta', 'getPluginMetaLinks', 10, 2 );
62 + $this->_addFilter( 'visualizer_logger_data', 'getLoggerData' );
63 + $this->_addFilter( 'visualizer_get_chart_counts', 'getChartCountsByTypeAndMeta' );
84 64 $this->_addFilter( 'visualizer_feedback_review_trigger', 'feedbackReviewTrigger' );
85 - $this->_addFilter( 'themeisle_sdk_blackfriday_data', 'add_black_friday_data' );
86 65
87 - // screen pagination
88 - $this->_addFilter( 'set-screen-option', 'setScreenOptions', 10, 3 );
89 -
90 66 // revision support.
91 67 $this->_addFilter( 'wp_revisions_to_keep', 'limitRevisions', null, 10, 2 );
92 68 $this->_addAction( '_wp_put_post_revision', 'addRevision', null, 10, 1 );
93 69 $this->_addAction( 'wp_restore_post_revision', 'restoreRevision', null, 10, 2 );
@@ -94,65 +70,12 @@
94 70
95 71 $this->_addAction( 'visualizer_chart_schedules_spl', 'addSplChartSchedules', null, 10, 3 );
96 72
97 73 $this->_addAction( 'admin_init', 'init' );
98 -
99 - $this->_addAction( 'visualizer_chart_languages', 'addMultilingualSupport' );
100 -
101 - $this->_addFilter( 'admin_footer_text', 'render_review_notice' );
102 -
103 - if ( ! defined( 'TI_E2E_TESTING' ) ) {
104 - $this->_addFilter( 'themeisle-sdk/survey/' . VISUALIZER_DIRNAME, 'get_survey_metadata', 10, 2 );
105 - }
106 -
107 - if ( defined( 'TI_E2E_TESTING' ) ) {
108 - $this->load_cypress_hooks();
109 - }
110 74 }
111 - /**
112 - * Display review notice.
113 - */
114 - public function render_review_notice( $footer_text ) {
115 - $current_screen = get_current_screen();
116 75
117 - $visualizer_page_ids = array( 'toplevel_page_visualizer', 'visualizer_page_viz-support', 'visualizer_page_ti-about-visualizer' );
118 76
119 - if ( ! empty( $current_screen ) && isset( $current_screen->id ) ) {
120 - foreach ( $visualizer_page_ids as $page_to_check ) {
121 - if ( strpos( $current_screen->id, $page_to_check ) !== false ) {
122 - $footer_text = sprintf(
123 - // translators: %1$s - the name of the plugin (Visualizer), %2$s - message (You can help us by leaving a), %3$s - HTML entity code.
124 - __( 'Enjoying %1$s? %2$s %3$s rating. Thank you for being so supportive!', 'visualizer' ),
125 - '<b>Visualizer</b>',
126 - esc_html__( 'You can help us by leaving a', 'visualizer' ),
127 - '<a href="https://wordpress.org/support/plugin/visualizer/reviews/#new-post" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
128 - );
129 - break;
130 - }
131 - }
132 - }
133 -
134 - return $footer_text;
135 - }
136 -
137 -
138 77 /**
139 - * Define the hooks that are needed for cypress.
140 - *
141 - * @since 3.4.0
142 - * @access private
143 - */
144 - private function load_cypress_hooks() {
145 - // all charts should load on the same page without pagination.
146 - add_filter(
147 - 'visualizer_query_args', function ( $args ) {
148 - $args['posts_per_page'] = 20;
149 - return $args;
150 - }, 10, 1
151 - );
152 - }
153 -
154 - /**
155 78 * Add disabled `optgroup` schedules to the drop downs.
156 79 *
157 80 * @since ?
158 81 *
@@ -166,16 +89,23 @@
166 89 if ( apply_filters( 'visualizer_is_business', false ) ) {
167 90 return;
168 91 }
169 92
170 - $is_new_personal = apply_filters( 'visualizer_is_new_personal', false );
93 + $license = __( 'PRO', 'visualizer' );
94 + if ( Visualizer_Module::is_pro() ) {
95 + switch ( $plan ) {
96 + case 1:
97 + $license = __( 'Developer', 'visualizer' );
98 + break;
99 + }
100 + }
171 101
172 102 $hours = array(
173 - '0.16' => __( '10 minutes', 'visualizer' ),
174 - '1' => __( 'Each hour', 'visualizer' ),
175 - '12' => __( 'Each 12 hours', 'visualizer' ),
176 - '24' => __( 'Each day', 'visualizer' ),
177 - '72' => __( 'Each 3 days', 'visualizer' ),
103 + '0' => __( 'Live', 'visualizer' ),
104 + '1' => __( 'Each hour', 'visualizer' ),
105 + '12' => __( 'Each 12 hours', 'visualizer' ),
106 + '24' => __( 'Each day', 'visualizer' ),
107 + '72' => __( 'Each 3 days', 'visualizer' ),
178 108 );
179 109
180 110 switch ( $feature ) {
181 111 case 'json':
@@ -180,9 +110,9 @@
180 110 switch ( $feature ) {
181 111 case 'json':
182 112 case 'csv':
183 113 // no more schedules if pro is already active.
184 - if ( Visualizer_Module::is_pro() && ! $is_new_personal ) {
114 + if ( Visualizer_Module::is_pro() ) {
185 115 return;
186 116 }
187 117 break;
188 118 case 'wp':
@@ -192,9 +122,9 @@
192 122 default:
193 123 return;
194 124 }
195 125
196 - echo '<optgroup disabled label="' . __( 'Upgrade required', 'visualizer' ) . '">';
126 + echo '<optgroup disabled label="' . sprintf( __( 'More in the %s version', 'visualizer' ), $license ) . '">';
197 127 foreach ( $hours as $hour => $desc ) {
198 128 echo '<option disabled>' . $desc . '</option>';
199 129 }
200 130 echo '</optgroup>';
@@ -221,9 +151,9 @@
221 151
222 152 if ( $meta ) {
223 153 foreach ( $meta as $key => $value ) {
224 154 if ( 0 === strpos( $key, 'visualizer' ) ) {
225 - add_metadata( 'post', $revision_id, $key, self::maybe_decode_content( $value[0] ) );
155 + add_metadata( 'post', $revision_id, $key, maybe_unserialize( $value[0] ) );
226 156 }
227 157 }
228 158 }
229 159 }
@@ -249,9 +179,9 @@
249 179
250 180 if ( $meta ) {
251 181 foreach ( $meta as $key => $value ) {
252 182 if ( 0 === strpos( $key, 'visualizer' ) ) {
253 - add_post_meta( $post_id, $key, self::maybe_decode_content( $value[0] ) );
183 + add_post_meta( $post_id, $key, maybe_unserialize( $value[0] ) );
254 184 }
255 185 }
256 186 }
257 187 }
@@ -262,9 +192,10 @@
262 192 *
263 193 * @access public
264 194 */
265 195 public function init() {
266 - if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' === get_user_option( 'rich_editing' ) ) {
196 + // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
197 + if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' == get_user_option( 'rich_editing' ) ) {
267 198 $this->_addFilter( 'mce_external_languages', 'add_tinymce_lang', 10, 1 );
268 199 $this->_addFilter( 'mce_external_plugins', 'tinymce_plugin', 10, 1 );
269 200 $this->_addFilter( 'mce_buttons', 'register_mce_button', 10, 1 );
270 201 $this->_addFilter( 'tiny_mce_before_init', 'get_strings_for_block', 10, 1 );
@@ -276,9 +207,9 @@
276 207 *
277 208 * @since ?
278 209 * @access friendly
279 210 */
280 - public function get_strings_for_block( $settings ) {
211 + function get_strings_for_block( $settings ) {
281 212 $class = new Visualizer_Module_Language();
282 213 $strings = $class->get_strings();
283 214 $array = array( 'visualizer_tinymce_plugin' => json_encode( $strings ) );
284 215 return array_merge( $settings, $array );
@@ -354,40 +285,15 @@
354 285 * @access public
355 286 */
356 287 public function enqueueMediaScripts() {
357 288 global $typenow;
358 - global $current_screen;
359 -
360 - if ( post_type_supports( $typenow, 'editor' ) || $current_screen->id === 'widgets' || $current_screen->id === 'customize' ) {
289 + if ( post_type_supports( $typenow, 'editor' ) ) {
361 290 wp_enqueue_style( 'visualizer-media', VISUALIZER_ABSURL . 'css/media.css', array( 'media-views' ), Visualizer_Plugin::VERSION );
362 291
363 - $d3_renderer_asset = VISUALIZER_ABSPATH . '/classes/Visualizer/D3Renderer/build/index.asset.php';
364 - if ( file_exists( $d3_renderer_asset ) && ! wp_script_is( 'visualizer-d3-renderer', 'registered' ) ) {
365 - // @phpstan-ignore-next-line
366 - $d3_asset = include $d3_renderer_asset;
367 - wp_register_script(
368 - 'visualizer-d3-renderer',
369 - VISUALIZER_ABSURL . 'classes/Visualizer/D3Renderer/build/index.js',
370 - array_merge( $d3_asset['dependencies'], array( 'jquery' ) ),
371 - $d3_asset['version'],
372 - true
373 - );
374 - }
375 - if ( wp_script_is( 'visualizer-d3-renderer', 'registered' ) ) {
376 - wp_enqueue_script( 'visualizer-d3-renderer' );
377 - wp_localize_script(
378 - 'visualizer-d3-renderer',
379 - 'vizD3Renderer',
380 - array(
381 - 'iframeJsUrl' => VISUALIZER_ABSURL . 'classes/Visualizer/D3Renderer/build/iframe.js',
382 - )
383 - );
384 - }
385 -
386 292 // Load all the assets for the different libraries we support.
387 293 $deps = array(
388 294 Visualizer_Render_Sidebar_Google::enqueue_assets( array( 'media-editor' ) ),
389 - Visualizer_Render_Sidebar_Type_DataTable_Tabular::enqueue_assets( array( 'media-editor' ) ),
295 + Visualizer_Render_Sidebar_Type_DataTable_DataTable::enqueue_assets( array( 'media-editor' ) ),
390 296 );
391 297
392 298 wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', $deps, Visualizer_Plugin::VERSION, true );
393 299 wp_enqueue_script( 'visualizer-media-collection', VISUALIZER_ABSURL . 'js/media/collection.js', array( 'visualizer-media-model' ), Visualizer_Plugin::VERSION, true );
@@ -397,9 +303,9 @@
397 303 'visualizer-media-view',
398 304 'visualizer',
399 305 array(
400 306 'i10n' => array(
401 - 'insert' => __( 'Insert Chart', 'visualizer' ),
307 + 'insert' => __( 'Insert', 'visualizer' ),
402 308 ),
403 309 )
404 310 );
405 311 wp_enqueue_script( 'visualizer-media-toolbar', VISUALIZER_ABSURL . 'js/media/toolbar.js', array( 'visualizer-media-view' ), Visualizer_Plugin::VERSION, true );
@@ -428,9 +334,9 @@
428 334 'controller' => array(
429 335 'title' => esc_html__( 'Visualizations', 'visualizer' ),
430 336 ),
431 337 'routers' => array(
432 - 'library' => esc_html__( 'Insert from Library', 'visualizer' ),
338 + 'library' => esc_html__( 'From Library', 'visualizer' ),
433 339 'create' => esc_html__( 'Create New', 'visualizer' ),
434 340 ),
435 341 'library' => array(
436 342 'filters' => $chart_types,
@@ -435,10 +341,10 @@
435 341 'library' => array(
436 342 'filters' => $chart_types,
437 343 'types' => array_keys( $chart_types ),
438 344 ),
439 - 'nonce' => wp_create_nonce( Visualizer_Plugin::ACTION_GET_CHARTS ),
440 - 'buildurl' => esc_url( add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ) ),
345 + 'nonce' => wp_create_nonce(),
346 + 'buildurl' => add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ),
441 347 );
442 348
443 349 return $strings;
444 350 }
@@ -460,17 +366,15 @@
460 366 'enabled' => true,
461 367 );
462 368 }
463 369
464 - $enabled = self::proFeaturesEnabled();
465 -
466 370 $types = array_merge(
467 371 $additional,
468 372 array(
469 - 'tabular' => array(
373 + 'dataTable' => array(
470 374 'name' => esc_html__( 'Table', 'visualizer' ),
471 375 'enabled' => true,
472 - 'supports' => $enabled ? array( 'Google Charts', 'DataTable' ) : array( 'DataTable' ),
376 + 'supports' => array( 'DataTable' ),
473 377 ),
474 378 'pie' => array(
475 379 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
476 380 'enabled' => true,
@@ -480,81 +384,75 @@
480 384 'name' => esc_html__( 'Line', 'visualizer' ),
481 385 'enabled' => true,
482 386 'supports' => array( 'Google Charts', 'ChartJS' ),
483 387 ),
484 - 'bar' => array(
485 - 'name' => esc_html__( 'Bar', 'visualizer' ),
486 - 'enabled' => true,
487 - 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
488 - ),
489 388 'area' => array(
490 389 'name' => esc_html__( 'Area', 'visualizer' ),
491 - 'enabled' => $enabled,
390 + 'enabled' => true,
492 391 // in ChartJS, the fill option is used to make Line chart an area: https://www.chartjs.org/docs/latest/charts/area.html
493 392 'supports' => array( 'Google Charts' ),
494 - 'demo_url' => 'https://demo.themeisle.com/visualizer/area-chart/',
495 393 ),
496 394 'geo' => array(
497 395 'name' => esc_html__( 'Geo', 'visualizer' ),
498 - 'enabled' => $enabled,
396 + 'enabled' => true,
499 397 'supports' => array( 'Google Charts' ),
500 - 'demo_url' => 'https://demo.themeisle.com/visualizer/geo-chart/',
501 398 ),
399 + 'bar' => array(
400 + 'name' => esc_html__( 'Bar', 'visualizer' ),
401 + 'enabled' => true,
402 + 'supports' => array( 'Google Charts', 'ChartJS' ),
403 + ),
502 404 'column' => array(
503 405 'name' => esc_html__( 'Column', 'visualizer' ),
504 - 'enabled' => $enabled,
406 + 'enabled' => true,
505 407 'supports' => array( 'Google Charts', 'ChartJS' ),
506 - 'demo_url' => 'https://demo.themeisle.com/visualizer/column-chart/',
507 408 ),
508 409 'bubble' => array(
509 410 'name' => esc_html__( 'Bubble', 'visualizer' ),
510 - 'enabled' => $enabled,
411 + 'enabled' => true,
511 412 // chartjs' bubble is ugly looking (and it won't work off the default bubble.csv) so it is being excluded for the time being.
512 413 'supports' => array( 'Google Charts' ),
513 - 'demo_url' => 'https://demo.themeisle.com/visualizer/bubble-chart/',
514 414 ),
515 415 'scatter' => array(
516 416 'name' => esc_html__( 'Scatter', 'visualizer' ),
517 - 'enabled' => $enabled,
417 + 'enabled' => true,
518 418 'supports' => array( 'Google Charts' ),
519 - 'demo_url' => 'https://demo.themeisle.com/visualizer/scatter-chart/',
520 419 ),
521 420 'gauge' => array(
522 421 'name' => esc_html__( 'Gauge', 'visualizer' ),
523 - 'enabled' => $enabled,
422 + 'enabled' => true,
524 423 'supports' => array( 'Google Charts' ),
525 - 'demo_url' => 'https://demo.themeisle.com/visualizer/gauge-chart/',
526 424 ),
527 425 'candlestick' => array(
528 426 'name' => esc_html__( 'Candlestick', 'visualizer' ),
529 - 'enabled' => $enabled,
427 + 'enabled' => true,
530 428 'supports' => array( 'Google Charts' ),
531 - 'demo_url' => 'https://demo.themeisle.com/visualizer/candlestick-chart/',
532 429 ),
533 430 // pro types
431 + 'table' => array(
432 + 'name' => esc_html__( 'Table (Deprecated)', 'visualizer' ),
433 + 'enabled' => false,
434 + 'supports' => array( 'Google Charts' ),
435 + ),
534 436 'timeline' => array(
535 437 'name' => esc_html__( 'Timeline', 'visualizer' ),
536 438 'enabled' => false,
537 439 'supports' => array( 'Google Charts', 'ChartJS' ),
538 - 'demo_url' => 'https://demo.themeisle.com/visualizer/timeline-chart/',
539 440 ),
540 441 'combo' => array(
541 442 'name' => esc_html__( 'Combo', 'visualizer' ),
542 443 'enabled' => false,
543 444 'supports' => array( 'Google Charts' ),
544 - 'demo_url' => 'https://demo.themeisle.com/visualizer/combo-chart/',
545 445 ),
546 446 'polarArea' => array(
547 447 'name' => esc_html__( 'Polar Area', 'visualizer' ),
548 448 'enabled' => false,
549 449 'supports' => array( 'ChartJS' ),
550 - 'demo_url' => 'https://demo.themeisle.com/visualizer/polar-area-chart/',
551 450 ),
552 451 'radar' => array(
553 452 'name' => esc_html__( 'Radar/Spider', 'visualizer' ),
554 453 'enabled' => false,
555 454 'supports' => array( 'ChartJS' ),
556 - 'demo_url' => 'https://demo.themeisle.com/visualizer/radar-spider-chart/',
557 455 ),
558 456 )
559 457 );
560 458 $types = apply_filters( 'visualizer_pro_chart_types', $types );
@@ -604,8 +502,18 @@
604 502 switch ( $where ) {
605 503 case 'types':
606 504 // fall-through
607 505 case 'library':
506 + // if the user has a Google Table chart, show it as deprecated otherwise remove the option from the library.
507 + if ( ! self::hasChartType( 'table' ) ) {
508 + $deprecated[] = 'table';
509 + if ( $get2Darray ) {
510 + $types['dataTable'] = esc_html__( 'Table', 'visualizer' );
511 + } else {
512 + $types['dataTable']['name'] = esc_html__( 'Table', 'visualizer' );
513 + }
514 + }
515 +
608 516 // if a user has a Gauge/Candlestick chart, then let them keep using it.
609 517 if ( ! Visualizer_Module::is_pro() ) {
610 518 if ( ! self::hasChartType( 'gauge' ) ) {
611 519 if ( $get2Darray ) {
@@ -623,8 +531,18 @@
623 531 }
624 532 }
625 533 break;
626 534 default:
535 + // remove the option to create a Google Table chart.
536 + $deprecated[] = 'table';
537 +
538 + // rename the new table chart type.
539 + if ( $get2Darray ) {
540 + $types['dataTable'] = esc_html__( 'Table', 'visualizer' );
541 + } else {
542 + $types['dataTable']['name'] = esc_html__( 'Table', 'visualizer' );
543 + }
544 +
627 545 // if a user has a Gauge/Candlestick chart, then let them keep using it.
628 546 if ( ! Visualizer_Module::is_pro() ) {
629 547 if ( ! self::hasChartType( 'gauge' ) ) {
630 548 if ( $get2Darray ) {
@@ -681,159 +599,44 @@
681 599 *
682 600 * @param string $suffix The current page suffix.
683 601 */
684 602 public function enqueueLibraryScripts( $suffix ) {
685 - if ( $suffix !== $this->_libraryPage ) {
686 - return;
687 - }
688 -
689 - wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
690 - $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
691 - wp_enqueue_media();
692 - wp_enqueue_script(
693 - 'visualizer-library',
694 - VISUALIZER_ABSURL . 'js/library.js',
695 - array(
696 - 'jquery',
697 - 'media-views',
698 - 'clipboard',
699 - ),
700 - Visualizer_Plugin::VERSION,
701 - true
702 - );
703 -
704 - wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
705 -
706 - $has_d3 = false;
707 - $query = $this->getQuery();
708 - while ( $query->have_posts() ) {
709 - $chart = $query->next_post();
710 - $library = $this->load_chart_type( $chart->ID );
711 - if ( is_null( $library ) ) {
712 - continue;
713 - }
603 + if ( $suffix === $this->_libraryPage ) {
604 + wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
605 + $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
606 + wp_enqueue_media();
714 607 wp_enqueue_script(
715 - "visualizer-render-$library",
716 - VISUALIZER_ABSURL . 'js/render-facade.js',
717 - apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
608 + 'visualizer-library',
609 + VISUALIZER_ABSURL . 'js/library.js',
610 + array(
611 + 'jquery',
612 + 'media-views',
613 + ),
718 614 Visualizer_Plugin::VERSION,
719 615 true
720 616 );
721 - if ( 'd3' === $library ) {
722 - $has_d3 = true;
723 - }
724 - }
725 617
726 - if ( $has_d3 ) {
727 - $d3_renderer_asset = VISUALIZER_ABSPATH . '/classes/Visualizer/D3Renderer/build/index.asset.php';
728 - if ( file_exists( $d3_renderer_asset ) && ! wp_script_is( 'visualizer-d3-renderer', 'registered' ) ) {
729 - /**
730 - * Ignore missing build asset in source checkout.
731 - *
732 - * @phpstan-ignore-next-line
733 - */
734 - $d3_asset = include $d3_renderer_asset;
735 - wp_register_script(
736 - 'visualizer-d3-renderer',
737 - VISUALIZER_ABSURL . 'classes/Visualizer/D3Renderer/build/index.js',
738 - array_merge( $d3_asset['dependencies'], array( 'jquery' ) ),
739 - $d3_asset['version'],
740 - true
741 - );
742 - wp_enqueue_script( 'visualizer-d3-renderer' );
743 - }
744 - wp_localize_script(
745 - 'visualizer-d3-renderer',
746 - 'vizD3Renderer',
747 - array(
748 - 'iframeJsUrl' => VISUALIZER_ABSURL . 'classes/Visualizer/D3Renderer/build/iframe.js',
749 - )
750 - );
751 - }
618 + wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
752 619
753 - $chart_builder_asset = VISUALIZER_ABSPATH . '/classes/Visualizer/ChartBuilder/build/index.asset.php';
754 - if ( file_exists( $chart_builder_asset ) ) {
755 - /**
756 - * Ignore missing build asset in source checkout.
757 - *
758 - * @phpstan-ignore-next-line
759 - */
760 - $asset = include $chart_builder_asset;
761 - $chart_builder_deps = $asset['dependencies'];
762 - if ( ! wp_script_is( 'visualizer-handsontable', 'registered' ) && defined( 'Visualizer_Pro_ABSURL' ) && defined( 'VISUALIZER_PRO_VERSION' ) ) {
763 - wp_register_script(
764 - 'visualizer-handsontable',
765 - Visualizer_Pro_ABSURL . 'vendor/handsontable/dist/handsontable.full.min.js',
766 - array(),
767 - VISUALIZER_PRO_VERSION,
620 + $query = $this->getQuery();
621 + while ( $query->have_posts() ) {
622 + $chart = $query->next_post();
623 + $library = $this->load_chart_type( $chart->ID );
624 + if ( is_null( $library ) ) {
625 + continue;
626 + }
627 + wp_enqueue_script(
628 + "visualizer-render-$library",
629 + VISUALIZER_ABSURL . 'js/render-facade.js',
630 + apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
631 + Visualizer_Plugin::VERSION,
768 632 true
769 633 );
770 634 }
771 - if ( ! wp_style_is( 'visualizer-handsontable', 'registered' ) && defined( 'Visualizer_Pro_ABSURL' ) && defined( 'VISUALIZER_PRO_VERSION' ) ) {
772 - wp_register_style(
773 - 'visualizer-handsontable',
774 - Visualizer_Pro_ABSURL . 'vendor/handsontable/dist/handsontable.full.min.css',
775 - array(),
776 - VISUALIZER_PRO_VERSION
777 - );
778 - }
779 - if ( wp_script_is( 'visualizer-handsontable', 'registered' ) ) {
780 - wp_enqueue_script( 'visualizer-handsontable' );
781 - $chart_builder_deps = array_unique( array_merge( $chart_builder_deps, array( 'visualizer-handsontable' ) ) );
782 - }
783 - if ( wp_style_is( 'visualizer-handsontable', 'registered' ) ) {
784 - wp_enqueue_style( 'visualizer-handsontable' );
785 - }
786 - wp_enqueue_script(
787 - 'visualizer-chart-builder',
788 - VISUALIZER_ABSURL . 'classes/Visualizer/ChartBuilder/build/index.js',
789 - $chart_builder_deps,
790 - $asset['version'],
791 - true
792 - );
793 - wp_enqueue_style(
794 - 'visualizer-chart-builder',
795 - VISUALIZER_ABSURL . 'classes/Visualizer/ChartBuilder/build/style-index.css',
796 - array(),
797 - $asset['version']
798 - );
799 - $chart_builder_css = VISUALIZER_ABSPATH . '/classes/Visualizer/ChartBuilder/build/index.css';
800 - if ( file_exists( $chart_builder_css ) ) {
801 - wp_enqueue_style(
802 - 'visualizer-chart-builder-runtime',
803 - VISUALIZER_ABSURL . 'classes/Visualizer/ChartBuilder/build/index.css',
804 - array( 'visualizer-chart-builder' ),
805 - $asset['version']
806 - );
807 - }
808 - wp_localize_script(
809 - 'visualizer-chart-builder',
810 - 'vizAIBuilder',
811 - array(
812 - 'ajaxUrl' => admin_url( 'admin-ajax.php' ),
813 - 'nonce' => wp_create_nonce( 'visualizer-ai-builder' ),
814 - 'isPro' => Visualizer_Module::is_pro(),
815 - 'upgradeUrl' => tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'aiBuilderUpgrade', 'dataSource' ),
816 - )
817 - );
818 635 }
819 -
820 - do_action( 'themeisle_internal_page', VISUALIZER_DIRNAME, 'library' );
821 636 }
822 637
823 638 /**
824 - * Enqueue script for support page.
825 - *
826 - * @param string $hook_suffix Current hook.
827 - */
828 - public function enqueue_support_page( $hook_suffix ) {
829 - if ( $this->_supportPage !== $hook_suffix ) {
830 - return;
831 - }
832 - do_action( 'themeisle_internal_page', VISUALIZER_DIRNAME, 'support' );
833 - }
834 -
835 - /**
836 639 * Adds visualizer tab for media upload tabs array.
837 640 *
838 641 * @since 1.0.0
839 642 *
@@ -865,9 +668,9 @@
865 668 Visualizer_Plugin::NAME,
866 669 __( 'Chart Library', 'visualizer' ),
867 670 __( 'Chart Library', 'visualizer' ),
868 671 'edit_posts',
869 - 'admin.php?page=' . Visualizer_Plugin::NAME
672 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME )
870 673 );
871 674 add_submenu_page(
872 675 Visualizer_Plugin::NAME,
873 676 __( 'Add New Chart', 'visualizer' ),
@@ -872,22 +675,12 @@
872 675 Visualizer_Plugin::NAME,
873 676 __( 'Add New Chart', 'visualizer' ),
874 677 __( 'Add New Chart', 'visualizer' ),
875 678 'edit_posts',
876 - 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew'
679 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew' )
877 680 );
878 -
879 - $this->_settingsPage = add_submenu_page(
681 + add_submenu_page(
880 682 Visualizer_Plugin::NAME,
881 - __( 'Settings', 'visualizer' ),
882 - __( 'Settings', 'visualizer' ),
883 - 'manage_options',
884 - 'viz-settings',
885 - array( $this, 'renderSettingsPage' )
886 - );
887 -
888 - $this->_supportPage = add_submenu_page(
889 - Visualizer_Plugin::NAME,
890 683 __( 'Support', 'visualizer' ),
891 684 __( 'Support', 'visualizer' ) . '<span class="dashicons dashicons-editor-help more-features-icon" style="width: 17px; height: 17px; margin-left: 4px; color: #ffca54; font-size: 17px; vertical-align: -3px;"></span>',
892 685 'edit_posts',
893 686 'viz-support',
@@ -892,151 +685,12 @@
892 685 'edit_posts',
893 686 'viz-support',
894 687 array( $this, 'renderSupportPage' )
895 688 );
896 -
897 689 remove_submenu_page( Visualizer_Plugin::NAME, Visualizer_Plugin::NAME );
898 -
899 - add_action( "load-{$this->_libraryPage}", array( $this, 'addScreenOptions' ) );
900 - add_action( 'admin_footer', array( $this, 'handleGetProSubMenu' ) );
901 690 }
902 691
903 692 /**
904 - * Handle get pro plugin submenu.
905 - */
906 - public function handleGetProSubMenu() {
907 - if ( ! Visualizer_Module::is_pro() ) {
908 - ?>
909 - <style type="text/css">
910 - #toplevel_page_visualizer ul.wp-submenu li:last-child {
911 - background: #FF7E65;
912 - font-size: 14px;
913 - font-weight: 600;
914 - color: #fff;
915 - }
916 - #toplevel_page_visualizer ul.wp-submenu li:last-child > a > span {
917 - color: #fff !important;
918 - }
919 - #toplevel_page_visualizer ul.wp-submenu li:last-child > a:hover {
920 - box-shadow: inherit;
921 - }
922 - </style>
923 - <?php
924 - if ( get_option( 'visualizer_fresh_install', false ) ) {
925 - ?>
926 - <style type="text/css">
927 - #toplevel_page_visualizer ul.wp-submenu li.wp-first-item + li + li + li {
928 - display: none;
929 - }
930 - </style>
931 - <?php
932 - }
933 - }
934 - }
935 -
936 - /**
937 - * Adds the screen options for pagination.
938 - */
939 - public function addScreenOptions() {
940 - $screen = get_current_screen();
941 -
942 - // bail if it's some other page.
943 - if ( ! is_object( $screen ) || $screen->id !== $this->_libraryPage ) {
944 - return;
945 - }
946 -
947 - $args = array(
948 - 'label' => __( 'Number of charts per page:', 'visualizer' ),
949 - 'default' => 6,
950 - 'option' => 'visualizer_library_per_page',
951 - );
952 - add_screen_option( 'per_page', $args );
953 - }
954 -
955 - /**
956 - * Returns the screen option for pagination.
957 - */
958 - public function setScreenOptions( $status, $option, $value ) {
959 - if ( 'visualizer_library_per_page' === $option ) {
960 - return $value;
961 - }
962 - }
963 -
964 - /**
965 - * Adds the display filters to be used in the meta_query while displaying the charts.
966 - */
967 - private function getDisplayFilters( &$query_args ) {
968 - $query = array();
969 - global $sitepress;
970 - if ( Visualizer_Module::is_pro() && ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) ) {
971 - $current_lang = icl_get_current_language();
972 - if ( in_array( $current_lang, array( 'all', icl_get_default_language() ), true ) ) {
973 - $query[] = array(
974 - 'key' => 'chart_lang',
975 - 'compare' => 'NOT EXISTS',
976 - );
977 - } else {
978 - $query[] = array(
979 - 'key' => 'chart_lang',
980 - 'value' => $current_lang,
981 - 'compare' => '=',
982 - );
983 - }
984 - }
985 -
986 - // add chart type filter to the query arguments
987 - $type = filter_input( INPUT_GET, 'type' );
988 - if ( $type && in_array( $type, Visualizer_Plugin::getChartTypes(), true ) ) {
989 - $query[] = array(
990 - 'key' => Visualizer_Plugin::CF_CHART_TYPE,
991 - 'value' => $type,
992 - 'compare' => '=',
993 - );
994 - }
995 -
996 - // add chart library filter to the query arguments
997 - $library = filter_input( INPUT_GET, 'library' );
998 - if ( $library ) {
999 - $query[] = array(
1000 - 'key' => Visualizer_Plugin::CF_CHART_LIBRARY,
1001 - 'value' => $library,
1002 - 'compare' => '=',
1003 - );
1004 - }
1005 -
1006 - // add date filter to the query arguments
1007 - $date = filter_input( INPUT_GET, 'date' );
1008 - $possible = array_keys( Visualizer_Plugin::getSupportedDateFilter() );
1009 - if ( $date && in_array( $date, $possible, true ) ) {
1010 - $query_args['date_query'] = array(
1011 - 'after' => "$date -1 day",
1012 - 'inclusive' => true,
1013 - );
1014 - }
1015 -
1016 - // add source filter to the query arguments
1017 - $source = filter_input( INPUT_GET, 'source' );
1018 - if ( $source ) {
1019 - $source = ucwords( $source );
1020 - $source = "Visualizer_Source_{$source}";
1021 - $query[] = array(
1022 - 'key' => Visualizer_Plugin::CF_SOURCE,
1023 - 'value' => $source,
1024 - 'compare' => '=',
1025 - );
1026 - }
1027 -
1028 - $query_args['meta_query'] = $query;
1029 -
1030 - $orderby = filter_input( INPUT_GET, 'orderby' );
1031 - $order = filter_input( INPUT_GET, 'order' );
1032 - if ( $orderby ) {
1033 - $query_args['order_by'] = $orderby;
1034 - }
1035 - $query_args['order'] = empty( $order ) ? 'desc' : $order;
1036 - }
1037 -
1038 - /**
1039 693 * Get the instance of WP_Query that fetches the charts as per the given criteria.
1040 694 */
1041 695 private function getQuery() {
1042 696 static $q;
@@ -1055,34 +709,29 @@
1055 709 'default' => 1,
1056 710 ),
1057 711 )
1058 712 );
1059 -
1060 - $per_page = 6;
1061 - $screen = get_current_screen();
1062 - if ( $screen ) {
1063 - // retrieve the per_page option
1064 - $screen_option = $screen->get_option( 'per_page', 'option' );
1065 - // retrieve the value stored for the current user
1066 - $user = get_current_user_id();
1067 - $per_page = get_user_meta( $user, $screen_option, true );
1068 - if ( empty( $per_page ) || $per_page < 1 ) {
1069 - // nothing set, get the default value
1070 - $per_page = $screen->get_option( 'per_page', 'default' );
1071 - }
1072 - }
1073 -
1074 713 // the initial query arguments to fetch charts
1075 714 $query_args = array(
1076 715 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
1077 - 'posts_per_page' => $per_page,
716 + 'posts_per_page' => 6,
1078 717 'paged' => $page,
1079 718 );
1080 -
1081 - $this->getDisplayFilters( $query_args );
1082 -
719 + // add chart type filter to the query arguments
720 + $filter = filter_input( INPUT_GET, 'type' );
721 + if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) {
722 + $query_args['meta_query'] = array(
723 + array(
724 + 'key' => Visualizer_Plugin::CF_CHART_TYPE,
725 + 'value' => $filter,
726 + 'compare' => '=',
727 + ),
728 + );
729 + } else {
730 + $filter = 'all';
731 + }
1083 732 // Added by Ash/Upwork
1084 - $filterByMeta = ! empty( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
733 + $filterByMeta = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
1085 734 if ( $filterByMeta ) {
1086 735 $query = array(
1087 736 'key' => Visualizer_Plugin::CF_SETTINGS,
1088 737 'value' => $filterByMeta,
@@ -1091,9 +740,9 @@
1091 740 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
1092 741 $meta[] = $query;
1093 742 $query_args['meta_query'] = $meta;
1094 743 }
1095 - $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
744 + $q = new WP_Query( $query_args );
1096 745 return $q;
1097 746 }
1098 747
1099 748 /**
@@ -1108,91 +757,8 @@
1108 757 include_once VISUALIZER_ABSPATH . '/templates/support.php';
1109 758 }
1110 759
1111 760 /**
1112 - * Enqueues scripts/styles for the Settings page.
1113 - *
1114 - * @access public
1115 - */
1116 - public function enqueueSettingsScripts( string $hook_suffix ): void {
1117 - if ( $this->_settingsPage !== $hook_suffix ) {
1118 - return;
1119 - }
1120 - wp_enqueue_style( 'wp-color-picker' );
1121 - wp_enqueue_script( 'wp-color-picker' );
1122 - }
1123 -
1124 - /**
1125 - * Renders the global style settings page.
1126 - *
1127 - * @access public
1128 - */
1129 - public function renderSettingsPage(): void {
1130 - if ( ! current_user_can( 'manage_options' ) ) {
1131 - wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'visualizer' ) );
1132 - }
1133 - $settings = self::getGlobalSettings();
1134 - include_once VISUALIZER_ABSPATH . '/templates/global-settings.php';
1135 - }
1136 -
1137 - /**
1138 - * Returns the global style settings option.
1139 - *
1140 - * @return array<string, string>
1141 - * @access public
1142 - * @static
1143 - */
1144 - public static function getGlobalSettings(): array {
1145 - $defaults = array(
1146 - 'color_primary' => '',
1147 - 'color_secondary' => '',
1148 - 'apply_existing' => '0',
1149 - );
1150 - $saved = get_option( self::OPTION_GLOBAL_SETTINGS, array() );
1151 - return wp_parse_args( $saved, $defaults );
1152 - }
1153 -
1154 - /**
1155 - * Handles saving of the global style settings.
1156 - *
1157 - * @access public
1158 - */
1159 - public function saveGlobalSettings(): void {
1160 - if ( ! current_user_can( 'manage_options' ) ) {
1161 - wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'visualizer' ) );
1162 - }
1163 -
1164 - check_admin_referer( 'visualizer_save_global_settings' );
1165 -
1166 - $color_primary = sanitize_hex_color( wp_unslash( $_POST['visualizer_color_primary'] ?? '' ) );
1167 - $color_secondary = sanitize_hex_color( wp_unslash( $_POST['visualizer_color_secondary'] ?? '' ) );
1168 - $apply_existing = ! empty( $_POST['visualizer_apply_existing'] ) ? '1' : '0';
1169 - $clear = ! empty( $_POST['visualizer_clear_settings'] );
1170 -
1171 - if ( $clear ) {
1172 - delete_option( self::OPTION_GLOBAL_SETTINGS );
1173 - } else {
1174 - $settings = array(
1175 - 'color_primary' => $color_primary ? $color_primary : '',
1176 - 'color_secondary' => $color_secondary ? $color_secondary : '',
1177 - 'apply_existing' => $apply_existing,
1178 - );
1179 - update_option( self::OPTION_GLOBAL_SETTINGS, $settings );
1180 - }
1181 -
1182 - wp_safe_redirect(
1183 - add_query_arg(
1184 - array(
1185 - 'page' => 'viz-settings',
1186 - 'updated' => $clear ? 'cleared' : 'true',
1187 - ),
1188 - admin_url( 'admin.php' )
1189 - )
1190 - );
1191 - exit;
1192 - }
1193 -
1194 - /**
1195 761 * Renders visualizer library page.
1196 762 *
1197 763 * @since 1.0.0
1198 764 *
@@ -1243,22 +809,10 @@
1243 809 unset( $settings['height'], $settings['width'], $settings['chartArea'] );
1244 810 }
1245 811
1246 812 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
1247 - $data = self::get_chart_data( $chart, $type );
813 + $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( $chart->post_content ) ), $chart->ID, $type );
1248 814
1249 - // Set default setting series when add manual chart data - Only during first creation.
1250 - if ( isset( $settings['series'] ) && ! empty( $series ) ) {
1251 - $count_series = count( $series ) - count( $settings['series'] );
1252 - if ( $count_series > 1 ) {
1253 - $clone_last_series = end( $settings['series'] );
1254 - $clone_last_series = array_fill_keys( array_keys( $clone_last_series ), '' );
1255 - foreach ( range( 1, $count_series ) as $item ) {
1256 - $settings['series'][] = $clone_last_series;
1257 - }
1258 - }
1259 - }
1260 -
1261 815 $library = $this->load_chart_type( $chart->ID );
1262 816
1263 817 $id = 'visualizer-' . $chart->ID;
1264 818 $arguments = $this->get_inline_custom_css( $id, $settings );
@@ -1266,19 +820,11 @@
1266 820 $css .= $arguments[0];
1267 821 $settings = $arguments[1];
1268 822 }
1269 823
1270 - if ( isset( $settings['controls']['ui']['labelStacking'] ) ) {
1271 - unset( $settings['controls']['ui']['labelStacking'] );
1272 - }
1273 - if ( isset( $settings['controls']['ui']['orientation'] ) ) {
1274 - unset( $settings['controls']['ui']['orientation'] );
1275 - }
1276 -
1277 824 // add chart to the array
1278 825 $charts[ $id ] = array(
1279 826 'id' => $chart->ID,
1280 - 'title' => $chart->post_title,
1281 827 'type' => $type,
1282 828 'series' => $series,
1283 829 'settings' => $settings,
1284 830 'data' => $data,
@@ -1283,15 +829,11 @@
1283 829 'settings' => $settings,
1284 830 'data' => $data,
1285 831 'library' => $library,
1286 832 );
1287 - if ( 'd3' === $library ) {
1288 - $charts[ $id ]['code'] = get_post_meta( $chart->ID, Visualizer_Module_AIBuilder::CF_D3_CODE, true );
1289 - }
1290 833 }
1291 834 // enqueue charts array
1292 835 $ajaxurl = admin_url( 'admin-ajax.php' );
1293 -
1294 836 wp_localize_script(
1295 837 'visualizer-library',
1296 838 'visualizer',
1297 839 array(
@@ -1298,39 +840,30 @@
1298 840 'language' => $this->get_language(),
1299 841 'map_api_key' => get_option( 'visualizer-map-api-key' ),
1300 842 'charts' => $charts,
1301 843 'urls' => array(
1302 - 'base' => esc_url( add_query_arg( array( 'vpage' => false, 'vaction' => false ) ) ),
1303 - 'create' => esc_url(
1304 - add_query_arg(
1305 - array(
1306 - 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
1307 - 'library' => 'yes',
1308 - 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
1309 - 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
1310 - 'vaction' => false,
1311 - ),
1312 - $ajaxurl
1313 - )
844 + 'base' => add_query_arg( array( 'vpage' => false, 'vaction' => false ) ),
845 + 'create' => add_query_arg(
846 + array(
847 + 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
848 + 'library' => 'yes',
849 + 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
850 + 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
851 + 'vaction' => false,
852 + ),
853 + $ajaxurl
1314 854 ),
1315 - 'edit' => esc_url(
1316 - add_query_arg(
1317 - array(
1318 - 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
1319 - 'library' => 'yes',
1320 - 'vaction' => false,
1321 - ),
1322 - $ajaxurl
1323 - )
855 + 'edit' => add_query_arg(
856 + array(
857 + 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
858 + 'library' => 'yes',
859 + 'vaction' => false,
860 + ),
861 + $ajaxurl
1324 862 ),
1325 863 ),
1326 864 'page_type' => 'library',
1327 865 'is_front' => false,
1328 - 'i10n' => array(
1329 - 'copied' => __( 'The shortcode has been copied to your clipboard. Hit Ctrl-V/Cmd-V to paste it.', 'visualizer' ),
1330 - 'conflict' => __( 'We have detected a potential conflict with another component that prevents Visualizer from functioning properly. Please disable any of the following components if they are activated on your instance: Modern Events Calendar plugin, Acronix plugin. In case the aforementioned components are not activated or you continue to see this error message, please disable all other plugins and enable them one by one to find out the component that is causing the conflict.', 'visualizer' ),
1331 - ),
1332 - 'is_pro_user' => Visualizer_Module::is_pro(),
1333 866 )
1334 867 );
1335 868 // render library page
1336 869 $render = new Visualizer_Render_Library();
@@ -1346,9 +879,8 @@
1346 879 'total' => $query->max_num_pages,
1347 880 'type' => 'array',
1348 881 )
1349 882 );
1350 -
1351 883 $render->render();
1352 884 }
1353 885
1354 886 /**
@@ -1390,268 +922,21 @@
1390 922 *
1391 923 * @return array Updated array of plugin meta links.
1392 924 */
1393 925 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
1394 - if ( Visualizer_Module::is_pro() ) {
1395 - return $plugin_meta;
1396 - }
1397 -
1398 - // Also suppress the upsell when Pro is installed but not currently active.
1399 - if ( ! function_exists( 'get_plugins' ) ) {
1400 - require_once ABSPATH . 'wp-admin/includes/plugin.php';
1401 - }
1402 - foreach ( array_keys( get_plugins() ) as $installed_plugin ) {
1403 - if ( false !== strpos( $installed_plugin, 'visualizer-pro' ) ) {
1404 - return $plugin_meta;
1405 - }
1406 - }
1407 -
1408 926 if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
1409 - $is_black_friday = apply_filters( 'themeisle_sdk_is_black_friday_sale', false );
1410 927 // knowledge base link
1411 928 $plugin_meta[] = sprintf(
1412 929 '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1413 930 esc_html__( 'Docs', 'visualizer' )
1414 931 );
1415 - if ( ! $is_black_friday ) {
1416 - // flattr link
1417 - $plugin_meta[] = sprintf(
1418 - '<a style="color:red" href="' . tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'pluginrow' ) . '" target="_blank">%s</a>',
1419 - esc_html__( 'Get Visualizer Pro', 'visualizer' )
1420 - );
1421 - }
932 + // flattr link
933 + $plugin_meta[] = sprintf(
934 + '<a style="color:red" href="' . Visualizer_Plugin::PRO_TEASER_URL . '" target="_blank">%s</a>',
935 + esc_html__( 'Pro Addon', 'visualizer' )
936 + );
1422 937 }
1423 938
1424 939 return $plugin_meta;
1425 940 }
1426 941
1427 - /**
1428 - * Returns true when premium chart types should be enabled for the current user.
1429 - *
1430 - * Pro 1.9.0+ hooks the 'visualizer_is_pro' filter and returns true only when
1431 - * the license is valid. Pre-1.9.0 Pro defined a Visualizer_Pro class instead;
1432 - * we detect that as a fallback so those legacy installs still work.
1433 - *
1434 - * Passing false as the filter default ensures the constant VISUALIZER_PRO
1435 - * (which is set to true whenever the Pro class exists, regardless of license
1436 - * state) cannot bypass the license check.
1437 - *
1438 - * @return bool
1439 - */
1440 - public static function proFeaturesEnabled() {
1441 - $is_pro_filter = apply_filters( 'visualizer_is_pro', false );
1442 -
1443 - // Pro 1.9.0+: filter is hooked and returns true only with a valid license.
1444 - if ( $is_pro_filter ) {
1445 - return true;
1446 - }
1447 -
1448 - // Pro is installed (active) but the license check above did not pass.
1449 - // Do NOT fall through to the legacy "old user" path — that path exists
1450 - // only for sites that never had Pro installed. If Pro is present but
1451 - // the license is inactive we should lock, regardless of chart history.
1452 - if ( class_exists( 'Visualizer_Pro', false ) ) {
1453 - return false;
1454 - }
1455 -
1456 - // No Pro installed at all: grant legacy access to existing users so
1457 - // their charts are not suddenly broken when they upgrade the free plugin.
1458 - return 'yes' === get_option( 'visualizer-new-user' ) ? false : true;
1459 - }
1460 -
1461 - /**
1462 - * Multilingual Support.
1463 - *
1464 - * @param int $chart_id Chart ID.
1465 - * @return bool Default false
1466 - */
1467 - public function addMultilingualSupport( $chart_id ) {
1468 - global $sitepress;
1469 - if ( Visualizer_Module::is_pro() ) {
1470 - return;
1471 - }
1472 - if ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) {
1473 - $language = icl_get_languages();
1474 - $current_lang = icl_get_current_language();
1475 - $default_lang = icl_get_default_language();
1476 - $post_info = wpml_get_language_information( null, $chart_id );
1477 - $translations = array();
1478 - if ( ! empty( $post_info ) && ( $default_lang === $post_info['language_code'] ) ) {
1479 - $trid = $sitepress->get_element_trid( $chart_id, 'post_' . Visualizer_Plugin::CPT_VISUALIZER );
1480 - $translations = $sitepress->get_element_translations( $trid );
1481 - }
1482 - if ( empty( $translations ) ) {
1483 - return;
1484 - }
1485 - ?>
1486 - <hr><div class="visualizer-languages-list only-pro">
1487 - <?php
1488 - foreach ( $language as $lang ) {
1489 - $lang_code = $lang['code'];
1490 - if ( $current_lang !== $lang_code ) {
1491 - ?>
1492 - <a href="javascript:;">
1493 - <img src="<?php echo esc_url( $lang['country_flag_url'] ); ?>" alt="<?php echo esc_attr( $lang['translated_name'] ); ?>">
1494 - </a>
1495 - <?php
1496 - }
1497 - }
1498 - ?>
1499 - <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>
1500 - </div>
1501 - <?php
1502 - }
1503 - }
1504 -
1505 - /**
1506 - * Check chart is enabled or not.
1507 - *
1508 - * @param string $type Chart ID.
1509 - *
1510 - * @return bool Default false
1511 - */
1512 - public static function checkChartStatus( $type ) {
1513 - $types = self::_getChartTypesLocalized( false, false, false, true );
1514 - if ( isset( $types[ $type ] ) ) {
1515 - return ! empty( $types[ $type ]['enabled'] );
1516 - }
1517 - return false;
1518 - }
1519 -
1520 - /**
1521 - * Get the survey metadata.
1522 - *
1523 - * @param array $data The data for survey in Formbricks format.
1524 - * @param string $page_slug The slug of the loaded page.
1525 - *
1526 - * @return array The survey metadata.
1527 - */
1528 - public function get_survey_metadata( $data, $page_slug ) {
1529 - $install_date = get_option( 'visualizer_install', time() );
1530 - $install_days_number = intval( ( time() - $install_date ) / DAY_IN_SECONDS );
1531 -
1532 - $license_status = apply_filters( 'product_visualizer_license_status', 'invalid' );
1533 - $license_plan = apply_filters( 'product_visualizer_license_plan', false );
1534 - $license_key = apply_filters( 'product_visualizer_license_key', false );
1535 -
1536 - $plugin_data = get_plugin_data( VISUALIZER_BASEFILE, false, false );
1537 - $plugin_version = '';
1538 -
1539 - if ( ! empty( $plugin_data['Version'] ) ) {
1540 - $plugin_version = $plugin_data['Version'];
1541 - }
1542 -
1543 - $count_charts_cache_key = 'visualizer_count_charts';
1544 - $charts_number = get_transient( $count_charts_cache_key );
1545 -
1546 - if ( false === $charts_number ) {
1547 - $charts_number = $this->count_charts( 100 );
1548 - set_transient( $count_charts_cache_key, $charts_number, 100 === $charts_number ? WEEK_IN_SECONDS : 6 * HOUR_IN_SECONDS );
1549 - } else {
1550 - $charts_number = strval( $charts_number );
1551 - }
1552 -
1553 - $data = array(
1554 - 'environmentId' => 'cltef8cut1s7wyyfxy3rlxzs5',
1555 - 'attributes' => array(
1556 - 'free_version' => $plugin_version,
1557 - 'pro_version' => defined( 'VISUALIZER_PRO_VERSION' ) ? VISUALIZER_PRO_VERSION : '',
1558 - 'license_status' => $license_status,
1559 - 'install_days_number' => $install_days_number,
1560 - 'charts_number' => $charts_number,
1561 - ),
1562 - );
1563 -
1564 - if ( ! empty( $license_plan ) ) {
1565 - $data['attributes']['plan'] = $license_plan;
1566 - }
1567 -
1568 - if ( ! empty( $license_key ) ) {
1569 - $data['attributes']['license_key'] = apply_filters( 'themeisle_sdk_secret_masking', $license_key );
1570 - }
1571 -
1572 - return $data;
1573 - }
1574 -
1575 - /**
1576 - * Count the charts.
1577 - *
1578 - * @param int $limit The count limit (optional).
1579 - *
1580 - * @return int The number of charts.
1581 - */
1582 - public function count_charts( $limit = -1 ) {
1583 - $args = array(
1584 - 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
1585 - 'post_status' => 'publish',
1586 - 'posts_per_page' => $limit,
1587 - 'fields' => 'ids',
1588 - );
1589 -
1590 - $query = new WP_Query( $args);
1591 - return $query->post_count;
1592 - }
1593 -
1594 - /**
1595 - * Set the black friday data.
1596 - *
1597 - * @param array $configs The configuration array for the loaded products.
1598 - * @return array
1599 - */
1600 - public function add_black_friday_data( $configs ) {
1601 - $config = $configs['default'];
1602 -
1603 - $message = __( 'Database queries, private charts, auto-sync. Go beyond basic charts. Exclusively for existing Visualizer users.', 'visualizer' );
1604 - $cta_label = __( 'Get Visualizer Pro', 'visualizer' );
1605 -
1606 - $plan = apply_filters( 'product_visualizer_license_plan', 0 );
1607 - $license = apply_filters( 'product_visualizer_license_key', false );
1608 - $status = apply_filters( 'product_visualizer_license_status', false );
1609 - $pro_product_slug = defined( 'VISUALIZER_PRO_BASEFILE' ) ? basename( dirname( VISUALIZER_PRO_BASEFILE ) ) : '';
1610 -
1611 - $is_pro = 'valid' === $status;
1612 - $is_expired = 'expired' === $status || 'active-expired' === $status;
1613 -
1614 - if ( $is_pro ) {
1615 - // translators: %s is the discount percentage.
1616 - $config['plugin_meta_message'] = sprintf( __( 'Black Friday Sale - up to %s off', 'visualizer' ), '30%' );
1617 - // translators: %1$s - discount, %2$s - discount.
1618 - $message = sprintf( __( 'Upgrade your Visualizer Pro plan: %1$s off this week. Already on the plan you need? Renew early and save up to %2$s.', 'visualizer' ), '30%', '20%' );
1619 - $cta_label = __( 'See your options', 'visualizer' );
1620 - } elseif ( $is_expired ) {
1621 - // translators: %s is the discount percentage.
1622 - $config['upgrade_menu_text'] = sprintf( __( 'BF Sale - %s off', 'visualizer' ), '50%' );
1623 - // translators: %s is the discount percentage.
1624 - $config['plugin_meta_message'] = sprintf( __( 'Black Friday Sale - %s off', 'visualizer' ), '50%' );
1625 - $message = __( 'Your Visualizer Pro features are still here, just locked. Renew at a reduced rate this week.', 'visualizer' );
1626 - $cta_label = __( 'Reactivate now', 'visualizer' );
1627 - } else {
1628 - // translators: %s is the discount percentage.
1629 - $config['plugin_meta_message'] = sprintf( __( 'Black Friday Sale - %s off', 'visualizer' ), '60%' );
1630 - $config['title'] = __( 'Visualizer Pro: 60% off this week', 'visualizer' );
1631 - // translators: %s is the discount percentage.
1632 - $config['upgrade_menu_text'] = sprintf( __( 'BF Sale - %s off', 'visualizer' ), '60%' );
1633 - }
1634 -
1635 - $url_params = array(
1636 - 'utm_term' => $is_pro ? 'plan-' . $plan : 'free',
1637 - 'lkey' => ! empty( $license ) ? $license : false,
1638 - 'expired' => $is_expired ? '1' : false,
1639 - );
1640 -
1641 - if ( ( $is_pro || $is_expired ) && ! empty( $pro_product_slug ) ) {
1642 - $config['plugin_meta_targets'] = array( $pro_product_slug );
1643 - }
1644 -
1645 - $config['message'] = $message;
1646 - $config['cta_label'] = $cta_label;
1647 -
1648 - $config['sale_url'] = add_query_arg(
1649 - $url_params,
1650 - tsdk_translate_link( tsdk_utmify( 'https://themeisle.link/vizualizer-bf', 'bfcm', 'visualizer' ) )
1651 - );
1652 -
1653 - $configs[ VISUALIZER_DIRNAME ] = $config;
1654 -
1655 - return $configs;
1656 - }
1657 942 }