PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.6.1
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.6.1
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/Chart.php +96 -358 4.0.43.6.1 View file →
@@ -69,8 +69,9 @@
69 69
70 70 $this->_addAjaxAction( Visualizer_Plugin::ACTION_SAVE_FILTER_QUERY, 'saveFilter' );
71 71
72 72 $this->_addFilter( 'visualizer_get_sidebar', 'getSidebar', 10, 2 );
73 +
73 74 }
74 75
75 76 /**
76 77 * Generates the HTML of the sidebar for the chart.
@@ -133,22 +134,8 @@
133 134 ),
134 135 )
135 136 );
136 137
137 - if ( Visualizer_Module::is_pro() ) {
138 - $is_woocommerce_report = filter_input(
139 - INPUT_POST,
140 - 'is_woocommerce_report',
141 - FILTER_VALIDATE_BOOLEAN
142 - );
143 -
144 - if ( $is_woocommerce_report ) {
145 - update_post_meta( $chart_id, Visualizer_Plugin::CF_IS_WOOCOMMERCE_SOURCE, true );
146 - } else {
147 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_IS_WOOCOMMERCE_SOURCE );
148 - }
149 - }
150 -
151 138 delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE );
152 139
153 140 if ( -1 < $time ) {
154 141 add_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE, $time );
@@ -258,16 +245,8 @@
258 245 if ( ! empty( $params['paging'] ) ) {
259 246 add_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_PAGING, $params['paging'] );
260 247 }
261 248
262 - if ( Visualizer_Module::is_pro() ) {
263 - if ( ! empty( $params['vz_woo_source'] ) ) {
264 - update_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_WOOCOMMERCE_SOURCE, $params['vz_woo_source'] );
265 - } else {
266 - delete_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_WOOCOMMERCE_SOURCE );
267 - }
268 - }
269 -
270 249 $time = filter_input(
271 250 INPUT_POST,
272 251 'time',
273 252 FILTER_VALIDATE_INT,
@@ -295,9 +274,9 @@
295 274 $render->data = json_encode( $source->getRawData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ) );
296 275 $render->series = json_encode( $source->getSeries() );
297 276 $render->render();
298 277
299 - ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) ? wp_die() : exit();
278 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
300 279 }
301 280
302 281
303 282 /**
@@ -373,13 +352,13 @@
373 352 * @since 1.0.0
374 353 *
375 354 * @access private
376 355 *
377 - * @param WP_Post|null $chart The chart object.
356 + * @param WP_Post $chart The chart object.
378 357 *
379 358 * @return array The array of chart data.
380 359 */
381 - private function _getChartArray( $chart = null ) {
360 + private function _getChartArray( WP_Post $chart = null ) {
382 361 if ( is_null( $chart ) ) {
383 362 $chart = $this->_chart;
384 363 }
385 364 $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
@@ -401,13 +380,8 @@
401 380 }
402 381
403 382 $date_formats = Visualizer_Source::get_date_formats_if_exists( $series, $data );
404 383
405 - $code = '';
406 - if ( 'd3' === $library ) {
407 - $code = get_post_meta( $chart->ID, Visualizer_Module_AIBuilder::CF_D3_CODE, true );
408 - }
409 -
410 384 return array(
411 385 'type' => $type,
412 386 'series' => $series,
413 387 'settings' => $settings,
@@ -412,9 +386,8 @@
412 386 'series' => $series,
413 387 'settings' => $settings,
414 388 'data' => $data,
415 389 'library' => $library,
416 - 'code' => $code,
417 390 'css' => $css,
418 391 'date_formats' => $date_formats,
419 392 );
420 393 }
@@ -431,9 +404,9 @@
431 404 public static function _sendResponse( $results ) {
432 405 header( 'Content-type: application/json' );
433 406 nocache_headers();
434 407 echo json_encode( $results );
435 - ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) ? wp_die() : exit();
408 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
436 409 }
437 410
438 411 /**
439 412 * Deletes a chart from database.
@@ -465,22 +438,9 @@
465 438 $success = $chart && $chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
466 439 }
467 440 }
468 441 if ( $success ) {
469 - global $sitepress;
470 - if ( Visualizer_Module::is_pro() && ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) ) {
471 - $trid = $sitepress->get_element_trid( $chart_id, 'post_' . Visualizer_Plugin::CPT_VISUALIZER );
472 - $translations = $sitepress->get_element_translations( $trid );
473 - if ( ! empty( $translations ) ) {
474 - foreach ( $translations as $translated_post ) {
475 - wp_delete_post( $translated_post->element_id, true );
476 - }
477 - } else {
478 - wp_delete_post( $chart_id, true );
479 - }
480 - } else {
481 - wp_delete_post( $chart_id, true );
482 - }
442 + wp_delete_post( $chart_id, true );
483 443 }
484 444 if ( $is_post ) {
485 445 self::_sendResponse(
486 446 array(
@@ -528,104 +488,48 @@
528 488 *
529 489 * @access public
530 490 */
531 491 public function renderChartPages() {
532 - if ( ! current_user_can( 'edit_posts' ) ) {
533 - wp_die( __( 'You do not have permission to access this page.', 'visualizer' ) );
534 - }
535 -
536 492 defined( 'IFRAME_REQUEST' ) || define( 'IFRAME_REQUEST', 1 );
537 - if ( ! defined( 'ET_BUILDER_PRODUCT_VERSION' ) && function_exists( 'et_get_theme_version' ) ) {
538 - define( 'ET_BUILDER_PRODUCT_VERSION', et_get_theme_version() );
539 - }
540 493 // Set current screen for the render chart.
541 494 set_current_screen( 'visualizer_render_chart' );
542 495 // check chart, if chart not exists, will create new one and redirects to the same page with proper chart id
543 496 $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
544 - if ( ! empty( $_POST ) ) {
545 - $_POST = map_deep( $_POST, 'wp_strip_all_tags' );
546 - }
547 - $chart = $chart_id ? get_post( $chart_id ) : null;
548 - if ( ! $chart_id || ! $chart || $chart->post_type !== Visualizer_Plugin::CPT_VISUALIZER ) {
549 - if ( empty( $_GET['lang'] ) || empty( $_GET['parent_chart_id'] ) ) {
550 - $this->deleteOldCharts();
551 - $default_type = isset( $_GET['type'] ) && ! empty( $_GET['type'] ) ? $_GET['type'] : 'line';
552 - $chart_status = Visualizer_Module_Admin::checkChartStatus( $default_type );
553 - if ( ! $chart_status ) {
554 - $default_type = 'line';
555 - }
556 - $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $default_type . '.csv' );
557 - $source->fetch();
558 - $chart_id = wp_insert_post(
497 + if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type !== Visualizer_Plugin::CPT_VISUALIZER ) {
498 + $this->deleteOldCharts();
499 + $default_type = isset( $_GET['type'] ) && ! empty( $_GET['type'] ) ? $_GET['type'] : 'line';
500 + $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $default_type . '.csv' );
501 + $source->fetch();
502 + $chart_id = wp_insert_post(
503 + array(
504 + 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
505 + 'post_title' => 'Visualization',
506 + 'post_author' => get_current_user_id(),
507 + 'post_status' => 'auto-draft',
508 + 'post_content' => $source->getData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ),
509 + )
510 + );
511 + if ( $chart_id && ! is_wp_error( $chart_id ) ) {
512 + add_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, $default_type );
513 + add_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 1 );
514 + add_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
515 + add_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
516 + add_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_LIBRARY, '' );
517 + add_post_meta(
518 + $chart_id,
519 + Visualizer_Plugin::CF_SETTINGS,
559 520 array(
560 - 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
561 - 'post_title' => 'Visualization',
562 - 'post_author' => get_current_user_id(),
563 - 'post_status' => 'auto-draft',
564 - 'post_content' => $source->getData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ),
521 + 'focusTarget' => 'datum',
565 522 )
566 523 );
567 - if ( $chart_id && ! is_wp_error( $chart_id ) ) {
568 - add_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, $default_type );
569 - add_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 1 );
570 - add_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
571 - add_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
572 - add_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_LIBRARY, '' );
573 - add_post_meta(
574 - $chart_id,
575 - Visualizer_Plugin::CF_SETTINGS,
576 - array(
577 - 'focusTarget' => 'datum',
578 - )
579 - );
580 -
581 - do_action( 'visualizer_pro_new_chart_defaults', $chart_id );
582 - }
583 - } else {
584 - $parent_chart_id = filter_var( $_GET['parent_chart_id'], FILTER_VALIDATE_INT );
585 - $success = false;
586 - if ( $parent_chart_id ) {
587 - $parent_chart = get_post( $parent_chart_id );
588 - $success = $parent_chart && $parent_chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
589 - }
590 - if ( $success ) {
591 - $new_chart_id = wp_insert_post(
592 - array(
593 - 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
594 - 'post_title' => 'Visualization',
595 - 'post_author' => get_current_user_id(),
596 - 'post_status' => $parent_chart->post_status,
597 - 'post_content' => $parent_chart->post_content,
598 - )
599 - );
600 -
601 - if ( is_wp_error( $new_chart_id ) ) {
602 - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Error while cloning chart %d = %s', $parent_chart_id, print_r( $new_chart_id, true ) ), 'error', __FILE__, __LINE__ );
603 - } else {
604 - $post_meta = get_post_meta( $parent_chart_id );
605 - $chart_id = $new_chart_id;
606 - foreach ( $post_meta as $key => $value ) {
607 - if ( strpos( $key, 'visualizer-' ) !== false ) {
608 - add_post_meta( $new_chart_id, $key, maybe_unserialize( $value[0] ) );
609 - }
610 - }
611 - }
612 - }
613 524 do_action( 'visualizer_pro_new_chart_defaults', $chart_id );
614 525 }
615 - wp_redirect( esc_url_raw( add_query_arg( 'chart', (int) $chart_id ) ) );
616 -
617 - if ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) {
618 - wp_die();
619 - }
620 - exit();
526 + wp_redirect( add_query_arg( 'chart', (int) $chart_id ) );
527 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
621 528 }
622 529
623 - $_POST['save_chart_image'] = isset( $_POST['save_chart_image'] ) && 'yes' === $_POST['save_chart_image'] ? true : false;
624 - $_POST['lazy_load_chart'] = isset( $_POST['lazy_load_chart'] ) && 'yes' === $_POST['lazy_load_chart'] ? true : false;
625 -
626 530 if ( isset( $_POST['chart-img'] ) && ! empty( $_POST['chart-img'] ) ) {
627 - $attachment_id = $this->save_chart_image( $_POST['chart-img'], $chart_id, $_POST['save_chart_image'] );
531 + $attachment_id = $this->save_chart_image( $_POST['chart-img'], $chart_id );
628 532 if ( $attachment_id ) {
629 533 update_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_IMAGE, $attachment_id );
630 534 }
631 535 }
@@ -691,16 +595,8 @@
691 595 // if the edit button is clicked.
692 596 $this->_chart = $this->handleExistingRevisions( $chart_id, $this->_chart );
693 597 }
694 598
695 - // Clear existing chart cache.
696 - if ( isset( $_POST['save'] ) && 1 === intval( $_POST['save'] ) ) {
697 - $cache_key = Visualizer_Plugin::CF_CHART_CACHE . '_' . $chart_id;
698 - if ( get_transient( $cache_key ) ) {
699 - delete_transient( $cache_key );
700 - }
701 - }
702 -
703 599 switch ( $tab ) {
704 600 case 'settings':
705 601 $this->_handleDataAndSettingsPage();
706 602 break;
@@ -711,9 +607,9 @@
711 607 default:
712 608 // this should never happen.
713 609 break;
714 610 }
715 - ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) ? wp_die() : exit();
611 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
716 612 }
717 613
718 614 /**
719 615 * Load code editor assets.
@@ -725,9 +621,9 @@
725 621
726 622 // data tables assets.
727 623 wp_register_script( 'visualizer-datatables', VISUALIZER_ABSURL . 'js/lib/datatables.min.js', array( 'jquery-ui-core' ), Visualizer_Plugin::VERSION );
728 624 wp_register_style( 'visualizer-datatables', VISUALIZER_ABSURL . 'css/lib/datatables.min.css', array(), Visualizer_Plugin::VERSION );
729 - wp_register_style( 'visualizer-jquery-ui', sprintf( '//code.jquery.com/ui/%s/themes/smoothness/jquery-ui.css', $wp_scripts->registered['jquery-ui-core']->ver ), array( 'visualizer-datatables' ), Visualizer_Plugin::VERSION );
625 + wp_register_style( 'visualizer-jquery-ui', sprintf( '//ajax.googleapis.com/ajax/libs/jqueryui/%s/themes/smoothness/jquery-ui.css', $wp_scripts->registered['jquery-ui-core']->ver ), array( 'visualizer-datatables' ), Visualizer_Plugin::VERSION );
730 626 wp_enqueue_script( 'visualizer-datatables' );
731 627 wp_enqueue_style( 'visualizer-jquery-ui' );
732 628
733 629 if ( ! Visualizer_Module::is_pro() ) {
@@ -743,9 +639,9 @@
743 639 wp_register_script( 'visualizer-codemirror-matchbrackets', '//codemirror.net/addon/edit/matchbrackets.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
744 640 wp_register_script( 'visualizer-codemirror-closebrackets', '//codemirror.net/addon/edit/closebrackets.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
745 641 wp_register_script( 'visualizer-codemirror-sql', '//codemirror.net/mode/sql/sql.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
746 642 wp_register_script( 'visualizer-codemirror-sql-hint', '//codemirror.net/addon/hint/sql-hint.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
747 - wp_register_script( 'visualizer-codemirror-hint', '//codemirror.net/addon/hint/show-hint.js', array( 'visualizer-codemirror-sql', 'visualizer-codemirror-sql-hint', 'visualizer-codemirror-placeholder', 'visualizer-codemirror-matchbrackets', 'visualizer-codemirror-closebrackets' ), Visualizer_Plugin::VERSION );
643 + wp_register_script( 'visualizer-codemirror-hint', '//codemirror.net/addon/hint/show-hint.js', array( 'visualizer-codemirror-sql', 'visualizer-codemirror-sql-hint', 'visualizer-codemirror-placeholder', 'visualizer-codemirror-matchbrackets', 'visualizer-codemirror-closebrackets' ), Visualizer_Plugin::VERSION );
748 644 wp_register_style( 'visualizer-codemirror-core', '//codemirror.net/lib/codemirror.css', array(), Visualizer_Plugin::VERSION );
749 645 wp_register_style( 'visualizer-codemirror-hint', '//codemirror.net/addon/hint/show-hint.css', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
750 646
751 647 wp_enqueue_script( 'visualizer-codemirror-hint' );
@@ -759,9 +655,9 @@
759 655 'lineWrapping' => true,
760 656 'dragDrop' => false,
761 657 'matchBrackets' => true,
762 658 'autoCloseBrackets' => true,
763 - 'extraKeys' => array( 'Shift-Space' => 'autocomplete' ),
659 + 'extraKeys' => array( 'Ctrl-Space' => 'autocomplete' ),
764 660 'hintOptions' => array( 'tables' => $table_col_mapping ),
765 661 ),
766 662 )
767 663 );
@@ -795,12 +691,9 @@
795 691 update_option( 'visualizer-map-api-key', $_POST['map_api_key'] );
796 692 }
797 693
798 694 if ( $_SERVER['REQUEST_METHOD'] === 'POST' && isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'] ) ) {
799 - $is_canceled = isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] );
800 - $is_newly_created = $this->_chart->post_status === 'auto-draft';
801 -
802 - if ( $is_newly_created && ! $is_canceled ) {
695 + if ( $this->_chart->post_status === 'auto-draft' ) {
803 696 $this->_chart->post_status = 'publish';
804 697
805 698 // 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.
806 699 // we do not want any difference in data so disable revisions temporarily.
@@ -808,15 +701,10 @@
808 701
809 702 wp_update_post( $this->_chart->to_array() );
810 703 }
811 704 // save meta data only when it is NOT being canceled.
812 - if ( ! $is_canceled ) {
813 - $post_settings = $_POST;
814 - $existing = get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
815 - if ( isset( $existing['colors'] ) && is_array( $existing['colors'] ) && ! isset( $post_settings['colors'] ) ) {
816 - $post_settings['colors'] = $existing['colors'];
817 - }
818 - update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $post_settings );
705 + if ( ! ( isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] ) ) ) {
706 + update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $_POST );
819 707
820 708 // we will keep a parameter called 'internal_title' that will be set to the given title or, if empty, the chart ID
821 709 // this will help in searching with the chart id.
822 710 $settings = get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
@@ -830,14 +718,8 @@
830 718 if ( empty( $title ) ) {
831 719 $title = $this->_chart->ID;
832 720 }
833 721 $settings['internal_title'] = $title;
834 - $settings_label = isset( $settings['pieResidueSliceLabel'] ) ? $settings['pieResidueSliceLabel'] : '';
835 - if ( empty( $settings_label ) ) {
836 - $settings['pieResidueSliceLabel'] = esc_html__( 'Other', 'visualizer' );
837 - } else {
838 - $settings['pieResidueSliceLabel'] = $settings_label;
839 - }
840 722 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $settings );
841 723 }
842 724 $render = new Visualizer_Render_Page_Send();
843 725 $render->text = sprintf( '[visualizer id="%d"]', $this->_chart->ID );
@@ -863,9 +745,8 @@
863 745 wp_enqueue_style( 'visualizer-frame' );
864 746 wp_enqueue_script( 'visualizer-preview' );
865 747 wp_enqueue_script( 'visualizer-chosen' );
866 748 wp_enqueue_script( 'visualizer-render' );
867 - wp_enqueue_code_editor( array( 'type' => 'application/json' ) );
868 749
869 750 if ( Visualizer_Module::can_show_feature( 'simple-editor' ) ) {
870 751 wp_enqueue_script( 'visualizer-editor-simple' );
871 752 wp_localize_script(
@@ -873,10 +754,12 @@
873 754 'visualizer1',
874 755 array(
875 756 'ajax' => array(
876 757 'url' => admin_url( 'admin-ajax.php' ),
877 - 'nonces' => array(),
878 - 'actions' => array(),
758 + 'nonces' => array(
759 + ),
760 + 'actions' => array(
761 + ),
879 762 ),
880 763 )
881 764 );
882 765 }
@@ -887,15 +770,13 @@
887 770 'visualizer-render',
888 771 'visualizer',
889 772 array(
890 773 'l10n' => array(
891 - 'invalid_source' => esc_html__( 'The URL you entered is invalid. Please enter a valid URL.', 'visualizer' ),
892 - 'loading' => esc_html__( 'Loading...', 'visualizer' ),
893 - 'json_error' => esc_html__( 'An error occured in fetching data.', 'visualizer' ),
894 - 'select_columns' => esc_html__( 'Please select a few columns to include in the chart.', 'visualizer' ),
895 - 'save_settings' => __( 'You have modified the chart\'s settings. To modify the source/data again, you must save this chart and reopen it for editing. If you continue without saving the chart, you may lose your changes.', 'visualizer' ),
896 - 'copied' => __( 'The data has been copied to your clipboard. Hit Ctrl-V/Cmd-V in your spreadsheet editor to paste the data.', 'visualizer' ),
897 - 'invalid_format' => esc_html__( 'This format pattern is not supported in the series settings field. Use the Manual Configuration option instead.', 'visualizer' ),
774 + 'invalid_source' => esc_html__( 'You have entered an invalid URL. Please provide a valid URL.', 'visualizer' ),
775 + 'loading' => esc_html__( 'Loading...', 'visualizer' ),
776 + 'json_error' => esc_html__( 'An error occured in fetching data.', 'visualizer' ),
777 + 'select_columns' => esc_html__( 'Please select a few columns to include in the chart.', 'visualizer' ),
778 + 'save_settings' => __( 'You have modified the chart\'s settings. To modify the source/data again, you must save this chart and reopen it for editing. If you continue without saving the chart, you may lose your changes.', 'visualizer' ),
898 779 ),
899 780 'charts' => array(
900 781 'canvas' => $data,
901 782 'id' => $this->_chart->ID,
@@ -926,9 +807,8 @@
926 807 'page_type' => 'chart',
927 808 'json_tag_separator' => Visualizer_Source_Json::TAG_SEPARATOR,
928 809 'json_tag_separator_view' => Visualizer_Source_Json::TAG_SEPARATOR_VIEW,
929 810 'is_front' => false,
930 - 'rest_base' => get_rest_url( null, 'wc/v3/reports/' ),
931 811 )
932 812 );
933 813
934 814 $render = new Visualizer_Render_Page_Data();
@@ -939,10 +819,11 @@
939 819 if ( filter_input( INPUT_GET, 'library', FILTER_VALIDATE_BOOLEAN ) ) {
940 820 $render->button = filter_input( INPUT_GET, 'action' ) === Visualizer_Plugin::ACTION_EDIT_CHART
941 821 ? esc_html__( 'Save Chart', 'visualizer' )
942 822 : esc_html__( 'Create Chart', 'visualizer' );
943 -
944 - $render->cancel_button = esc_html__( 'Cancel', 'visualizer' );
823 + if ( filter_input( INPUT_GET, 'action' ) === Visualizer_Plugin::ACTION_EDIT_CHART ) {
824 + $render->cancel_button = esc_html__( 'Cancel', 'visualizer' );
825 + }
945 826 } else {
946 827 $render->button = esc_attr__( 'Insert Chart', 'visualizer' );
947 828 }
948 829
@@ -965,12 +846,12 @@
965 846 * @access private
966 847 */
967 848 private function _handleTypesPage() {
968 849 // process post request
969 - if ( $_SERVER['REQUEST_METHOD'] === 'POST' && wp_verify_nonce( filter_input( INPUT_POST, 'nonce' ), 'visualizer-upload-data' ) ) {
850 + if ( $_SERVER['REQUEST_METHOD'] === 'POST' && wp_verify_nonce( filter_input( INPUT_POST, 'nonce' ) ) ) {
970 851 $type = filter_input( INPUT_POST, 'type' );
971 852 $library = filter_input( INPUT_POST, 'chart-library' );
972 - if ( Visualizer_Module_Admin::checkChartStatus( $type ) ) {
853 + if ( in_array( $type, Visualizer_Plugin::getChartTypes(), true ) ) {
973 854 if ( empty( $library ) ) {
974 855 // library cannot be empty.
975 856 do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, 'Chart library empty while creating the chart! Aborting...', 'error', __FILE__, __LINE__ );
976 857 return;
@@ -991,9 +872,9 @@
991 872 Visualizer_Module_Utility::set_defaults( $this->_chart );
992 873
993 874 // redirect to next tab
994 875 // changed by Ash/Upwork
995 - wp_redirect( esc_url_raw( add_query_arg( 'tab', 'settings' ) ) );
876 + wp_redirect( add_query_arg( 'tab', 'settings' ) );
996 877
997 878 return;
998 879 }
999 880 }
@@ -1022,80 +903,8 @@
1022 903 * Processes the CSV that is sent in the request as a string.
1023 904 *
1024 905 * @since 3.2.0
1025 906 */
1026 - /**
1027 - * Determines whether a remote URL serves an XLSX file.
1028 - *
1029 - * Used as a fallback when the URL path has no recognisable file extension
1030 - * (e.g. SharePoint, signed S3 URLs, or "download?id=…" endpoints).
1031 - *
1032 - * Uses wp_safe_remote_get() to block requests to private/loopback addresses,
1033 - * and streams the response to a temp file so no body data is held in memory
1034 - * regardless of whether the server honours the Range header.
1035 - *
1036 - * The check relies on the ZIP magic number (PK\x03\x04) that every XLSX
1037 - * file begins with, making it immune to misleading Content-Type headers
1038 - * such as application/octet-stream. Content-Type is used as a last-resort
1039 - * fallback only when the temp file is empty (e.g. a HEAD-only server).
1040 - *
1041 - * @access private
1042 - * @param string $url The remote URL to probe.
1043 - * @return bool TRUE if the file appears to be XLSX, FALSE otherwise.
1044 - */
1045 - private static function _url_is_xlsx( $url ) {
1046 - $tmpfile = wp_tempnam( 'visualizer_xlsx_probe' );
1047 - if ( ! $tmpfile ) {
1048 - return false;
1049 - }
1050 -
1051 - $response = wp_safe_remote_get(
1052 - $url,
1053 - array(
1054 - 'timeout' => 10,
1055 - 'user-agent' => 'WordPress/' . get_bloginfo( 'version' ),
1056 - 'headers' => array( 'Range' => 'bytes=0-3' ),
1057 - 'stream' => true,
1058 - 'filename' => $tmpfile,
1059 - )
1060 - );
1061 -
1062 - if ( is_wp_error( $response ) ) {
1063 - @unlink( $tmpfile ); // phpcs:ignore WordPress.PHP.NoSilencedErrors
1064 - return false;
1065 - }
1066 -
1067 - $magic = '';
1068 - // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen
1069 - $fh = @fopen( $tmpfile, 'rb' ); // phpcs:ignore WordPress.PHP.NoSilencedErrors
1070 - if ( $fh ) {
1071 - $magic = fread( $fh, 4 ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fread
1072 - fclose( $fh ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
1073 - }
1074 - @unlink( $tmpfile ); // phpcs:ignore WordPress.PHP.NoSilencedErrors
1075 -
1076 - if ( strlen( $magic ) >= 4 ) {
1077 - // XLSX (and all ZIP-based Office formats) start with PK\x03\x04.
1078 - return $magic === "PK\x03\x04";
1079 - }
1080 -
1081 - // Last resort: server returned an empty body (e.g. ignored Range and
1082 - // returned only headers). Check Content-Type from the same response.
1083 - // application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
1084 - return false !== strpos(
1085 - wp_remote_retrieve_header( $response, 'content-type' ),
1086 - 'spreadsheetml'
1087 - );
1088 - }
1089 -
1090 - /**
1091 - * Parses a raw CSV string or editor payload and returns a source object.
1092 - *
1093 - * @access private
1094 - * @param string $data The raw CSV data string.
1095 - * @param string $editor_type The editor type ('text' or 'tabular').
1096 - * @return Visualizer_Source|null The populated source object, or null on failure.
1097 - */
1098 907 private function handleCSVasString( $data, $editor_type ) {
1099 908 $source = null;
1100 909
1101 910 switch ( $editor_type ) {
@@ -1110,9 +919,9 @@
1110 919 continue;
1111 920 }
1112 921 $row = explode( ',', $row );
1113 922 $row = array_map(
1114 - function ( $r ) {
923 + function( $r ) {
1115 924 return '' === $r ? ' ' : $r;
1116 925 },
1117 926 $row
1118 927 );
@@ -1161,9 +970,9 @@
1161 970 foreach ( $types as $type ) {
1162 971 if ( empty( $type ) ) {
1163 972 $exclude[] = $index;
1164 973 }
1165 - ++$index;
974 + $index++;
1166 975 }
1167 976
1168 977 // when N headers are being renamed, the number of headers increases by N
1169 978 // because of the way datatable duplicates header information
@@ -1223,13 +1032,9 @@
1223 1032 // otherwise, assume this is a normal web request.
1224 1033 $can_die = ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE );
1225 1034
1226 1035 // validate nonce
1227 - if (
1228 - ! isset( $_GET['nonce'] ) ||
1229 - ! wp_verify_nonce( $_GET['nonce'], 'visualizer-upload-data' ) ||
1230 - ! current_user_can( 'edit_posts' )
1231 - ) {
1036 + if ( ! isset( $_GET['nonce'] ) || ! wp_verify_nonce( $_GET['nonce'] ) ) {
1232 1037 if ( ! $can_die ) {
1233 1038 return;
1234 1039 }
1235 1040 status_header( 403 );
@@ -1238,15 +1043,9 @@
1238 1043
1239 1044 // check chart, if chart exists
1240 1045 // do not use filter_input as it does not work for phpunit test cases, use filter_var instead
1241 1046 $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
1242 - $chart = $chart_id ? get_post( $chart_id ) : null;
1243 - if (
1244 - ! $chart_id ||
1245 - ! $chart ||
1246 - $chart->post_type !== Visualizer_Plugin::CPT_VISUALIZER ||
1247 - ! current_user_can( 'edit_post', $chart_id )
1248 - ) {
1047 + if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type !== Visualizer_Plugin::CPT_VISUALIZER ) {
1249 1048 if ( ! $can_die ) {
1250 1049 return;
1251 1050 }
1252 1051 status_header( 400 );
@@ -1287,30 +1086,16 @@
1287 1086 delete_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE );
1288 1087
1289 1088 $source = null;
1290 1089 $render = new Visualizer_Render_Page_Update();
1291 -
1292 - $remote_data = false;
1293 - if ( isset( $_POST['remote_data'] ) && function_exists( 'wp_http_validate_url' ) ) {
1294 - $remote_data = wp_http_validate_url( $_POST['remote_data'] );
1295 - }
1296 - if ( false !== $remote_data ) {
1297 - $remote_ext = strtolower( pathinfo( parse_url( $remote_data, PHP_URL_PATH ), PATHINFO_EXTENSION ) );
1298 - if ( 'xlsx' === $remote_ext || ( 'csv' !== $remote_ext && self::_url_is_xlsx( $remote_data ) ) ) {
1299 - $source = new Visualizer_Source_Xlsx_Remote( $remote_data );
1300 - } else {
1301 - $source = new Visualizer_Source_Csv_Remote( $remote_data );
1302 - }
1090 + if ( isset( $_POST['remote_data'] ) && filter_var( $_POST['remote_data'], FILTER_VALIDATE_URL ) ) {
1091 + $source = new Visualizer_Source_Csv_Remote( $_POST['remote_data'] );
1303 1092 if ( isset( $_POST['vz-import-time'] ) ) {
1304 - apply_filters( 'visualizer_pro_chart_schedule', $chart_id, $remote_data, $_POST['vz-import-time'] );
1093 + apply_filters( 'visualizer_pro_chart_schedule', $chart_id, $_POST['remote_data'], $_POST['vz-import-time'] );
1305 1094 }
1306 - } elseif ( isset( $_FILES['local_data'] ) && $_FILES['local_data']['error'] === 0 ) {
1307 - $local_ext = strtolower( pathinfo( isset( $_FILES['local_data']['name'] ) ? $_FILES['local_data']['name'] : '', PATHINFO_EXTENSION ) );
1308 - if ( 'xlsx' === $local_ext ) {
1309 - $source = new Visualizer_Source_Xlsx( $_FILES['local_data']['tmp_name'] );
1310 - } else {
1311 - $source = new Visualizer_Source_Csv( $_FILES['local_data']['tmp_name'] );
1312 - }
1095 + // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
1096 + } elseif ( isset( $_FILES['local_data'] ) && $_FILES['local_data']['error'] == 0 ) {
1097 + $source = new Visualizer_Source_Csv( $_FILES['local_data']['tmp_name'] );
1313 1098 } elseif ( isset( $_POST['chart_data'] ) && strlen( $_POST['chart_data'] ) > 0 ) {
1314 1099 $source = $this->handleCSVasString( $_POST['chart_data'], $_POST['editor-type'] );
1315 1100 update_post_meta( $chart_id, Visualizer_Plugin::CF_EDITOR, $_POST['editor-type'] );
1316 1101 } elseif ( isset( $_POST['table_data'] ) && 'yes' === $_POST['table_data'] ) {
@@ -1317,10 +1102,10 @@
1317 1102 $source = $this->handleTabularData();
1318 1103 update_post_meta( $chart_id, Visualizer_Plugin::CF_EDITOR, $_POST['editor-type'] );
1319 1104 } else {
1320 1105 do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'CSV file with chart data was not uploaded for chart %d.', $chart_id ), 'error', __FILE__, __LINE__ );
1321 - $render->message = esc_html__( 'No CSV file was received. Select a file and try uploading again.', 'visualizer' );
1322 - update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, esc_html__( 'No CSV file was received. Select a file and try uploading again.', 'visualizer' ) );
1106 + $render->message = esc_html__( 'CSV file with chart data was not uploaded. Please try again.', 'visualizer' );
1107 + update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, esc_html__( 'CSV file with chart data was not uploaded. Please try again.', 'visualizer' ) );
1323 1108 }
1324 1109
1325 1110 do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Uploaded data for chart %d with source %s', $chart_id, print_r( $source, true ) ), 'debug', __FILE__, __LINE__ );
1326 1111
@@ -1341,9 +1126,8 @@
1341 1126 if ( $populate ) {
1342 1127 $chart->post_content = $content;
1343 1128 }
1344 1129 wp_update_post( $chart->to_array() );
1345 -
1346 1130 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
1347 1131 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
1348 1132 update_post_meta( $chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
1349 1133
@@ -1351,17 +1135,8 @@
1351 1135
1352 1136 Visualizer_Module_Utility::set_defaults( $chart, null );
1353 1137
1354 1138 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
1355 - if ( isset( $settings['series'] ) && ! ( count( $settings['series'] ) - count( $source->getSeries() ) > 1 ) ) {
1356 - $diff_total_series = abs( count( $settings['series'] ) - count( $source->getSeries() ) );
1357 - if ( $diff_total_series ) {
1358 - foreach ( range( 1, $diff_total_series ) as $k => $diff_series ) {
1359 - $settings['series'][] = end( $settings['series'] );
1360 - }
1361 - update_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, $settings );
1362 - }
1363 - }
1364 1139
1365 1140 $render->id = $chart->ID;
1366 1141 $render->data = json_encode( $source->getRawData( get_post_meta( $chart->ID, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ) );
1367 1142 $render->series = json_encode( $source->getSeries() );
@@ -1368,9 +1143,9 @@
1368 1143 $render->settings = json_encode( $settings );
1369 1144 } else {
1370 1145 $error = $source->get_error();
1371 1146 if ( empty( $error ) ) {
1372 - $error = esc_html__( 'The CSV file couldn\'t be read. Check that it\'s properly formatted and try again.', 'visualizer' );
1147 + $error = esc_html__( 'CSV file is broken or invalid. Please try again.', 'visualizer' );
1373 1148 }
1374 1149 $render->message = $error;
1375 1150 do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( '%s for chart %d.', $error, $chart_id ), 'error', __FILE__, __LINE__ );
1376 1151 update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, $error );
@@ -1381,9 +1156,9 @@
1381 1156 $render->render();
1382 1157 if ( ! $can_die ) {
1383 1158 return;
1384 1159 }
1385 - ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) ? wp_die() : exit();
1160 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1386 1161 }
1387 1162
1388 1163 /**
1389 1164 * Clones the chart.
@@ -1422,26 +1197,23 @@
1422 1197 if ( strpos( $key, 'visualizer-' ) !== false ) {
1423 1198 add_post_meta( $new_chart_id, $key, maybe_unserialize( $value[0] ) );
1424 1199 }
1425 1200 }
1426 - $redirect = esc_url(
1427 - add_query_arg(
1428 - array(
1429 - 'page' => 'visualizer',
1430 - 'type' => filter_input( INPUT_GET, 'type' ),
1431 - 'vaction' => false,
1432 - ),
1433 - admin_url( 'admin.php' )
1201 + $redirect = add_query_arg(
1202 + array(
1203 + 'page' => 'visualizer',
1204 + 'type' => filter_input( INPUT_GET, 'type' ),
1205 + 'vaction' => false,
1434 1206 ),
1435 - null,
1436 - 'db'
1207 + admin_url( 'admin.php' )
1437 1208 );
1438 1209 }
1439 1210 }
1440 1211
1441 - if ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) {
1212 + if ( defined( 'WP_TESTS_DOMAIN' ) ) {
1442 1213 wp_die();
1443 1214 }
1215 +
1444 1216 wp_redirect( $redirect );
1445 1217 exit;
1446 1218 }
1447 1219
@@ -1472,9 +1244,9 @@
1472 1244 }
1473 1245 }
1474 1246 }
1475 1247
1476 - ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) ? wp_die() : exit();
1248 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1477 1249 }
1478 1250
1479 1251 /**
1480 1252 * Handles chart data page.
@@ -1498,11 +1270,10 @@
1498 1270 'visualizer-render',
1499 1271 'visualizer',
1500 1272 array(
1501 1273 'l10n' => array(
1502 - 'invalid_source' => esc_html__( 'The URL you entered is invalid. Please enter a valid URL.', 'visualizer' ),
1503 - 'loading' => esc_html__( 'Loading...', 'visualizer' ),
1504 - 'invalid_format' => esc_html__( 'This format pattern is not supported in the series settings field. To display percentages, use the Manual Configuration option instead.', 'visualizer' ),
1274 + 'invalid_source' => esc_html__( 'You have entered an invalid URL. Please provide a valid URL.', 'visualizer' ),
1275 + 'loading' => esc_html__( 'Loading...', 'visualizer' ),
1505 1276 ),
1506 1277 'charts' => array(
1507 1278 'canvas' => $data,
1508 1279 ),
@@ -1528,24 +1299,12 @@
1528 1299 */
1529 1300 public function getQueryData() {
1530 1301 check_ajax_referer( Visualizer_Plugin::ACTION_FETCH_DB_DATA . Visualizer_Plugin::VERSION, 'security' );
1531 1302
1532 - if ( ! current_user_can( 'administrator' ) ) {
1533 - wp_send_json_error( array( 'msg' => __( 'Action not allowed for this user.', 'visualizer' ) ) );
1534 - }
1535 - if ( ! is_super_admin() ) {
1536 - wp_send_json_error( array( 'msg' => __( 'Action not allowed for this user.', 'visualizer' ) ) );
1537 - }
1538 -
1539 - if ( ! Visualizer_Module::is_pro() ) {
1540 - wp_send_json_error( array( 'msg' => __( 'Feature is not available.', 'visualizer' ) ) );
1541 - }
1542 -
1543 1303 $params = wp_parse_args( $_POST['params'] );
1544 1304 $chart_id = filter_var( $params['chart_id'], FILTER_VALIDATE_INT );
1545 - $query = trim( $params['query'], ';' );
1546 1305
1547 - $source = new Visualizer_Source_Query( stripslashes( $query ), $chart_id, $params );
1306 + $source = new Visualizer_Source_Query( stripslashes( $params['query'] ), $chart_id, $params );
1548 1307 $html = $source->fetch( true );
1549 1308 $error = $source->get_error();
1550 1309 if ( ! empty( $error ) ) {
1551 1310 wp_send_json_error( array( 'msg' => $error ) );
@@ -1560,19 +1319,8 @@
1560 1319 */
1561 1320 public function saveQuery() {
1562 1321 check_ajax_referer( Visualizer_Plugin::ACTION_SAVE_DB_QUERY . Visualizer_Plugin::VERSION, 'security' );
1563 1322
1564 - if ( ! current_user_can( 'administrator' ) ) {
1565 - wp_send_json_error( array( 'msg' => __( 'Action not allowed for this user.', 'visualizer' ) ) );
1566 - }
1567 - if ( ! is_super_admin() ) {
1568 - wp_send_json_error( array( 'msg' => __( 'Action not allowed for this user.', 'visualizer' ) ) );
1569 - }
1570 -
1571 - if ( ! Visualizer_Module::is_pro() ) {
1572 - wp_send_json_error( array( 'msg' => __( 'Feature is not available.', 'visualizer' ) ) );
1573 - }
1574 -
1575 1323 $chart_id = filter_input(
1576 1324 INPUT_GET,
1577 1325 'chart',
1578 1326 FILTER_VALIDATE_INT,
@@ -1585,9 +1333,9 @@
1585 1333
1586 1334 $hours = filter_input(
1587 1335 INPUT_POST,
1588 1336 'refresh',
1589 - FILTER_VALIDATE_FLOAT,
1337 + FILTER_VALIDATE_INT,
1590 1338 array(
1591 1339 'options' => array(
1592 1340 'min_range' => -1,
1593 1341 'max_range' => apply_filters( 'visualizer_is_business', false ) ? PHP_INT_MAX : -1,
@@ -1594,9 +1342,9 @@
1594 1342 ),
1595 1343 )
1596 1344 );
1597 1345
1598 - if ( ! is_numeric( $hours ) ) {
1346 + if ( ! is_int( $hours ) ) {
1599 1347 $hours = -1;
1600 1348 }
1601 1349
1602 1350 $render = new Visualizer_Render_Page_Update();
@@ -1601,14 +1349,13 @@
1601 1349
1602 1350 $render = new Visualizer_Render_Page_Update();
1603 1351 if ( $chart_id ) {
1604 1352 $params = wp_parse_args( $_POST['params'] );
1605 - $query = trim( $params['query'], ';' );
1606 - $source = new Visualizer_Source_Query( stripslashes( $query ), $chart_id, $params );
1353 + $source = new Visualizer_Source_Query( stripslashes( $params['query'] ), $chart_id, $params );
1607 1354 $source->fetch( false );
1608 1355 $error = $source->get_error();
1609 1356 if ( empty( $error ) ) {
1610 - update_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY, stripslashes( $query ) );
1357 + update_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY, stripslashes( $params['query'] ) );
1611 1358 update_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
1612 1359 update_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
1613 1360 update_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, $hours );
1614 1361 update_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
@@ -1637,9 +1384,9 @@
1637 1384 }
1638 1385 }
1639 1386 $render->render();
1640 1387 if ( ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ) ) {
1641 - ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) ? wp_die() : exit();
1388 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1642 1389 }
1643 1390 }
1644 1391
1645 1392
@@ -1664,9 +1411,9 @@
1664 1411
1665 1412 $hours = filter_input(
1666 1413 INPUT_POST,
1667 1414 'refresh',
1668 - FILTER_VALIDATE_FLOAT,
1415 + FILTER_VALIDATE_INT,
1669 1416 array(
1670 1417 'options' => array(
1671 1418 'min_range' => -1,
1672 1419 'max_range' => apply_filters( 'visualizer_is_business', false ) ? PHP_INT_MAX : -1,
@@ -1673,9 +1420,9 @@
1673 1420 ),
1674 1421 )
1675 1422 );
1676 1423
1677 - if ( ! is_numeric( $hours ) ) {
1424 + if ( 0 !== $hours && empty( $hours ) ) {
1678 1425 $hours = -1;
1679 1426 }
1680 1427
1681 1428 do_action( 'visualizer_save_filter', $chart_id, $hours );
@@ -1680,9 +1427,9 @@
1680 1427
1681 1428 do_action( 'visualizer_save_filter', $chart_id, $hours );
1682 1429
1683 1430 if ( ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ) ) {
1684 - ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) ? wp_die() : exit();
1431 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1685 1432 }
1686 1433 }
1687 1434
1688 1435 /**
@@ -1689,22 +1436,11 @@
1689 1436 * Save chart image.
1690 1437 *
1691 1438 * @param string $base64_img Chart image.
1692 1439 * @param int $chart_id Chart ID.
1693 - * @param bool $save_attachment Save attachment.
1694 1440 * @return attachment ID
1695 1441 */
1696 - public function save_chart_image( $base64_img, $chart_id, $save_attachment = true ) {
1697 - // Delete old chart image.
1698 - $old_attachment_id = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_IMAGE, true );
1699 - if ( $old_attachment_id ) {
1700 - wp_delete_attachment( $old_attachment_id, true );
1701 - }
1702 -
1703 - if ( ! $save_attachment ) {
1704 - return 0;
1705 - }
1706 -
1442 + public function save_chart_image( $base64_img, $chart_id ) {
1707 1443 // Upload dir.
1708 1444 $upload_dir = wp_upload_dir();
1709 1445 $upload_path = str_replace( '/', DIRECTORY_SEPARATOR, $upload_dir['path'] ) . DIRECTORY_SEPARATOR;
1710 1446
@@ -1714,16 +1450,18 @@
1714 1450 $filename = 'visualization-' . $chart_id . '.png';
1715 1451 $file_type = 'image/png';
1716 1452 $hashed_filename = $filename;
1717 1453
1454 + // Delete old chart image.
1455 + $old_attachment_id = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_IMAGE, true );
1456 + if ( $old_attachment_id ) {
1457 + wp_delete_attachment( $old_attachment_id, true );
1458 + }
1459 +
1718 1460 // Save the image in the uploads directory.
1719 1461 require_once ABSPATH . '/wp-admin/includes/file.php';
1720 1462 \WP_Filesystem();
1721 1463 global $wp_filesystem;
1722 - if ( ! is_a( $wp_filesystem, 'WP_Filesystem_Base' ) ) {
1723 - $creds = request_filesystem_credentials( site_url() );
1724 - wp_filesystem( $creds );
1725 - }
1726 1464 $upload_file = $wp_filesystem->put_contents( $upload_path . $hashed_filename, $decoded );
1727 1465
1728 1466 // Insert new chart image.
1729 1467 $attachment = array(