PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.4.0
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.4.0
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 +181 -43 3.3.43.4.0 View file →
@@ -68,11 +68,39 @@
68 68 $this->_addAjaxAction( Visualizer_Plugin::ACTION_JSON_SET_SCHEDULE, 'setJsonSchedule' );
69 69
70 70 $this->_addAjaxAction( Visualizer_Plugin::ACTION_SAVE_FILTER_QUERY, 'saveFilter' );
71 71
72 + $this->_addFilter( 'visualizer_get_sidebar', 'getSidebar', 10, 2 );
73 +
72 74 }
73 75
74 76 /**
77 + * Generates the HTML of the sidebar for the chart.
78 + *
79 + * @since ?
80 + *
81 + * @access public
82 + */
83 + public function getSidebar( $sidebar, $chart_id ) {
84 + $chart = get_post( $chart_id );
85 + $data = $this->_getChartArray( $chart );
86 + $sidebar = '';
87 + $sidebar_class = $this->load_chart_class_name( $chart_id );
88 + if ( class_exists( $sidebar_class, true ) ) {
89 + $sidebar = new $sidebar_class( $data['settings'] );
90 + $sidebar->__series = $data['series'];
91 + $sidebar->__data = $data['data'];
92 + } else {
93 + $sidebar = apply_filters( 'visualizer_pro_chart_type_sidebar', '', $data );
94 + if ( $sidebar !== '' ) {
95 + $sidebar->__series = $data['series'];
96 + $sidebar->__data = $data['data'];
97 + }
98 + }
99 + return str_replace( "'", '"', $sidebar->__toString() );
100 + }
101 +
102 + /**
75 103 * Sets the schedule for how JSON-endpoint charts should be updated.
76 104 *
77 105 * @since ?
78 106 *
@@ -155,10 +183,11 @@
155 183 wp_die();
156 184 }
157 185
158 186 $source = new Visualizer_Source_Json( $params );
187 + $source->fetch();
188 + $data = $source->getRawData();
159 189
160 - $data = $source->parse();
161 190 if ( empty( $data ) ) {
162 191 wp_send_json_error( array( 'msg' => esc_html__( 'Unable to fetch data from the endpoint. Please try again.', 'visualizer' ) ) );
163 192 }
164 193
@@ -185,9 +214,9 @@
185 214
186 215 $chart = get_post( $chart_id );
187 216
188 217 $source = new Visualizer_Source_Json( $params );
189 - $source->fetch();
218 + $source->fetchFromEditableTable();
190 219
191 220 $content = $source->getData();
192 221 $chart->post_content = $content;
193 222 wp_update_post( $chart->to_array() );
@@ -195,13 +224,47 @@
195 224 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
196 225 update_post_meta( $chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
197 226 update_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_URL, $params['url'] );
198 227 update_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_ROOT, $params['root'] );
228 +
229 + delete_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_HEADERS );
230 + $headers = array( 'method' => $params['method'] );
231 + if ( ! empty( $params['auth'] ) ) {
232 + $headers['auth'] = $params['auth'];
233 + } elseif ( ! empty( $params['username'] ) && ! empty( $params['password'] ) ) {
234 + $headers['auth'] = array( 'username' => $params['username'], 'password' => $params['password'] );
235 + }
236 +
237 + add_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_HEADERS, $headers );
238 +
199 239 delete_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_PAGING );
200 240 if ( ! empty( $params['paging'] ) ) {
201 241 add_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_PAGING, $params['paging'] );
202 242 }
203 243
244 + $time = filter_input(
245 + INPUT_POST,
246 + 'time',
247 + FILTER_VALIDATE_INT,
248 + array(
249 + 'options' => array(
250 + 'min_range' => -1,
251 + ),
252 + )
253 + );
254 +
255 + delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE );
256 +
257 + if ( -1 < $time ) {
258 + add_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE, $time );
259 + }
260 +
261 + // delete other source specific parameters.
262 + delete_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY );
263 + delete_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE );
264 + delete_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_URL );
265 + delete_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_SCHEDULE );
266 +
204 267 $render = new Visualizer_Render_Page_Update();
205 268 $render->id = $chart->ID;
206 269 $render->data = json_encode( $source->getRawData() );
207 270 $render->series = json_encode( $source->getSeries() );
@@ -536,9 +599,9 @@
536 599
537 600 /**
538 601 * Load code editor assets.
539 602 */
540 - private function loadCodeEditorAssets() {
603 + private function loadCodeEditorAssets( $chart_id ) {
541 604 global $wp_version;
542 605
543 606 $wp_scripts = wp_scripts();
544 607
@@ -552,9 +615,9 @@
552 615 if ( ! Visualizer_Module::is_pro() ) {
553 616 return;
554 617 }
555 618
556 - $table_col_mapping = Visualizer_Source_Query_Params::get_all_db_tables_column_mapping();
619 + $table_col_mapping = Visualizer_Source_Query_Params::get_all_db_tables_column_mapping( $chart_id );
557 620
558 621 if ( version_compare( $wp_version, '4.9.0', '<' ) ) {
559 622 // code mirror assets.
560 623 wp_register_script( 'visualizer-codemirror-core', '//codemirror.net/lib/codemirror.js', array( 'jquery' ), Visualizer_Plugin::VERSION );
@@ -651,9 +714,9 @@
651 714 wp_enqueue_script( 'visualizer-preview' );
652 715 wp_enqueue_script( 'visualizer-chosen' );
653 716 wp_enqueue_script( 'visualizer-render' );
654 717
655 - if ( ! Visualizer_Module::is_pro() ) {
718 + if ( Visualizer_Module::can_show_feature( 'simple-editor' ) ) {
656 719 wp_enqueue_script( 'visualizer-editor-simple' );
657 720 wp_localize_script(
658 721 'visualizer-editor-simple',
659 722 'visualizer1',
@@ -668,9 +731,9 @@
668 731 )
669 732 );
670 733 }
671 734
672 - $table_col_mapping = $this->loadCodeEditorAssets();
735 + $table_col_mapping = $this->loadCodeEditorAssets( $this->_chart->ID );
673 736
674 737 wp_localize_script(
675 738 'visualizer-render',
676 739 'visualizer',
@@ -675,11 +738,12 @@
675 738 'visualizer-render',
676 739 'visualizer',
677 740 array(
678 741 'l10n' => array(
679 - 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ),
742 + 'invalid_source' => esc_html__( 'You have entered an invalid URL. Please provide a valid URL.', 'visualizer' ),
680 743 'loading' => esc_html__( 'Loading...', 'visualizer' ),
681 744 'json_error' => esc_html__( 'An error occured in fetching data.', 'visualizer' ),
745 + 'select_columns' => esc_html__( 'Please select a few columns to include in the chart.', 'visualizer' ),
682 746 ),
683 747 'charts' => array(
684 748 'canvas' => $data,
685 749 'id' => $this->_chart->ID,
@@ -729,13 +793,13 @@
729 793 } else {
730 794 $render->button = esc_attr__( 'Insert Chart', 'visualizer' );
731 795 }
732 796
733 - do_action( 'visualizer_enqueue_scripts_and_styles', $data );
797 + do_action( 'visualizer_enqueue_scripts_and_styles', $data, $this->_chart->ID );
734 798
735 799 if ( Visualizer_Module::is_pro() && Visualizer_Module::is_pro_older_than( '1.9.0' ) ) {
736 800 global $Visualizer_Pro;
737 - $Visualizer_Pro->_enqueueScriptsAndStyles( $data );
801 + $Visualizer_Pro->_enqueueScriptsAndStyles( $data, $this->_chart->ID );
738 802 }
739 803
740 804 $this->_addAction( 'admin_head', 'renderFlattrScript' );
741 805 wp_iframe( array( $render, 'render' ) );
@@ -806,30 +870,39 @@
806 870 * Processes the CSV that is sent in the request as a string.
807 871 *
808 872 * @since 3.2.0
809 873 */
810 - private function handleCSVasString( $data ) {
874 + private function handleCSVasString( $data, $editor_type ) {
811 875 $source = null;
812 876
813 - // @issue https://github.com/Codeinwp/visualizer/issues/412
814 - if ( has_filter( 'visualizer_pro_handle_chart_data' ) ) {
815 - $source = apply_filters( 'visualizer_pro_handle_chart_data', $data, '' );
816 - } else {
817 - // data coming in from the text editor.
818 - $tmpfile = tempnam( get_temp_dir(), Visualizer_Plugin::NAME );
819 - $handle = fopen( $tmpfile, 'w' );
820 - $values = preg_split( '/[\n\r]+/', stripslashes( trim( $data ) ) );
821 - if ( $values ) {
822 - foreach ( $values as $row ) {
823 - if ( empty( $row ) ) {
824 - continue;
877 + switch ( $editor_type ) {
878 + case 'text':
879 + // data coming in from the text editor.
880 + $tmpfile = tempnam( get_temp_dir(), Visualizer_Plugin::NAME );
881 + $handle = fopen( $tmpfile, 'w' );
882 + $values = preg_split( '/[\n\r]+/', stripslashes( trim( $data ) ) );
883 + if ( $values ) {
884 + foreach ( $values as $row ) {
885 + if ( empty( $row ) ) {
886 + continue;
887 + }
888 + // don't use fpucsv here because we need to just dump the data
889 + // minus the empty rows
890 + // and if any row contains ' or ", fputcsv will mess it up
891 + // because fputcsv needs to tokenize
892 + // and let's standardize the CSV enclosure
893 + $row = str_replace( "'", VISUALIZER_CSV_ENCLOSURE, $row );
894 + fwrite( $handle, $row );
895 + fwrite( $handle, PHP_EOL );
825 896 }
826 - $columns = explode( ',', $row );
827 - fputcsv( $handle, $columns );
828 897 }
829 - }
830 - $source = new Visualizer_Source_Csv( $tmpfile );
831 - fclose( $handle );
898 + $source = new Visualizer_Source_Csv( $tmpfile );
899 + fclose( $handle );
900 + break;
901 + case 'excel':
902 + // data coming in from the excel editor.
903 + $source = apply_filters( 'visualizer_pro_handle_chart_data', $data, '' );
904 + break;
832 905 }
833 906 return $source;
834 907 }
835 908
@@ -878,9 +951,9 @@
878 951 $csv[] = $types;
879 952 for ( $j = 0; $j < count( $columns[0] ); $j++ ) {
880 953 $row = array();
881 954 for ( $i = 0; $i < count( $headers ); $i++ ) {
882 - $row[] = $columns[ $i ][ $j ];
955 + $row[] = sanitize_text_field( $columns[ $i ][ $j ] );
883 956 }
884 957 $csv[] = $row;
885 958 }
886 959
@@ -933,8 +1006,10 @@
933 1006 status_header( 400 );
934 1007 exit;
935 1008 }
936 1009
1010 + do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Uploading data for chart %d with POST = %s and GET = %s', $chart_id, print_r( $_POST, true ), print_r( $_GET, true ) ), 'debug', __FILE__, __LINE__ );
1011 +
937 1012 if ( ! isset( $_POST['vz-import-time'] ) ) {
938 1013 apply_filters( 'visualizer_pro_remove_schedule', $chart_id );
939 1014 }
940 1015
@@ -946,8 +1021,9 @@
946 1021
947 1022 // delete "import from db" specific parameters.
948 1023 delete_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY );
949 1024 delete_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE );
1025 + delete_post_meta( $chart_id, Visualizer_Plugin::CF_REMOTE_DB_PARAMS );
950 1026 }
951 1027
952 1028 // delete json related data.
953 1029 delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_URL );
@@ -952,9 +1028,16 @@
952 1028 // delete json related data.
953 1029 delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_URL );
954 1030 delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_ROOT );
955 1031 delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_PAGING );
1032 + delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_HEADERS );
956 1033
1034 + // delete last error
1035 + delete_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR );
1036 +
1037 + // delete editor related data.
1038 + delete_post_meta( $chart_id, Visualizer_Plugin::CF_EDITOR );
1039 +
957 1040 $source = null;
958 1041 $render = new Visualizer_Render_Page_Update();
959 1042 if ( isset( $_POST['remote_data'] ) && filter_var( $_POST['remote_data'], FILTER_VALIDATE_URL ) ) {
960 1043 $source = new Visualizer_Source_Csv_Remote( $_POST['remote_data'] );
@@ -964,14 +1047,21 @@
964 1047 // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
965 1048 } elseif ( isset( $_FILES['local_data'] ) && $_FILES['local_data']['error'] == 0 ) {
966 1049 $source = new Visualizer_Source_Csv( $_FILES['local_data']['tmp_name'] );
967 1050 } elseif ( isset( $_POST['chart_data'] ) && strlen( $_POST['chart_data'] ) > 0 ) {
968 - $source = $this->handleCSVasString( $_POST['chart_data'] );
1051 + $source = $this->handleCSVasString( $_POST['chart_data'], $_POST['editor-type'] );
1052 + update_post_meta( $chart_id, Visualizer_Plugin::CF_EDITOR, $_POST['editor-type'] );
969 1053 } elseif ( isset( $_POST['table_data'] ) && 'yes' === $_POST['table_data'] ) {
970 1054 $source = $this->handleTabularData();
1055 + update_post_meta( $chart_id, Visualizer_Plugin::CF_EDITOR, $_POST['editor-type'] );
971 1056 } else {
1057 + 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__ );
972 1058 $render->message = esc_html__( 'CSV file with chart data was not uploaded. Please try again.', 'visualizer' );
1059 + update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, esc_html__( 'CSV file with chart data was not uploaded. Please try again.', 'visualizer' ) );
973 1060 }
1061 +
1062 + 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__ );
1063 +
974 1064 if ( $source ) {
975 1065 if ( $source->fetch() ) {
976 1066 $content = $source->getData();
977 1067 $populate = true;
@@ -980,8 +1070,9 @@
980 1070 // if source exists, so should data. if source exists but data is blank, do not populate the chart.
981 1071 // if we populate the data even if it is empty, the chart will show "Table has no columns".
982 1072 if ( array_key_exists( 'source', $json ) && ! empty( $json['source'] ) && ( ! array_key_exists( 'data', $json ) || empty( $json['data'] ) ) ) {
983 1073 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__ );
1074 + update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, sprintf( 'Not populating chart data as source exists (%s) but data is empty!', $json['source'] ) );
984 1075 $populate = false;
985 1076 }
986 1077 }
987 1078 if ( $populate ) {
@@ -991,8 +1082,10 @@
991 1082 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
992 1083 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
993 1084 update_post_meta( $chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
994 1085
1086 + do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Updated post for chart %d', $chart_id ), 'debug', __FILE__, __LINE__ );
1087 +
995 1088 Visualizer_Module_Utility::set_defaults( $chart, null );
996 1089
997 1090 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
998 1091
@@ -1000,13 +1093,18 @@
1000 1093 $render->data = json_encode( $source->getRawData() );
1001 1094 $render->series = json_encode( $source->getSeries() );
1002 1095 $render->settings = json_encode( $settings );
1003 1096 } else {
1004 - $render->message = $source->get_error();
1005 - if ( empty( $render->message ) ) {
1006 - $render->message = esc_html__( 'CSV file is broken or invalid. Please try again.', 'visualizer' );
1097 + $error = $source->get_error();
1098 + if ( empty( $error ) ) {
1099 + $error = esc_html__( 'CSV file is broken or invalid. Please try again.', 'visualizer' );
1007 1100 }
1101 + $render->message = $error;
1102 + do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( '%s for chart %d.', $error, $chart_id ), 'error', __FILE__, __LINE__ );
1103 + update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, $error );
1008 1104 }
1105 + } else {
1106 + do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Unknown internal error for chart %d.', $chart_id ), 'error', __FILE__, __LINE__ );
1009 1107 }
1010 1108 $render->render();
1011 1109 if ( ! $can_die ) {
1012 1110 return;
@@ -1113,9 +1211,12 @@
1113 1211 $data = $this->_getChartArray();
1114 1212 $render = new Visualizer_Render_Page_Data();
1115 1213 $render->chart = $this->_chart;
1116 1214 $render->type = $data['type'];
1117 - unset( $data['settings']['width'], $data['settings']['height'], $data['settings']['chartArea'] );
1215 +
1216 + if ( $data && $data['settings'] ) {
1217 + unset( $data['settings']['width'], $data['settings']['height'], $data['settings']['chartArea'] );
1218 + }
1118 1219 wp_enqueue_style( 'visualizer-frame' );
1119 1220 wp_enqueue_script( 'visualizer-render' );
1120 1221 wp_localize_script(
1121 1222 'visualizer-render',
@@ -1121,9 +1222,9 @@
1121 1222 'visualizer-render',
1122 1223 'visualizer',
1123 1224 array(
1124 1225 'l10n' => array(
1125 - 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ),
1226 + 'invalid_source' => esc_html__( 'You have entered an invalid URL. Please provide a valid URL.', 'visualizer' ),
1126 1227 'loading' => esc_html__( 'Loading...', 'visualizer' ),
1127 1228 ),
1128 1229 'charts' => array(
1129 1230 'canvas' => $data,
@@ -1130,13 +1231,13 @@
1130 1231 ),
1131 1232 )
1132 1233 );
1133 1234
1134 - do_action( 'visualizer_enqueue_scripts_and_styles', $data );
1235 + do_action( 'visualizer_enqueue_scripts_and_styles', $data, $this->_chart->ID );
1135 1236
1136 1237 if ( Visualizer_Module::is_pro() && Visualizer_Module::is_pro_older_than( '1.9.0' ) ) {
1137 1238 global $Visualizer_Pro;
1138 - $Visualizer_Pro->_enqueueScriptsAndStyles( $data );
1239 + $Visualizer_Pro->_enqueueScriptsAndStyles( $data, $this->_chart->ID );
1139 1240 }
1140 1241
1141 1242 // Added by Ash/Upwork
1142 1243 $this->_addAction( 'admin_head', 'renderFlattrScript' );
@@ -1151,13 +1252,14 @@
1151 1252 public function getQueryData() {
1152 1253 check_ajax_referer( Visualizer_Plugin::ACTION_FETCH_DB_DATA . Visualizer_Plugin::VERSION, 'security' );
1153 1254
1154 1255 $params = wp_parse_args( $_POST['params'] );
1155 - $source = new Visualizer_Source_Query( stripslashes( $params['query'] ) );
1256 + $chart_id = filter_var( $params['chart_id'], FILTER_VALIDATE_INT );
1257 +
1258 + $source = new Visualizer_Source_Query( stripslashes( $params['query'] ), $chart_id, $params );
1156 1259 $html = $source->fetch( true );
1157 - $error = '';
1158 - if ( empty( $html ) ) {
1159 - $error = $source->get_error();
1260 + $error = $source->get_error();
1261 + if ( ! empty( $error ) ) {
1160 1262 wp_send_json_error( array( 'msg' => $error ) );
1161 1263 }
1162 1264 wp_send_json_success( array( 'table' => $html ) );
1163 1265 }
@@ -1180,21 +1282,42 @@
1180 1282 ),
1181 1283 )
1182 1284 );
1183 1285
1286 + $hours = filter_input(
1287 + INPUT_POST,
1288 + 'refresh',
1289 + FILTER_VALIDATE_INT,
1290 + array(
1291 + 'options' => array(
1292 + 'min_range' => -1,
1293 + 'max_range' => apply_filters( 'visualizer_is_business', false ) ? PHP_INT_MAX : -1,
1294 + ),
1295 + )
1296 + );
1297 +
1298 + if ( ! is_int( $hours ) ) {
1299 + $hours = -1;
1300 + }
1301 +
1184 1302 $render = new Visualizer_Render_Page_Update();
1185 1303 if ( $chart_id ) {
1186 1304 $params = wp_parse_args( $_POST['params'] );
1187 - $source = new Visualizer_Source_Query( stripslashes( $params['query'] ) );
1305 + $source = new Visualizer_Source_Query( stripslashes( $params['query'] ), $chart_id, $params );
1188 1306 $source->fetch( false );
1189 1307 $error = $source->get_error();
1190 1308 if ( empty( $error ) ) {
1191 - $hours = $_POST['refresh'];
1192 1309 update_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY, stripslashes( $params['query'] ) );
1193 1310 update_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
1194 1311 update_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
1195 1312 update_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, $hours );
1196 1313 update_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
1314 + if ( isset( $params['db_type'] ) && $params['db_type'] !== Visualizer_Plugin::WP_DB_NAME ) {
1315 + $remote_db_params = $params;
1316 + unset( $remote_db_params['query'] );
1317 + unset( $remote_db_params['chart_id'] );
1318 + update_post_meta( $chart_id, Visualizer_Plugin::CF_REMOTE_DB_PARAMS, $remote_db_params );
1319 + }
1197 1320
1198 1321 $schedules = get_option( Visualizer_Plugin::CF_DB_SCHEDULE, array() );
1199 1322 $schedules[ $chart_id ] = time() + $hours * HOUR_IN_SECONDS;
1200 1323 update_option( Visualizer_Plugin::CF_DB_SCHEDULE, $schedules );
@@ -1206,8 +1329,9 @@
1206 1329 )
1207 1330 );
1208 1331 $render->data = json_encode( $source->getRawData() );
1209 1332 $render->series = json_encode( $source->getSeries() );
1333 + $render->id = $chart_id;
1210 1334 } else {
1211 1335 $render->message = $error;
1212 1336 }
1213 1337 }
@@ -1236,9 +1360,23 @@
1236 1360 ),
1237 1361 )
1238 1362 );
1239 1363
1240 - $hours = $_POST['refresh'];
1364 + $hours = filter_input(
1365 + INPUT_POST,
1366 + 'refresh',
1367 + FILTER_VALIDATE_INT,
1368 + array(
1369 + 'options' => array(
1370 + 'min_range' => -1,
1371 + 'max_range' => apply_filters( 'visualizer_is_business', false ) ? PHP_INT_MAX : -1,
1372 + ),
1373 + )
1374 + );
1375 +
1376 + if ( ! $hours ) {
1377 + $hours = -1;
1378 + }
1241 1379
1242 1380 do_action( 'visualizer_save_filter', $chart_id, $hours );
1243 1381
1244 1382 if ( ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ) ) {