PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.0.12
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.0.12
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/Chart.php +96 -23 3.0.63.0.12 View file →
@@ -56,11 +56,9 @@
56 56 $this->_addAjaxAction( Visualizer_Plugin::ACTION_CREATE_CHART, 'renderChartPages' );
57 57 $this->_addAjaxAction( Visualizer_Plugin::ACTION_EDIT_CHART, 'renderChartPages' );
58 58 $this->_addAjaxAction( Visualizer_Plugin::ACTION_UPLOAD_DATA, 'uploadData' );
59 59 $this->_addAjaxAction( Visualizer_Plugin::ACTION_CLONE_CHART, 'cloneChart' );
60 - // Added by Ash/Upwork
61 60 $this->_addAjaxAction( Visualizer_Plugin::ACTION_EXPORT_DATA, 'exportData' );
62 - // Added by Ash/Upwork
63 61 }
64 62
65 63 /**
66 64 * Fetches charts from database.
@@ -73,9 +71,12 @@
73 71 $query_args = array(
74 72 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
75 73 'posts_per_page' => 9,
76 74 'paged' => filter_input(
77 - INPUT_GET, 'page', FILTER_VALIDATE_INT, array(
75 + INPUT_GET,
76 + 'page',
77 + FILTER_VALIDATE_INT,
78 + array(
78 79 'options' => array(
79 80 'min_range' => 1,
80 81 'default' => 1,
81 82 ),
@@ -172,9 +173,12 @@
172 173 $nonce = wp_verify_nonce( filter_input( $input_method, 'nonce' ) );
173 174 $capable = current_user_can( 'delete_posts' );
174 175 if ( $nonce && $capable ) {
175 176 $chart_id = filter_input(
176 - $input_method, 'chart', FILTER_VALIDATE_INT, array(
177 + $input_method,
178 + 'chart',
179 + FILTER_VALIDATE_INT,
180 + array(
177 181 'options' => array(
178 182 'min_range' => 1,
179 183 ),
180 184 )
@@ -210,9 +214,9 @@
210 214 defined( 'IFRAME_REQUEST' ) || define( 'IFRAME_REQUEST', 1 );
211 215 // check chart, if chart not exists, will create new one and redirects to the same page with proper chart id
212 216 $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
213 217 if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
214 - $default_type = 'line';
218 + $default_type = isset( $_GET['type'] ) && ! empty( $_GET['type'] ) ? $_GET['type'] : 'line';
215 219 $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $default_type . '.csv' );
216 220 $source->fetch();
217 221 $chart_id = wp_insert_post(
218 222 array(
@@ -228,9 +232,11 @@
228 232 add_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 1 );
229 233 add_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
230 234 add_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
231 235 add_post_meta(
232 - $chart_id, Visualizer_Plugin::CF_SETTINGS, array(
236 + $chart_id,
237 + Visualizer_Plugin::CF_SETTINGS,
238 + array(
233 239 'focusTarget' => 'datum',
234 240 )
235 241 );
236 242 do_action( 'visualizer_pro_new_chart_defaults', $chart_id );
@@ -245,20 +251,30 @@
245 251 wp_register_style( 'visualizer-frame', VISUALIZER_ABSURL . 'css/frame.css', array( 'visualizer-chosen' ), Visualizer_Plugin::VERSION );
246 252 wp_register_script( 'visualizer-frame', VISUALIZER_ABSURL . 'js/frame.js', array( 'visualizer-chosen' ), Visualizer_Plugin::VERSION, true );
247 253 wp_register_script( 'google-jsapi-new', '//www.gstatic.com/charts/loader.js', array(), null, true );
248 254 wp_register_script( 'google-jsapi-old', '//www.google.com/jsapi', array( 'google-jsapi-new' ), null, true );
255 + wp_register_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
249 256 wp_register_script(
250 - 'visualizer-render', VISUALIZER_ABSURL . 'js/render.js', array(
257 + 'visualizer-render',
258 + VISUALIZER_ABSURL . 'js/render.js',
259 + array(
251 260 'google-jsapi-old',
252 261 'google-jsapi-new',
253 262 'visualizer-frame',
254 - ), Visualizer_Plugin::VERSION, true
263 + 'visualizer-customization',
264 + ),
265 + Visualizer_Plugin::VERSION,
266 + true
255 267 );
256 268 wp_register_script(
257 - 'visualizer-preview', VISUALIZER_ABSURL . 'js/preview.js', array(
269 + 'visualizer-preview',
270 + VISUALIZER_ABSURL . 'js/preview.js',
271 + array(
258 272 'wp-color-picker',
259 273 'visualizer-render',
260 - ), Visualizer_Plugin::VERSION, true
274 + ),
275 + Visualizer_Plugin::VERSION,
276 + true
261 277 );
262 278 // added by Ash/Upwork
263 279 if ( VISUALIZER_PRO ) {
264 280 global $Visualizer_Pro;
@@ -268,12 +284,23 @@
268 284 $this->_chart = get_post( $chart_id );
269 285 $tab = isset( $_GET['tab'] ) && ! empty( $_GET['tab'] ) ? $_GET['tab'] : 'visualizer';
270 286
271 287 // skip chart type pages only for existing charts.
272 - if ( VISUALIZER_SKIP_CHART_TYPE_PAGE && 'auto-draft' !== $this->_chart->post_status ) {
288 + if ( VISUALIZER_SKIP_CHART_TYPE_PAGE && 'auto-draft' !== $this->_chart->post_status && ( ! empty( $_GET['tab'] ) && 'visualizer' === $_GET['tab'] ) ) {
273 289 $tab = 'settings';
274 290 }
275 291
292 + if ( isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] ) ) {
293 + // if the cancel button is clicked.
294 + $this->undoRevisions( $chart_id, true );
295 + } elseif ( isset( $_POST['save'] ) && 1 === intval( $_POST['save'] ) ) {
296 + // if the save button is clicked.
297 + $this->undoRevisions( $chart_id, false );
298 + } else {
299 + // if the edit button is clicked.
300 + $this->_chart = $this->handleExistingRevisions( $chart_id, $this->_chart );
301 + }
302 +
276 303 switch ( $tab ) {
277 304 case 'settings':
278 305 $this->_handleDataAndSettingsPage();
279 306 break;
@@ -297,11 +324,18 @@
297 324 }
298 325 if ( $_SERVER['REQUEST_METHOD'] == 'POST' && isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'] ) ) {
299 326 if ( $this->_chart->post_status == 'auto-draft' ) {
300 327 $this->_chart->post_status = 'publish';
328 +
329 + // ensure that a revision is not created. If a revision is created it will have the proper data and the parent of the revision will have default data.
330 + // we do not want any difference in data so disable revisions temporarily.
331 + add_filter( 'wp_revisions_to_keep', '__return_false' );
301 332 wp_update_post( $this->_chart->to_array() );
302 333 }
303 - update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $_POST );
334 + // save meta data only when it is NOT being canceled.
335 + if ( ! ( isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] ) ) ) {
336 + update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $_POST );
337 + }
304 338 $render = new Visualizer_Render_Page_Send();
305 339 $render->text = sprintf( '[visualizer id="%d"]', $this->_chart->ID );
306 340 wp_iframe( array( $render, 'render' ) );
307 341
@@ -327,9 +361,11 @@
327 361 wp_enqueue_style( 'visualizer-frame' );
328 362 wp_enqueue_script( 'visualizer-preview' );
329 363 wp_enqueue_script( 'visualizer-render' );
330 364 wp_localize_script(
331 - 'visualizer-render', 'visualizer', array(
365 + 'visualizer-render',
366 + 'visualizer',
367 + array(
332 368 'l10n' => array(
333 369 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ),
334 370 'loading' => esc_html__( 'Loading...', 'visualizer' ),
335 371 ),
@@ -335,8 +371,9 @@
335 371 ),
336 372 'charts' => array(
337 373 'canvas' => $data,
338 374 ),
375 + 'language' => $this->get_language(),
339 376 'map_api_key' => get_option( 'visualizer-map-api-key' ),
340 377 'ajax' => array(
341 378 'url' => admin_url( 'admin-ajax.php' ),
342 379 'nonces' => array(
@@ -355,8 +392,11 @@
355 392 if ( filter_input( INPUT_GET, 'library', FILTER_VALIDATE_BOOLEAN ) ) {
356 393 $render->button = filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART
357 394 ? esc_html__( 'Save Chart', 'visualizer' )
358 395 : esc_html__( 'Create Chart', 'visualizer' );
396 + if ( filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART ) {
397 + $render->cancel_button = esc_html__( 'Cancel', 'visualizer' );
398 + }
359 399 } else {
360 400 $render->button = esc_attr__( 'Insert Chart', 'visualizer' );
361 401 }
362 402 if ( VISUALIZER_PRO ) {
@@ -424,20 +464,32 @@
424 464 *
425 465 * @access public
426 466 */
427 467 public function uploadData() {
468 + // if this is being called internally from pro and VISUALIZER_DO_NOT_DIE is set.
469 + // otherwise, assume this is a normal web request.
470 + $can_die = ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE );
471 +
428 472 // validate nonce
429 - // do not use filter_input as it does not work for phpunit test cases, use filter_var instead
430 473 if ( ! isset( $_GET['nonce'] ) || ! wp_verify_nonce( $_GET['nonce'] ) ) {
474 + if ( ! $can_die ) {
475 + return;
476 + }
431 477 status_header( 403 );
432 478 exit;
433 479 }
480 +
434 481 // check chart, if chart exists
482 + // do not use filter_input as it does not work for phpunit test cases, use filter_var instead
435 483 $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
436 484 if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
485 + if ( ! $can_die ) {
486 + return;
487 + }
437 488 status_header( 400 );
438 489 exit;
439 490 }
491 +
440 492 if ( ! isset( $_POST['vz-import-time'] ) ) {
441 493 apply_filters( 'visualizer_pro_remove_schedule', $chart_id );
442 494 }
443 495
@@ -454,18 +506,29 @@
454 506 apply_filters( 'visualizer_pro_chart_schedule', $chart_id, $_POST['remote_data'], $_POST['vz-import-time'] );
455 507 }
456 508 } elseif ( isset( $_FILES['local_data'] ) && $_FILES['local_data']['error'] == 0 ) {
457 509 $source = new Visualizer_Source_Csv( $_FILES['local_data']['tmp_name'] );
458 - // Added by Ash/Upwork
459 510 } elseif ( isset( $_POST['chart_data'] ) && strlen( $_POST['chart_data'] ) > 0 ) {
460 511 $source = apply_filters( 'visualizer_pro_handle_chart_data', $_POST['chart_data'], '' );
461 - // Added by Ash/Upwork
462 512 } else {
463 513 $render->message = esc_html__( 'CSV file with chart data was not uploaded. Please, try again.', 'visualizer' );
464 514 }
465 515 if ( $source ) {
466 516 if ( $source->fetch() ) {
467 - $chart->post_content = $source->getData();
517 + $content = $source->getData();
518 + $populate = true;
519 + if ( is_string( $content ) && is_array( unserialize( $content ) ) ) {
520 + $json = unserialize( $content );
521 + // if source exists, so should data. if source exists but data is blank, do not populate the chart.
522 + // if we populate the data even if it is empty, the chart will show "Table has no columns".
523 + if ( array_key_exists( 'source', $json ) && ! empty( $json['source'] ) && ( ! array_key_exists( 'data', $json ) || empty( $json['data'] ) ) ) {
524 + do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Not populating chart data as source exists (%s) but data is empty!', $json['source'] ), 'warn', __FILE__, __LINE__ );
525 + $populate = false;
526 + }
527 + }
528 + if ( $populate ) {
529 + $chart->post_content = $content;
530 + }
468 531 wp_update_post( $chart->to_array() );
469 532 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
470 533 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
471 534 update_post_meta( $chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
@@ -475,11 +538,12 @@
475 538 $render->message = esc_html__( 'CSV file is broken or invalid. Please, try again.', 'visualizer' );
476 539 }
477 540 }
478 541 $render->render();
479 - if ( ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ) ) {
480 - defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
542 + if ( ! $can_die ) {
543 + return;
481 544 }
545 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
482 546 }
483 547
484 548 /**
485 549 * Clones the chart.
@@ -493,9 +557,12 @@
493 557 $nonce = wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), Visualizer_Plugin::ACTION_CLONE_CHART );
494 558 $capable = current_user_can( 'edit_posts' );
495 559 if ( $nonce && $capable ) {
496 560 $chart_id = filter_input(
497 - INPUT_GET, 'chart', FILTER_VALIDATE_INT, array(
561 + INPUT_GET,
562 + 'chart',
563 + FILTER_VALIDATE_INT,
564 + array(
498 565 'options' => array(
499 566 'min_range' => 1,
500 567 ),
501 568 )
@@ -525,9 +592,10 @@
525 592 $redirect = add_query_arg(
526 593 array(
527 594 'page' => 'visualizer',
528 595 'type' => filter_input( INPUT_GET, 'type' ),
529 - ), admin_url( 'upload.php' )
596 + ),
597 + admin_url( 'upload.php' )
530 598 );
531 599 }
532 600 }
533 601 wp_redirect( $redirect );
@@ -545,9 +613,11 @@
545 613 check_ajax_referer( Visualizer_Plugin::ACTION_EXPORT_DATA . Visualizer_Plugin::VERSION, 'security' );
546 614 $capable = current_user_can( 'edit_posts' );
547 615 if ( $capable ) {
548 616 $chart_id = isset( $_GET['chart'] ) ? filter_var(
549 - $_GET['chart'], FILTER_VALIDATE_INT, array(
617 + $_GET['chart'],
618 + FILTER_VALIDATE_INT,
619 + array(
550 620 'options' => array(
551 621 'min_range' => 1,
552 622 ),
553 623 )
@@ -578,9 +648,11 @@
578 648 unset( $data['settings']['width'], $data['settings']['height'] );
579 649 wp_enqueue_style( 'visualizer-frame' );
580 650 wp_enqueue_script( 'visualizer-render' );
581 651 wp_localize_script(
582 - 'visualizer-render', 'visualizer', array(
652 + 'visualizer-render',
653 + 'visualizer',
654 + array(
583 655 'l10n' => array(
584 656 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ),
585 657 'loading' => esc_html__( 'Loading...', 'visualizer' ),
586 658 ),
@@ -597,5 +669,6 @@
597 669 // Added by Ash/Upwork
598 670 $this->_addAction( 'admin_head', 'renderFlattrScript' );
599 671 wp_iframe( array( $render, 'render' ) );
600 672 }
673 +
601 674 }