PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.4.0
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.4.0
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 All 149 releases
← All changes | classes/Visualizer/Module/Admin.php +132 -861 4.0.83.4.0 View file →
@@ -29,10 +29,8 @@
29 29 class Visualizer_Module_Admin extends Visualizer_Module {
30 30
31 31 const NAME = __CLASS__;
32 32
33 - const OPTION_GLOBAL_SETTINGS = 'visualizer_global_settings';
34 -
35 33 /**
36 34 * Library page suffix.
37 35 *
38 36 * @since 1.0.0
@@ -42,24 +40,8 @@
42 40 */
43 41 private $_libraryPage;
44 42
45 43 /**
46 - * Support page suffix.
47 - *
48 - * @access private
49 - * @var string
50 - */
51 - private $_supportPage;
52 -
53 - /**
54 - * Settings page suffix.
55 - *
56 - * @access private
57 - * @var string
58 - */
59 - private $_settingsPage;
60 -
61 - /**
62 44 * Constructor.
63 45 *
64 46 * @since 1.0.0
65 47 *
@@ -70,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,30 +192,17 @@
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 - $this->_addFilter( 'tiny_mce_before_init', 'get_strings_for_block', 10, 1 );
271 201 }
272 202 }
273 203
274 204 /**
275 - * Add the strings required for the TinyMCE buttons for the classic block (not the classic editor).
276 - *
277 - * @since ?
278 - * @access friendly
279 - */
280 - public function get_strings_for_block( $settings ) {
281 - $class = new Visualizer_Module_Language();
282 - $strings = $class->get_strings();
283 - $array = array( 'visualizer_tinymce_plugin' => json_encode( $strings ) );
284 - return array_merge( $settings, $array );
285 - }
286 -
287 - /**
288 205 * Load plugin translation for - TinyMCE API
289 206 *
290 207 * @access public
291 208 * @param array $arr The tinymce_lang array.
@@ -354,40 +271,15 @@
354 271 * @access public
355 272 */
356 273 public function enqueueMediaScripts() {
357 274 global $typenow;
358 - global $current_screen;
359 -
360 - if ( post_type_supports( $typenow, 'editor' ) || $current_screen->id === 'widgets' || $current_screen->id === 'customize' ) {
275 + if ( post_type_supports( $typenow, 'editor' ) ) {
361 276 wp_enqueue_style( 'visualizer-media', VISUALIZER_ABSURL . 'css/media.css', array( 'media-views' ), Visualizer_Plugin::VERSION );
362 277
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 278 // Load all the assets for the different libraries we support.
387 279 $deps = array(
388 280 Visualizer_Render_Sidebar_Google::enqueue_assets( array( 'media-editor' ) ),
389 - Visualizer_Render_Sidebar_Type_DataTable_Tabular::enqueue_assets( array( 'media-editor' ) ),
281 + Visualizer_Render_Sidebar_Type_DataTable_DataTable::enqueue_assets( array( 'media-editor' ) ),
390 282 );
391 283
392 284 wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', $deps, Visualizer_Plugin::VERSION, true );
393 285 wp_enqueue_script( 'visualizer-media-collection', VISUALIZER_ABSURL . 'js/media/collection.js', array( 'visualizer-media-model' ), Visualizer_Plugin::VERSION, true );
@@ -397,9 +289,9 @@
397 289 'visualizer-media-view',
398 290 'visualizer',
399 291 array(
400 292 'i10n' => array(
401 - 'insert' => __( 'Insert Chart', 'visualizer' ),
293 + 'insert' => __( 'Insert', 'visualizer' ),
402 294 ),
403 295 )
404 296 );
405 297 wp_enqueue_script( 'visualizer-media-toolbar', VISUALIZER_ABSURL . 'js/media/toolbar.js', array( 'visualizer-media-view' ), Visualizer_Plugin::VERSION, true );
@@ -428,9 +320,9 @@
428 320 'controller' => array(
429 321 'title' => esc_html__( 'Visualizations', 'visualizer' ),
430 322 ),
431 323 'routers' => array(
432 - 'library' => esc_html__( 'Insert from Library', 'visualizer' ),
324 + 'library' => esc_html__( 'From Library', 'visualizer' ),
433 325 'create' => esc_html__( 'Create New', 'visualizer' ),
434 326 ),
435 327 'library' => array(
436 328 'filters' => $chart_types,
@@ -435,10 +327,10 @@
435 327 'library' => array(
436 328 'filters' => $chart_types,
437 329 'types' => array_keys( $chart_types ),
438 330 ),
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' ) ) ),
331 + 'nonce' => wp_create_nonce(),
332 + 'buildurl' => add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ),
441 333 );
442 334
443 335 return $strings;
444 336 }
@@ -460,17 +352,15 @@
460 352 'enabled' => true,
461 353 );
462 354 }
463 355
464 - $enabled = self::proFeaturesEnabled();
465 -
466 356 $types = array_merge(
467 357 $additional,
468 358 array(
469 - 'tabular' => array(
359 + 'dataTable' => array(
470 360 'name' => esc_html__( 'Table', 'visualizer' ),
471 361 'enabled' => true,
472 - 'supports' => $enabled ? array( 'Google Charts', 'DataTable' ) : array( 'DataTable' ),
362 + 'supports' => array( 'DataTable' ),
473 363 ),
474 364 'pie' => array(
475 365 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
476 366 'enabled' => true,
@@ -480,81 +370,75 @@
480 370 'name' => esc_html__( 'Line', 'visualizer' ),
481 371 'enabled' => true,
482 372 'supports' => array( 'Google Charts', 'ChartJS' ),
483 373 ),
484 - 'bar' => array(
485 - 'name' => esc_html__( 'Bar', 'visualizer' ),
486 - 'enabled' => true,
487 - 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
488 - ),
489 374 'area' => array(
490 375 'name' => esc_html__( 'Area', 'visualizer' ),
491 - 'enabled' => $enabled,
376 + 'enabled' => true,
492 377 // in ChartJS, the fill option is used to make Line chart an area: https://www.chartjs.org/docs/latest/charts/area.html
493 378 'supports' => array( 'Google Charts' ),
494 - 'demo_url' => 'https://demo.themeisle.com/visualizer/area-chart/',
495 379 ),
496 380 'geo' => array(
497 381 'name' => esc_html__( 'Geo', 'visualizer' ),
498 - 'enabled' => $enabled,
382 + 'enabled' => true,
499 383 'supports' => array( 'Google Charts' ),
500 - 'demo_url' => 'https://demo.themeisle.com/visualizer/geo-chart/',
501 384 ),
385 + 'bar' => array(
386 + 'name' => esc_html__( 'Bar', 'visualizer' ),
387 + 'enabled' => true,
388 + 'supports' => array( 'Google Charts', 'ChartJS' ),
389 + ),
502 390 'column' => array(
503 391 'name' => esc_html__( 'Column', 'visualizer' ),
504 - 'enabled' => $enabled,
392 + 'enabled' => true,
505 393 'supports' => array( 'Google Charts', 'ChartJS' ),
506 - 'demo_url' => 'https://demo.themeisle.com/visualizer/column-chart/',
507 394 ),
508 395 'bubble' => array(
509 396 'name' => esc_html__( 'Bubble', 'visualizer' ),
510 - 'enabled' => $enabled,
397 + 'enabled' => true,
511 398 // chartjs' bubble is ugly looking (and it won't work off the default bubble.csv) so it is being excluded for the time being.
512 399 'supports' => array( 'Google Charts' ),
513 - 'demo_url' => 'https://demo.themeisle.com/visualizer/bubble-chart/',
514 400 ),
515 401 'scatter' => array(
516 402 'name' => esc_html__( 'Scatter', 'visualizer' ),
517 - 'enabled' => $enabled,
403 + 'enabled' => true,
518 404 'supports' => array( 'Google Charts' ),
519 - 'demo_url' => 'https://demo.themeisle.com/visualizer/scatter-chart/',
520 405 ),
521 406 'gauge' => array(
522 407 'name' => esc_html__( 'Gauge', 'visualizer' ),
523 - 'enabled' => $enabled,
408 + 'enabled' => true,
524 409 'supports' => array( 'Google Charts' ),
525 - 'demo_url' => 'https://demo.themeisle.com/visualizer/gauge-chart/',
526 410 ),
527 411 'candlestick' => array(
528 412 'name' => esc_html__( 'Candlestick', 'visualizer' ),
529 - 'enabled' => $enabled,
413 + 'enabled' => true,
530 414 'supports' => array( 'Google Charts' ),
531 - 'demo_url' => 'https://demo.themeisle.com/visualizer/candlestick-chart/',
532 415 ),
533 416 // pro types
417 + 'table' => array(
418 + 'name' => esc_html__( 'Table (Deprecated)', 'visualizer' ),
419 + 'enabled' => false,
420 + 'supports' => array( 'Google Charts' ),
421 + ),
534 422 'timeline' => array(
535 423 'name' => esc_html__( 'Timeline', 'visualizer' ),
536 424 'enabled' => false,
537 425 'supports' => array( 'Google Charts', 'ChartJS' ),
538 - 'demo_url' => 'https://demo.themeisle.com/visualizer/timeline-chart/',
539 426 ),
540 427 'combo' => array(
541 428 'name' => esc_html__( 'Combo', 'visualizer' ),
542 429 'enabled' => false,
543 430 'supports' => array( 'Google Charts' ),
544 - 'demo_url' => 'https://demo.themeisle.com/visualizer/combo-chart/',
545 431 ),
546 432 'polarArea' => array(
547 433 'name' => esc_html__( 'Polar Area', 'visualizer' ),
548 434 'enabled' => false,
549 435 'supports' => array( 'ChartJS' ),
550 - 'demo_url' => 'https://demo.themeisle.com/visualizer/polar-area-chart/',
551 436 ),
552 437 'radar' => array(
553 438 'name' => esc_html__( 'Radar/Spider', 'visualizer' ),
554 439 'enabled' => false,
555 440 'supports' => array( 'ChartJS' ),
556 - 'demo_url' => 'https://demo.themeisle.com/visualizer/radar-spider-chart/',
557 441 ),
558 442 )
559 443 );
560 444 $types = apply_filters( 'visualizer_pro_chart_types', $types );
@@ -604,8 +488,18 @@
604 488 switch ( $where ) {
605 489 case 'types':
606 490 // fall-through
607 491 case 'library':
492 + // if the user has a Google Table chart, show it as deprecated otherwise remove the option from the library.
493 + if ( ! self::hasChartType( 'table' ) ) {
494 + $deprecated[] = 'table';
495 + if ( $get2Darray ) {
496 + $types['dataTable'] = esc_html__( 'Table', 'visualizer' );
497 + } else {
498 + $types['dataTable']['name'] = esc_html__( 'Table', 'visualizer' );
499 + }
500 + }
501 +
608 502 // if a user has a Gauge/Candlestick chart, then let them keep using it.
609 503 if ( ! Visualizer_Module::is_pro() ) {
610 504 if ( ! self::hasChartType( 'gauge' ) ) {
611 505 if ( $get2Darray ) {
@@ -623,8 +517,18 @@
623 517 }
624 518 }
625 519 break;
626 520 default:
521 + // remove the option to create a Google Table chart.
522 + $deprecated[] = 'table';
523 +
524 + // rename the new table chart type.
525 + if ( $get2Darray ) {
526 + $types['dataTable'] = esc_html__( 'Table', 'visualizer' );
527 + } else {
528 + $types['dataTable']['name'] = esc_html__( 'Table', 'visualizer' );
529 + }
530 +
627 531 // if a user has a Gauge/Candlestick chart, then let them keep using it.
628 532 if ( ! Visualizer_Module::is_pro() ) {
629 533 if ( ! self::hasChartType( 'gauge' ) ) {
630 534 if ( $get2Darray ) {
@@ -681,159 +585,44 @@
681 585 *
682 586 * @param string $suffix The current page suffix.
683 587 */
684 588 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 - }
589 + if ( $suffix === $this->_libraryPage ) {
590 + wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
591 + $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
592 + wp_enqueue_media();
714 593 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 ),
594 + 'visualizer-library',
595 + VISUALIZER_ABSURL . 'js/library.js',
596 + array(
597 + 'jquery',
598 + 'media-views',
599 + ),
718 600 Visualizer_Plugin::VERSION,
719 601 true
720 602 );
721 - if ( 'd3' === $library ) {
722 - $has_d3 = true;
723 - }
724 - }
725 603
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 - }
604 + wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
752 605
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,
606 + $query = $this->getQuery();
607 + while ( $query->have_posts() ) {
608 + $chart = $query->next_post();
609 + $library = $this->load_chart_type( $chart->ID );
610 + if ( is_null( $library ) ) {
611 + continue;
612 + }
613 + wp_enqueue_script(
614 + "visualizer-render-$library",
615 + VISUALIZER_ABSURL . 'js/render-facade.js',
616 + apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
617 + Visualizer_Plugin::VERSION,
768 618 true
769 619 );
770 620 }
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 621 }
819 -
820 - do_action( 'themeisle_internal_page', VISUALIZER_DIRNAME, 'library' );
821 622 }
822 623
823 624 /**
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 625 * Adds visualizer tab for media upload tabs array.
837 626 *
838 627 * @since 1.0.0
839 628 *
@@ -865,9 +654,9 @@
865 654 Visualizer_Plugin::NAME,
866 655 __( 'Chart Library', 'visualizer' ),
867 656 __( 'Chart Library', 'visualizer' ),
868 657 'edit_posts',
869 - 'admin.php?page=' . Visualizer_Plugin::NAME
658 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME )
870 659 );
871 660 add_submenu_page(
872 661 Visualizer_Plugin::NAME,
873 662 __( 'Add New Chart', 'visualizer' ),
@@ -872,22 +661,12 @@
872 661 Visualizer_Plugin::NAME,
873 662 __( 'Add New Chart', 'visualizer' ),
874 663 __( 'Add New Chart', 'visualizer' ),
875 664 'edit_posts',
876 - 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew'
665 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew' )
877 666 );
878 -
879 - $this->_settingsPage = add_submenu_page(
667 + add_submenu_page(
880 668 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 669 __( 'Support', 'visualizer' ),
891 670 __( 'Support', 'visualizer' ) . '<span class="dashicons dashicons-editor-help more-features-icon" style="width: 17px; height: 17px; margin-left: 4px; color: #ffca54; font-size: 17px; vertical-align: -3px;"></span>',
892 671 'edit_posts',
893 672 'viz-support',
@@ -892,151 +671,12 @@
892 671 'edit_posts',
893 672 'viz-support',
894 673 array( $this, 'renderSupportPage' )
895 674 );
896 -
897 675 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 676 }
902 677
903 678 /**
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 679 * Get the instance of WP_Query that fetches the charts as per the given criteria.
1040 680 */
1041 681 private function getQuery() {
1042 682 static $q;
@@ -1055,34 +695,29 @@
1055 695 'default' => 1,
1056 696 ),
1057 697 )
1058 698 );
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 699 // the initial query arguments to fetch charts
1075 700 $query_args = array(
1076 701 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
1077 - 'posts_per_page' => $per_page,
702 + 'posts_per_page' => 6,
1078 703 'paged' => $page,
1079 704 );
1080 -
1081 - $this->getDisplayFilters( $query_args );
1082 -
705 + // add chart type filter to the query arguments
706 + $filter = filter_input( INPUT_GET, 'type' );
707 + if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) {
708 + $query_args['meta_query'] = array(
709 + array(
710 + 'key' => Visualizer_Plugin::CF_CHART_TYPE,
711 + 'value' => $filter,
712 + 'compare' => '=',
713 + ),
714 + );
715 + } else {
716 + $filter = 'all';
717 + }
1083 718 // Added by Ash/Upwork
1084 - $filterByMeta = ! empty( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
719 + $filterByMeta = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
1085 720 if ( $filterByMeta ) {
1086 721 $query = array(
1087 722 'key' => Visualizer_Plugin::CF_SETTINGS,
1088 723 'value' => $filterByMeta,
@@ -1091,9 +726,9 @@
1091 726 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
1092 727 $meta[] = $query;
1093 728 $query_args['meta_query'] = $meta;
1094 729 }
1095 - $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
730 + $q = new WP_Query( $query_args );
1096 731 return $q;
1097 732 }
1098 733
1099 734 /**
@@ -1108,91 +743,8 @@
1108 743 include_once VISUALIZER_ABSPATH . '/templates/support.php';
1109 744 }
1110 745
1111 746 /**
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 747 * Renders visualizer library page.
1196 748 *
1197 749 * @since 1.0.0
1198 750 *
@@ -1243,22 +795,10 @@
1243 795 unset( $settings['height'], $settings['width'], $settings['chartArea'] );
1244 796 }
1245 797
1246 798 $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 );
799 + $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( $chart->post_content ) ), $chart->ID, $type );
1248 800
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 801 $library = $this->load_chart_type( $chart->ID );
1262 802
1263 803 $id = 'visualizer-' . $chart->ID;
1264 804 $arguments = $this->get_inline_custom_css( $id, $settings );
@@ -1266,19 +806,11 @@
1266 806 $css .= $arguments[0];
1267 807 $settings = $arguments[1];
1268 808 }
1269 809
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 810 // add chart to the array
1278 811 $charts[ $id ] = array(
1279 812 'id' => $chart->ID,
1280 - 'title' => $chart->post_title,
1281 813 'type' => $type,
1282 814 'series' => $series,
1283 815 'settings' => $settings,
1284 816 'data' => $data,
@@ -1283,15 +815,11 @@
1283 815 'settings' => $settings,
1284 816 'data' => $data,
1285 817 'library' => $library,
1286 818 );
1287 - if ( 'd3' === $library ) {
1288 - $charts[ $id ]['code'] = get_post_meta( $chart->ID, Visualizer_Module_AIBuilder::CF_D3_CODE, true );
1289 - }
1290 819 }
1291 820 // enqueue charts array
1292 821 $ajaxurl = admin_url( 'admin-ajax.php' );
1293 -
1294 822 wp_localize_script(
1295 823 'visualizer-library',
1296 824 'visualizer',
1297 825 array(
@@ -1298,39 +826,30 @@
1298 826 'language' => $this->get_language(),
1299 827 'map_api_key' => get_option( 'visualizer-map-api-key' ),
1300 828 'charts' => $charts,
1301 829 '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 - )
830 + 'base' => add_query_arg( array( 'vpage' => false, 'vaction' => false ) ),
831 + 'create' => add_query_arg(
832 + array(
833 + 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
834 + 'library' => 'yes',
835 + 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
836 + 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
837 + 'vaction' => false,
838 + ),
839 + $ajaxurl
1314 840 ),
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 - )
841 + 'edit' => add_query_arg(
842 + array(
843 + 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
844 + 'library' => 'yes',
845 + 'vaction' => false,
846 + ),
847 + $ajaxurl
1324 848 ),
1325 849 ),
1326 850 'page_type' => 'library',
1327 851 '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 852 )
1334 853 );
1335 854 // render library page
1336 855 $render = new Visualizer_Render_Library();
@@ -1346,9 +865,8 @@
1346 865 'total' => $query->max_num_pages,
1347 866 'type' => 'array',
1348 867 )
1349 868 );
1350 -
1351 869 $render->render();
1352 870 }
1353 871
1354 872 /**
@@ -1390,268 +908,21 @@
1390 908 *
1391 909 * @return array Updated array of plugin meta links.
1392 910 */
1393 911 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 912 if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
1409 - $is_black_friday = apply_filters( 'themeisle_sdk_is_black_friday_sale', false );
1410 913 // knowledge base link
1411 914 $plugin_meta[] = sprintf(
1412 915 '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1413 916 esc_html__( 'Docs', 'visualizer' )
1414 917 );
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 - }
918 + // flattr link
919 + $plugin_meta[] = sprintf(
920 + '<a style="color:red" href="' . Visualizer_Plugin::PRO_TEASER_URL . '" target="_blank">%s</a>',
921 + esc_html__( 'Pro Addon', 'visualizer' )
922 + );
1422 923 }
1423 924
1424 925 return $plugin_meta;
1425 926 }
1426 927
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 928 }