PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.0.9
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.0.9
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 +105 -1087 3.10.113.0.9 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 */
@@ -314,12 +71,9 @@
314 71 $query_args = array(
315 72 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
316 73 'posts_per_page' => 9,
317 74 'paged' => filter_input(
318 - INPUT_GET,
319 - 'page',
320 - FILTER_VALIDATE_INT,
321 - array(
75 + INPUT_GET, 'page', FILTER_VALIDATE_INT, array(
322 76 'options' => array(
323 77 'min_range' => 1,
324 78 'default' => 1,
325 79 ),
@@ -331,9 +85,9 @@
331 85 // 'filter' is from the modal from the add media button.
332 86 $filter = filter_input( INPUT_GET, 'filter', FILTER_SANITIZE_STRING );
333 87 }
334 88
335 - if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) {
89 + if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) {
336 90 $query_args['meta_query'] = array(
337 91 array(
338 92 'key' => Visualizer_Plugin::CF_CHART_TYPE,
339 93 'value' => $filter,
@@ -346,18 +100,8 @@
346 100 while ( $query->have_posts() ) {
347 101 $chart = $query->next_post();
348 102 $chart_data = $this->_getChartArray( $chart );
349 103 $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 104 $charts[] = $chart_data;
361 105 }
362 106 self::_sendResponse(
363 107 array(
@@ -384,34 +128,15 @@
384 128 $chart = $this->_chart;
385 129 }
386 130 $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
387 131 $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 );
132 + $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( $chart->post_content ), $chart->ID, $type );
390 133
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 134 return array(
407 135 'type' => $type,
408 136 'series' => $series,
409 - 'settings' => $settings,
137 + 'settings' => get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true ),
410 138 'data' => $data,
411 - 'library' => $library,
412 - 'css' => $css,
413 - 'date_formats' => $date_formats,
414 139 );
415 140 }
416 141
417 142 /**
@@ -438,9 +163,9 @@
438 163 *
439 164 * @access public
440 165 */
441 166 public function deleteChart() {
442 - $is_post = $_SERVER['REQUEST_METHOD'] === 'POST';
167 + $is_post = $_SERVER['REQUEST_METHOD'] == 'POST';
443 168 $input_method = $is_post ? INPUT_POST : INPUT_GET;
444 169 $chart_id = $success = false;
445 170 $nonce = wp_verify_nonce( filter_input( $input_method, 'nonce' ) );
446 171 $capable = current_user_can( 'delete_posts' );
@@ -445,12 +170,9 @@
445 170 $nonce = wp_verify_nonce( filter_input( $input_method, 'nonce' ) );
446 171 $capable = current_user_can( 'delete_posts' );
447 172 if ( $nonce && $capable ) {
448 173 $chart_id = filter_input(
449 - $input_method,
450 - 'chart',
451 - FILTER_VALIDATE_INT,
452 - array(
174 + $input_method, 'chart', FILTER_VALIDATE_INT, array(
453 175 'options' => array(
454 176 'min_range' => 1,
455 177 ),
456 178 )
@@ -456,26 +178,13 @@
456 178 )
457 179 );
458 180 if ( $chart_id ) {
459 181 $chart = get_post( $chart_id );
460 - $success = $chart && $chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
182 + $success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
461 183 }
462 184 }
463 185 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 - }
186 + wp_delete_post( $chart_id, true );
478 187 }
479 188 if ( $is_post ) {
480 189 self::_sendResponse(
481 190 array(
@@ -482,41 +191,13 @@
482 191 'success' => $success,
483 192 )
484 193 );
485 194 }
486 - wp_redirect( remove_query_arg( 'vaction', wp_get_referer() ) );
195 + wp_redirect( wp_get_referer() );
487 196 exit;
488 197 }
489 198
490 199 /**
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 200 * Renders appropriate page for chart builder. Creates new auto draft chart
520 201 * if no chart has been specified.
521 202 *
522 203 * @since 1.0.0
@@ -524,146 +205,64 @@
524 205 * @access public
525 206 */
526 207 public function renderChartPages() {
527 208 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 209 // check chart, if chart not exists, will create new one and redirects to the same page with proper chart id
534 210 $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(
549 - 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 ) ),
211 + if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
212 + $default_type = isset( $_GET['type'] ) && ! empty( $_GET['type'] ) ? $_GET['type'] : 'line';
213 + $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $default_type . '.csv' );
214 + $source->fetch();
215 + $chart_id = wp_insert_post(
216 + array(
217 + 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
218 + 'post_title' => 'Visualization',
219 + 'post_author' => get_current_user_id(),
220 + 'post_status' => 'auto-draft',
221 + 'post_content' => $source->getData(),
222 + )
223 + );
224 + if ( $chart_id && ! is_wp_error( $chart_id ) ) {
225 + add_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, $default_type );
226 + add_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 1 );
227 + add_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
228 + add_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
229 + add_post_meta(
230 + $chart_id, Visualizer_Plugin::CF_SETTINGS, array(
231 + 'focusTarget' => 'datum',
555 232 )
556 233 );
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 234 do_action( 'visualizer_pro_new_chart_defaults', $chart_id );
606 235 }
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();
236 + wp_redirect( add_query_arg( 'chart', (int) $chart_id ) );
237 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
613 238 }
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 239 // enqueue and register scripts and styles
634 240 wp_register_script( 'visualizer-chosen', VISUALIZER_ABSURL . 'js/lib/chosen.jquery.min.js', array( 'jquery' ), Visualizer_Plugin::VERSION );
635 241 wp_register_style( 'visualizer-chosen', VISUALIZER_ABSURL . 'css/lib/chosen.min.css', array(), Visualizer_Plugin::VERSION );
636 242
637 243 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 );
639 - wp_register_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
244 + wp_register_script( 'visualizer-frame', VISUALIZER_ABSURL . 'js/frame.js', array( 'visualizer-chosen' ), Visualizer_Plugin::VERSION, true );
245 + wp_register_script( 'google-jsapi-new', '//www.gstatic.com/charts/loader.js', array(), null, true );
246 + wp_register_script( 'google-jsapi-old', '//www.google.com/jsapi', array( 'google-jsapi-new' ), null, true );
640 247 wp_register_script(
641 - 'visualizer-render',
642 - VISUALIZER_ABSURL . 'js/render-facade.js',
643 - apply_filters( 'visualizer_assets_render', array( 'visualizer-frame', 'visualizer-customization' ), false ),
644 - Visualizer_Plugin::VERSION,
645 - true
248 + 'visualizer-render', VISUALIZER_ABSURL . 'js/render.js', array(
249 + 'google-jsapi-old',
250 + 'google-jsapi-new',
251 + 'visualizer-frame',
252 + ), Visualizer_Plugin::VERSION, true
646 253 );
647 254 wp_register_script(
648 - 'visualizer-preview',
649 - VISUALIZER_ABSURL . 'js/preview.js',
650 - array(
651 - $color_picker_dep,
255 + 'visualizer-preview', VISUALIZER_ABSURL . 'js/preview.js', array(
256 + 'wp-color-picker',
652 257 'visualizer-render',
653 - ),
654 - Visualizer_Plugin::VERSION,
655 - true
258 + ), Visualizer_Plugin::VERSION, true
656 259 );
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' ) ) {
260 + // added by Ash/Upwork
261 + if ( VISUALIZER_PRO ) {
662 262 global $Visualizer_Pro;
663 263 $Visualizer_Pro->_addScriptsAndStyles();
664 264 }
665 -
666 265 // dispatch pages
667 266 $this->_chart = get_post( $chart_id );
668 267 $tab = isset( $_GET['tab'] ) && ! empty( $_GET['tab'] ) ? $_GET['tab'] : 'visualizer';
669 268
@@ -675,9 +274,8 @@
675 274 if ( isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] ) ) {
676 275 // if the cancel button is clicked.
677 276 $this->undoRevisions( $chart_id, true );
678 277 } elseif ( isset( $_POST['save'] ) && 1 === intval( $_POST['save'] ) ) {
679 - $this->handlePermissions();
680 278 // if the save button is clicked.
681 279 $this->undoRevisions( $chart_id, false );
682 280 } else {
683 281 // if the edit button is clicked.
@@ -683,16 +281,8 @@
683 281 // if the edit button is clicked.
684 282 $this->_chart = $this->handleExistingRevisions( $chart_id, $this->_chart );
685 283 }
686 284
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 285 switch ( $tab ) {
696 286 case 'settings':
697 287 $this->_handleDataAndSettingsPage();
698 288 break;
@@ -700,9 +290,9 @@
700 290 case 'visualizer': // fall through.
701 291 $this->_handleTypesPage();
702 292 break;
703 293 default:
704 - // this should never happen.
294 + do_action( 'visualizer_pro_handle_tab', $tab, $this->_chart );
705 295 break;
706 296 }
707 297 defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
708 298 }
@@ -707,80 +297,8 @@
707 297 defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
708 298 }
709 299
710 300 /**
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 301 * Handle data and settings page
784 302 */
785 303 private function _handleDataAndSettingsPage() {
786 304 if ( isset( $_POST['map_api_key'] ) ) {
@@ -785,53 +303,23 @@
785 303 private function _handleDataAndSettingsPage() {
786 304 if ( isset( $_POST['map_api_key'] ) ) {
787 305 update_option( 'visualizer-map-api-key', $_POST['map_api_key'] );
788 306 }
789 -
790 - if ( $_SERVER['REQUEST_METHOD'] === 'POST' && isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'] ) ) {
791 - if ( $this->_chart->post_status === 'auto-draft' ) {
307 + if ( $_SERVER['REQUEST_METHOD'] == 'POST' && isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'] ) ) {
308 + if ( $this->_chart->post_status == 'auto-draft' ) {
792 309 $this->_chart->post_status = 'publish';
793 -
794 - // 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 - // we do not want any difference in data so disable revisions temporarily.
796 - $this->disableRevisionsTemporarily();
797 -
798 310 wp_update_post( $this->_chart->to_array() );
799 311 }
800 - // save meta data only when it is NOT being canceled.
801 - if ( ! ( isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] ) ) ) {
802 - 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 - }
312 + update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $_POST );
826 313 $render = new Visualizer_Render_Page_Send();
827 314 $render->text = sprintf( '[visualizer id="%d"]', $this->_chart->ID );
828 315 wp_iframe( array( $render, 'render' ) );
316 +
829 317 return;
830 318 }
831 319 $data = $this->_getChartArray();
832 320 $sidebar = '';
833 - $sidebar_class = $this->load_chart_class_name( $this->_chart->ID );
321 + $sidebar_class = 'Visualizer_Render_Sidebar_Type_' . ucfirst( $data['type'] );
834 322 if ( class_exists( $sidebar_class, true ) ) {
835 323 $sidebar = new $sidebar_class( $data['settings'] );
836 324 $sidebar->__series = $data['series'];
837 325 $sidebar->__data = $data['data'];
@@ -836,108 +324,59 @@
836 324 $sidebar->__series = $data['series'];
837 325 $sidebar->__data = $data['data'];
838 326 } else {
839 327 $sidebar = apply_filters( 'visualizer_pro_chart_type_sidebar', '', $data );
840 - if ( $sidebar !== '' ) {
328 + if ( $sidebar != '' ) {
841 329 $sidebar->__series = $data['series'];
842 330 $sidebar->__data = $data['data'];
843 331 }
844 332 }
845 - unset( $data['settings']['width'], $data['settings']['height'], $data['settings']['chartArea'] );
333 + unset( $data['settings']['width'], $data['settings']['height'] );
334 + wp_enqueue_style( 'visualizer-frame' );
846 335 wp_enqueue_style( 'wp-color-picker' );
847 336 wp_enqueue_style( 'visualizer-frame' );
848 337 wp_enqueue_script( 'visualizer-preview' );
849 - wp_enqueue_script( 'visualizer-chosen' );
850 338 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 339 wp_localize_script(
872 - 'visualizer-render',
873 - 'visualizer',
874 - array(
340 + 'visualizer-render', 'visualizer', array(
875 341 'l10n' => array(
876 - 'invalid_source' => esc_html__( 'You have entered an invalid URL. Please provide a valid URL.', 'visualizer' ),
342 + 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ),
877 343 '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 344 ),
882 345 'charts' => array(
883 346 'canvas' => $data,
884 - 'id' => $this->_chart->ID,
885 347 ),
886 348 'language' => $this->get_language(),
887 349 'map_api_key' => get_option( 'visualizer-map-api-key' ),
888 - 'ajax' => array(
350 + 'ajax' => array(
889 351 'url' => admin_url( 'admin-ajax.php' ),
890 352 'nonces' => array(
891 353 '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 354 ),
897 355 'actions' => array(
898 356 '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 357 ),
904 358 ),
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 359 )
915 360 );
916 -
917 361 $render = new Visualizer_Render_Page_Data();
918 362 $render->chart = $this->_chart;
919 363 $render->type = $data['type'];
920 - $render->custom_css = $data['css'];
921 364 $render->sidebar = $sidebar;
922 365 if ( filter_input( INPUT_GET, 'library', FILTER_VALIDATE_BOOLEAN ) ) {
923 - $render->button = filter_input( INPUT_GET, 'action' ) === Visualizer_Plugin::ACTION_EDIT_CHART
366 + $render->button = filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART
924 367 ? esc_html__( 'Save Chart', 'visualizer' )
925 368 : esc_html__( 'Create Chart', 'visualizer' );
926 - if ( filter_input( INPUT_GET, 'action' ) === Visualizer_Plugin::ACTION_EDIT_CHART ) {
369 + if ( filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART ) {
927 370 $render->cancel_button = esc_html__( 'Cancel', 'visualizer' );
928 371 }
929 372 } else {
930 373 $render->button = esc_attr__( 'Insert Chart', 'visualizer' );
931 374 }
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' ) ) {
375 + if ( VISUALIZER_PRO ) {
936 376 global $Visualizer_Pro;
937 - $Visualizer_Pro->_enqueueScriptsAndStyles( $data, $this->_chart->ID );
377 + $Visualizer_Pro->_enqueueScriptsAndStyles( $data );
938 378 }
939 -
940 379 $this->_addAction( 'admin_head', 'renderFlattrScript' );
941 380 wp_iframe( array( $render, 'render' ) );
942 381 }
943 382
@@ -949,35 +388,24 @@
949 388 * @access private
950 389 */
951 390 private function _handleTypesPage() {
952 391 // process post request
953 - if ( $_SERVER['REQUEST_METHOD'] === 'POST' && wp_verify_nonce( filter_input( INPUT_POST, 'nonce' ) ) ) {
392 + if ( $_SERVER['REQUEST_METHOD'] == 'POST' && wp_verify_nonce( filter_input( INPUT_POST, 'nonce' ) ) ) {
954 393 $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 -
394 + if ( in_array( $type, Visualizer_Plugin::getChartTypes() ) ) {
963 395 // save new chart type
964 396 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 397 // if the chart has default data, update it with appropriate default data for new type
967 398 if ( filter_var( get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, true ), FILTER_VALIDATE_BOOLEAN ) ) {
968 399 $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $type . '.csv' );
969 400 $source->fetch();
970 - $this->_chart->post_content = $source->getData( get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) );
401 + $this->_chart->post_content = $source->getData();
971 402 wp_update_post( $this->_chart->to_array() );
972 403 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
973 404 }
974 -
975 - Visualizer_Module_Utility::set_defaults( $this->_chart );
976 -
977 405 // redirect to next tab
978 406 // changed by Ash/Upwork
979 - wp_redirect( esc_url_raw( add_query_arg( 'tab', 'settings' ) ) );
407 + wp_redirect( add_query_arg( 'tab', 'settings' ) );
980 408
981 409 return;
982 410 }
983 411 }
@@ -982,9 +410,9 @@
982 410 }
983 411 }
984 412 $render = new Visualizer_Render_Page_Types();
985 413 $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' );
414 + $render->types = Visualizer_Module_Admin::_getChartTypesLocalized();
987 415 $render->chart = $this->_chart;
988 416 wp_enqueue_style( 'visualizer-frame' );
989 417 wp_enqueue_script( 'visualizer-frame' );
990 418 wp_iframe( array( $render, 'render' ) );
@@ -1000,131 +428,10 @@
1000 428 */
1001 429 public function renderFlattrScript() {
1002 430 echo '';
1003 431 }
1004 -
432 + // changed by Ash/Upwork
1005 433 /**
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 434 * Parses uploaded CSV file and saves new data for the chart.
1128 435 *
1129 436 * @since 1.0.0
1130 437 *
@@ -1146,9 +453,9 @@
1146 453
1147 454 // check chart, if chart exists
1148 455 // do not use filter_input as it does not work for phpunit test cases, use filter_var instead
1149 456 $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 ) {
457 + if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
1151 458 if ( ! $can_die ) {
1152 459 return;
1153 460 }
1154 461 status_header( 400 );
@@ -1154,10 +461,8 @@
1154 461 status_header( 400 );
1155 462 exit;
1156 463 }
1157 464
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 465 if ( ! isset( $_POST['vz-import-time'] ) ) {
1161 466 apply_filters( 'visualizer_pro_remove_schedule', $chart_id );
1162 467 }
1163 468
@@ -1162,115 +467,37 @@
1162 467 }
1163 468
1164 469 if ( ! isset( $_POST['chart_data_src'] ) || Visualizer_Plugin::CF_SOURCE_FILTER !== $_POST['chart_data_src'] ) {
1165 470 // 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 );
471 + delete_post_meta( $chart_id, 'visualizer-filter-config' );
1174 472 }
1175 473
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 474 $source = null;
1192 475 $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 );
476 + if ( isset( $_POST['remote_data'] ) && filter_var( $_POST['remote_data'], FILTER_VALIDATE_URL ) ) {
477 + $source = new Visualizer_Source_Csv_Remote( $_POST['remote_data'] );
1200 478 if ( isset( $_POST['vz-import-time'] ) ) {
1201 - apply_filters( 'visualizer_pro_chart_schedule', $chart_id, $remote_data, $_POST['vz-import-time'] );
479 + apply_filters( 'visualizer_pro_chart_schedule', $chart_id, $_POST['remote_data'], $_POST['vz-import-time'] );
1202 480 }
1203 - // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
1204 481 } elseif ( isset( $_FILES['local_data'] ) && $_FILES['local_data']['error'] == 0 ) {
1205 482 $source = new Visualizer_Source_Csv( $_FILES['local_data']['tmp_name'] );
1206 483 } 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'] );
484 + $source = apply_filters( 'visualizer_pro_handle_chart_data', $_POST['chart_data'], '' );
1212 485 } 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' ) );
486 + $render->message = esc_html__( 'CSV file with chart data was not uploaded. Please, try again.', 'visualizer' );
1216 487 }
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 488 if ( $source ) {
1221 489 if ( $source->fetch() ) {
1222 - $content = $source->getData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) );
1223 - $populate = true;
1224 - if ( is_string( $content ) && is_array( unserialize( $content ) ) ) {
1225 - $json = unserialize( $content );
1226 - // if source exists, so should data. if source exists but data is blank, do not populate the chart.
1227 - // if we populate the data even if it is empty, the chart will show "Table has no columns".
1228 - if ( array_key_exists( 'source', $json ) && ! empty( $json['source'] ) && ( ! array_key_exists( 'data', $json ) || empty( $json['data'] ) ) ) {
1229 - 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 - $populate = false;
1232 - }
1233 - }
1234 - if ( $populate ) {
1235 - $chart->post_content = $content;
1236 - }
490 + $chart->post_content = $source->getData();
1237 491 wp_update_post( $chart->to_array() );
1238 -
1239 492 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
1240 493 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
1241 494 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 ) ) );
495 + $render->data = json_encode( $source->getRawData() );
1260 496 $render->series = json_encode( $source->getSeries() );
1261 - $render->settings = json_encode( $settings );
1262 497 } 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 );
498 + $render->message = esc_html__( 'CSV file is broken or invalid. Please, try again.', 'visualizer' );
1270 499 }
1271 - } else {
1272 - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Unknown internal error for chart %d.', $chart_id ), 'error', __FILE__, __LINE__ );
1273 500 }
1274 501 $render->render();
1275 502 if ( ! $can_die ) {
1276 503 return;
@@ -1286,18 +513,24 @@
1286 513 * @access public
1287 514 */
1288 515 public function cloneChart() {
1289 516 $chart_id = $success = false;
1290 - $nonce = isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'], Visualizer_Plugin::ACTION_CLONE_CHART );
517 + $nonce = wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), Visualizer_Plugin::ACTION_CLONE_CHART );
1291 518 $capable = current_user_can( 'edit_posts' );
1292 519 if ( $nonce && $capable ) {
1293 - $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
520 + $chart_id = filter_input(
521 + INPUT_GET, 'chart', FILTER_VALIDATE_INT, array(
522 + 'options' => array(
523 + 'min_range' => 1,
524 + ),
525 + )
526 + );
1294 527 if ( $chart_id ) {
1295 528 $chart = get_post( $chart_id );
1296 - $success = $chart && $chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
529 + $success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
1297 530 }
1298 531 }
1299 - $redirect = remove_query_arg( 'vaction', wp_get_referer() );
532 + $redirect = wp_get_referer();
1300 533 if ( $success ) {
1301 534 $new_chart_id = wp_insert_post(
1302 535 array(
1303 536 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
@@ -1306,35 +539,22 @@
1306 539 'post_status' => $chart->post_status,
1307 540 'post_content' => $chart->post_content,
1308 541 )
1309 542 );
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' )
1327 - ),
1328 - null,
1329 - 'db'
543 + if ( $new_chart_id && ! is_wp_error( $new_chart_id ) ) {
544 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_CHART_TYPE, get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true ) );
545 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, get_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, true ) );
546 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SOURCE, get_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, true ) );
547 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SERIES, get_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, true ) );
548 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SETTINGS, get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true ) );
549 + $redirect = add_query_arg(
550 + array(
551 + 'page' => 'visualizer',
552 + 'type' => filter_input( INPUT_GET, 'type' ),
553 + ), admin_url( 'upload.php' )
1330 554 );
1331 555 }
1332 556 }
1333 -
1334 - if ( defined( 'WP_TESTS_DOMAIN' ) ) {
1335 - wp_die();
1336 - }
1337 557 wp_redirect( $redirect );
1338 558 exit;
1339 559 }
1340 560
@@ -1349,11 +569,9 @@
1349 569 check_ajax_referer( Visualizer_Plugin::ACTION_EXPORT_DATA . Visualizer_Plugin::VERSION, 'security' );
1350 570 $capable = current_user_can( 'edit_posts' );
1351 571 if ( $capable ) {
1352 572 $chart_id = isset( $_GET['chart'] ) ? filter_var(
1353 - $_GET['chart'],
1354 - FILTER_VALIDATE_INT,
1355 - array(
573 + $_GET['chart'], FILTER_VALIDATE_INT, array(
1356 574 'options' => array(
1357 575 'min_range' => 1,
1358 576 ),
1359 577 )
@@ -1380,20 +598,15 @@
1380 598 $data = $this->_getChartArray();
1381 599 $render = new Visualizer_Render_Page_Data();
1382 600 $render->chart = $this->_chart;
1383 601 $render->type = $data['type'];
1384 -
1385 - if ( $data && $data['settings'] ) {
1386 - unset( $data['settings']['width'], $data['settings']['height'], $data['settings']['chartArea'] );
1387 - }
602 + unset( $data['settings']['width'], $data['settings']['height'] );
1388 603 wp_enqueue_style( 'visualizer-frame' );
1389 604 wp_enqueue_script( 'visualizer-render' );
1390 605 wp_localize_script(
1391 - 'visualizer-render',
1392 - 'visualizer',
1393 - array(
606 + 'visualizer-render', 'visualizer', array(
1394 607 'l10n' => array(
1395 - 'invalid_source' => esc_html__( 'You have entered an invalid URL. Please provide a valid URL.', 'visualizer' ),
608 + 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ),
1396 609 'loading' => esc_html__( 'Loading...', 'visualizer' ),
1397 610 ),
1398 611 'charts' => array(
1399 612 'canvas' => $data,
@@ -1399,210 +612,15 @@
1399 612 'canvas' => $data,
1400 613 ),
1401 614 )
1402 615 );
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' ) ) {
616 + // Added by Ash/Upwork
617 + if ( VISUALIZER_PRO ) {
1407 618 global $Visualizer_Pro;
1408 - $Visualizer_Pro->_enqueueScriptsAndStyles( $data, $this->_chart->ID );
619 + $Visualizer_Pro->_enqueueScriptsAndStyles( $data );
1409 620 }
1410 -
1411 621 // Added by Ash/Upwork
1412 622 $this->_addAction( 'admin_head', 'renderFlattrScript' );
1413 623 wp_iframe( array( $render, 'render' ) );
1414 624 }
1415 625
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 626 }