PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.3.4
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.3.4
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 / Gutenberg / Block.php

Block.php in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.3.4, at classes/Visualizer/Gutenberg/Block.php

460 lines 14.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // +----------------------------------------------------------------------+
3 // | Copyright 2018 ThemeIsle (email : friends@themeisle.com) |
4 // +----------------------------------------------------------------------+
5 // | This program is free software; you can redistribute it and/or modify |
6 // | it under the terms of the GNU General Public License, version 2, as |
7 // | published by the Free Software Foundation. |
8 // | |
9 // | This program is distributed in the hope that it will be useful, |
10 // | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 // | GNU General Public License for more details. |
13 // | |
14 // | You should have received a copy of the GNU General Public License |
15 // | along with this program; if not, write to the Free Software |
16 // | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, |
17 // | MA 02110-1301 USA |
18 // +----------------------------------------------------------------------+
19 // | Author: Hardeep Asrani <hardeep@themeisle.com> |
20 // +----------------------------------------------------------------------+
21 /**
22 * All the Gutenberg block related code.
23 *
24 * @category Visualizer
25 * @package Gutenberg
26 *
27 * @since 3.1.0
28 */
29 class Visualizer_Gutenberg_Block {
30
31 /**
32 * A reference to an instance of this class.
33 *
34 * @var Visualizer_Gutenberg_Block The one Visualizer_Gutenberg_Block instance.
35 */
36 private static $instance;
37
38 /**
39 * Visualizer plugin version.
40 *
41 * @var string $version The current version of the plugin.
42 */
43 protected $version;
44
45 /**
46 * Returns an instance of this class.
47 */
48 public static function get_instance() {
49 if ( null === self::$instance ) {
50 self::$instance = new Visualizer_Gutenberg_Block();
51 }
52 return self::$instance;
53 }
54
55 /**
56 * Initializes the plugin by setting filters and administration functions.
57 */
58 private function __construct() {
59 $this->version = Visualizer_Plugin::VERSION;
60 add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_gutenberg_scripts' ) );
61 add_action( 'init', array( $this, 'register_block_type' ) );
62 add_action( 'rest_api_init', array( $this, 'register_rest_endpoints' ) );
63 add_filter( 'rest_visualizer_query', array( $this, 'add_rest_query_vars' ), 9, 2 );
64 }
65
66 /**
67 * Enqueue front end and editor JavaScript and CSS
68 */
69 public function enqueue_gutenberg_scripts() {
70 $blockPath = VISUALIZER_ABSURL . 'classes/Visualizer/Gutenberg/build/block.js';
71 $handsontableJS = VISUALIZER_ABSURL . 'classes/Visualizer/Gutenberg/build/handsontable.js';
72 $stylePath = VISUALIZER_ABSURL . 'classes/Visualizer/Gutenberg/build/block.css';
73 $handsontableCSS = VISUALIZER_ABSURL . 'classes/Visualizer/Gutenberg/build/handsontable.css';
74
75 if ( VISUALIZER_TEST_JS_CUSTOMIZATION ) {
76 $version = filemtime( VISUALIZER_ABSPATH . 'classes/Visualizer/Gutenberg/build/block.js' );
77 } else {
78 $version = $this->version;
79 }
80
81 // Enqueue the bundled block JS file
82 wp_enqueue_script( 'handsontable', $handsontableJS );
83 wp_enqueue_script( 'visualizer-gutenberg-block', $blockPath, array( 'wp-api', 'handsontable', 'visualizer-datatables', 'moment' ), $version, true );
84
85 $type = 'community';
86
87 if ( Visualizer_Module::is_pro() ) {
88 $type = 'pro';
89 if ( apply_filters( 'visualizer_is_business', false ) ) {
90 $type = 'business';
91 }
92 }
93
94 $translation_array = array(
95 'isPro' => $type,
96 'proTeaser' => Visualizer_Plugin::PRO_TEASER_URL,
97 'absurl' => VISUALIZER_ABSURL,
98 'charts' => Visualizer_Module_Admin::_getChartTypesLocalized(),
99 'adminPage' => menu_page_url( 'visualizer', false ),
100 );
101 wp_localize_script( 'visualizer-gutenberg-block', 'visualizerLocalize', $translation_array );
102
103 // Enqueue frontend and editor block styles
104 wp_enqueue_style( 'handsontable', $handsontableCSS );
105 wp_enqueue_style( 'visualizer-gutenberg-block', $stylePath, array( 'visualizer-datatables' ), $version );
106 }
107 /**
108 * Hook server side rendering into render callback
109 */
110 public function register_block_type() {
111 register_block_type(
112 'visualizer/chart', array(
113 'render_callback' => array( $this, 'gutenberg_block_callback' ),
114 'attributes' => array(
115 'id' => array(
116 'type' => 'number',
117 ),
118 ),
119 )
120 );
121 }
122
123 /**
124 * Gutenberg Block Callback Function
125 */
126 public function gutenberg_block_callback( $attr ) {
127 if ( isset( $attr['id'] ) ) {
128 $id = $attr['id'];
129 if ( empty( $id ) || $id === 'none' ) {
130 return ''; // no id = no fun
131 }
132 return '[visualizer id="' . $id . '"]';
133 }
134 }
135
136 /**
137 * Hook server side rendering into render callback
138 */
139 public function register_rest_endpoints() {
140 register_rest_field(
141 'visualizer',
142 'chart_data',
143 array(
144 'get_callback' => array( $this, 'get_visualizer_data' ),
145 )
146 );
147
148 register_rest_route(
149 'visualizer/v' . VISUALIZER_REST_VERSION,
150 '/update-chart',
151 array(
152 'methods' => 'POST',
153 'callback' => array( $this, 'update_chart_data' ),
154 'args' => array(
155 'id' => array(
156 'sanitize_callback' => 'absint',
157 ),
158 ),
159 'permission_callback' => function () {
160 return current_user_can( 'edit_posts' );
161 },
162 )
163 );
164
165 register_rest_route(
166 'visualizer/v' . VISUALIZER_REST_VERSION,
167 '/upload-data',
168 array(
169 'methods' => 'POST',
170 'callback' => array( $this, 'upload_csv_data' ),
171 'args' => array(
172 'url' => array(
173 'sanitize_callback' => 'esc_url_raw',
174 ),
175 ),
176 'permission_callback' => function () {
177 return current_user_can( 'edit_posts' );
178 },
179 )
180 );
181
182 register_rest_route(
183 'visualizer/v' . VISUALIZER_REST_VERSION,
184 '/get-permission-data',
185 array(
186 'methods' => 'GET',
187 'callback' => array( $this, 'get_permission_data' ),
188 'args' => array(
189 'type' => array(
190 'sanitize_callback' => 'sanitize_text_field',
191 ),
192 ),
193 'permission_callback' => function () {
194 return current_user_can( 'edit_posts' );
195 },
196 )
197 );
198 }
199
200 /**
201 * Get Post Meta Fields
202 */
203 public function get_visualizer_data( $post ) {
204 if ( ! current_user_can( 'edit_posts' ) ) {
205 return false;
206 }
207
208 $data = array();
209 $post_id = $post['id'];
210
211 $data['visualizer-chart-type'] = get_post_meta( $post_id, Visualizer_Plugin::CF_CHART_TYPE, true );
212
213 $data['visualizer-chart-library'] = get_post_meta( $post_id, Visualizer_Plugin::CF_CHART_LIBRARY, true );
214
215 $data['visualizer-source'] = get_post_meta( $post_id, Visualizer_Plugin::CF_SOURCE, true );
216
217 $data['visualizer-default-data'] = get_post_meta( $post_id, Visualizer_Plugin::CF_DEFAULT_DATA, true );
218
219 // faetch and update settings
220 $data['visualizer-settings'] = get_post_meta( $post_id, Visualizer_Plugin::CF_SETTINGS, true );
221
222 // handle series filter hooks
223 $data['visualizer-series'] = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $post_id, Visualizer_Plugin::CF_SERIES, true ), $post_id, $data['visualizer-chart-type'] );
224
225 // handle settings filter hooks
226 $data['visualizer-settings'] = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $data['visualizer-settings'], $post_id, $data['visualizer-chart-type'] );
227
228 // handle data filter hooks
229 $data['visualizer-data'] = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( get_the_content( $post_id ) ) ), $post_id, $data['visualizer-chart-type'] );
230
231 $import = get_post_meta( $post_id, Visualizer_Plugin::CF_CHART_URL, true );
232
233 $schedule = get_post_meta( $post_id, Visualizer_Plugin::CF_CHART_SCHEDULE, true );
234
235 if ( ! empty( $import ) && ! empty( $schedule ) ) {
236 $data['visualizer-chart-url'] = $import;
237 $data['visualizer-chart-schedule'] = $schedule;
238 }
239
240 if ( Visualizer_Module::is_pro() ) {
241 $permissions = get_post_meta( $post_id, Visualizer_PRO::CF_PERMISSIONS, true );
242
243 if ( ! empty( $permissions ) ) {
244 $data['visualizer-permissions'] = $permissions;
245 }
246 }
247
248 return $data;
249 }
250
251 /**
252 * Rest Callback Method
253 */
254 public function update_chart_data( $data ) {
255 if ( ! current_user_can( 'edit_posts' ) ) {
256 return false;
257 }
258
259 if ( $data['id'] && ! is_wp_error( $data['id'] ) ) {
260
261 $chart_type = sanitize_text_field( $data['visualizer-chart-type'] );
262 $source_type = sanitize_text_field( $data['visualizer-source'] );
263
264 update_post_meta( $data['id'], Visualizer_Plugin::CF_CHART_TYPE, $chart_type );
265 update_post_meta( $data['id'], Visualizer_Plugin::CF_SOURCE, $source_type );
266 update_post_meta( $data['id'], Visualizer_Plugin::CF_DEFAULT_DATA, $data['visualizer-default-data'] );
267 update_post_meta( $data['id'], Visualizer_Plugin::CF_SERIES, $data['visualizer-series'] );
268 update_post_meta( $data['id'], Visualizer_Plugin::CF_SETTINGS, $data['visualizer-settings'] );
269
270 if ( $data['visualizer-chart-url'] && $data['visualizer-chart-schedule'] ) {
271 $chart_url = esc_url_raw( $data['visualizer-chart-url'] );
272 $chart_schedule = intval( $data['visualizer-chart-schedule'] );
273 update_post_meta( $data['id'], Visualizer_Plugin::CF_CHART_URL, $chart_url );
274 apply_filters( 'visualizer_pro_chart_schedule', $data['id'], $chart_url, $chart_schedule );
275 } else {
276 delete_post_meta( $data['id'], Visualizer_Plugin::CF_CHART_URL );
277 apply_filters( 'visualizer_pro_remove_schedule', $data['id'] );
278 }
279
280 if ( Visualizer_Module::is_pro() ) {
281 update_post_meta( $data['id'], Visualizer_PRO::CF_PERMISSIONS, $data['visualizer-permissions'] );
282 }
283
284 if ( $data['visualizer-chart-url'] ) {
285 $chart_url = esc_url_raw( $data['visualizer-chart-url'] );
286 $content['source'] = $chart_url;
287 $content['data'] = $this->format_chart_data( $data['visualizer-data'], $data['visualizer-series'] );
288 } else {
289 $content = $this->format_chart_data( $data['visualizer-data'], $data['visualizer-series'] );
290 }
291
292 $chart = array(
293 'ID' => $data['id'],
294 'post_content' => serialize( $content ),
295 );
296
297 wp_update_post( $chart );
298
299 $revisions = wp_get_post_revisions( $data['id'], array( 'order' => 'ASC' ) );
300
301 if ( count( $revisions ) > 1 ) {
302 $revision_ids = array_keys( $revisions );
303
304 // delete all revisions.
305 foreach ( $revision_ids as $id ) {
306 wp_delete_post_revision( $id );
307 }
308 }
309
310 return new \WP_REST_Response( array( 'success' => sprintf( 'Chart updated' ) ) );
311 }
312 }
313
314 /**
315 * Format chart data.
316 */
317 public function format_chart_data( $data, $series ) {
318 foreach ( $series as $i => $row ) {
319 // if no value exists for the seires, then add null
320 if ( ! isset( $series[ $i ] ) ) {
321 $series[ $i ] = null;
322 }
323
324 if ( is_null( $series[ $i ] ) ) {
325 continue;
326 }
327
328 if ( $row['type'] === 'number' ) {
329 foreach ( $data as $o => $col ) {
330 $data[ $o ][ $i ] = ( is_numeric( $col[ $i ] ) ) ? floatval( $col[ $i ] ) : ( is_numeric( str_replace( ',', '', $col[ $i ] ) ) ? floatval( str_replace( ',', '', $col[ $i ] ) ) : null );
331 }
332 }
333
334 if ( $row['type'] === 'boolean' ) {
335 foreach ( $data as $o => $col ) {
336 $data[ $o ][ $i ] = ! empty( $col[ $i ] ) ? filter_validate( $col[ $i ], FILTER_VALIDATE_BOOLEAN ) : null;
337 }
338 }
339
340 if ( $row['type'] === 'timeofday' ) {
341 foreach ( $data as $o => $col ) {
342 $date = new DateTime( '1984-03-16T' . $col[ $i ] );
343 if ( $date ) {
344 $data[ $o ][ $i ] = array(
345 intval( $date->format( 'H' ) ),
346 intval( $date->format( 'i' ) ),
347 intval( $date->format( 's' ) ),
348 0,
349 );
350 }
351 }
352 }
353
354 if ( $row['type'] === 'string' ) {
355 foreach ( $data as $o => $col ) {
356 $data[ $o ][ $i ] = $this->toUTF8( $col[ $i ] );
357 }
358 }
359 }
360
361 return $data;
362 }
363
364 /**
365 * Use toUTF8 function
366 */
367 public function toUTF8( $datum ) {
368 if ( ! function_exists( 'mb_detect_encoding' ) || mb_detect_encoding( $datum ) !== 'ASCII' ) {
369 $datum = \ForceUTF8\Encoding::toUTF8( $datum );
370 }
371 return $datum;
372 }
373
374 /**
375 * Handle remote CSV data
376 */
377 public function upload_csv_data( $data ) {
378 if ( ! current_user_can( 'edit_posts' ) ) {
379 return false;
380 }
381
382 if ( $data['url'] && ! is_wp_error( $data['url'] ) && filter_var( $data['url'], FILTER_VALIDATE_URL ) ) {
383 $source = new Visualizer_Source_Csv_Remote( $data['url'] );
384 if ( $source->fetch() ) {
385 $temp = $source->getData();
386 if ( is_string( $temp ) && is_array( unserialize( $temp ) ) ) {
387 $content['series'] = $source->getSeries();
388 $content['data'] = $source->getRawData();
389 return $content;
390 } else {
391 return new \WP_REST_Response( array( 'failed' => sprintf( 'Invalid CSV URL' ) ) );
392 }
393 } else {
394 return new \WP_REST_Response( array( 'failed' => sprintf( 'Invalid CSV URL' ) ) );
395 }
396 } else {
397 return new \WP_REST_Response( array( 'failed' => sprintf( 'Invalid CSV URL' ) ) );
398 }
399 }
400
401 /**
402 * Get permission data
403 */
404 public function get_permission_data( $data ) {
405 if ( ! current_user_can( 'edit_posts' ) ) {
406 return false;
407 }
408
409 $options = array();
410 switch ( $data['type'] ) {
411 case 'users':
412 $query = new WP_User_Query(
413 array(
414 'number' => 1000,
415 'orderby' => 'display_name',
416 'fields' => array( 'ID', 'display_name' ),
417 'count_total' => false,
418 )
419 );
420 $users = $query->get_results();
421 if ( ! empty( $users ) ) {
422 $i = 0;
423 foreach ( $users as $user ) {
424 $options[ $i ]['value'] = $user->ID;
425 $options[ $i ]['label'] = $user->display_name;
426 $i++;
427 }
428 }
429 break;
430 case 'roles':
431 if ( ! function_exists( 'get_editable_roles' ) ) {
432 require_once ABSPATH . 'wp-admin/includes/user.php';
433 }
434 $roles = get_editable_roles();
435 if ( ! empty( $roles ) ) {
436 $i = 0;
437 foreach ( get_editable_roles() as $name => $info ) {
438 $options[ $i ]['value'] = $name;
439 $options[ $i ]['label'] = $name;
440 $i++;
441 }
442 }
443 break;
444 }
445 return $options;
446 }
447
448 /**
449 * Filter Rest Query
450 */
451 public function add_rest_query_vars( $args, \WP_REST_Request $request ) {
452 if ( isset( $request['meta_key'] ) && isset( $request['meta_value'] ) ) {
453 $args['meta_key'] = $request->get_param( 'meta_key' );
454 $args['meta_value'] = $request->get_param( 'meta_value' );
455 $args['meta_compare'] = '!=';
456 }
457 return $args;
458 }
459 }
460