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