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 +341 -71 3.1.03.4.5 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 ),
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 - '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,49 +516,45 @@
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 - $deprecated[] = 'gauge';
526 + if ( $get2Darray ) {
527 + $deprecated[] = 'gauge';
528 + } else {
529 + $types['gauge']['enabled'] = false;
530 + }
403 531 }
404 532 if ( ! self::hasChartType( 'candlestick' ) ) {
405 - $deprecated[] = 'candlestick';
533 + if ( $get2Darray ) {
534 + $deprecated[] = 'candlestick';
535 + } else {
536 + $types['candlestick']['enabled'] = false;
537 + }
406 538 }
407 539 }
408 540 break;
409 541 default:
410 - // remove the option to create a Google Table chart.
411 - $deprecated[] = 'table';
412 -
413 - // 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 - }
420 - }
421 -
422 542 // if a user has a Gauge/Candlestick chart, then let them keep using it.
423 - if ( ! VISUALIZER_PRO ) {
543 + if ( ! Visualizer_Module::is_pro() ) {
424 544 if ( ! self::hasChartType( 'gauge' ) ) {
425 - $deprecated[] = 'gauge';
545 + if ( $get2Darray ) {
546 + $deprecated[] = 'gauge';
547 + } else {
548 + $types['gauge']['enabled'] = false;
549 + }
426 550 }
427 551 if ( ! self::hasChartType( 'candlestick' ) ) {
428 - $deprecated[] = 'candlestick';
552 + if ( $get2Darray ) {
553 + $deprecated[] = 'candlestick';
554 + } else {
555 + $types['candlestick']['enabled'] = false;
556 + }
429 557 }
430 558 }
431 559 }
432 560
@@ -448,9 +576,9 @@
448 576 * @access public
449 577 */
450 578 public function renderTemplates() {
451 579 global $pagenow;
452 - if ( 'post.php' != $pagenow && 'post-new.php' != $pagenow ) {
580 + if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
453 581 return;
454 582 }
455 583 $render = new Visualizer_Render_Templates();
456 584 $render->render();
@@ -468,9 +596,10 @@
468 596 *
469 597 * @param string $suffix The current page suffix.
470 598 */
471 599 public function enqueueLibraryScripts( $suffix ) {
472 - 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 );
473 602 wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
474 603 $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
475 604 wp_enqueue_media();
476 605 wp_enqueue_script(
@@ -478,8 +607,9 @@
478 607 VISUALIZER_ABSURL . 'js/library.js',
479 608 array(
480 609 'jquery',
481 610 'media-views',
611 + 'visualizer-clipboardjs',
482 612 ),
483 613 Visualizer_Plugin::VERSION,
484 614 true
485 615 );
@@ -528,14 +658,126 @@
528 658 *
529 659 * @access public
530 660 */
531 661 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 );
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' ) );
535 691 }
536 692
537 693 /**
694 + * Adds the screen options for pagination.
695 + */
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 + /**
538 780 * Get the instance of WP_Query that fetches the charts as per the given criteria.
539 781 */
540 782 private function getQuery() {
541 783 static $q;
@@ -554,27 +796,32 @@
554 796 'default' => 1,
555 797 ),
556 798 )
557 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 +
558 815 // the initial query arguments to fetch charts
559 816 $query_args = array(
560 817 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
561 - 'posts_per_page' => 6,
818 + 'posts_per_page' => $per_page,
562 819 'paged' => $page,
563 820 );
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 - }
821 +
822 + $this->getDisplayFilters( $query_args );
823 +
577 824 // Added by Ash/Upwork
578 825 $filterByMeta = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
579 826 if ( $filterByMeta ) {
580 827 $query = array(
@@ -585,13 +832,25 @@
585 832 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
586 833 $meta[] = $query;
587 834 $query_args['meta_query'] = $meta;
588 835 }
589 - $q = new WP_Query( $query_args );
836 + $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
590 837 return $q;
591 838 }
592 839
593 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 + /**
594 853 * Renders visualizer library page.
595 854 *
596 855 * @since 1.0.0
597 856 *
@@ -614,9 +873,9 @@
614 873 )
615 874 );
616 875 // add chart type filter to the query arguments
617 876 $filter = filter_input( INPUT_GET, 'type' );
618 - if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) ) {
877 + if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) ) {
619 878 $filter = 'all';
620 879 }
621 880
622 881 $css = '';
@@ -637,11 +896,14 @@
637 896 if ( ! empty( $atts['settings'] ) ) {
638 897 $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
639 898 }
640 899
641 - unset( $settings['height'], $settings['width'] );
900 + if ( $settings ) {
901 + unset( $settings['height'], $settings['width'], $settings['chartArea'] );
902 + }
903 +
642 904 $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 );
905 + $data = self::get_chart_data( $chart, $type );
644 906
645 907 $library = $this->load_chart_type( $chart->ID );
646 908
647 909 $id = 'visualizer-' . $chart->ID;
@@ -670,14 +932,16 @@
670 932 'language' => $this->get_language(),
671 933 'map_api_key' => get_option( 'visualizer-map-api-key' ),
672 934 'charts' => $charts,
673 935 'urls' => array(
674 - 'base' => add_query_arg( 'vpage', false ),
936 + 'base' => add_query_arg( array( 'vpage' => false, 'vaction' => false ) ),
675 937 'create' => add_query_arg(
676 938 array(
677 939 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
678 940 'library' => 'yes',
679 941 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
942 + 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
943 + 'vaction' => false,
680 944 ),
681 945 $ajaxurl
682 946 ),
683 947 'edit' => add_query_arg(
@@ -683,13 +947,19 @@
683 947 'edit' => add_query_arg(
684 948 array(
685 949 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
686 950 'library' => 'yes',
951 + 'vaction' => false,
687 952 ),
688 953 $ajaxurl
689 954 ),
690 955 ),
691 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 + ),
692 962 )
693 963 );
694 964 // render library page
695 965 $render = new Visualizer_Render_Library();
@@ -698,9 +968,9 @@
698 968 $render->types = self::_getChartTypesLocalized( false, false, false, true );
699 969 $render->custom_css = $css;
700 970 $render->pagination = paginate_links(
701 971 array(
702 - 'base' => add_query_arg( 'vpage', '%#%' ),
972 + 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
703 973 'format' => '',
704 974 'current' => $page,
705 975 'total' => $query->max_num_pages,
706 976 'type' => 'array',
@@ -721,14 +991,14 @@
721 991 *
722 992 * @return array Updated array of action links.
723 993 */
724 994 public function getPluginActionLinks( $links, $file ) {
725 - if ( $file == plugin_basename( VISUALIZER_BASEFILE ) ) {
995 + if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
726 996 array_unshift(
727 997 $links,
728 998 sprintf(
729 999 '<a href="%s">%s</a>',
730 - admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ),
1000 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
731 1001 esc_html__( 'Library', 'visualizer' )
732 1002 )
733 1003 );
734 1004 }
@@ -748,17 +1018,17 @@
748 1018 *
749 1019 * @return array Updated array of plugin meta links.
750 1020 */
751 1021 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
752 - if ( $plugin_file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1022 + if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
753 1023 // knowledge base link
754 1024 $plugin_meta[] = sprintf(
755 - '<a href="https://github.com/codeinwp/visualizer/wiki" target="_blank">%s</a>',
756 - esc_html__( 'Knowledge Base', 'visualizer' )
1025 + '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1026 + esc_html__( 'Docs', 'visualizer' )
757 1027 );
758 1028 // flattr link
759 1029 $plugin_meta[] = sprintf(
760 - '<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>',
761 1031 esc_html__( 'Pro Addon', 'visualizer' )
762 1032 );
763 1033 }
764 1034