PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.4.5
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.4.5
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 +486 -71 3.0.93.4.5 View file →
@@ -52,26 +52,108 @@
52 52 public function __construct( Visualizer_Plugin $plugin ) {
53 53 parent::__construct( $plugin );
54 54 $this->_addAction( 'load-post.php', 'enqueueMediaScripts' );
55 55 $this->_addAction( 'load-post-new.php', 'enqueueMediaScripts' );
56 - $this->_addAction( 'admin_footer', 'renderTempaltes' );
56 + $this->_addAction( 'admin_footer', 'renderTemplates' );
57 57 $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 8 );
58 58 $this->_addAction( 'admin_menu', 'registerAdminMenu' );
59 59 $this->_addFilter( 'media_view_strings', 'setupMediaViewStrings' );
60 60 $this->_addFilter( 'plugin_action_links', 'getPluginActionLinks', 10, 2 );
61 + $this->_addFilter( 'plugin_row_meta', 'getPluginMetaLinks', 10, 2 );
61 62 $this->_addFilter( 'visualizer_logger_data', 'getLoggerData' );
62 - $this->_addFilter( 'visualizer_get_chart_counts', 'getChartCountsByTypeAndMeta' );
63 63 $this->_addFilter( 'visualizer_feedback_review_trigger', 'feedbackReviewTrigger' );
64 64
65 + // screen pagination
66 + $this->_addFilter( 'set-screen-option', 'setScreenOptions', 10, 3 );
67 +
65 68 // revision support.
66 69 $this->_addFilter( 'wp_revisions_to_keep', 'limitRevisions', null, 10, 2 );
67 70 $this->_addAction( '_wp_put_post_revision', 'addRevision', null, 10, 1 );
68 71 $this->_addAction( 'wp_restore_post_revision', 'restoreRevision', null, 10, 2 );
69 72
73 + $this->_addAction( 'visualizer_chart_schedules_spl', 'addSplChartSchedules', null, 10, 3 );
74 +
70 75 $this->_addAction( 'admin_init', 'init' );
76 +
77 + if ( defined( 'TI_CYPRESS_TESTING' ) ) {
78 + $this->load_cypress_hooks();
79 + }
80 +
71 81 }
72 82
73 83 /**
84 + * Define the hooks that are needed for cypress.
85 + *
86 + * @since 3.4.0
87 + * @access private
88 + */
89 + private function load_cypress_hooks() {
90 + // all charts should load on the same page without pagination.
91 + add_filter(
92 + 'visualizer_query_args', function( $args ) {
93 + $args['posts_per_page'] = 20;
94 + return $args;
95 + }, 10, 1
96 + );
97 + }
98 +
99 + /**
100 + * Add disabled `optgroup` schedules to the drop downs.
101 + *
102 + * @since ?
103 + *
104 + * @access public
105 + *
106 + * @param string $feature The feature for which to add schedules.
107 + * @param int $chart_id The chart ID.
108 + * @param int $plan The plan number.
109 + */
110 + public function addSplChartSchedules( $feature, $chart_id, $plan ) {
111 + if ( apply_filters( 'visualizer_is_business', false ) ) {
112 + return;
113 + }
114 +
115 + $license = __( 'PRO', 'visualizer' );
116 + if ( Visualizer_Module::is_pro() ) {
117 + switch ( $plan ) {
118 + case 1:
119 + $license = __( 'Developer', 'visualizer' );
120 + break;
121 + }
122 + }
123 +
124 + $hours = array(
125 + '0' => __( 'Live', 'visualizer' ),
126 + '1' => __( 'Each hour', 'visualizer' ),
127 + '12' => __( 'Each 12 hours', 'visualizer' ),
128 + '24' => __( 'Each day', 'visualizer' ),
129 + '72' => __( 'Each 3 days', 'visualizer' ),
130 + );
131 +
132 + switch ( $feature ) {
133 + case 'json':
134 + case 'csv':
135 + // no more schedules if pro is already active.
136 + if ( Visualizer_Module::is_pro() ) {
137 + return;
138 + }
139 + break;
140 + case 'wp':
141 + // fall-through.
142 + case 'db':
143 + break;
144 + default:
145 + return;
146 + }
147 +
148 + echo '<optgroup disabled label="' . sprintf( __( 'More in the %s version', 'visualizer' ), $license ) . '">';
149 + foreach ( $hours as $hour => $desc ) {
150 + echo '<option disabled>' . $desc . '</option>';
151 + }
152 + echo '</optgroup>';
153 + }
154 +
155 + /**
74 156 * No limits on revisions.
75 157 */
76 158 public function limitRevisions( $num, $post ) {
77 159 if ( Visualizer_Plugin::CPT_VISUALIZER === $post->post_type ) {
@@ -132,16 +214,31 @@
132 214 *
133 215 * @access public
134 216 */
135 217 public function init() {
218 + // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
136 219 if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' == get_user_option( 'rich_editing' ) ) {
137 220 $this->_addFilter( 'mce_external_languages', 'add_tinymce_lang', 10, 1 );
138 221 $this->_addFilter( 'mce_external_plugins', 'tinymce_plugin', 10, 1 );
139 222 $this->_addFilter( 'mce_buttons', 'register_mce_button', 10, 1 );
223 + $this->_addFilter( 'tiny_mce_before_init', 'get_strings_for_block', 10, 1 );
140 224 }
141 225 }
142 226
143 227 /**
228 + * Add the strings required for the TinyMCE buttons for the classic block (not the classic editor).
229 + *
230 + * @since ?
231 + * @access friendly
232 + */
233 + function get_strings_for_block( $settings ) {
234 + $class = new Visualizer_Module_Language();
235 + $strings = $class->get_strings();
236 + $array = array( 'visualizer_tinymce_plugin' => json_encode( $strings ) );
237 + return array_merge( $settings, $array );
238 + }
239 +
240 + /**
144 241 * Load plugin translation for - TinyMCE API
145 242 *
146 243 * @access public
147 244 * @param array $arr The tinymce_lang array.
@@ -212,16 +309,23 @@
212 309 public function enqueueMediaScripts() {
213 310 global $typenow;
214 311 if ( post_type_supports( $typenow, 'editor' ) ) {
215 312 wp_enqueue_style( 'visualizer-media', VISUALIZER_ABSURL . 'css/media.css', array( 'media-views' ), Visualizer_Plugin::VERSION );
216 - wp_enqueue_script( 'visualizer-google-jsapi-new', '//www.gstatic.com/charts/loader.js', array( 'media-editor' ), null, true );
217 - wp_enqueue_script( 'visualizer-google-jsapi-old', '//www.google.com/jsapi', array( 'visualizer-google-jsapi-new' ), null, true );
218 - wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', array( 'visualizer-google-jsapi-old' ), Visualizer_Plugin::VERSION, true );
313 +
314 + // Load all the assets for the different libraries we support.
315 + $deps = array(
316 + Visualizer_Render_Sidebar_Google::enqueue_assets( array( 'media-editor' ) ),
317 + Visualizer_Render_Sidebar_Type_DataTable_Tabular::enqueue_assets( array( 'media-editor' ) ),
318 + );
319 +
320 + wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', $deps, Visualizer_Plugin::VERSION, true );
219 321 wp_enqueue_script( 'visualizer-media-collection', VISUALIZER_ABSURL . 'js/media/collection.js', array( 'visualizer-media-model' ), Visualizer_Plugin::VERSION, true );
220 322 wp_enqueue_script( 'visualizer-media-controller', VISUALIZER_ABSURL . 'js/media/controller.js', array( 'visualizer-media-collection' ), Visualizer_Plugin::VERSION, true );
221 323 wp_enqueue_script( 'visualizer-media-view', VISUALIZER_ABSURL . 'js/media/view.js', array( 'visualizer-media-controller' ), Visualizer_Plugin::VERSION, true );
222 324 wp_localize_script(
223 - 'visualizer-media-view', 'visualizer', array(
325 + 'visualizer-media-view',
326 + 'visualizer',
327 + array(
224 328 'i10n' => array(
225 329 'insert' => __( 'Insert', 'visualizer' ),
226 330 ),
227 331 )
@@ -275,9 +379,9 @@
275 379 * @static
276 380 * @access private
277 381 * @return array The associated array of chart types with localized names.
278 382 */
279 - public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false, $add_select = false ) {
383 + public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false, $add_select = false, $where = null ) {
280 384 $additional = array();
281 385 if ( $add_select ) {
282 386 $additional['select'] = array(
283 387 'name' => esc_html__( 'All', 'visualizer' ),
@@ -285,58 +389,88 @@
285 389 );
286 390 }
287 391
288 392 $types = array_merge(
289 - $additional, array(
393 + $additional,
394 + array(
395 + 'tabular' => array(
396 + 'name' => esc_html__( 'Table', 'visualizer' ),
397 + 'enabled' => true,
398 + 'supports' => array( 'Google Charts', 'DataTable' ),
399 + ),
290 400 'pie' => array(
291 - 'name' => esc_html__( 'Pie', 'visualizer' ),
401 + 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
292 402 'enabled' => true,
403 + 'supports' => array( 'Google Charts', 'ChartJS' ),
293 404 ),
294 405 'line' => array(
295 406 'name' => esc_html__( 'Line', 'visualizer' ),
296 407 'enabled' => true,
408 + 'supports' => array( 'Google Charts', 'ChartJS' ),
297 409 ),
298 410 'area' => array(
299 411 'name' => esc_html__( 'Area', 'visualizer' ),
300 412 'enabled' => true,
413 + // in ChartJS, the fill option is used to make Line chart an area: https://www.chartjs.org/docs/latest/charts/area.html
414 + 'supports' => array( 'Google Charts' ),
301 415 ),
302 416 'geo' => array(
303 417 'name' => esc_html__( 'Geo', 'visualizer' ),
304 418 'enabled' => true,
419 + 'supports' => array( 'Google Charts' ),
305 420 ),
306 421 'bar' => array(
307 422 'name' => esc_html__( 'Bar', 'visualizer' ),
308 423 'enabled' => true,
424 + 'supports' => array( 'Google Charts', 'ChartJS' ),
309 425 ),
310 426 'column' => array(
311 427 'name' => esc_html__( 'Column', 'visualizer' ),
312 428 'enabled' => true,
429 + 'supports' => array( 'Google Charts', 'ChartJS' ),
313 430 ),
314 - 'gauge' => array(
315 - 'name' => esc_html__( 'Gauge', 'visualizer' ),
431 + 'bubble' => array(
432 + 'name' => esc_html__( 'Bubble', 'visualizer' ),
316 433 'enabled' => true,
434 + // chartjs' bubble is ugly looking (and it won't work off the default bubble.csv) so it is being excluded for the time being.
435 + 'supports' => array( 'Google Charts' ),
317 436 ),
318 437 'scatter' => array(
319 438 'name' => esc_html__( 'Scatter', 'visualizer' ),
320 439 'enabled' => true,
440 + 'supports' => array( 'Google Charts' ),
321 441 ),
442 + 'gauge' => array(
443 + 'name' => esc_html__( 'Gauge', 'visualizer' ),
444 + 'enabled' => true,
445 + 'supports' => array( 'Google Charts' ),
446 + ),
322 447 'candlestick' => array(
323 448 'name' => esc_html__( 'Candlestick', 'visualizer' ),
324 449 'enabled' => true,
450 + 'supports' => array( 'Google Charts' ),
325 451 ),
326 452 // pro types
327 - 'table' => array(
328 - 'name' => esc_html__( 'Table', 'visualizer' ),
329 - 'enabled' => false,
330 - ),
331 453 'timeline' => array(
332 454 'name' => esc_html__( 'Timeline', 'visualizer' ),
333 455 'enabled' => false,
456 + 'supports' => array( 'Google Charts', 'ChartJS' ),
334 457 ),
335 458 'combo' => array(
336 459 'name' => esc_html__( 'Combo', 'visualizer' ),
337 460 'enabled' => false,
461 + 'supports' => array( 'Google Charts' ),
338 462 ),
463 + 'polarArea' => array(
464 + 'name' => esc_html__( 'Polar Area', 'visualizer' ),
465 + 'enabled' => false,
466 + 'supports' => array( 'ChartJS' ),
467 + ),
468 + 'radar' => array(
469 + 'name' => esc_html__( 'Radar/Spider', 'visualizer' ),
470 + 'enabled' => false,
471 + 'supports' => array( 'ChartJS' ),
472 + ),
339 473 )
340 474 );
341 475 $types = apply_filters( 'visualizer_pro_chart_types', $types );
342 476 if ( $enabledOnly ) {
@@ -345,8 +479,12 @@
345 479 if ( ! is_array( $array ) ) {
346 480 // support for old pro
347 481 $array = array( 'enabled' => true, 'name' => $array );
348 482 }
483 + // backward compatibility for PRO before v1.9.0
484 + if ( ! array_key_exists( 'supports', $array ) ) {
485 + $array['supports'] = array( 'Google Charts' );
486 + }
349 487 if ( ! $array['enabled'] ) {
350 488 continue;
351 489 }
352 490 $filtered[ $type ] = $array;
@@ -359,13 +497,74 @@
359 497 if ( ! is_array( $array ) ) {
360 498 // support for old pro
361 499 $array = array( 'enabled' => true, 'name' => $array );
362 500 }
501 + // backward compatibility for PRO before v1.9.0
502 + if ( ! array_key_exists( 'supports', $array ) ) {
503 + $array['supports'] = array( 'Google Charts' );
504 + }
363 505 $doubleD[ $type ] = $array['name'];
364 506 }
365 507 $types = $doubleD;
366 508 }
367 509
510 + return self::handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where );
511 + }
512 +
513 + /**
514 + * Handle (soon-to-be) deprecated charts.
515 + */
516 + private static function handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where ) {
517 + $deprecated = array();
518 +
519 + switch ( $where ) {
520 + case 'types':
521 + // fall-through
522 + case 'library':
523 + // if a user has a Gauge/Candlestick chart, then let them keep using it.
524 + if ( ! Visualizer_Module::is_pro() ) {
525 + if ( ! self::hasChartType( 'gauge' ) ) {
526 + if ( $get2Darray ) {
527 + $deprecated[] = 'gauge';
528 + } else {
529 + $types['gauge']['enabled'] = false;
530 + }
531 + }
532 + if ( ! self::hasChartType( 'candlestick' ) ) {
533 + if ( $get2Darray ) {
534 + $deprecated[] = 'candlestick';
535 + } else {
536 + $types['candlestick']['enabled'] = false;
537 + }
538 + }
539 + }
540 + break;
541 + default:
542 + // if a user has a Gauge/Candlestick chart, then let them keep using it.
543 + if ( ! Visualizer_Module::is_pro() ) {
544 + if ( ! self::hasChartType( 'gauge' ) ) {
545 + if ( $get2Darray ) {
546 + $deprecated[] = 'gauge';
547 + } else {
548 + $types['gauge']['enabled'] = false;
549 + }
550 + }
551 + if ( ! self::hasChartType( 'candlestick' ) ) {
552 + if ( $get2Darray ) {
553 + $deprecated[] = 'candlestick';
554 + } else {
555 + $types['candlestick']['enabled'] = false;
556 + }
557 + }
558 + }
559 + }
560 +
561 + if ( $deprecated ) {
562 + foreach ( $deprecated as $type ) {
563 + unset( $types[ $type ] );
564 + }
565 + }
566 +
368 567 return $types;
369 568 }
370 569
371 570 /**
@@ -375,11 +574,11 @@
375 574 * @global string $pagenow The name of the current page.
376 575 *
377 576 * @access public
378 577 */
379 - public function renderTempaltes() {
578 + public function renderTemplates() {
380 579 global $pagenow;
381 - if ( 'post.php' != $pagenow && 'post-new.php' != $pagenow ) {
580 + if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
382 581 return;
383 582 }
384 583 $render = new Visualizer_Render_Templates();
385 584 $render->render();
@@ -397,26 +596,42 @@
397 596 *
398 597 * @param string $suffix The current page suffix.
399 598 */
400 599 public function enqueueLibraryScripts( $suffix ) {
401 - if ( $suffix == $this->_libraryPage ) {
600 + if ( $suffix === $this->_libraryPage ) {
601 + wp_register_script( 'visualizer-clipboardjs', VISUALIZER_ABSURL . 'js/lib/clipboardjs/clipboard.min.js', array( 'jquery' ), Visualizer_Plugin::VERSION, true );
402 602 wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
403 603 $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
404 604 wp_enqueue_media();
405 605 wp_enqueue_script(
406 - 'visualizer-library', VISUALIZER_ABSURL . 'js/library.js', array(
606 + 'visualizer-library',
607 + VISUALIZER_ABSURL . 'js/library.js',
608 + array(
407 609 'jquery',
408 610 'media-views',
409 - ), Visualizer_Plugin::VERSION, true
611 + 'visualizer-clipboardjs',
612 + ),
613 + Visualizer_Plugin::VERSION,
614 + true
410 615 );
411 - wp_enqueue_script( 'google-jsapi-new', '//www.gstatic.com/charts/loader.js', array(), null, true );
412 - wp_enqueue_script( 'google-jsapi-old', '//www.google.com/jsapi', array( 'google-jsapi-new' ), null, true );
413 - wp_enqueue_script(
414 - 'visualizer-render', VISUALIZER_ABSURL . 'js/render.js', array(
415 - 'google-jsapi-old',
416 - 'visualizer-library',
417 - ), Visualizer_Plugin::VERSION, true
418 - );
616 +
617 + wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
618 +
619 + $query = $this->getQuery();
620 + while ( $query->have_posts() ) {
621 + $chart = $query->next_post();
622 + $library = $this->load_chart_type( $chart->ID );
623 + if ( is_null( $library ) ) {
624 + continue;
625 + }
626 + wp_enqueue_script(
627 + "visualizer-render-$library",
628 + VISUALIZER_ABSURL . 'js/render-facade.js',
629 + apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
630 + Visualizer_Plugin::VERSION,
631 + true
632 + );
633 + }
419 634 }
420 635 }
421 636
422 637 /**
@@ -443,24 +658,140 @@
443 658 *
444 659 * @access public
445 660 */
446 661 public function registerAdminMenu() {
447 - $title = esc_html__( 'Visualizer Library', 'visualizer' );
448 - $callback = array( $this, 'renderLibraryPage' );
449 - $this->_libraryPage = add_submenu_page( 'upload.php', $title, $title, 'edit_posts', Visualizer_Plugin::NAME, $callback );
662 + $svg_base64_icon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNzdweCIgaGVpZ2h0PSI3N3B4IiB2aWV3Qm94PSIwIDAgNzcgNzciIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjYgKDY3NDkxKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Db21iaW5lZCBTaGFwZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxnIGlkPSJQcm9kdWN0LVBhZ2UiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJXb3JkUHJlc3MtcGx1Z2lucyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE5MC4wMDAwMDAsIC00MzUuMDAwMDAwKSIgZmlsbD0iIzM5QzNEMiI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMjguNSw1MTIgQzIwNy4yMzcwMzcsNTEyIDE5MCw0OTQuNzYyOTYzIDE5MCw0NzMuNSBDMTkwLDQ1Mi4yMzcwMzcgMjA3LjIzNzAzNyw0MzUgMjI4LjUsNDM1IEMyNDkuNzYyOTYzLDQzNSAyNjcsNDUyLjIzNzAzNyAyNjcsNDczLjUgQzI2Nyw0OTQuNzYyOTYzIDI0OS43NjI5NjMsNTEyIDIyOC41LDUxMiBaIE0yNDYuODQzNzUsNDgzLjU5MjA1OSBMMjE1LjYyNSw0ODMuNTkyMDU5IEwyMTUuNjI1LDQ2MC44MjY1NDQgQzIxNS42MjUsNDYwLjE2NDU0NyAyMTUuMTA3NTc4LDQ1OS42MjgzNTkgMjE0LjQ2ODc1LDQ1OS42MjgzNTkgTDIxMi4xNTYyNSw0NTkuNjI4MzU5IEMyMTEuNTE3NDIyLDQ1OS42MjgzNTkgMjExLDQ2MC4xNjQ1NDcgMjExLDQ2MC44MjY1NDQgTDIxMSw0ODUuOTg4NDI5IEMyMTEsNDg3LjMxMTY3NCAyMTIuMDM1NTY2LDQ4OC4zODQ3OTggMjEzLjMxMjUsNDg4LjM4NDc5OCBMMjQ2Ljg0Mzc1LDQ4OC4zODQ3OTggQzI0Ny40ODI1NzgsNDg4LjM4NDc5OCAyNDgsNDg3Ljg0ODYxMSAyNDgsNDg3LjE4NjYxMyBMMjQ4LDQ4NC43OTAyNDQgQzI0OCw0ODQuMTI4MjQ2IDI0Ny40ODI1NzgsNDgzLjU5MjA1OSAyNDYuODQzNzUsNDgzLjU5MjA1OSBaIE0yNDQuNTMxMjUsNDYyLjAyNDcyOSBMMjM1Ljk5OTU3LDQ2Mi4wMjQ3MjkgQzIzNC40NTQ1MzEsNDYyLjAyNDcyOSAyMzMuNjgwNTY2LDQ2My45NjA1NDcgMjM0Ljc3MzIyMyw0NjUuMDkyODMyIEwyMzcuMTE0NjI5LDQ2Ny41MTkxNTYgTDIzMS44MTI1LDQ3My4wMTQzMzIgTDIyNi41MTAzNzEsNDY3LjUxOTkwNSBDMjI1LjYwNzA1MSw0NjYuNTgzODIzIDIyNC4xNDI5NDksNDY2LjU4MzgyMyAyMjMuMjQwMzUyLDQ2Ny41MTk5MDUgTDIxOC4yNzY0MjYsNDcyLjY2Mzg2MyBDMjE3LjgyNDc2Niw0NzMuMTMxOTA0IDIxNy44MjQ3NjYsNDczLjg5MDUwNSAyMTguMjc2NDI2LDQ3NC4zNTg1NDYgTDIxOS45MTEwNzQsNDc2LjA1MjQ4IEMyMjAuMzYyNzM0LDQ3Ni41MjA1MjEgMjIxLjA5NDc4NSw0NzYuNTIwNTIxIDIyMS41NDY0NDUsNDc2LjA1MjQ4IEwyMjQuODc1LDQ3Mi42MDI0NTYgTDIzMC4xNzcxMjksNDc4LjA5Njg4MyBDMjMxLjA4MDQ0OSw0NzkuMDMyOTY1IDIzMi41NDQ1NTEsNDc5LjAzMjk2NSAyMzMuNDQ3MTQ4LDQ3OC4wOTY4ODMgTDI0MC4zODQ2NDgsNDcwLjkwNzc3MyBMMjQyLjcyNjA1NSw0NzMuMzM0MDk4IEMyNDMuODE4NzExLDQ3NC40NjYzODIgMjQ1LjY4Njc3Nyw0NzMuNjY0MzQ3IDI0NS42ODY3NzcsNDcyLjA2MzI3MyBMMjQ1LjY4Njc3Nyw0NjMuMjIyOTE0IEMyNDUuNjg3NSw0NjIuNTYwOTE3IDI0NS4xNzAwNzgsNDYyLjAyNDcyOSAyNDQuNTMxMjUsNDYyLjAyNDcyOSBaIiBpZD0iQ29tYmluZWQtU2hhcGUiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==';
663 +
664 + $this->_libraryPage = add_menu_page( __( 'Visualizer', 'visualizer' ), __( 'Visualizer', 'visualizer' ), 'edit_posts', Visualizer_Plugin::NAME, array( $this, 'renderLibraryPage' ), $svg_base64_icon, 99.7666 );
665 +
666 + add_submenu_page(
667 + Visualizer_Plugin::NAME,
668 + __( 'Chart Library', 'visualizer' ),
669 + __( 'Chart Library', 'visualizer' ),
670 + 'edit_posts',
671 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME )
672 + );
673 + add_submenu_page(
674 + Visualizer_Plugin::NAME,
675 + __( 'Add New Chart', 'visualizer' ),
676 + __( 'Add New Chart', 'visualizer' ),
677 + 'edit_posts',
678 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew' )
679 + );
680 + add_submenu_page(
681 + Visualizer_Plugin::NAME,
682 + __( 'Support', 'visualizer' ),
683 + __( '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>',
684 + 'edit_posts',
685 + 'viz-support',
686 + array( $this, 'renderSupportPage' )
687 + );
688 + remove_submenu_page( Visualizer_Plugin::NAME, Visualizer_Plugin::NAME );
689 +
690 + add_action( "load-{$this->_libraryPage}", array( $this, 'addScreenOptions' ) );
450 691 }
451 692
452 693 /**
453 - * Renders visualizer library page.
454 - *
455 - * @since 1.0.0
456 - *
457 - * @access public
694 + * Adds the screen options for pagination.
458 695 */
459 - public function renderLibraryPage() {
696 + function addScreenOptions() {
697 + $screen = get_current_screen();
698 +
699 + // bail if it's some other page.
700 + if ( ! is_object( $screen ) || $screen->id !== $this->_libraryPage ) {
701 + return;
702 + }
703 +
704 + $args = array(
705 + 'label' => __( 'Number of charts per page:', 'visualizer' ),
706 + 'default' => 6,
707 + 'option' => 'visualizer_per_page_library',
708 + );
709 + add_screen_option( 'per_page', $args );
710 + }
711 +
712 + /**
713 + * Returns the screen option for pagination.
714 + */
715 + function setScreenOptions( $status, $option, $value ) {
716 + if ( 'visualizer_per_page_library' === $option ) {
717 + return $value;
718 + }
719 + }
720 +
721 + /**
722 + * Adds the display filters to be used in the meta_query while displaying the charts.
723 + */
724 + private function getDisplayFilters( &$query_args ) {
725 + $query = array();
726 +
727 + // add chart type filter to the query arguments
728 + $type = filter_input( INPUT_GET, 'type' );
729 + if ( $type && in_array( $type, Visualizer_Plugin::getChartTypes(), true ) ) {
730 + $query[] = array(
731 + 'key' => Visualizer_Plugin::CF_CHART_TYPE,
732 + 'value' => $type,
733 + 'compare' => '=',
734 + );
735 + }
736 +
737 + // add chart library filter to the query arguments
738 + $library = filter_input( INPUT_GET, 'library' );
739 + if ( $library ) {
740 + $query[] = array(
741 + 'key' => Visualizer_Plugin::CF_CHART_LIBRARY,
742 + 'value' => $library,
743 + 'compare' => '=',
744 + );
745 + }
746 +
747 + // add date filter to the query arguments
748 + $date = filter_input( INPUT_GET, 'date' );
749 + $possible = array_keys( Visualizer_Plugin::getSupportedDateFilter() );
750 + if ( $date && in_array( $date, $possible, true ) ) {
751 + $query_args['date_query'] = array(
752 + 'after' => "$date -1 day",
753 + 'inclusive' => true,
754 + );
755 + }
756 +
757 + // add source filter to the query arguments
758 + $source = filter_input( INPUT_GET, 'source' );
759 + if ( $source ) {
760 + $source = ucwords( $source );
761 + $source = "Visualizer_Source_{$source}";
762 + $query[] = array(
763 + 'key' => Visualizer_Plugin::CF_SOURCE,
764 + 'value' => $source,
765 + 'compare' => '=',
766 + );
767 + }
768 +
769 + $query_args['meta_query'] = $query;
770 +
771 + $orderby = filter_input( INPUT_GET, 'orderby' );
772 + $order = filter_input( INPUT_GET, 'order' );
773 + if ( $orderby ) {
774 + $query_args['order_by'] = $orderby;
775 + }
776 + $query_args['order'] = empty( $order ) ? 'desc' : $order;
777 + }
778 +
779 + /**
780 + * Get the instance of WP_Query that fetches the charts as per the given criteria.
781 + */
782 + private function getQuery() {
783 + static $q;
784 + if ( ! is_null( $q ) ) {
785 + return $q;
786 + }
787 +
460 788 // get current page
461 789 $page = filter_input(
462 - INPUT_GET, 'vpage', FILTER_VALIDATE_INT, array(
790 + INPUT_GET,
791 + 'vpage',
792 + FILTER_VALIDATE_INT,
793 + array(
463 794 'options' => array(
464 795 'min_range' => 1,
465 796 'default' => 1,
466 797 ),
@@ -465,27 +796,32 @@
465 796 'default' => 1,
466 797 ),
467 798 )
468 799 );
800 +
801 + $per_page = 6;
802 + $screen = get_current_screen();
803 + if ( $screen ) {
804 + // retrieve the per_page option
805 + $screen_option = $screen->get_option( 'per_page', 'option' );
806 + // retrieve the value stored for the current user
807 + $user = get_current_user_id();
808 + $per_page = get_user_meta( $user, $screen_option, true );
809 + if ( empty( $per_page ) || $per_page < 1 ) {
810 + // nothing set, get the default value
811 + $per_page = $screen->get_option( 'per_page', 'default' );
812 + }
813 + }
814 +
469 815 // the initial query arguments to fetch charts
470 816 $query_args = array(
471 817 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
472 - 'posts_per_page' => 6,
818 + 'posts_per_page' => $per_page,
473 819 'paged' => $page,
474 820 );
475 - // add chart type filter to the query arguments
476 - $filter = filter_input( INPUT_GET, 'type' );
477 - if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) {
478 - $query_args['meta_query'] = array(
479 - array(
480 - 'key' => Visualizer_Plugin::CF_CHART_TYPE,
481 - 'value' => $filter,
482 - 'compare' => '=',
483 - ),
484 - );
485 - } else {
486 - $filter = 'all';
487 - }
821 +
822 + $this->getDisplayFilters( $query_args );
823 +
488 824 // Added by Ash/Upwork
489 825 $filterByMeta = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
490 826 if ( $filterByMeta ) {
491 827 $query = array(
@@ -496,56 +832,134 @@
496 832 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
497 833 $meta[] = $query;
498 834 $query_args['meta_query'] = $meta;
499 835 }
500 - // Added by Ash/Upwork
501 - // fetch charts
836 + $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
837 + return $q;
838 + }
839 +
840 + /**
841 + * Renders support page.
842 + *
843 + * @since 3.3.0
844 + *
845 + * @access public
846 + */
847 + public function renderSupportPage() {
848 + wp_enqueue_style( 'visualizer-upsell', VISUALIZER_ABSURL . 'css/upsell.css', array(), Visualizer_Plugin::VERSION );
849 + include_once VISUALIZER_ABSPATH . '/templates/support.php';
850 + }
851 +
852 + /**
853 + * Renders visualizer library page.
854 + *
855 + * @since 1.0.0
856 + *
857 + * @access public
858 + */
859 + public function renderLibraryPage() {
502 860 $charts = array();
503 - $query = new WP_Query( $query_args );
861 + $query = $this->getQuery();
862 +
863 + // get current page
864 + $page = filter_input(
865 + INPUT_GET,
866 + 'vpage',
867 + FILTER_VALIDATE_INT,
868 + array(
869 + 'options' => array(
870 + 'min_range' => 1,
871 + 'default' => 1,
872 + ),
873 + )
874 + );
875 + // add chart type filter to the query arguments
876 + $filter = filter_input( INPUT_GET, 'type' );
877 + if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) ) {
878 + $filter = 'all';
879 + }
880 +
881 + $css = '';
504 882 while ( $query->have_posts() ) {
505 883 $chart = $query->next_post();
506 884
507 885 // if the user has updated a chart and instead of saving it, has closed the modal. If the user refreshes, they should get the original chart.
508 886 $chart = $this->handleExistingRevisions( $chart->ID, $chart );
887 + // refresh a "live" db query chart.
888 + $chart = apply_filters( 'visualizer_schedule_refresh_chart', $chart, $chart->ID, false );
509 889
890 + $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
891 +
510 892 // fetch and update settings
511 893 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
512 - unset( $settings['height'], $settings['width'] );
513 - $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
894 +
895 + $settings = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $settings, $chart->ID, $type );
896 + if ( ! empty( $atts['settings'] ) ) {
897 + $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
898 + }
899 +
900 + if ( $settings ) {
901 + unset( $settings['height'], $settings['width'], $settings['chartArea'] );
902 + }
903 +
514 904 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
515 - $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( $chart->post_content ) ), $chart->ID, $type );
905 + $data = self::get_chart_data( $chart, $type );
906 +
907 + $library = $this->load_chart_type( $chart->ID );
908 +
909 + $id = 'visualizer-' . $chart->ID;
910 + $arguments = $this->get_inline_custom_css( $id, $settings );
911 + if ( ! empty( $arguments ) ) {
912 + $css .= $arguments[0];
913 + $settings = $arguments[1];
914 + }
915 +
516 916 // add chart to the array
517 - $charts[ 'visualizer-' . $chart->ID ] = array(
917 + $charts[ $id ] = array(
518 918 'id' => $chart->ID,
519 919 'type' => $type,
520 920 'series' => $series,
521 921 'settings' => $settings,
522 922 'data' => $data,
923 + 'library' => $library,
523 924 );
524 925 }
525 926 // enqueue charts array
526 927 $ajaxurl = admin_url( 'admin-ajax.php' );
527 928 wp_localize_script(
528 - 'visualizer-library', 'visualizer', array(
929 + 'visualizer-library',
930 + 'visualizer',
931 + array(
529 932 'language' => $this->get_language(),
530 933 'map_api_key' => get_option( 'visualizer-map-api-key' ),
531 934 'charts' => $charts,
532 935 'urls' => array(
533 - 'base' => add_query_arg( 'vpage', false ),
936 + 'base' => add_query_arg( array( 'vpage' => false, 'vaction' => false ) ),
534 937 'create' => add_query_arg(
535 938 array(
536 939 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
537 940 'library' => 'yes',
538 941 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
539 - ), $ajaxurl
942 + 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
943 + 'vaction' => false,
944 + ),
945 + $ajaxurl
540 946 ),
541 947 'edit' => add_query_arg(
542 948 array(
543 949 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
544 950 'library' => 'yes',
545 - ), $ajaxurl
951 + 'vaction' => false,
952 + ),
953 + $ajaxurl
546 954 ),
547 955 ),
956 + 'page_type' => 'library',
957 + 'is_front' => false,
958 + 'i10n' => array(
959 + 'copied' => __( 'The shortcode has been copied to your clipboard. Hit Ctrl-V/Cmd-V to paste it.', 'visualizer' ),
960 + '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' ),
961 + ),
548 962 )
549 963 );
550 964 // render library page
551 965 $render = new Visualizer_Render_Library();
@@ -550,12 +964,13 @@
550 964 // render library page
551 965 $render = new Visualizer_Render_Library();
552 966 $render->charts = $charts;
553 967 $render->type = $filter;
554 - $render->types = self::_getChartTypesLocalized();
968 + $render->types = self::_getChartTypesLocalized( false, false, false, true );
969 + $render->custom_css = $css;
555 970 $render->pagination = paginate_links(
556 971 array(
557 - 'base' => add_query_arg( 'vpage', '%#%' ),
972 + 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
558 973 'format' => '',
559 974 'current' => $page,
560 975 'total' => $query->max_num_pages,
561 976 'type' => 'array',
@@ -576,14 +991,14 @@
576 991 *
577 992 * @return array Updated array of action links.
578 993 */
579 994 public function getPluginActionLinks( $links, $file ) {
580 - if ( $file == plugin_basename( VISUALIZER_BASEFILE ) ) {
995 + if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
581 996 array_unshift(
582 997 $links,
583 998 sprintf(
584 999 '<a href="%s">%s</a>',
585 - admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ),
1000 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
586 1001 esc_html__( 'Library', 'visualizer' )
587 1002 )
588 1003 );
589 1004 }
@@ -603,17 +1018,17 @@
603 1018 *
604 1019 * @return array Updated array of plugin meta links.
605 1020 */
606 1021 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
607 - if ( $plugin_file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1022 + if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
608 1023 // knowledge base link
609 1024 $plugin_meta[] = sprintf(
610 - '<a href="https://github.com/codeinwp/visualizer/wiki" target="_blank">%s</a>',
611 - esc_html__( 'Knowledge Base', 'visualizer' )
1025 + '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1026 + esc_html__( 'Docs', 'visualizer' )
612 1027 );
613 1028 // flattr link
614 1029 $plugin_meta[] = sprintf(
615 - '<a style="color:red" href="https://themeisle.com/plugins/visualizer-charts-and-graphs-pro-addon/" target="_blank">%s</a>',
1030 + '<a style="color:red" href="' . Visualizer_Plugin::PRO_TEASER_URL . '" target="_blank">%s</a>',
616 1031 esc_html__( 'Pro Addon', 'visualizer' )
617 1032 );
618 1033 }
619 1034