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