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 +414 -88 3.1.13.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 ),
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' ),
438 + ),
324 439 'scatter' => array(
325 440 'name' => esc_html__( 'Scatter', 'visualizer' ),
326 - 'enabled' => true,
441 + 'enabled' => $enabled,
442 + 'supports' => array( 'Google Charts' ),
327 443 ),
328 444 'gauge' => array(
329 445 'name' => esc_html__( 'Gauge', 'visualizer' ),
330 - 'enabled' => true,
446 + 'enabled' => $enabled,
447 + 'supports' => array( 'Google Charts' ),
331 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,21 +518,13 @@
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 528 if ( $get2Darray ) {
403 529 $deprecated[] = 'gauge';
404 530 } else {
@@ -414,20 +540,10 @@
414 540 }
415 541 }
416 542 break;
417 543 default:
418 - // remove the option to create a Google Table chart.
419 - $deprecated[] = 'table';
420 -
421 - // rename the new table chart type.
422 - if ( $get2Darray ) {
423 - $types['dataTable'] = esc_html__( 'Table', 'visualizer' );
424 - } else {
425 - $types['dataTable']['name'] = esc_html__( 'Table', 'visualizer' );
426 - }
427 -
428 544 // if a user has a Gauge/Candlestick chart, then let them keep using it.
429 - if ( ! VISUALIZER_PRO ) {
545 + if ( ! Visualizer_Module::is_pro() ) {
430 546 if ( ! self::hasChartType( 'gauge' ) ) {
431 547 if ( $get2Darray ) {
432 548 $deprecated[] = 'gauge';
433 549 } else {
@@ -462,9 +578,9 @@
462 578 * @access public
463 579 */
464 580 public function renderTemplates() {
465 581 global $pagenow;
466 - if ( 'post.php' != $pagenow && 'post-new.php' != $pagenow ) {
582 + if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
467 583 return;
468 584 }
469 585 $render = new Visualizer_Render_Templates();
470 586 $render->render();
@@ -482,9 +598,9 @@
482 598 *
483 599 * @param string $suffix The current page suffix.
484 600 */
485 601 public function enqueueLibraryScripts( $suffix ) {
486 - if ( $suffix == $this->_libraryPage ) {
602 + if ( $suffix === $this->_libraryPage ) {
487 603 wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
488 604 $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
489 605 wp_enqueue_media();
490 606 wp_enqueue_script(
@@ -492,8 +608,9 @@
492 608 VISUALIZER_ABSURL . 'js/library.js',
493 609 array(
494 610 'jquery',
495 611 'media-views',
612 + 'clipboard',
496 613 ),
497 614 Visualizer_Plugin::VERSION,
498 615 true
499 616 );
@@ -542,14 +659,168 @@
542 659 *
543 660 * @access public
544 661 */
545 662 public function registerAdminMenu() {
546 - $title = esc_html__( 'Visualizer Library', 'visualizer' );
547 - $callback = array( $this, 'renderLibraryPage' );
548 - $this->_libraryPage = add_submenu_page( 'upload.php', $title, $title, 'edit_posts', Visualizer_Plugin::NAME, $callback );
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' ) );
549 704 }
550 705
551 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 + /**
552 823 * Get the instance of WP_Query that fetches the charts as per the given criteria.
553 824 */
554 825 private function getQuery() {
555 826 static $q;
@@ -568,27 +839,32 @@
568 839 'default' => 1,
569 840 ),
570 841 )
571 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 +
572 858 // the initial query arguments to fetch charts
573 859 $query_args = array(
574 860 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
575 - 'posts_per_page' => 6,
861 + 'posts_per_page' => $per_page,
576 862 'paged' => $page,
577 863 );
578 - // add chart type filter to the query arguments
579 - $filter = filter_input( INPUT_GET, 'type' );
580 - if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) {
581 - $query_args['meta_query'] = array(
582 - array(
583 - 'key' => Visualizer_Plugin::CF_CHART_TYPE,
584 - 'value' => $filter,
585 - 'compare' => '=',
586 - ),
587 - );
588 - } else {
589 - $filter = 'all';
590 - }
864 +
865 + $this->getDisplayFilters( $query_args );
866 +
591 867 // Added by Ash/Upwork
592 868 $filterByMeta = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
593 869 if ( $filterByMeta ) {
594 870 $query = array(
@@ -599,13 +875,25 @@
599 875 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
600 876 $meta[] = $query;
601 877 $query_args['meta_query'] = $meta;
602 878 }
603 - $q = new WP_Query( $query_args );
879 + $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
604 880 return $q;
605 881 }
606 882
607 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 + /**
608 896 * Renders visualizer library page.
609 897 *
610 898 * @since 1.0.0
611 899 *
@@ -628,9 +916,9 @@
628 916 )
629 917 );
630 918 // add chart type filter to the query arguments
631 919 $filter = filter_input( INPUT_GET, 'type' );
632 - if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) ) {
920 + if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) ) {
633 921 $filter = 'all';
634 922 }
635 923
636 924 $css = '';
@@ -651,12 +939,27 @@
651 939 if ( ! empty( $atts['settings'] ) ) {
652 940 $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
653 941 }
654 942
655 - unset( $settings['height'], $settings['width'] );
943 + if ( $settings ) {
944 + unset( $settings['height'], $settings['width'], $settings['chartArea'] );
945 + }
946 +
656 947 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
657 - $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( $chart->post_content ) ), $chart->ID, $type );
948 + $data = self::get_chart_data( $chart, $type );
658 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 +
659 962 $library = $this->load_chart_type( $chart->ID );
660 963
661 964 $id = 'visualizer-' . $chart->ID;
662 965 $arguments = $this->get_inline_custom_css( $id, $settings );
@@ -684,26 +987,38 @@
684 987 'language' => $this->get_language(),
685 988 'map_api_key' => get_option( 'visualizer-map-api-key' ),
686 989 'charts' => $charts,
687 990 'urls' => array(
688 - 'base' => add_query_arg( 'vpage', false ),
689 - 'create' => add_query_arg(
690 - array(
691 - 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
692 - 'library' => 'yes',
693 - 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
694 - ),
695 - $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 + )
696 1003 ),
697 - 'edit' => add_query_arg(
698 - array(
699 - 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
700 - 'library' => 'yes',
701 - ),
702 - $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 + )
703 1013 ),
704 1014 ),
705 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 + ),
706 1021 )
707 1022 );
708 1023 // render library page
709 1024 $render = new Visualizer_Render_Library();
@@ -712,9 +1027,9 @@
712 1027 $render->types = self::_getChartTypesLocalized( false, false, false, true );
713 1028 $render->custom_css = $css;
714 1029 $render->pagination = paginate_links(
715 1030 array(
716 - 'base' => add_query_arg( 'vpage', '%#%' ),
1031 + 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
717 1032 'format' => '',
718 1033 'current' => $page,
719 1034 'total' => $query->max_num_pages,
720 1035 'type' => 'array',
@@ -735,14 +1050,14 @@
735 1050 *
736 1051 * @return array Updated array of action links.
737 1052 */
738 1053 public function getPluginActionLinks( $links, $file ) {
739 - if ( $file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1054 + if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
740 1055 array_unshift(
741 1056 $links,
742 1057 sprintf(
743 1058 '<a href="%s">%s</a>',
744 - admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ),
1059 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
745 1060 esc_html__( 'Library', 'visualizer' )
746 1061 )
747 1062 );
748 1063 }
@@ -762,17 +1077,17 @@
762 1077 *
763 1078 * @return array Updated array of plugin meta links.
764 1079 */
765 1080 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
766 - if ( $plugin_file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1081 + if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
767 1082 // knowledge base link
768 1083 $plugin_meta[] = sprintf(
769 - '<a href="https://github.com/codeinwp/visualizer/wiki" target="_blank">%s</a>',
770 - esc_html__( 'Knowledge Base', 'visualizer' )
1084 + '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1085 + esc_html__( 'Docs', 'visualizer' )
771 1086 );
772 1087 // flattr link
773 1088 $plugin_meta[] = sprintf(
774 - '<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>',
775 1090 esc_html__( 'Pro Addon', 'visualizer' )
776 1091 );
777 1092 }
778 1093
@@ -778,5 +1093,16 @@
778 1093
779 1094 return $plugin_meta;
780 1095 }
781 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 + }
782 1108 }