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.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 -366 4.0.53.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 );
@@ -169,12 +156,8 @@
169 156 */
170 157 public function getJsonRoots() {
171 158 check_ajax_referer( Visualizer_Plugin::ACTION_JSON_GET_ROOTS . Visualizer_Plugin::VERSION, 'security' );
172 159
173 - if ( ! current_user_can( 'edit_posts' ) ) {
174 - wp_send_json_error( array( 'msg' => esc_html__( 'You do not have permission to perform this action.', 'visualizer' ) ) );
175 - }
176 -
177 160 $params = wp_parse_args( $_POST['params'] );
178 161
179 162 $source = new Visualizer_Source_Json( $params );
180 163
@@ -195,12 +178,8 @@
195 178 */
196 179 public function getJsonData() {
197 180 check_ajax_referer( Visualizer_Plugin::ACTION_JSON_GET_DATA . Visualizer_Plugin::VERSION, 'security' );
198 181
199 - if ( ! current_user_can( 'edit_posts' ) ) {
200 - wp_send_json_error( array( 'msg' => esc_html__( 'You do not have permission to perform this action.', 'visualizer' ) ) );
201 - }
202 -
203 182 $params = wp_parse_args( $_POST['params'] );
204 183
205 184 $chart_id = $params['chart'];
206 185
@@ -266,16 +245,8 @@
266 245 if ( ! empty( $params['paging'] ) ) {
267 246 add_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_PAGING, $params['paging'] );
268 247 }
269 248
270 - if ( Visualizer_Module::is_pro() ) {
271 - if ( ! empty( $params['vz_woo_source'] ) ) {
272 - update_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_WOOCOMMERCE_SOURCE, $params['vz_woo_source'] );
273 - } else {
274 - delete_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_WOOCOMMERCE_SOURCE );
275 - }
276 - }
277 -
278 249 $time = filter_input(
279 250 INPUT_POST,
280 251 'time',
281 252 FILTER_VALIDATE_INT,
@@ -303,9 +274,9 @@
303 274 $render->data = json_encode( $source->getRawData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ) );
304 275 $render->series = json_encode( $source->getSeries() );
305 276 $render->render();
306 277
307 - ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) ? wp_die() : exit();
278 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
308 279 }
309 280
310 281
311 282 /**
@@ -381,13 +352,13 @@
381 352 * @since 1.0.0
382 353 *
383 354 * @access private
384 355 *
385 - * @param WP_Post|null $chart The chart object.
356 + * @param WP_Post $chart The chart object.
386 357 *
387 358 * @return array The array of chart data.
388 359 */
389 - private function _getChartArray( $chart = null ) {
360 + private function _getChartArray( WP_Post $chart = null ) {
390 361 if ( is_null( $chart ) ) {
391 362 $chart = $this->_chart;
392 363 }
393 364 $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
@@ -409,13 +380,8 @@
409 380 }
410 381
411 382 $date_formats = Visualizer_Source::get_date_formats_if_exists( $series, $data );
412 383
413 - $code = '';
414 - if ( 'd3' === $library ) {
415 - $code = get_post_meta( $chart->ID, Visualizer_Module_AIBuilder::CF_D3_CODE, true );
416 - }
417 -
418 384 return array(
419 385 'type' => $type,
420 386 'series' => $series,
421 387 'settings' => $settings,
@@ -420,9 +386,8 @@
420 386 'series' => $series,
421 387 'settings' => $settings,
422 388 'data' => $data,
423 389 'library' => $library,
424 - 'code' => $code,
425 390 'css' => $css,
426 391 'date_formats' => $date_formats,
427 392 );
428 393 }
@@ -439,9 +404,9 @@
439 404 public static function _sendResponse( $results ) {
440 405 header( 'Content-type: application/json' );
441 406 nocache_headers();
442 407 echo json_encode( $results );
443 - ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) ? wp_die() : exit();
408 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
444 409 }
445 410
446 411 /**
447 412 * Deletes a chart from database.
@@ -473,22 +438,9 @@
473 438 $success = $chart && $chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
474 439 }
475 440 }
476 441 if ( $success ) {
477 - global $sitepress;
478 - if ( Visualizer_Module::is_pro() && ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) ) {
479 - $trid = $sitepress->get_element_trid( $chart_id, 'post_' . Visualizer_Plugin::CPT_VISUALIZER );
480 - $translations = $sitepress->get_element_translations( $trid );
481 - if ( ! empty( $translations ) ) {
482 - foreach ( $translations as $translated_post ) {
483 - wp_delete_post( $translated_post->element_id, true );
484 - }
485 - } else {
486 - wp_delete_post( $chart_id, true );
487 - }
488 - } else {
489 - wp_delete_post( $chart_id, true );
490 - }
442 + wp_delete_post( $chart_id, true );
491 443 }
492 444 if ( $is_post ) {
493 445 self::_sendResponse(
494 446 array(
@@ -536,104 +488,48 @@
536 488 *
537 489 * @access public
538 490 */
539 491 public function renderChartPages() {
540 - if ( ! current_user_can( 'edit_posts' ) ) {
541 - wp_die( __( 'You do not have permission to access this page.', 'visualizer' ) );
542 - }
543 -
544 492 defined( 'IFRAME_REQUEST' ) || define( 'IFRAME_REQUEST', 1 );
545 - if ( ! defined( 'ET_BUILDER_PRODUCT_VERSION' ) && function_exists( 'et_get_theme_version' ) ) {
546 - define( 'ET_BUILDER_PRODUCT_VERSION', et_get_theme_version() );
547 - }
548 493 // Set current screen for the render chart.
549 494 set_current_screen( 'visualizer_render_chart' );
550 495 // check chart, if chart not exists, will create new one and redirects to the same page with proper chart id
551 496 $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
552 - if ( ! empty( $_POST ) ) {
553 - $_POST = map_deep( $_POST, 'wp_strip_all_tags' );
554 - }
555 - $chart = $chart_id ? get_post( $chart_id ) : null;
556 - if ( ! $chart_id || ! $chart || $chart->post_type !== Visualizer_Plugin::CPT_VISUALIZER ) {
557 - if ( empty( $_GET['lang'] ) || empty( $_GET['parent_chart_id'] ) ) {
558 - $this->deleteOldCharts();
559 - $default_type = isset( $_GET['type'] ) && ! empty( $_GET['type'] ) ? $_GET['type'] : 'line';
560 - $chart_status = Visualizer_Module_Admin::checkChartStatus( $default_type );
561 - if ( ! $chart_status ) {
562 - $default_type = 'line';
563 - }
564 - $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $default_type . '.csv' );
565 - $source->fetch();
566 - $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,
567 520 array(
568 - 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
569 - 'post_title' => 'Visualization',
570 - 'post_author' => get_current_user_id(),
571 - 'post_status' => 'auto-draft',
572 - 'post_content' => $source->getData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ),
521 + 'focusTarget' => 'datum',
573 522 )
574 523 );
575 - if ( $chart_id && ! is_wp_error( $chart_id ) ) {
576 - add_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, $default_type );
577 - add_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 1 );
578 - add_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
579 - add_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
580 - add_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_LIBRARY, '' );
581 - add_post_meta(
582 - $chart_id,
583 - Visualizer_Plugin::CF_SETTINGS,
584 - array(
585 - 'focusTarget' => 'datum',
586 - )
587 - );
588 -
589 - do_action( 'visualizer_pro_new_chart_defaults', $chart_id );
590 - }
591 - } else {
592 - $parent_chart_id = filter_var( $_GET['parent_chart_id'], FILTER_VALIDATE_INT );
593 - $success = false;
594 - if ( $parent_chart_id ) {
595 - $parent_chart = get_post( $parent_chart_id );
596 - $success = $parent_chart && $parent_chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
597 - }
598 - if ( $success ) {
599 - $new_chart_id = wp_insert_post(
600 - array(
601 - 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
602 - 'post_title' => 'Visualization',
603 - 'post_author' => get_current_user_id(),
604 - 'post_status' => $parent_chart->post_status,
605 - 'post_content' => $parent_chart->post_content,
606 - )
607 - );
608 -
609 - if ( is_wp_error( $new_chart_id ) ) {
610 - 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__ );
611 - } else {
612 - $post_meta = get_post_meta( $parent_chart_id );
613 - $chart_id = $new_chart_id;
614 - foreach ( $post_meta as $key => $value ) {
615 - if ( strpos( $key, 'visualizer-' ) !== false ) {
616 - add_post_meta( $new_chart_id, $key, maybe_unserialize( $value[0] ) );
617 - }
618 - }
619 - }
620 - }
621 524 do_action( 'visualizer_pro_new_chart_defaults', $chart_id );
622 525 }
623 - wp_redirect( esc_url_raw( add_query_arg( 'chart', (int) $chart_id ) ) );
624 -
625 - if ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) {
626 - wp_die();
627 - }
628 - exit();
526 + wp_redirect( add_query_arg( 'chart', (int) $chart_id ) );
527 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
629 528 }
630 529
631 - $_POST['save_chart_image'] = isset( $_POST['save_chart_image'] ) && 'yes' === $_POST['save_chart_image'] ? true : false;
632 - $_POST['lazy_load_chart'] = isset( $_POST['lazy_load_chart'] ) && 'yes' === $_POST['lazy_load_chart'] ? true : false;
633 -
634 530 if ( isset( $_POST['chart-img'] ) && ! empty( $_POST['chart-img'] ) ) {
635 - $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 );
636 532 if ( $attachment_id ) {
637 533 update_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_IMAGE, $attachment_id );
638 534 }
639 535 }
@@ -699,16 +595,8 @@
699 595 // if the edit button is clicked.
700 596 $this->_chart = $this->handleExistingRevisions( $chart_id, $this->_chart );
701 597 }
702 598
703 - // Clear existing chart cache.
704 - if ( isset( $_POST['save'] ) && 1 === intval( $_POST['save'] ) ) {
705 - $cache_key = Visualizer_Plugin::CF_CHART_CACHE . '_' . $chart_id;
706 - if ( get_transient( $cache_key ) ) {
707 - delete_transient( $cache_key );
708 - }
709 - }
710 -
711 599 switch ( $tab ) {
712 600 case 'settings':
713 601 $this->_handleDataAndSettingsPage();
714 602 break;
@@ -719,9 +607,9 @@
719 607 default:
720 608 // this should never happen.
721 609 break;
722 610 }
723 - ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) ? wp_die() : exit();
611 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
724 612 }
725 613
726 614 /**
727 615 * Load code editor assets.
@@ -733,9 +621,9 @@
733 621
734 622 // data tables assets.
735 623 wp_register_script( 'visualizer-datatables', VISUALIZER_ABSURL . 'js/lib/datatables.min.js', array( 'jquery-ui-core' ), Visualizer_Plugin::VERSION );
736 624 wp_register_style( 'visualizer-datatables', VISUALIZER_ABSURL . 'css/lib/datatables.min.css', array(), Visualizer_Plugin::VERSION );
737 - 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 );
738 626 wp_enqueue_script( 'visualizer-datatables' );
739 627 wp_enqueue_style( 'visualizer-jquery-ui' );
740 628
741 629 if ( ! Visualizer_Module::is_pro() ) {
@@ -751,9 +639,9 @@
751 639 wp_register_script( 'visualizer-codemirror-matchbrackets', '//codemirror.net/addon/edit/matchbrackets.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
752 640 wp_register_script( 'visualizer-codemirror-closebrackets', '//codemirror.net/addon/edit/closebrackets.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
753 641 wp_register_script( 'visualizer-codemirror-sql', '//codemirror.net/mode/sql/sql.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
754 642 wp_register_script( 'visualizer-codemirror-sql-hint', '//codemirror.net/addon/hint/sql-hint.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
755 - 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 );
756 644 wp_register_style( 'visualizer-codemirror-core', '//codemirror.net/lib/codemirror.css', array(), Visualizer_Plugin::VERSION );
757 645 wp_register_style( 'visualizer-codemirror-hint', '//codemirror.net/addon/hint/show-hint.css', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
758 646
759 647 wp_enqueue_script( 'visualizer-codemirror-hint' );
@@ -767,9 +655,9 @@
767 655 'lineWrapping' => true,
768 656 'dragDrop' => false,
769 657 'matchBrackets' => true,
770 658 'autoCloseBrackets' => true,
771 - 'extraKeys' => array( 'Shift-Space' => 'autocomplete' ),
659 + 'extraKeys' => array( 'Ctrl-Space' => 'autocomplete' ),
772 660 'hintOptions' => array( 'tables' => $table_col_mapping ),
773 661 ),
774 662 )
775 663 );
@@ -803,12 +691,9 @@
803 691 update_option( 'visualizer-map-api-key', $_POST['map_api_key'] );
804 692 }
805 693
806 694 if ( $_SERVER['REQUEST_METHOD'] === 'POST' && isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'] ) ) {
807 - $is_canceled = isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] );
808 - $is_newly_created = $this->_chart->post_status === 'auto-draft';
809 -
810 - if ( $is_newly_created && ! $is_canceled ) {
695 + if ( $this->_chart->post_status === 'auto-draft' ) {
811 696 $this->_chart->post_status = 'publish';
812 697
813 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.
814 699 // we do not want any difference in data so disable revisions temporarily.
@@ -816,15 +701,10 @@
816 701
817 702 wp_update_post( $this->_chart->to_array() );
818 703 }
819 704 // save meta data only when it is NOT being canceled.
820 - if ( ! $is_canceled ) {
821 - $post_settings = $_POST;
822 - $existing = get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
823 - if ( isset( $existing['colors'] ) && is_array( $existing['colors'] ) && ! isset( $post_settings['colors'] ) ) {
824 - $post_settings['colors'] = $existing['colors'];
825 - }
826 - 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 );
827 707
828 708 // we will keep a parameter called 'internal_title' that will be set to the given title or, if empty, the chart ID
829 709 // this will help in searching with the chart id.
830 710 $settings = get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
@@ -838,14 +718,8 @@
838 718 if ( empty( $title ) ) {
839 719 $title = $this->_chart->ID;
840 720 }
841 721 $settings['internal_title'] = $title;
842 - $settings_label = isset( $settings['pieResidueSliceLabel'] ) ? $settings['pieResidueSliceLabel'] : '';
843 - if ( empty( $settings_label ) ) {
844 - $settings['pieResidueSliceLabel'] = esc_html__( 'Other', 'visualizer' );
845 - } else {
846 - $settings['pieResidueSliceLabel'] = $settings_label;
847 - }
848 722 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $settings );
849 723 }
850 724 $render = new Visualizer_Render_Page_Send();
851 725 $render->text = sprintf( '[visualizer id="%d"]', $this->_chart->ID );
@@ -871,9 +745,8 @@
871 745 wp_enqueue_style( 'visualizer-frame' );
872 746 wp_enqueue_script( 'visualizer-preview' );
873 747 wp_enqueue_script( 'visualizer-chosen' );
874 748 wp_enqueue_script( 'visualizer-render' );
875 - wp_enqueue_code_editor( array( 'type' => 'application/json' ) );
876 749
877 750 if ( Visualizer_Module::can_show_feature( 'simple-editor' ) ) {
878 751 wp_enqueue_script( 'visualizer-editor-simple' );
879 752 wp_localize_script(
@@ -881,10 +754,12 @@
881 754 'visualizer1',
882 755 array(
883 756 'ajax' => array(
884 757 'url' => admin_url( 'admin-ajax.php' ),
885 - 'nonces' => array(),
886 - 'actions' => array(),
758 + 'nonces' => array(
759 + ),
760 + 'actions' => array(
761 + ),
887 762 ),
888 763 )
889 764 );
890 765 }
@@ -895,15 +770,13 @@
895 770 'visualizer-render',
896 771 'visualizer',
897 772 array(
898 773 'l10n' => array(
899 - 'invalid_source' => esc_html__( 'The URL you entered is invalid. Please enter a valid URL.', 'visualizer' ),
900 - 'loading' => esc_html__( 'Loading...', 'visualizer' ),
901 - 'json_error' => esc_html__( 'An error occured in fetching data.', 'visualizer' ),
902 - 'select_columns' => esc_html__( 'Please select a few columns to include in the chart.', 'visualizer' ),
903 - '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' ),
904 - 'copied' => __( 'The data has been copied to your clipboard. Hit Ctrl-V/Cmd-V in your spreadsheet editor to paste the data.', 'visualizer' ),
905 - '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' ),
906 779 ),
907 780 'charts' => array(
908 781 'canvas' => $data,
909 782 'id' => $this->_chart->ID,
@@ -934,9 +807,8 @@
934 807 'page_type' => 'chart',
935 808 'json_tag_separator' => Visualizer_Source_Json::TAG_SEPARATOR,
936 809 'json_tag_separator_view' => Visualizer_Source_Json::TAG_SEPARATOR_VIEW,
937 810 'is_front' => false,
938 - 'rest_base' => get_rest_url( null, 'wc/v3/reports/' ),
939 811 )
940 812 );
941 813
942 814 $render = new Visualizer_Render_Page_Data();
@@ -947,10 +819,11 @@
947 819 if ( filter_input( INPUT_GET, 'library', FILTER_VALIDATE_BOOLEAN ) ) {
948 820 $render->button = filter_input( INPUT_GET, 'action' ) === Visualizer_Plugin::ACTION_EDIT_CHART
949 821 ? esc_html__( 'Save Chart', 'visualizer' )
950 822 : esc_html__( 'Create Chart', 'visualizer' );
951 -
952 - $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 + }
953 826 } else {
954 827 $render->button = esc_attr__( 'Insert Chart', 'visualizer' );
955 828 }
956 829
@@ -973,12 +846,12 @@
973 846 * @access private
974 847 */
975 848 private function _handleTypesPage() {
976 849 // process post request
977 - 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' ) ) ) {
978 851 $type = filter_input( INPUT_POST, 'type' );
979 852 $library = filter_input( INPUT_POST, 'chart-library' );
980 - if ( Visualizer_Module_Admin::checkChartStatus( $type ) ) {
853 + if ( in_array( $type, Visualizer_Plugin::getChartTypes(), true ) ) {
981 854 if ( empty( $library ) ) {
982 855 // library cannot be empty.
983 856 do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, 'Chart library empty while creating the chart! Aborting...', 'error', __FILE__, __LINE__ );
984 857 return;
@@ -999,9 +872,9 @@
999 872 Visualizer_Module_Utility::set_defaults( $this->_chart );
1000 873
1001 874 // redirect to next tab
1002 875 // changed by Ash/Upwork
1003 - wp_redirect( esc_url_raw( add_query_arg( 'tab', 'settings' ) ) );
876 + wp_redirect( add_query_arg( 'tab', 'settings' ) );
1004 877
1005 878 return;
1006 879 }
1007 880 }
@@ -1030,80 +903,8 @@
1030 903 * Processes the CSV that is sent in the request as a string.
1031 904 *
1032 905 * @since 3.2.0
1033 906 */
1034 - /**
1035 - * Determines whether a remote URL serves an XLSX file.
1036 - *
1037 - * Used as a fallback when the URL path has no recognisable file extension
1038 - * (e.g. SharePoint, signed S3 URLs, or "download?id=…" endpoints).
1039 - *
1040 - * Uses wp_safe_remote_get() to block requests to private/loopback addresses,
1041 - * and streams the response to a temp file so no body data is held in memory
1042 - * regardless of whether the server honours the Range header.
1043 - *
1044 - * The check relies on the ZIP magic number (PK\x03\x04) that every XLSX
1045 - * file begins with, making it immune to misleading Content-Type headers
1046 - * such as application/octet-stream. Content-Type is used as a last-resort
1047 - * fallback only when the temp file is empty (e.g. a HEAD-only server).
1048 - *
1049 - * @access private
1050 - * @param string $url The remote URL to probe.
1051 - * @return bool TRUE if the file appears to be XLSX, FALSE otherwise.
1052 - */
1053 - private static function _url_is_xlsx( $url ) {
1054 - $tmpfile = wp_tempnam( 'visualizer_xlsx_probe' );
1055 - if ( ! $tmpfile ) {
1056 - return false;
1057 - }
1058 -
1059 - $response = wp_safe_remote_get(
1060 - $url,
1061 - array(
1062 - 'timeout' => 10,
1063 - 'user-agent' => 'WordPress/' . get_bloginfo( 'version' ),
1064 - 'headers' => array( 'Range' => 'bytes=0-3' ),
1065 - 'stream' => true,
1066 - 'filename' => $tmpfile,
1067 - )
1068 - );
1069 -
1070 - if ( is_wp_error( $response ) ) {
1071 - @unlink( $tmpfile ); // phpcs:ignore WordPress.PHP.NoSilencedErrors
1072 - return false;
1073 - }
1074 -
1075 - $magic = '';
1076 - // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen
1077 - $fh = @fopen( $tmpfile, 'rb' ); // phpcs:ignore WordPress.PHP.NoSilencedErrors
1078 - if ( $fh ) {
1079 - $magic = fread( $fh, 4 ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fread
1080 - fclose( $fh ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
1081 - }
1082 - @unlink( $tmpfile ); // phpcs:ignore WordPress.PHP.NoSilencedErrors
1083 -
1084 - if ( strlen( $magic ) >= 4 ) {
1085 - // XLSX (and all ZIP-based Office formats) start with PK\x03\x04.
1086 - return $magic === "PK\x03\x04";
1087 - }
1088 -
1089 - // Last resort: server returned an empty body (e.g. ignored Range and
1090 - // returned only headers). Check Content-Type from the same response.
1091 - // application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
1092 - return false !== strpos(
1093 - wp_remote_retrieve_header( $response, 'content-type' ),
1094 - 'spreadsheetml'
1095 - );
1096 - }
1097 -
1098 - /**
1099 - * Parses a raw CSV string or editor payload and returns a source object.
1100 - *
1101 - * @access private
1102 - * @param string $data The raw CSV data string.
1103 - * @param string $editor_type The editor type ('text' or 'tabular').
1104 - * @return Visualizer_Source|null The populated source object, or null on failure.
1105 - */
1106 907 private function handleCSVasString( $data, $editor_type ) {
1107 908 $source = null;
1108 909
1109 910 switch ( $editor_type ) {
@@ -1118,9 +919,9 @@
1118 919 continue;
1119 920 }
1120 921 $row = explode( ',', $row );
1121 922 $row = array_map(
1122 - function ( $r ) {
923 + function( $r ) {
1123 924 return '' === $r ? ' ' : $r;
1124 925 },
1125 926 $row
1126 927 );
@@ -1169,9 +970,9 @@
1169 970 foreach ( $types as $type ) {
1170 971 if ( empty( $type ) ) {
1171 972 $exclude[] = $index;
1172 973 }
1173 - ++$index;
974 + $index++;
1174 975 }
1175 976
1176 977 // when N headers are being renamed, the number of headers increases by N
1177 978 // because of the way datatable duplicates header information
@@ -1231,13 +1032,9 @@
1231 1032 // otherwise, assume this is a normal web request.
1232 1033 $can_die = ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE );
1233 1034
1234 1035 // validate nonce
1235 - if (
1236 - ! isset( $_GET['nonce'] ) ||
1237 - ! wp_verify_nonce( $_GET['nonce'], 'visualizer-upload-data' ) ||
1238 - ! current_user_can( 'edit_posts' )
1239 - ) {
1036 + if ( ! isset( $_GET['nonce'] ) || ! wp_verify_nonce( $_GET['nonce'] ) ) {
1240 1037 if ( ! $can_die ) {
1241 1038 return;
1242 1039 }
1243 1040 status_header( 403 );
@@ -1246,15 +1043,9 @@
1246 1043
1247 1044 // check chart, if chart exists
1248 1045 // do not use filter_input as it does not work for phpunit test cases, use filter_var instead
1249 1046 $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
1250 - $chart = $chart_id ? get_post( $chart_id ) : null;
1251 - if (
1252 - ! $chart_id ||
1253 - ! $chart ||
1254 - $chart->post_type !== Visualizer_Plugin::CPT_VISUALIZER ||
1255 - ! current_user_can( 'edit_post', $chart_id )
1256 - ) {
1047 + if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type !== Visualizer_Plugin::CPT_VISUALIZER ) {
1257 1048 if ( ! $can_die ) {
1258 1049 return;
1259 1050 }
1260 1051 status_header( 400 );
@@ -1295,30 +1086,16 @@
1295 1086 delete_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE );
1296 1087
1297 1088 $source = null;
1298 1089 $render = new Visualizer_Render_Page_Update();
1299 -
1300 - $remote_data = false;
1301 - if ( isset( $_POST['remote_data'] ) && function_exists( 'wp_http_validate_url' ) ) {
1302 - $remote_data = wp_http_validate_url( $_POST['remote_data'] );
1303 - }
1304 - if ( false !== $remote_data ) {
1305 - $remote_ext = strtolower( pathinfo( parse_url( $remote_data, PHP_URL_PATH ), PATHINFO_EXTENSION ) );
1306 - if ( 'xlsx' === $remote_ext || ( 'csv' !== $remote_ext && self::_url_is_xlsx( $remote_data ) ) ) {
1307 - $source = new Visualizer_Source_Xlsx_Remote( $remote_data );
1308 - } else {
1309 - $source = new Visualizer_Source_Csv_Remote( $remote_data );
1310 - }
1090 + if ( isset( $_POST['remote_data'] ) && filter_var( $_POST['remote_data'], FILTER_VALIDATE_URL ) ) {
1091 + $source = new Visualizer_Source_Csv_Remote( $_POST['remote_data'] );
1311 1092 if ( isset( $_POST['vz-import-time'] ) ) {
1312 - 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'] );
1313 1094 }
1314 - } elseif ( isset( $_FILES['local_data'] ) && $_FILES['local_data']['error'] === 0 ) {
1315 - $local_ext = strtolower( pathinfo( isset( $_FILES['local_data']['name'] ) ? $_FILES['local_data']['name'] : '', PATHINFO_EXTENSION ) );
1316 - if ( 'xlsx' === $local_ext ) {
1317 - $source = new Visualizer_Source_Xlsx( $_FILES['local_data']['tmp_name'] );
1318 - } else {
1319 - $source = new Visualizer_Source_Csv( $_FILES['local_data']['tmp_name'] );
1320 - }
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'] );
1321 1098 } elseif ( isset( $_POST['chart_data'] ) && strlen( $_POST['chart_data'] ) > 0 ) {
1322 1099 $source = $this->handleCSVasString( $_POST['chart_data'], $_POST['editor-type'] );
1323 1100 update_post_meta( $chart_id, Visualizer_Plugin::CF_EDITOR, $_POST['editor-type'] );
1324 1101 } elseif ( isset( $_POST['table_data'] ) && 'yes' === $_POST['table_data'] ) {
@@ -1325,10 +1102,10 @@
1325 1102 $source = $this->handleTabularData();
1326 1103 update_post_meta( $chart_id, Visualizer_Plugin::CF_EDITOR, $_POST['editor-type'] );
1327 1104 } else {
1328 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__ );
1329 - $render->message = esc_html__( 'No CSV file was received. Select a file and try uploading again.', 'visualizer' );
1330 - 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' ) );
1331 1108 }
1332 1109
1333 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__ );
1334 1111
@@ -1349,9 +1126,8 @@
1349 1126 if ( $populate ) {
1350 1127 $chart->post_content = $content;
1351 1128 }
1352 1129 wp_update_post( $chart->to_array() );
1353 -
1354 1130 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
1355 1131 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
1356 1132 update_post_meta( $chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
1357 1133
@@ -1359,17 +1135,8 @@
1359 1135
1360 1136 Visualizer_Module_Utility::set_defaults( $chart, null );
1361 1137
1362 1138 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
1363 - if ( isset( $settings['series'] ) && ! ( count( $settings['series'] ) - count( $source->getSeries() ) > 1 ) ) {
1364 - $diff_total_series = abs( count( $settings['series'] ) - count( $source->getSeries() ) );
1365 - if ( $diff_total_series ) {
1366 - foreach ( range( 1, $diff_total_series ) as $k => $diff_series ) {
1367 - $settings['series'][] = end( $settings['series'] );
1368 - }
1369 - update_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, $settings );
1370 - }
1371 - }
1372 1139
1373 1140 $render->id = $chart->ID;
1374 1141 $render->data = json_encode( $source->getRawData( get_post_meta( $chart->ID, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ) );
1375 1142 $render->series = json_encode( $source->getSeries() );
@@ -1376,9 +1143,9 @@
1376 1143 $render->settings = json_encode( $settings );
1377 1144 } else {
1378 1145 $error = $source->get_error();
1379 1146 if ( empty( $error ) ) {
1380 - $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' );
1381 1148 }
1382 1149 $render->message = $error;
1383 1150 do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( '%s for chart %d.', $error, $chart_id ), 'error', __FILE__, __LINE__ );
1384 1151 update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, $error );
@@ -1389,9 +1156,9 @@
1389 1156 $render->render();
1390 1157 if ( ! $can_die ) {
1391 1158 return;
1392 1159 }
1393 - ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) ? wp_die() : exit();
1160 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1394 1161 }
1395 1162
1396 1163 /**
1397 1164 * Clones the chart.
@@ -1430,26 +1197,23 @@
1430 1197 if ( strpos( $key, 'visualizer-' ) !== false ) {
1431 1198 add_post_meta( $new_chart_id, $key, maybe_unserialize( $value[0] ) );
1432 1199 }
1433 1200 }
1434 - $redirect = esc_url(
1435 - add_query_arg(
1436 - array(
1437 - 'page' => 'visualizer',
1438 - 'type' => filter_input( INPUT_GET, 'type' ),
1439 - 'vaction' => false,
1440 - ),
1441 - admin_url( 'admin.php' )
1201 + $redirect = add_query_arg(
1202 + array(
1203 + 'page' => 'visualizer',
1204 + 'type' => filter_input( INPUT_GET, 'type' ),
1205 + 'vaction' => false,
1442 1206 ),
1443 - null,
1444 - 'db'
1207 + admin_url( 'admin.php' )
1445 1208 );
1446 1209 }
1447 1210 }
1448 1211
1449 - if ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) {
1212 + if ( defined( 'WP_TESTS_DOMAIN' ) ) {
1450 1213 wp_die();
1451 1214 }
1215 +
1452 1216 wp_redirect( $redirect );
1453 1217 exit;
1454 1218 }
1455 1219
@@ -1480,9 +1244,9 @@
1480 1244 }
1481 1245 }
1482 1246 }
1483 1247
1484 - ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) ? wp_die() : exit();
1248 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1485 1249 }
1486 1250
1487 1251 /**
1488 1252 * Handles chart data page.
@@ -1506,11 +1270,10 @@
1506 1270 'visualizer-render',
1507 1271 'visualizer',
1508 1272 array(
1509 1273 'l10n' => array(
1510 - 'invalid_source' => esc_html__( 'The URL you entered is invalid. Please enter a valid URL.', 'visualizer' ),
1511 - 'loading' => esc_html__( 'Loading...', 'visualizer' ),
1512 - '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' ),
1513 1276 ),
1514 1277 'charts' => array(
1515 1278 'canvas' => $data,
1516 1279 ),
@@ -1536,24 +1299,12 @@
1536 1299 */
1537 1300 public function getQueryData() {
1538 1301 check_ajax_referer( Visualizer_Plugin::ACTION_FETCH_DB_DATA . Visualizer_Plugin::VERSION, 'security' );
1539 1302
1540 - if ( ! current_user_can( 'administrator' ) ) {
1541 - wp_send_json_error( array( 'msg' => __( 'Action not allowed for this user.', 'visualizer' ) ) );
1542 - }
1543 - if ( ! is_super_admin() ) {
1544 - wp_send_json_error( array( 'msg' => __( 'Action not allowed for this user.', 'visualizer' ) ) );
1545 - }
1546 -
1547 - if ( ! Visualizer_Module::is_pro() ) {
1548 - wp_send_json_error( array( 'msg' => __( 'Feature is not available.', 'visualizer' ) ) );
1549 - }
1550 -
1551 1303 $params = wp_parse_args( $_POST['params'] );
1552 1304 $chart_id = filter_var( $params['chart_id'], FILTER_VALIDATE_INT );
1553 - $query = trim( $params['query'], ';' );
1554 1305
1555 - $source = new Visualizer_Source_Query( stripslashes( $query ), $chart_id, $params );
1306 + $source = new Visualizer_Source_Query( stripslashes( $params['query'] ), $chart_id, $params );
1556 1307 $html = $source->fetch( true );
1557 1308 $error = $source->get_error();
1558 1309 if ( ! empty( $error ) ) {
1559 1310 wp_send_json_error( array( 'msg' => $error ) );
@@ -1568,19 +1319,8 @@
1568 1319 */
1569 1320 public function saveQuery() {
1570 1321 check_ajax_referer( Visualizer_Plugin::ACTION_SAVE_DB_QUERY . Visualizer_Plugin::VERSION, 'security' );
1571 1322
1572 - if ( ! current_user_can( 'administrator' ) ) {
1573 - wp_send_json_error( array( 'msg' => __( 'Action not allowed for this user.', 'visualizer' ) ) );
1574 - }
1575 - if ( ! is_super_admin() ) {
1576 - wp_send_json_error( array( 'msg' => __( 'Action not allowed for this user.', 'visualizer' ) ) );
1577 - }
1578 -
1579 - if ( ! Visualizer_Module::is_pro() ) {
1580 - wp_send_json_error( array( 'msg' => __( 'Feature is not available.', 'visualizer' ) ) );
1581 - }
1582 -
1583 1323 $chart_id = filter_input(
1584 1324 INPUT_GET,
1585 1325 'chart',
1586 1326 FILTER_VALIDATE_INT,
@@ -1593,9 +1333,9 @@
1593 1333
1594 1334 $hours = filter_input(
1595 1335 INPUT_POST,
1596 1336 'refresh',
1597 - FILTER_VALIDATE_FLOAT,
1337 + FILTER_VALIDATE_INT,
1598 1338 array(
1599 1339 'options' => array(
1600 1340 'min_range' => -1,
1601 1341 'max_range' => apply_filters( 'visualizer_is_business', false ) ? PHP_INT_MAX : -1,
@@ -1602,9 +1342,9 @@
1602 1342 ),
1603 1343 )
1604 1344 );
1605 1345
1606 - if ( ! is_numeric( $hours ) ) {
1346 + if ( ! is_int( $hours ) ) {
1607 1347 $hours = -1;
1608 1348 }
1609 1349
1610 1350 $render = new Visualizer_Render_Page_Update();
@@ -1609,14 +1349,13 @@
1609 1349
1610 1350 $render = new Visualizer_Render_Page_Update();
1611 1351 if ( $chart_id ) {
1612 1352 $params = wp_parse_args( $_POST['params'] );
1613 - $query = trim( $params['query'], ';' );
1614 - $source = new Visualizer_Source_Query( stripslashes( $query ), $chart_id, $params );
1353 + $source = new Visualizer_Source_Query( stripslashes( $params['query'] ), $chart_id, $params );
1615 1354 $source->fetch( false );
1616 1355 $error = $source->get_error();
1617 1356 if ( empty( $error ) ) {
1618 - 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'] ) );
1619 1358 update_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
1620 1359 update_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
1621 1360 update_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, $hours );
1622 1361 update_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
@@ -1645,9 +1384,9 @@
1645 1384 }
1646 1385 }
1647 1386 $render->render();
1648 1387 if ( ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ) ) {
1649 - ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) ? wp_die() : exit();
1388 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1650 1389 }
1651 1390 }
1652 1391
1653 1392
@@ -1672,9 +1411,9 @@
1672 1411
1673 1412 $hours = filter_input(
1674 1413 INPUT_POST,
1675 1414 'refresh',
1676 - FILTER_VALIDATE_FLOAT,
1415 + FILTER_VALIDATE_INT,
1677 1416 array(
1678 1417 'options' => array(
1679 1418 'min_range' => -1,
1680 1419 'max_range' => apply_filters( 'visualizer_is_business', false ) ? PHP_INT_MAX : -1,
@@ -1681,9 +1420,9 @@
1681 1420 ),
1682 1421 )
1683 1422 );
1684 1423
1685 - if ( ! is_numeric( $hours ) ) {
1424 + if ( 0 !== $hours && empty( $hours ) ) {
1686 1425 $hours = -1;
1687 1426 }
1688 1427
1689 1428 do_action( 'visualizer_save_filter', $chart_id, $hours );
@@ -1688,9 +1427,9 @@
1688 1427
1689 1428 do_action( 'visualizer_save_filter', $chart_id, $hours );
1690 1429
1691 1430 if ( ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ) ) {
1692 - ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) ? wp_die() : exit();
1431 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1693 1432 }
1694 1433 }
1695 1434
1696 1435 /**
@@ -1697,22 +1436,11 @@
1697 1436 * Save chart image.
1698 1437 *
1699 1438 * @param string $base64_img Chart image.
1700 1439 * @param int $chart_id Chart ID.
1701 - * @param bool $save_attachment Save attachment.
1702 1440 * @return attachment ID
1703 1441 */
1704 - public function save_chart_image( $base64_img, $chart_id, $save_attachment = true ) {
1705 - // Delete old chart image.
1706 - $old_attachment_id = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_IMAGE, true );
1707 - if ( $old_attachment_id ) {
1708 - wp_delete_attachment( $old_attachment_id, true );
1709 - }
1710 -
1711 - if ( ! $save_attachment ) {
1712 - return 0;
1713 - }
1714 -
1442 + public function save_chart_image( $base64_img, $chart_id ) {
1715 1443 // Upload dir.
1716 1444 $upload_dir = wp_upload_dir();
1717 1445 $upload_path = str_replace( '/', DIRECTORY_SEPARATOR, $upload_dir['path'] ) . DIRECTORY_SEPARATOR;
1718 1446
@@ -1722,16 +1450,18 @@
1722 1450 $filename = 'visualization-' . $chart_id . '.png';
1723 1451 $file_type = 'image/png';
1724 1452 $hashed_filename = $filename;
1725 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 +
1726 1460 // Save the image in the uploads directory.
1727 1461 require_once ABSPATH . '/wp-admin/includes/file.php';
1728 1462 \WP_Filesystem();
1729 1463 global $wp_filesystem;
1730 - if ( ! is_a( $wp_filesystem, 'WP_Filesystem_Base' ) ) {
1731 - $creds = request_filesystem_credentials( site_url() );
1732 - wp_filesystem( $creds );
1733 - }
1734 1464 $upload_file = $wp_filesystem->put_contents( $upload_path . $hashed_filename, $decoded );
1735 1465
1736 1466 // Insert new chart image.
1737 1467 $attachment = array(