PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.0.12
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.0.12
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.12, at classes/Visualizer/Module/Chart.php

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