PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.2.1
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.2.1
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 All 149 releases
← All changes | classes/Visualizer/Module/Admin.php +119 -990 4.0.83.2.1 View file →
@@ -29,10 +29,8 @@
29 29 class Visualizer_Module_Admin extends Visualizer_Module {
30 30
31 31 const NAME = __CLASS__;
32 32
33 - const OPTION_GLOBAL_SETTINGS = 'visualizer_global_settings';
34 -
35 33 /**
36 34 * Library page suffix.
37 35 *
38 36 * @since 1.0.0
@@ -42,24 +40,8 @@
42 40 */
43 41 private $_libraryPage;
44 42
45 43 /**
46 - * Support page suffix.
47 - *
48 - * @access private
49 - * @var string
50 - */
51 - private $_supportPage;
52 -
53 - /**
54 - * Settings page suffix.
55 - *
56 - * @access private
57 - * @var string
58 - */
59 - private $_settingsPage;
60 -
61 - /**
62 44 * Constructor.
63 45 *
64 46 * @since 1.0.0
65 47 *
@@ -70,138 +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 );
61 + $this->_addFilter( 'visualizer_logger_data', 'getLoggerData' );
62 + $this->_addFilter( 'visualizer_get_chart_counts', 'getChartCountsByTypeAndMeta' );
84 63 $this->_addFilter( 'visualizer_feedback_review_trigger', 'feedbackReviewTrigger' );
85 - $this->_addFilter( 'themeisle_sdk_blackfriday_data', 'add_black_friday_data' );
86 64
87 - // screen pagination
88 - $this->_addFilter( 'set-screen-option', 'setScreenOptions', 10, 3 );
89 -
90 65 // revision support.
91 66 $this->_addFilter( 'wp_revisions_to_keep', 'limitRevisions', null, 10, 2 );
92 67 $this->_addAction( '_wp_put_post_revision', 'addRevision', null, 10, 1 );
93 68 $this->_addAction( 'wp_restore_post_revision', 'restoreRevision', null, 10, 2 );
94 69
95 - $this->_addAction( 'visualizer_chart_schedules_spl', 'addSplChartSchedules', null, 10, 3 );
96 -
97 70 $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 71 }
111 - /**
112 - * Display review notice.
113 - */
114 - public function render_review_notice( $footer_text ) {
115 - $current_screen = get_current_screen();
116 72
117 - $visualizer_page_ids = array( 'toplevel_page_visualizer', 'visualizer_page_viz-support', 'visualizer_page_ti-about-visualizer' );
118 -
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 73 /**
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 - * Add disabled `optgroup` schedules to the drop downs.
156 - *
157 - * @since ?
158 - *
159 - * @access public
160 - *
161 - * @param string $feature The feature for which to add schedules.
162 - * @param int $chart_id The chart ID.
163 - * @param int $plan The plan number.
164 - */
165 - public function addSplChartSchedules( $feature, $chart_id, $plan ) {
166 - if ( apply_filters( 'visualizer_is_business', false ) ) {
167 - return;
168 - }
169 -
170 - $is_new_personal = apply_filters( 'visualizer_is_new_personal', false );
171 -
172 - $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' ),
178 - );
179 -
180 - switch ( $feature ) {
181 - case 'json':
182 - case 'csv':
183 - // no more schedules if pro is already active.
184 - if ( Visualizer_Module::is_pro() && ! $is_new_personal ) {
185 - return;
186 - }
187 - break;
188 - case 'wp':
189 - // fall-through.
190 - case 'db':
191 - break;
192 - default:
193 - return;
194 - }
195 -
196 - echo '<optgroup disabled label="' . __( 'Upgrade required', 'visualizer' ) . '">';
197 - foreach ( $hours as $hour => $desc ) {
198 - echo '<option disabled>' . $desc . '</option>';
199 - }
200 - echo '</optgroup>';
201 - }
202 -
203 - /**
204 74 * No limits on revisions.
205 75 */
206 76 public function limitRevisions( $num, $post ) {
207 77 if ( Visualizer_Plugin::CPT_VISUALIZER === $post->post_type ) {
@@ -221,9 +91,9 @@
221 91
222 92 if ( $meta ) {
223 93 foreach ( $meta as $key => $value ) {
224 94 if ( 0 === strpos( $key, 'visualizer' ) ) {
225 - add_metadata( 'post', $revision_id, $key, self::maybe_decode_content( $value[0] ) );
95 + add_metadata( 'post', $revision_id, $key, maybe_unserialize( $value[0] ) );
226 96 }
227 97 }
228 98 }
229 99 }
@@ -249,9 +119,9 @@
249 119
250 120 if ( $meta ) {
251 121 foreach ( $meta as $key => $value ) {
252 122 if ( 0 === strpos( $key, 'visualizer' ) ) {
253 - add_post_meta( $post_id, $key, self::maybe_decode_content( $value[0] ) );
123 + add_post_meta( $post_id, $key, maybe_unserialize( $value[0] ) );
254 124 }
255 125 }
256 126 }
257 127 }
@@ -262,30 +132,17 @@
262 132 *
263 133 * @access public
264 134 */
265 135 public function init() {
266 - 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' ) ) {
267 138 $this->_addFilter( 'mce_external_languages', 'add_tinymce_lang', 10, 1 );
268 139 $this->_addFilter( 'mce_external_plugins', 'tinymce_plugin', 10, 1 );
269 140 $this->_addFilter( 'mce_buttons', 'register_mce_button', 10, 1 );
270 - $this->_addFilter( 'tiny_mce_before_init', 'get_strings_for_block', 10, 1 );
271 141 }
272 142 }
273 143
274 144 /**
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 145 * Load plugin translation for - TinyMCE API
289 146 *
290 147 * @access public
291 148 * @param array $arr The tinymce_lang array.
@@ -354,40 +211,15 @@
354 211 * @access public
355 212 */
356 213 public function enqueueMediaScripts() {
357 214 global $typenow;
358 - global $current_screen;
359 -
360 - if ( post_type_supports( $typenow, 'editor' ) || $current_screen->id === 'widgets' || $current_screen->id === 'customize' ) {
215 + if ( post_type_supports( $typenow, 'editor' ) ) {
361 216 wp_enqueue_style( 'visualizer-media', VISUALIZER_ABSURL . 'css/media.css', array( 'media-views' ), Visualizer_Plugin::VERSION );
362 217
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 218 // Load all the assets for the different libraries we support.
387 219 $deps = array(
388 220 Visualizer_Render_Sidebar_Google::enqueue_assets( array( 'media-editor' ) ),
389 - Visualizer_Render_Sidebar_Type_DataTable_Tabular::enqueue_assets( array( 'media-editor' ) ),
221 + Visualizer_Render_Sidebar_Type_DataTable::enqueue_assets( array( 'media-editor' ) ),
390 222 );
391 223
392 224 wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', $deps, Visualizer_Plugin::VERSION, true );
393 225 wp_enqueue_script( 'visualizer-media-collection', VISUALIZER_ABSURL . 'js/media/collection.js', array( 'visualizer-media-model' ), Visualizer_Plugin::VERSION, true );
@@ -397,9 +229,9 @@
397 229 'visualizer-media-view',
398 230 'visualizer',
399 231 array(
400 232 'i10n' => array(
401 - 'insert' => __( 'Insert Chart', 'visualizer' ),
233 + 'insert' => __( 'Insert', 'visualizer' ),
402 234 ),
403 235 )
404 236 );
405 237 wp_enqueue_script( 'visualizer-media-toolbar', VISUALIZER_ABSURL . 'js/media/toolbar.js', array( 'visualizer-media-view' ), Visualizer_Plugin::VERSION, true );
@@ -428,9 +260,9 @@
428 260 'controller' => array(
429 261 'title' => esc_html__( 'Visualizations', 'visualizer' ),
430 262 ),
431 263 'routers' => array(
432 - 'library' => esc_html__( 'Insert from Library', 'visualizer' ),
264 + 'library' => esc_html__( 'From Library', 'visualizer' ),
433 265 'create' => esc_html__( 'Create New', 'visualizer' ),
434 266 ),
435 267 'library' => array(
436 268 'filters' => $chart_types,
@@ -435,10 +267,10 @@
435 267 'library' => array(
436 268 'filters' => $chart_types,
437 269 'types' => array_keys( $chart_types ),
438 270 ),
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' ) ) ),
271 + 'nonce' => wp_create_nonce(),
272 + 'buildurl' => add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ),
441 273 );
442 274
443 275 return $strings;
444 276 }
@@ -460,102 +292,64 @@
460 292 'enabled' => true,
461 293 );
462 294 }
463 295
464 - $enabled = self::proFeaturesEnabled();
465 -
466 296 $types = array_merge(
467 297 $additional,
468 298 array(
469 - 'tabular' => array(
470 - 'name' => esc_html__( 'Table', 'visualizer' ),
299 + 'dataTable' => array(
300 + 'name' => esc_html__( 'Table (New)', 'visualizer' ),
471 301 'enabled' => true,
472 - 'supports' => $enabled ? array( 'Google Charts', 'DataTable' ) : array( 'DataTable' ),
473 302 ),
474 303 'pie' => array(
475 - 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
304 + 'name' => esc_html__( 'Pie', 'visualizer' ),
476 305 'enabled' => true,
477 - 'supports' => array( 'Google Charts', 'ChartJS' ),
478 306 ),
479 307 'line' => array(
480 308 'name' => esc_html__( 'Line', 'visualizer' ),
481 309 'enabled' => true,
482 - 'supports' => array( 'Google Charts', 'ChartJS' ),
483 310 ),
484 - 'bar' => array(
485 - 'name' => esc_html__( 'Bar', 'visualizer' ),
486 - 'enabled' => true,
487 - 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
488 - ),
489 311 'area' => array(
490 312 'name' => esc_html__( 'Area', 'visualizer' ),
491 - 'enabled' => $enabled,
492 - // in ChartJS, the fill option is used to make Line chart an area: https://www.chartjs.org/docs/latest/charts/area.html
493 - 'supports' => array( 'Google Charts' ),
494 - 'demo_url' => 'https://demo.themeisle.com/visualizer/area-chart/',
313 + 'enabled' => true,
495 314 ),
496 315 'geo' => array(
497 316 'name' => esc_html__( 'Geo', 'visualizer' ),
498 - 'enabled' => $enabled,
499 - 'supports' => array( 'Google Charts' ),
500 - 'demo_url' => 'https://demo.themeisle.com/visualizer/geo-chart/',
317 + 'enabled' => true,
501 318 ),
319 + 'bar' => array(
320 + 'name' => esc_html__( 'Bar', 'visualizer' ),
321 + 'enabled' => true,
322 + ),
502 323 'column' => array(
503 324 'name' => esc_html__( 'Column', 'visualizer' ),
504 - 'enabled' => $enabled,
505 - 'supports' => array( 'Google Charts', 'ChartJS' ),
506 - 'demo_url' => 'https://demo.themeisle.com/visualizer/column-chart/',
325 + 'enabled' => true,
507 326 ),
508 - 'bubble' => array(
509 - 'name' => esc_html__( 'Bubble', 'visualizer' ),
510 - 'enabled' => $enabled,
511 - // 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 - 'supports' => array( 'Google Charts' ),
513 - 'demo_url' => 'https://demo.themeisle.com/visualizer/bubble-chart/',
514 - ),
515 327 'scatter' => array(
516 328 'name' => esc_html__( 'Scatter', 'visualizer' ),
517 - 'enabled' => $enabled,
518 - 'supports' => array( 'Google Charts' ),
519 - 'demo_url' => 'https://demo.themeisle.com/visualizer/scatter-chart/',
329 + 'enabled' => true,
520 330 ),
521 331 'gauge' => array(
522 332 'name' => esc_html__( 'Gauge', 'visualizer' ),
523 - 'enabled' => $enabled,
524 - 'supports' => array( 'Google Charts' ),
525 - 'demo_url' => 'https://demo.themeisle.com/visualizer/gauge-chart/',
333 + 'enabled' => true,
526 334 ),
527 335 'candlestick' => array(
528 336 'name' => esc_html__( 'Candlestick', 'visualizer' ),
529 - 'enabled' => $enabled,
530 - 'supports' => array( 'Google Charts' ),
531 - 'demo_url' => 'https://demo.themeisle.com/visualizer/candlestick-chart/',
337 + 'enabled' => true,
532 338 ),
533 339 // pro types
340 + 'table' => array(
341 + 'name' => esc_html__( 'Table (Deprecated)', 'visualizer' ),
342 + 'enabled' => false,
343 + ),
534 344 'timeline' => array(
535 345 'name' => esc_html__( 'Timeline', 'visualizer' ),
536 346 'enabled' => false,
537 - 'supports' => array( 'Google Charts', 'ChartJS' ),
538 - 'demo_url' => 'https://demo.themeisle.com/visualizer/timeline-chart/',
539 347 ),
540 348 'combo' => array(
541 349 'name' => esc_html__( 'Combo', 'visualizer' ),
542 350 'enabled' => false,
543 - 'supports' => array( 'Google Charts' ),
544 - 'demo_url' => 'https://demo.themeisle.com/visualizer/combo-chart/',
545 351 ),
546 - 'polarArea' => array(
547 - 'name' => esc_html__( 'Polar Area', 'visualizer' ),
548 - 'enabled' => false,
549 - 'supports' => array( 'ChartJS' ),
550 - 'demo_url' => 'https://demo.themeisle.com/visualizer/polar-area-chart/',
551 - ),
552 - 'radar' => array(
553 - 'name' => esc_html__( 'Radar/Spider', 'visualizer' ),
554 - 'enabled' => false,
555 - 'supports' => array( 'ChartJS' ),
556 - 'demo_url' => 'https://demo.themeisle.com/visualizer/radar-spider-chart/',
557 - ),
558 352 )
559 353 );
560 354 $types = apply_filters( 'visualizer_pro_chart_types', $types );
561 355 if ( $enabledOnly ) {
@@ -564,12 +358,8 @@
564 358 if ( ! is_array( $array ) ) {
565 359 // support for old pro
566 360 $array = array( 'enabled' => true, 'name' => $array );
567 361 }
568 - // backward compatibility for PRO before v1.9.0
569 - if ( ! array_key_exists( 'supports', $array ) ) {
570 - $array['supports'] = array( 'Google Charts' );
571 - }
572 362 if ( ! $array['enabled'] ) {
573 363 continue;
574 364 }
575 365 $filtered[ $type ] = $array;
@@ -582,12 +372,8 @@
582 372 if ( ! is_array( $array ) ) {
583 373 // support for old pro
584 374 $array = array( 'enabled' => true, 'name' => $array );
585 375 }
586 - // backward compatibility for PRO before v1.9.0
587 - if ( ! array_key_exists( 'supports', $array ) ) {
588 - $array['supports'] = array( 'Google Charts' );
589 - }
590 376 $doubleD[ $type ] = $array['name'];
591 377 }
592 378 $types = $doubleD;
593 379 }
@@ -601,13 +387,21 @@
601 387 private static function handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where ) {
602 388 $deprecated = array();
603 389
604 390 switch ( $where ) {
605 - case 'types':
606 - // fall-through
607 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 +
608 402 // if a user has a Gauge/Candlestick chart, then let them keep using it.
609 - if ( ! Visualizer_Module::is_pro() ) {
403 + if ( ! VISUALIZER_PRO ) {
610 404 if ( ! self::hasChartType( 'gauge' ) ) {
611 405 if ( $get2Darray ) {
612 406 $deprecated[] = 'gauge';
613 407 } else {
@@ -623,10 +417,20 @@
623 417 }
624 418 }
625 419 break;
626 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 +
627 431 // if a user has a Gauge/Candlestick chart, then let them keep using it.
628 - if ( ! Visualizer_Module::is_pro() ) {
432 + if ( ! VISUALIZER_PRO ) {
629 433 if ( ! self::hasChartType( 'gauge' ) ) {
630 434 if ( $get2Darray ) {
631 435 $deprecated[] = 'gauge';
632 436 } else {
@@ -681,159 +485,44 @@
681 485 *
682 486 * @param string $suffix The current page suffix.
683 487 */
684 488 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 - }
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();
714 493 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 ),
494 + 'visualizer-library',
495 + VISUALIZER_ABSURL . 'js/library.js',
496 + array(
497 + 'jquery',
498 + 'media-views',
499 + ),
718 500 Visualizer_Plugin::VERSION,
719 501 true
720 502 );
721 - if ( 'd3' === $library ) {
722 - $has_d3 = true;
723 - }
724 - }
725 503
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 - }
504 + wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
752 505
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,
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,
768 518 true
769 519 );
770 520 }
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 521 }
819 -
820 - do_action( 'themeisle_internal_page', VISUALIZER_DIRNAME, 'library' );
821 522 }
822 523
823 524 /**
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 525 * Adds visualizer tab for media upload tabs array.
837 526 *
838 527 * @since 1.0.0
839 528 *
@@ -856,187 +545,14 @@
856 545 *
857 546 * @access public
858 547 */
859 548 public function registerAdminMenu() {
860 - $svg_base64_icon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNzdweCIgaGVpZ2h0PSI3N3B4IiB2aWV3Qm94PSIwIDAgNzcgNzciIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjYgKDY3NDkxKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Db21iaW5lZCBTaGFwZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxnIGlkPSJQcm9kdWN0LVBhZ2UiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJXb3JkUHJlc3MtcGx1Z2lucyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE5MC4wMDAwMDAsIC00MzUuMDAwMDAwKSIgZmlsbD0iIzM5QzNEMiI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMjguNSw1MTIgQzIwNy4yMzcwMzcsNTEyIDE5MCw0OTQuNzYyOTYzIDE5MCw0NzMuNSBDMTkwLDQ1Mi4yMzcwMzcgMjA3LjIzNzAzNyw0MzUgMjI4LjUsNDM1IEMyNDkuNzYyOTYzLDQzNSAyNjcsNDUyLjIzNzAzNyAyNjcsNDczLjUgQzI2Nyw0OTQuNzYyOTYzIDI0OS43NjI5NjMsNTEyIDIyOC41LDUxMiBaIE0yNDYuODQzNzUsNDgzLjU5MjA1OSBMMjE1LjYyNSw0ODMuNTkyMDU5IEwyMTUuNjI1LDQ2MC44MjY1NDQgQzIxNS42MjUsNDYwLjE2NDU0NyAyMTUuMTA3NTc4LDQ1OS42MjgzNTkgMjE0LjQ2ODc1LDQ1OS42MjgzNTkgTDIxMi4xNTYyNSw0NTkuNjI4MzU5IEMyMTEuNTE3NDIyLDQ1OS42MjgzNTkgMjExLDQ2MC4xNjQ1NDcgMjExLDQ2MC44MjY1NDQgTDIxMSw0ODUuOTg4NDI5IEMyMTEsNDg3LjMxMTY3NCAyMTIuMDM1NTY2LDQ4OC4zODQ3OTggMjEzLjMxMjUsNDg4LjM4NDc5OCBMMjQ2Ljg0Mzc1LDQ4OC4zODQ3OTggQzI0Ny40ODI1NzgsNDg4LjM4NDc5OCAyNDgsNDg3Ljg0ODYxMSAyNDgsNDg3LjE4NjYxMyBMMjQ4LDQ4NC43OTAyNDQgQzI0OCw0ODQuMTI4MjQ2IDI0Ny40ODI1NzgsNDgzLjU5MjA1OSAyNDYuODQzNzUsNDgzLjU5MjA1OSBaIE0yNDQuNTMxMjUsNDYyLjAyNDcyOSBMMjM1Ljk5OTU3LDQ2Mi4wMjQ3MjkgQzIzNC40NTQ1MzEsNDYyLjAyNDcyOSAyMzMuNjgwNTY2LDQ2My45NjA1NDcgMjM0Ljc3MzIyMyw0NjUuMDkyODMyIEwyMzcuMTE0NjI5LDQ2Ny41MTkxNTYgTDIzMS44MTI1LDQ3My4wMTQzMzIgTDIyNi41MTAzNzEsNDY3LjUxOTkwNSBDMjI1LjYwNzA1MSw0NjYuNTgzODIzIDIyNC4xNDI5NDksNDY2LjU4MzgyMyAyMjMuMjQwMzUyLDQ2Ny41MTk5MDUgTDIxOC4yNzY0MjYsNDcyLjY2Mzg2MyBDMjE3LjgyNDc2Niw0NzMuMTMxOTA0IDIxNy44MjQ3NjYsNDczLjg5MDUwNSAyMTguMjc2NDI2LDQ3NC4zNTg1NDYgTDIxOS45MTEwNzQsNDc2LjA1MjQ4IEMyMjAuMzYyNzM0LDQ3Ni41MjA1MjEgMjIxLjA5NDc4NSw0NzYuNTIwNTIxIDIyMS41NDY0NDUsNDc2LjA1MjQ4IEwyMjQuODc1LDQ3Mi42MDI0NTYgTDIzMC4xNzcxMjksNDc4LjA5Njg4MyBDMjMxLjA4MDQ0OSw0NzkuMDMyOTY1IDIzMi41NDQ1NTEsNDc5LjAzMjk2NSAyMzMuNDQ3MTQ4LDQ3OC4wOTY4ODMgTDI0MC4zODQ2NDgsNDcwLjkwNzc3MyBMMjQyLjcyNjA1NSw0NzMuMzM0MDk4IEMyNDMuODE4NzExLDQ3NC40NjYzODIgMjQ1LjY4Njc3Nyw0NzMuNjY0MzQ3IDI0NS42ODY3NzcsNDcyLjA2MzI3MyBMMjQ1LjY4Njc3Nyw0NjMuMjIyOTE0IEMyNDUuNjg3NSw0NjIuNTYwOTE3IDI0NS4xNzAwNzgsNDYyLjAyNDcyOSAyNDQuNTMxMjUsNDYyLjAyNDcyOSBaIiBpZD0iQ29tYmluZWQtU2hhcGUiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==';
861 -
862 - $this->_libraryPage = add_menu_page( __( 'Visualizer', 'visualizer' ), __( 'Visualizer', 'visualizer' ), 'edit_posts', Visualizer_Plugin::NAME, array( $this, 'renderLibraryPage' ), $svg_base64_icon, 99.7666 );
863 -
864 - add_submenu_page(
865 - Visualizer_Plugin::NAME,
866 - __( 'Chart Library', 'visualizer' ),
867 - __( 'Chart Library', 'visualizer' ),
868 - 'edit_posts',
869 - 'admin.php?page=' . Visualizer_Plugin::NAME
870 - );
871 - add_submenu_page(
872 - Visualizer_Plugin::NAME,
873 - __( 'Add New Chart', 'visualizer' ),
874 - __( 'Add New Chart', 'visualizer' ),
875 - 'edit_posts',
876 - 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew'
877 - );
878 -
879 - $this->_settingsPage = add_submenu_page(
880 - 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 - __( 'Support', 'visualizer' ),
891 - __( '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 - 'edit_posts',
893 - 'viz-support',
894 - array( $this, 'renderSupportPage' )
895 - );
896 -
897 - 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' ) );
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 );
901 552 }
902 553
903 554 /**
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 555 * Get the instance of WP_Query that fetches the charts as per the given criteria.
1040 556 */
1041 557 private function getQuery() {
1042 558 static $q;
@@ -1055,34 +571,29 @@
1055 571 'default' => 1,
1056 572 ),
1057 573 )
1058 574 );
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 575 // the initial query arguments to fetch charts
1075 576 $query_args = array(
1076 577 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
1077 - 'posts_per_page' => $per_page,
578 + 'posts_per_page' => 6,
1078 579 'paged' => $page,
1079 580 );
1080 -
1081 - $this->getDisplayFilters( $query_args );
1082 -
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 + }
1083 594 // Added by Ash/Upwork
1084 - $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 );
1085 596 if ( $filterByMeta ) {
1086 597 $query = array(
1087 598 'key' => Visualizer_Plugin::CF_SETTINGS,
1088 599 'value' => $filterByMeta,
@@ -1091,108 +602,13 @@
1091 602 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
1092 603 $meta[] = $query;
1093 604 $query_args['meta_query'] = $meta;
1094 605 }
1095 - $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
606 + $q = new WP_Query( $query_args );
1096 607 return $q;
1097 608 }
1098 609
1099 610 /**
1100 - * Renders support page.
1101 - *
1102 - * @since 3.3.0
1103 - *
1104 - * @access public
1105 - */
1106 - public function renderSupportPage() {
1107 - wp_enqueue_style( 'visualizer-upsell', VISUALIZER_ABSURL . 'css/upsell.css', array(), Visualizer_Plugin::VERSION );
1108 - include_once VISUALIZER_ABSPATH . '/templates/support.php';
1109 - }
1110 -
1111 - /**
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 611 * Renders visualizer library page.
1196 612 *
1197 613 * @since 1.0.0
1198 614 *
@@ -1238,27 +654,12 @@
1238 654 if ( ! empty( $atts['settings'] ) ) {
1239 655 $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
1240 656 }
1241 657
1242 - if ( $settings ) {
1243 - unset( $settings['height'], $settings['width'], $settings['chartArea'] );
1244 - }
1245 -
658 + unset( $settings['height'], $settings['width'] );
1246 659 $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 );
660 + $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( $chart->post_content ) ), $chart->ID, $type );
1248 661
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 662 $library = $this->load_chart_type( $chart->ID );
1262 663
1263 664 $id = 'visualizer-' . $chart->ID;
1264 665 $arguments = $this->get_inline_custom_css( $id, $settings );
@@ -1266,19 +667,11 @@
1266 667 $css .= $arguments[0];
1267 668 $settings = $arguments[1];
1268 669 }
1269 670
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 671 // add chart to the array
1278 672 $charts[ $id ] = array(
1279 673 'id' => $chart->ID,
1280 - 'title' => $chart->post_title,
1281 674 'type' => $type,
1282 675 'series' => $series,
1283 676 'settings' => $settings,
1284 677 'data' => $data,
@@ -1283,15 +676,11 @@
1283 676 'settings' => $settings,
1284 677 'data' => $data,
1285 678 'library' => $library,
1286 679 );
1287 - if ( 'd3' === $library ) {
1288 - $charts[ $id ]['code'] = get_post_meta( $chart->ID, Visualizer_Module_AIBuilder::CF_D3_CODE, true );
1289 - }
1290 680 }
1291 681 // enqueue charts array
1292 682 $ajaxurl = admin_url( 'admin-ajax.php' );
1293 -
1294 683 wp_localize_script(
1295 684 'visualizer-library',
1296 685 'visualizer',
1297 686 array(
@@ -1298,39 +687,27 @@
1298 687 'language' => $this->get_language(),
1299 688 'map_api_key' => get_option( 'visualizer-map-api-key' ),
1300 689 'charts' => $charts,
1301 690 '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 - )
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
1314 699 ),
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 - )
700 + 'edit' => add_query_arg(
701 + array(
702 + 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
703 + 'library' => 'yes',
704 + ),
705 + $ajaxurl
1324 706 ),
1325 707 ),
1326 708 'page_type' => 'library',
1327 709 '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 710 )
1334 711 );
1335 712 // render library page
1336 713 $render = new Visualizer_Render_Library();
@@ -1339,9 +716,9 @@
1339 716 $render->types = self::_getChartTypesLocalized( false, false, false, true );
1340 717 $render->custom_css = $css;
1341 718 $render->pagination = paginate_links(
1342 719 array(
1343 - 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
720 + 'base' => add_query_arg( 'vpage', '%#%' ),
1344 721 'format' => '',
1345 722 'current' => $page,
1346 723 'total' => $query->max_num_pages,
1347 724 'type' => 'array',
@@ -1346,9 +723,8 @@
1346 723 'total' => $query->max_num_pages,
1347 724 'type' => 'array',
1348 725 )
1349 726 );
1350 -
1351 727 $render->render();
1352 728 }
1353 729
1354 730 /**
@@ -1368,9 +744,9 @@
1368 744 array_unshift(
1369 745 $links,
1370 746 sprintf(
1371 747 '<a href="%s">%s</a>',
1372 - admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
748 + admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ),
1373 749 esc_html__( 'Library', 'visualizer' )
1374 750 )
1375 751 );
1376 752 }
@@ -1390,268 +766,21 @@
1390 766 *
1391 767 * @return array Updated array of plugin meta links.
1392 768 */
1393 769 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 770 if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
1409 - $is_black_friday = apply_filters( 'themeisle_sdk_is_black_friday_sale', false );
1410 771 // knowledge base link
1411 772 $plugin_meta[] = sprintf(
1412 - '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1413 - esc_html__( 'Docs', 'visualizer' )
773 + '<a href="https://github.com/codeinwp/visualizer/wiki" target="_blank">%s</a>',
774 + esc_html__( 'Knowledge Base', 'visualizer' )
1414 775 );
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 - }
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 + );
1422 781 }
1423 782
1424 783 return $plugin_meta;
1425 784 }
1426 785
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 786 }