PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.8.1
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.8.1
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 +443 -96 3.1.03.8.1 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( '<?php echo tsdk_utmify( 'https://themeisle.com/plugins/visualizer-charts-and-graphs/upgrade/', 'toplevel' ); ?>', '_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 );
@@ -650,8 +967,15 @@
650 967 $css .= $arguments[0];
651 968 $settings = $arguments[1];
652 969 }
653 970
971 + if ( isset( $settings['controls']['ui']['labelStacking'] ) ) {
972 + unset( $settings['controls']['ui']['labelStacking'] );
973 + }
974 + if ( isset( $settings['controls']['ui']['orientation'] ) ) {
975 + unset( $settings['controls']['ui']['orientation'] );
976 + }
977 +
654 978 // add chart to the array
655 979 $charts[ $id ] = array(
656 980 'id' => $chart->ID,
657 981 'type' => $type,
@@ -670,26 +994,38 @@
670 994 'language' => $this->get_language(),
671 995 'map_api_key' => get_option( 'visualizer-map-api-key' ),
672 996 'charts' => $charts,
673 997 '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
998 + 'base' => esc_url( add_query_arg( array( 'vpage' => false, 'vaction' => false ) ) ),
999 + 'create' => esc_url(
1000 + add_query_arg(
1001 + array(
1002 + 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
1003 + 'library' => 'yes',
1004 + 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
1005 + 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
1006 + 'vaction' => false,
1007 + ),
1008 + $ajaxurl
1009 + )
682 1010 ),
683 - 'edit' => add_query_arg(
684 - array(
685 - 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
686 - 'library' => 'yes',
687 - ),
688 - $ajaxurl
1011 + 'edit' => esc_url(
1012 + add_query_arg(
1013 + array(
1014 + 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
1015 + 'library' => 'yes',
1016 + 'vaction' => false,
1017 + ),
1018 + $ajaxurl
1019 + )
689 1020 ),
690 1021 ),
691 1022 'page_type' => 'library',
1023 + 'is_front' => false,
1024 + 'i10n' => array(
1025 + 'copied' => __( 'The shortcode has been copied to your clipboard. Hit Ctrl-V/Cmd-V to paste it.', 'visualizer' ),
1026 + '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' ),
1027 + ),
692 1028 )
693 1029 );
694 1030 // render library page
695 1031 $render = new Visualizer_Render_Library();
@@ -698,9 +1034,9 @@
698 1034 $render->types = self::_getChartTypesLocalized( false, false, false, true );
699 1035 $render->custom_css = $css;
700 1036 $render->pagination = paginate_links(
701 1037 array(
702 - 'base' => add_query_arg( 'vpage', '%#%' ),
1038 + 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
703 1039 'format' => '',
704 1040 'current' => $page,
705 1041 'total' => $query->max_num_pages,
706 1042 'type' => 'array',
@@ -721,14 +1057,14 @@
721 1057 *
722 1058 * @return array Updated array of action links.
723 1059 */
724 1060 public function getPluginActionLinks( $links, $file ) {
725 - if ( $file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1061 + if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
726 1062 array_unshift(
727 1063 $links,
728 1064 sprintf(
729 1065 '<a href="%s">%s</a>',
730 - admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ),
1066 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
731 1067 esc_html__( 'Library', 'visualizer' )
732 1068 )
733 1069 );
734 1070 }
@@ -748,17 +1084,17 @@
748 1084 *
749 1085 * @return array Updated array of plugin meta links.
750 1086 */
751 1087 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
752 - if ( $plugin_file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1088 + if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
753 1089 // knowledge base link
754 1090 $plugin_meta[] = sprintf(
755 - '<a href="https://github.com/codeinwp/visualizer/wiki" target="_blank">%s</a>',
756 - esc_html__( 'Knowledge Base', 'visualizer' )
1091 + '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1092 + esc_html__( 'Docs', 'visualizer' )
757 1093 );
758 1094 // flattr link
759 1095 $plugin_meta[] = sprintf(
760 - '<a style="color:red" href="https://themeisle.com/plugins/visualizer-charts-and-graphs-pro-addon/" target="_blank">%s</a>',
1096 + '<a style="color:red" href="' . tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'pluginrow' ) . '" target="_blank">%s</a>',
761 1097 esc_html__( 'Pro Addon', 'visualizer' )
762 1098 );
763 1099 }
764 1100
@@ -764,5 +1100,16 @@
764 1100
765 1101 return $plugin_meta;
766 1102 }
767 1103
1104 + /**
1105 + * If check is existing user.
1106 + *
1107 + * @return bool Default false
1108 + */
1109 + public static function proFeaturesLocked() {
1110 + if ( Visualizer_Module::is_pro() ) {
1111 + return true;
1112 + }
1113 + return 'yes' === get_option( 'visualizer-new-user', 'yes' ) ? false : true;
1114 + }
768 1115 }