PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 1.3.0.1
Visualizer – Tables & Charts Manager with Built-in AI Generator v1.3.0.1
4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 3.10.4 All 148 releases
visualizer / classes / Visualizer / Module / Chart.php

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

486 lines 15.7 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 = Visualizer_Security::verifyNonce( 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' && Visualizer_Security::verifyNonce( 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 wp_iframe( array( $render, 'render') );
327 }
328
329 /**
330 * Handles chart settigns page.
331 *
332 * @since 1.0.0
333 *
334 * @access private
335 */
336 private function _handleSettingsPage() {
337 if ( $_SERVER['REQUEST_METHOD'] == 'POST' && Visualizer_Security::verifyNonce( filter_input( INPUT_GET, 'nonce' ) ) ) {
338 if ( $this->_chart->post_status == 'auto-draft' ) {
339 $this->_chart->post_status = 'publish';
340 wp_update_post( $this->_chart->to_array() );
341 }
342
343 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $_POST );
344
345 $render = new Visualizer_Render_Page_Send();
346 $render->text = sprintf( '[visualizer id="%d"]', $this->_chart->ID );
347
348 wp_iframe( array( $render, 'render') );
349 return;
350 }
351
352 $data = $this->_getChartArray();
353
354 $sidebar = '';
355 $sidebar_class = 'Visualizer_Render_Sidebar_Type_' . ucfirst( $data['type'] );
356 if ( class_exists( $sidebar_class, true ) ) {
357 $sidebar = new $sidebar_class( $data['settings'] );
358 $sidebar->__series = $data['series'];
359 $sidebar->__data = $data['data'];
360 }
361
362 unset( $data['settings']['width'], $data['settings']['height'] );
363
364 wp_enqueue_style( 'wp-color-picker' );
365 wp_enqueue_style( 'visualizer-frame' );
366
367 wp_enqueue_script( 'visualizer-preview' );
368 wp_localize_script( 'visualizer-render', 'visualizer', array(
369 'charts' => array(
370 'canvas' => $data,
371 ),
372 ) );
373
374 $render = new Visualizer_Render_Page_Settings();
375
376 $render->sidebar = $sidebar;
377 if ( filter_input( INPUT_GET, 'library', FILTER_VALIDATE_BOOLEAN ) ) {
378 $render->button = filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART
379 ? esc_html__( 'Save Chart', Visualizer_Plugin::NAME )
380 : esc_html__( 'Create Chart', Visualizer_Plugin::NAME );
381 } else {
382 $render->button = esc_attr__( 'Insert Chart', Visualizer_Plugin::NAME );
383 }
384
385 wp_iframe( array( $render, 'render') );
386 }
387
388 /**
389 * Parses uploaded CSV file and saves new data for the chart.
390 *
391 * @since 1.0.0
392 *
393 * @access public
394 */
395 public function uploadData() {
396 // validate nonce
397 if ( !Visualizer_Security::verifyNonce( filter_input( INPUT_GET, 'nonce' ) ) ) {
398 status_header( 403 );
399 exit;
400 }
401
402 // check chart, if chart exists
403 $chart_id = filter_input( INPUT_GET, 'chart', FILTER_VALIDATE_INT );
404 if ( !$chart_id || !( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
405 status_header( 400 );
406 exit;
407 }
408
409 $source = null;
410 $render = new Visualizer_Render_Page_Update();
411 if ( filter_input( INPUT_POST, 'remote_data', FILTER_VALIDATE_URL ) ) {
412 $source = new Visualizer_Source_Csv_Remote( $_POST['remote_data'] );
413 } elseif ( isset( $_FILES['local_data'] ) && $_FILES['local_data']['error'] == 0 ) {
414 $source = new Visualizer_Source_Csv( $_FILES['local_data']['tmp_name'] );
415 } else {
416 $render->message = esc_html__( "CSV file with chart data was not uploaded. Please, try again.", Visualizer_Plugin::NAME );
417 }
418
419 if ( $source ) {
420 if ( $source->fetch() ) {
421 $chart->post_content = $source->getData();
422 wp_update_post( $chart->to_array() );
423
424 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
425 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
426 update_post_meta( $chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
427
428 $render->data = json_encode( $source->getRawData() );
429 $render->series = json_encode( $source->getSeries() );
430 } else {
431 $render->message = esc_html__( "CSV file is broken or invalid. Please, try again.", Visualizer_Plugin::NAME );
432 }
433 }
434
435 $render->render();
436 exit;
437 }
438
439 /**
440 * Clones the chart.
441 *
442 * @since 1.0.0
443 *
444 * @access public
445 */
446 public function cloneChart() {
447 $chart_id = $success = false;
448 $nonce = Visualizer_Security::verifyNonce( filter_input( INPUT_GET, 'nonce' ), Visualizer_Plugin::ACTION_CLONE_CHART );
449 $capable = current_user_can( 'edit_posts' );
450 if ( $nonce && $capable ) {
451 $chart_id = filter_input( INPUT_GET, 'chart', FILTER_VALIDATE_INT, array( 'options' => array( 'min_range' => 1 ) ) );
452 if ( $chart_id ) {
453 $chart = get_post( $chart_id );
454 $success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
455 }
456 }
457
458 $redirect = wp_get_referer();
459 if ( $success ) {
460 $new_chart_id = wp_insert_post( array(
461 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
462 'post_title' => 'Visualization',
463 'post_author' => get_current_user_id(),
464 'post_status' => $chart->post_status,
465 'post_content' => $chart->post_content,
466 ) );
467
468 if ( $new_chart_id && !is_wp_error( $new_chart_id ) ) {
469 add_post_meta( $new_chart_id, Visualizer_Plugin::CF_CHART_TYPE, get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true ) );
470 add_post_meta( $new_chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, get_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, true ) );
471 add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SOURCE, get_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, true ) );
472 add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SERIES, get_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, true ) );
473 add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SETTINGS, get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true ) );
474
475 $redirect = add_query_arg( array(
476 'page' => 'visualizer',
477 'type' => filter_input( INPUT_GET, 'type' ),
478 ), admin_url( 'upload.php' ) );
479 }
480 }
481
482 wp_redirect( $redirect );
483 exit;
484 }
485
486 }