PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.4.4
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.4.4
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 +342 -50 3.1.03.4.4 View file →
@@ -57,21 +57,103 @@
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.
@@ -214,10 +311,12 @@
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 313
217 314 // Load all the assets for the different libraries we support.
218 - $deps = Visualizer_Render_Sidebar_Google::enqueue_assets( array( 'media-editor' ) );
219 - $deps += Visualizer_Render_Sidebar_Type_DataTable::enqueue_assets( array( 'media-editor' ) );
315 + $deps = array(
316 + Visualizer_Render_Sidebar_Google::enqueue_assets( array( 'media-editor' ) ),
317 + Visualizer_Render_Sidebar_Type_DataTable_DataTable::enqueue_assets( array( 'media-editor' ) ),
318 + );
220 319
221 320 wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', $deps, Visualizer_Plugin::VERSION, true );
222 321 wp_enqueue_script( 'visualizer-media-collection', VISUALIZER_ABSURL . 'js/media/collection.js', array( 'visualizer-media-model' ), Visualizer_Plugin::VERSION, true );
223 322 wp_enqueue_script( 'visualizer-media-controller', VISUALIZER_ABSURL . 'js/media/controller.js', array( 'visualizer-media-collection' ), Visualizer_Plugin::VERSION, true );
@@ -293,60 +392,90 @@
293 392 $types = array_merge(
294 393 $additional,
295 394 array(
296 395 'dataTable' => array(
297 - 'name' => esc_html__( 'Table (New)', 'visualizer' ),
396 + 'name' => esc_html__( 'Table', 'visualizer' ),
298 397 'enabled' => true,
398 + 'supports' => array( 'DataTable' ),
299 399 ),
300 400 'pie' => array(
301 - 'name' => esc_html__( 'Pie', 'visualizer' ),
401 + 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
302 402 'enabled' => true,
403 + 'supports' => array( 'Google Charts', 'ChartJS' ),
303 404 ),
304 405 'line' => array(
305 406 'name' => esc_html__( 'Line', 'visualizer' ),
306 407 'enabled' => true,
408 + 'supports' => array( 'Google Charts', 'ChartJS' ),
307 409 ),
308 410 'area' => array(
309 411 'name' => esc_html__( 'Area', 'visualizer' ),
310 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' ),
311 415 ),
312 416 'geo' => array(
313 417 'name' => esc_html__( 'Geo', 'visualizer' ),
314 418 'enabled' => true,
419 + 'supports' => array( 'Google Charts' ),
315 420 ),
316 421 'bar' => array(
317 422 'name' => esc_html__( 'Bar', 'visualizer' ),
318 423 'enabled' => true,
424 + 'supports' => array( 'Google Charts', 'ChartJS' ),
319 425 ),
320 426 'column' => array(
321 427 'name' => esc_html__( 'Column', 'visualizer' ),
322 428 'enabled' => true,
429 + 'supports' => array( 'Google Charts', 'ChartJS' ),
323 430 ),
324 - 'gauge' => array(
325 - 'name' => esc_html__( 'Gauge', 'visualizer' ),
431 + 'bubble' => array(
432 + 'name' => esc_html__( 'Bubble', 'visualizer' ),
326 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' ),
327 436 ),
328 437 'scatter' => array(
329 438 'name' => esc_html__( 'Scatter', 'visualizer' ),
330 439 'enabled' => true,
440 + 'supports' => array( 'Google Charts' ),
331 441 ),
442 + 'gauge' => array(
443 + 'name' => esc_html__( 'Gauge', 'visualizer' ),
444 + 'enabled' => true,
445 + 'supports' => array( 'Google Charts' ),
446 + ),
332 447 'candlestick' => array(
333 448 'name' => esc_html__( 'Candlestick', 'visualizer' ),
334 449 'enabled' => true,
450 + 'supports' => array( 'Google Charts' ),
335 451 ),
336 452 // pro types
337 453 'table' => array(
338 454 'name' => esc_html__( 'Table (Deprecated)', 'visualizer' ),
339 455 'enabled' => false,
456 + 'supports' => array( 'Google Charts' ),
340 457 ),
341 458 'timeline' => array(
342 459 'name' => esc_html__( 'Timeline', 'visualizer' ),
343 460 'enabled' => false,
461 + 'supports' => array( 'Google Charts', 'ChartJS' ),
344 462 ),
345 463 'combo' => array(
346 464 'name' => esc_html__( 'Combo', 'visualizer' ),
347 465 'enabled' => false,
466 + 'supports' => array( 'Google Charts' ),
348 467 ),
468 + 'polarArea' => array(
469 + 'name' => esc_html__( 'Polar Area', 'visualizer' ),
470 + 'enabled' => false,
471 + 'supports' => array( 'ChartJS' ),
472 + ),
473 + 'radar' => array(
474 + 'name' => esc_html__( 'Radar/Spider', 'visualizer' ),
475 + 'enabled' => false,
476 + 'supports' => array( 'ChartJS' ),
477 + ),
349 478 )
350 479 );
351 480 $types = apply_filters( 'visualizer_pro_chart_types', $types );
352 481 if ( $enabledOnly ) {
@@ -355,8 +484,12 @@
355 484 if ( ! is_array( $array ) ) {
356 485 // support for old pro
357 486 $array = array( 'enabled' => true, 'name' => $array );
358 487 }
488 + // backward compatibility for PRO before v1.9.0
489 + if ( ! array_key_exists( 'supports', $array ) ) {
490 + $array['supports'] = array( 'Google Charts' );
491 + }
359 492 if ( ! $array['enabled'] ) {
360 493 continue;
361 494 }
362 495 $filtered[ $type ] = $array;
@@ -369,8 +502,12 @@
369 502 if ( ! is_array( $array ) ) {
370 503 // support for old pro
371 504 $array = array( 'enabled' => true, 'name' => $array );
372 505 }
506 + // backward compatibility for PRO before v1.9.0
507 + if ( ! array_key_exists( 'supports', $array ) ) {
508 + $array['supports'] = array( 'Google Charts' );
509 + }
373 510 $doubleD[ $type ] = $array['name'];
374 511 }
375 512 $types = $doubleD;
376 513 }
@@ -384,8 +521,10 @@
384 521 private static function handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where ) {
385 522 $deprecated = array();
386 523
387 524 switch ( $where ) {
525 + case 'types':
526 + // fall-through
388 527 case 'library':
389 528 // if the user has a Google Table chart, show it as deprecated otherwise remove the option from the library.
390 529 if ( ! self::hasChartType( 'table' ) ) {
391 530 $deprecated[] = 'table';
@@ -396,14 +535,22 @@
396 535 }
397 536 }
398 537
399 538 // if a user has a Gauge/Candlestick chart, then let them keep using it.
400 - if ( ! VISUALIZER_PRO ) {
539 + if ( ! Visualizer_Module::is_pro() ) {
401 540 if ( ! self::hasChartType( 'gauge' ) ) {
402 - $deprecated[] = 'gauge';
541 + if ( $get2Darray ) {
542 + $deprecated[] = 'gauge';
543 + } else {
544 + $types['gauge']['enabled'] = false;
545 + }
403 546 }
404 547 if ( ! self::hasChartType( 'candlestick' ) ) {
405 - $deprecated[] = 'candlestick';
548 + if ( $get2Darray ) {
549 + $deprecated[] = 'candlestick';
550 + } else {
551 + $types['candlestick']['enabled'] = false;
552 + }
406 553 }
407 554 }
408 555 break;
409 556 default:
@@ -410,23 +557,29 @@
410 557 // remove the option to create a Google Table chart.
411 558 $deprecated[] = 'table';
412 559
413 560 // rename the new table chart type.
414 - if ( self::hasChartType( 'table' ) ) {
415 - if ( $get2Darray ) {
416 - $types['dataTable'] = esc_html__( 'Table', 'visualizer' );
417 - } else {
418 - $types['dataTable']['name'] = esc_html__( 'Table', 'visualizer' );
419 - }
561 + if ( $get2Darray ) {
562 + $types['dataTable'] = esc_html__( 'Table', 'visualizer' );
563 + } else {
564 + $types['dataTable']['name'] = esc_html__( 'Table', 'visualizer' );
420 565 }
421 566
422 567 // if a user has a Gauge/Candlestick chart, then let them keep using it.
423 - if ( ! VISUALIZER_PRO ) {
568 + if ( ! Visualizer_Module::is_pro() ) {
424 569 if ( ! self::hasChartType( 'gauge' ) ) {
425 - $deprecated[] = 'gauge';
570 + if ( $get2Darray ) {
571 + $deprecated[] = 'gauge';
572 + } else {
573 + $types['gauge']['enabled'] = false;
574 + }
426 575 }
427 576 if ( ! self::hasChartType( 'candlestick' ) ) {
428 - $deprecated[] = 'candlestick';
577 + if ( $get2Darray ) {
578 + $deprecated[] = 'candlestick';
579 + } else {
580 + $types['candlestick']['enabled'] = false;
581 + }
429 582 }
430 583 }
431 584 }
432 585
@@ -448,9 +601,9 @@
448 601 * @access public
449 602 */
450 603 public function renderTemplates() {
451 604 global $pagenow;
452 - if ( 'post.php' != $pagenow && 'post-new.php' != $pagenow ) {
605 + if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
453 606 return;
454 607 }
455 608 $render = new Visualizer_Render_Templates();
456 609 $render->render();
@@ -468,9 +621,9 @@
468 621 *
469 622 * @param string $suffix The current page suffix.
470 623 */
471 624 public function enqueueLibraryScripts( $suffix ) {
472 - if ( $suffix == $this->_libraryPage ) {
625 + if ( $suffix === $this->_libraryPage ) {
473 626 wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
474 627 $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
475 628 wp_enqueue_media();
476 629 wp_enqueue_script(
@@ -528,14 +681,126 @@
528 681 *
529 682 * @access public
530 683 */
531 684 public function registerAdminMenu() {
532 - $title = esc_html__( 'Visualizer Library', 'visualizer' );
533 - $callback = array( $this, 'renderLibraryPage' );
534 - $this->_libraryPage = add_submenu_page( 'upload.php', $title, $title, 'edit_posts', Visualizer_Plugin::NAME, $callback );
685 + $svg_base64_icon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNzdweCIgaGVpZ2h0PSI3N3B4IiB2aWV3Qm94PSIwIDAgNzcgNzciIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjYgKDY3NDkxKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Db21iaW5lZCBTaGFwZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxnIGlkPSJQcm9kdWN0LVBhZ2UiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJXb3JkUHJlc3MtcGx1Z2lucyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE5MC4wMDAwMDAsIC00MzUuMDAwMDAwKSIgZmlsbD0iIzM5QzNEMiI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMjguNSw1MTIgQzIwNy4yMzcwMzcsNTEyIDE5MCw0OTQuNzYyOTYzIDE5MCw0NzMuNSBDMTkwLDQ1Mi4yMzcwMzcgMjA3LjIzNzAzNyw0MzUgMjI4LjUsNDM1IEMyNDkuNzYyOTYzLDQzNSAyNjcsNDUyLjIzNzAzNyAyNjcsNDczLjUgQzI2Nyw0OTQuNzYyOTYzIDI0OS43NjI5NjMsNTEyIDIyOC41LDUxMiBaIE0yNDYuODQzNzUsNDgzLjU5MjA1OSBMMjE1LjYyNSw0ODMuNTkyMDU5IEwyMTUuNjI1LDQ2MC44MjY1NDQgQzIxNS42MjUsNDYwLjE2NDU0NyAyMTUuMTA3NTc4LDQ1OS42MjgzNTkgMjE0LjQ2ODc1LDQ1OS42MjgzNTkgTDIxMi4xNTYyNSw0NTkuNjI4MzU5IEMyMTEuNTE3NDIyLDQ1OS42MjgzNTkgMjExLDQ2MC4xNjQ1NDcgMjExLDQ2MC44MjY1NDQgTDIxMSw0ODUuOTg4NDI5IEMyMTEsNDg3LjMxMTY3NCAyMTIuMDM1NTY2LDQ4OC4zODQ3OTggMjEzLjMxMjUsNDg4LjM4NDc5OCBMMjQ2Ljg0Mzc1LDQ4OC4zODQ3OTggQzI0Ny40ODI1NzgsNDg4LjM4NDc5OCAyNDgsNDg3Ljg0ODYxMSAyNDgsNDg3LjE4NjYxMyBMMjQ4LDQ4NC43OTAyNDQgQzI0OCw0ODQuMTI4MjQ2IDI0Ny40ODI1NzgsNDgzLjU5MjA1OSAyNDYuODQzNzUsNDgzLjU5MjA1OSBaIE0yNDQuNTMxMjUsNDYyLjAyNDcyOSBMMjM1Ljk5OTU3LDQ2Mi4wMjQ3MjkgQzIzNC40NTQ1MzEsNDYyLjAyNDcyOSAyMzMuNjgwNTY2LDQ2My45NjA1NDcgMjM0Ljc3MzIyMyw0NjUuMDkyODMyIEwyMzcuMTE0NjI5LDQ2Ny41MTkxNTYgTDIzMS44MTI1LDQ3My4wMTQzMzIgTDIyNi41MTAzNzEsNDY3LjUxOTkwNSBDMjI1LjYwNzA1MSw0NjYuNTgzODIzIDIyNC4xNDI5NDksNDY2LjU4MzgyMyAyMjMuMjQwMzUyLDQ2Ny41MTk5MDUgTDIxOC4yNzY0MjYsNDcyLjY2Mzg2MyBDMjE3LjgyNDc2Niw0NzMuMTMxOTA0IDIxNy44MjQ3NjYsNDczLjg5MDUwNSAyMTguMjc2NDI2LDQ3NC4zNTg1NDYgTDIxOS45MTEwNzQsNDc2LjA1MjQ4IEMyMjAuMzYyNzM0LDQ3Ni41MjA1MjEgMjIxLjA5NDc4NSw0NzYuNTIwNTIxIDIyMS41NDY0NDUsNDc2LjA1MjQ4IEwyMjQuODc1LDQ3Mi42MDI0NTYgTDIzMC4xNzcxMjksNDc4LjA5Njg4MyBDMjMxLjA4MDQ0OSw0NzkuMDMyOTY1IDIzMi41NDQ1NTEsNDc5LjAzMjk2NSAyMzMuNDQ3MTQ4LDQ3OC4wOTY4ODMgTDI0MC4zODQ2NDgsNDcwLjkwNzc3MyBMMjQyLjcyNjA1NSw0NzMuMzM0MDk4IEMyNDMuODE4NzExLDQ3NC40NjYzODIgMjQ1LjY4Njc3Nyw0NzMuNjY0MzQ3IDI0NS42ODY3NzcsNDcyLjA2MzI3MyBMMjQ1LjY4Njc3Nyw0NjMuMjIyOTE0IEMyNDUuNjg3NSw0NjIuNTYwOTE3IDI0NS4xNzAwNzgsNDYyLjAyNDcyOSAyNDQuNTMxMjUsNDYyLjAyNDcyOSBaIiBpZD0iQ29tYmluZWQtU2hhcGUiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==';
686 +
687 + $this->_libraryPage = add_menu_page( __( 'Visualizer', 'visualizer' ), __( 'Visualizer', 'visualizer' ), 'edit_posts', Visualizer_Plugin::NAME, array( $this, 'renderLibraryPage' ), $svg_base64_icon, 99.7666 );
688 +
689 + add_submenu_page(
690 + Visualizer_Plugin::NAME,
691 + __( 'Chart Library', 'visualizer' ),
692 + __( 'Chart Library', 'visualizer' ),
693 + 'edit_posts',
694 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME )
695 + );
696 + add_submenu_page(
697 + Visualizer_Plugin::NAME,
698 + __( 'Add New Chart', 'visualizer' ),
699 + __( 'Add New Chart', 'visualizer' ),
700 + 'edit_posts',
701 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew' )
702 + );
703 + add_submenu_page(
704 + Visualizer_Plugin::NAME,
705 + __( 'Support', 'visualizer' ),
706 + __( '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>',
707 + 'edit_posts',
708 + 'viz-support',
709 + array( $this, 'renderSupportPage' )
710 + );
711 + remove_submenu_page( Visualizer_Plugin::NAME, Visualizer_Plugin::NAME );
712 +
713 + add_action( "load-{$this->_libraryPage}", array( $this, 'addScreenOptions' ) );
535 714 }
536 715
537 716 /**
717 + * Adds the screen options for pagination.
718 + */
719 + function addScreenOptions() {
720 + $screen = get_current_screen();
721 +
722 + // bail if it's some other page.
723 + if ( ! is_object( $screen ) || $screen->id !== $this->_libraryPage ) {
724 + return;
725 + }
726 +
727 + $args = array(
728 + 'label' => __( 'Number of charts per page:', 'visualizer' ),
729 + 'default' => 6,
730 + 'option' => 'visualizer_per_page_library',
731 + );
732 + add_screen_option( 'per_page', $args );
733 + }
734 +
735 + /**
736 + * Returns the screen option for pagination.
737 + */
738 + function setScreenOptions( $status, $option, $value ) {
739 + if ( 'visualizer_per_page_library' === $option ) {
740 + return $value;
741 + }
742 + }
743 +
744 + /**
745 + * Adds the display filters to be used in the meta_query while displaying the charts.
746 + */
747 + private function getDisplayFilters( &$query_args ) {
748 + $query = array();
749 +
750 + // add chart type filter to the query arguments
751 + $type = filter_input( INPUT_GET, 'type' );
752 + if ( $type && in_array( $type, Visualizer_Plugin::getChartTypes(), true ) ) {
753 + $query[] = array(
754 + 'key' => Visualizer_Plugin::CF_CHART_TYPE,
755 + 'value' => $type,
756 + 'compare' => '=',
757 + );
758 + }
759 +
760 + // add chart library filter to the query arguments
761 + $library = filter_input( INPUT_GET, 'library' );
762 + if ( $library ) {
763 + $query[] = array(
764 + 'key' => Visualizer_Plugin::CF_CHART_LIBRARY,
765 + 'value' => $library,
766 + 'compare' => '=',
767 + );
768 + }
769 +
770 + // add date filter to the query arguments
771 + $date = filter_input( INPUT_GET, 'date' );
772 + $possible = array_keys( Visualizer_Plugin::getSupportedDateFilter() );
773 + if ( $date && in_array( $date, $possible, true ) ) {
774 + $query_args['date_query'] = array(
775 + 'after' => "$date -1 day",
776 + 'inclusive' => true,
777 + );
778 + }
779 +
780 + // add source filter to the query arguments
781 + $source = filter_input( INPUT_GET, 'source' );
782 + if ( $source ) {
783 + $source = ucwords( $source );
784 + $source = "Visualizer_Source_{$source}";
785 + $query[] = array(
786 + 'key' => Visualizer_Plugin::CF_SOURCE,
787 + 'value' => $source,
788 + 'compare' => '=',
789 + );
790 + }
791 +
792 + $query_args['meta_query'] = $query;
793 +
794 + $orderby = filter_input( INPUT_GET, 'orderby' );
795 + $order = filter_input( INPUT_GET, 'order' );
796 + if ( $orderby ) {
797 + $query_args['order_by'] = $orderby;
798 + }
799 + $query_args['order'] = empty( $order ) ? 'desc' : $order;
800 + }
801 +
802 + /**
538 803 * Get the instance of WP_Query that fetches the charts as per the given criteria.
539 804 */
540 805 private function getQuery() {
541 806 static $q;
@@ -554,27 +819,32 @@
554 819 'default' => 1,
555 820 ),
556 821 )
557 822 );
823 +
824 + $per_page = 6;
825 + $screen = get_current_screen();
826 + if ( $screen ) {
827 + // retrieve the per_page option
828 + $screen_option = $screen->get_option( 'per_page', 'option' );
829 + // retrieve the value stored for the current user
830 + $user = get_current_user_id();
831 + $per_page = get_user_meta( $user, $screen_option, true );
832 + if ( empty( $per_page ) || $per_page < 1 ) {
833 + // nothing set, get the default value
834 + $per_page = $screen->get_option( 'per_page', 'default' );
835 + }
836 + }
837 +
558 838 // the initial query arguments to fetch charts
559 839 $query_args = array(
560 840 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
561 - 'posts_per_page' => 6,
841 + 'posts_per_page' => $per_page,
562 842 'paged' => $page,
563 843 );
564 - // add chart type filter to the query arguments
565 - $filter = filter_input( INPUT_GET, 'type' );
566 - if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) {
567 - $query_args['meta_query'] = array(
568 - array(
569 - 'key' => Visualizer_Plugin::CF_CHART_TYPE,
570 - 'value' => $filter,
571 - 'compare' => '=',
572 - ),
573 - );
574 - } else {
575 - $filter = 'all';
576 - }
844 +
845 + $this->getDisplayFilters( $query_args );
846 +
577 847 // Added by Ash/Upwork
578 848 $filterByMeta = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
579 849 if ( $filterByMeta ) {
580 850 $query = array(
@@ -585,13 +855,25 @@
585 855 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
586 856 $meta[] = $query;
587 857 $query_args['meta_query'] = $meta;
588 858 }
589 - $q = new WP_Query( $query_args );
859 + $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
590 860 return $q;
591 861 }
592 862
593 863 /**
864 + * Renders support page.
865 + *
866 + * @since 3.3.0
867 + *
868 + * @access public
869 + */
870 + public function renderSupportPage() {
871 + wp_enqueue_style( 'visualizer-upsell', VISUALIZER_ABSURL . 'css/upsell.css', array(), Visualizer_Plugin::VERSION );
872 + include_once VISUALIZER_ABSPATH . '/templates/support.php';
873 + }
874 +
875 + /**
594 876 * Renders visualizer library page.
595 877 *
596 878 * @since 1.0.0
597 879 *
@@ -614,9 +896,9 @@
614 896 )
615 897 );
616 898 // add chart type filter to the query arguments
617 899 $filter = filter_input( INPUT_GET, 'type' );
618 - if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) ) {
900 + if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) ) {
619 901 $filter = 'all';
620 902 }
621 903
622 904 $css = '';
@@ -637,11 +919,14 @@
637 919 if ( ! empty( $atts['settings'] ) ) {
638 920 $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
639 921 }
640 922
641 - unset( $settings['height'], $settings['width'] );
923 + if ( $settings ) {
924 + unset( $settings['height'], $settings['width'], $settings['chartArea'] );
925 + }
926 +
642 927 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
643 - $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( $chart->post_content ) ), $chart->ID, $type );
928 + $data = self::get_chart_data( $chart, $type );
644 929
645 930 $library = $this->load_chart_type( $chart->ID );
646 931
647 932 $id = 'visualizer-' . $chart->ID;
@@ -670,14 +955,16 @@
670 955 'language' => $this->get_language(),
671 956 'map_api_key' => get_option( 'visualizer-map-api-key' ),
672 957 'charts' => $charts,
673 958 'urls' => array(
674 - 'base' => add_query_arg( 'vpage', false ),
959 + 'base' => add_query_arg( array( 'vpage' => false, 'vaction' => false ) ),
675 960 'create' => add_query_arg(
676 961 array(
677 962 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
678 963 'library' => 'yes',
679 964 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
965 + 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
966 + 'vaction' => false,
680 967 ),
681 968 $ajaxurl
682 969 ),
683 970 'edit' => add_query_arg(
@@ -683,13 +970,18 @@
683 970 'edit' => add_query_arg(
684 971 array(
685 972 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
686 973 'library' => 'yes',
974 + 'vaction' => false,
687 975 ),
688 976 $ajaxurl
689 977 ),
690 978 ),
691 979 'page_type' => 'library',
980 + 'is_front' => false,
981 + 'i10n' => array(
982 + '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' ),
983 + ),
692 984 )
693 985 );
694 986 // render library page
695 987 $render = new Visualizer_Render_Library();
@@ -698,9 +990,9 @@
698 990 $render->types = self::_getChartTypesLocalized( false, false, false, true );
699 991 $render->custom_css = $css;
700 992 $render->pagination = paginate_links(
701 993 array(
702 - 'base' => add_query_arg( 'vpage', '%#%' ),
994 + 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
703 995 'format' => '',
704 996 'current' => $page,
705 997 'total' => $query->max_num_pages,
706 998 'type' => 'array',
@@ -721,14 +1013,14 @@
721 1013 *
722 1014 * @return array Updated array of action links.
723 1015 */
724 1016 public function getPluginActionLinks( $links, $file ) {
725 - if ( $file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1017 + if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
726 1018 array_unshift(
727 1019 $links,
728 1020 sprintf(
729 1021 '<a href="%s">%s</a>',
730 - admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ),
1022 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
731 1023 esc_html__( 'Library', 'visualizer' )
732 1024 )
733 1025 );
734 1026 }
@@ -748,17 +1040,17 @@
748 1040 *
749 1041 * @return array Updated array of plugin meta links.
750 1042 */
751 1043 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
752 - if ( $plugin_file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1044 + if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
753 1045 // knowledge base link
754 1046 $plugin_meta[] = sprintf(
755 - '<a href="https://github.com/codeinwp/visualizer/wiki" target="_blank">%s</a>',
756 - esc_html__( 'Knowledge Base', 'visualizer' )
1047 + '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1048 + esc_html__( 'Docs', 'visualizer' )
757 1049 );
758 1050 // flattr link
759 1051 $plugin_meta[] = sprintf(
760 - '<a style="color:red" href="https://themeisle.com/plugins/visualizer-charts-and-graphs-pro-addon/" target="_blank">%s</a>',
1052 + '<a style="color:red" href="' . Visualizer_Plugin::PRO_TEASER_URL . '" target="_blank">%s</a>',
761 1053 esc_html__( 'Pro Addon', 'visualizer' )
762 1054 );
763 1055 }
764 1056