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

484 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 // check chart, if chart not exists, will create new one and redirects to the same page with proper chart id
200 $chart_id = filter_input( INPUT_GET, 'chart', FILTER_VALIDATE_INT );
201 if ( !$chart_id || !( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
202 $default_type = 'line';
203
204 $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $default_type . '.csv' );
205 $source->fetch();
206
207 $chart_id = wp_insert_post( array(
208 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
209 'post_title' => 'Visualization',
210 'post_author' => get_current_user_id(),
211 'post_status' => 'auto-draft',
212 'post_content' => $source->getData(),
213 ) );
214
215 if ( $chart_id && !is_wp_error( $chart_id ) ) {
216 add_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, $default_type );
217 add_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 1 );
218 add_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
219 add_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
220 add_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, array() );
221 }
222
223 wp_redirect( add_query_arg( 'chart', (int)$chart_id ) );
224 exit;
225 }
226
227 // enqueue and register scripts and styles
228 wp_register_style( 'visualizer-frame', VISUALIZER_ABSURL . 'css/frame.css', array(), Visualizer_Plugin::VERSION );
229
230 wp_register_script( 'visualizer-frame', VISUALIZER_ABSURL . 'js/frame.js', array( 'jquery' ), Visualizer_Plugin::VERSION, true );
231 wp_register_script( 'google-jsapi', '//www.google.com/jsapi', array(), null, true );
232 wp_register_script( 'visualizer-render', VISUALIZER_ABSURL . 'js/render.js', array( 'google-jsapi', 'visualizer-frame' ), Visualizer_Plugin::VERSION, true );
233 wp_register_script( 'visualizer-preview', VISUALIZER_ABSURL . 'js/preview.js', array( 'wp-color-picker', 'visualizer-render' ), Visualizer_Plugin::VERSION, true );
234
235 // dispatch pages
236 $this->_chart = $chart;
237 switch ( filter_input( INPUT_GET, 'tab' ) ) {
238 case 'data':
239 $this->_handleDataPage();
240 break;
241 case 'settings':
242 $this->_handleSettingsPage();
243 break;
244 case 'type':
245 default:
246 $this->_handleTypesPage();
247 break;
248 }
249
250 exit;
251 }
252
253 /**
254 * Handles chart type selection page.
255 *
256 * @since 1.0.0
257 *
258 * @access private
259 */
260 private function _handleTypesPage() {
261 // process post request
262 if ( $_SERVER['REQUEST_METHOD'] == 'POST' && Visualizer_Security::verifyNonce( filter_input( INPUT_POST, 'nonce' ) ) ) {
263 $type = filter_input( INPUT_POST, 'type' );
264 if ( in_array( $type, Visualizer_Plugin::getChartTypes() ) ) {
265 // save new chart type
266 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_CHART_TYPE, $type );
267
268 // if the chart has default data, update it with appropriate default data for new type
269 if ( filter_var( get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, true ), FILTER_VALIDATE_BOOLEAN ) ) {
270 $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $type . '.csv' );
271 $source->fetch();
272
273 $this->_chart->post_content = $source->getData();
274 wp_update_post( $this->_chart->to_array() );
275
276 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
277 }
278
279 // redirect to next tab
280 wp_redirect( add_query_arg( 'tab', 'data' ) );
281 return;
282 }
283 }
284
285 $render = new Visualizer_Render_Page_Types();
286 $render->type = get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
287 $render->types = Visualizer_Plugin::getChartTypes();
288 $render->chart = $this->_chart;
289
290 wp_enqueue_style( 'visualizer-frame' );
291 wp_enqueue_script( 'visualizer-frame' );
292
293 wp_iframe( array( $render, 'render') );
294 }
295
296 /**
297 * Handles chart data page.
298 *
299 * @since 1.0.0
300 *
301 * @access private
302 */
303 private function _handleDataPage() {
304 $data = $this->_getChartArray();
305
306 $render = new Visualizer_Render_Page_Data();
307 $render->chart = $this->_chart;
308 $render->type = $data['type'];
309
310 unset( $data['settings']['width'], $data['settings']['height'] );
311
312 wp_enqueue_style( 'visualizer-frame' );
313 wp_enqueue_script( 'visualizer-render' );
314 wp_localize_script( 'visualizer-render', 'visualizer', array(
315 'l10n' => array(
316 'remotecsv_prompt' => esc_html__( 'Please, enter the URL of CSV file:', Visualizer_Plugin::NAME ),
317 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', Visualizer_Plugin::NAME ),
318 ),
319 'charts' => array(
320 'canvas' => $data,
321 ),
322 ) );
323
324 wp_iframe( array( $render, 'render') );
325 }
326
327 /**
328 * Handles chart settigns page.
329 *
330 * @since 1.0.0
331 *
332 * @access private
333 */
334 private function _handleSettingsPage() {
335 if ( $_SERVER['REQUEST_METHOD'] == 'POST' && Visualizer_Security::verifyNonce( filter_input( INPUT_GET, 'nonce' ) ) ) {
336 if ( $this->_chart->post_status == 'auto-draft' ) {
337 $this->_chart->post_status = 'publish';
338 wp_update_post( $this->_chart->to_array() );
339 }
340
341 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $_POST );
342
343 $render = new Visualizer_Render_Page_Send();
344 $render->text = sprintf( '[visualizer id="%d"]', $this->_chart->ID );
345
346 wp_iframe( array( $render, 'render') );
347 return;
348 }
349
350 $data = $this->_getChartArray();
351
352 $sidebar = '';
353 $sidebar_class = 'Visualizer_Render_Sidebar_Type_' . ucfirst( $data['type'] );
354 if ( class_exists( $sidebar_class, true ) ) {
355 $sidebar = new $sidebar_class( $data['settings'] );
356 $sidebar->__series = $data['series'];
357 $sidebar->__data = $data['data'];
358 }
359
360 unset( $data['settings']['width'], $data['settings']['height'] );
361
362 wp_enqueue_style( 'wp-color-picker' );
363 wp_enqueue_style( 'visualizer-frame' );
364
365 wp_enqueue_script( 'visualizer-preview' );
366 wp_localize_script( 'visualizer-render', 'visualizer', array(
367 'charts' => array(
368 'canvas' => $data,
369 ),
370 ) );
371
372 $render = new Visualizer_Render_Page_Settings();
373
374 $render->sidebar = $sidebar;
375 if ( filter_input( INPUT_GET, 'library', FILTER_VALIDATE_BOOLEAN ) ) {
376 $render->button = filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART
377 ? esc_html__( 'Save Chart', Visualizer_Plugin::NAME )
378 : esc_html__( 'Create Chart', Visualizer_Plugin::NAME );
379 } else {
380 $render->button = esc_attr__( 'Insert Chart', Visualizer_Plugin::NAME );
381 }
382
383 wp_iframe( array( $render, 'render') );
384 }
385
386 /**
387 * Parses uploaded CSV file and saves new data for the chart.
388 *
389 * @since 1.0.0
390 *
391 * @access public
392 */
393 public function uploadData() {
394 // validate nonce
395 if ( !Visualizer_Security::verifyNonce( filter_input( INPUT_GET, 'nonce' ) ) ) {
396 status_header( 403 );
397 exit;
398 }
399
400 // check chart, if chart exists
401 $chart_id = filter_input( INPUT_GET, 'chart', FILTER_VALIDATE_INT );
402 if ( !$chart_id || !( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
403 status_header( 400 );
404 exit;
405 }
406
407 $source = null;
408 $render = new Visualizer_Render_Page_Update();
409 if ( filter_input( INPUT_POST, 'remote_data', FILTER_VALIDATE_URL ) ) {
410 $source = new Visualizer_Source_Csv_Remote( $_POST['remote_data'] );
411 } elseif ( isset( $_FILES['local_data'] ) && $_FILES['local_data']['error'] == 0 ) {
412 $source = new Visualizer_Source_Csv( $_FILES['local_data']['tmp_name'] );
413 } else {
414 $render->message = esc_html__( "CSV file with chart data was not uploaded. Please, try again.", Visualizer_Plugin::NAME );
415 }
416
417 if ( $source ) {
418 if ( $source->fetch() ) {
419 $chart->post_content = $source->getData();
420 wp_update_post( $chart->to_array() );
421
422 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
423 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
424 update_post_meta( $chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
425
426 $render->data = json_encode( $source->getRawData() );
427 $render->series = json_encode( $source->getSeries() );
428 } else {
429 $render->message = esc_html__( "CSV file is broken or invalid. Please, try again.", Visualizer_Plugin::NAME );
430 }
431 }
432
433 $render->render();
434 exit;
435 }
436
437 /**
438 * Clones the chart.
439 *
440 * @since 1.0.0
441 *
442 * @access public
443 */
444 public function cloneChart() {
445 $chart_id = $success = false;
446 $nonce = Visualizer_Security::verifyNonce( filter_input( INPUT_GET, 'nonce' ), Visualizer_Plugin::ACTION_CLONE_CHART );
447 $capable = current_user_can( 'edit_posts' );
448 if ( $nonce && $capable ) {
449 $chart_id = filter_input( INPUT_GET, 'chart', FILTER_VALIDATE_INT, array( 'options' => array( 'min_range' => 1 ) ) );
450 if ( $chart_id ) {
451 $chart = get_post( $chart_id );
452 $success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
453 }
454 }
455
456 $redirect = wp_get_referer();
457 if ( $success ) {
458 $new_chart_id = wp_insert_post( array(
459 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
460 'post_title' => 'Visualization',
461 'post_author' => get_current_user_id(),
462 'post_status' => $chart->post_status,
463 'post_content' => $chart->post_content,
464 ) );
465
466 if ( $new_chart_id && !is_wp_error( $new_chart_id ) ) {
467 add_post_meta( $new_chart_id, Visualizer_Plugin::CF_CHART_TYPE, get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true ) );
468 add_post_meta( $new_chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, get_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, true ) );
469 add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SOURCE, get_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, true ) );
470 add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SERIES, get_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, true ) );
471 add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SETTINGS, get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true ) );
472
473 $redirect = add_query_arg( array(
474 'page' => 'visualizer',
475 'type' => filter_input( INPUT_GET, 'type' ),
476 ), admin_url( 'upload.php' ) );
477 }
478 }
479
480 wp_redirect( $redirect );
481 exit;
482 }
483
484 }