PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 1.7.1
Visualizer – Tables & Charts Manager with Built-in AI Generator v1.7.1
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 3.10.4 All 148 releases
← All changes | classes/Visualizer/Module/Chart.php +309 -1287 3.10.21.7.1 View file →
@@ -1,5 +1,6 @@
1 1 <?php
2 +
2 3 // +----------------------------------------------------------------------+
3 4 // | Copyright 2013 Madpixels (email : visualizer@madpixels.net) |
4 5 // +----------------------------------------------------------------------+
5 6 // | This program is free software; you can redistribute it and/or modify |
@@ -45,13 +46,13 @@
45 46 *
46 47 * @since 1.0.0
47 48 *
48 49 * @access public
49 - *
50 50 * @param Visualizer_Plugin $plugin The instance of the plugin.
51 51 */
52 52 public function __construct( Visualizer_Plugin $plugin ) {
53 53 parent::__construct( $plugin );
54 +
54 55 $this->_addAjaxAction( Visualizer_Plugin::ACTION_GET_CHARTS, 'getCharts' );
55 56 $this->_addAjaxAction( Visualizer_Plugin::ACTION_DELETE_CHART, 'deleteChart' );
56 57 $this->_addAjaxAction( Visualizer_Plugin::ACTION_CREATE_CHART, 'renderChartPages' );
57 58 $this->_addAjaxAction( Visualizer_Plugin::ACTION_EDIT_CHART, 'renderChartPages' );
@@ -56,257 +57,64 @@
56 57 $this->_addAjaxAction( Visualizer_Plugin::ACTION_CREATE_CHART, 'renderChartPages' );
57 58 $this->_addAjaxAction( Visualizer_Plugin::ACTION_EDIT_CHART, 'renderChartPages' );
58 59 $this->_addAjaxAction( Visualizer_Plugin::ACTION_UPLOAD_DATA, 'uploadData' );
59 60 $this->_addAjaxAction( Visualizer_Plugin::ACTION_CLONE_CHART, 'cloneChart' );
61 +
62 + // Added by Ash/Upwork
60 63 $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 - }
75 -
76 - /**
77 - * Generates the HTML of the sidebar for the chart.
78 - *
79 - * @since ?
80 - *
81 - * @access public
82 - */
83 - public function getSidebar( $sidebar, $chart_id ) {
84 - $chart = get_post( $chart_id );
85 - $data = $this->_getChartArray( $chart );
86 - $sidebar = '';
87 - $sidebar_class = $this->load_chart_class_name( $chart_id );
88 - if ( class_exists( $sidebar_class, true ) ) {
89 - $sidebar = new $sidebar_class( $data['settings'] );
90 - $sidebar->__series = $data['series'];
91 - $sidebar->__data = $data['data'];
92 - } else {
93 - $sidebar = apply_filters( 'visualizer_pro_chart_type_sidebar', '', $data );
94 - if ( $sidebar !== '' ) {
95 - $sidebar->__series = $data['series'];
96 - $sidebar->__data = $data['data'];
97 - }
64 + if ( defined( 'Visualizer_Pro' ) ) {
65 + global $Visualizer_Pro;
66 + list($action, $name, $class) = $Visualizer_Pro->_getAjaxAction( $this );
67 + $this->_addAjaxAction( $action, $name, $class );
98 68 }
99 - return str_replace( "'", '"', $sidebar->__toString() );
69 + // Added by Ash/Upwork
100 70 }
101 71
102 72 /**
103 - * Sets the schedule for how JSON-endpoint charts should be updated.
73 + * Sends json response.
104 74 *
105 - * @since ?
75 + * @since 1.0.0
106 76 *
107 - * @access public
77 + * @access private
78 + * @param array $results The response array.
108 79 */
109 - public function setJsonSchedule() {
110 - check_ajax_referer( Visualizer_Plugin::ACTION_JSON_SET_SCHEDULE . Visualizer_Plugin::VERSION, 'security' );
80 + public function _sendResponse( $results ) {
81 + header( 'Content-type: application/json' );
82 + nocache_headers();
111 83
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();
84 + echo json_encode( $results );
85 + exit;
162 86 }
163 87
164 88 /**
165 - * Get the root elements for JSON-endpoint.
89 + * Returns chart data required for rendering.
166 90 *
167 - * @since ?
91 + * @since 1.0.0
168 92 *
169 - * @access public
93 + * @access private
94 + * @param WP_Post $chart The chart object.
95 + * @return array The array of chart data.
170 96 */
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() ) );
97 + private function _getChartArray( WP_Post $chart = null ) {
98 + if ( is_null( $chart ) ) {
99 + $chart = $this->_chart;
181 100 }
182 101
183 - wp_send_json_success( array( 'url' => $params['url'], 'roots' => $roots ) );
184 - }
102 + $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
103 + $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
104 + $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( $chart->post_content ), $chart->ID, $type );
185 105
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 - )
106 + return array(
107 + 'type' => $type,
108 + 'series' => $series,
109 + 'settings' => get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true ),
110 + 'data' => $data,
280 111 );
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 112 }
302 113
303 -
304 114 /**
305 115 * Fetches charts from database.
306 116 *
307 - * This method is also called from the media pop-up (classic editor: create a post and add chart from insert content).
308 - *
309 117 * @since 1.0.0
310 118 *
311 119 * @access public
312 120 */
@@ -313,27 +121,18 @@
313 121 public function getCharts() {
314 122 $query_args = array(
315 123 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
316 124 'posts_per_page' => 9,
317 - 'paged' => filter_input(
318 - INPUT_GET,
319 - 'page',
320 - FILTER_VALIDATE_INT,
321 - array(
322 - 'options' => array(
323 - 'min_range' => 1,
324 - 'default' => 1,
325 - ),
326 - )
327 - ),
125 + 'paged' => filter_input( INPUT_GET, 'page', FILTER_VALIDATE_INT, array(
126 + 'options' => array(
127 + 'min_range' => 1,
128 + 'default' => 1,
129 + ),
130 + ) ),
328 131 );
329 - $filter = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
330 - if ( empty( $filter ) ) {
331 - // 'filter' is from the modal from the add media button.
332 - $filter = filter_input( INPUT_GET, 'filter', FILTER_SANITIZE_STRING );
333 - }
334 132
335 - if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) {
133 + $filter = filter_input( INPUT_GET, 'filter', FILTER_SANITIZE_STRING );
134 + if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) {
336 135 $query_args['meta_query'] = array(
337 136 array(
338 137 'key' => Visualizer_Plugin::CF_CHART_TYPE,
339 138 'value' => $filter,
@@ -340,98 +139,29 @@
340 139 'compare' => '=',
341 140 ),
342 141 );
343 142 }
344 - $query = new WP_Query( $query_args );
143 +
144 + $query = new WP_Query( $query_args );
145 +
345 146 $charts = array();
346 147 while ( $query->have_posts() ) {
347 - $chart = $query->next_post();
348 - $chart_data = $this->_getChartArray( $chart );
148 + $chart = $query->next_post();
149 +
150 + $chart_data = $this->_getChartArray( $chart );
349 151 $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 - $charts[] = $chart_data;
361 - }
362 - self::_sendResponse(
363 - array(
364 - 'success' => true,
365 - 'data' => $charts,
366 - 'total' => $query->max_num_pages,
367 - )
368 - );
369 - }
370 152
371 - /**
372 - * Returns chart data required for rendering.
373 - *
374 - * @since 1.0.0
375 - *
376 - * @access private
377 - *
378 - * @param WP_Post $chart The chart object.
379 - *
380 - * @return array The array of chart data.
381 - */
382 - private function _getChartArray( WP_Post $chart = null ) {
383 - if ( is_null( $chart ) ) {
384 - $chart = $this->_chart;
153 + $charts[] = $chart_data;
385 154 }
386 - $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
387 - $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 );
390 155
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 - return array(
407 - 'type' => $type,
408 - 'series' => $series,
409 - 'settings' => $settings,
410 - 'data' => $data,
411 - 'library' => $library,
412 - 'css' => $css,
413 - 'date_formats' => $date_formats,
414 - );
156 + $this->_sendResponse( array(
157 + 'success' => true,
158 + 'data' => $charts,
159 + 'total' => $query->max_num_pages,
160 + ) );
415 161 }
416 162
417 163 /**
418 - * Sends json response.
419 - *
420 - * @since 1.0.0
421 - *
422 - * @access private
423 - *
424 - * @param array $results The response array.
425 - */
426 - public static function _sendResponse( $results ) {
427 - header( 'Content-type: application/json' );
428 - nocache_headers();
429 - echo json_encode( $results );
430 - defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
431 - }
432 -
433 - /**
434 164 * Deletes a chart from database.
435 165 *
436 166 * @since 1.0.0
437 167 * @uses wp_delete_post() To delete a chart.
@@ -438,85 +168,35 @@
438 168 *
439 169 * @access public
440 170 */
441 171 public function deleteChart() {
442 - $is_post = $_SERVER['REQUEST_METHOD'] === 'POST';
172 + $is_post = $_SERVER['REQUEST_METHOD'] == 'POST';
443 173 $input_method = $is_post ? INPUT_POST : INPUT_GET;
444 - $chart_id = $success = false;
445 - $nonce = wp_verify_nonce( filter_input( $input_method, 'nonce' ) );
446 - $capable = current_user_can( 'delete_posts' );
174 +
175 + $chart_id = $success = false;
176 + $nonce = wp_verify_nonce( filter_input( $input_method, 'nonce' ) );
177 + $capable = current_user_can( 'delete_posts' );
447 178 if ( $nonce && $capable ) {
448 - $chart_id = filter_input(
449 - $input_method,
450 - 'chart',
451 - FILTER_VALIDATE_INT,
452 - array(
453 - 'options' => array(
454 - 'min_range' => 1,
455 - ),
456 - )
457 - );
179 + $chart_id = filter_input( $input_method, 'chart', FILTER_VALIDATE_INT, array( 'options' => array( 'min_range' => 1 ) ) );
458 180 if ( $chart_id ) {
459 - $chart = get_post( $chart_id );
460 - $success = $chart && $chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
181 + $chart = get_post( $chart_id );
182 + $success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
461 183 }
462 184 }
185 +
463 186 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 - }
187 + wp_delete_post( $chart_id, true );
478 188 }
189 +
479 190 if ( $is_post ) {
480 - self::_sendResponse(
481 - array(
482 - 'success' => $success,
483 - )
484 - );
191 + $this->_sendResponse( array( 'success' => $success ) );
485 192 }
486 - wp_redirect( remove_query_arg( 'vaction', wp_get_referer() ) );
193 +
194 + wp_redirect( wp_get_referer() );
487 195 exit;
488 196 }
489 197
490 198 /**
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 199 * Renders appropriate page for chart builder. Creates new auto draft chart
520 200 * if no chart has been specified.
521 201 *
522 202 * @since 1.0.0
@@ -523,261 +203,150 @@
523 203 *
524 204 * @access public
525 205 */
526 206 public function renderChartPages() {
527 - 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' );
207 + define( 'IFRAME_REQUEST', 1 );
208 +
533 209 // check chart, if chart not exists, will create new one and redirects to the same page with proper chart id
534 - $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 ) ),
555 - )
556 - );
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 - );
210 + $chart_id = filter_input( INPUT_GET, 'chart', FILTER_VALIDATE_INT );
211 + if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
212 + $default_type = 'line';
570 213
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 - );
214 + $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $default_type . '.csv' );
215 + $source->fetch();
591 216
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 - do_action( 'visualizer_pro_new_chart_defaults', $chart_id );
606 - }
607 - wp_redirect( esc_url_raw( add_query_arg( 'chart', (int) $chart_id ) ) );
217 + $chart_id = wp_insert_post( array(
218 + 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
219 + 'post_title' => 'Visualization',
220 + 'post_author' => get_current_user_id(),
221 + 'post_status' => 'auto-draft',
222 + 'post_content' => $source->getData(),
223 + ) );
608 224
609 - if ( defined( 'WP_TESTS_DOMAIN' ) ) {
610 - wp_die();
225 + if ( $chart_id && ! is_wp_error( $chart_id ) ) {
226 + add_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, $default_type );
227 + add_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 1 );
228 + add_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
229 + add_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
230 + add_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, array( 'focusTarget' => 'datum' ) );
611 231 }
612 - exit();
613 - }
614 232
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 - }
233 + wp_redirect( add_query_arg( 'chart', (int) $chart_id ) );
234 + exit;
623 235 }
624 - $lib = $this->load_chart_type( $chart_id );
625 236
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 237 // enqueue and register scripts and styles
634 - wp_register_script( 'visualizer-chosen', VISUALIZER_ABSURL . 'js/lib/chosen.jquery.min.js', array( 'jquery' ), Visualizer_Plugin::VERSION );
635 - wp_register_style( 'visualizer-chosen', VISUALIZER_ABSURL . 'css/lib/chosen.min.css', array(), Visualizer_Plugin::VERSION );
238 + wp_register_style( 'visualizer-frame', VISUALIZER_ABSURL . 'css/frame.css', array(), Visualizer_Plugin::VERSION );
636 239
637 - 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 );
640 - 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
646 - );
647 - wp_register_script(
648 - 'visualizer-preview',
649 - VISUALIZER_ABSURL . 'js/preview.js',
650 - array(
651 - $color_picker_dep,
652 - 'visualizer-render',
653 - ),
654 - Visualizer_Plugin::VERSION,
655 - true
656 - );
657 - wp_register_script( 'visualizer-editor-simple', VISUALIZER_ABSURL . 'js/simple-editor.js', array( 'jquery' ), Visualizer_Plugin::VERSION, true );
240 + wp_register_script( 'visualizer-frame', VISUALIZER_ABSURL . 'js/frame.js', array( 'jquery' ), Visualizer_Plugin::VERSION, true );
241 + wp_register_script( 'google-jsapi-new', '//www.gstatic.com/charts/loader.js', array(), null, true );
242 + wp_register_script( 'google-jsapi-old', '//www.google.com/jsapi', array( 'google-jsapi-new' ), null, true );
243 + wp_register_script( 'visualizer-render', VISUALIZER_ABSURL . 'js/render.js', array( 'google-jsapi-old', 'google-jsapi-new', 'visualizer-frame' ), Visualizer_Plugin::VERSION, true );
244 + wp_register_script( 'visualizer-preview', VISUALIZER_ABSURL . 'js/preview.js', array( 'wp-color-picker', 'visualizer-render' ), Visualizer_Plugin::VERSION, true );
658 245
659 - do_action( 'visualizer_add_scripts' );
660 -
661 - if ( Visualizer_Module::is_pro() && Visualizer_Module::is_pro_older_than( '1.9.0' ) ) {
246 + // added by Ash/Upwork
247 + if ( defined( 'Visualizer_Pro' ) ) {
662 248 global $Visualizer_Pro;
663 249 $Visualizer_Pro->_addScriptsAndStyles();
664 250 }
665 251
666 252 // dispatch pages
667 - $this->_chart = get_post( $chart_id );
668 - $tab = isset( $_GET['tab'] ) && ! empty( $_GET['tab'] ) ? $_GET['tab'] : 'visualizer';
669 -
670 - // skip chart type pages only for existing charts.
671 - if ( VISUALIZER_SKIP_CHART_TYPE_PAGE && 'auto-draft' !== $this->_chart->post_status && ( ! empty( $_GET['tab'] ) && 'visualizer' === $_GET['tab'] ) ) {
672 - $tab = 'settings';
673 - }
674 -
675 - if ( isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] ) ) {
676 - // if the cancel button is clicked.
677 - $this->undoRevisions( $chart_id, true );
678 - } elseif ( isset( $_POST['save'] ) && 1 === intval( $_POST['save'] ) ) {
679 - $this->handlePermissions();
680 - // if the save button is clicked.
681 - $this->undoRevisions( $chart_id, false );
682 - } else {
683 - // if the edit button is clicked.
684 - $this->_chart = $this->handleExistingRevisions( $chart_id, $this->_chart );
685 - }
686 -
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 - switch ( $tab ) {
253 + $this->_chart = $chart;
254 + switch ( filter_input( INPUT_GET, 'tab' ) ) {
696 255 case 'settings':
256 + // changed by Ash/Upwork
697 257 $this->_handleDataAndSettingsPage();
698 258 break;
699 - case 'type': // fall through.
700 - case 'visualizer': // fall through.
259 + case 'type':
260 + default:
701 261 $this->_handleTypesPage();
702 262 break;
703 - default:
704 - // this should never happen.
705 - break;
706 263 }
707 - defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
264 +
265 + exit;
708 266 }
709 267
710 268 /**
711 - * Load code editor assets.
269 + * Handles chart type selection page.
270 + *
271 + * @since 1.0.0
272 + *
273 + * @access private
712 274 */
713 - private function loadCodeEditorAssets( $chart_id ) {
714 - global $wp_version;
275 + private function _handleTypesPage() {
276 + // process post request
277 + if ( $_SERVER['REQUEST_METHOD'] == 'POST' && wp_verify_nonce( filter_input( INPUT_POST, 'nonce' ) ) ) {
278 + $type = filter_input( INPUT_POST, 'type' );
279 + if ( in_array( $type, Visualizer_Plugin::getChartTypes() ) ) {
280 + // save new chart type
281 + update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_CHART_TYPE, $type );
715 282
716 - $wp_scripts = wp_scripts();
283 + // if the chart has default data, update it with appropriate default data for new type
284 + if ( filter_var( get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, true ), FILTER_VALIDATE_BOOLEAN ) ) {
285 + $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $type . '.csv' );
286 + $source->fetch();
717 287
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' );
288 + $this->_chart->post_content = $source->getData();
289 + wp_update_post( $this->_chart->to_array() );
724 290
725 - if ( ! Visualizer_Module::is_pro() ) {
726 - return;
291 + update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
292 + }
293 +
294 + // redirect to next tab
295 + // changed by Ash/Upwork
296 + wp_redirect( add_query_arg( 'tab', 'settings' ) );
297 + return;
298 + }
727 299 }
728 300
729 - $table_col_mapping = Visualizer_Source_Query_Params::get_all_db_tables_column_mapping( $chart_id );
301 + $render = new Visualizer_Render_Page_Types();
302 + $render->type = get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
303 + $render->types = Visualizer_Plugin::getChartTypes();
304 + $render->chart = $this->_chart;
730 305
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 );
306 + wp_enqueue_style( 'visualizer-frame' );
307 + wp_enqueue_script( 'visualizer-frame' );
742 308
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;
309 + wp_iframe( array( $render, 'render' ) );
763 310 }
764 311
765 312 /**
766 - * Handle permissions from the new conslidated settings sidebar.
313 + * Handles chart data page.
314 + *
315 + * @since 1.0.0
316 + *
317 + * @access private
767 318 */
768 - private function handlePermissions() {
769 - if ( ! Visualizer_Module::is_pro() ) {
770 - return;
319 + private function _handleDataPage() {
320 + $data = $this->_getChartArray();
321 +
322 + $render = new Visualizer_Render_Page_Data();
323 + $render->chart = $this->_chart;
324 + $render->type = $data['type'];
325 +
326 + unset( $data['settings']['width'], $data['settings']['height'] );
327 +
328 + wp_enqueue_style( 'visualizer-frame' );
329 + wp_enqueue_script( 'visualizer-render' );
330 + wp_localize_script( 'visualizer-render', 'visualizer', array(
331 + 'l10n' => array(
332 + 'remotecsv_prompt' => esc_html__( 'Please, enter the URL of CSV file:', 'visualizer' ),
333 + 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ),
334 + ),
335 + 'charts' => array(
336 + 'canvas' => $data,
337 + ),
338 + ) );
339 +
340 + // Added by Ash/Upwork
341 + if ( defined( 'Visualizer_Pro' ) ) {
342 + global $Visualizer_Pro;
343 + $Visualizer_Pro->_enqueueScriptsAndStyles( $data );
771 344 }
345 + // Added by Ash/Upwork
346 + $this->_addAction( 'admin_head', 'renderFlattrScript' );
772 347
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 - }
348 + wp_iframe( array( $render, 'render' ) );
780 349 }
781 350
782 351 /**
783 352 * Handle data and settings page
@@ -782,215 +351,80 @@
782 351 /**
783 352 * Handle data and settings page
784 353 */
785 354 private function _handleDataAndSettingsPage() {
786 - if ( isset( $_POST['map_api_key'] ) ) {
787 - update_option( 'visualizer-map-api-key', $_POST['map_api_key'] );
788 - }
789 -
790 - if ( $_SERVER['REQUEST_METHOD'] === 'POST' && isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'] ) ) {
791 - if ( $this->_chart->post_status === 'auto-draft' ) {
355 + if ( $_SERVER['REQUEST_METHOD'] == 'POST' && wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ) ) ) {
356 + if ( $this->_chart->post_status == 'auto-draft' ) {
792 357 $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 358 wp_update_post( $this->_chart->to_array() );
799 359 }
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 360
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 - }
826 - $render = new Visualizer_Render_Page_Send();
361 + update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $_POST );
362 +
363 + $render = new Visualizer_Render_Page_Send();
827 364 $render->text = sprintf( '[visualizer id="%d"]', $this->_chart->ID );
365 +
828 366 wp_iframe( array( $render, 'render' ) );
829 367 return;
830 368 }
831 - $data = $this->_getChartArray();
832 - $sidebar = '';
833 - $sidebar_class = $this->load_chart_class_name( $this->_chart->ID );
369 +
370 + $data = $this->_getChartArray();
371 +
372 + $sidebar = '';
373 + $sidebar_class = 'Visualizer_Render_Sidebar_Type_' . ucfirst( $data['type'] );
834 374 if ( class_exists( $sidebar_class, true ) ) {
835 - $sidebar = new $sidebar_class( $data['settings'] );
375 + $sidebar = new $sidebar_class( $data['settings'] );
836 376 $sidebar->__series = $data['series'];
837 - $sidebar->__data = $data['data'];
377 + $sidebar->__data = $data['data'];
838 378 } else {
839 - $sidebar = apply_filters( 'visualizer_pro_chart_type_sidebar', '', $data );
840 - if ( $sidebar !== '' ) {
379 + $sidebar = apply_filters( 'visualizer_pro_chart_type_sidebar', '', $data );
380 + if ( $sidebar != '' ) {
841 381 $sidebar->__series = $data['series'];
842 - $sidebar->__data = $data['data'];
382 + $sidebar->__data = $data['data'];
843 383 }
844 384 }
845 - unset( $data['settings']['width'], $data['settings']['height'], $data['settings']['chartArea'] );
385 +
386 + unset( $data['settings']['width'], $data['settings']['height'] );
387 +
388 + wp_enqueue_style( 'visualizer-frame' );
846 389 wp_enqueue_style( 'wp-color-picker' );
847 390 wp_enqueue_style( 'visualizer-frame' );
391 +
848 392 wp_enqueue_script( 'visualizer-preview' );
849 - wp_enqueue_script( 'visualizer-chosen' );
850 393 wp_enqueue_script( 'visualizer-render' );
394 + wp_localize_script( 'visualizer-render', 'visualizer', array(
395 + 'l10n' => array(
396 + 'remotecsv_prompt' => esc_html__( 'Please, enter the URL of CSV file:', 'visualizer' ),
397 + 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ),
398 + ),
399 + 'charts' => array(
400 + 'canvas' => $data,
401 + ),
402 + ) );
851 403
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 - }
404 + $render = new Visualizer_Render_Page_Data();
405 + $render->chart = $this->_chart;
406 + $render->type = $data['type'];
868 407
869 - $table_col_mapping = $this->loadCodeEditorAssets( $this->_chart->ID );
870 -
871 - wp_localize_script(
872 - 'visualizer-render',
873 - 'visualizer',
874 - array(
875 - 'l10n' => array(
876 - 'invalid_source' => esc_html__( 'You have entered an invalid URL. Please provide a valid URL.', 'visualizer' ),
877 - '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 - ),
882 - 'charts' => array(
883 - 'canvas' => $data,
884 - 'id' => $this->_chart->ID,
885 - ),
886 - 'language' => $this->get_language(),
887 - 'map_api_key' => get_option( 'visualizer-map-api-key' ),
888 - 'ajax' => array(
889 - 'url' => admin_url( 'admin-ajax.php' ),
890 - 'nonces' => array(
891 - '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 - ),
897 - 'actions' => array(
898 - '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 - ),
904 - ),
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 - )
915 - );
916 -
917 - $render = new Visualizer_Render_Page_Data();
918 - $render->chart = $this->_chart;
919 - $render->type = $data['type'];
920 - $render->custom_css = $data['css'];
921 408 $render->sidebar = $sidebar;
922 409 if ( filter_input( INPUT_GET, 'library', FILTER_VALIDATE_BOOLEAN ) ) {
923 - $render->button = filter_input( INPUT_GET, 'action' ) === Visualizer_Plugin::ACTION_EDIT_CHART
410 + $render->button = filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART
924 411 ? esc_html__( 'Save Chart', 'visualizer' )
925 412 : esc_html__( 'Create Chart', 'visualizer' );
926 - if ( filter_input( INPUT_GET, 'action' ) === Visualizer_Plugin::ACTION_EDIT_CHART ) {
927 - $render->cancel_button = esc_html__( 'Cancel', 'visualizer' );
928 - }
929 413 } else {
930 414 $render->button = esc_attr__( 'Insert Chart', 'visualizer' );
931 415 }
932 416
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' ) ) {
417 + if ( defined( 'Visualizer_Pro' ) ) {
936 418 global $Visualizer_Pro;
937 - $Visualizer_Pro->_enqueueScriptsAndStyles( $data, $this->_chart->ID );
419 + $Visualizer_Pro->_enqueueScriptsAndStyles( $data );
938 420 }
939 421
940 422 $this->_addAction( 'admin_head', 'renderFlattrScript' );
941 - wp_iframe( array( $render, 'render' ) );
942 - }
943 423
944 - /**
945 - * Handles chart type selection page.
946 - *
947 - * @since 1.0.0
948 - *
949 - * @access private
950 - */
951 - private function _handleTypesPage() {
952 - // process post request
953 - if ( $_SERVER['REQUEST_METHOD'] === 'POST' && wp_verify_nonce( filter_input( INPUT_POST, 'nonce' ) ) ) {
954 - $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 -
963 - // save new chart type
964 - 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 - // if the chart has default data, update it with appropriate default data for new type
967 - if ( filter_var( get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, true ), FILTER_VALIDATE_BOOLEAN ) ) {
968 - $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $type . '.csv' );
969 - $source->fetch();
970 - $this->_chart->post_content = $source->getData( get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) );
971 - wp_update_post( $this->_chart->to_array() );
972 - update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
973 - }
974 -
975 - Visualizer_Module_Utility::set_defaults( $this->_chart );
976 -
977 - // redirect to next tab
978 - // changed by Ash/Upwork
979 - wp_redirect( esc_url_raw( add_query_arg( 'tab', 'settings' ) ) );
980 -
981 - return;
982 - }
983 - }
984 - $render = new Visualizer_Render_Page_Types();
985 - $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' );
987 - $render->chart = $this->_chart;
988 - wp_enqueue_style( 'visualizer-frame' );
989 - wp_enqueue_script( 'visualizer-frame' );
990 424 wp_iframe( array( $render, 'render' ) );
991 425 }
992 -
426 + // changed by Ash/Upwork
993 427 /**
994 428 * Renders flattr script in the iframe <head>
995 429 *
996 430 * @since 1.4.2
@@ -1002,129 +436,8 @@
1002 436 echo '';
1003 437 }
1004 438
1005 439 /**
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 440 * Parses uploaded CSV file and saves new data for the chart.
1128 441 *
1129 442 * @since 1.0.0
1130 443 *
@@ -1130,111 +443,40 @@
1130 443 *
1131 444 * @access public
1132 445 */
1133 446 public function uploadData() {
1134 - // if this is being called internally from pro and VISUALIZER_DO_NOT_DIE is set.
1135 - // otherwise, assume this is a normal web request.
1136 - $can_die = ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE );
1137 -
1138 447 // validate nonce
1139 - if ( ! isset( $_GET['nonce'] ) || ! wp_verify_nonce( $_GET['nonce'] ) ) {
1140 - if ( ! $can_die ) {
1141 - return;
1142 - }
448 + if ( ! wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ) ) ) {
1143 449 status_header( 403 );
1144 450 exit;
1145 451 }
1146 452
1147 453 // check chart, if chart exists
1148 - // do not use filter_input as it does not work for phpunit test cases, use filter_var instead
1149 - $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 ) {
1151 - if ( ! $can_die ) {
1152 - return;
1153 - }
454 + $chart_id = filter_input( INPUT_GET, 'chart', FILTER_VALIDATE_INT );
455 + if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
1154 456 status_header( 400 );
1155 457 exit;
1156 458 }
1157 459
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 - if ( ! isset( $_POST['vz-import-time'] ) ) {
1161 - apply_filters( 'visualizer_pro_remove_schedule', $chart_id );
1162 - }
1163 -
1164 - if ( ! isset( $_POST['chart_data_src'] ) || Visualizer_Plugin::CF_SOURCE_FILTER !== $_POST['chart_data_src'] ) {
1165 - // 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 );
1174 - }
1175 -
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 460 $source = null;
1192 461 $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 );
1200 - if ( isset( $_POST['vz-import-time'] ) ) {
1201 - apply_filters( 'visualizer_pro_chart_schedule', $chart_id, $remote_data, $_POST['vz-import-time'] );
1202 - }
1203 - // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
462 + if ( filter_input( INPUT_POST, 'remote_data', FILTER_VALIDATE_URL ) ) {
463 + $source = new Visualizer_Source_Csv_Remote( $_POST['remote_data'] );
1204 464 } elseif ( isset( $_FILES['local_data'] ) && $_FILES['local_data']['error'] == 0 ) {
1205 465 $source = new Visualizer_Source_Csv( $_FILES['local_data']['tmp_name'] );
1206 - } 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'] );
466 +
467 + // Added by Ash/Upwork
468 + } elseif ( defined( 'Visualizer_Pro' ) && isset( $_POST['chart_data'] ) && strlen( $_POST['chart_data'] ) > 0 ) {
469 + global $Visualizer_Pro;
470 + $source = $Visualizer_Pro->_handleChartData( $_POST['chart_data'] );
471 + // Added by Ash/Upwork
1212 472 } 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' ) );
473 + $render->message = esc_html__( 'CSV file with chart data was not uploaded. Please, try again.', 'visualizer' );
1216 474 }
1217 475
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 476 if ( $source ) {
1221 477 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 - }
478 + $chart->post_content = $source->getData();
1237 479 wp_update_post( $chart->to_array() );
1238 480
1239 481 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
1240 482 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
@@ -1239,44 +481,17 @@
1239 481 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
1240 482 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
1241 483 update_post_meta( $chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
1242 484
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 ) ) );
485 + $render->data = json_encode( $source->getRawData() );
1260 486 $render->series = json_encode( $source->getSeries() );
1261 - $render->settings = json_encode( $settings );
1262 487 } 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 );
488 + $render->message = esc_html__( 'CSV file is broken or invalid. Please, try again.', 'visualizer' );
1270 489 }
1271 - } else {
1272 - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Unknown internal error for chart %d.', $chart_id ), 'error', __FILE__, __LINE__ );
1273 490 }
491 +
1274 492 $render->render();
1275 - if ( ! $can_die ) {
1276 - return;
1277 - }
1278 - defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
493 + exit;
1279 494 }
1280 495
1281 496 /**
1282 497 * Clones the chart.
@@ -1286,55 +501,42 @@
1286 501 * @access public
1287 502 */
1288 503 public function cloneChart() {
1289 504 $chart_id = $success = false;
1290 - $nonce = isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'], Visualizer_Plugin::ACTION_CLONE_CHART );
1291 - $capable = current_user_can( 'edit_posts' );
505 + $nonce = wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), Visualizer_Plugin::ACTION_CLONE_CHART );
506 + $capable = current_user_can( 'edit_posts' );
1292 507 if ( $nonce && $capable ) {
1293 - $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
508 + $chart_id = filter_input( INPUT_GET, 'chart', FILTER_VALIDATE_INT, array( 'options' => array( 'min_range' => 1 ) ) );
1294 509 if ( $chart_id ) {
1295 - $chart = get_post( $chart_id );
1296 - $success = $chart && $chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
510 + $chart = get_post( $chart_id );
511 + $success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
1297 512 }
1298 513 }
1299 - $redirect = remove_query_arg( 'vaction', wp_get_referer() );
514 +
515 + $redirect = wp_get_referer();
1300 516 if ( $success ) {
1301 - $new_chart_id = wp_insert_post(
1302 - array(
1303 - 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
1304 - 'post_title' => 'Visualization',
1305 - 'post_author' => get_current_user_id(),
1306 - 'post_status' => $chart->post_status,
1307 - 'post_content' => $chart->post_content,
1308 - )
1309 - );
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'
1330 - );
517 + $new_chart_id = wp_insert_post( array(
518 + 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
519 + 'post_title' => 'Visualization',
520 + 'post_author' => get_current_user_id(),
521 + 'post_status' => $chart->post_status,
522 + 'post_content' => $chart->post_content,
523 + ) );
524 +
525 + if ( $new_chart_id && ! is_wp_error( $new_chart_id ) ) {
526 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_CHART_TYPE, get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true ) );
527 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, get_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, true ) );
528 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SOURCE, get_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, true ) );
529 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SERIES, get_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, true ) );
530 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SETTINGS, get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true ) );
531 +
532 + $redirect = add_query_arg( array(
533 + 'page' => 'visualizer',
534 + 'type' => filter_input( INPUT_GET, 'type' ),
535 + ), admin_url( 'upload.php' ) );
1331 536 }
1332 537 }
1333 538
1334 - if ( defined( 'WP_TESTS_DOMAIN' ) ) {
1335 - wp_die();
1336 - }
1337 539 wp_redirect( $redirect );
1338 540 exit;
1339 541 }
1340 542
@@ -1346,259 +548,79 @@
1346 548 * @access public
1347 549 */
1348 550 public function exportData() {
1349 551 check_ajax_referer( Visualizer_Plugin::ACTION_EXPORT_DATA . Visualizer_Plugin::VERSION, 'security' );
1350 - $capable = current_user_can( 'edit_posts' );
552 +
553 + $chart_id = $success = false;
554 + $capable = current_user_can( 'edit_posts' );
1351 555 if ( $capable ) {
1352 - $chart_id = isset( $_GET['chart'] ) ? filter_var(
1353 - $_GET['chart'],
1354 - FILTER_VALIDATE_INT,
1355 - array(
1356 - 'options' => array(
1357 - 'min_range' => 1,
1358 - ),
1359 - )
1360 - ) : '';
556 + $chart_id = filter_input( INPUT_GET, 'chart', FILTER_VALIDATE_INT, array( 'options' => array( 'min_range' => 1 ) ) );
1361 557 if ( $chart_id ) {
1362 - $data = $this->_getDataAs( $chart_id, 'csv' );
1363 - if ( $data ) {
1364 - echo wp_send_json_success( $data );
1365 - }
558 + $chart = get_post( $chart_id );
559 + $success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
1366 560 }
1367 561 }
1368 562
1369 - defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1370 - }
563 + if ( $success ) {
564 + $settings = get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true );
565 + $filename = $settings['title'];
566 + if ( empty( $filename ) ) {
567 + $filename = 'export.csv';
568 + } else {
569 + $filename .= '.csv';
570 + }
571 + $rows = array();
572 + $series = get_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, true );
573 + $data = unserialize( $chart->post_content );
574 + if ( ! empty( $series ) ) {
575 + $row = array();
576 + foreach ( $series as $array ) {
577 + $row[] = $array['label'];
578 + }
579 + $rows[] = $row;
1371 580
1372 - /**
1373 - * Handles chart data page.
1374 - *
1375 - * @since 1.0.0
1376 - *
1377 - * @access private
1378 - */
1379 - private function _handleDataPage() {
1380 - $data = $this->_getChartArray();
1381 - $render = new Visualizer_Render_Page_Data();
1382 - $render->chart = $this->_chart;
1383 - $render->type = $data['type'];
581 + $row = array();
582 + foreach ( $series as $array ) {
583 + $row[] = $array['type'];
584 + }
585 + $rows[] = $row;
586 + }
1384 587
1385 - if ( $data && $data['settings'] ) {
1386 - unset( $data['settings']['width'], $data['settings']['height'], $data['settings']['chartArea'] );
1387 - }
1388 - wp_enqueue_style( 'visualizer-frame' );
1389 - wp_enqueue_script( 'visualizer-render' );
1390 - wp_localize_script(
1391 - 'visualizer-render',
1392 - 'visualizer',
1393 - array(
1394 - 'l10n' => array(
1395 - 'invalid_source' => esc_html__( 'You have entered an invalid URL. Please provide a valid URL.', 'visualizer' ),
1396 - 'loading' => esc_html__( 'Loading...', 'visualizer' ),
1397 - ),
1398 - 'charts' => array(
1399 - 'canvas' => $data,
1400 - ),
1401 - )
1402 - );
588 + if ( ! empty( $data ) ) {
589 + foreach ( $data as $array ) {
590 + // ignore strings
591 + if ( ! is_array( $array ) ) { continue; }
1403 592
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' ) ) {
1407 - global $Visualizer_Pro;
1408 - $Visualizer_Pro->_enqueueScriptsAndStyles( $data, $this->_chart->ID );
1409 - }
1410 -
1411 - // Added by Ash/Upwork
1412 - $this->_addAction( 'admin_head', 'renderFlattrScript' );
1413 - wp_iframe( array( $render, 'render' ) );
1414 - }
1415 -
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 );
593 + // if this is an array of arrays...
594 + if ( is_array( $array[0] ) ) {
595 + foreach ( $array as $arr ) {
596 + $rows[] = $arr;
597 + }
598 + } else {
599 + // just an array
600 + $rows[] = $array;
601 + }
1488 602 }
603 + }
1489 604
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 );
605 + $fp = tmpfile();
606 + foreach ( $rows as $row ) {
607 + fputcsv( $fp, $row );
608 + }
609 + rewind( $fp );
1493 610
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;
611 + $csv = '';
612 + while ( ($array = fgetcsv( $fp )) !== false ) {
613 + if ( strlen( $csv ) > 0 ) { $csv .= PHP_EOL; }
614 + $csv .= implode( ',', $array );
1505 615 }
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 - }
616 + fclose( $fp );
1512 617
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;
618 + echo wp_send_json_success(array(
619 + 'csv' => $csv,
620 + 'name' => $filename,
621 + ));
1547 622 }
1548 623
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;
624 + exit;
1603 625 }
1604 626 }