PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 2.1.1
Visualizer – Tables & Charts Manager with Built-in AI Generator v2.1.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 +211 -1228 3.10.152.1.1 View file →
@@ -56,257 +56,16 @@
56 56 $this->_addAjaxAction( Visualizer_Plugin::ACTION_CREATE_CHART, 'renderChartPages' );
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 + // Added by Ash/Upwork
60 61 $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 -
62 + // Added by Ash/Upwork
74 63 }
75 64
76 65 /**
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 66 * Fetches charts from database.
306 67 *
307 - * This method is also called from the media pop-up (classic editor: create a post and add chart from insert content).
308 - *
309 68 * @since 1.0.0
310 69 *
311 70 * @access public
312 71 */
@@ -313,27 +72,17 @@
313 72 public function getCharts() {
314 73 $query_args = array(
315 74 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
316 75 '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 - ),
76 + 'paged' => filter_input( INPUT_GET, 'page', FILTER_VALIDATE_INT, array(
77 + 'options' => array(
78 + 'min_range' => 1,
79 + 'default' => 1,
80 + ),
81 + ) ),
328 82 );
329 83 $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 -
335 - if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) {
84 + if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) {
336 85 $query_args['meta_query'] = array(
337 86 array(
338 87 'key' => Visualizer_Plugin::CF_CHART_TYPE,
339 88 'value' => $filter,
@@ -346,27 +95,15 @@
346 95 while ( $query->have_posts() ) {
347 96 $chart = $query->next_post();
348 97 $chart_data = $this->_getChartArray( $chart );
349 98 $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 99 $charts[] = $chart_data;
361 100 }
362 - self::_sendResponse(
363 - array(
364 - 'success' => true,
365 - 'data' => $charts,
366 - 'total' => $query->max_num_pages,
367 - )
368 - );
101 + self::_sendResponse( array(
102 + 'success' => true,
103 + 'data' => $charts,
104 + 'total' => $query->max_num_pages,
105 + ) );
369 106 }
370 107
371 108 /**
372 109 * Returns chart data required for rendering.
@@ -384,34 +121,15 @@
384 121 $chart = $this->_chart;
385 122 }
386 123 $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
387 124 $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 );
125 + $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( $chart->post_content ), $chart->ID, $type );
390 126
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 127 return array(
407 128 'type' => $type,
408 129 'series' => $series,
409 - 'settings' => $settings,
130 + 'settings' => get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true ),
410 131 'data' => $data,
411 - 'library' => $library,
412 - 'css' => $css,
413 - 'date_formats' => $date_formats,
414 132 );
415 133 }
416 134
417 135 /**
@@ -438,85 +156,37 @@
438 156 *
439 157 * @access public
440 158 */
441 159 public function deleteChart() {
442 - $is_post = $_SERVER['REQUEST_METHOD'] === 'POST';
160 + $is_post = $_SERVER['REQUEST_METHOD'] == 'POST';
443 161 $input_method = $is_post ? INPUT_POST : INPUT_GET;
444 162 $chart_id = $success = false;
445 163 $nonce = wp_verify_nonce( filter_input( $input_method, 'nonce' ) );
446 164 $capable = current_user_can( 'delete_posts' );
447 165 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 - );
166 + $chart_id = filter_input( $input_method, 'chart', FILTER_VALIDATE_INT, array(
167 + 'options' => array(
168 + 'min_range' => 1,
169 + ),
170 + ) );
458 171 if ( $chart_id ) {
459 172 $chart = get_post( $chart_id );
460 - $success = $chart && $chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
173 + $success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
461 174 }
462 175 }
463 176 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 - }
177 + wp_delete_post( $chart_id, true );
478 178 }
479 179 if ( $is_post ) {
480 - self::_sendResponse(
481 - array(
482 - 'success' => $success,
483 - )
484 - );
180 + self::_sendResponse( array(
181 + 'success' => $success,
182 + ) );
485 183 }
486 - wp_redirect( remove_query_arg( 'vaction', wp_get_referer() ) );
184 + wp_redirect( wp_get_referer() );
487 185 exit;
488 186 }
489 187
490 188 /**
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 189 * Renders appropriate page for chart builder. Creates new auto draft chart
520 190 * if no chart has been specified.
521 191 *
522 192 * @since 1.0.0
@@ -524,263 +194,68 @@
524 194 * @access public
525 195 */
526 196 public function renderChartPages() {
527 197 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 198 // check chart, if chart not exists, will create new one and redirects to the same page with proper chart id
534 199 $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 - );
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 - do_action( 'visualizer_pro_new_chart_defaults', $chart_id );
200 + if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
201 + $default_type = 'line';
202 + $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $default_type . '.csv' );
203 + $source->fetch();
204 + $chart_id = wp_insert_post( array(
205 + 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
206 + 'post_title' => 'Visualization',
207 + 'post_author' => get_current_user_id(),
208 + 'post_status' => 'auto-draft',
209 + 'post_content' => $source->getData(),
210 + ) );
211 + if ( $chart_id && ! is_wp_error( $chart_id ) ) {
212 + add_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, $default_type );
213 + add_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 1 );
214 + add_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
215 + add_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
216 + add_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, array(
217 + 'focusTarget' => 'datum',
218 + ) );
606 219 }
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();
220 + wp_redirect( add_query_arg( 'chart', (int) $chart_id ) );
221 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
613 222 }
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 223 // 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 );
636 -
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(
224 + wp_register_style( 'visualizer-frame', VISUALIZER_ABSURL . 'css/frame.css', array(), Visualizer_Plugin::VERSION );
225 + wp_register_script( 'visualizer-frame', VISUALIZER_ABSURL . 'js/frame.js', array( 'jquery' ), Visualizer_Plugin::VERSION, true );
226 + wp_register_script( 'google-jsapi-new', '//www.gstatic.com/charts/loader.js', array(), null, true );
227 + wp_register_script( 'google-jsapi-old', '//www.google.com/jsapi', array( 'google-jsapi-new' ), null, true );
228 + wp_register_script( 'visualizer-render', VISUALIZER_ABSURL . 'js/render.js', array(
229 + 'google-jsapi-old',
230 + 'google-jsapi-new',
231 + 'visualizer-frame',
232 + ), Visualizer_Plugin::VERSION, true );
233 + wp_register_script( 'visualizer-preview', VISUALIZER_ABSURL . 'js/preview.js', array(
234 + 'wp-color-picker',
641 235 '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 );
658 -
659 - do_action( 'visualizer_add_scripts' );
660 -
661 - if ( Visualizer_Module::is_pro() && Visualizer_Module::is_pro_older_than( '1.9.0' ) ) {
236 + ), Visualizer_Plugin::VERSION, true );
237 + // added by Ash/Upwork
238 + if ( VISUALIZER_PRO ) {
662 239 global $Visualizer_Pro;
663 240 $Visualizer_Pro->_addScriptsAndStyles();
664 241 }
665 -
666 242 // dispatch pages
667 243 $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 ) {
244 + switch ( isset( $_GET['tab'] ) ? $_GET['tab'] : '' ) {
696 245 case 'settings':
246 + // changed by Ash/Upwork
697 247 $this->_handleDataAndSettingsPage();
698 248 break;
699 - case 'type': // fall through.
700 - case 'visualizer': // fall through.
249 + case 'type':
250 + default:
701 251 $this->_handleTypesPage();
702 252 break;
703 - default:
704 - // this should never happen.
705 - break;
706 253 }
707 254 defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
708 255 }
709 256
710 257 /**
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 258 * Handle data and settings page
784 259 */
785 260 private function _handleDataAndSettingsPage() {
786 261 if ( isset( $_POST['map_api_key'] ) ) {
@@ -785,53 +260,23 @@
785 260 private function _handleDataAndSettingsPage() {
786 261 if ( isset( $_POST['map_api_key'] ) ) {
787 262 update_option( 'visualizer-map-api-key', $_POST['map_api_key'] );
788 263 }
789 -
790 - if ( $_SERVER['REQUEST_METHOD'] === 'POST' && isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'] ) ) {
791 - if ( $this->_chart->post_status === 'auto-draft' ) {
264 + if ( $_SERVER['REQUEST_METHOD'] == 'POST' && isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'] ) ) {
265 + if ( $this->_chart->post_status == 'auto-draft' ) {
792 266 $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 267 wp_update_post( $this->_chart->to_array() );
799 268 }
800 - // save meta data only when it is NOT being canceled.
801 - if ( ! ( isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] ) ) ) {
802 - update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $_POST );
803 -
804 - // we will keep a parameter called 'internal_title' that will be set to the given title or, if empty, the chart ID
805 - // this will help in searching with the chart id.
806 - $settings = get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
807 - $title = null;
808 - if ( isset( $settings['title'] ) && ! empty( $settings['title'] ) ) {
809 - $title = $settings['title'];
810 - if ( is_array( $title ) ) {
811 - $title = $settings['title']['text'];
812 - }
813 - }
814 - if ( empty( $title ) ) {
815 - $title = $this->_chart->ID;
816 - }
817 - $settings['internal_title'] = $title;
818 - $settings_label = isset( $settings['pieResidueSliceLabel'] ) ? $settings['pieResidueSliceLabel'] : '';
819 - if ( empty( $settings_label ) ) {
820 - $settings['pieResidueSliceLabel'] = esc_html__( 'Other', 'visualizer' );
821 - } else {
822 - $settings['pieResidueSliceLabel'] = $settings_label;
823 - }
824 - update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $settings );
825 - }
269 + update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $_POST );
826 270 $render = new Visualizer_Render_Page_Send();
827 271 $render->text = sprintf( '[visualizer id="%d"]', $this->_chart->ID );
828 272 wp_iframe( array( $render, 'render' ) );
273 +
829 274 return;
830 275 }
831 276 $data = $this->_getChartArray();
832 277 $sidebar = '';
833 - $sidebar_class = $this->load_chart_class_name( $this->_chart->ID );
278 + $sidebar_class = 'Visualizer_Render_Sidebar_Type_' . ucfirst( $data['type'] );
834 279 if ( class_exists( $sidebar_class, true ) ) {
835 280 $sidebar = new $sidebar_class( $data['settings'] );
836 281 $sidebar->__series = $data['series'];
837 282 $sidebar->__data = $data['data'];
@@ -836,108 +281,43 @@
836 281 $sidebar->__series = $data['series'];
837 282 $sidebar->__data = $data['data'];
838 283 } else {
839 284 $sidebar = apply_filters( 'visualizer_pro_chart_type_sidebar', '', $data );
840 - if ( $sidebar !== '' ) {
285 + if ( $sidebar != '' ) {
841 286 $sidebar->__series = $data['series'];
842 287 $sidebar->__data = $data['data'];
843 288 }
844 289 }
845 - unset( $data['settings']['width'], $data['settings']['height'], $data['settings']['chartArea'] );
290 + unset( $data['settings']['width'], $data['settings']['height'] );
291 + wp_enqueue_style( 'visualizer-frame' );
846 292 wp_enqueue_style( 'wp-color-picker' );
847 293 wp_enqueue_style( 'visualizer-frame' );
848 294 wp_enqueue_script( 'visualizer-preview' );
849 - wp_enqueue_script( 'visualizer-chosen' );
850 295 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 - 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 -
296 + wp_localize_script( 'visualizer-render', 'visualizer', array(
297 + 'l10n' => array(
298 + 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ),
299 + ),
300 + 'charts' => array(
301 + 'canvas' => $data,
302 + ),
303 + 'map_api_key' => get_option( 'visualizer-map-api-key' ),
304 + ) );
917 305 $render = new Visualizer_Render_Page_Data();
918 306 $render->chart = $this->_chart;
919 307 $render->type = $data['type'];
920 - $render->custom_css = $data['css'];
921 308 $render->sidebar = $sidebar;
922 309 if ( filter_input( INPUT_GET, 'library', FILTER_VALIDATE_BOOLEAN ) ) {
923 - $render->button = filter_input( INPUT_GET, 'action' ) === Visualizer_Plugin::ACTION_EDIT_CHART
310 + $render->button = filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART
924 311 ? esc_html__( 'Save Chart', 'visualizer' )
925 312 : 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 313 } else {
930 314 $render->button = esc_attr__( 'Insert Chart', 'visualizer' );
931 315 }
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' ) ) {
316 + if ( VISUALIZER_PRO ) {
936 317 global $Visualizer_Pro;
937 - $Visualizer_Pro->_enqueueScriptsAndStyles( $data, $this->_chart->ID );
318 + $Visualizer_Pro->_enqueueScriptsAndStyles( $data );
938 319 }
939 -
940 320 $this->_addAction( 'admin_head', 'renderFlattrScript' );
941 321 wp_iframe( array( $render, 'render' ) );
942 322 }
943 323
@@ -949,35 +329,24 @@
949 329 * @access private
950 330 */
951 331 private function _handleTypesPage() {
952 332 // process post request
953 - if ( $_SERVER['REQUEST_METHOD'] === 'POST' && wp_verify_nonce( filter_input( INPUT_POST, 'nonce' ) ) ) {
333 + if ( $_SERVER['REQUEST_METHOD'] == 'POST' && wp_verify_nonce( filter_input( INPUT_POST, 'nonce' ) ) ) {
954 334 $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 -
335 + if ( in_array( $type, Visualizer_Plugin::getChartTypes() ) ) {
963 336 // save new chart type
964 337 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 338 // if the chart has default data, update it with appropriate default data for new type
967 339 if ( filter_var( get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, true ), FILTER_VALIDATE_BOOLEAN ) ) {
968 340 $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $type . '.csv' );
969 341 $source->fetch();
970 - $this->_chart->post_content = $source->getData( get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) );
342 + $this->_chart->post_content = $source->getData();
971 343 wp_update_post( $this->_chart->to_array() );
972 344 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
973 345 }
974 -
975 - Visualizer_Module_Utility::set_defaults( $this->_chart );
976 -
977 346 // redirect to next tab
978 347 // changed by Ash/Upwork
979 - wp_redirect( esc_url_raw( add_query_arg( 'tab', 'settings' ) ) );
348 + wp_redirect( add_query_arg( 'tab', 'settings' ) );
980 349
981 350 return;
982 351 }
983 352 }
@@ -982,9 +351,9 @@
982 351 }
983 352 }
984 353 $render = new Visualizer_Render_Page_Types();
985 354 $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' );
355 + $render->types = Visualizer_Module_Admin::_getChartTypesLocalized();
987 356 $render->chart = $this->_chart;
988 357 wp_enqueue_style( 'visualizer-frame' );
989 358 wp_enqueue_script( 'visualizer-frame' );
990 359 wp_iframe( array( $render, 'render' ) );
@@ -1000,131 +369,10 @@
1000 369 */
1001 370 public function renderFlattrScript() {
1002 371 echo '';
1003 372 }
1004 -
373 + // changed by Ash/Upwork
1005 374 /**
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 375 * Parses uploaded CSV file and saves new data for the chart.
1128 376 *
1129 377 * @since 1.0.0
1130 378 *
@@ -1130,153 +378,57 @@
1130 378 *
1131 379 * @access public
1132 380 */
1133 381 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 -
382 + error_log( 'in uploadData ' . print_r( $_GET,true ) . print_r( $_POST,true ) );
1138 383 // validate nonce
384 + // do not use filter_input as it does not work for phpunit test cases, use filter_var instead
1139 385 if ( ! isset( $_GET['nonce'] ) || ! wp_verify_nonce( $_GET['nonce'] ) ) {
1140 - if ( ! $can_die ) {
1141 - return;
1142 - }
1143 386 status_header( 403 );
1144 387 exit;
1145 388 }
1146 -
1147 389 // 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 390 $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 - }
391 + if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
1154 392 status_header( 400 );
1155 393 exit;
1156 394 }
1157 -
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 395 if ( ! isset( $_POST['vz-import-time'] ) ) {
1161 396 apply_filters( 'visualizer_pro_remove_schedule', $chart_id );
1162 397 }
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 398 $source = null;
1192 399 $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 );
400 + if ( isset( $_POST['remote_data'] ) && filter_var( $_POST['remote_data'], FILTER_VALIDATE_URL ) ) {
401 + $source = new Visualizer_Source_Csv_Remote( $_POST['remote_data'] );
1200 402 if ( isset( $_POST['vz-import-time'] ) ) {
1201 - apply_filters( 'visualizer_pro_chart_schedule', $chart_id, $remote_data, $_POST['vz-import-time'] );
403 + apply_filters( 'visualizer_pro_chart_schedule', $chart_id, $_POST['remote_data'], $_POST['vz-import-time'] );
1202 404 }
1203 - // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
1204 405 } elseif ( isset( $_FILES['local_data'] ) && $_FILES['local_data']['error'] == 0 ) {
1205 406 $source = new Visualizer_Source_Csv( $_FILES['local_data']['tmp_name'] );
407 + // Added by Ash/Upwork
1206 408 } 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'] );
409 + $source = apply_filters( 'visualizer_pro_handle_chart_data', $_POST['chart_data'], '' );
410 + // Added by Ash/Upwork
1212 411 } 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' ) );
412 + $render->message = esc_html__( 'CSV file with chart data was not uploaded. Please, try again.', 'visualizer' );
1216 413 }
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 414 if ( $source ) {
1221 415 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 - }
416 + $chart->post_content = $source->getData();
1237 417 wp_update_post( $chart->to_array() );
1238 -
1239 418 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
1240 419 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
1241 420 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 ) ) );
421 + $render->data = json_encode( $source->getRawData() );
1260 422 $render->series = json_encode( $source->getSeries() );
1261 - $render->settings = json_encode( $settings );
1262 423 } 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 );
424 + $render->message = esc_html__( 'CSV file is broken or invalid. Please, try again.', 'visualizer' );
1270 425 }
1271 - } else {
1272 - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Unknown internal error for chart %d.', $chart_id ), 'error', __FILE__, __LINE__ );
1273 426 }
1274 427 $render->render();
1275 - if ( ! $can_die ) {
1276 - return;
428 + if ( ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ) ) {
429 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1277 430 }
1278 - defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1279 431 }
1280 432
1281 433 /**
1282 434 * Clones the chart.
@@ -1286,55 +438,42 @@
1286 438 * @access public
1287 439 */
1288 440 public function cloneChart() {
1289 441 $chart_id = $success = false;
1290 - $nonce = isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'], Visualizer_Plugin::ACTION_CLONE_CHART );
442 + $nonce = wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), Visualizer_Plugin::ACTION_CLONE_CHART );
1291 443 $capable = current_user_can( 'edit_posts' );
1292 444 if ( $nonce && $capable ) {
1293 - $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
445 + $chart_id = filter_input( INPUT_GET, 'chart', FILTER_VALIDATE_INT, array(
446 + 'options' => array(
447 + 'min_range' => 1,
448 + ),
449 + ) );
1294 450 if ( $chart_id ) {
1295 451 $chart = get_post( $chart_id );
1296 - $success = $chart && $chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
452 + $success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
1297 453 }
1298 454 }
1299 - $redirect = remove_query_arg( 'vaction', wp_get_referer() );
455 + $redirect = wp_get_referer();
1300 456 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 - );
457 + $new_chart_id = wp_insert_post( array(
458 + 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
459 + 'post_title' => 'Visualization',
460 + 'post_author' => get_current_user_id(),
461 + 'post_status' => $chart->post_status,
462 + 'post_content' => $chart->post_content,
463 + ) );
464 + if ( $new_chart_id && ! is_wp_error( $new_chart_id ) ) {
465 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_CHART_TYPE, get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true ) );
466 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, get_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, true ) );
467 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SOURCE, get_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, true ) );
468 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SERIES, get_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, true ) );
469 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SETTINGS, get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true ) );
470 + $redirect = add_query_arg( array(
471 + 'page' => 'visualizer',
472 + 'type' => filter_input( INPUT_GET, 'type' ),
473 + ), admin_url( 'upload.php' ) );
1331 474 }
1332 475 }
1333 -
1334 - if ( defined( 'WP_TESTS_DOMAIN' ) ) {
1335 - wp_die();
1336 - }
1337 476 wp_redirect( $redirect );
1338 477 exit;
1339 478 }
1340 479
@@ -1346,27 +485,79 @@
1346 485 * @access public
1347 486 */
1348 487 public function exportData() {
1349 488 check_ajax_referer( Visualizer_Plugin::ACTION_EXPORT_DATA . Visualizer_Plugin::VERSION, 'security' );
489 + $chart_id = $success = false;
1350 490 $capable = current_user_can( 'edit_posts' );
1351 491 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 - ) : '';
492 + $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT, array(
493 + 'options' => array(
494 + 'min_range' => 1,
495 + ),
496 + ) ) : '';
1361 497 if ( $chart_id ) {
1362 - $data = $this->_getDataAs( $chart_id, 'csv' );
1363 - if ( $data ) {
1364 - echo wp_send_json_success( $data );
498 + $chart = get_post( $chart_id );
499 + $success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
500 + }
501 + }
502 + if ( $success ) {
503 + $settings = get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true );
504 + $filename = isset( $settings['title'] ) ? $settings['title'] : '';
505 + if ( empty( $filename ) ) {
506 + $filename = 'export.csv';
507 + } else {
508 + $filename .= '.csv';
509 + }
510 + $rows = array();
511 + $series = get_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, true );
512 + $data = unserialize( $chart->post_content );
513 + if ( ! empty( $series ) ) {
514 + $row = array();
515 + foreach ( $series as $array ) {
516 + $row[] = $array['label'];
1365 517 }
518 + $rows[] = $row;
519 + $row = array();
520 + foreach ( $series as $array ) {
521 + $row[] = $array['type'];
522 + }
523 + $rows[] = $row;
1366 524 }
1367 - }
1368 -
525 + if ( ! empty( $data ) ) {
526 + foreach ( $data as $array ) {
527 + // ignore strings
528 + if ( ! is_array( $array ) ) {
529 + continue;
530 + }
531 + // if this is an array of arrays...
532 + if ( is_array( $array[0] ) ) {
533 + foreach ( $array as $arr ) {
534 + $rows[] = $arr;
535 + }
536 + } else {
537 + // just an array
538 + $rows[] = $array;
539 + }
540 + }
541 + }
542 + $fp = tmpfile();
543 + foreach ( $rows as $row ) {
544 + fputcsv( $fp, $row );
545 + }
546 + rewind( $fp );
547 + $csv = '';
548 + while ( ( $array = fgetcsv( $fp ) ) !== false ) {
549 + if ( strlen( $csv ) > 0 ) {
550 + $csv .= PHP_EOL;
551 + }
552 + $csv .= implode( ',', $array );
553 + }
554 + fclose( $fp );
555 + echo wp_send_json_success( array(
556 + 'csv' => $csv,
557 + 'name' => $filename,
558 + ) );
559 + }// End if().
1369 560 defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1370 561 }
1371 562
1372 563 /**
@@ -1380,233 +571,25 @@
1380 571 $data = $this->_getChartArray();
1381 572 $render = new Visualizer_Render_Page_Data();
1382 573 $render->chart = $this->_chart;
1383 574 $render->type = $data['type'];
1384 -
1385 - if ( $data && $data['settings'] ) {
1386 - unset( $data['settings']['width'], $data['settings']['height'], $data['settings']['chartArea'] );
1387 - }
575 + unset( $data['settings']['width'], $data['settings']['height'] );
1388 576 wp_enqueue_style( 'visualizer-frame' );
1389 577 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 - );
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' ) ) {
578 + wp_localize_script( 'visualizer-render', 'visualizer', array(
579 + 'l10n' => array(
580 + 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ),
581 + ),
582 + 'charts' => array(
583 + 'canvas' => $data,
584 + ),
585 + ) );
586 + // Added by Ash/Upwork
587 + if ( VISUALIZER_PRO ) {
1407 588 global $Visualizer_Pro;
1408 - $Visualizer_Pro->_enqueueScriptsAndStyles( $data, $this->_chart->ID );
589 + $Visualizer_Pro->_enqueueScriptsAndStyles( $data );
1409 590 }
1410 -
1411 591 // Added by Ash/Upwork
1412 592 $this->_addAction( 'admin_head', 'renderFlattrScript' );
1413 593 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 - if ( ! current_user_can( 'administrator' ) ) {
1425 - wp_send_json_error( array( 'msg' => __( 'Action not allowed for this user.', 'visualizer' ) ) );
1426 - }
1427 -
1428 - $params = wp_parse_args( $_POST['params'] );
1429 - $chart_id = filter_var( $params['chart_id'], FILTER_VALIDATE_INT );
1430 -
1431 - $source = new Visualizer_Source_Query( stripslashes( $params['query'] ), $chart_id, $params );
1432 - $html = $source->fetch( true );
1433 - $error = $source->get_error();
1434 - if ( ! empty( $error ) ) {
1435 - wp_send_json_error( array( 'msg' => $error ) );
1436 - }
1437 - wp_send_json_success( array( 'table' => $html ) );
1438 - }
1439 -
1440 - /**
1441 - * Saves the query and the schedule.
1442 - *
1443 - * @access public
1444 - */
1445 - public function saveQuery() {
1446 - check_ajax_referer( Visualizer_Plugin::ACTION_SAVE_DB_QUERY . Visualizer_Plugin::VERSION, 'security' );
1447 -
1448 - $chart_id = filter_input(
1449 - INPUT_GET,
1450 - 'chart',
1451 - FILTER_VALIDATE_INT,
1452 - array(
1453 - 'options' => array(
1454 - 'min_range' => 1,
1455 - ),
1456 - )
1457 - );
1458 -
1459 - $hours = filter_input(
1460 - INPUT_POST,
1461 - 'refresh',
1462 - FILTER_VALIDATE_FLOAT,
1463 - array(
1464 - 'options' => array(
1465 - 'min_range' => -1,
1466 - 'max_range' => apply_filters( 'visualizer_is_business', false ) ? PHP_INT_MAX : -1,
1467 - ),
1468 - )
1469 - );
1470 -
1471 - if ( ! is_numeric( $hours ) ) {
1472 - $hours = -1;
1473 - }
1474 -
1475 - $render = new Visualizer_Render_Page_Update();
1476 - if ( $chart_id ) {
1477 - $params = wp_parse_args( $_POST['params'] );
1478 - $source = new Visualizer_Source_Query( stripslashes( $params['query'] ), $chart_id, $params );
1479 - $source->fetch( false );
1480 - $error = $source->get_error();
1481 - if ( empty( $error ) ) {
1482 - update_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY, stripslashes( $params['query'] ) );
1483 - update_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
1484 - update_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
1485 - update_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, $hours );
1486 - update_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
1487 - if ( isset( $params['db_type'] ) && $params['db_type'] !== Visualizer_Plugin::WP_DB_NAME ) {
1488 - $remote_db_params = $params;
1489 - unset( $remote_db_params['query'] );
1490 - unset( $remote_db_params['chart_id'] );
1491 - update_post_meta( $chart_id, Visualizer_Plugin::CF_REMOTE_DB_PARAMS, $remote_db_params );
1492 - }
1493 -
1494 - $schedules = get_option( Visualizer_Plugin::CF_DB_SCHEDULE, array() );
1495 - $schedules[ $chart_id ] = time() + $hours * HOUR_IN_SECONDS;
1496 - update_option( Visualizer_Plugin::CF_DB_SCHEDULE, $schedules );
1497 -
1498 - wp_update_post(
1499 - array(
1500 - 'ID' => $chart_id,
1501 - 'post_content' => $source->getData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ),
1502 - )
1503 - );
1504 - $render->data = json_encode( $source->getRawData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ) );
1505 - $render->series = json_encode( $source->getSeries() );
1506 - $render->id = $chart_id;
1507 - } else {
1508 - $render->message = $error;
1509 - }
1510 - }
1511 - $render->render();
1512 - if ( ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ) ) {
1513 - defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1514 - }
1515 - }
1516 -
1517 -
1518 - /**
1519 - * Saves the filter query and the schedule.
1520 - *
1521 - * @access public
1522 - */
1523 - public function saveFilter() {
1524 - check_ajax_referer( Visualizer_Plugin::ACTION_SAVE_FILTER_QUERY . Visualizer_Plugin::VERSION, 'security' );
1525 -
1526 - $chart_id = filter_input(
1527 - INPUT_GET,
1528 - 'chart',
1529 - FILTER_VALIDATE_INT,
1530 - array(
1531 - 'options' => array(
1532 - 'min_range' => 1,
1533 - ),
1534 - )
1535 - );
1536 -
1537 - $hours = filter_input(
1538 - INPUT_POST,
1539 - 'refresh',
1540 - FILTER_VALIDATE_INT,
1541 - array(
1542 - 'options' => array(
1543 - 'min_range' => -1,
1544 - 'max_range' => apply_filters( 'visualizer_is_business', false ) ? PHP_INT_MAX : -1,
1545 - ),
1546 - )
1547 - );
1548 -
1549 - if ( 0 !== $hours && empty( $hours ) ) {
1550 - $hours = -1;
1551 - }
1552 -
1553 - do_action( 'visualizer_save_filter', $chart_id, $hours );
1554 -
1555 - if ( ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ) ) {
1556 - defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1557 - }
1558 - }
1559 -
1560 - /**
1561 - * Save chart image.
1562 - *
1563 - * @param string $base64_img Chart image.
1564 - * @param int $chart_id Chart ID.
1565 - * @param bool $save_attachment Save attachment.
1566 - * @return attachment ID
1567 - */
1568 - public function save_chart_image( $base64_img, $chart_id, $save_attachment = true ) {
1569 - // Delete old chart image.
1570 - $old_attachment_id = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_IMAGE, true );
1571 - if ( $old_attachment_id ) {
1572 - wp_delete_attachment( $old_attachment_id, true );
1573 - }
1574 -
1575 - if ( ! $save_attachment ) {
1576 - return 0;
1577 - }
1578 -
1579 - // Upload dir.
1580 - $upload_dir = wp_upload_dir();
1581 - $upload_path = str_replace( '/', DIRECTORY_SEPARATOR, $upload_dir['path'] ) . DIRECTORY_SEPARATOR;
1582 -
1583 - $img = str_replace( 'data:image/png;base64,', '', $base64_img );
1584 - $img = str_replace( ' ', '+', $img );
1585 - $decoded = base64_decode( $img );
1586 - $filename = 'visualization-' . $chart_id . '.png';
1587 - $file_type = 'image/png';
1588 - $hashed_filename = $filename;
1589 -
1590 - // Save the image in the uploads directory.
1591 - require_once ABSPATH . '/wp-admin/includes/file.php';
1592 - \WP_Filesystem();
1593 - global $wp_filesystem;
1594 - if ( ! is_a( $wp_filesystem, 'WP_Filesystem_Base' ) ) {
1595 - $creds = request_filesystem_credentials( site_url() );
1596 - wp_filesystem( $creds );
1597 - }
1598 - $upload_file = $wp_filesystem->put_contents( $upload_path . $hashed_filename, $decoded );
1599 -
1600 - // Insert new chart image.
1601 - $attachment = array(
1602 - 'post_mime_type' => $file_type,
1603 - 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $hashed_filename ) ),
1604 - 'post_content' => '',
1605 - 'post_status' => 'inherit',
1606 - 'guid' => $upload_dir['url'] . '/' . basename( $hashed_filename ),
1607 - );
1608 -
1609 - $attach_id = wp_insert_attachment( $attachment, $upload_dir['path'] . '/' . $hashed_filename );
1610 - return $attach_id;
1611 594 }
1612 595 }