PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.4.8
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.4.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 3.10.4 All 148 releases
← All changes | classes/Visualizer/Module/Admin.php +318 -63 3.1.13.4.8 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_Tabular::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 );
@@ -292,61 +391,86 @@
292 391
293 392 $types = array_merge(
294 393 $additional,
295 394 array(
296 - 'dataTable' => array(
297 - 'name' => esc_html__( 'Table (New)', 'visualizer' ),
395 + 'tabular' => array(
396 + 'name' => esc_html__( 'Table', 'visualizer' ),
298 397 'enabled' => true,
398 + 'supports' => array( 'Google Charts', '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 ),
431 + 'bubble' => array(
432 + 'name' => esc_html__( 'Bubble', 'visualizer' ),
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' ),
436 + ),
324 437 'scatter' => array(
325 438 'name' => esc_html__( 'Scatter', 'visualizer' ),
326 439 'enabled' => true,
440 + 'supports' => array( 'Google Charts' ),
327 441 ),
328 442 'gauge' => array(
329 443 'name' => esc_html__( 'Gauge', 'visualizer' ),
330 444 'enabled' => true,
445 + 'supports' => array( 'Google Charts' ),
331 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 - 'table' => array(
338 - 'name' => esc_html__( 'Table (Deprecated)', 'visualizer' ),
339 - 'enabled' => false,
340 - ),
341 453 'timeline' => array(
342 454 'name' => esc_html__( 'Timeline', 'visualizer' ),
343 455 'enabled' => false,
456 + 'supports' => array( 'Google Charts', 'ChartJS' ),
344 457 ),
345 458 'combo' => array(
346 459 'name' => esc_html__( 'Combo', 'visualizer' ),
347 460 'enabled' => false,
461 + 'supports' => array( 'Google Charts' ),
348 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 + ),
349 473 )
350 474 );
351 475 $types = apply_filters( 'visualizer_pro_chart_types', $types );
352 476 if ( $enabledOnly ) {
@@ -355,8 +479,12 @@
355 479 if ( ! is_array( $array ) ) {
356 480 // support for old pro
357 481 $array = array( 'enabled' => true, 'name' => $array );
358 482 }
483 + // backward compatibility for PRO before v1.9.0
484 + if ( ! array_key_exists( 'supports', $array ) ) {
485 + $array['supports'] = array( 'Google Charts' );
486 + }
359 487 if ( ! $array['enabled'] ) {
360 488 continue;
361 489 }
362 490 $filtered[ $type ] = $array;
@@ -369,8 +497,12 @@
369 497 if ( ! is_array( $array ) ) {
370 498 // support for old pro
371 499 $array = array( 'enabled' => true, 'name' => $array );
372 500 }
501 + // backward compatibility for PRO before v1.9.0
502 + if ( ! array_key_exists( 'supports', $array ) ) {
503 + $array['supports'] = array( 'Google Charts' );
504 + }
373 505 $doubleD[ $type ] = $array['name'];
374 506 }
375 507 $types = $doubleD;
376 508 }
@@ -384,21 +516,13 @@
384 516 private static function handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where ) {
385 517 $deprecated = array();
386 518
387 519 switch ( $where ) {
520 + case 'types':
521 + // fall-through
388 522 case 'library':
389 - // if the user has a Google Table chart, show it as deprecated otherwise remove the option from the library.
390 - if ( ! self::hasChartType( 'table' ) ) {
391 - $deprecated[] = 'table';
392 - if ( $get2Darray ) {
393 - $types['dataTable'] = esc_html__( 'Table', 'visualizer' );
394 - } else {
395 - $types['dataTable']['name'] = esc_html__( 'Table', 'visualizer' );
396 - }
397 - }
398 -
399 523 // if a user has a Gauge/Candlestick chart, then let them keep using it.
400 - if ( ! VISUALIZER_PRO ) {
524 + if ( ! Visualizer_Module::is_pro() ) {
401 525 if ( ! self::hasChartType( 'gauge' ) ) {
402 526 if ( $get2Darray ) {
403 527 $deprecated[] = 'gauge';
404 528 } else {
@@ -414,20 +538,10 @@
414 538 }
415 539 }
416 540 break;
417 541 default:
418 - // remove the option to create a Google Table chart.
419 - $deprecated[] = 'table';
420 -
421 - // rename the new table chart type.
422 - if ( $get2Darray ) {
423 - $types['dataTable'] = esc_html__( 'Table', 'visualizer' );
424 - } else {
425 - $types['dataTable']['name'] = esc_html__( 'Table', 'visualizer' );
426 - }
427 -
428 542 // if a user has a Gauge/Candlestick chart, then let them keep using it.
429 - if ( ! VISUALIZER_PRO ) {
543 + if ( ! Visualizer_Module::is_pro() ) {
430 544 if ( ! self::hasChartType( 'gauge' ) ) {
431 545 if ( $get2Darray ) {
432 546 $deprecated[] = 'gauge';
433 547 } else {
@@ -462,9 +576,9 @@
462 576 * @access public
463 577 */
464 578 public function renderTemplates() {
465 579 global $pagenow;
466 - if ( 'post.php' != $pagenow && 'post-new.php' != $pagenow ) {
580 + if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
467 581 return;
468 582 }
469 583 $render = new Visualizer_Render_Templates();
470 584 $render->render();
@@ -482,9 +596,9 @@
482 596 *
483 597 * @param string $suffix The current page suffix.
484 598 */
485 599 public function enqueueLibraryScripts( $suffix ) {
486 - if ( $suffix == $this->_libraryPage ) {
600 + if ( $suffix === $this->_libraryPage ) {
487 601 wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
488 602 $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
489 603 wp_enqueue_media();
490 604 wp_enqueue_script(
@@ -492,8 +606,9 @@
492 606 VISUALIZER_ABSURL . 'js/library.js',
493 607 array(
494 608 'jquery',
495 609 'media-views',
610 + 'clipboard',
496 611 ),
497 612 Visualizer_Plugin::VERSION,
498 613 true
499 614 );
@@ -542,14 +657,126 @@
542 657 *
543 658 * @access public
544 659 */
545 660 public function registerAdminMenu() {
546 - $title = esc_html__( 'Visualizer Library', 'visualizer' );
547 - $callback = array( $this, 'renderLibraryPage' );
548 - $this->_libraryPage = add_submenu_page( 'upload.php', $title, $title, 'edit_posts', Visualizer_Plugin::NAME, $callback );
661 + $svg_base64_icon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNzdweCIgaGVpZ2h0PSI3N3B4IiB2aWV3Qm94PSIwIDAgNzcgNzciIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjYgKDY3NDkxKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Db21iaW5lZCBTaGFwZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxnIGlkPSJQcm9kdWN0LVBhZ2UiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJXb3JkUHJlc3MtcGx1Z2lucyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE5MC4wMDAwMDAsIC00MzUuMDAwMDAwKSIgZmlsbD0iIzM5QzNEMiI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMjguNSw1MTIgQzIwNy4yMzcwMzcsNTEyIDE5MCw0OTQuNzYyOTYzIDE5MCw0NzMuNSBDMTkwLDQ1Mi4yMzcwMzcgMjA3LjIzNzAzNyw0MzUgMjI4LjUsNDM1IEMyNDkuNzYyOTYzLDQzNSAyNjcsNDUyLjIzNzAzNyAyNjcsNDczLjUgQzI2Nyw0OTQuNzYyOTYzIDI0OS43NjI5NjMsNTEyIDIyOC41LDUxMiBaIE0yNDYuODQzNzUsNDgzLjU5MjA1OSBMMjE1LjYyNSw0ODMuNTkyMDU5IEwyMTUuNjI1LDQ2MC44MjY1NDQgQzIxNS42MjUsNDYwLjE2NDU0NyAyMTUuMTA3NTc4LDQ1OS42MjgzNTkgMjE0LjQ2ODc1LDQ1OS42MjgzNTkgTDIxMi4xNTYyNSw0NTkuNjI4MzU5IEMyMTEuNTE3NDIyLDQ1OS42MjgzNTkgMjExLDQ2MC4xNjQ1NDcgMjExLDQ2MC44MjY1NDQgTDIxMSw0ODUuOTg4NDI5IEMyMTEsNDg3LjMxMTY3NCAyMTIuMDM1NTY2LDQ4OC4zODQ3OTggMjEzLjMxMjUsNDg4LjM4NDc5OCBMMjQ2Ljg0Mzc1LDQ4OC4zODQ3OTggQzI0Ny40ODI1NzgsNDg4LjM4NDc5OCAyNDgsNDg3Ljg0ODYxMSAyNDgsNDg3LjE4NjYxMyBMMjQ4LDQ4NC43OTAyNDQgQzI0OCw0ODQuMTI4MjQ2IDI0Ny40ODI1NzgsNDgzLjU5MjA1OSAyNDYuODQzNzUsNDgzLjU5MjA1OSBaIE0yNDQuNTMxMjUsNDYyLjAyNDcyOSBMMjM1Ljk5OTU3LDQ2Mi4wMjQ3MjkgQzIzNC40NTQ1MzEsNDYyLjAyNDcyOSAyMzMuNjgwNTY2LDQ2My45NjA1NDcgMjM0Ljc3MzIyMyw0NjUuMDkyODMyIEwyMzcuMTE0NjI5LDQ2Ny41MTkxNTYgTDIzMS44MTI1LDQ3My4wMTQzMzIgTDIyNi41MTAzNzEsNDY3LjUxOTkwNSBDMjI1LjYwNzA1MSw0NjYuNTgzODIzIDIyNC4xNDI5NDksNDY2LjU4MzgyMyAyMjMuMjQwMzUyLDQ2Ny41MTk5MDUgTDIxOC4yNzY0MjYsNDcyLjY2Mzg2MyBDMjE3LjgyNDc2Niw0NzMuMTMxOTA0IDIxNy44MjQ3NjYsNDczLjg5MDUwNSAyMTguMjc2NDI2LDQ3NC4zNTg1NDYgTDIxOS45MTEwNzQsNDc2LjA1MjQ4IEMyMjAuMzYyNzM0LDQ3Ni41MjA1MjEgMjIxLjA5NDc4NSw0NzYuNTIwNTIxIDIyMS41NDY0NDUsNDc2LjA1MjQ4IEwyMjQuODc1LDQ3Mi42MDI0NTYgTDIzMC4xNzcxMjksNDc4LjA5Njg4MyBDMjMxLjA4MDQ0OSw0NzkuMDMyOTY1IDIzMi41NDQ1NTEsNDc5LjAzMjk2NSAyMzMuNDQ3MTQ4LDQ3OC4wOTY4ODMgTDI0MC4zODQ2NDgsNDcwLjkwNzc3MyBMMjQyLjcyNjA1NSw0NzMuMzM0MDk4IEMyNDMuODE4NzExLDQ3NC40NjYzODIgMjQ1LjY4Njc3Nyw0NzMuNjY0MzQ3IDI0NS42ODY3NzcsNDcyLjA2MzI3MyBMMjQ1LjY4Njc3Nyw0NjMuMjIyOTE0IEMyNDUuNjg3NSw0NjIuNTYwOTE3IDI0NS4xNzAwNzgsNDYyLjAyNDcyOSAyNDQuNTMxMjUsNDYyLjAyNDcyOSBaIiBpZD0iQ29tYmluZWQtU2hhcGUiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==';
662 +
663 + $this->_libraryPage = add_menu_page( __( 'Visualizer', 'visualizer' ), __( 'Visualizer', 'visualizer' ), 'edit_posts', Visualizer_Plugin::NAME, array( $this, 'renderLibraryPage' ), $svg_base64_icon, 99.7666 );
664 +
665 + add_submenu_page(
666 + Visualizer_Plugin::NAME,
667 + __( 'Chart Library', 'visualizer' ),
668 + __( 'Chart Library', 'visualizer' ),
669 + 'edit_posts',
670 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME )
671 + );
672 + add_submenu_page(
673 + Visualizer_Plugin::NAME,
674 + __( 'Add New Chart', 'visualizer' ),
675 + __( 'Add New Chart', 'visualizer' ),
676 + 'edit_posts',
677 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew' )
678 + );
679 + add_submenu_page(
680 + Visualizer_Plugin::NAME,
681 + __( 'Support', 'visualizer' ),
682 + __( '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>',
683 + 'edit_posts',
684 + 'viz-support',
685 + array( $this, 'renderSupportPage' )
686 + );
687 + remove_submenu_page( Visualizer_Plugin::NAME, Visualizer_Plugin::NAME );
688 +
689 + add_action( "load-{$this->_libraryPage}", array( $this, 'addScreenOptions' ) );
549 690 }
550 691
551 692 /**
693 + * Adds the screen options for pagination.
694 + */
695 + function addScreenOptions() {
696 + $screen = get_current_screen();
697 +
698 + // bail if it's some other page.
699 + if ( ! is_object( $screen ) || $screen->id !== $this->_libraryPage ) {
700 + return;
701 + }
702 +
703 + $args = array(
704 + 'label' => __( 'Number of charts per page:', 'visualizer' ),
705 + 'default' => 6,
706 + 'option' => 'visualizer_per_page_library',
707 + );
708 + add_screen_option( 'per_page', $args );
709 + }
710 +
711 + /**
712 + * Returns the screen option for pagination.
713 + */
714 + function setScreenOptions( $status, $option, $value ) {
715 + if ( 'visualizer_per_page_library' === $option ) {
716 + return $value;
717 + }
718 + }
719 +
720 + /**
721 + * Adds the display filters to be used in the meta_query while displaying the charts.
722 + */
723 + private function getDisplayFilters( &$query_args ) {
724 + $query = array();
725 +
726 + // add chart type filter to the query arguments
727 + $type = filter_input( INPUT_GET, 'type' );
728 + if ( $type && in_array( $type, Visualizer_Plugin::getChartTypes(), true ) ) {
729 + $query[] = array(
730 + 'key' => Visualizer_Plugin::CF_CHART_TYPE,
731 + 'value' => $type,
732 + 'compare' => '=',
733 + );
734 + }
735 +
736 + // add chart library filter to the query arguments
737 + $library = filter_input( INPUT_GET, 'library' );
738 + if ( $library ) {
739 + $query[] = array(
740 + 'key' => Visualizer_Plugin::CF_CHART_LIBRARY,
741 + 'value' => $library,
742 + 'compare' => '=',
743 + );
744 + }
745 +
746 + // add date filter to the query arguments
747 + $date = filter_input( INPUT_GET, 'date' );
748 + $possible = array_keys( Visualizer_Plugin::getSupportedDateFilter() );
749 + if ( $date && in_array( $date, $possible, true ) ) {
750 + $query_args['date_query'] = array(
751 + 'after' => "$date -1 day",
752 + 'inclusive' => true,
753 + );
754 + }
755 +
756 + // add source filter to the query arguments
757 + $source = filter_input( INPUT_GET, 'source' );
758 + if ( $source ) {
759 + $source = ucwords( $source );
760 + $source = "Visualizer_Source_{$source}";
761 + $query[] = array(
762 + 'key' => Visualizer_Plugin::CF_SOURCE,
763 + 'value' => $source,
764 + 'compare' => '=',
765 + );
766 + }
767 +
768 + $query_args['meta_query'] = $query;
769 +
770 + $orderby = filter_input( INPUT_GET, 'orderby' );
771 + $order = filter_input( INPUT_GET, 'order' );
772 + if ( $orderby ) {
773 + $query_args['order_by'] = $orderby;
774 + }
775 + $query_args['order'] = empty( $order ) ? 'desc' : $order;
776 + }
777 +
778 + /**
552 779 * Get the instance of WP_Query that fetches the charts as per the given criteria.
553 780 */
554 781 private function getQuery() {
555 782 static $q;
@@ -568,27 +795,32 @@
568 795 'default' => 1,
569 796 ),
570 797 )
571 798 );
799 +
800 + $per_page = 6;
801 + $screen = get_current_screen();
802 + if ( $screen ) {
803 + // retrieve the per_page option
804 + $screen_option = $screen->get_option( 'per_page', 'option' );
805 + // retrieve the value stored for the current user
806 + $user = get_current_user_id();
807 + $per_page = get_user_meta( $user, $screen_option, true );
808 + if ( empty( $per_page ) || $per_page < 1 ) {
809 + // nothing set, get the default value
810 + $per_page = $screen->get_option( 'per_page', 'default' );
811 + }
812 + }
813 +
572 814 // the initial query arguments to fetch charts
573 815 $query_args = array(
574 816 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
575 - 'posts_per_page' => 6,
817 + 'posts_per_page' => $per_page,
576 818 'paged' => $page,
577 819 );
578 - // add chart type filter to the query arguments
579 - $filter = filter_input( INPUT_GET, 'type' );
580 - if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) {
581 - $query_args['meta_query'] = array(
582 - array(
583 - 'key' => Visualizer_Plugin::CF_CHART_TYPE,
584 - 'value' => $filter,
585 - 'compare' => '=',
586 - ),
587 - );
588 - } else {
589 - $filter = 'all';
590 - }
820 +
821 + $this->getDisplayFilters( $query_args );
822 +
591 823 // Added by Ash/Upwork
592 824 $filterByMeta = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
593 825 if ( $filterByMeta ) {
594 826 $query = array(
@@ -599,13 +831,25 @@
599 831 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
600 832 $meta[] = $query;
601 833 $query_args['meta_query'] = $meta;
602 834 }
603 - $q = new WP_Query( $query_args );
835 + $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
604 836 return $q;
605 837 }
606 838
607 839 /**
840 + * Renders support page.
841 + *
842 + * @since 3.3.0
843 + *
844 + * @access public
845 + */
846 + public function renderSupportPage() {
847 + wp_enqueue_style( 'visualizer-upsell', VISUALIZER_ABSURL . 'css/upsell.css', array(), Visualizer_Plugin::VERSION );
848 + include_once VISUALIZER_ABSPATH . '/templates/support.php';
849 + }
850 +
851 + /**
608 852 * Renders visualizer library page.
609 853 *
610 854 * @since 1.0.0
611 855 *
@@ -628,9 +872,9 @@
628 872 )
629 873 );
630 874 // add chart type filter to the query arguments
631 875 $filter = filter_input( INPUT_GET, 'type' );
632 - if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) ) {
876 + if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) ) {
633 877 $filter = 'all';
634 878 }
635 879
636 880 $css = '';
@@ -651,11 +895,14 @@
651 895 if ( ! empty( $atts['settings'] ) ) {
652 896 $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
653 897 }
654 898
655 - unset( $settings['height'], $settings['width'] );
899 + if ( $settings ) {
900 + unset( $settings['height'], $settings['width'], $settings['chartArea'] );
901 + }
902 +
656 903 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
657 - $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( $chart->post_content ) ), $chart->ID, $type );
904 + $data = self::get_chart_data( $chart, $type );
658 905
659 906 $library = $this->load_chart_type( $chart->ID );
660 907
661 908 $id = 'visualizer-' . $chart->ID;
@@ -684,14 +931,16 @@
684 931 'language' => $this->get_language(),
685 932 'map_api_key' => get_option( 'visualizer-map-api-key' ),
686 933 'charts' => $charts,
687 934 'urls' => array(
688 - 'base' => add_query_arg( 'vpage', false ),
935 + 'base' => add_query_arg( array( 'vpage' => false, 'vaction' => false ) ),
689 936 'create' => add_query_arg(
690 937 array(
691 938 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
692 939 'library' => 'yes',
693 940 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
941 + 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
942 + 'vaction' => false,
694 943 ),
695 944 $ajaxurl
696 945 ),
697 946 'edit' => add_query_arg(
@@ -697,13 +946,19 @@
697 946 'edit' => add_query_arg(
698 947 array(
699 948 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
700 949 'library' => 'yes',
950 + 'vaction' => false,
701 951 ),
702 952 $ajaxurl
703 953 ),
704 954 ),
705 955 'page_type' => 'library',
956 + 'is_front' => false,
957 + 'i10n' => array(
958 + 'copied' => __( 'The shortcode has been copied to your clipboard. Hit Ctrl-V/Cmd-V to paste it.', 'visualizer' ),
959 + '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' ),
960 + ),
706 961 )
707 962 );
708 963 // render library page
709 964 $render = new Visualizer_Render_Library();
@@ -712,9 +967,9 @@
712 967 $render->types = self::_getChartTypesLocalized( false, false, false, true );
713 968 $render->custom_css = $css;
714 969 $render->pagination = paginate_links(
715 970 array(
716 - 'base' => add_query_arg( 'vpage', '%#%' ),
971 + 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
717 972 'format' => '',
718 973 'current' => $page,
719 974 'total' => $query->max_num_pages,
720 975 'type' => 'array',
@@ -735,14 +990,14 @@
735 990 *
736 991 * @return array Updated array of action links.
737 992 */
738 993 public function getPluginActionLinks( $links, $file ) {
739 - if ( $file == plugin_basename( VISUALIZER_BASEFILE ) ) {
994 + if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
740 995 array_unshift(
741 996 $links,
742 997 sprintf(
743 998 '<a href="%s">%s</a>',
744 - admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ),
999 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
745 1000 esc_html__( 'Library', 'visualizer' )
746 1001 )
747 1002 );
748 1003 }
@@ -762,17 +1017,17 @@
762 1017 *
763 1018 * @return array Updated array of plugin meta links.
764 1019 */
765 1020 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
766 - if ( $plugin_file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1021 + if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
767 1022 // knowledge base link
768 1023 $plugin_meta[] = sprintf(
769 - '<a href="https://github.com/codeinwp/visualizer/wiki" target="_blank">%s</a>',
770 - esc_html__( 'Knowledge Base', 'visualizer' )
1024 + '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1025 + esc_html__( 'Docs', 'visualizer' )
771 1026 );
772 1027 // flattr link
773 1028 $plugin_meta[] = sprintf(
774 - '<a style="color:red" href="https://themeisle.com/plugins/visualizer-charts-and-graphs-pro-addon/" target="_blank">%s</a>',
1029 + '<a style="color:red" href="' . Visualizer_Plugin::PRO_TEASER_URL . '" target="_blank">%s</a>',
775 1030 esc_html__( 'Pro Addon', 'visualizer' )
776 1031 );
777 1032 }
778 1033