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 +95 -23 3.0.73.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 ),
@@ -356,8 +392,11 @@
356 392 if ( filter_input( INPUT_GET, 'library', FILTER_VALIDATE_BOOLEAN ) ) {
357 393 $render->button = filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART
358 394 ? esc_html__( 'Save Chart', 'visualizer' )
359 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 + }
360 399 } else {
361 400 $render->button = esc_attr__( 'Insert Chart', 'visualizer' );
362 401 }
363 402 if ( VISUALIZER_PRO ) {
@@ -425,20 +464,32 @@
425 464 *
426 465 * @access public
427 466 */
428 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 +
429 472 // validate nonce
430 - // do not use filter_input as it does not work for phpunit test cases, use filter_var instead
431 473 if ( ! isset( $_GET['nonce'] ) || ! wp_verify_nonce( $_GET['nonce'] ) ) {
474 + if ( ! $can_die ) {
475 + return;
476 + }
432 477 status_header( 403 );
433 478 exit;
434 479 }
480 +
435 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
436 483 $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
437 484 if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
485 + if ( ! $can_die ) {
486 + return;
487 + }
438 488 status_header( 400 );
439 489 exit;
440 490 }
491 +
441 492 if ( ! isset( $_POST['vz-import-time'] ) ) {
442 493 apply_filters( 'visualizer_pro_remove_schedule', $chart_id );
443 494 }
444 495
@@ -455,18 +506,29 @@
455 506 apply_filters( 'visualizer_pro_chart_schedule', $chart_id, $_POST['remote_data'], $_POST['vz-import-time'] );
456 507 }
457 508 } elseif ( isset( $_FILES['local_data'] ) && $_FILES['local_data']['error'] == 0 ) {
458 509 $source = new Visualizer_Source_Csv( $_FILES['local_data']['tmp_name'] );
459 - // Added by Ash/Upwork
460 510 } elseif ( isset( $_POST['chart_data'] ) && strlen( $_POST['chart_data'] ) > 0 ) {
461 511 $source = apply_filters( 'visualizer_pro_handle_chart_data', $_POST['chart_data'], '' );
462 - // Added by Ash/Upwork
463 512 } else {
464 513 $render->message = esc_html__( 'CSV file with chart data was not uploaded. Please, try again.', 'visualizer' );
465 514 }
466 515 if ( $source ) {
467 516 if ( $source->fetch() ) {
468 - $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 + }
469 531 wp_update_post( $chart->to_array() );
470 532 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
471 533 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
472 534 update_post_meta( $chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
@@ -476,11 +538,12 @@
476 538 $render->message = esc_html__( 'CSV file is broken or invalid. Please, try again.', 'visualizer' );
477 539 }
478 540 }
479 541 $render->render();
480 - if ( ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ) ) {
481 - defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
542 + if ( ! $can_die ) {
543 + return;
482 544 }
545 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
483 546 }
484 547
485 548 /**
486 549 * Clones the chart.
@@ -494,9 +557,12 @@
494 557 $nonce = wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), Visualizer_Plugin::ACTION_CLONE_CHART );
495 558 $capable = current_user_can( 'edit_posts' );
496 559 if ( $nonce && $capable ) {
497 560 $chart_id = filter_input(
498 - INPUT_GET, 'chart', FILTER_VALIDATE_INT, array(
561 + INPUT_GET,
562 + 'chart',
563 + FILTER_VALIDATE_INT,
564 + array(
499 565 'options' => array(
500 566 'min_range' => 1,
501 567 ),
502 568 )
@@ -526,9 +592,10 @@
526 592 $redirect = add_query_arg(
527 593 array(
528 594 'page' => 'visualizer',
529 595 'type' => filter_input( INPUT_GET, 'type' ),
530 - ), admin_url( 'upload.php' )
596 + ),
597 + admin_url( 'upload.php' )
531 598 );
532 599 }
533 600 }
534 601 wp_redirect( $redirect );
@@ -546,9 +613,11 @@
546 613 check_ajax_referer( Visualizer_Plugin::ACTION_EXPORT_DATA . Visualizer_Plugin::VERSION, 'security' );
547 614 $capable = current_user_can( 'edit_posts' );
548 615 if ( $capable ) {
549 616 $chart_id = isset( $_GET['chart'] ) ? filter_var(
550 - $_GET['chart'], FILTER_VALIDATE_INT, array(
617 + $_GET['chart'],
618 + FILTER_VALIDATE_INT,
619 + array(
551 620 'options' => array(
552 621 'min_range' => 1,
553 622 ),
554 623 )
@@ -579,9 +648,11 @@
579 648 unset( $data['settings']['width'], $data['settings']['height'] );
580 649 wp_enqueue_style( 'visualizer-frame' );
581 650 wp_enqueue_script( 'visualizer-render' );
582 651 wp_localize_script(
583 - 'visualizer-render', 'visualizer', array(
652 + 'visualizer-render',
653 + 'visualizer',
654 + array(
584 655 'l10n' => array(
585 656 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ),
586 657 'loading' => esc_html__( 'Loading...', 'visualizer' ),
587 658 ),
@@ -598,5 +669,6 @@
598 669 // Added by Ash/Upwork
599 670 $this->_addAction( 'admin_head', 'renderFlattrScript' );
600 671 wp_iframe( array( $render, 'render' ) );
601 672 }
673 +
602 674 }