PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.0.11
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.0.11
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
visualizer / classes / Visualizer / Module / Chart.php

Chart.php in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.0.11, at classes/Visualizer/Module/Chart.php

647 lines 22.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // +----------------------------------------------------------------------+
3 // | Copyright 2013 Madpixels (email : visualizer@madpixels.net) |
4 // +----------------------------------------------------------------------+
5 // | This program is free software; you can redistribute it and/or modify |
6 // | it under the terms of the GNU General Public License, version 2, as |
7 // | published by the Free Software Foundation. |
8 // | |
9 // | This program is distributed in the hope that it will be useful, |
10 // | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 // | GNU General Public License for more details. |
13 // | |
14 // | You should have received a copy of the GNU General Public License |
15 // | along with this program; if not, write to the Free Software |
16 // | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, |
17 // | MA 02110-1301 USA |
18 // +----------------------------------------------------------------------+
19 // | Author: Eugene Manuilov <eugene@manuilov.org> |
20 // +----------------------------------------------------------------------+
21 /**
22 * The module for all stuff related to getting, editing, creating and deleting charts.
23 *
24 * @category Visualizer
25 * @package Module
26 *
27 * @since 1.0.0
28 */
29 class Visualizer_Module_Chart extends Visualizer_Module {
30
31 const NAME = __CLASS__;
32
33 /**
34 * The chart object.
35 *
36 * @since 1.0.0
37 *
38 * @access private
39 * @var WP_Post
40 */
41 private $_chart;
42
43 /**
44 * Constructor.
45 *
46 * @since 1.0.0
47 *
48 * @access public
49 *
50 * @param Visualizer_Plugin $plugin The instance of the plugin.
51 */
52 public function __construct( Visualizer_Plugin $plugin ) {
53 parent::__construct( $plugin );
54 $this->_addAjaxAction( Visualizer_Plugin::ACTION_GET_CHARTS, 'getCharts' );
55 $this->_addAjaxAction( Visualizer_Plugin::ACTION_DELETE_CHART, 'deleteChart' );
56 $this->_addAjaxAction( Visualizer_Plugin::ACTION_CREATE_CHART, 'renderChartPages' );
57 $this->_addAjaxAction( Visualizer_Plugin::ACTION_EDIT_CHART, 'renderChartPages' );
58 $this->_addAjaxAction( Visualizer_Plugin::ACTION_UPLOAD_DATA, 'uploadData' );
59 $this->_addAjaxAction( Visualizer_Plugin::ACTION_CLONE_CHART, 'cloneChart' );
60 $this->_addAjaxAction( Visualizer_Plugin::ACTION_EXPORT_DATA, 'exportData' );
61 }
62
63 /**
64 * Fetches charts from database.
65 *
66 * @since 1.0.0
67 *
68 * @access public
69 */
70 public function getCharts() {
71 $query_args = array(
72 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
73 'posts_per_page' => 9,
74 'paged' => filter_input(
75 INPUT_GET, 'page', FILTER_VALIDATE_INT, array(
76 'options' => array(
77 'min_range' => 1,
78 'default' => 1,
79 ),
80 )
81 ),
82 );
83 $filter = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
84 if ( empty( $filter ) ) {
85 // 'filter' is from the modal from the add media button.
86 $filter = filter_input( INPUT_GET, 'filter', FILTER_SANITIZE_STRING );
87 }
88
89 if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) {
90 $query_args['meta_query'] = array(
91 array(
92 'key' => Visualizer_Plugin::CF_CHART_TYPE,
93 'value' => $filter,
94 'compare' => '=',
95 ),
96 );
97 }
98 $query = new WP_Query( $query_args );
99 $charts = array();
100 while ( $query->have_posts() ) {
101 $chart = $query->next_post();
102 $chart_data = $this->_getChartArray( $chart );
103 $chart_data['id'] = $chart->ID;
104 $charts[] = $chart_data;
105 }
106 self::_sendResponse(
107 array(
108 'success' => true,
109 'data' => $charts,
110 'total' => $query->max_num_pages,
111 )
112 );
113 }
114
115 /**
116 * Returns chart data required for rendering.
117 *
118 * @since 1.0.0
119 *
120 * @access private
121 *
122 * @param WP_Post $chart The chart object.
123 *
124 * @return array The array of chart data.
125 */
126 private function _getChartArray( WP_Post $chart = null ) {
127 if ( is_null( $chart ) ) {
128 $chart = $this->_chart;
129 }
130 $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
131 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
132 $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( $chart->post_content ), $chart->ID, $type );
133
134 return array(
135 'type' => $type,
136 'series' => $series,
137 'settings' => get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true ),
138 'data' => $data,
139 );
140 }
141
142 /**
143 * Sends json response.
144 *
145 * @since 1.0.0
146 *
147 * @access private
148 *
149 * @param array $results The response array.
150 */
151 public static function _sendResponse( $results ) {
152 header( 'Content-type: application/json' );
153 nocache_headers();
154 echo json_encode( $results );
155 defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
156 }
157
158 /**
159 * Deletes a chart from database.
160 *
161 * @since 1.0.0
162 * @uses wp_delete_post() To delete a chart.
163 *
164 * @access public
165 */
166 public function deleteChart() {
167 $is_post = $_SERVER['REQUEST_METHOD'] == 'POST';
168 $input_method = $is_post ? INPUT_POST : INPUT_GET;
169 $chart_id = $success = false;
170 $nonce = wp_verify_nonce( filter_input( $input_method, 'nonce' ) );
171 $capable = current_user_can( 'delete_posts' );
172 if ( $nonce && $capable ) {
173 $chart_id = filter_input(
174 $input_method, 'chart', FILTER_VALIDATE_INT, array(
175 'options' => array(
176 'min_range' => 1,
177 ),
178 )
179 );
180 if ( $chart_id ) {
181 $chart = get_post( $chart_id );
182 $success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
183 }
184 }
185 if ( $success ) {
186 wp_delete_post( $chart_id, true );
187 }
188 if ( $is_post ) {
189 self::_sendResponse(
190 array(
191 'success' => $success,
192 )
193 );
194 }
195 wp_redirect( wp_get_referer() );
196 exit;
197 }
198
199 /**
200 * Renders appropriate page for chart builder. Creates new auto draft chart
201 * if no chart has been specified.
202 *
203 * @since 1.0.0
204 *
205 * @access public
206 */
207 public function renderChartPages() {
208 defined( 'IFRAME_REQUEST' ) || define( 'IFRAME_REQUEST', 1 );
209 // check chart, if chart not exists, will create new one and redirects to the same page with proper chart id
210 $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
211 if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
212 $default_type = isset( $_GET['type'] ) && ! empty( $_GET['type'] ) ? $_GET['type'] : 'line';
213 $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $default_type . '.csv' );
214 $source->fetch();
215 $chart_id = wp_insert_post(
216 array(
217 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
218 'post_title' => 'Visualization',
219 'post_author' => get_current_user_id(),
220 'post_status' => 'auto-draft',
221 'post_content' => $source->getData(),
222 )
223 );
224 if ( $chart_id && ! is_wp_error( $chart_id ) ) {
225 add_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, $default_type );
226 add_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 1 );
227 add_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
228 add_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
229 add_post_meta(
230 $chart_id, Visualizer_Plugin::CF_SETTINGS, array(
231 'focusTarget' => 'datum',
232 )
233 );
234 do_action( 'visualizer_pro_new_chart_defaults', $chart_id );
235 }
236 wp_redirect( add_query_arg( 'chart', (int) $chart_id ) );
237 defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
238 }
239 // enqueue and register scripts and styles
240 wp_register_script( 'visualizer-chosen', VISUALIZER_ABSURL . 'js/lib/chosen.jquery.min.js', array( 'jquery' ), Visualizer_Plugin::VERSION );
241 wp_register_style( 'visualizer-chosen', VISUALIZER_ABSURL . 'css/lib/chosen.min.css', array(), Visualizer_Plugin::VERSION );
242
243 wp_register_style( 'visualizer-frame', VISUALIZER_ABSURL . 'css/frame.css', array( 'visualizer-chosen' ), Visualizer_Plugin::VERSION );
244 wp_register_script( 'visualizer-frame', VISUALIZER_ABSURL . 'js/frame.js', array( 'visualizer-chosen' ), Visualizer_Plugin::VERSION, true );
245 wp_register_script( 'google-jsapi-new', '//www.gstatic.com/charts/loader.js', array(), null, true );
246 wp_register_script( 'google-jsapi-old', '//www.google.com/jsapi', array( 'google-jsapi-new' ), null, true );
247 wp_register_script(
248 'visualizer-render', VISUALIZER_ABSURL . 'js/render.js', array(
249 'google-jsapi-old',
250 'google-jsapi-new',
251 'visualizer-frame',
252 ), Visualizer_Plugin::VERSION, true
253 );
254 wp_register_script(
255 'visualizer-preview', VISUALIZER_ABSURL . 'js/preview.js', array(
256 'wp-color-picker',
257 'visualizer-render',
258 ), Visualizer_Plugin::VERSION, true
259 );
260 // added by Ash/Upwork
261 if ( VISUALIZER_PRO ) {
262 global $Visualizer_Pro;
263 $Visualizer_Pro->_addScriptsAndStyles();
264 }
265 // dispatch pages
266 $this->_chart = get_post( $chart_id );
267 $tab = isset( $_GET['tab'] ) && ! empty( $_GET['tab'] ) ? $_GET['tab'] : 'visualizer';
268
269 // skip chart type pages only for existing charts.
270 if ( VISUALIZER_SKIP_CHART_TYPE_PAGE && 'auto-draft' !== $this->_chart->post_status && ( ! empty( $_GET['tab'] ) && 'visualizer' === $_GET['tab'] ) ) {
271 $tab = 'settings';
272 }
273
274 if ( isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] ) ) {
275 // if the cancel button is clicked.
276 $this->undoRevisions( $chart_id, true );
277 } elseif ( isset( $_POST['save'] ) && 1 === intval( $_POST['save'] ) ) {
278 // if the save button is clicked.
279 $this->undoRevisions( $chart_id, false );
280 } else {
281 // if the edit button is clicked.
282 $this->_chart = $this->handleExistingRevisions( $chart_id, $this->_chart );
283 }
284
285 switch ( $tab ) {
286 case 'settings':
287 $this->_handleDataAndSettingsPage();
288 break;
289 case 'type': // fall through.
290 case 'visualizer': // fall through.
291 $this->_handleTypesPage();
292 break;
293 default:
294 do_action( 'visualizer_pro_handle_tab', $tab, $this->_chart );
295 break;
296 }
297 defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
298 }
299
300 /**
301 * Handle data and settings page
302 */
303 private function _handleDataAndSettingsPage() {
304 if ( isset( $_POST['map_api_key'] ) ) {
305 update_option( 'visualizer-map-api-key', $_POST['map_api_key'] );
306 }
307 if ( $_SERVER['REQUEST_METHOD'] == 'POST' && isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'] ) ) {
308 if ( $this->_chart->post_status == 'auto-draft' ) {
309 $this->_chart->post_status = 'publish';
310
311 // ensure that a revision is not created. If a revision is created it will have the proper data and the parent of the revision will have default data.
312 // we do not want any difference in data so disable revisions temporarily.
313 add_filter( 'wp_revisions_to_keep', '__return_false' );
314 wp_update_post( $this->_chart->to_array() );
315 }
316 // save meta data only when it is NOT being canceled.
317 if ( ! ( isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] ) ) ) {
318 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $_POST );
319 }
320 $render = new Visualizer_Render_Page_Send();
321 $render->text = sprintf( '[visualizer id="%d"]', $this->_chart->ID );
322 wp_iframe( array( $render, 'render' ) );
323
324 return;
325 }
326 $data = $this->_getChartArray();
327 $sidebar = '';
328 $sidebar_class = 'Visualizer_Render_Sidebar_Type_' . ucfirst( $data['type'] );
329 if ( class_exists( $sidebar_class, true ) ) {
330 $sidebar = new $sidebar_class( $data['settings'] );
331 $sidebar->__series = $data['series'];
332 $sidebar->__data = $data['data'];
333 } else {
334 $sidebar = apply_filters( 'visualizer_pro_chart_type_sidebar', '', $data );
335 if ( $sidebar != '' ) {
336 $sidebar->__series = $data['series'];
337 $sidebar->__data = $data['data'];
338 }
339 }
340 unset( $data['settings']['width'], $data['settings']['height'] );
341 wp_enqueue_style( 'visualizer-frame' );
342 wp_enqueue_style( 'wp-color-picker' );
343 wp_enqueue_style( 'visualizer-frame' );
344 wp_enqueue_script( 'visualizer-preview' );
345 wp_enqueue_script( 'visualizer-render' );
346 wp_localize_script(
347 'visualizer-render', 'visualizer', array(
348 'l10n' => array(
349 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ),
350 'loading' => esc_html__( 'Loading...', 'visualizer' ),
351 ),
352 'charts' => array(
353 'canvas' => $data,
354 ),
355 'language' => $this->get_language(),
356 'map_api_key' => get_option( 'visualizer-map-api-key' ),
357 'ajax' => array(
358 'url' => admin_url( 'admin-ajax.php' ),
359 'nonces' => array(
360 'permissions' => wp_create_nonce( Visualizer_Plugin::ACTION_FETCH_PERMISSIONS_DATA ),
361 ),
362 'actions' => array(
363 'permissions' => Visualizer_Plugin::ACTION_FETCH_PERMISSIONS_DATA,
364 ),
365 ),
366 )
367 );
368 $render = new Visualizer_Render_Page_Data();
369 $render->chart = $this->_chart;
370 $render->type = $data['type'];
371 $render->sidebar = $sidebar;
372 if ( filter_input( INPUT_GET, 'library', FILTER_VALIDATE_BOOLEAN ) ) {
373 $render->button = filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART
374 ? esc_html__( 'Save Chart', 'visualizer' )
375 : esc_html__( 'Create Chart', 'visualizer' );
376 if ( filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART ) {
377 $render->cancel_button = esc_html__( 'Cancel', 'visualizer' );
378 }
379 } else {
380 $render->button = esc_attr__( 'Insert Chart', 'visualizer' );
381 }
382 if ( VISUALIZER_PRO ) {
383 global $Visualizer_Pro;
384 $Visualizer_Pro->_enqueueScriptsAndStyles( $data );
385 }
386 $this->_addAction( 'admin_head', 'renderFlattrScript' );
387 wp_iframe( array( $render, 'render' ) );
388 }
389
390 /**
391 * Handles chart type selection page.
392 *
393 * @since 1.0.0
394 *
395 * @access private
396 */
397 private function _handleTypesPage() {
398 // process post request
399 if ( $_SERVER['REQUEST_METHOD'] == 'POST' && wp_verify_nonce( filter_input( INPUT_POST, 'nonce' ) ) ) {
400 $type = filter_input( INPUT_POST, 'type' );
401 if ( in_array( $type, Visualizer_Plugin::getChartTypes() ) ) {
402 // save new chart type
403 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_CHART_TYPE, $type );
404 // if the chart has default data, update it with appropriate default data for new type
405 if ( filter_var( get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, true ), FILTER_VALIDATE_BOOLEAN ) ) {
406 $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $type . '.csv' );
407 $source->fetch();
408 $this->_chart->post_content = $source->getData();
409 wp_update_post( $this->_chart->to_array() );
410 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
411 }
412 // redirect to next tab
413 // changed by Ash/Upwork
414 wp_redirect( add_query_arg( 'tab', 'settings' ) );
415
416 return;
417 }
418 }
419 $render = new Visualizer_Render_Page_Types();
420 $render->type = get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
421 $render->types = Visualizer_Module_Admin::_getChartTypesLocalized();
422 $render->chart = $this->_chart;
423 wp_enqueue_style( 'visualizer-frame' );
424 wp_enqueue_script( 'visualizer-frame' );
425 wp_iframe( array( $render, 'render' ) );
426 }
427
428 /**
429 * Renders flattr script in the iframe <head>
430 *
431 * @since 1.4.2
432 * @action admin_head
433 *
434 * @access public
435 */
436 public function renderFlattrScript() {
437 echo '';
438 }
439 // changed by Ash/Upwork
440 /**
441 * Parses uploaded CSV file and saves new data for the chart.
442 *
443 * @since 1.0.0
444 *
445 * @access public
446 */
447 public function uploadData() {
448 // if this is being called internally from pro and VISUALIZER_DO_NOT_DIE is set.
449 // otherwise, assume this is a normal web request.
450 $can_die = ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE );
451
452 // validate nonce
453 if ( ! isset( $_GET['nonce'] ) || ! wp_verify_nonce( $_GET['nonce'] ) ) {
454 if ( ! $can_die ) {
455 return;
456 }
457 status_header( 403 );
458 exit;
459 }
460
461 // check chart, if chart exists
462 // do not use filter_input as it does not work for phpunit test cases, use filter_var instead
463 $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
464 if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
465 if ( ! $can_die ) {
466 return;
467 }
468 status_header( 400 );
469 exit;
470 }
471
472 if ( ! isset( $_POST['vz-import-time'] ) ) {
473 apply_filters( 'visualizer_pro_remove_schedule', $chart_id );
474 }
475
476 if ( ! isset( $_POST['chart_data_src'] ) || Visualizer_Plugin::CF_SOURCE_FILTER !== $_POST['chart_data_src'] ) {
477 // delete the filters in case this chart is being uploaded from other data sources
478 delete_post_meta( $chart_id, 'visualizer-filter-config' );
479 }
480
481 $source = null;
482 $render = new Visualizer_Render_Page_Update();
483 if ( isset( $_POST['remote_data'] ) && filter_var( $_POST['remote_data'], FILTER_VALIDATE_URL ) ) {
484 $source = new Visualizer_Source_Csv_Remote( $_POST['remote_data'] );
485 if ( isset( $_POST['vz-import-time'] ) ) {
486 apply_filters( 'visualizer_pro_chart_schedule', $chart_id, $_POST['remote_data'], $_POST['vz-import-time'] );
487 }
488 } elseif ( isset( $_FILES['local_data'] ) && $_FILES['local_data']['error'] == 0 ) {
489 $source = new Visualizer_Source_Csv( $_FILES['local_data']['tmp_name'] );
490 } elseif ( isset( $_POST['chart_data'] ) && strlen( $_POST['chart_data'] ) > 0 ) {
491 $source = apply_filters( 'visualizer_pro_handle_chart_data', $_POST['chart_data'], '' );
492 } else {
493 $render->message = esc_html__( 'CSV file with chart data was not uploaded. Please, try again.', 'visualizer' );
494 }
495 if ( $source ) {
496 if ( $source->fetch() ) {
497 $content = $source->getData();
498 $populate = true;
499 if ( is_string( $content ) && is_array( unserialize( $content ) ) ) {
500 $json = unserialize( $content );
501 // if source exists, so should data. if source exists but data is blank, do not populate the chart.
502 // if we populate the data even if it is empty, the chart will show "Table has no columns".
503 if ( array_key_exists( 'source', $json ) && ! empty( $json['source'] ) && ( ! array_key_exists( 'data', $json ) || empty( $json['data'] ) ) ) {
504 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__ );
505 $populate = false;
506 }
507 }
508 if ( $populate ) {
509 $chart->post_content = $content;
510 }
511 wp_update_post( $chart->to_array() );
512 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
513 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
514 update_post_meta( $chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
515 $render->data = json_encode( $source->getRawData() );
516 $render->series = json_encode( $source->getSeries() );
517 } else {
518 $render->message = esc_html__( 'CSV file is broken or invalid. Please, try again.', 'visualizer' );
519 }
520 }
521 $render->render();
522 if ( ! $can_die ) {
523 return;
524 }
525 defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
526 }
527
528 /**
529 * Clones the chart.
530 *
531 * @since 1.0.0
532 *
533 * @access public
534 */
535 public function cloneChart() {
536 $chart_id = $success = false;
537 $nonce = wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), Visualizer_Plugin::ACTION_CLONE_CHART );
538 $capable = current_user_can( 'edit_posts' );
539 if ( $nonce && $capable ) {
540 $chart_id = filter_input(
541 INPUT_GET, 'chart', FILTER_VALIDATE_INT, array(
542 'options' => array(
543 'min_range' => 1,
544 ),
545 )
546 );
547 if ( $chart_id ) {
548 $chart = get_post( $chart_id );
549 $success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
550 }
551 }
552 $redirect = wp_get_referer();
553 if ( $success ) {
554 $new_chart_id = wp_insert_post(
555 array(
556 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
557 'post_title' => 'Visualization',
558 'post_author' => get_current_user_id(),
559 'post_status' => $chart->post_status,
560 'post_content' => $chart->post_content,
561 )
562 );
563 if ( $new_chart_id && ! is_wp_error( $new_chart_id ) ) {
564 add_post_meta( $new_chart_id, Visualizer_Plugin::CF_CHART_TYPE, get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true ) );
565 add_post_meta( $new_chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, get_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, true ) );
566 add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SOURCE, get_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, true ) );
567 add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SERIES, get_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, true ) );
568 add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SETTINGS, get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true ) );
569 $redirect = add_query_arg(
570 array(
571 'page' => 'visualizer',
572 'type' => filter_input( INPUT_GET, 'type' ),
573 ), admin_url( 'upload.php' )
574 );
575 }
576 }
577 wp_redirect( $redirect );
578 exit;
579 }
580
581 /**
582 * Exports the chart data
583 *
584 * @since 1.0.0
585 *
586 * @access public
587 */
588 public function exportData() {
589 check_ajax_referer( Visualizer_Plugin::ACTION_EXPORT_DATA . Visualizer_Plugin::VERSION, 'security' );
590 $capable = current_user_can( 'edit_posts' );
591 if ( $capable ) {
592 $chart_id = isset( $_GET['chart'] ) ? filter_var(
593 $_GET['chart'], FILTER_VALIDATE_INT, array(
594 'options' => array(
595 'min_range' => 1,
596 ),
597 )
598 ) : '';
599 if ( $chart_id ) {
600 $data = $this->_getDataAs( $chart_id, 'csv' );
601 if ( $data ) {
602 echo wp_send_json_success( $data );
603 }
604 }
605 }
606
607 defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
608 }
609
610 /**
611 * Handles chart data page.
612 *
613 * @since 1.0.0
614 *
615 * @access private
616 */
617 private function _handleDataPage() {
618 $data = $this->_getChartArray();
619 $render = new Visualizer_Render_Page_Data();
620 $render->chart = $this->_chart;
621 $render->type = $data['type'];
622 unset( $data['settings']['width'], $data['settings']['height'] );
623 wp_enqueue_style( 'visualizer-frame' );
624 wp_enqueue_script( 'visualizer-render' );
625 wp_localize_script(
626 'visualizer-render', 'visualizer', array(
627 'l10n' => array(
628 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ),
629 'loading' => esc_html__( 'Loading...', 'visualizer' ),
630 ),
631 'charts' => array(
632 'canvas' => $data,
633 ),
634 )
635 );
636 // Added by Ash/Upwork
637 if ( VISUALIZER_PRO ) {
638 global $Visualizer_Pro;
639 $Visualizer_Pro->_enqueueScriptsAndStyles( $data );
640 }
641 // Added by Ash/Upwork
642 $this->_addAction( 'admin_head', 'renderFlattrScript' );
643 wp_iframe( array( $render, 'render' ) );
644 }
645
646 }
647