PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.0.12
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.0.12
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 All 149 releases
← All changes | classes/Visualizer/Module/Chart.php +104 -1038 3.10.113.0.12 View file →
@@ -57,256 +57,13 @@
57 57 $this->_addAjaxAction( Visualizer_Plugin::ACTION_EDIT_CHART, 'renderChartPages' );
58 58 $this->_addAjaxAction( Visualizer_Plugin::ACTION_UPLOAD_DATA, 'uploadData' );
59 59 $this->_addAjaxAction( Visualizer_Plugin::ACTION_CLONE_CHART, 'cloneChart' );
60 60 $this->_addAjaxAction( Visualizer_Plugin::ACTION_EXPORT_DATA, 'exportData' );
61 -
62 - $this->_addAjaxAction( Visualizer_Plugin::ACTION_FETCH_DB_DATA, 'getQueryData' );
63 - $this->_addAjaxAction( Visualizer_Plugin::ACTION_SAVE_DB_QUERY, 'saveQuery' );
64 -
65 - $this->_addAjaxAction( Visualizer_Plugin::ACTION_JSON_GET_ROOTS, 'getJsonRoots' );
66 - $this->_addAjaxAction( Visualizer_Plugin::ACTION_JSON_GET_DATA, 'getJsonData' );
67 - $this->_addAjaxAction( Visualizer_Plugin::ACTION_JSON_SET_DATA, 'setJsonData' );
68 - $this->_addAjaxAction( Visualizer_Plugin::ACTION_JSON_SET_SCHEDULE, 'setJsonSchedule' );
69 -
70 - $this->_addAjaxAction( Visualizer_Plugin::ACTION_SAVE_FILTER_QUERY, 'saveFilter' );
71 -
72 - $this->_addFilter( 'visualizer_get_sidebar', 'getSidebar', 10, 2 );
73 -
74 61 }
75 62
76 63 /**
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 - /**
103 - * Sets the schedule for how JSON-endpoint charts should be updated.
104 - *
105 - * @since ?
106 - *
107 - * @access public
108 - */
109 - public function setJsonSchedule() {
110 - check_ajax_referer( Visualizer_Plugin::ACTION_JSON_SET_SCHEDULE . Visualizer_Plugin::VERSION, 'security' );
111 -
112 - $chart_id = filter_input(
113 - INPUT_POST,
114 - 'chart',
115 - FILTER_VALIDATE_INT,
116 - array(
117 - 'options' => array(
118 - 'min_range' => 1,
119 - ),
120 - )
121 - );
122 -
123 - if ( ! $chart_id ) {
124 - wp_send_json_error();
125 - }
126 -
127 - $time = filter_input(
128 - INPUT_POST,
129 - 'time',
130 - FILTER_VALIDATE_INT,
131 - array(
132 - 'options' => array(
133 - 'min_range' => -1,
134 - ),
135 - )
136 - );
137 -
138 - if ( Visualizer_Module::is_pro() ) {
139 - $is_woocommerce_report = filter_input(
140 - INPUT_POST,
141 - 'is_woocommerce_report',
142 - FILTER_VALIDATE_BOOLEAN
143 - );
144 -
145 - if ( $is_woocommerce_report ) {
146 - update_post_meta( $chart_id, Visualizer_Plugin::CF_IS_WOOCOMMERCE_SOURCE, true );
147 - } else {
148 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_IS_WOOCOMMERCE_SOURCE );
149 - }
150 - }
151 -
152 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE );
153 -
154 - if ( -1 < $time ) {
155 - add_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE, $time );
156 - // Update schedules.
157 - $schedules = get_option( Visualizer_Plugin::CF_JSON_SCHEDULE, array() );
158 - $schedules[ $chart_id ] = time() + $time * HOUR_IN_SECONDS;
159 - update_option( Visualizer_Plugin::CF_JSON_SCHEDULE, $schedules );
160 - }
161 - wp_send_json_success();
162 - }
163 -
164 - /**
165 - * Get the root elements for JSON-endpoint.
166 - *
167 - * @since ?
168 - *
169 - * @access public
170 - */
171 - public function getJsonRoots() {
172 - check_ajax_referer( Visualizer_Plugin::ACTION_JSON_GET_ROOTS . Visualizer_Plugin::VERSION, 'security' );
173 -
174 - $params = wp_parse_args( $_POST['params'] );
175 -
176 - $source = new Visualizer_Source_Json( $params );
177 -
178 - $roots = $source->fetchRoots();
179 - if ( empty( $roots ) ) {
180 - wp_send_json_error( array( 'msg' => $source->get_error() ) );
181 - }
182 -
183 - wp_send_json_success( array( 'url' => $params['url'], 'roots' => $roots ) );
184 - }
185 -
186 - /**
187 - * Get the data for the JSON-endpoint corresponding to the chosen root.
188 - *
189 - * @since ?
190 - *
191 - * @access public
192 - */
193 - public function getJsonData() {
194 - check_ajax_referer( Visualizer_Plugin::ACTION_JSON_GET_DATA . Visualizer_Plugin::VERSION, 'security' );
195 -
196 - $params = wp_parse_args( $_POST['params'] );
197 -
198 - $chart_id = $params['chart'];
199 -
200 - if ( empty( $chart_id ) ) {
201 - wp_die();
202 - }
203 -
204 - $source = new Visualizer_Source_Json( $params );
205 - $source->fetch();
206 - $data = $source->getRawData();
207 -
208 - if ( empty( $data ) ) {
209 - wp_send_json_error( array( 'msg' => esc_html__( 'Unable to fetch data from the endpoint. Please try again.', 'visualizer' ) ) );
210 - }
211 -
212 - $data = Visualizer_Render_Layout::show( 'editor-table', $data, $chart_id, 'viz-json-table', false, false );
213 - wp_send_json_success( array( 'table' => $data, 'root' => $params['root'], 'url' => $params['url'], 'paging' => $source->getPaginationElements() ) );
214 - }
215 -
216 - /**
217 - * Updates the database with the correct post parameters for JSON-endpoint charts.
218 - *
219 - * @since ?
220 - *
221 - * @access public
222 - */
223 - public function setJsonData() {
224 - check_ajax_referer( Visualizer_Plugin::ACTION_JSON_SET_DATA . Visualizer_Plugin::VERSION, 'security' );
225 -
226 - $params = $_POST;
227 - $chart_id = $_GET['chart'];
228 -
229 - if ( empty( $chart_id ) ) {
230 - wp_die();
231 - }
232 -
233 - $chart = get_post( $chart_id );
234 -
235 - $source = new Visualizer_Source_Json( $params );
236 - update_post_meta( $chart->ID, Visualizer_Plugin::CF_EDITABLE_TABLE, true );
237 - $source->fetchFromEditableTable();
238 -
239 - $content = $source->getData( get_post_meta( $chart->ID, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) );
240 - $chart->post_content = $content;
241 - wp_update_post( $chart->to_array() );
242 - update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
243 - update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
244 - update_post_meta( $chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
245 - update_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_URL, $params['url'] );
246 - update_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_ROOT, $params['root'] );
247 -
248 - delete_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_HEADERS );
249 - $headers = array( 'method' => $params['method'] );
250 - if ( ! empty( $params['auth'] ) ) {
251 - $headers['auth'] = $params['auth'];
252 - } elseif ( ! empty( $params['username'] ) && ! empty( $params['password'] ) ) {
253 - $headers['auth'] = array( 'username' => $params['username'], 'password' => $params['password'] );
254 - }
255 -
256 - add_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_HEADERS, $headers );
257 -
258 - delete_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_PAGING );
259 - if ( ! empty( $params['paging'] ) ) {
260 - add_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_PAGING, $params['paging'] );
261 - }
262 -
263 - if ( Visualizer_Module::is_pro() ) {
264 - if ( ! empty( $params['vz_woo_source'] ) ) {
265 - update_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_WOOCOMMERCE_SOURCE, $params['vz_woo_source'] );
266 - } else {
267 - delete_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_WOOCOMMERCE_SOURCE );
268 - }
269 - }
270 -
271 - $time = filter_input(
272 - INPUT_POST,
273 - 'time',
274 - FILTER_VALIDATE_INT,
275 - array(
276 - 'options' => array(
277 - 'min_range' => -1,
278 - ),
279 - )
280 - );
281 -
282 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE );
283 -
284 - if ( -1 < $time ) {
285 - add_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE, $time );
286 - }
287 -
288 - // delete other source specific parameters.
289 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY );
290 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE );
291 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_URL );
292 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_SCHEDULE );
293 -
294 - $render = new Visualizer_Render_Page_Update();
295 - $render->id = $chart->ID;
296 - $render->data = json_encode( $source->getRawData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ) );
297 - $render->series = json_encode( $source->getSeries() );
298 - $render->render();
299 -
300 - defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
301 - }
302 -
303 -
304 - /**
305 64 * Fetches charts from database.
306 65 *
307 - * This method is also called from the media pop-up (classic editor: create a post and add chart from insert content).
308 - *
309 66 * @since 1.0.0
310 67 *
311 68 * @access public
312 69 */
@@ -331,9 +88,9 @@
331 88 // 'filter' is from the modal from the add media button.
332 89 $filter = filter_input( INPUT_GET, 'filter', FILTER_SANITIZE_STRING );
333 90 }
334 91
335 - if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) {
92 + if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) {
336 93 $query_args['meta_query'] = array(
337 94 array(
338 95 'key' => Visualizer_Plugin::CF_CHART_TYPE,
339 96 'value' => $filter,
@@ -346,18 +103,8 @@
346 103 while ( $query->have_posts() ) {
347 104 $chart = $query->next_post();
348 105 $chart_data = $this->_getChartArray( $chart );
349 106 $chart_data['id'] = $chart->ID;
350 - $chart_data['library'] = $this->load_chart_type( $chart->ID );
351 - $css = '';
352 - $settings = $chart_data['settings'];
353 - $arguments = $this->get_inline_custom_css( 'visualizer-chart-' . $chart->ID, $settings );
354 - if ( ! empty( $arguments ) ) {
355 - $css = $arguments[0];
356 - $settings = $arguments[1];
357 - }
358 - $chart_data['settings'] = $settings;
359 - $chart_data['css'] = $css;
360 107 $charts[] = $chart_data;
361 108 }
362 109 self::_sendResponse(
363 110 array(
@@ -384,34 +131,15 @@
384 131 $chart = $this->_chart;
385 132 }
386 133 $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
387 134 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
388 - $data = self::get_chart_data( $chart, $type );
389 - $library = $this->load_chart_type( $chart->ID );
135 + $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( $chart->post_content ), $chart->ID, $type );
390 136
391 - $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
392 - $settings = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $settings, $chart->ID, $type );
393 - if ( ! empty( $atts['settings'] ) ) {
394 - $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
395 - }
396 -
397 - $css = '';
398 - $arguments = $this->get_inline_custom_css( 'visualizer-' . $chart->ID, $settings );
399 - if ( ! empty( $arguments ) ) {
400 - $css = $arguments[0];
401 - $settings = $arguments[1];
402 - }
403 -
404 - $date_formats = Visualizer_Source::get_date_formats_if_exists( $series, $data );
405 -
406 137 return array(
407 138 'type' => $type,
408 139 'series' => $series,
409 - 'settings' => $settings,
140 + 'settings' => get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true ),
410 141 'data' => $data,
411 - 'library' => $library,
412 - 'css' => $css,
413 - 'date_formats' => $date_formats,
414 142 );
415 143 }
416 144
417 145 /**
@@ -438,9 +166,9 @@
438 166 *
439 167 * @access public
440 168 */
441 169 public function deleteChart() {
442 - $is_post = $_SERVER['REQUEST_METHOD'] === 'POST';
170 + $is_post = $_SERVER['REQUEST_METHOD'] == 'POST';
443 171 $input_method = $is_post ? INPUT_POST : INPUT_GET;
444 172 $chart_id = $success = false;
445 173 $nonce = wp_verify_nonce( filter_input( $input_method, 'nonce' ) );
446 174 $capable = current_user_can( 'delete_posts' );
@@ -456,26 +184,13 @@
456 184 )
457 185 );
458 186 if ( $chart_id ) {
459 187 $chart = get_post( $chart_id );
460 - $success = $chart && $chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
188 + $success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
461 189 }
462 190 }
463 191 if ( $success ) {
464 - global $sitepress;
465 - if ( Visualizer_Module::is_pro() && ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) ) {
466 - $trid = $sitepress->get_element_trid( $chart_id, 'post_' . Visualizer_Plugin::CPT_VISUALIZER );
467 - $translations = $sitepress->get_element_translations( $trid );
468 - if ( ! empty( $translations ) ) {
469 - foreach ( $translations as $translated_post ) {
470 - wp_delete_post( $translated_post->element_id, true );
471 - }
472 - } else {
473 - wp_delete_post( $chart_id, true );
474 - }
475 - } else {
476 - wp_delete_post( $chart_id, true );
477 - }
192 + wp_delete_post( $chart_id, true );
478 193 }
479 194 if ( $is_post ) {
480 195 self::_sendResponse(
481 196 array(
@@ -482,41 +197,13 @@
482 197 'success' => $success,
483 198 )
484 199 );
485 200 }
486 - wp_redirect( remove_query_arg( 'vaction', wp_get_referer() ) );
201 + wp_redirect( wp_get_referer() );
487 202 exit;
488 203 }
489 204
490 205 /**
491 - * Delete charts that are still in auto-draft mode.
492 - */
493 - private function deleteOldCharts() {
494 - $query = new WP_Query(
495 - array(
496 - 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
497 - 'post_status' => 'auto-draft',
498 - 'fields' => 'ids',
499 - 'update_post_meta_cache' => false,
500 - 'update_post_term_cache' => false,
501 - 'posts_per_page' => 50,
502 - 'date_query' => array(
503 - array(
504 - 'before' => 'today',
505 - ),
506 - ),
507 - )
508 - );
509 -
510 - if ( $query->have_posts() ) {
511 - $ids = array();
512 - while ( $query->have_posts() ) {
513 - wp_delete_post( $query->next_post(), true );
514 - }
515 - }
516 - }
517 -
518 - /**
519 206 * Renders appropriate page for chart builder. Creates new auto draft chart
520 207 * if no chart has been specified.
521 208 *
522 209 * @since 1.0.0
@@ -524,124 +211,58 @@
524 211 * @access public
525 212 */
526 213 public function renderChartPages() {
527 214 defined( 'IFRAME_REQUEST' ) || define( 'IFRAME_REQUEST', 1 );
528 - if ( ! defined( 'ET_BUILDER_PRODUCT_VERSION' ) && function_exists( 'et_get_theme_version' ) ) {
529 - define( 'ET_BUILDER_PRODUCT_VERSION', et_get_theme_version() );
530 - }
531 - // Set current screen for the render chart.
532 - set_current_screen( 'visualizer_render_chart' );
533 215 // check chart, if chart not exists, will create new one and redirects to the same page with proper chart id
534 216 $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
535 - if ( ! empty( $_POST ) ) {
536 - $_POST = map_deep( $_POST, 'wp_strip_all_tags' );
537 - }
538 - if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type !== Visualizer_Plugin::CPT_VISUALIZER ) {
539 - if ( empty( $_GET['lang'] ) || empty( $_GET['parent_chart_id'] ) ) {
540 - $this->deleteOldCharts();
541 - $default_type = isset( $_GET['type'] ) && ! empty( $_GET['type'] ) ? $_GET['type'] : 'line';
542 - $chart_status = Visualizer_Module_Admin::checkChartStatus( $default_type );
543 - if ( ! $chart_status ) {
544 - $default_type = 'line';
545 - }
546 - $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $default_type . '.csv' );
547 - $source->fetch();
548 - $chart_id = wp_insert_post(
217 + if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
218 + $default_type = isset( $_GET['type'] ) && ! empty( $_GET['type'] ) ? $_GET['type'] : 'line';
219 + $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $default_type . '.csv' );
220 + $source->fetch();
221 + $chart_id = wp_insert_post(
222 + array(
223 + 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
224 + 'post_title' => 'Visualization',
225 + 'post_author' => get_current_user_id(),
226 + 'post_status' => 'auto-draft',
227 + 'post_content' => $source->getData(),
228 + )
229 + );
230 + if ( $chart_id && ! is_wp_error( $chart_id ) ) {
231 + add_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, $default_type );
232 + add_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 1 );
233 + add_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
234 + add_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
235 + add_post_meta(
236 + $chart_id,
237 + Visualizer_Plugin::CF_SETTINGS,
549 238 array(
550 - 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
551 - 'post_title' => 'Visualization',
552 - 'post_author' => get_current_user_id(),
553 - 'post_status' => 'auto-draft',
554 - 'post_content' => $source->getData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ),
239 + 'focusTarget' => 'datum',
555 240 )
556 241 );
557 - if ( $chart_id && ! is_wp_error( $chart_id ) ) {
558 - add_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, $default_type );
559 - add_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 1 );
560 - add_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
561 - add_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
562 - add_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_LIBRARY, '' );
563 - add_post_meta(
564 - $chart_id,
565 - Visualizer_Plugin::CF_SETTINGS,
566 - array(
567 - 'focusTarget' => 'datum',
568 - )
569 - );
570 -
571 - do_action( 'visualizer_pro_new_chart_defaults', $chart_id );
572 - }
573 - } else {
574 - if ( current_user_can( 'edit_posts' ) ) {
575 - $parent_chart_id = isset( $_GET['parent_chart_id'] ) ? filter_var( $_GET['parent_chart_id'], FILTER_VALIDATE_INT ) : '';
576 - $success = false;
577 - if ( $parent_chart_id ) {
578 - $parent_chart = get_post( $parent_chart_id );
579 - $success = $parent_chart && $parent_chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
580 - }
581 - if ( $success ) {
582 - $new_chart_id = wp_insert_post(
583 - array(
584 - 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
585 - 'post_title' => 'Visualization',
586 - 'post_author' => get_current_user_id(),
587 - 'post_status' => $parent_chart->post_status,
588 - 'post_content' => $parent_chart->post_content,
589 - )
590 - );
591 -
592 - if ( is_wp_error( $new_chart_id ) ) {
593 - 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__ );
594 - } else {
595 - $post_meta = get_post_meta( $parent_chart_id );
596 - $chart_id = $new_chart_id;
597 - foreach ( $post_meta as $key => $value ) {
598 - if ( strpos( $key, 'visualizer-' ) !== false ) {
599 - add_post_meta( $new_chart_id, $key, maybe_unserialize( $value[0] ) );
600 - }
601 - }
602 - }
603 - }
604 - }
605 242 do_action( 'visualizer_pro_new_chart_defaults', $chart_id );
606 243 }
607 - wp_redirect( esc_url_raw( add_query_arg( 'chart', (int) $chart_id ) ) );
608 -
609 - if ( defined( 'WP_TESTS_DOMAIN' ) ) {
610 - wp_die();
611 - }
612 - exit();
244 + wp_redirect( add_query_arg( 'chart', (int) $chart_id ) );
245 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
613 246 }
614 -
615 - $_POST['save_chart_image'] = isset( $_POST['save_chart_image'] ) && 'yes' === $_POST['save_chart_image'] ? true : false;
616 - $_POST['lazy_load_chart'] = isset( $_POST['lazy_load_chart'] ) && 'yes' === $_POST['lazy_load_chart'] ? true : false;
617 -
618 - if ( isset( $_POST['chart-img'] ) && ! empty( $_POST['chart-img'] ) ) {
619 - $attachment_id = $this->save_chart_image( $_POST['chart-img'], $chart_id, $_POST['save_chart_image'] );
620 - if ( $attachment_id ) {
621 - update_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_IMAGE, $attachment_id );
622 - }
623 - }
624 - $lib = $this->load_chart_type( $chart_id );
625 -
626 - // the alpha color picker (RGBA) is not supported by google.
627 - $color_picker_dep = 'wp-color-picker';
628 - if ( in_array( $lib, array( 'chartjs', 'datatables' ), true ) && ! wp_script_is( 'wp-color-picker-alpha', 'registered' ) ) {
629 - wp_register_script( 'wp-color-picker-alpha', VISUALIZER_ABSURL . 'js/lib/wp-color-picker-alpha.min.js', array( 'wp-color-picker' ), Visualizer_Plugin::VERSION );
630 - $color_picker_dep = 'wp-color-picker-alpha';
631 - }
632 -
633 247 // enqueue and register scripts and styles
634 248 wp_register_script( 'visualizer-chosen', VISUALIZER_ABSURL . 'js/lib/chosen.jquery.min.js', array( 'jquery' ), Visualizer_Plugin::VERSION );
635 249 wp_register_style( 'visualizer-chosen', VISUALIZER_ABSURL . 'css/lib/chosen.min.css', array(), Visualizer_Plugin::VERSION );
636 250
637 251 wp_register_style( 'visualizer-frame', VISUALIZER_ABSURL . 'css/frame.css', array( 'visualizer-chosen' ), Visualizer_Plugin::VERSION );
638 - wp_register_script( 'visualizer-frame', VISUALIZER_ABSURL . 'js/frame.js', array( 'visualizer-chosen', 'jquery-ui-accordion', 'jquery-ui-tabs' ), Visualizer_Plugin::VERSION, true );
252 + wp_register_script( 'visualizer-frame', VISUALIZER_ABSURL . 'js/frame.js', array( 'visualizer-chosen' ), Visualizer_Plugin::VERSION, true );
253 + wp_register_script( 'google-jsapi-new', '//www.gstatic.com/charts/loader.js', array(), null, true );
254 + wp_register_script( 'google-jsapi-old', '//www.google.com/jsapi', array( 'google-jsapi-new' ), null, true );
639 255 wp_register_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
640 256 wp_register_script(
641 257 'visualizer-render',
642 - VISUALIZER_ABSURL . 'js/render-facade.js',
643 - apply_filters( 'visualizer_assets_render', array( 'visualizer-frame', 'visualizer-customization' ), false ),
258 + VISUALIZER_ABSURL . 'js/render.js',
259 + array(
260 + 'google-jsapi-old',
261 + 'google-jsapi-new',
262 + 'visualizer-frame',
263 + 'visualizer-customization',
264 + ),
644 265 Visualizer_Plugin::VERSION,
645 266 true
646 267 );
647 268 wp_register_script(
@@ -647,23 +268,19 @@
647 268 wp_register_script(
648 269 'visualizer-preview',
649 270 VISUALIZER_ABSURL . 'js/preview.js',
650 271 array(
651 - $color_picker_dep,
272 + 'wp-color-picker',
652 273 'visualizer-render',
653 274 ),
654 275 Visualizer_Plugin::VERSION,
655 276 true
656 277 );
657 - wp_register_script( 'visualizer-editor-simple', VISUALIZER_ABSURL . 'js/simple-editor.js', array( 'jquery' ), Visualizer_Plugin::VERSION, true );
658 -
659 - do_action( 'visualizer_add_scripts' );
660 -
661 - if ( Visualizer_Module::is_pro() && Visualizer_Module::is_pro_older_than( '1.9.0' ) ) {
278 + // added by Ash/Upwork
279 + if ( VISUALIZER_PRO ) {
662 280 global $Visualizer_Pro;
663 281 $Visualizer_Pro->_addScriptsAndStyles();
664 282 }
665 -
666 283 // dispatch pages
667 284 $this->_chart = get_post( $chart_id );
668 285 $tab = isset( $_GET['tab'] ) && ! empty( $_GET['tab'] ) ? $_GET['tab'] : 'visualizer';
669 286
@@ -675,9 +292,8 @@
675 292 if ( isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] ) ) {
676 293 // if the cancel button is clicked.
677 294 $this->undoRevisions( $chart_id, true );
678 295 } elseif ( isset( $_POST['save'] ) && 1 === intval( $_POST['save'] ) ) {
679 - $this->handlePermissions();
680 296 // if the save button is clicked.
681 297 $this->undoRevisions( $chart_id, false );
682 298 } else {
683 299 // if the edit button is clicked.
@@ -683,16 +299,8 @@
683 299 // if the edit button is clicked.
684 300 $this->_chart = $this->handleExistingRevisions( $chart_id, $this->_chart );
685 301 }
686 302
687 - // Clear existing chart cache.
688 - if ( isset( $_POST['save'] ) && 1 === intval( $_POST['save'] ) ) {
689 - $cache_key = Visualizer_Plugin::CF_CHART_CACHE . '_' . $chart_id;
690 - if ( get_transient( $cache_key ) ) {
691 - delete_transient( $cache_key );
692 - }
693 - }
694 -
695 303 switch ( $tab ) {
696 304 case 'settings':
697 305 $this->_handleDataAndSettingsPage();
698 306 break;
@@ -700,9 +308,9 @@
700 308 case 'visualizer': // fall through.
701 309 $this->_handleTypesPage();
702 310 break;
703 311 default:
704 - // this should never happen.
312 + do_action( 'visualizer_pro_handle_tab', $tab, $this->_chart );
705 313 break;
706 314 }
707 315 defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
708 316 }
@@ -707,80 +315,8 @@
707 315 defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
708 316 }
709 317
710 318 /**
711 - * Load code editor assets.
712 - */
713 - private function loadCodeEditorAssets( $chart_id ) {
714 - global $wp_version;
715 -
716 - $wp_scripts = wp_scripts();
717 -
718 - // data tables assets.
719 - wp_register_script( 'visualizer-datatables', VISUALIZER_ABSURL . 'js/lib/datatables.min.js', array( 'jquery-ui-core' ), Visualizer_Plugin::VERSION );
720 - wp_register_style( 'visualizer-datatables', VISUALIZER_ABSURL . 'css/lib/datatables.min.css', array(), Visualizer_Plugin::VERSION );
721 - 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 );
722 - wp_enqueue_script( 'visualizer-datatables' );
723 - wp_enqueue_style( 'visualizer-jquery-ui' );
724 -
725 - if ( ! Visualizer_Module::is_pro() ) {
726 - return;
727 - }
728 -
729 - $table_col_mapping = Visualizer_Source_Query_Params::get_all_db_tables_column_mapping( $chart_id );
730 -
731 - if ( version_compare( $wp_version, '4.9.0', '<' ) ) {
732 - // code mirror assets.
733 - wp_register_script( 'visualizer-codemirror-core', '//codemirror.net/lib/codemirror.js', array( 'jquery' ), Visualizer_Plugin::VERSION );
734 - wp_register_script( 'visualizer-codemirror-placeholder', '//codemirror.net/addon/display/placeholder.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
735 - wp_register_script( 'visualizer-codemirror-matchbrackets', '//codemirror.net/addon/edit/matchbrackets.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
736 - wp_register_script( 'visualizer-codemirror-closebrackets', '//codemirror.net/addon/edit/closebrackets.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
737 - wp_register_script( 'visualizer-codemirror-sql', '//codemirror.net/mode/sql/sql.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
738 - wp_register_script( 'visualizer-codemirror-sql-hint', '//codemirror.net/addon/hint/sql-hint.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
739 - 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 );
740 - wp_register_style( 'visualizer-codemirror-core', '//codemirror.net/lib/codemirror.css', array(), Visualizer_Plugin::VERSION );
741 - wp_register_style( 'visualizer-codemirror-hint', '//codemirror.net/addon/hint/show-hint.css', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
742 -
743 - wp_enqueue_script( 'visualizer-codemirror-hint' );
744 - wp_enqueue_style( 'visualizer-codemirror-hint' );
745 - } else {
746 - wp_enqueue_code_editor(
747 - array(
748 - 'type' => 'sql',
749 - 'codemirror' => array(
750 - 'autofocus' => true,
751 - 'lineWrapping' => true,
752 - 'dragDrop' => false,
753 - 'matchBrackets' => true,
754 - 'autoCloseBrackets' => true,
755 - 'extraKeys' => array( 'Ctrl-Space' => 'autocomplete' ),
756 - 'hintOptions' => array( 'tables' => $table_col_mapping ),
757 - ),
758 - )
759 - );
760 - }
761 -
762 - return $table_col_mapping;
763 - }
764 -
765 - /**
766 - * Handle permissions from the new conslidated settings sidebar.
767 - */
768 - private function handlePermissions() {
769 - if ( ! Visualizer_Module::is_pro() ) {
770 - return;
771 - }
772 -
773 - // we will not support old free and new pro.
774 - // handling new free and old pro.
775 - if ( has_action( 'visualizer_pro_handle_tab' ) ) {
776 - do_action( 'visualizer_pro_handle_tab', 'permissions', $this->_chart );
777 - } else {
778 - do_action( 'visualizer_handle_permissions', $this->_chart );
779 - }
780 - }
781 -
782 - /**
783 319 * Handle data and settings page
784 320 */
785 321 private function _handleDataAndSettingsPage() {
786 322 if ( isset( $_POST['map_api_key'] ) ) {
@@ -785,53 +321,30 @@
785 321 private function _handleDataAndSettingsPage() {
786 322 if ( isset( $_POST['map_api_key'] ) ) {
787 323 update_option( 'visualizer-map-api-key', $_POST['map_api_key'] );
788 324 }
789 -
790 - if ( $_SERVER['REQUEST_METHOD'] === 'POST' && isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'] ) ) {
791 - if ( $this->_chart->post_status === 'auto-draft' ) {
325 + if ( $_SERVER['REQUEST_METHOD'] == 'POST' && isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'] ) ) {
326 + if ( $this->_chart->post_status == 'auto-draft' ) {
792 327 $this->_chart->post_status = 'publish';
793 328
794 329 // ensure that a revision is not created. If a revision is created it will have the proper data and the parent of the revision will have default data.
795 330 // we do not want any difference in data so disable revisions temporarily.
796 - $this->disableRevisionsTemporarily();
797 -
331 + add_filter( 'wp_revisions_to_keep', '__return_false' );
798 332 wp_update_post( $this->_chart->to_array() );
799 333 }
800 334 // save meta data only when it is NOT being canceled.
801 335 if ( ! ( isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] ) ) ) {
802 336 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $_POST );
803 -
804 - // we will keep a parameter called 'internal_title' that will be set to the given title or, if empty, the chart ID
805 - // this will help in searching with the chart id.
806 - $settings = get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
807 - $title = null;
808 - if ( isset( $settings['title'] ) && ! empty( $settings['title'] ) ) {
809 - $title = $settings['title'];
810 - if ( is_array( $title ) ) {
811 - $title = $settings['title']['text'];
812 - }
813 - }
814 - if ( empty( $title ) ) {
815 - $title = $this->_chart->ID;
816 - }
817 - $settings['internal_title'] = $title;
818 - $settings_label = isset( $settings['pieResidueSliceLabel'] ) ? $settings['pieResidueSliceLabel'] : '';
819 - if ( empty( $settings_label ) ) {
820 - $settings['pieResidueSliceLabel'] = esc_html__( 'Other', 'visualizer' );
821 - } else {
822 - $settings['pieResidueSliceLabel'] = $settings_label;
823 - }
824 - update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $settings );
825 337 }
826 338 $render = new Visualizer_Render_Page_Send();
827 339 $render->text = sprintf( '[visualizer id="%d"]', $this->_chart->ID );
828 340 wp_iframe( array( $render, 'render' ) );
341 +
829 342 return;
830 343 }
831 344 $data = $this->_getChartArray();
832 345 $sidebar = '';
833 - $sidebar_class = $this->load_chart_class_name( $this->_chart->ID );
346 + $sidebar_class = 'Visualizer_Render_Sidebar_Type_' . ucfirst( $data['type'] );
834 347 if ( class_exists( $sidebar_class, true ) ) {
835 348 $sidebar = new $sidebar_class( $data['settings'] );
836 349 $sidebar->__series = $data['series'];
837 350 $sidebar->__data = $data['data'];
@@ -836,108 +349,61 @@
836 349 $sidebar->__series = $data['series'];
837 350 $sidebar->__data = $data['data'];
838 351 } else {
839 352 $sidebar = apply_filters( 'visualizer_pro_chart_type_sidebar', '', $data );
840 - if ( $sidebar !== '' ) {
353 + if ( $sidebar != '' ) {
841 354 $sidebar->__series = $data['series'];
842 355 $sidebar->__data = $data['data'];
843 356 }
844 357 }
845 - unset( $data['settings']['width'], $data['settings']['height'], $data['settings']['chartArea'] );
358 + unset( $data['settings']['width'], $data['settings']['height'] );
359 + wp_enqueue_style( 'visualizer-frame' );
846 360 wp_enqueue_style( 'wp-color-picker' );
847 361 wp_enqueue_style( 'visualizer-frame' );
848 362 wp_enqueue_script( 'visualizer-preview' );
849 - wp_enqueue_script( 'visualizer-chosen' );
850 363 wp_enqueue_script( 'visualizer-render' );
851 -
852 - if ( Visualizer_Module::can_show_feature( 'simple-editor' ) ) {
853 - wp_enqueue_script( 'visualizer-editor-simple' );
854 - wp_localize_script(
855 - 'visualizer-editor-simple',
856 - 'visualizer1',
857 - array(
858 - 'ajax' => array(
859 - 'url' => admin_url( 'admin-ajax.php' ),
860 - 'nonces' => array(
861 - ),
862 - 'actions' => array(
863 - ),
864 - ),
865 - )
866 - );
867 - }
868 -
869 - $table_col_mapping = $this->loadCodeEditorAssets( $this->_chart->ID );
870 -
871 364 wp_localize_script(
872 365 'visualizer-render',
873 366 'visualizer',
874 367 array(
875 368 'l10n' => array(
876 - 'invalid_source' => esc_html__( 'You have entered an invalid URL. Please provide a valid URL.', 'visualizer' ),
369 + 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ),
877 370 'loading' => esc_html__( 'Loading...', 'visualizer' ),
878 - 'json_error' => esc_html__( 'An error occured in fetching data.', 'visualizer' ),
879 - 'select_columns' => esc_html__( 'Please select a few columns to include in the chart.', 'visualizer' ),
880 - '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' ),
881 371 ),
882 372 'charts' => array(
883 373 'canvas' => $data,
884 - 'id' => $this->_chart->ID,
885 374 ),
886 375 'language' => $this->get_language(),
887 376 'map_api_key' => get_option( 'visualizer-map-api-key' ),
888 - 'ajax' => array(
377 + 'ajax' => array(
889 378 'url' => admin_url( 'admin-ajax.php' ),
890 379 'nonces' => array(
891 380 'permissions' => wp_create_nonce( Visualizer_Plugin::ACTION_FETCH_PERMISSIONS_DATA ),
892 - 'db_get_data' => wp_create_nonce( Visualizer_Plugin::ACTION_FETCH_DB_DATA . Visualizer_Plugin::VERSION ),
893 - 'json_get_roots' => wp_create_nonce( Visualizer_Plugin::ACTION_JSON_GET_ROOTS . Visualizer_Plugin::VERSION ),
894 - 'json_get_data' => wp_create_nonce( Visualizer_Plugin::ACTION_JSON_GET_DATA . Visualizer_Plugin::VERSION ),
895 - 'json_set_schedule' => wp_create_nonce( Visualizer_Plugin::ACTION_JSON_SET_SCHEDULE . Visualizer_Plugin::VERSION ),
896 381 ),
897 382 'actions' => array(
898 383 'permissions' => Visualizer_Plugin::ACTION_FETCH_PERMISSIONS_DATA,
899 - 'db_get_data' => Visualizer_Plugin::ACTION_FETCH_DB_DATA,
900 - 'json_get_roots' => Visualizer_Plugin::ACTION_JSON_GET_ROOTS,
901 - 'json_get_data' => Visualizer_Plugin::ACTION_JSON_GET_DATA,
902 - 'json_set_schedule' => Visualizer_Plugin::ACTION_JSON_SET_SCHEDULE,
903 384 ),
904 385 ),
905 - 'db_query' => array(
906 - 'tables' => $table_col_mapping,
907 - ),
908 - 'is_pro' => Visualizer_Module::is_pro(),
909 - 'page_type' => 'chart',
910 - 'json_tag_separator' => Visualizer_Source_Json::TAG_SEPARATOR,
911 - 'json_tag_separator_view' => Visualizer_Source_Json::TAG_SEPARATOR_VIEW,
912 - 'is_front' => false,
913 - 'rest_base' => get_rest_url( null, 'wc/v3/reports/' ),
914 386 )
915 387 );
916 -
917 388 $render = new Visualizer_Render_Page_Data();
918 389 $render->chart = $this->_chart;
919 390 $render->type = $data['type'];
920 - $render->custom_css = $data['css'];
921 391 $render->sidebar = $sidebar;
922 392 if ( filter_input( INPUT_GET, 'library', FILTER_VALIDATE_BOOLEAN ) ) {
923 - $render->button = filter_input( INPUT_GET, 'action' ) === Visualizer_Plugin::ACTION_EDIT_CHART
393 + $render->button = filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART
924 394 ? esc_html__( 'Save Chart', 'visualizer' )
925 395 : esc_html__( 'Create Chart', 'visualizer' );
926 - if ( filter_input( INPUT_GET, 'action' ) === Visualizer_Plugin::ACTION_EDIT_CHART ) {
396 + if ( filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART ) {
927 397 $render->cancel_button = esc_html__( 'Cancel', 'visualizer' );
928 398 }
929 399 } else {
930 400 $render->button = esc_attr__( 'Insert Chart', 'visualizer' );
931 401 }
932 -
933 - do_action( 'visualizer_enqueue_scripts_and_styles', $data, $this->_chart->ID );
934 -
935 - if ( Visualizer_Module::is_pro() && Visualizer_Module::is_pro_older_than( '1.9.0' ) ) {
402 + if ( VISUALIZER_PRO ) {
936 403 global $Visualizer_Pro;
937 - $Visualizer_Pro->_enqueueScriptsAndStyles( $data, $this->_chart->ID );
404 + $Visualizer_Pro->_enqueueScriptsAndStyles( $data );
938 405 }
939 -
940 406 $this->_addAction( 'admin_head', 'renderFlattrScript' );
941 407 wp_iframe( array( $render, 'render' ) );
942 408 }
943 409
@@ -949,35 +415,24 @@
949 415 * @access private
950 416 */
951 417 private function _handleTypesPage() {
952 418 // process post request
953 - if ( $_SERVER['REQUEST_METHOD'] === 'POST' && wp_verify_nonce( filter_input( INPUT_POST, 'nonce' ) ) ) {
419 + if ( $_SERVER['REQUEST_METHOD'] == 'POST' && wp_verify_nonce( filter_input( INPUT_POST, 'nonce' ) ) ) {
954 420 $type = filter_input( INPUT_POST, 'type' );
955 - $library = filter_input( INPUT_POST, 'chart-library' );
956 - if ( Visualizer_Module_Admin::checkChartStatus( $type ) ) {
957 - if ( empty( $library ) ) {
958 - // library cannot be empty.
959 - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, 'Chart library empty while creating the chart! Aborting...', 'error', __FILE__, __LINE__ );
960 - return;
961 - }
962 -
421 + if ( in_array( $type, Visualizer_Plugin::getChartTypes() ) ) {
963 422 // save new chart type
964 423 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_CHART_TYPE, $type );
965 - update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_CHART_LIBRARY, $library );
966 424 // if the chart has default data, update it with appropriate default data for new type
967 425 if ( filter_var( get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, true ), FILTER_VALIDATE_BOOLEAN ) ) {
968 426 $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $type . '.csv' );
969 427 $source->fetch();
970 - $this->_chart->post_content = $source->getData( get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) );
428 + $this->_chart->post_content = $source->getData();
971 429 wp_update_post( $this->_chart->to_array() );
972 430 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
973 431 }
974 -
975 - Visualizer_Module_Utility::set_defaults( $this->_chart );
976 -
977 432 // redirect to next tab
978 433 // changed by Ash/Upwork
979 - wp_redirect( esc_url_raw( add_query_arg( 'tab', 'settings' ) ) );
434 + wp_redirect( add_query_arg( 'tab', 'settings' ) );
980 435
981 436 return;
982 437 }
983 438 }
@@ -982,9 +437,9 @@
982 437 }
983 438 }
984 439 $render = new Visualizer_Render_Page_Types();
985 440 $render->type = get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
986 - $render->types = Visualizer_Module_Admin::_getChartTypesLocalized( false, false, false, 'types' );
441 + $render->types = Visualizer_Module_Admin::_getChartTypesLocalized();
987 442 $render->chart = $this->_chart;
988 443 wp_enqueue_style( 'visualizer-frame' );
989 444 wp_enqueue_script( 'visualizer-frame' );
990 445 wp_iframe( array( $render, 'render' ) );
@@ -1000,131 +455,10 @@
1000 455 */
1001 456 public function renderFlattrScript() {
1002 457 echo '';
1003 458 }
1004 -
459 + // changed by Ash/Upwork
1005 460 /**
1006 - * Processes the CSV that is sent in the request as a string.
1007 - *
1008 - * @since 3.2.0
1009 - */
1010 - private function handleCSVasString( $data, $editor_type ) {
1011 - $source = null;
1012 -
1013 - switch ( $editor_type ) {
1014 - case 'text':
1015 - // data coming in from the text editor.
1016 - $tmpfile = tempnam( get_temp_dir(), Visualizer_Plugin::NAME );
1017 - $handle = fopen( $tmpfile, 'w' );
1018 - $values = preg_split( '/[\n\r]+/', stripslashes( trim( $data ) ) );
1019 - if ( $values ) {
1020 - foreach ( $values as $row ) {
1021 - if ( empty( $row ) ) {
1022 - continue;
1023 - }
1024 - $row = explode( ',', $row );
1025 - $row = array_map(
1026 - function( $r ) {
1027 - return '' === $r ? ' ' : $r;
1028 - },
1029 - $row
1030 - );
1031 - $row = implode( ',', $row );
1032 - // don't use fpucsv here because we need to just dump the data
1033 - // minus the empty rows
1034 - // because fputcsv needs to tokenize
1035 - // we can standardize the CSV enclosure here and replace all ' with "
1036 - // we can assume that if there are an even number of ' they should be changed to "
1037 - // but that will screw up words like fo'c'sle
1038 - // so here let's just assume ' will NOT be used for enclosures
1039 - fwrite( $handle, $row );
1040 - fwrite( $handle, PHP_EOL );
1041 - }
1042 - }
1043 - $source = new Visualizer_Source_Csv( $tmpfile );
1044 - fclose( $handle );
1045 - break;
1046 - case 'table':
1047 - // Import from Chart
1048 - // fall-through.
1049 - case 'excel':
1050 - // data coming in from the excel editor.
1051 - $source = apply_filters( 'visualizer_pro_handle_chart_data', $data, '' );
1052 - break;
1053 - }
1054 - return $source;
1055 - }
1056 -
1057 - /**
1058 - * Parses the data uploaded as an HTML table.
1059 - *
1060 - * @since 3.2.0
1061 - *
1062 - * @access private
1063 - */
1064 - private function handleTabularData() {
1065 - $csv = array();
1066 - // the datatable mentions the headers twice, so lets remove the duplicates.
1067 - $headers = array_unique( array_filter( $_POST['header'] ) );
1068 - $types = $_POST['type'];
1069 -
1070 - // capture all the indexes that correspond to excluded columns.
1071 - $exclude = array();
1072 - $index = 0;
1073 - foreach ( $types as $type ) {
1074 - if ( empty( $type ) ) {
1075 - $exclude[] = $index;
1076 - }
1077 - $index++;
1078 - }
1079 -
1080 - // when N headers are being renamed, the number of headers increases by N
1081 - // because of the way datatable duplicates header information
1082 - // so unset the headers that have been renamed.
1083 - if ( count( $headers ) !== count( $types ) ) {
1084 - $to = count( $headers );
1085 - for ( $i = count( $types ); $i < $to; $i++ ) {
1086 - unset( $headers[ $i + 1 ] );
1087 - }
1088 - }
1089 -
1090 - $columns = array();
1091 - for ( $i = 0; $i < count( $headers ); $i++ ) {
1092 - if ( ! isset( $_POST[ 'data' . $i ] ) ) {
1093 - continue;
1094 - }
1095 - $columns[ $i ] = $_POST[ 'data' . $i ];
1096 - }
1097 -
1098 - $csv[] = $headers;
1099 - $csv[] = $types;
1100 - for ( $j = 0; $j < count( $columns[0] ); $j++ ) {
1101 - $row = array();
1102 - for ( $i = 0; $i < count( $headers ); $i++ ) {
1103 - $row[] = sanitize_text_field( $columns[ $i ][ $j ] );
1104 - }
1105 - $csv[] = $row;
1106 - }
1107 -
1108 - $tmpfile = tempnam( get_temp_dir(), Visualizer_Plugin::NAME );
1109 - $handle = fopen( $tmpfile, 'w' );
1110 -
1111 - if ( $csv ) {
1112 - $index = 0;
1113 - foreach ( $csv as $row ) {
1114 - // remove all the cells corresponding to the excluded headers.
1115 - foreach ( $exclude as $j ) {
1116 - unset( $row[ $j ] );
1117 - }
1118 - fputcsv( $handle, $row );
1119 - }
1120 - }
1121 - $source = new Visualizer_Source_Csv( $tmpfile );
1122 - fclose( $handle );
1123 - return $source;
1124 - }
1125 -
1126 - /**
1127 461 * Parses uploaded CSV file and saves new data for the chart.
1128 462 *
1129 463 * @since 1.0.0
1130 464 *
@@ -1146,9 +480,9 @@
1146 480
1147 481 // check chart, if chart exists
1148 482 // do not use filter_input as it does not work for phpunit test cases, use filter_var instead
1149 483 $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
1150 - if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type !== Visualizer_Plugin::CPT_VISUALIZER ) {
484 + if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
1151 485 if ( ! $can_die ) {
1152 486 return;
1153 487 }
1154 488 status_header( 400 );
@@ -1154,10 +488,8 @@
1154 488 status_header( 400 );
1155 489 exit;
1156 490 }
1157 491
1158 - 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__ );
1159 -
1160 492 if ( ! isset( $_POST['vz-import-time'] ) ) {
1161 493 apply_filters( 'visualizer_pro_remove_schedule', $chart_id );
1162 494 }
1163 495
@@ -1162,65 +494,28 @@
1162 494 }
1163 495
1164 496 if ( ! isset( $_POST['chart_data_src'] ) || Visualizer_Plugin::CF_SOURCE_FILTER !== $_POST['chart_data_src'] ) {
1165 497 // delete the filters in case this chart is being uploaded from other data sources
1166 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_FILTER_CONFIG );
1167 - delete_post_meta( $chart_id, '__transient-' . Visualizer_Plugin::CF_FILTER_CONFIG );
1168 - delete_post_meta( $chart_id, '__transient-' . Visualizer_Plugin::CF_DB_QUERY );
1169 -
1170 - // delete "import from db" specific parameters.
1171 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY );
1172 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE );
1173 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_REMOTE_DB_PARAMS );
498 + delete_post_meta( $chart_id, 'visualizer-filter-config' );
1174 499 }
1175 500
1176 - // delete json related data.
1177 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_URL );
1178 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_ROOT );
1179 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_PAGING );
1180 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_HEADERS );
1181 -
1182 - // delete last error
1183 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR );
1184 -
1185 - // delete editor related data.
1186 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_EDITOR );
1187 -
1188 - // delete this so that a JSON import can be later edited manually without a problem.
1189 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE );
1190 -
1191 501 $source = null;
1192 502 $render = new Visualizer_Render_Page_Update();
1193 -
1194 - $remote_data = false;
1195 - if ( isset( $_POST['remote_data'] ) && function_exists( 'wp_http_validate_url' ) ) {
1196 - $remote_data = wp_http_validate_url( $_POST['remote_data'] );
1197 - }
1198 - if ( false !== $remote_data ) {
1199 - $source = new Visualizer_Source_Csv_Remote( $remote_data );
503 + if ( isset( $_POST['remote_data'] ) && filter_var( $_POST['remote_data'], FILTER_VALIDATE_URL ) ) {
504 + $source = new Visualizer_Source_Csv_Remote( $_POST['remote_data'] );
1200 505 if ( isset( $_POST['vz-import-time'] ) ) {
1201 - apply_filters( 'visualizer_pro_chart_schedule', $chart_id, $remote_data, $_POST['vz-import-time'] );
506 + apply_filters( 'visualizer_pro_chart_schedule', $chart_id, $_POST['remote_data'], $_POST['vz-import-time'] );
1202 507 }
1203 - // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
1204 508 } elseif ( isset( $_FILES['local_data'] ) && $_FILES['local_data']['error'] == 0 ) {
1205 509 $source = new Visualizer_Source_Csv( $_FILES['local_data']['tmp_name'] );
1206 510 } elseif ( isset( $_POST['chart_data'] ) && strlen( $_POST['chart_data'] ) > 0 ) {
1207 - $source = $this->handleCSVasString( $_POST['chart_data'], $_POST['editor-type'] );
1208 - update_post_meta( $chart_id, Visualizer_Plugin::CF_EDITOR, $_POST['editor-type'] );
1209 - } elseif ( isset( $_POST['table_data'] ) && 'yes' === $_POST['table_data'] ) {
1210 - $source = $this->handleTabularData();
1211 - update_post_meta( $chart_id, Visualizer_Plugin::CF_EDITOR, $_POST['editor-type'] );
511 + $source = apply_filters( 'visualizer_pro_handle_chart_data', $_POST['chart_data'], '' );
1212 512 } else {
1213 - 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__ );
1214 - $render->message = esc_html__( 'CSV file with chart data was not uploaded. Please try again.', 'visualizer' );
1215 - update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, esc_html__( 'CSV file with chart data was not uploaded. Please try again.', 'visualizer' ) );
513 + $render->message = esc_html__( 'CSV file with chart data was not uploaded. Please, try again.', 'visualizer' );
1216 514 }
1217 -
1218 - 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__ );
1219 -
1220 515 if ( $source ) {
1221 516 if ( $source->fetch() ) {
1222 - $content = $source->getData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) );
517 + $content = $source->getData();
1223 518 $populate = true;
1224 519 if ( is_string( $content ) && is_array( unserialize( $content ) ) ) {
1225 520 $json = unserialize( $content );
1226 521 // if source exists, so should data. if source exists but data is blank, do not populate the chart.
@@ -1226,9 +521,8 @@
1226 521 // if source exists, so should data. if source exists but data is blank, do not populate the chart.
1227 522 // if we populate the data even if it is empty, the chart will show "Table has no columns".
1228 523 if ( array_key_exists( 'source', $json ) && ! empty( $json['source'] ) && ( ! array_key_exists( 'data', $json ) || empty( $json['data'] ) ) ) {
1229 524 do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Not populating chart data as source exists (%s) but data is empty!', $json['source'] ), 'warn', __FILE__, __LINE__ );
1230 - update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, sprintf( 'Not populating chart data as source exists (%s) but data is empty!', $json['source'] ) );
1231 525 $populate = false;
1232 526 }
1233 527 }
1234 528 if ( $populate ) {
@@ -1234,43 +528,16 @@
1234 528 if ( $populate ) {
1235 529 $chart->post_content = $content;
1236 530 }
1237 531 wp_update_post( $chart->to_array() );
1238 -
1239 532 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
1240 533 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
1241 534 update_post_meta( $chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
1242 -
1243 - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Updated post for chart %d', $chart_id ), 'debug', __FILE__, __LINE__ );
1244 -
1245 - Visualizer_Module_Utility::set_defaults( $chart, null );
1246 -
1247 - $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
1248 - if ( isset( $settings['series'] ) && ! ( count( $settings['series'] ) - count( $source->getSeries() ) > 1 ) ) {
1249 - $diff_total_series = abs( count( $settings['series'] ) - count( $source->getSeries() ) );
1250 - if ( $diff_total_series ) {
1251 - foreach ( range( 1, $diff_total_series ) as $k => $diff_series ) {
1252 - $settings['series'][] = end( $settings['series'] );
1253 - }
1254 - update_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, $settings );
1255 - }
1256 - }
1257 -
1258 - $render->id = $chart->ID;
1259 - $render->data = json_encode( $source->getRawData( get_post_meta( $chart->ID, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ) );
535 + $render->data = json_encode( $source->getRawData() );
1260 536 $render->series = json_encode( $source->getSeries() );
1261 - $render->settings = json_encode( $settings );
1262 537 } else {
1263 - $error = $source->get_error();
1264 - if ( empty( $error ) ) {
1265 - $error = esc_html__( 'CSV file is broken or invalid. Please try again.', 'visualizer' );
1266 - }
1267 - $render->message = $error;
1268 - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( '%s for chart %d.', $error, $chart_id ), 'error', __FILE__, __LINE__ );
1269 - update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, $error );
538 + $render->message = esc_html__( 'CSV file is broken or invalid. Please, try again.', 'visualizer' );
1270 539 }
1271 - } else {
1272 - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Unknown internal error for chart %d.', $chart_id ), 'error', __FILE__, __LINE__ );
1273 540 }
1274 541 $render->render();
1275 542 if ( ! $can_die ) {
1276 543 return;
@@ -1286,18 +553,27 @@
1286 553 * @access public
1287 554 */
1288 555 public function cloneChart() {
1289 556 $chart_id = $success = false;
1290 - $nonce = isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'], Visualizer_Plugin::ACTION_CLONE_CHART );
557 + $nonce = wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), Visualizer_Plugin::ACTION_CLONE_CHART );
1291 558 $capable = current_user_can( 'edit_posts' );
1292 559 if ( $nonce && $capable ) {
1293 - $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
560 + $chart_id = filter_input(
561 + INPUT_GET,
562 + 'chart',
563 + FILTER_VALIDATE_INT,
564 + array(
565 + 'options' => array(
566 + 'min_range' => 1,
567 + ),
568 + )
569 + );
1294 570 if ( $chart_id ) {
1295 571 $chart = get_post( $chart_id );
1296 - $success = $chart && $chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
572 + $success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
1297 573 }
1298 574 }
1299 - $redirect = remove_query_arg( 'vaction', wp_get_referer() );
575 + $redirect = wp_get_referer();
1300 576 if ( $success ) {
1301 577 $new_chart_id = wp_insert_post(
1302 578 array(
1303 579 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
@@ -1306,35 +582,23 @@
1306 582 'post_status' => $chart->post_status,
1307 583 'post_content' => $chart->post_content,
1308 584 )
1309 585 );
1310 - if ( is_wp_error( $new_chart_id ) ) {
1311 - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Error while cloning chart %d = %s', $chart_id, print_r( $new_chart_id, true ) ), 'error', __FILE__, __LINE__ );
1312 - } else {
1313 - $post_meta = get_post_meta( $chart_id );
1314 - foreach ( $post_meta as $key => $value ) {
1315 - if ( strpos( $key, 'visualizer-' ) !== false ) {
1316 - add_post_meta( $new_chart_id, $key, maybe_unserialize( $value[0] ) );
1317 - }
1318 - }
1319 - $redirect = esc_url(
1320 - add_query_arg(
1321 - array(
1322 - 'page' => 'visualizer',
1323 - 'type' => filter_input( INPUT_GET, 'type' ),
1324 - 'vaction' => false,
1325 - ),
1326 - admin_url( 'admin.php' )
586 + if ( $new_chart_id && ! is_wp_error( $new_chart_id ) ) {
587 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_CHART_TYPE, get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true ) );
588 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, get_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, true ) );
589 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SOURCE, get_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, true ) );
590 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SERIES, get_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, true ) );
591 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SETTINGS, get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true ) );
592 + $redirect = add_query_arg(
593 + array(
594 + 'page' => 'visualizer',
595 + 'type' => filter_input( INPUT_GET, 'type' ),
1327 596 ),
1328 - null,
1329 - 'db'
597 + admin_url( 'upload.php' )
1330 598 );
1331 599 }
1332 600 }
1333 -
1334 - if ( defined( 'WP_TESTS_DOMAIN' ) ) {
1335 - wp_die();
1336 - }
1337 601 wp_redirect( $redirect );
1338 602 exit;
1339 603 }
1340 604
@@ -1380,12 +644,9 @@
1380 644 $data = $this->_getChartArray();
1381 645 $render = new Visualizer_Render_Page_Data();
1382 646 $render->chart = $this->_chart;
1383 647 $render->type = $data['type'];
1384 -
1385 - if ( $data && $data['settings'] ) {
1386 - unset( $data['settings']['width'], $data['settings']['height'], $data['settings']['chartArea'] );
1387 - }
648 + unset( $data['settings']['width'], $data['settings']['height'] );
1388 649 wp_enqueue_style( 'visualizer-frame' );
1389 650 wp_enqueue_script( 'visualizer-render' );
1390 651 wp_localize_script(
1391 652 'visualizer-render',
@@ -1391,9 +652,9 @@
1391 652 'visualizer-render',
1392 653 'visualizer',
1393 654 array(
1394 655 'l10n' => array(
1395 - 'invalid_source' => esc_html__( 'You have entered an invalid URL. Please provide a valid URL.', 'visualizer' ),
656 + 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ),
1396 657 'loading' => esc_html__( 'Loading...', 'visualizer' ),
1397 658 ),
1398 659 'charts' => array(
1399 660 'canvas' => $data,
@@ -1399,210 +660,15 @@
1399 660 'canvas' => $data,
1400 661 ),
1401 662 )
1402 663 );
1403 -
1404 - do_action( 'visualizer_enqueue_scripts_and_styles', $data, $this->_chart->ID );
1405 -
1406 - if ( Visualizer_Module::is_pro() && Visualizer_Module::is_pro_older_than( '1.9.0' ) ) {
664 + // Added by Ash/Upwork
665 + if ( VISUALIZER_PRO ) {
1407 666 global $Visualizer_Pro;
1408 - $Visualizer_Pro->_enqueueScriptsAndStyles( $data, $this->_chart->ID );
667 + $Visualizer_Pro->_enqueueScriptsAndStyles( $data );
1409 668 }
1410 -
1411 669 // Added by Ash/Upwork
1412 670 $this->_addAction( 'admin_head', 'renderFlattrScript' );
1413 671 wp_iframe( array( $render, 'render' ) );
1414 672 }
1415 673
1416 - /**
1417 - * Returns the data for the query.
1418 - *
1419 - * @access public
1420 - */
1421 - public function getQueryData() {
1422 - check_ajax_referer( Visualizer_Plugin::ACTION_FETCH_DB_DATA . Visualizer_Plugin::VERSION, 'security' );
1423 -
1424 - $params = wp_parse_args( $_POST['params'] );
1425 - $chart_id = filter_var( $params['chart_id'], FILTER_VALIDATE_INT );
1426 -
1427 - $source = new Visualizer_Source_Query( stripslashes( $params['query'] ), $chart_id, $params );
1428 - $html = $source->fetch( true );
1429 - $error = $source->get_error();
1430 - if ( ! empty( $error ) ) {
1431 - wp_send_json_error( array( 'msg' => $error ) );
1432 - }
1433 - wp_send_json_success( array( 'table' => $html ) );
1434 - }
1435 -
1436 - /**
1437 - * Saves the query and the schedule.
1438 - *
1439 - * @access public
1440 - */
1441 - public function saveQuery() {
1442 - check_ajax_referer( Visualizer_Plugin::ACTION_SAVE_DB_QUERY . Visualizer_Plugin::VERSION, 'security' );
1443 -
1444 - $chart_id = filter_input(
1445 - INPUT_GET,
1446 - 'chart',
1447 - FILTER_VALIDATE_INT,
1448 - array(
1449 - 'options' => array(
1450 - 'min_range' => 1,
1451 - ),
1452 - )
1453 - );
1454 -
1455 - $hours = filter_input(
1456 - INPUT_POST,
1457 - 'refresh',
1458 - FILTER_VALIDATE_FLOAT,
1459 - array(
1460 - 'options' => array(
1461 - 'min_range' => -1,
1462 - 'max_range' => apply_filters( 'visualizer_is_business', false ) ? PHP_INT_MAX : -1,
1463 - ),
1464 - )
1465 - );
1466 -
1467 - if ( ! is_numeric( $hours ) ) {
1468 - $hours = -1;
1469 - }
1470 -
1471 - $render = new Visualizer_Render_Page_Update();
1472 - if ( $chart_id ) {
1473 - $params = wp_parse_args( $_POST['params'] );
1474 - $source = new Visualizer_Source_Query( stripslashes( $params['query'] ), $chart_id, $params );
1475 - $source->fetch( false );
1476 - $error = $source->get_error();
1477 - if ( empty( $error ) ) {
1478 - update_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY, stripslashes( $params['query'] ) );
1479 - update_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
1480 - update_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
1481 - update_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, $hours );
1482 - update_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
1483 - if ( isset( $params['db_type'] ) && $params['db_type'] !== Visualizer_Plugin::WP_DB_NAME ) {
1484 - $remote_db_params = $params;
1485 - unset( $remote_db_params['query'] );
1486 - unset( $remote_db_params['chart_id'] );
1487 - update_post_meta( $chart_id, Visualizer_Plugin::CF_REMOTE_DB_PARAMS, $remote_db_params );
1488 - }
1489 -
1490 - $schedules = get_option( Visualizer_Plugin::CF_DB_SCHEDULE, array() );
1491 - $schedules[ $chart_id ] = time() + $hours * HOUR_IN_SECONDS;
1492 - update_option( Visualizer_Plugin::CF_DB_SCHEDULE, $schedules );
1493 -
1494 - wp_update_post(
1495 - array(
1496 - 'ID' => $chart_id,
1497 - 'post_content' => $source->getData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ),
1498 - )
1499 - );
1500 - $render->data = json_encode( $source->getRawData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ) );
1501 - $render->series = json_encode( $source->getSeries() );
1502 - $render->id = $chart_id;
1503 - } else {
1504 - $render->message = $error;
1505 - }
1506 - }
1507 - $render->render();
1508 - if ( ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ) ) {
1509 - defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1510 - }
1511 - }
1512 -
1513 -
1514 - /**
1515 - * Saves the filter query and the schedule.
1516 - *
1517 - * @access public
1518 - */
1519 - public function saveFilter() {
1520 - check_ajax_referer( Visualizer_Plugin::ACTION_SAVE_FILTER_QUERY . Visualizer_Plugin::VERSION, 'security' );
1521 -
1522 - $chart_id = filter_input(
1523 - INPUT_GET,
1524 - 'chart',
1525 - FILTER_VALIDATE_INT,
1526 - array(
1527 - 'options' => array(
1528 - 'min_range' => 1,
1529 - ),
1530 - )
1531 - );
1532 -
1533 - $hours = filter_input(
1534 - INPUT_POST,
1535 - 'refresh',
1536 - FILTER_VALIDATE_INT,
1537 - array(
1538 - 'options' => array(
1539 - 'min_range' => -1,
1540 - 'max_range' => apply_filters( 'visualizer_is_business', false ) ? PHP_INT_MAX : -1,
1541 - ),
1542 - )
1543 - );
1544 -
1545 - if ( 0 !== $hours && empty( $hours ) ) {
1546 - $hours = -1;
1547 - }
1548 -
1549 - do_action( 'visualizer_save_filter', $chart_id, $hours );
1550 -
1551 - if ( ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ) ) {
1552 - defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1553 - }
1554 - }
1555 -
1556 - /**
1557 - * Save chart image.
1558 - *
1559 - * @param string $base64_img Chart image.
1560 - * @param int $chart_id Chart ID.
1561 - * @param bool $save_attachment Save attachment.
1562 - * @return attachment ID
1563 - */
1564 - public function save_chart_image( $base64_img, $chart_id, $save_attachment = true ) {
1565 - // Delete old chart image.
1566 - $old_attachment_id = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_IMAGE, true );
1567 - if ( $old_attachment_id ) {
1568 - wp_delete_attachment( $old_attachment_id, true );
1569 - }
1570 -
1571 - if ( ! $save_attachment ) {
1572 - return 0;
1573 - }
1574 -
1575 - // Upload dir.
1576 - $upload_dir = wp_upload_dir();
1577 - $upload_path = str_replace( '/', DIRECTORY_SEPARATOR, $upload_dir['path'] ) . DIRECTORY_SEPARATOR;
1578 -
1579 - $img = str_replace( 'data:image/png;base64,', '', $base64_img );
1580 - $img = str_replace( ' ', '+', $img );
1581 - $decoded = base64_decode( $img );
1582 - $filename = 'visualization-' . $chart_id . '.png';
1583 - $file_type = 'image/png';
1584 - $hashed_filename = $filename;
1585 -
1586 - // Save the image in the uploads directory.
1587 - require_once ABSPATH . '/wp-admin/includes/file.php';
1588 - \WP_Filesystem();
1589 - global $wp_filesystem;
1590 - if ( ! is_a( $wp_filesystem, 'WP_Filesystem_Base' ) ) {
1591 - $creds = request_filesystem_credentials( site_url() );
1592 - wp_filesystem( $creds );
1593 - }
1594 - $upload_file = $wp_filesystem->put_contents( $upload_path . $hashed_filename, $decoded );
1595 -
1596 - // Insert new chart image.
1597 - $attachment = array(
1598 - 'post_mime_type' => $file_type,
1599 - 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $hashed_filename ) ),
1600 - 'post_content' => '',
1601 - 'post_status' => 'inherit',
1602 - 'guid' => $upload_dir['url'] . '/' . basename( $hashed_filename ),
1603 - );
1604 -
1605 - $attach_id = wp_insert_attachment( $attachment, $upload_dir['path'] . '/' . $hashed_filename );
1606 - return $attach_id;
1607 - }
1608 674 }