PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.1.0
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.1.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 +114 -872 3.10.33.1.0 View file →
@@ -60,249 +60,11 @@
60 60 $this->_addAjaxAction( Visualizer_Plugin::ACTION_EXPORT_DATA, 'exportData' );
61 61
62 62 $this->_addAjaxAction( Visualizer_Plugin::ACTION_FETCH_DB_DATA, 'getQueryData' );
63 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 64 }
75 65
76 66 /**
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 67 * Fetches charts from database.
306 68 *
307 69 * This method is also called from the media pop-up (classic editor: create a post and add chart from insert content).
308 70 *
@@ -331,9 +93,9 @@
331 93 // 'filter' is from the modal from the add media button.
332 94 $filter = filter_input( INPUT_GET, 'filter', FILTER_SANITIZE_STRING );
333 95 }
334 96
335 - if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) {
97 + if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) {
336 98 $query_args['meta_query'] = array(
337 99 array(
338 100 'key' => Visualizer_Plugin::CF_CHART_TYPE,
339 101 'value' => $filter,
@@ -384,9 +146,9 @@
384 146 $chart = $this->_chart;
385 147 }
386 148 $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
387 149 $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 );
150 + $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( $chart->post_content ), $chart->ID, $type );
389 151 $library = $this->load_chart_type( $chart->ID );
390 152
391 153 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
392 154 $settings = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $settings, $chart->ID, $type );
@@ -400,10 +162,8 @@
400 162 $css = $arguments[0];
401 163 $settings = $arguments[1];
402 164 }
403 165
404 - $date_formats = Visualizer_Source::get_date_formats_if_exists( $series, $data );
405 -
406 166 return array(
407 167 'type' => $type,
408 168 'series' => $series,
409 169 'settings' => $settings,
@@ -409,9 +169,8 @@
409 169 'settings' => $settings,
410 170 'data' => $data,
411 171 'library' => $library,
412 172 'css' => $css,
413 - 'date_formats' => $date_formats,
414 173 );
415 174 }
416 175
417 176 /**
@@ -438,9 +197,9 @@
438 197 *
439 198 * @access public
440 199 */
441 200 public function deleteChart() {
442 - $is_post = $_SERVER['REQUEST_METHOD'] === 'POST';
201 + $is_post = $_SERVER['REQUEST_METHOD'] == 'POST';
443 202 $input_method = $is_post ? INPUT_POST : INPUT_GET;
444 203 $chart_id = $success = false;
445 204 $nonce = wp_verify_nonce( filter_input( $input_method, 'nonce' ) );
446 205 $capable = current_user_can( 'delete_posts' );
@@ -456,26 +215,13 @@
456 215 )
457 216 );
458 217 if ( $chart_id ) {
459 218 $chart = get_post( $chart_id );
460 - $success = $chart && $chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
219 + $success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
461 220 }
462 221 }
463 222 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 - }
223 + wp_delete_post( $chart_id, true );
478 224 }
479 225 if ( $is_post ) {
480 226 self::_sendResponse(
481 227 array(
@@ -482,41 +228,13 @@
482 228 'success' => $success,
483 229 )
484 230 );
485 231 }
486 - wp_redirect( remove_query_arg( 'vaction', wp_get_referer() ) );
232 + wp_redirect( wp_get_referer() );
487 233 exit;
488 234 }
489 235
490 236 /**
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 237 * Renders appropriate page for chart builder. Creates new auto draft chart
520 238 * if no chart has been specified.
521 239 *
522 240 * @since 1.0.0
@@ -524,119 +242,49 @@
524 242 * @access public
525 243 */
526 244 public function renderChartPages() {
527 245 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 246 // check chart, if chart not exists, will create new one and redirects to the same page with proper chart id
534 247 $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(
248 + if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
249 + $default_type = isset( $_GET['type'] ) && ! empty( $_GET['type'] ) ? $_GET['type'] : 'line';
250 + $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $default_type . '.csv' );
251 + $source->fetch();
252 + $chart_id = wp_insert_post(
253 + array(
254 + 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
255 + 'post_title' => 'Visualization',
256 + 'post_author' => get_current_user_id(),
257 + 'post_status' => 'auto-draft',
258 + 'post_content' => $source->getData(),
259 + )
260 + );
261 + if ( $chart_id && ! is_wp_error( $chart_id ) ) {
262 + add_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, $default_type );
263 + add_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 1 );
264 + add_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
265 + add_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
266 + add_post_meta(
267 + $chart_id,
268 + Visualizer_Plugin::CF_SETTINGS,
549 269 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 ) ),
270 + 'focusTarget' => 'datum',
555 271 )
556 272 );
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 273 do_action( 'visualizer_pro_new_chart_defaults', $chart_id );
606 274 }
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();
275 + wp_redirect( add_query_arg( 'chart', (int) $chart_id ) );
276 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
613 277 }
614 278
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;
279 + $this->load_chart_type( $chart_id );
617 280
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 281 // enqueue and register scripts and styles
634 282 wp_register_script( 'visualizer-chosen', VISUALIZER_ABSURL . 'js/lib/chosen.jquery.min.js', array( 'jquery' ), Visualizer_Plugin::VERSION );
635 283 wp_register_style( 'visualizer-chosen', VISUALIZER_ABSURL . 'css/lib/chosen.min.css', array(), Visualizer_Plugin::VERSION );
636 284
637 285 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 );
286 + wp_register_script( 'visualizer-frame', VISUALIZER_ABSURL . 'js/frame.js', array( 'visualizer-chosen' ), Visualizer_Plugin::VERSION, true );
639 287 wp_register_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
640 288 wp_register_script(
641 289 'visualizer-render',
642 290 VISUALIZER_ABSURL . 'js/render-facade.js',
@@ -647,23 +295,19 @@
647 295 wp_register_script(
648 296 'visualizer-preview',
649 297 VISUALIZER_ABSURL . 'js/preview.js',
650 298 array(
651 - $color_picker_dep,
299 + 'wp-color-picker',
652 300 'visualizer-render',
653 301 ),
654 302 Visualizer_Plugin::VERSION,
655 303 true
656 304 );
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' ) ) {
305 + // added by Ash/Upwork
306 + if ( VISUALIZER_PRO ) {
662 307 global $Visualizer_Pro;
663 308 $Visualizer_Pro->_addScriptsAndStyles();
664 309 }
665 -
666 310 // dispatch pages
667 311 $this->_chart = get_post( $chart_id );
668 312 $tab = isset( $_GET['tab'] ) && ! empty( $_GET['tab'] ) ? $_GET['tab'] : 'visualizer';
669 313
@@ -675,9 +319,8 @@
675 319 if ( isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] ) ) {
676 320 // if the cancel button is clicked.
677 321 $this->undoRevisions( $chart_id, true );
678 322 } elseif ( isset( $_POST['save'] ) && 1 === intval( $_POST['save'] ) ) {
679 - $this->handlePermissions();
680 323 // if the save button is clicked.
681 324 $this->undoRevisions( $chart_id, false );
682 325 } else {
683 326 // if the edit button is clicked.
@@ -683,16 +326,8 @@
683 326 // if the edit button is clicked.
684 327 $this->_chart = $this->handleExistingRevisions( $chart_id, $this->_chart );
685 328 }
686 329
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 330 switch ( $tab ) {
696 331 case 'settings':
697 332 $this->_handleDataAndSettingsPage();
698 333 break;
@@ -700,9 +335,9 @@
700 335 case 'visualizer': // fall through.
701 336 $this->_handleTypesPage();
702 337 break;
703 338 default:
704 - // this should never happen.
339 + do_action( 'visualizer_pro_handle_tab', $tab, $this->_chart );
705 340 break;
706 341 }
707 342 defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
708 343 }
@@ -709,26 +344,25 @@
709 344
710 345 /**
711 346 * Load code editor assets.
712 347 */
713 - private function loadCodeEditorAssets( $chart_id ) {
348 + private function loadCodeEditorAssets() {
714 349 global $wp_version;
715 350
716 - $wp_scripts = wp_scripts();
351 + if ( ! VISUALIZER_PRO ) {
352 + return;
353 + }
717 354
355 + $table_col_mapping = Visualizer_Source_Query_Params::get_all_db_tables_column_mapping();
356 +
718 357 // 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 );
358 + wp_register_script( 'visualizer-datatables', '//cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js', array( 'jquery-ui-core' ), Visualizer_Plugin::VERSION );
359 + wp_register_style( 'visualizer-datatables', '//cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css', array(), Visualizer_Plugin::VERSION );
360 + wp_register_style( 'visualizer-datatables-ui', '//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css', array( 'visualizer-datatables' ), Visualizer_Plugin::VERSION );
361 +
722 362 wp_enqueue_script( 'visualizer-datatables' );
723 - wp_enqueue_style( 'visualizer-jquery-ui' );
363 + wp_enqueue_style( 'visualizer-datatables-ui' );
724 364
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 365 if ( version_compare( $wp_version, '4.9.0', '<' ) ) {
732 366 // code mirror assets.
733 367 wp_register_script( 'visualizer-codemirror-core', '//codemirror.net/lib/codemirror.js', array( 'jquery' ), Visualizer_Plugin::VERSION );
734 368 wp_register_script( 'visualizer-codemirror-placeholder', '//codemirror.net/addon/display/placeholder.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
@@ -762,25 +396,8 @@
762 396 return $table_col_mapping;
763 397 }
764 398
765 399 /**
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 400 * Handle data and settings page
784 401 */
785 402 private function _handleDataAndSettingsPage() {
786 403 if ( isset( $_POST['map_api_key'] ) ) {
@@ -785,53 +402,30 @@
785 402 private function _handleDataAndSettingsPage() {
786 403 if ( isset( $_POST['map_api_key'] ) ) {
787 404 update_option( 'visualizer-map-api-key', $_POST['map_api_key'] );
788 405 }
789 -
790 - if ( $_SERVER['REQUEST_METHOD'] === 'POST' && isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'] ) ) {
791 - if ( $this->_chart->post_status === 'auto-draft' ) {
406 + if ( $_SERVER['REQUEST_METHOD'] == 'POST' && isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'] ) ) {
407 + if ( $this->_chart->post_status == 'auto-draft' ) {
792 408 $this->_chart->post_status = 'publish';
793 409
794 410 // 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 411 // we do not want any difference in data so disable revisions temporarily.
796 - $this->disableRevisionsTemporarily();
797 -
412 + add_filter( 'wp_revisions_to_keep', '__return_false' );
798 413 wp_update_post( $this->_chart->to_array() );
799 414 }
800 415 // save meta data only when it is NOT being canceled.
801 416 if ( ! ( isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] ) ) ) {
802 417 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 418 }
826 419 $render = new Visualizer_Render_Page_Send();
827 420 $render->text = sprintf( '[visualizer id="%d"]', $this->_chart->ID );
828 421 wp_iframe( array( $render, 'render' ) );
422 +
829 423 return;
830 424 }
831 425 $data = $this->_getChartArray();
832 426 $sidebar = '';
833 - $sidebar_class = $this->load_chart_class_name( $this->_chart->ID );
427 + $sidebar_class = 'Visualizer_Render_Sidebar_Type_' . ucfirst( $data['type'] );
834 428 if ( class_exists( $sidebar_class, true ) ) {
835 429 $sidebar = new $sidebar_class( $data['settings'] );
836 430 $sidebar->__series = $data['series'];
837 431 $sidebar->__data = $data['data'];
@@ -836,14 +430,14 @@
836 430 $sidebar->__series = $data['series'];
837 431 $sidebar->__data = $data['data'];
838 432 } else {
839 433 $sidebar = apply_filters( 'visualizer_pro_chart_type_sidebar', '', $data );
840 - if ( $sidebar !== '' ) {
434 + if ( $sidebar != '' ) {
841 435 $sidebar->__series = $data['series'];
842 436 $sidebar->__data = $data['data'];
843 437 }
844 438 }
845 - unset( $data['settings']['width'], $data['settings']['height'], $data['settings']['chartArea'] );
439 + unset( $data['settings']['width'], $data['settings']['height'] );
846 440 wp_enqueue_style( 'wp-color-picker' );
847 441 wp_enqueue_style( 'visualizer-frame' );
848 442 wp_enqueue_script( 'visualizer-preview' );
849 443 wp_enqueue_script( 'visualizer-chosen' );
@@ -848,37 +442,17 @@
848 442 wp_enqueue_script( 'visualizer-preview' );
849 443 wp_enqueue_script( 'visualizer-chosen' );
850 444 wp_enqueue_script( 'visualizer-render' );
851 445
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 - }
446 + $table_col_mapping = $this->loadCodeEditorAssets();
868 447
869 - $table_col_mapping = $this->loadCodeEditorAssets( $this->_chart->ID );
870 -
871 448 wp_localize_script(
872 449 'visualizer-render',
873 450 'visualizer',
874 451 array(
875 452 'l10n' => array(
876 - 'invalid_source' => esc_html__( 'You have entered an invalid URL. Please provide a valid URL.', 'visualizer' ),
453 + 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ),
877 454 '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 455 ),
882 456 'charts' => array(
883 457 'canvas' => $data,
884 458 'id' => $this->_chart->ID,
@@ -889,29 +463,19 @@
889 463 'url' => admin_url( 'admin-ajax.php' ),
890 464 'nonces' => array(
891 465 'permissions' => wp_create_nonce( Visualizer_Plugin::ACTION_FETCH_PERMISSIONS_DATA ),
892 466 '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 467 ),
897 468 'actions' => array(
898 469 'permissions' => Visualizer_Plugin::ACTION_FETCH_PERMISSIONS_DATA,
899 470 '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 471 ),
904 472 ),
905 473 'db_query' => array(
906 474 'tables' => $table_col_mapping,
907 475 ),
908 - 'is_pro' => Visualizer_Module::is_pro(),
476 + 'is_pro' => VISUALIZER_PRO,
909 477 '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 478 )
915 479 );
916 480
917 481 $render = new Visualizer_Render_Page_Data();
@@ -919,25 +483,21 @@
919 483 $render->type = $data['type'];
920 484 $render->custom_css = $data['css'];
921 485 $render->sidebar = $sidebar;
922 486 if ( filter_input( INPUT_GET, 'library', FILTER_VALIDATE_BOOLEAN ) ) {
923 - $render->button = filter_input( INPUT_GET, 'action' ) === Visualizer_Plugin::ACTION_EDIT_CHART
487 + $render->button = filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART
924 488 ? esc_html__( 'Save Chart', 'visualizer' )
925 489 : esc_html__( 'Create Chart', 'visualizer' );
926 - if ( filter_input( INPUT_GET, 'action' ) === Visualizer_Plugin::ACTION_EDIT_CHART ) {
490 + if ( filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART ) {
927 491 $render->cancel_button = esc_html__( 'Cancel', 'visualizer' );
928 492 }
929 493 } else {
930 494 $render->button = esc_attr__( 'Insert Chart', 'visualizer' );
931 495 }
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' ) ) {
496 + if ( VISUALIZER_PRO ) {
936 497 global $Visualizer_Pro;
937 - $Visualizer_Pro->_enqueueScriptsAndStyles( $data, $this->_chart->ID );
498 + $Visualizer_Pro->_enqueueScriptsAndStyles( $data );
938 499 }
939 -
940 500 $this->_addAction( 'admin_head', 'renderFlattrScript' );
941 501 wp_iframe( array( $render, 'render' ) );
942 502 }
943 503
@@ -949,35 +509,24 @@
949 509 * @access private
950 510 */
951 511 private function _handleTypesPage() {
952 512 // process post request
953 - if ( $_SERVER['REQUEST_METHOD'] === 'POST' && wp_verify_nonce( filter_input( INPUT_POST, 'nonce' ) ) ) {
513 + if ( $_SERVER['REQUEST_METHOD'] == 'POST' && wp_verify_nonce( filter_input( INPUT_POST, 'nonce' ) ) ) {
954 514 $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 -
515 + if ( in_array( $type, Visualizer_Plugin::getChartTypes() ) ) {
963 516 // save new chart type
964 517 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 518 // if the chart has default data, update it with appropriate default data for new type
967 519 if ( filter_var( get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, true ), FILTER_VALIDATE_BOOLEAN ) ) {
968 520 $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $type . '.csv' );
969 521 $source->fetch();
970 - $this->_chart->post_content = $source->getData( get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) );
522 + $this->_chart->post_content = $source->getData();
971 523 wp_update_post( $this->_chart->to_array() );
972 524 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
973 525 }
974 -
975 - Visualizer_Module_Utility::set_defaults( $this->_chart );
976 -
977 526 // redirect to next tab
978 527 // changed by Ash/Upwork
979 - wp_redirect( esc_url_raw( add_query_arg( 'tab', 'settings' ) ) );
528 + wp_redirect( add_query_arg( 'tab', 'settings' ) );
980 529
981 530 return;
982 531 }
983 532 }
@@ -982,9 +531,9 @@
982 531 }
983 532 }
984 533 $render = new Visualizer_Render_Page_Types();
985 534 $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' );
535 + $render->types = Visualizer_Module_Admin::_getChartTypesLocalized();
987 536 $render->chart = $this->_chart;
988 537 wp_enqueue_style( 'visualizer-frame' );
989 538 wp_enqueue_script( 'visualizer-frame' );
990 539 wp_iframe( array( $render, 'render' ) );
@@ -1000,131 +549,10 @@
1000 549 */
1001 550 public function renderFlattrScript() {
1002 551 echo '';
1003 552 }
1004 -
553 + // changed by Ash/Upwork
1005 554 /**
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 555 * Parses uploaded CSV file and saves new data for the chart.
1128 556 *
1129 557 * @since 1.0.0
1130 558 *
@@ -1146,9 +574,9 @@
1146 574
1147 575 // check chart, if chart exists
1148 576 // do not use filter_input as it does not work for phpunit test cases, use filter_var instead
1149 577 $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 ) {
578 + if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
1151 579 if ( ! $can_die ) {
1152 580 return;
1153 581 }
1154 582 status_header( 400 );
@@ -1154,10 +582,8 @@
1154 582 status_header( 400 );
1155 583 exit;
1156 584 }
1157 585
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 586 if ( ! isset( $_POST['vz-import-time'] ) ) {
1161 587 apply_filters( 'visualizer_pro_remove_schedule', $chart_id );
1162 588 }
1163 589
@@ -1162,65 +588,32 @@
1162 588 }
1163 589
1164 590 if ( ! isset( $_POST['chart_data_src'] ) || Visualizer_Plugin::CF_SOURCE_FILTER !== $_POST['chart_data_src'] ) {
1165 591 // 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 );
592 + delete_post_meta( $chart_id, 'visualizer-filter-config' );
1169 593
1170 594 // delete "import from db" specific parameters.
1171 595 delete_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY );
1172 596 delete_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE );
1173 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_REMOTE_DB_PARAMS );
1174 597 }
1175 598
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 599 $source = null;
1192 600 $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 );
601 + if ( isset( $_POST['remote_data'] ) && filter_var( $_POST['remote_data'], FILTER_VALIDATE_URL ) ) {
602 + $source = new Visualizer_Source_Csv_Remote( $_POST['remote_data'] );
1200 603 if ( isset( $_POST['vz-import-time'] ) ) {
1201 - apply_filters( 'visualizer_pro_chart_schedule', $chart_id, $remote_data, $_POST['vz-import-time'] );
604 + apply_filters( 'visualizer_pro_chart_schedule', $chart_id, $_POST['remote_data'], $_POST['vz-import-time'] );
1202 605 }
1203 - // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
1204 606 } elseif ( isset( $_FILES['local_data'] ) && $_FILES['local_data']['error'] == 0 ) {
1205 607 $source = new Visualizer_Source_Csv( $_FILES['local_data']['tmp_name'] );
1206 608 } 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'] );
609 + $source = apply_filters( 'visualizer_pro_handle_chart_data', $_POST['chart_data'], '' );
1212 610 } 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' ) );
611 + $render->message = esc_html__( 'CSV file with chart data was not uploaded. Please, try again.', 'visualizer' );
1216 612 }
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 613 if ( $source ) {
1221 614 if ( $source->fetch() ) {
1222 - $content = $source->getData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) );
615 + $content = $source->getData();
1223 616 $populate = true;
1224 617 if ( is_string( $content ) && is_array( unserialize( $content ) ) ) {
1225 618 $json = unserialize( $content );
1226 619 // if source exists, so should data. if source exists but data is blank, do not populate the chart.
@@ -1226,9 +619,8 @@
1226 619 // if source exists, so should data. if source exists but data is blank, do not populate the chart.
1227 620 // if we populate the data even if it is empty, the chart will show "Table has no columns".
1228 621 if ( array_key_exists( 'source', $json ) && ! empty( $json['source'] ) && ( ! array_key_exists( 'data', $json ) || empty( $json['data'] ) ) ) {
1229 622 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 623 $populate = false;
1232 624 }
1233 625 }
1234 626 if ( $populate ) {
@@ -1234,43 +626,17 @@
1234 626 if ( $populate ) {
1235 627 $chart->post_content = $content;
1236 628 }
1237 629 wp_update_post( $chart->to_array() );
1238 -
1239 630 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
1240 631 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
1241 632 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 633 $render->id = $chart->ID;
1259 - $render->data = json_encode( $source->getRawData( get_post_meta( $chart->ID, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ) );
634 + $render->data = json_encode( $source->getRawData() );
1260 635 $render->series = json_encode( $source->getSeries() );
1261 - $render->settings = json_encode( $settings );
1262 636 } 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 );
637 + $render->message = esc_html__( 'CSV file is broken or invalid. Please, try again.', 'visualizer' );
1270 638 }
1271 - } else {
1272 - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Unknown internal error for chart %d.', $chart_id ), 'error', __FILE__, __LINE__ );
1273 639 }
1274 640 $render->render();
1275 641 if ( ! $can_die ) {
1276 642 return;
@@ -1286,18 +652,27 @@
1286 652 * @access public
1287 653 */
1288 654 public function cloneChart() {
1289 655 $chart_id = $success = false;
1290 - $nonce = isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'], Visualizer_Plugin::ACTION_CLONE_CHART );
656 + $nonce = wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), Visualizer_Plugin::ACTION_CLONE_CHART );
1291 657 $capable = current_user_can( 'edit_posts' );
1292 658 if ( $nonce && $capable ) {
1293 - $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
659 + $chart_id = filter_input(
660 + INPUT_GET,
661 + 'chart',
662 + FILTER_VALIDATE_INT,
663 + array(
664 + 'options' => array(
665 + 'min_range' => 1,
666 + ),
667 + )
668 + );
1294 669 if ( $chart_id ) {
1295 670 $chart = get_post( $chart_id );
1296 - $success = $chart && $chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
671 + $success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
1297 672 }
1298 673 }
1299 - $redirect = remove_query_arg( 'vaction', wp_get_referer() );
674 + $redirect = wp_get_referer();
1300 675 if ( $success ) {
1301 676 $new_chart_id = wp_insert_post(
1302 677 array(
1303 678 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
@@ -1306,35 +681,23 @@
1306 681 'post_status' => $chart->post_status,
1307 682 'post_content' => $chart->post_content,
1308 683 )
1309 684 );
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' )
685 + if ( $new_chart_id && ! is_wp_error( $new_chart_id ) ) {
686 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_CHART_TYPE, get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true ) );
687 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, get_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, true ) );
688 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SOURCE, get_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, true ) );
689 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SERIES, get_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, true ) );
690 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SETTINGS, get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true ) );
691 + $redirect = add_query_arg(
692 + array(
693 + 'page' => 'visualizer',
694 + 'type' => filter_input( INPUT_GET, 'type' ),
1327 695 ),
1328 - null,
1329 - 'db'
696 + admin_url( 'upload.php' )
1330 697 );
1331 698 }
1332 699 }
1333 -
1334 - if ( defined( 'WP_TESTS_DOMAIN' ) ) {
1335 - wp_die();
1336 - }
1337 700 wp_redirect( $redirect );
1338 701 exit;
1339 702 }
1340 703
@@ -1380,12 +743,9 @@
1380 743 $data = $this->_getChartArray();
1381 744 $render = new Visualizer_Render_Page_Data();
1382 745 $render->chart = $this->_chart;
1383 746 $render->type = $data['type'];
1384 -
1385 - if ( $data && $data['settings'] ) {
1386 - unset( $data['settings']['width'], $data['settings']['height'], $data['settings']['chartArea'] );
1387 - }
747 + unset( $data['settings']['width'], $data['settings']['height'] );
1388 748 wp_enqueue_style( 'visualizer-frame' );
1389 749 wp_enqueue_script( 'visualizer-render' );
1390 750 wp_localize_script(
1391 751 'visualizer-render',
@@ -1391,9 +751,9 @@
1391 751 'visualizer-render',
1392 752 'visualizer',
1393 753 array(
1394 754 'l10n' => array(
1395 - 'invalid_source' => esc_html__( 'You have entered an invalid URL. Please provide a valid URL.', 'visualizer' ),
755 + 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ),
1396 756 'loading' => esc_html__( 'Loading...', 'visualizer' ),
1397 757 ),
1398 758 'charts' => array(
1399 759 'canvas' => $data,
@@ -1399,16 +759,13 @@
1399 759 'canvas' => $data,
1400 760 ),
1401 761 )
1402 762 );
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' ) ) {
763 + // Added by Ash/Upwork
764 + if ( VISUALIZER_PRO ) {
1407 765 global $Visualizer_Pro;
1408 - $Visualizer_Pro->_enqueueScriptsAndStyles( $data, $this->_chart->ID );
766 + $Visualizer_Pro->_enqueueScriptsAndStyles( $data );
1409 767 }
1410 -
1411 768 // Added by Ash/Upwork
1412 769 $this->_addAction( 'admin_head', 'renderFlattrScript' );
1413 770 wp_iframe( array( $render, 'render' ) );
1414 771 }
@@ -1421,14 +778,13 @@
1421 778 public function getQueryData() {
1422 779 check_ajax_referer( Visualizer_Plugin::ACTION_FETCH_DB_DATA . Visualizer_Plugin::VERSION, 'security' );
1423 780
1424 781 $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 );
782 + $source = new Visualizer_Source_Query( stripslashes( $params['query'] ) );
1428 783 $html = $source->fetch( true );
1429 - $error = $source->get_error();
1430 - if ( ! empty( $error ) ) {
784 + $error = '';
785 + if ( empty( $html ) ) {
786 + $error = $source->get_error();
1431 787 wp_send_json_error( array( 'msg' => $error ) );
1432 788 }
1433 789 wp_send_json_success( array( 'table' => $html ) );
1434 790 }
@@ -1451,42 +807,21 @@
1451 807 ),
1452 808 )
1453 809 );
1454 810
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 811 $render = new Visualizer_Render_Page_Update();
1472 812 if ( $chart_id ) {
1473 813 $params = wp_parse_args( $_POST['params'] );
1474 - $source = new Visualizer_Source_Query( stripslashes( $params['query'] ), $chart_id, $params );
814 + $source = new Visualizer_Source_Query( stripslashes( $params['query'] ) );
1475 815 $source->fetch( false );
1476 816 $error = $source->get_error();
1477 817 if ( empty( $error ) ) {
818 + $hours = $_POST['refresh'];
1478 819 update_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY, stripslashes( $params['query'] ) );
1479 820 update_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
1480 821 update_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
1481 822 update_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, $hours );
1482 823 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 824
1490 825 $schedules = get_option( Visualizer_Plugin::CF_DB_SCHEDULE, array() );
1491 826 $schedules[ $chart_id ] = time() + $hours * HOUR_IN_SECONDS;
1492 827 update_option( Visualizer_Plugin::CF_DB_SCHEDULE, $schedules );
@@ -1493,14 +828,13 @@
1493 828
1494 829 wp_update_post(
1495 830 array(
1496 831 'ID' => $chart_id,
1497 - 'post_content' => $source->getData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ),
832 + 'post_content' => $source->getData(),
1498 833 )
1499 834 );
1500 - $render->data = json_encode( $source->getRawData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ) );
835 + $render->data = json_encode( $source->getRawData() );
1501 836 $render->series = json_encode( $source->getSeries() );
1502 - $render->id = $chart_id;
1503 837 } else {
1504 838 $render->message = $error;
1505 839 }
1506 840 }
@@ -1507,98 +841,6 @@
1507 841 $render->render();
1508 842 if ( ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ) ) {
1509 843 defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1510 844 }
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 - $upload_file = $wp_filesystem->put_contents( $upload_path . $hashed_filename, $decoded );
1591 -
1592 - // Insert new chart image.
1593 - $attachment = array(
1594 - 'post_mime_type' => $file_type,
1595 - 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $hashed_filename ) ),
1596 - 'post_content' => '',
1597 - 'post_status' => 'inherit',
1598 - 'guid' => $upload_dir['url'] . '/' . basename( $hashed_filename ),
1599 - );
1600 -
1601 - $attach_id = wp_insert_attachment( $attachment, $upload_dir['path'] . '/' . $hashed_filename );
1602 - return $attach_id;
1603 845 }
1604 846 }