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

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

411 lines 12.6 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 }
64
65 /**
66 * Enqueue front end and editor JavaScript and CSS
67 */
68 public function enqueue_gutenberg_scripts() {
69 $blockPath = VISUALIZER_ABSURL . 'classes/Visualizer/Gutenberg/build/block.js';
70 $handsontableJS = VISUALIZER_ABSURL . 'classes/Visualizer/Gutenberg/build/handsontable.js';
71 $stylePath = VISUALIZER_ABSURL . 'classes/Visualizer/Gutenberg/build/block.css';
72 $handsontableCSS = VISUALIZER_ABSURL . 'classes/Visualizer/Gutenberg/build/handsontable.css';
73
74 if ( VISUALIZER_TEST_JS_CUSTOMIZATION ) {
75 $version = filemtime( VISUALIZER_ABSPATH . 'classes/Visualizer/Gutenberg/build/block.js' );
76 } else {
77 $version = $this->version;
78 }
79
80 // Enqueue the bundled block JS file
81 wp_enqueue_script( 'handsontable', $handsontableJS );
82 wp_enqueue_script( 'visualizer-gutenberg-block', $blockPath, array( 'wp-api', 'handsontable' ), $version, true );
83
84 $type = 'community';
85
86 if ( VISUALIZER_PRO ) {
87 $type = 'pro';
88 if ( apply_filters( 'visualizer_is_business', false ) ) {
89 $type = 'business';
90 }
91 }
92
93 $translation_array = array(
94 'isPro' => $type,
95 'proTeaser' => Visualizer_Plugin::PRO_TEASER_URL,
96 'absurl' => VISUALIZER_ABSURL,
97 );
98 wp_localize_script( 'visualizer-gutenberg-block', 'visualizerLocalize', $translation_array );
99
100 // Enqueue frontend and editor block styles
101 wp_enqueue_style( 'handsontable', $handsontableCSS );
102 wp_enqueue_style( 'visualizer-gutenberg-block', $stylePath, '', $version );
103 }
104 /**
105 * Hook server side rendering into render callback
106 */
107 public function register_block_type() {
108 register_block_type(
109 'visualizer/chart', array(
110 'render_callback' => array( $this, 'gutenberg_block_callback' ),
111 'attributes' => array(
112 'id' => array(
113 'type' => 'number',
114 ),
115 ),
116 )
117 );
118 }
119
120 /**
121 * Gutenberg Block Callback Function
122 */
123 public function gutenberg_block_callback( $attr ) {
124 $id = $attr['id'];
125 if ( empty( $id ) || $id === 'none' ) {
126 return ''; // no id = no fun
127 }
128 return '[visualizer id="' . $id . '"]';
129 }
130
131 /**
132 * Hook server side rendering into render callback
133 */
134 public function register_rest_endpoints() {
135 register_rest_field(
136 'visualizer',
137 'chart_data',
138 array(
139 'get_callback' => array( $this, 'get_visualizer_data' ),
140 )
141 );
142
143 register_rest_route(
144 'visualizer/v' . VISUALIZER_REST_VERSION,
145 '/update-chart',
146 array(
147 'methods' => 'POST',
148 'callback' => array( $this, 'update_chart_data' ),
149 'args' => array(
150 'id' => array(
151 'sanitize_callback' => 'absint',
152 ),
153 ),
154 )
155 );
156
157 register_rest_route(
158 'visualizer/v' . VISUALIZER_REST_VERSION,
159 '/upload-data',
160 array(
161 'methods' => 'POST',
162 'callback' => array( $this, 'upload_csv_data' ),
163 'args' => array(
164 'url' => array(
165 'sanitize_callback' => 'esc_url_raw',
166 ),
167 ),
168 )
169 );
170
171 register_rest_route(
172 'visualizer/v' . VISUALIZER_REST_VERSION,
173 '/get-permission-data',
174 array(
175 'methods' => 'GET',
176 'callback' => array( $this, 'get_permission_data' ),
177 'args' => array(
178 'type' => array(
179 'sanitize_callback' => 'sanitize_text_field',
180 ),
181 ),
182 )
183 );
184 }
185
186 /**
187 * Get Post Meta Fields
188 */
189 public function get_visualizer_data( $post ) {
190 $data = array();
191 $post_id = $post['id'];
192
193 $data['visualizer-chart-type'] = get_post_meta( $post_id, Visualizer_Plugin::CF_CHART_TYPE, true );
194
195 $data['visualizer-source'] = get_post_meta( $post_id, Visualizer_Plugin::CF_SOURCE, true );
196
197 $data['visualizer-default-data'] = get_post_meta( $post_id, Visualizer_Plugin::CF_DEFAULT_DATA, true );
198
199 // faetch and update settings
200 $data['visualizer-settings'] = get_post_meta( $post_id, Visualizer_Plugin::CF_SETTINGS, true );
201
202 // handle series filter hooks
203 $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'] );
204
205 // handle settings filter hooks
206 $data['visualizer-settings'] = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $data['visualizer-settings'], $post_id, $data['visualizer-chart-type'] );
207
208 // handle data filter hooks
209 $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'] );
210
211 $import = get_post_meta( $post_id, Visualizer_Plugin::CF_CHART_URL, true );
212
213 $schedule = get_post_meta( $post_id, Visualizer_Plugin::CF_CHART_SCHEDULE, true );
214
215 if ( ! empty( $import ) && ! empty( $schedule ) ) {
216 $data['visualizer-chart-url'] = $import;
217 $data['visualizer-chart-schedule'] = $schedule;
218 }
219
220 if ( VISUALIZER_PRO ) {
221 $permissions = get_post_meta( $post_id, Visualizer_PRO::CF_PERMISSIONS, true );
222
223 if ( ! empty( $permissions ) ) {
224 $data['visualizer-permissions'] = $permissions;
225 }
226 }
227
228 return $data;
229 }
230
231 /**
232 * Rest Callback Method
233 */
234 public function update_chart_data( $data ) {
235 if ( $data['id'] && ! is_wp_error( $data['id'] ) ) {
236
237 update_post_meta( $data['id'], Visualizer_Plugin::CF_CHART_TYPE, $data['visualizer-chart-type'] );
238 update_post_meta( $data['id'], Visualizer_Plugin::CF_SOURCE, $data['visualizer-source'] );
239 update_post_meta( $data['id'], Visualizer_Plugin::CF_DEFAULT_DATA, $data['visualizer-default-data'] );
240 update_post_meta( $data['id'], Visualizer_Plugin::CF_SERIES, $data['visualizer-series'] );
241 update_post_meta( $data['id'], Visualizer_Plugin::CF_SETTINGS, $data['visualizer-settings'] );
242
243 if ( $data['visualizer-chart-url'] && $data['visualizer-chart-schedule'] ) {
244 update_post_meta( $data['id'], Visualizer_Plugin::CF_CHART_URL, $data['visualizer-chart-url'] );
245 apply_filters( 'visualizer_pro_chart_schedule', $data['id'], $data['visualizer-chart-url'], $data['visualizer-chart-schedule'] );
246 } else {
247 delete_post_meta( $data['id'], Visualizer_Plugin::CF_CHART_URL );
248 apply_filters( 'visualizer_pro_remove_schedule', $data['id'] );
249 }
250
251 if ( VISUALIZER_PRO ) {
252 update_post_meta( $data['id'], Visualizer_PRO::CF_PERMISSIONS, $data['visualizer-permissions'] );
253 }
254
255 if ( $data['visualizer-chart-url'] ) {
256 $content['source'] = $data['visualizer-chart-url'];
257 $content['data'] = $this->format_chart_data( $data['visualizer-data'], $data['visualizer-series'] );
258 } else {
259 $content = $this->format_chart_data( $data['visualizer-data'], $data['visualizer-series'] );
260 }
261
262 $chart = array(
263 'ID' => $data['id'],
264 'post_content' => serialize( $content ),
265 );
266
267 wp_update_post( $chart );
268
269 $revisions = wp_get_post_revisions( $data['id'], array( 'order' => 'ASC' ) );
270
271 if ( count( $revisions ) > 1 ) {
272 $revision_ids = array_keys( $revisions );
273
274 // delete all revisions.
275 foreach ( $revision_ids as $id ) {
276 wp_delete_post_revision( $id );
277 }
278 }
279
280 return new \WP_REST_Response( array( 'success' => sprintf( 'Chart updated' ) ) );
281 }
282 }
283
284 /**
285 * Format chart data.
286 */
287 public function format_chart_data( $data, $series ) {
288 foreach ( $series as $i => $row ) {
289 // if no value exists for the seires, then add null
290 if ( ! isset( $series[ $i ] ) ) {
291 $series[ $i ] = null;
292 }
293
294 if ( is_null( $series[ $i ] ) ) {
295 continue;
296 }
297
298 if ( $row['type'] == 'number' ) {
299 foreach ( $data as $o => $col ) {
300 $data[ $o ][ $i ] = ( is_numeric( $col[ $i ] ) ) ? floatval( $col[ $i ] ) : ( is_numeric( str_replace( ',', '', $col[ $i ] ) ) ? floatval( str_replace( ',', '', $col[ $i ] ) ) : null );
301 }
302 }
303
304 if ( $row['type'] == 'boolean' ) {
305 foreach ( $data as $o => $col ) {
306 $data[ $o ][ $i ] = ! empty( $col[ $i ] ) ? filter_validate( $col[ $i ], FILTER_VALIDATE_BOOLEAN ) : null;
307 }
308 }
309
310 if ( $row['type'] == 'timeofday' ) {
311 foreach ( $data as $o => $col ) {
312 $date = new DateTime( '1984-03-16T' . $col[ $i ] );
313 if ( $date ) {
314 $data[ $o ][ $i ] = array(
315 intval( $date->format( 'H' ) ),
316 intval( $date->format( 'i' ) ),
317 intval( $date->format( 's' ) ),
318 0,
319 );
320 }
321 }
322 }
323
324 if ( $row['type'] == 'string' ) {
325 foreach ( $data as $o => $col ) {
326 $data[ $o ][ $i ] = $this->toUTF8( $col[ $i ] );
327 }
328 }
329 }
330
331 return $data;
332 }
333
334 /**
335 * Use toUTF8 function
336 */
337 public function toUTF8( $datum ) {
338 if ( ! function_exists( 'mb_detect_encoding' ) || mb_detect_encoding( $datum ) !== 'ASCII' ) {
339 $datum = \ForceUTF8\Encoding::toUTF8( $datum );
340 }
341 return $datum;
342 }
343
344 /**
345 * Handle remote CSV data
346 */
347 public function upload_csv_data( $data ) {
348 if ( $data['url'] && ! is_wp_error( $data['url'] ) && filter_var( $data['url'], FILTER_VALIDATE_URL ) ) {
349 $source = new Visualizer_Source_Csv_Remote( $data['url'] );
350 if ( $source->fetch() ) {
351 $temp = $source->getData();
352 if ( is_string( $temp ) && is_array( unserialize( $temp ) ) ) {
353 $content['series'] = $source->getSeries();
354 $content['data'] = $source->getRawData();
355 return $content;
356 } else {
357 return new \WP_REST_Response( array( 'failed' => sprintf( 'Invalid CSV URL' ) ) );
358 }
359 } else {
360 return new \WP_REST_Response( array( 'failed' => sprintf( 'Invalid CSV URL' ) ) );
361 }
362 } else {
363 return new \WP_REST_Response( array( 'failed' => sprintf( 'Invalid CSV URL' ) ) );
364 }
365 }
366
367 /**
368 * Get permission data
369 */
370 public function get_permission_data( $data ) {
371 $options = array();
372 switch ( $data['type'] ) {
373 case 'users':
374 $query = new WP_User_Query(
375 array(
376 'number' => 1000,
377 'orderby' => 'display_name',
378 'fields' => array( 'ID', 'display_name' ),
379 'count_total' => false,
380 )
381 );
382 $users = $query->get_results();
383 if ( ! empty( $users ) ) {
384 $i = 0;
385 foreach ( $users as $user ) {
386 $options[ $i ]['value'] = $user->ID;
387 $options[ $i ]['label'] = $user->display_name;
388 $i++;
389 }
390 }
391 break;
392 case 'roles':
393 if ( ! function_exists( 'get_editable_roles' ) ) {
394 require_once ABSPATH . 'wp-admin/includes/user.php';
395 }
396 $roles = get_editable_roles();
397 if ( ! empty( $roles ) ) {
398 $i = 0;
399 foreach ( get_editable_roles() as $name => $info ) {
400 $options[ $i ]['value'] = $name;
401 $options[ $i ]['label'] = $name;
402 $i++;
403 }
404 }
405 break;
406 }
407 return $options;
408 }
409
410 }
411