PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.0.10
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.0.10
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 -1076 3.10.23.0.10 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,30 @@
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 310
794 311 // 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 312 // we do not want any difference in data so disable revisions temporarily.
796 - $this->disableRevisionsTemporarily();
797 -
313 + add_filter( 'wp_revisions_to_keep', '__return_false' );
798 314 wp_update_post( $this->_chart->to_array() );
799 315 }
800 316 // save meta data only when it is NOT being canceled.
801 317 if ( ! ( isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] ) ) ) {
802 318 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 319 }
826 320 $render = new Visualizer_Render_Page_Send();
827 321 $render->text = sprintf( '[visualizer id="%d"]', $this->_chart->ID );
828 322 wp_iframe( array( $render, 'render' ) );
323 +
829 324 return;
830 325 }
831 326 $data = $this->_getChartArray();
832 327 $sidebar = '';
833 - $sidebar_class = $this->load_chart_class_name( $this->_chart->ID );
328 + $sidebar_class = 'Visualizer_Render_Sidebar_Type_' . ucfirst( $data['type'] );
834 329 if ( class_exists( $sidebar_class, true ) ) {
835 330 $sidebar = new $sidebar_class( $data['settings'] );
836 331 $sidebar->__series = $data['series'];
837 332 $sidebar->__data = $data['data'];
@@ -836,108 +331,59 @@
836 331 $sidebar->__series = $data['series'];
837 332 $sidebar->__data = $data['data'];
838 333 } else {
839 334 $sidebar = apply_filters( 'visualizer_pro_chart_type_sidebar', '', $data );
840 - if ( $sidebar !== '' ) {
335 + if ( $sidebar != '' ) {
841 336 $sidebar->__series = $data['series'];
842 337 $sidebar->__data = $data['data'];
843 338 }
844 339 }
845 - unset( $data['settings']['width'], $data['settings']['height'], $data['settings']['chartArea'] );
340 + unset( $data['settings']['width'], $data['settings']['height'] );
341 + wp_enqueue_style( 'visualizer-frame' );
846 342 wp_enqueue_style( 'wp-color-picker' );
847 343 wp_enqueue_style( 'visualizer-frame' );
848 344 wp_enqueue_script( 'visualizer-preview' );
849 - wp_enqueue_script( 'visualizer-chosen' );
850 345 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 346 wp_localize_script(
872 - 'visualizer-render',
873 - 'visualizer',
874 - array(
347 + 'visualizer-render', 'visualizer', array(
875 348 'l10n' => array(
876 - 'invalid_source' => esc_html__( 'You have entered an invalid URL. Please provide a valid URL.', 'visualizer' ),
349 + 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ),
877 350 '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 351 ),
882 352 'charts' => array(
883 353 'canvas' => $data,
884 - 'id' => $this->_chart->ID,
885 354 ),
886 355 'language' => $this->get_language(),
887 356 'map_api_key' => get_option( 'visualizer-map-api-key' ),
888 - 'ajax' => array(
357 + 'ajax' => array(
889 358 'url' => admin_url( 'admin-ajax.php' ),
890 359 'nonces' => array(
891 360 '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 361 ),
897 362 'actions' => array(
898 363 '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 364 ),
904 365 ),
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 366 )
915 367 );
916 -
917 368 $render = new Visualizer_Render_Page_Data();
918 369 $render->chart = $this->_chart;
919 370 $render->type = $data['type'];
920 - $render->custom_css = $data['css'];
921 371 $render->sidebar = $sidebar;
922 372 if ( filter_input( INPUT_GET, 'library', FILTER_VALIDATE_BOOLEAN ) ) {
923 - $render->button = filter_input( INPUT_GET, 'action' ) === Visualizer_Plugin::ACTION_EDIT_CHART
373 + $render->button = filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART
924 374 ? esc_html__( 'Save Chart', 'visualizer' )
925 375 : esc_html__( 'Create Chart', 'visualizer' );
926 - if ( filter_input( INPUT_GET, 'action' ) === Visualizer_Plugin::ACTION_EDIT_CHART ) {
376 + if ( filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART ) {
927 377 $render->cancel_button = esc_html__( 'Cancel', 'visualizer' );
928 378 }
929 379 } else {
930 380 $render->button = esc_attr__( 'Insert Chart', 'visualizer' );
931 381 }
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' ) ) {
382 + if ( VISUALIZER_PRO ) {
936 383 global $Visualizer_Pro;
937 - $Visualizer_Pro->_enqueueScriptsAndStyles( $data, $this->_chart->ID );
384 + $Visualizer_Pro->_enqueueScriptsAndStyles( $data );
938 385 }
939 -
940 386 $this->_addAction( 'admin_head', 'renderFlattrScript' );
941 387 wp_iframe( array( $render, 'render' ) );
942 388 }
943 389
@@ -949,35 +395,24 @@
949 395 * @access private
950 396 */
951 397 private function _handleTypesPage() {
952 398 // process post request
953 - if ( $_SERVER['REQUEST_METHOD'] === 'POST' && wp_verify_nonce( filter_input( INPUT_POST, 'nonce' ) ) ) {
399 + if ( $_SERVER['REQUEST_METHOD'] == 'POST' && wp_verify_nonce( filter_input( INPUT_POST, 'nonce' ) ) ) {
954 400 $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 -
401 + if ( in_array( $type, Visualizer_Plugin::getChartTypes() ) ) {
963 402 // save new chart type
964 403 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 404 // if the chart has default data, update it with appropriate default data for new type
967 405 if ( filter_var( get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, true ), FILTER_VALIDATE_BOOLEAN ) ) {
968 406 $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $type . '.csv' );
969 407 $source->fetch();
970 - $this->_chart->post_content = $source->getData( get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) );
408 + $this->_chart->post_content = $source->getData();
971 409 wp_update_post( $this->_chart->to_array() );
972 410 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
973 411 }
974 -
975 - Visualizer_Module_Utility::set_defaults( $this->_chart );
976 -
977 412 // redirect to next tab
978 413 // changed by Ash/Upwork
979 - wp_redirect( esc_url_raw( add_query_arg( 'tab', 'settings' ) ) );
414 + wp_redirect( add_query_arg( 'tab', 'settings' ) );
980 415
981 416 return;
982 417 }
983 418 }
@@ -982,9 +417,9 @@
982 417 }
983 418 }
984 419 $render = new Visualizer_Render_Page_Types();
985 420 $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' );
421 + $render->types = Visualizer_Module_Admin::_getChartTypesLocalized();
987 422 $render->chart = $this->_chart;
988 423 wp_enqueue_style( 'visualizer-frame' );
989 424 wp_enqueue_script( 'visualizer-frame' );
990 425 wp_iframe( array( $render, 'render' ) );
@@ -1000,131 +435,10 @@
1000 435 */
1001 436 public function renderFlattrScript() {
1002 437 echo '';
1003 438 }
1004 -
439 + // changed by Ash/Upwork
1005 440 /**
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 441 * Parses uploaded CSV file and saves new data for the chart.
1128 442 *
1129 443 * @since 1.0.0
1130 444 *
@@ -1146,9 +460,9 @@
1146 460
1147 461 // check chart, if chart exists
1148 462 // do not use filter_input as it does not work for phpunit test cases, use filter_var instead
1149 463 $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 ) {
464 + if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
1151 465 if ( ! $can_die ) {
1152 466 return;
1153 467 }
1154 468 status_header( 400 );
@@ -1154,10 +468,8 @@
1154 468 status_header( 400 );
1155 469 exit;
1156 470 }
1157 471
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 472 if ( ! isset( $_POST['vz-import-time'] ) ) {
1161 473 apply_filters( 'visualizer_pro_remove_schedule', $chart_id );
1162 474 }
1163 475
@@ -1162,115 +474,37 @@
1162 474 }
1163 475
1164 476 if ( ! isset( $_POST['chart_data_src'] ) || Visualizer_Plugin::CF_SOURCE_FILTER !== $_POST['chart_data_src'] ) {
1165 477 // 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 );
478 + delete_post_meta( $chart_id, 'visualizer-filter-config' );
1174 479 }
1175 480
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 481 $source = null;
1192 482 $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 );
483 + if ( isset( $_POST['remote_data'] ) && filter_var( $_POST['remote_data'], FILTER_VALIDATE_URL ) ) {
484 + $source = new Visualizer_Source_Csv_Remote( $_POST['remote_data'] );
1200 485 if ( isset( $_POST['vz-import-time'] ) ) {
1201 - apply_filters( 'visualizer_pro_chart_schedule', $chart_id, $remote_data, $_POST['vz-import-time'] );
486 + apply_filters( 'visualizer_pro_chart_schedule', $chart_id, $_POST['remote_data'], $_POST['vz-import-time'] );
1202 487 }
1203 - // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
1204 488 } elseif ( isset( $_FILES['local_data'] ) && $_FILES['local_data']['error'] == 0 ) {
1205 489 $source = new Visualizer_Source_Csv( $_FILES['local_data']['tmp_name'] );
1206 490 } 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'] );
491 + $source = apply_filters( 'visualizer_pro_handle_chart_data', $_POST['chart_data'], '' );
1212 492 } 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' ) );
493 + $render->message = esc_html__( 'CSV file with chart data was not uploaded. Please, try again.', 'visualizer' );
1216 494 }
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 495 if ( $source ) {
1221 496 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 - }
497 + $chart->post_content = $source->getData();
1237 498 wp_update_post( $chart->to_array() );
1238 -
1239 499 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
1240 500 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
1241 501 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 ) ) );
502 + $render->data = json_encode( $source->getRawData() );
1260 503 $render->series = json_encode( $source->getSeries() );
1261 - $render->settings = json_encode( $settings );
1262 504 } 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 );
505 + $render->message = esc_html__( 'CSV file is broken or invalid. Please, try again.', 'visualizer' );
1270 506 }
1271 - } else {
1272 - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Unknown internal error for chart %d.', $chart_id ), 'error', __FILE__, __LINE__ );
1273 507 }
1274 508 $render->render();
1275 509 if ( ! $can_die ) {
1276 510 return;
@@ -1286,18 +520,24 @@
1286 520 * @access public
1287 521 */
1288 522 public function cloneChart() {
1289 523 $chart_id = $success = false;
1290 - $nonce = isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'], Visualizer_Plugin::ACTION_CLONE_CHART );
524 + $nonce = wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), Visualizer_Plugin::ACTION_CLONE_CHART );
1291 525 $capable = current_user_can( 'edit_posts' );
1292 526 if ( $nonce && $capable ) {
1293 - $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
527 + $chart_id = filter_input(
528 + INPUT_GET, 'chart', FILTER_VALIDATE_INT, array(
529 + 'options' => array(
530 + 'min_range' => 1,
531 + ),
532 + )
533 + );
1294 534 if ( $chart_id ) {
1295 535 $chart = get_post( $chart_id );
1296 - $success = $chart && $chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
536 + $success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
1297 537 }
1298 538 }
1299 - $redirect = remove_query_arg( 'vaction', wp_get_referer() );
539 + $redirect = wp_get_referer();
1300 540 if ( $success ) {
1301 541 $new_chart_id = wp_insert_post(
1302 542 array(
1303 543 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
@@ -1306,35 +546,22 @@
1306 546 'post_status' => $chart->post_status,
1307 547 'post_content' => $chart->post_content,
1308 548 )
1309 549 );
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'
550 + if ( $new_chart_id && ! is_wp_error( $new_chart_id ) ) {
551 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_CHART_TYPE, get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true ) );
552 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, get_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, true ) );
553 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SOURCE, get_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, true ) );
554 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SERIES, get_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, true ) );
555 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SETTINGS, get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true ) );
556 + $redirect = add_query_arg(
557 + array(
558 + 'page' => 'visualizer',
559 + 'type' => filter_input( INPUT_GET, 'type' ),
560 + ), admin_url( 'upload.php' )
1330 561 );
1331 562 }
1332 563 }
1333 -
1334 - if ( defined( 'WP_TESTS_DOMAIN' ) ) {
1335 - wp_die();
1336 - }
1337 564 wp_redirect( $redirect );
1338 565 exit;
1339 566 }
1340 567
@@ -1349,11 +576,9 @@
1349 576 check_ajax_referer( Visualizer_Plugin::ACTION_EXPORT_DATA . Visualizer_Plugin::VERSION, 'security' );
1350 577 $capable = current_user_can( 'edit_posts' );
1351 578 if ( $capable ) {
1352 579 $chart_id = isset( $_GET['chart'] ) ? filter_var(
1353 - $_GET['chart'],
1354 - FILTER_VALIDATE_INT,
1355 - array(
580 + $_GET['chart'], FILTER_VALIDATE_INT, array(
1356 581 'options' => array(
1357 582 'min_range' => 1,
1358 583 ),
1359 584 )
@@ -1380,20 +605,15 @@
1380 605 $data = $this->_getChartArray();
1381 606 $render = new Visualizer_Render_Page_Data();
1382 607 $render->chart = $this->_chart;
1383 608 $render->type = $data['type'];
1384 -
1385 - if ( $data && $data['settings'] ) {
1386 - unset( $data['settings']['width'], $data['settings']['height'], $data['settings']['chartArea'] );
1387 - }
609 + unset( $data['settings']['width'], $data['settings']['height'] );
1388 610 wp_enqueue_style( 'visualizer-frame' );
1389 611 wp_enqueue_script( 'visualizer-render' );
1390 612 wp_localize_script(
1391 - 'visualizer-render',
1392 - 'visualizer',
1393 - array(
613 + 'visualizer-render', 'visualizer', array(
1394 614 'l10n' => array(
1395 - 'invalid_source' => esc_html__( 'You have entered an invalid URL. Please provide a valid URL.', 'visualizer' ),
615 + 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ),
1396 616 'loading' => esc_html__( 'Loading...', 'visualizer' ),
1397 617 ),
1398 618 'charts' => array(
1399 619 'canvas' => $data,
@@ -1399,206 +619,15 @@
1399 619 'canvas' => $data,
1400 620 ),
1401 621 )
1402 622 );
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' ) ) {
623 + // Added by Ash/Upwork
624 + if ( VISUALIZER_PRO ) {
1407 625 global $Visualizer_Pro;
1408 - $Visualizer_Pro->_enqueueScriptsAndStyles( $data, $this->_chart->ID );
626 + $Visualizer_Pro->_enqueueScriptsAndStyles( $data );
1409 627 }
1410 -
1411 628 // Added by Ash/Upwork
1412 629 $this->_addAction( 'admin_head', 'renderFlattrScript' );
1413 630 wp_iframe( array( $render, 'render' ) );
1414 631 }
1415 632
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 - $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 - }
1604 633 }