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

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

445 lines 13.7 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 = 'developer';
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 )
160 );
161
162 register_rest_route(
163 'visualizer/v' . VISUALIZER_REST_VERSION,
164 '/upload-data',
165 array(
166 'methods' => 'POST',
167 'callback' => array( $this, 'upload_csv_data' ),
168 'args' => array(
169 'url' => array(
170 'sanitize_callback' => 'esc_url_raw',
171 ),
172 ),
173 )
174 );
175
176 register_rest_route(
177 'visualizer/v' . VISUALIZER_REST_VERSION,
178 '/get-permission-data',
179 array(
180 'methods' => 'GET',
181 'callback' => array( $this, 'get_permission_data' ),
182 'args' => array(
183 'type' => array(
184 'sanitize_callback' => 'sanitize_text_field',
185 ),
186 ),
187 )
188 );
189 }
190
191 /**
192 * Get Post Meta Fields
193 */
194 public function get_visualizer_data( $post ) {
195 if ( ! current_user_can( 'edit_posts' ) ) {
196 return false;
197 }
198
199 $data = array();
200 $post_id = $post['id'];
201
202 $data['visualizer-chart-type'] = get_post_meta( $post_id, Visualizer_Plugin::CF_CHART_TYPE, true );
203
204 $data['visualizer-chart-library'] = get_post_meta( $post_id, Visualizer_Plugin::CF_CHART_LIBRARY, true );
205
206 $data['visualizer-source'] = get_post_meta( $post_id, Visualizer_Plugin::CF_SOURCE, true );
207
208 $data['visualizer-default-data'] = get_post_meta( $post_id, Visualizer_Plugin::CF_DEFAULT_DATA, true );
209
210 // faetch and update settings
211 $data['visualizer-settings'] = get_post_meta( $post_id, Visualizer_Plugin::CF_SETTINGS, true );
212
213 // handle series filter hooks
214 $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'] );
215
216 // handle settings filter hooks
217 $data['visualizer-settings'] = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $data['visualizer-settings'], $post_id, $data['visualizer-chart-type'] );
218
219 // handle data filter hooks
220 $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'] );
221
222 $import = get_post_meta( $post_id, Visualizer_Plugin::CF_CHART_URL, true );
223
224 $schedule = get_post_meta( $post_id, Visualizer_Plugin::CF_CHART_SCHEDULE, true );
225
226 if ( ! empty( $import ) && ! empty( $schedule ) ) {
227 $data['visualizer-chart-url'] = $import;
228 $data['visualizer-chart-schedule'] = $schedule;
229 }
230
231 if ( Visualizer_Module::is_pro() ) {
232 $permissions = get_post_meta( $post_id, Visualizer_PRO::CF_PERMISSIONS, true );
233
234 if ( ! empty( $permissions ) ) {
235 $data['visualizer-permissions'] = $permissions;
236 }
237 }
238
239 return $data;
240 }
241
242 /**
243 * Rest Callback Method
244 */
245 public function update_chart_data( $data ) {
246 if ( ! current_user_can( 'edit_posts' ) ) {
247 return false;
248 }
249
250 if ( $data['id'] && ! is_wp_error( $data['id'] ) ) {
251
252 update_post_meta( $data['id'], Visualizer_Plugin::CF_CHART_TYPE, $data['visualizer-chart-type'] );
253 update_post_meta( $data['id'], Visualizer_Plugin::CF_SOURCE, $data['visualizer-source'] );
254 update_post_meta( $data['id'], Visualizer_Plugin::CF_DEFAULT_DATA, $data['visualizer-default-data'] );
255 update_post_meta( $data['id'], Visualizer_Plugin::CF_SERIES, $data['visualizer-series'] );
256 update_post_meta( $data['id'], Visualizer_Plugin::CF_SETTINGS, $data['visualizer-settings'] );
257
258 if ( $data['visualizer-chart-url'] && $data['visualizer-chart-schedule'] ) {
259 update_post_meta( $data['id'], Visualizer_Plugin::CF_CHART_URL, $data['visualizer-chart-url'] );
260 apply_filters( 'visualizer_pro_chart_schedule', $data['id'], $data['visualizer-chart-url'], $data['visualizer-chart-schedule'] );
261 } else {
262 delete_post_meta( $data['id'], Visualizer_Plugin::CF_CHART_URL );
263 apply_filters( 'visualizer_pro_remove_schedule', $data['id'] );
264 }
265
266 if ( Visualizer_Module::is_pro() ) {
267 update_post_meta( $data['id'], Visualizer_PRO::CF_PERMISSIONS, $data['visualizer-permissions'] );
268 }
269
270 if ( $data['visualizer-chart-url'] ) {
271 $content['source'] = $data['visualizer-chart-url'];
272 $content['data'] = $this->format_chart_data( $data['visualizer-data'], $data['visualizer-series'] );
273 } else {
274 $content = $this->format_chart_data( $data['visualizer-data'], $data['visualizer-series'] );
275 }
276
277 $chart = array(
278 'ID' => $data['id'],
279 'post_content' => serialize( $content ),
280 );
281
282 wp_update_post( $chart );
283
284 $revisions = wp_get_post_revisions( $data['id'], array( 'order' => 'ASC' ) );
285
286 if ( count( $revisions ) > 1 ) {
287 $revision_ids = array_keys( $revisions );
288
289 // delete all revisions.
290 foreach ( $revision_ids as $id ) {
291 wp_delete_post_revision( $id );
292 }
293 }
294
295 return new \WP_REST_Response( array( 'success' => sprintf( 'Chart updated' ) ) );
296 }
297 }
298
299 /**
300 * Format chart data.
301 */
302 public function format_chart_data( $data, $series ) {
303 foreach ( $series as $i => $row ) {
304 // if no value exists for the seires, then add null
305 if ( ! isset( $series[ $i ] ) ) {
306 $series[ $i ] = null;
307 }
308
309 if ( is_null( $series[ $i ] ) ) {
310 continue;
311 }
312
313 if ( $row['type'] === 'number' ) {
314 foreach ( $data as $o => $col ) {
315 $data[ $o ][ $i ] = ( is_numeric( $col[ $i ] ) ) ? floatval( $col[ $i ] ) : ( is_numeric( str_replace( ',', '', $col[ $i ] ) ) ? floatval( str_replace( ',', '', $col[ $i ] ) ) : null );
316 }
317 }
318
319 if ( $row['type'] === 'boolean' ) {
320 foreach ( $data as $o => $col ) {
321 $data[ $o ][ $i ] = ! empty( $col[ $i ] ) ? filter_validate( $col[ $i ], FILTER_VALIDATE_BOOLEAN ) : null;
322 }
323 }
324
325 if ( $row['type'] === 'timeofday' ) {
326 foreach ( $data as $o => $col ) {
327 $date = new DateTime( '1984-03-16T' . $col[ $i ] );
328 if ( $date ) {
329 $data[ $o ][ $i ] = array(
330 intval( $date->format( 'H' ) ),
331 intval( $date->format( 'i' ) ),
332 intval( $date->format( 's' ) ),
333 0,
334 );
335 }
336 }
337 }
338
339 if ( $row['type'] === 'string' ) {
340 foreach ( $data as $o => $col ) {
341 $data[ $o ][ $i ] = $this->toUTF8( $col[ $i ] );
342 }
343 }
344 }
345
346 return $data;
347 }
348
349 /**
350 * Use toUTF8 function
351 */
352 public function toUTF8( $datum ) {
353 if ( ! function_exists( 'mb_detect_encoding' ) || mb_detect_encoding( $datum ) !== 'ASCII' ) {
354 $datum = \ForceUTF8\Encoding::toUTF8( $datum );
355 }
356 return $datum;
357 }
358
359 /**
360 * Handle remote CSV data
361 */
362 public function upload_csv_data( $data ) {
363 if ( ! current_user_can( 'edit_posts' ) ) {
364 return false;
365 }
366
367 if ( $data['url'] && ! is_wp_error( $data['url'] ) && filter_var( $data['url'], FILTER_VALIDATE_URL ) ) {
368 $source = new Visualizer_Source_Csv_Remote( $data['url'] );
369 if ( $source->fetch() ) {
370 $temp = $source->getData();
371 if ( is_string( $temp ) && is_array( unserialize( $temp ) ) ) {
372 $content['series'] = $source->getSeries();
373 $content['data'] = $source->getRawData();
374 return $content;
375 } else {
376 return new \WP_REST_Response( array( 'failed' => sprintf( 'Invalid CSV URL' ) ) );
377 }
378 } else {
379 return new \WP_REST_Response( array( 'failed' => sprintf( 'Invalid CSV URL' ) ) );
380 }
381 } else {
382 return new \WP_REST_Response( array( 'failed' => sprintf( 'Invalid CSV URL' ) ) );
383 }
384 }
385
386 /**
387 * Get permission data
388 */
389 public function get_permission_data( $data ) {
390 if ( ! current_user_can( 'edit_posts' ) ) {
391 return false;
392 }
393
394 $options = array();
395 switch ( $data['type'] ) {
396 case 'users':
397 $query = new WP_User_Query(
398 array(
399 'number' => 1000,
400 'orderby' => 'display_name',
401 'fields' => array( 'ID', 'display_name' ),
402 'count_total' => false,
403 )
404 );
405 $users = $query->get_results();
406 if ( ! empty( $users ) ) {
407 $i = 0;
408 foreach ( $users as $user ) {
409 $options[ $i ]['value'] = $user->ID;
410 $options[ $i ]['label'] = $user->display_name;
411 $i++;
412 }
413 }
414 break;
415 case 'roles':
416 if ( ! function_exists( 'get_editable_roles' ) ) {
417 require_once ABSPATH . 'wp-admin/includes/user.php';
418 }
419 $roles = get_editable_roles();
420 if ( ! empty( $roles ) ) {
421 $i = 0;
422 foreach ( get_editable_roles() as $name => $info ) {
423 $options[ $i ]['value'] = $name;
424 $options[ $i ]['label'] = $name;
425 $i++;
426 }
427 }
428 break;
429 }
430 return $options;
431 }
432
433 /**
434 * Filter Rest Query
435 */
436 public function add_rest_query_vars( $args, \WP_REST_Request $request ) {
437 if ( isset( $request['meta_key'] ) && isset( $request['meta_value'] ) ) {
438 $args['meta_key'] = $request->get_param( 'meta_key' );
439 $args['meta_value'] = $request->get_param( 'meta_value' );
440 $args['meta_compare'] = '!=';
441 }
442 return $args;
443 }
444 }
445