PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.7.9
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.7.9
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 +436 -96 3.1.03.7.9 View file →
@@ -53,25 +53,107 @@
53 53 parent::__construct( $plugin );
54 54 $this->_addAction( 'load-post.php', 'enqueueMediaScripts' );
55 55 $this->_addAction( 'load-post-new.php', 'enqueueMediaScripts' );
56 56 $this->_addAction( 'admin_footer', 'renderTemplates' );
57 - $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 8 );
57 + $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 0 );
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 );
@@ -265,9 +364,9 @@
265 364 'filters' => $chart_types,
266 365 'types' => array_keys( $chart_types ),
267 366 ),
268 367 'nonce' => wp_create_nonce(),
269 - 'buildurl' => add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ),
368 + 'buildurl' => esc_url( add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ) ),
270 369 );
271 370
272 371 return $strings;
273 372 }
@@ -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,168 @@
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 +
690 + if ( ! Visualizer_Module::is_pro() ) {
691 + add_submenu_page(
692 + Visualizer_Plugin::NAME,
693 + __( 'Get Visualizer Pro', 'visualizer' ),
694 + __( 'Get Visualizer Pro', 'visualizer' ),
695 + 'edit_posts',
696 + 'viz-get-pro',
697 + '__return_null'
698 + );
699 + add_action( 'admin_footer', array( $this, 'handleGetProSubMenu' ) );
700 + }
701 + remove_submenu_page( Visualizer_Plugin::NAME, Visualizer_Plugin::NAME );
702 +
703 + add_action( "load-{$this->_libraryPage}", array( $this, 'addScreenOptions' ) );
535 704 }
536 705
537 706 /**
707 + * Handle get pro plugin submenu.
708 + */
709 + public function handleGetProSubMenu() {
710 + ?>
711 + <style type="text/css">
712 + #toplevel_page_visualizer ul.wp-submenu li.wp-first-item + li + li + li {
713 + background: #FF7E65;
714 + font-size: 14px;
715 + font-weight: 600;
716 + color: #fff;
717 + }
718 + #toplevel_page_visualizer ul.wp-submenu li.wp-first-item + li + li + li > a {
719 + color: #fff !important;
720 + }
721 + #toplevel_page_visualizer ul.wp-submenu li.wp-first-item + li + li + li > a:hover {
722 + box-shadow: inherit;
723 + }
724 + </style>
725 + <script type="text/javascript">
726 + jQuery( document ).ready( function() {
727 + jQuery( '#toplevel_page_visualizer' ).on( 'click', 'li:not(.wp-submenu-head, .wp-first-item):eq(2)', function( e ) {
728 + e.preventDefault();
729 + window.open( 'https://themeisle.com/plugins/visualizer-charts-and-graphs/upgrade/#pricing', '_blank' );
730 + } );
731 + } );
732 + </script>
733 + <?php
734 + }
735 +
736 + /**
737 + * Adds the screen options for pagination.
738 + */
739 + function addScreenOptions() {
740 + $screen = get_current_screen();
741 +
742 + // bail if it's some other page.
743 + if ( ! is_object( $screen ) || $screen->id !== $this->_libraryPage ) {
744 + return;
745 + }
746 +
747 + $args = array(
748 + 'label' => __( 'Number of charts per page:', 'visualizer' ),
749 + 'default' => 6,
750 + 'option' => 'visualizer_library_per_page',
751 + );
752 + add_screen_option( 'per_page', $args );
753 + }
754 +
755 + /**
756 + * Returns the screen option for pagination.
757 + */
758 + function setScreenOptions( $status, $option, $value ) {
759 + if ( 'visualizer_library_per_page' === $option ) {
760 + return $value;
761 + }
762 + }
763 +
764 + /**
765 + * Adds the display filters to be used in the meta_query while displaying the charts.
766 + */
767 + private function getDisplayFilters( &$query_args ) {
768 + $query = array();
769 +
770 + // add chart type filter to the query arguments
771 + $type = filter_input( INPUT_GET, 'type' );
772 + if ( $type && in_array( $type, Visualizer_Plugin::getChartTypes(), true ) ) {
773 + $query[] = array(
774 + 'key' => Visualizer_Plugin::CF_CHART_TYPE,
775 + 'value' => $type,
776 + 'compare' => '=',
777 + );
778 + }
779 +
780 + // add chart library filter to the query arguments
781 + $library = filter_input( INPUT_GET, 'library' );
782 + if ( $library ) {
783 + $query[] = array(
784 + 'key' => Visualizer_Plugin::CF_CHART_LIBRARY,
785 + 'value' => $library,
786 + 'compare' => '=',
787 + );
788 + }
789 +
790 + // add date filter to the query arguments
791 + $date = filter_input( INPUT_GET, 'date' );
792 + $possible = array_keys( Visualizer_Plugin::getSupportedDateFilter() );
793 + if ( $date && in_array( $date, $possible, true ) ) {
794 + $query_args['date_query'] = array(
795 + 'after' => "$date -1 day",
796 + 'inclusive' => true,
797 + );
798 + }
799 +
800 + // add source filter to the query arguments
801 + $source = filter_input( INPUT_GET, 'source' );
802 + if ( $source ) {
803 + $source = ucwords( $source );
804 + $source = "Visualizer_Source_{$source}";
805 + $query[] = array(
806 + 'key' => Visualizer_Plugin::CF_SOURCE,
807 + 'value' => $source,
808 + 'compare' => '=',
809 + );
810 + }
811 +
812 + $query_args['meta_query'] = $query;
813 +
814 + $orderby = filter_input( INPUT_GET, 'orderby' );
815 + $order = filter_input( INPUT_GET, 'order' );
816 + if ( $orderby ) {
817 + $query_args['order_by'] = $orderby;
818 + }
819 + $query_args['order'] = empty( $order ) ? 'desc' : $order;
820 + }
821 +
822 + /**
538 823 * Get the instance of WP_Query that fetches the charts as per the given criteria.
539 824 */
540 825 private function getQuery() {
541 826 static $q;
@@ -554,27 +839,32 @@
554 839 'default' => 1,
555 840 ),
556 841 )
557 842 );
843 +
844 + $per_page = 6;
845 + $screen = get_current_screen();
846 + if ( $screen ) {
847 + // retrieve the per_page option
848 + $screen_option = $screen->get_option( 'per_page', 'option' );
849 + // retrieve the value stored for the current user
850 + $user = get_current_user_id();
851 + $per_page = get_user_meta( $user, $screen_option, true );
852 + if ( empty( $per_page ) || $per_page < 1 ) {
853 + // nothing set, get the default value
854 + $per_page = $screen->get_option( 'per_page', 'default' );
855 + }
856 + }
857 +
558 858 // the initial query arguments to fetch charts
559 859 $query_args = array(
560 860 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
561 - 'posts_per_page' => 6,
861 + 'posts_per_page' => $per_page,
562 862 'paged' => $page,
563 863 );
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 - }
864 +
865 + $this->getDisplayFilters( $query_args );
866 +
577 867 // Added by Ash/Upwork
578 868 $filterByMeta = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
579 869 if ( $filterByMeta ) {
580 870 $query = array(
@@ -585,13 +875,25 @@
585 875 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
586 876 $meta[] = $query;
587 877 $query_args['meta_query'] = $meta;
588 878 }
589 - $q = new WP_Query( $query_args );
879 + $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
590 880 return $q;
591 881 }
592 882
593 883 /**
884 + * Renders support page.
885 + *
886 + * @since 3.3.0
887 + *
888 + * @access public
889 + */
890 + public function renderSupportPage() {
891 + wp_enqueue_style( 'visualizer-upsell', VISUALIZER_ABSURL . 'css/upsell.css', array(), Visualizer_Plugin::VERSION );
892 + include_once VISUALIZER_ABSPATH . '/templates/support.php';
893 + }
894 +
895 + /**
594 896 * Renders visualizer library page.
595 897 *
596 898 * @since 1.0.0
597 899 *
@@ -614,9 +916,9 @@
614 916 )
615 917 );
616 918 // add chart type filter to the query arguments
617 919 $filter = filter_input( INPUT_GET, 'type' );
618 - if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) ) {
920 + if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) ) {
619 921 $filter = 'all';
620 922 }
621 923
622 924 $css = '';
@@ -637,12 +939,27 @@
637 939 if ( ! empty( $atts['settings'] ) ) {
638 940 $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
639 941 }
640 942
641 - unset( $settings['height'], $settings['width'] );
943 + if ( $settings ) {
944 + unset( $settings['height'], $settings['width'], $settings['chartArea'] );
945 + }
946 +
642 947 $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 );
948 + $data = self::get_chart_data( $chart, $type );
644 949
950 + // Set default setting series when add manual chart data - Only during first creation.
951 + if ( isset( $settings['series'] ) && ! empty( $series ) ) {
952 + $count_series = count( $series ) - count( $settings['series'] );
953 + if ( $count_series > 1 ) {
954 + $clone_last_series = end( $settings['series'] );
955 + $clone_last_series = array_fill_keys( array_keys( $clone_last_series ), '' );
956 + foreach ( range( 1, $count_series ) as $item ) {
957 + $settings['series'][] = $clone_last_series;
958 + }
959 + }
960 + }
961 +
645 962 $library = $this->load_chart_type( $chart->ID );
646 963
647 964 $id = 'visualizer-' . $chart->ID;
648 965 $arguments = $this->get_inline_custom_css( $id, $settings );
@@ -670,26 +987,38 @@
670 987 'language' => $this->get_language(),
671 988 'map_api_key' => get_option( 'visualizer-map-api-key' ),
672 989 'charts' => $charts,
673 990 'urls' => array(
674 - 'base' => add_query_arg( 'vpage', false ),
675 - 'create' => add_query_arg(
676 - array(
677 - 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
678 - 'library' => 'yes',
679 - 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
680 - ),
681 - $ajaxurl
991 + 'base' => esc_url( add_query_arg( array( 'vpage' => false, 'vaction' => false ) ) ),
992 + 'create' => esc_url(
993 + add_query_arg(
994 + array(
995 + 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
996 + 'library' => 'yes',
997 + 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
998 + 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
999 + 'vaction' => false,
1000 + ),
1001 + $ajaxurl
1002 + )
682 1003 ),
683 - 'edit' => add_query_arg(
684 - array(
685 - 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
686 - 'library' => 'yes',
687 - ),
688 - $ajaxurl
1004 + 'edit' => esc_url(
1005 + add_query_arg(
1006 + array(
1007 + 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
1008 + 'library' => 'yes',
1009 + 'vaction' => false,
1010 + ),
1011 + $ajaxurl
1012 + )
689 1013 ),
690 1014 ),
691 1015 'page_type' => 'library',
1016 + 'is_front' => false,
1017 + 'i10n' => array(
1018 + 'copied' => __( 'The shortcode has been copied to your clipboard. Hit Ctrl-V/Cmd-V to paste it.', 'visualizer' ),
1019 + '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' ),
1020 + ),
692 1021 )
693 1022 );
694 1023 // render library page
695 1024 $render = new Visualizer_Render_Library();
@@ -698,9 +1027,9 @@
698 1027 $render->types = self::_getChartTypesLocalized( false, false, false, true );
699 1028 $render->custom_css = $css;
700 1029 $render->pagination = paginate_links(
701 1030 array(
702 - 'base' => add_query_arg( 'vpage', '%#%' ),
1031 + 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
703 1032 'format' => '',
704 1033 'current' => $page,
705 1034 'total' => $query->max_num_pages,
706 1035 'type' => 'array',
@@ -721,14 +1050,14 @@
721 1050 *
722 1051 * @return array Updated array of action links.
723 1052 */
724 1053 public function getPluginActionLinks( $links, $file ) {
725 - if ( $file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1054 + if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
726 1055 array_unshift(
727 1056 $links,
728 1057 sprintf(
729 1058 '<a href="%s">%s</a>',
730 - admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ),
1059 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
731 1060 esc_html__( 'Library', 'visualizer' )
732 1061 )
733 1062 );
734 1063 }
@@ -748,17 +1077,17 @@
748 1077 *
749 1078 * @return array Updated array of plugin meta links.
750 1079 */
751 1080 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
752 - if ( $plugin_file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1081 + if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
753 1082 // knowledge base link
754 1083 $plugin_meta[] = sprintf(
755 - '<a href="https://github.com/codeinwp/visualizer/wiki" target="_blank">%s</a>',
756 - esc_html__( 'Knowledge Base', 'visualizer' )
1084 + '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1085 + esc_html__( 'Docs', 'visualizer' )
757 1086 );
758 1087 // flattr link
759 1088 $plugin_meta[] = sprintf(
760 - '<a style="color:red" href="https://themeisle.com/plugins/visualizer-charts-and-graphs-pro-addon/" target="_blank">%s</a>',
1089 + '<a style="color:red" href="' . Visualizer_Plugin::PRO_TEASER_URL . '" target="_blank">%s</a>',
761 1090 esc_html__( 'Pro Addon', 'visualizer' )
762 1091 );
763 1092 }
764 1093
@@ -764,5 +1093,16 @@
764 1093
765 1094 return $plugin_meta;
766 1095 }
767 1096
1097 + /**
1098 + * If check is existing user.
1099 + *
1100 + * @return bool Default false
1101 + */
1102 + public static function proFeaturesLocked() {
1103 + if ( Visualizer_Module::is_pro() ) {
1104 + return true;
1105 + }
1106 + return 'yes' === get_option( 'visualizer-new-user', 'yes' ) ? false : true;
1107 + }
768 1108 }