PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.7.4
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.7.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 +375 -81 3.1.03.7.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_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 );
@@ -289,64 +388,91 @@
289 388 'enabled' => true,
290 389 );
291 390 }
292 391
392 + $enabled = self::proFeaturesLocked();
393 +
293 394 $types = array_merge(
294 395 $additional,
295 396 array(
296 - 'dataTable' => array(
297 - 'name' => esc_html__( 'Table (New)', 'visualizer' ),
397 + 'tabular' => array(
398 + 'name' => esc_html__( 'Table', 'visualizer' ),
298 399 'enabled' => true,
400 + 'supports' => $enabled ? array( 'Google Charts', 'DataTable' ) : array( 'DataTable' ),
299 401 ),
300 402 'pie' => array(
301 - 'name' => esc_html__( 'Pie', 'visualizer' ),
403 + 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
302 404 'enabled' => true,
405 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
303 406 ),
304 407 'line' => array(
305 408 'name' => esc_html__( 'Line', 'visualizer' ),
306 409 'enabled' => true,
410 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
307 411 ),
412 + 'bar' => array(
413 + 'name' => esc_html__( 'Bar', 'visualizer' ),
414 + 'enabled' => true,
415 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
416 + ),
308 417 'area' => array(
309 418 'name' => esc_html__( 'Area', 'visualizer' ),
310 - 'enabled' => true,
419 + 'enabled' => $enabled,
420 + // in ChartJS, the fill option is used to make Line chart an area: https://www.chartjs.org/docs/latest/charts/area.html
421 + 'supports' => array( 'Google Charts' ),
311 422 ),
312 423 'geo' => array(
313 424 'name' => esc_html__( 'Geo', 'visualizer' ),
314 - 'enabled' => true,
425 + 'enabled' => $enabled,
426 + 'supports' => array( 'Google Charts' ),
315 427 ),
316 - 'bar' => array(
317 - 'name' => esc_html__( 'Bar', 'visualizer' ),
318 - 'enabled' => true,
319 - ),
320 428 'column' => array(
321 429 'name' => esc_html__( 'Column', 'visualizer' ),
322 - 'enabled' => true,
430 + 'enabled' => $enabled,
431 + 'supports' => array( 'Google Charts', 'ChartJS' ),
323 432 ),
324 - 'gauge' => array(
325 - 'name' => esc_html__( 'Gauge', 'visualizer' ),
326 - 'enabled' => true,
433 + 'bubble' => array(
434 + 'name' => esc_html__( 'Bubble', 'visualizer' ),
435 + 'enabled' => $enabled,
436 + // chartjs' bubble is ugly looking (and it won't work off the default bubble.csv) so it is being excluded for the time being.
437 + 'supports' => array( 'Google Charts' ),
327 438 ),
328 439 'scatter' => array(
329 440 'name' => esc_html__( 'Scatter', 'visualizer' ),
330 - 'enabled' => true,
441 + 'enabled' => $enabled,
442 + 'supports' => array( 'Google Charts' ),
331 443 ),
444 + 'gauge' => array(
445 + 'name' => esc_html__( 'Gauge', 'visualizer' ),
446 + 'enabled' => $enabled,
447 + 'supports' => array( 'Google Charts' ),
448 + ),
332 449 'candlestick' => array(
333 450 'name' => esc_html__( 'Candlestick', 'visualizer' ),
334 - 'enabled' => true,
451 + 'enabled' => $enabled,
452 + 'supports' => array( 'Google Charts' ),
335 453 ),
336 454 // pro types
337 - 'table' => array(
338 - 'name' => esc_html__( 'Table (Deprecated)', 'visualizer' ),
339 - 'enabled' => false,
340 - ),
341 455 'timeline' => array(
342 456 'name' => esc_html__( 'Timeline', 'visualizer' ),
343 457 'enabled' => false,
458 + 'supports' => array( 'Google Charts', 'ChartJS' ),
344 459 ),
345 460 'combo' => array(
346 461 'name' => esc_html__( 'Combo', 'visualizer' ),
347 462 'enabled' => false,
463 + 'supports' => array( 'Google Charts' ),
348 464 ),
465 + 'polarArea' => array(
466 + 'name' => esc_html__( 'Polar Area', 'visualizer' ),
467 + 'enabled' => false,
468 + 'supports' => array( 'ChartJS' ),
469 + ),
470 + 'radar' => array(
471 + 'name' => esc_html__( 'Radar/Spider', 'visualizer' ),
472 + 'enabled' => false,
473 + 'supports' => array( 'ChartJS' ),
474 + ),
349 475 )
350 476 );
351 477 $types = apply_filters( 'visualizer_pro_chart_types', $types );
352 478 if ( $enabledOnly ) {
@@ -355,8 +481,12 @@
355 481 if ( ! is_array( $array ) ) {
356 482 // support for old pro
357 483 $array = array( 'enabled' => true, 'name' => $array );
358 484 }
485 + // backward compatibility for PRO before v1.9.0
486 + if ( ! array_key_exists( 'supports', $array ) ) {
487 + $array['supports'] = array( 'Google Charts' );
488 + }
359 489 if ( ! $array['enabled'] ) {
360 490 continue;
361 491 }
362 492 $filtered[ $type ] = $array;
@@ -369,8 +499,12 @@
369 499 if ( ! is_array( $array ) ) {
370 500 // support for old pro
371 501 $array = array( 'enabled' => true, 'name' => $array );
372 502 }
503 + // backward compatibility for PRO before v1.9.0
504 + if ( ! array_key_exists( 'supports', $array ) ) {
505 + $array['supports'] = array( 'Google Charts' );
506 + }
373 507 $doubleD[ $type ] = $array['name'];
374 508 }
375 509 $types = $doubleD;
376 510 }
@@ -384,49 +518,45 @@
384 518 private static function handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where ) {
385 519 $deprecated = array();
386 520
387 521 switch ( $where ) {
522 + case 'types':
523 + // fall-through
388 524 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 525 // if a user has a Gauge/Candlestick chart, then let them keep using it.
400 - if ( ! VISUALIZER_PRO ) {
526 + if ( ! Visualizer_Module::is_pro() ) {
401 527 if ( ! self::hasChartType( 'gauge' ) ) {
402 - $deprecated[] = 'gauge';
528 + if ( $get2Darray ) {
529 + $deprecated[] = 'gauge';
530 + } else {
531 + $types['gauge']['enabled'] = false;
532 + }
403 533 }
404 534 if ( ! self::hasChartType( 'candlestick' ) ) {
405 - $deprecated[] = 'candlestick';
535 + if ( $get2Darray ) {
536 + $deprecated[] = 'candlestick';
537 + } else {
538 + $types['candlestick']['enabled'] = false;
539 + }
406 540 }
407 541 }
408 542 break;
409 543 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 544 // if a user has a Gauge/Candlestick chart, then let them keep using it.
423 - if ( ! VISUALIZER_PRO ) {
545 + if ( ! Visualizer_Module::is_pro() ) {
424 546 if ( ! self::hasChartType( 'gauge' ) ) {
425 - $deprecated[] = 'gauge';
547 + if ( $get2Darray ) {
548 + $deprecated[] = 'gauge';
549 + } else {
550 + $types['gauge']['enabled'] = false;
551 + }
426 552 }
427 553 if ( ! self::hasChartType( 'candlestick' ) ) {
428 - $deprecated[] = 'candlestick';
554 + if ( $get2Darray ) {
555 + $deprecated[] = 'candlestick';
556 + } else {
557 + $types['candlestick']['enabled'] = false;
558 + }
429 559 }
430 560 }
431 561 }
432 562
@@ -448,9 +578,9 @@
448 578 * @access public
449 579 */
450 580 public function renderTemplates() {
451 581 global $pagenow;
452 - if ( 'post.php' != $pagenow && 'post-new.php' != $pagenow ) {
582 + if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
453 583 return;
454 584 }
455 585 $render = new Visualizer_Render_Templates();
456 586 $render->render();
@@ -468,9 +598,9 @@
468 598 *
469 599 * @param string $suffix The current page suffix.
470 600 */
471 601 public function enqueueLibraryScripts( $suffix ) {
472 - if ( $suffix == $this->_libraryPage ) {
602 + if ( $suffix === $this->_libraryPage ) {
473 603 wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
474 604 $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
475 605 wp_enqueue_media();
476 606 wp_enqueue_script(
@@ -478,8 +608,9 @@
478 608 VISUALIZER_ABSURL . 'js/library.js',
479 609 array(
480 610 'jquery',
481 611 'media-views',
612 + 'clipboard',
482 613 ),
483 614 Visualizer_Plugin::VERSION,
484 615 true
485 616 );
@@ -528,14 +659,126 @@
528 659 *
529 660 * @access public
530 661 */
531 662 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 );
663 + $svg_base64_icon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNzdweCIgaGVpZ2h0PSI3N3B4IiB2aWV3Qm94PSIwIDAgNzcgNzciIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjYgKDY3NDkxKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Db21iaW5lZCBTaGFwZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxnIGlkPSJQcm9kdWN0LVBhZ2UiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJXb3JkUHJlc3MtcGx1Z2lucyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE5MC4wMDAwMDAsIC00MzUuMDAwMDAwKSIgZmlsbD0iIzM5QzNEMiI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMjguNSw1MTIgQzIwNy4yMzcwMzcsNTEyIDE5MCw0OTQuNzYyOTYzIDE5MCw0NzMuNSBDMTkwLDQ1Mi4yMzcwMzcgMjA3LjIzNzAzNyw0MzUgMjI4LjUsNDM1IEMyNDkuNzYyOTYzLDQzNSAyNjcsNDUyLjIzNzAzNyAyNjcsNDczLjUgQzI2Nyw0OTQuNzYyOTYzIDI0OS43NjI5NjMsNTEyIDIyOC41LDUxMiBaIE0yNDYuODQzNzUsNDgzLjU5MjA1OSBMMjE1LjYyNSw0ODMuNTkyMDU5IEwyMTUuNjI1LDQ2MC44MjY1NDQgQzIxNS42MjUsNDYwLjE2NDU0NyAyMTUuMTA3NTc4LDQ1OS42MjgzNTkgMjE0LjQ2ODc1LDQ1OS42MjgzNTkgTDIxMi4xNTYyNSw0NTkuNjI4MzU5IEMyMTEuNTE3NDIyLDQ1OS42MjgzNTkgMjExLDQ2MC4xNjQ1NDcgMjExLDQ2MC44MjY1NDQgTDIxMSw0ODUuOTg4NDI5IEMyMTEsNDg3LjMxMTY3NCAyMTIuMDM1NTY2LDQ4OC4zODQ3OTggMjEzLjMxMjUsNDg4LjM4NDc5OCBMMjQ2Ljg0Mzc1LDQ4OC4zODQ3OTggQzI0Ny40ODI1NzgsNDg4LjM4NDc5OCAyNDgsNDg3Ljg0ODYxMSAyNDgsNDg3LjE4NjYxMyBMMjQ4LDQ4NC43OTAyNDQgQzI0OCw0ODQuMTI4MjQ2IDI0Ny40ODI1NzgsNDgzLjU5MjA1OSAyNDYuODQzNzUsNDgzLjU5MjA1OSBaIE0yNDQuNTMxMjUsNDYyLjAyNDcyOSBMMjM1Ljk5OTU3LDQ2Mi4wMjQ3MjkgQzIzNC40NTQ1MzEsNDYyLjAyNDcyOSAyMzMuNjgwNTY2LDQ2My45NjA1NDcgMjM0Ljc3MzIyMyw0NjUuMDkyODMyIEwyMzcuMTE0NjI5LDQ2Ny41MTkxNTYgTDIzMS44MTI1LDQ3My4wMTQzMzIgTDIyNi41MTAzNzEsNDY3LjUxOTkwNSBDMjI1LjYwNzA1MSw0NjYuNTgzODIzIDIyNC4xNDI5NDksNDY2LjU4MzgyMyAyMjMuMjQwMzUyLDQ2Ny41MTk5MDUgTDIxOC4yNzY0MjYsNDcyLjY2Mzg2MyBDMjE3LjgyNDc2Niw0NzMuMTMxOTA0IDIxNy44MjQ3NjYsNDczLjg5MDUwNSAyMTguMjc2NDI2LDQ3NC4zNTg1NDYgTDIxOS45MTEwNzQsNDc2LjA1MjQ4IEMyMjAuMzYyNzM0LDQ3Ni41MjA1MjEgMjIxLjA5NDc4NSw0NzYuNTIwNTIxIDIyMS41NDY0NDUsNDc2LjA1MjQ4IEwyMjQuODc1LDQ3Mi42MDI0NTYgTDIzMC4xNzcxMjksNDc4LjA5Njg4MyBDMjMxLjA4MDQ0OSw0NzkuMDMyOTY1IDIzMi41NDQ1NTEsNDc5LjAzMjk2NSAyMzMuNDQ3MTQ4LDQ3OC4wOTY4ODMgTDI0MC4zODQ2NDgsNDcwLjkwNzc3MyBMMjQyLjcyNjA1NSw0NzMuMzM0MDk4IEMyNDMuODE4NzExLDQ3NC40NjYzODIgMjQ1LjY4Njc3Nyw0NzMuNjY0MzQ3IDI0NS42ODY3NzcsNDcyLjA2MzI3MyBMMjQ1LjY4Njc3Nyw0NjMuMjIyOTE0IEMyNDUuNjg3NSw0NjIuNTYwOTE3IDI0NS4xNzAwNzgsNDYyLjAyNDcyOSAyNDQuNTMxMjUsNDYyLjAyNDcyOSBaIiBpZD0iQ29tYmluZWQtU2hhcGUiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==';
664 +
665 + $this->_libraryPage = add_menu_page( __( 'Visualizer', 'visualizer' ), __( 'Visualizer', 'visualizer' ), 'edit_posts', Visualizer_Plugin::NAME, array( $this, 'renderLibraryPage' ), $svg_base64_icon, 99.7666 );
666 +
667 + add_submenu_page(
668 + Visualizer_Plugin::NAME,
669 + __( 'Chart Library', 'visualizer' ),
670 + __( 'Chart Library', 'visualizer' ),
671 + 'edit_posts',
672 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME )
673 + );
674 + add_submenu_page(
675 + Visualizer_Plugin::NAME,
676 + __( 'Add New Chart', 'visualizer' ),
677 + __( 'Add New Chart', 'visualizer' ),
678 + 'edit_posts',
679 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew' )
680 + );
681 + add_submenu_page(
682 + Visualizer_Plugin::NAME,
683 + __( 'Support', 'visualizer' ),
684 + __( '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>',
685 + 'edit_posts',
686 + 'viz-support',
687 + array( $this, 'renderSupportPage' )
688 + );
689 + remove_submenu_page( Visualizer_Plugin::NAME, Visualizer_Plugin::NAME );
690 +
691 + add_action( "load-{$this->_libraryPage}", array( $this, 'addScreenOptions' ) );
535 692 }
536 693
537 694 /**
695 + * Adds the screen options for pagination.
696 + */
697 + function addScreenOptions() {
698 + $screen = get_current_screen();
699 +
700 + // bail if it's some other page.
701 + if ( ! is_object( $screen ) || $screen->id !== $this->_libraryPage ) {
702 + return;
703 + }
704 +
705 + $args = array(
706 + 'label' => __( 'Number of charts per page:', 'visualizer' ),
707 + 'default' => 6,
708 + 'option' => 'visualizer_library_per_page',
709 + );
710 + add_screen_option( 'per_page', $args );
711 + }
712 +
713 + /**
714 + * Returns the screen option for pagination.
715 + */
716 + function setScreenOptions( $status, $option, $value ) {
717 + if ( 'visualizer_library_per_page' === $option ) {
718 + return $value;
719 + }
720 + }
721 +
722 + /**
723 + * Adds the display filters to be used in the meta_query while displaying the charts.
724 + */
725 + private function getDisplayFilters( &$query_args ) {
726 + $query = array();
727 +
728 + // add chart type filter to the query arguments
729 + $type = filter_input( INPUT_GET, 'type' );
730 + if ( $type && in_array( $type, Visualizer_Plugin::getChartTypes(), true ) ) {
731 + $query[] = array(
732 + 'key' => Visualizer_Plugin::CF_CHART_TYPE,
733 + 'value' => $type,
734 + 'compare' => '=',
735 + );
736 + }
737 +
738 + // add chart library filter to the query arguments
739 + $library = filter_input( INPUT_GET, 'library' );
740 + if ( $library ) {
741 + $query[] = array(
742 + 'key' => Visualizer_Plugin::CF_CHART_LIBRARY,
743 + 'value' => $library,
744 + 'compare' => '=',
745 + );
746 + }
747 +
748 + // add date filter to the query arguments
749 + $date = filter_input( INPUT_GET, 'date' );
750 + $possible = array_keys( Visualizer_Plugin::getSupportedDateFilter() );
751 + if ( $date && in_array( $date, $possible, true ) ) {
752 + $query_args['date_query'] = array(
753 + 'after' => "$date -1 day",
754 + 'inclusive' => true,
755 + );
756 + }
757 +
758 + // add source filter to the query arguments
759 + $source = filter_input( INPUT_GET, 'source' );
760 + if ( $source ) {
761 + $source = ucwords( $source );
762 + $source = "Visualizer_Source_{$source}";
763 + $query[] = array(
764 + 'key' => Visualizer_Plugin::CF_SOURCE,
765 + 'value' => $source,
766 + 'compare' => '=',
767 + );
768 + }
769 +
770 + $query_args['meta_query'] = $query;
771 +
772 + $orderby = filter_input( INPUT_GET, 'orderby' );
773 + $order = filter_input( INPUT_GET, 'order' );
774 + if ( $orderby ) {
775 + $query_args['order_by'] = $orderby;
776 + }
777 + $query_args['order'] = empty( $order ) ? 'desc' : $order;
778 + }
779 +
780 + /**
538 781 * Get the instance of WP_Query that fetches the charts as per the given criteria.
539 782 */
540 783 private function getQuery() {
541 784 static $q;
@@ -554,27 +797,32 @@
554 797 'default' => 1,
555 798 ),
556 799 )
557 800 );
801 +
802 + $per_page = 6;
803 + $screen = get_current_screen();
804 + if ( $screen ) {
805 + // retrieve the per_page option
806 + $screen_option = $screen->get_option( 'per_page', 'option' );
807 + // retrieve the value stored for the current user
808 + $user = get_current_user_id();
809 + $per_page = get_user_meta( $user, $screen_option, true );
810 + if ( empty( $per_page ) || $per_page < 1 ) {
811 + // nothing set, get the default value
812 + $per_page = $screen->get_option( 'per_page', 'default' );
813 + }
814 + }
815 +
558 816 // the initial query arguments to fetch charts
559 817 $query_args = array(
560 818 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
561 - 'posts_per_page' => 6,
819 + 'posts_per_page' => $per_page,
562 820 'paged' => $page,
563 821 );
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 - }
822 +
823 + $this->getDisplayFilters( $query_args );
824 +
577 825 // Added by Ash/Upwork
578 826 $filterByMeta = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
579 827 if ( $filterByMeta ) {
580 828 $query = array(
@@ -585,13 +833,25 @@
585 833 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
586 834 $meta[] = $query;
587 835 $query_args['meta_query'] = $meta;
588 836 }
589 - $q = new WP_Query( $query_args );
837 + $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
590 838 return $q;
591 839 }
592 840
593 841 /**
842 + * Renders support page.
843 + *
844 + * @since 3.3.0
845 + *
846 + * @access public
847 + */
848 + public function renderSupportPage() {
849 + wp_enqueue_style( 'visualizer-upsell', VISUALIZER_ABSURL . 'css/upsell.css', array(), Visualizer_Plugin::VERSION );
850 + include_once VISUALIZER_ABSPATH . '/templates/support.php';
851 + }
852 +
853 + /**
594 854 * Renders visualizer library page.
595 855 *
596 856 * @since 1.0.0
597 857 *
@@ -614,9 +874,9 @@
614 874 )
615 875 );
616 876 // add chart type filter to the query arguments
617 877 $filter = filter_input( INPUT_GET, 'type' );
618 - if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) ) {
878 + if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) ) {
619 879 $filter = 'all';
620 880 }
621 881
622 882 $css = '';
@@ -637,12 +897,27 @@
637 897 if ( ! empty( $atts['settings'] ) ) {
638 898 $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
639 899 }
640 900
641 - unset( $settings['height'], $settings['width'] );
901 + if ( $settings ) {
902 + unset( $settings['height'], $settings['width'], $settings['chartArea'] );
903 + }
904 +
642 905 $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 );
906 + $data = self::get_chart_data( $chart, $type );
644 907
908 + // Set default setting series when add manual chart data - Only during first creation.
909 + if ( isset( $settings['series'] ) && ! empty( $series ) ) {
910 + $count_series = count( $series ) - count( $settings['series'] );
911 + if ( $count_series > 1 ) {
912 + $clone_last_series = end( $settings['series'] );
913 + $clone_last_series = array_fill_keys( array_keys( $clone_last_series ), '' );
914 + foreach ( range( 1, $count_series ) as $item ) {
915 + $settings['series'][] = $clone_last_series;
916 + }
917 + }
918 + }
919 +
645 920 $library = $this->load_chart_type( $chart->ID );
646 921
647 922 $id = 'visualizer-' . $chart->ID;
648 923 $arguments = $this->get_inline_custom_css( $id, $settings );
@@ -670,14 +945,16 @@
670 945 'language' => $this->get_language(),
671 946 'map_api_key' => get_option( 'visualizer-map-api-key' ),
672 947 'charts' => $charts,
673 948 'urls' => array(
674 - 'base' => add_query_arg( 'vpage', false ),
949 + 'base' => add_query_arg( array( 'vpage' => false, 'vaction' => false ) ),
675 950 'create' => add_query_arg(
676 951 array(
677 952 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
678 953 'library' => 'yes',
679 954 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
955 + 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
956 + 'vaction' => false,
680 957 ),
681 958 $ajaxurl
682 959 ),
683 960 'edit' => add_query_arg(
@@ -683,13 +960,19 @@
683 960 'edit' => add_query_arg(
684 961 array(
685 962 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
686 963 'library' => 'yes',
964 + 'vaction' => false,
687 965 ),
688 966 $ajaxurl
689 967 ),
690 968 ),
691 969 'page_type' => 'library',
970 + 'is_front' => false,
971 + 'i10n' => array(
972 + 'copied' => __( 'The shortcode has been copied to your clipboard. Hit Ctrl-V/Cmd-V to paste it.', 'visualizer' ),
973 + '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' ),
974 + ),
692 975 )
693 976 );
694 977 // render library page
695 978 $render = new Visualizer_Render_Library();
@@ -698,9 +981,9 @@
698 981 $render->types = self::_getChartTypesLocalized( false, false, false, true );
699 982 $render->custom_css = $css;
700 983 $render->pagination = paginate_links(
701 984 array(
702 - 'base' => add_query_arg( 'vpage', '%#%' ),
985 + 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
703 986 'format' => '',
704 987 'current' => $page,
705 988 'total' => $query->max_num_pages,
706 989 'type' => 'array',
@@ -721,14 +1004,14 @@
721 1004 *
722 1005 * @return array Updated array of action links.
723 1006 */
724 1007 public function getPluginActionLinks( $links, $file ) {
725 - if ( $file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1008 + if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
726 1009 array_unshift(
727 1010 $links,
728 1011 sprintf(
729 1012 '<a href="%s">%s</a>',
730 - admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ),
1013 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
731 1014 esc_html__( 'Library', 'visualizer' )
732 1015 )
733 1016 );
734 1017 }
@@ -748,17 +1031,17 @@
748 1031 *
749 1032 * @return array Updated array of plugin meta links.
750 1033 */
751 1034 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
752 - if ( $plugin_file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1035 + if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
753 1036 // knowledge base link
754 1037 $plugin_meta[] = sprintf(
755 - '<a href="https://github.com/codeinwp/visualizer/wiki" target="_blank">%s</a>',
756 - esc_html__( 'Knowledge Base', 'visualizer' )
1038 + '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1039 + esc_html__( 'Docs', 'visualizer' )
757 1040 );
758 1041 // flattr link
759 1042 $plugin_meta[] = sprintf(
760 - '<a style="color:red" href="https://themeisle.com/plugins/visualizer-charts-and-graphs-pro-addon/" target="_blank">%s</a>',
1043 + '<a style="color:red" href="' . Visualizer_Plugin::PRO_TEASER_URL . '" target="_blank">%s</a>',
761 1044 esc_html__( 'Pro Addon', 'visualizer' )
762 1045 );
763 1046 }
764 1047
@@ -764,5 +1047,16 @@
764 1047
765 1048 return $plugin_meta;
766 1049 }
767 1050
1051 + /**
1052 + * If check is existing user.
1053 + *
1054 + * @return bool Default false
1055 + */
1056 + public static function proFeaturesLocked() {
1057 + if ( Visualizer_Module::is_pro() ) {
1058 + return true;
1059 + }
1060 + return 'yes' === get_option( 'visualizer-new-user', 'yes' ) ? false : true;
1061 + }
768 1062 }