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

514 lines 16.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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
64 /**
65 * Sends json response.
66 *
67 * @since 1.0.0
68 *
69 * @access private
70 * @param array $results The response array.
71 */
72 private function _sendResponse( $results ) {
73 header( 'Content-type: application/json' );
74 nocache_headers();
75
76 echo json_encode( $results );
77 exit;
78 }
79
80 /**
81 * Returns chart data required for rendering.
82 *
83 * @since 1.0.0
84 *
85 * @access private
86 * @param WP_Post $chart The chart object.
87 * @return array The array of chart data.
88 */
89 private function _getChartArray( WP_Post $chart = null ) {
90 if ( is_null( $chart ) ) {
91 $chart = $this->_chart;
92 }
93
94 $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
95 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
96 $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( $chart->post_content ), $chart->ID, $type );
97
98 return array(
99 'type' => $type,
100 'series' => $series,
101 'settings' => get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true ),
102 'data' => $data,
103 );
104 }
105
106 /**
107 * Fetches charts from database.
108 *
109 * @since 1.0.0
110 *
111 * @access public
112 */
113 public function getCharts() {
114 $query_args = array(
115 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
116 'posts_per_page' => 9,
117 'paged' => filter_input( INPUT_GET, 'page', FILTER_VALIDATE_INT, array(
118 'options' => array(
119 'min_range' => 1,
120 'default' => 1,
121 )
122 ) )
123 );
124
125 $filter = filter_input( INPUT_GET, 'filter' );
126 if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) {
127 $query_args['meta_query'] = array(
128 array(
129 'key' => Visualizer_Plugin::CF_CHART_TYPE,
130 'value' => $filter,
131 'compare' => '=',
132 ),
133 );
134 }
135
136 $query = new WP_Query( $query_args );
137
138 $charts = array();
139 while( $query->have_posts() ) {
140 $chart = $query->next_post();
141
142 $chart_data = $this->_getChartArray( $chart );
143 $chart_data['id'] = $chart->ID;
144
145 $charts[] = $chart_data;
146 }
147
148 $this->_sendResponse( array(
149 'success' => true,
150 'data' => $charts,
151 'total' => $query->max_num_pages,
152 ) );
153 }
154
155 /**
156 * Deletes a chart from database.
157 *
158 * @since 1.0.0
159 * @uses wp_delete_post() To delete a chart.
160 *
161 * @access public
162 */
163 public function deleteChart() {
164 $is_post = $_SERVER['REQUEST_METHOD'] == 'POST';
165 $input_method = $is_post ? INPUT_POST : INPUT_GET;
166
167 $chart_id = $success = false;
168 $nonce = wp_verify_nonce( filter_input( $input_method, 'nonce' ) );
169 $capable = current_user_can( 'delete_posts' );
170 if ( $nonce && $capable ) {
171 $chart_id = filter_input( $input_method, 'chart', FILTER_VALIDATE_INT, array( 'options' => array( 'min_range' => 1 ) ) );
172 if ( $chart_id ) {
173 $chart = get_post( $chart_id );
174 $success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
175 }
176 }
177
178 if ( $success ) {
179 wp_delete_post( $chart_id, true );
180 }
181
182 if ( $is_post ) {
183 $this->_sendResponse( array( 'success' => $success ) );
184 }
185
186 wp_redirect( wp_get_referer() );
187 exit;
188 }
189
190 /**
191 * Renders appropriate page for chart builder. Creates new auto draft chart
192 * if no chart has been specified.
193 *
194 * @since 1.0.0
195 *
196 * @access public
197 */
198 public function renderChartPages() {
199 define ( 'IFRAME_REQUEST', 1 );
200
201 // check chart, if chart not exists, will create new one and redirects to the same page with proper chart id
202 $chart_id = filter_input( INPUT_GET, 'chart', FILTER_VALIDATE_INT );
203 if ( !$chart_id || !( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
204 $default_type = 'line';
205
206 $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $default_type . '.csv' );
207 $source->fetch();
208
209 $chart_id = wp_insert_post( array(
210 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
211 'post_title' => 'Visualization',
212 'post_author' => get_current_user_id(),
213 'post_status' => 'auto-draft',
214 'post_content' => $source->getData(),
215 ) );
216
217 if ( $chart_id && !is_wp_error( $chart_id ) ) {
218 add_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, $default_type );
219 add_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 1 );
220 add_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
221 add_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
222 add_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, array() );
223 }
224
225 wp_redirect( add_query_arg( 'chart', (int)$chart_id ) );
226 exit;
227 }
228
229 // enqueue and register scripts and styles
230 wp_register_style( 'visualizer-frame', VISUALIZER_ABSURL . 'css/frame.css', array(), Visualizer_Plugin::VERSION );
231
232 wp_register_script( 'visualizer-frame', VISUALIZER_ABSURL . 'js/frame.js', array( 'jquery' ), Visualizer_Plugin::VERSION, true );
233 wp_register_script( 'google-jsapi', '//www.google.com/jsapi', array(), null, true );
234 wp_register_script( 'visualizer-render', VISUALIZER_ABSURL . 'js/render.js', array( 'google-jsapi', 'visualizer-frame' ), Visualizer_Plugin::VERSION, true );
235 wp_register_script( 'visualizer-preview', VISUALIZER_ABSURL . 'js/preview.js', array( 'wp-color-picker', 'visualizer-render' ), Visualizer_Plugin::VERSION, true );
236
237 // dispatch pages
238 $this->_chart = $chart;
239 switch ( filter_input( INPUT_GET, 'tab' ) ) {
240 case 'data':
241 $this->_handleDataPage();
242 break;
243 case 'settings':
244 $this->_handleSettingsPage();
245 break;
246 case 'type':
247 default:
248 $this->_handleTypesPage();
249 break;
250 }
251
252 exit;
253 }
254
255 /**
256 * Handles chart type selection page.
257 *
258 * @since 1.0.0
259 *
260 * @access private
261 */
262 private function _handleTypesPage() {
263 // process post request
264 if ( $_SERVER['REQUEST_METHOD'] == 'POST' && wp_verify_nonce( filter_input( INPUT_POST, 'nonce' ) ) ) {
265 $type = filter_input( INPUT_POST, 'type' );
266 if ( in_array( $type, Visualizer_Plugin::getChartTypes() ) ) {
267 // save new chart type
268 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_CHART_TYPE, $type );
269
270 // if the chart has default data, update it with appropriate default data for new type
271 if ( filter_var( get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, true ), FILTER_VALIDATE_BOOLEAN ) ) {
272 $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $type . '.csv' );
273 $source->fetch();
274
275 $this->_chart->post_content = $source->getData();
276 wp_update_post( $this->_chart->to_array() );
277
278 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
279 }
280
281 // redirect to next tab
282 wp_redirect( add_query_arg( 'tab', 'data' ) );
283 return;
284 }
285 }
286
287 $render = new Visualizer_Render_Page_Types();
288 $render->type = get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
289 $render->types = Visualizer_Plugin::getChartTypes();
290 $render->chart = $this->_chart;
291
292 wp_enqueue_style( 'visualizer-frame' );
293 wp_enqueue_script( 'visualizer-frame' );
294
295 wp_iframe( array( $render, 'render') );
296 }
297
298 /**
299 * Handles chart data page.
300 *
301 * @since 1.0.0
302 *
303 * @access private
304 */
305 private function _handleDataPage() {
306 $data = $this->_getChartArray();
307
308 $render = new Visualizer_Render_Page_Data();
309 $render->chart = $this->_chart;
310 $render->type = $data['type'];
311
312 unset( $data['settings']['width'], $data['settings']['height'] );
313
314 wp_enqueue_style( 'visualizer-frame' );
315 wp_enqueue_script( 'visualizer-render' );
316 wp_localize_script( 'visualizer-render', 'visualizer', array(
317 'l10n' => array(
318 'remotecsv_prompt' => esc_html__( 'Please, enter the URL of CSV file:', Visualizer_Plugin::NAME ),
319 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', Visualizer_Plugin::NAME ),
320 ),
321 'charts' => array(
322 'canvas' => $data,
323 ),
324 ) );
325
326 $this->_addAction( 'admin_head', 'renderFlattrScript' );
327
328 wp_iframe( array( $render, 'render') );
329 }
330
331 /**
332 * Handles chart settigns page.
333 *
334 * @since 1.0.0
335 *
336 * @access private
337 */
338 private function _handleSettingsPage() {
339 if ( $_SERVER['REQUEST_METHOD'] == 'POST' && wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ) ) ) {
340 if ( $this->_chart->post_status == 'auto-draft' ) {
341 $this->_chart->post_status = 'publish';
342 wp_update_post( $this->_chart->to_array() );
343 }
344
345 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $_POST );
346
347 $render = new Visualizer_Render_Page_Send();
348 $render->text = sprintf( '[visualizer id="%d"]', $this->_chart->ID );
349
350 wp_iframe( array( $render, 'render') );
351 return;
352 }
353
354 $data = $this->_getChartArray();
355
356 $sidebar = '';
357 $sidebar_class = 'Visualizer_Render_Sidebar_Type_' . ucfirst( $data['type'] );
358 if ( class_exists( $sidebar_class, true ) ) {
359 $sidebar = new $sidebar_class( $data['settings'] );
360 $sidebar->__series = $data['series'];
361 $sidebar->__data = $data['data'];
362 }
363
364 unset( $data['settings']['width'], $data['settings']['height'] );
365
366 wp_enqueue_style( 'wp-color-picker' );
367 wp_enqueue_style( 'visualizer-frame' );
368
369 wp_enqueue_script( 'visualizer-preview' );
370 wp_localize_script( 'visualizer-render', 'visualizer', array(
371 'charts' => array(
372 'canvas' => $data,
373 ),
374 ) );
375
376 $render = new Visualizer_Render_Page_Settings();
377
378 $render->sidebar = $sidebar;
379 if ( filter_input( INPUT_GET, 'library', FILTER_VALIDATE_BOOLEAN ) ) {
380 $render->button = filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART
381 ? esc_html__( 'Save Chart', Visualizer_Plugin::NAME )
382 : esc_html__( 'Create Chart', Visualizer_Plugin::NAME );
383 } else {
384 $render->button = esc_attr__( 'Insert Chart', Visualizer_Plugin::NAME );
385 }
386
387 $this->_addAction( 'admin_head', 'renderFlattrScript' );
388
389 wp_iframe( array( $render, 'render') );
390 }
391
392 /**
393 * Renders flattr script in the iframe <head>
394 *
395 * @since 1.4.2
396 * @action admin_head
397 *
398 * @access public
399 */
400 public function renderFlattrScript() {
401 echo <<<EOL
402 <script type="text/javascript">
403 /* <![CDATA[ */
404 (function() {
405 var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
406 s.type = 'text/javascript';
407 s.async = true;
408 s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
409 t.parentNode.insertBefore(s, t);
410 })();
411 /* ]]> */
412 </script>
413 EOL;
414 }
415
416 /**
417 * Parses uploaded CSV file and saves new data for the chart.
418 *
419 * @since 1.0.0
420 *
421 * @access public
422 */
423 public function uploadData() {
424 // validate nonce
425 if ( !wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ) ) ) {
426 status_header( 403 );
427 exit;
428 }
429
430 // check chart, if chart exists
431 $chart_id = filter_input( INPUT_GET, 'chart', FILTER_VALIDATE_INT );
432 if ( !$chart_id || !( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
433 status_header( 400 );
434 exit;
435 }
436
437 $source = null;
438 $render = new Visualizer_Render_Page_Update();
439 if ( filter_input( INPUT_POST, 'remote_data', FILTER_VALIDATE_URL ) ) {
440 $source = new Visualizer_Source_Csv_Remote( $_POST['remote_data'] );
441 } elseif ( isset( $_FILES['local_data'] ) && $_FILES['local_data']['error'] == 0 ) {
442 $source = new Visualizer_Source_Csv( $_FILES['local_data']['tmp_name'] );
443 } else {
444 $render->message = esc_html__( "CSV file with chart data was not uploaded. Please, try again.", Visualizer_Plugin::NAME );
445 }
446
447 if ( $source ) {
448 if ( $source->fetch() ) {
449 $chart->post_content = $source->getData();
450 wp_update_post( $chart->to_array() );
451
452 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
453 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
454 update_post_meta( $chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
455
456 $render->data = json_encode( $source->getRawData() );
457 $render->series = json_encode( $source->getSeries() );
458 } else {
459 $render->message = esc_html__( "CSV file is broken or invalid. Please, try again.", Visualizer_Plugin::NAME );
460 }
461 }
462
463 $render->render();
464 exit;
465 }
466
467 /**
468 * Clones the chart.
469 *
470 * @since 1.0.0
471 *
472 * @access public
473 */
474 public function cloneChart() {
475 $chart_id = $success = false;
476 $nonce = wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), Visualizer_Plugin::ACTION_CLONE_CHART );
477 $capable = current_user_can( 'edit_posts' );
478 if ( $nonce && $capable ) {
479 $chart_id = filter_input( INPUT_GET, 'chart', FILTER_VALIDATE_INT, array( 'options' => array( 'min_range' => 1 ) ) );
480 if ( $chart_id ) {
481 $chart = get_post( $chart_id );
482 $success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
483 }
484 }
485
486 $redirect = wp_get_referer();
487 if ( $success ) {
488 $new_chart_id = wp_insert_post( array(
489 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
490 'post_title' => 'Visualization',
491 'post_author' => get_current_user_id(),
492 'post_status' => $chart->post_status,
493 'post_content' => $chart->post_content,
494 ) );
495
496 if ( $new_chart_id && !is_wp_error( $new_chart_id ) ) {
497 add_post_meta( $new_chart_id, Visualizer_Plugin::CF_CHART_TYPE, get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true ) );
498 add_post_meta( $new_chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, get_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, true ) );
499 add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SOURCE, get_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, true ) );
500 add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SERIES, get_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, true ) );
501 add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SETTINGS, get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true ) );
502
503 $redirect = add_query_arg( array(
504 'page' => 'visualizer',
505 'type' => filter_input( INPUT_GET, 'type' ),
506 ), admin_url( 'upload.php' ) );
507 }
508 }
509
510 wp_redirect( $redirect );
511 exit;
512 }
513
514 }