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

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

399 lines 12.9 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 * Frontend module class.
24 *
25 * @category Visualizer
26 * @package Module
27 *
28 * @since 1.0.0
29 */
30 class Visualizer_Module_Frontend extends Visualizer_Module {
31
32 const NAME = __CLASS__;
33
34 /**
35 * The array of charts to render.
36 *
37 * @since 1.0.0
38 *
39 * @access private
40 * @var array
41 */
42 private $_charts = array();
43
44 /**
45 * Constructor.
46 *
47 * @since 1.0.0
48 * @uses add_filter() To add "do_shortcode" hook for "widget_text" and "term_description" filters.
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->_addAction( 'wp_enqueue_scripts', 'enqueueScripts' );
57 $this->_addAction( 'visualizer_enqueue_scripts', 'enqueueScripts' );
58 $this->_addFilter( 'visualizer_get_language', 'getLanguage' );
59 $this->_addShortcode( 'visualizer', 'renderChart' );
60
61 // add do_shortocde hook for widget_text filter
62 if ( ! has_filter( 'widget_text', 'do_shortcode' ) ) {
63 add_filter( 'widget_text', 'do_shortcode' );
64 }
65
66 // add do_shortcode hook for term_description filter
67 if ( ! has_filter( 'term_description', 'do_shortcode' ) ) {
68 add_filter( 'term_description', 'do_shortcode' );
69 }
70
71 add_action( 'rest_api_init', array( $this, 'endpoint_register' ) );
72
73 $this->_addFilter( 'script_loader_tag', 'script_loader_tag', null, 10, 3 );
74 }
75
76 /**
77 * Adds the async attribute to certain scripts.
78 */
79 function script_loader_tag( $tag, $handle, $src ) {
80 if ( is_admin() ) {
81 return $tag;
82 }
83
84 $scripts = array( 'google-jsapi-new', 'google-jsapi-old', 'visualizer-render-google-lib', 'visualizer-render-google' );
85
86 foreach ( $scripts as $async ) {
87 if ( $async === $handle ) {
88 $tag = str_replace( ' src', ' defer="defer" src', $tag );
89 break;
90 }
91 }
92 return $tag;
93 }
94
95 /**
96 * Returns the language/locale.
97 */
98 function getLanguage( $dummy, $only_language ) {
99 return $this->get_language();
100 }
101
102
103 /**
104 * Registers the endpoints
105 */
106 function endpoint_register() {
107 register_rest_route(
108 'visualizer/v' . VISUALIZER_REST_VERSION,
109 '/action/(?P<chart>\d+)/(?P<type>.+)/',
110 array(
111 'methods' => array( 'GET', 'POST' ),
112 'callback' => array( $this, 'perform_action' ),
113 )
114 );
115 }
116
117 /**
118 * All possible actions and their labels
119 *
120 * @access private
121 */
122 private function get_actions() {
123 return apply_filters(
124 'visualizer_action_buttons',
125 array(
126 'print' => __( 'Print', 'visualizer' ),
127 'csv' => __( 'CSV', 'visualizer' ),
128 'xls' => __( 'Excel', 'visualizer' ),
129 'copy' => __( 'Copy', 'visualizer' ),
130 )
131 );
132 }
133
134 /**
135 * The print button
136 *
137 * @since 1.0.0
138 *
139 * @access public
140 */
141 public function perform_action( WP_REST_Request $params ) {
142 $chart_id = filter_var( sanitize_text_field( $params['chart'] ), FILTER_VALIDATE_INT );
143 $type = sanitize_text_field( $params['type'] );
144 $data = null;
145
146 if ( ! $chart_id ) {
147 return new WP_REST_Response( array( 'error' => new WP_Error( __( 'Invalid chart ID', 'visualizer' ) ) ) );
148 }
149
150 if ( ! $type ) {
151 return new WP_REST_Response( array( 'error' => new WP_Error( __( 'Invalid action', 'visualizer' ) ) ) );
152 }
153
154 switch ( $type ) {
155 case 'print':
156 $data = $this->_getDataAs( $chart_id, 'print' );
157 break;
158 case 'csv':
159 $data = $this->_getDataAs( $chart_id, 'csv' );
160 break;
161 case 'xls':
162 $data = $this->_getDataAs( $chart_id, 'xls' );
163 break;
164 default:
165 $data = apply_filters( 'visualizer_action_data', $data, $chart_id, $type, $params, $this );
166 break;
167 }
168
169 return new WP_REST_Response( array( 'data' => $data ) );
170 }
171
172 /**
173 * Registers scripts for charts rendering.
174 *
175 * @since 1.0.0
176 * @uses wp_register_script To register javascript file.
177 *
178 * @access public
179 */
180 public function enqueueScripts() {
181 wp_register_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
182 wp_register_script( 'visualizer-clipboardjs', VISUALIZER_ABSURL . 'js/lib/clipboardjs/clipboard.min.js', array( 'jquery' ), Visualizer_Plugin::VERSION, true );
183 wp_register_style( 'visualizer-front', VISUALIZER_ABSURL . 'css/front.css', array(), Visualizer_Plugin::VERSION );
184 do_action( 'visualizer_pro_frontend_load_resources' );
185 }
186
187 /**
188 * Returns placeholder for chart according to visualizer shortcode attributes.
189 *
190 * @since 1.0.0
191 * @uses shortcode_atts() To parse income shortocdes.
192 * @uses apply_filters() To filter chart's data and series arrays.
193 * @uses get_post_meta() To fetch chart's meta information.
194 * @uses wp_enqueue_script() To enqueue charts render script.
195 * @uses wp_localize_script() To add chart data to the page inline script.
196 *
197 * @access public
198 * @param array $atts The array of shortcode attributes.
199 */
200 public function renderChart( $atts ) {
201 global $wp_version;
202 $atts = shortcode_atts(
203 array(
204 'id' => false, // chart id
205 'class' => false, // chart class
206 'series' => false, // series filter hook
207 'data' => false, // data filter hook
208 'settings' => false, // data filter hook
209 ),
210 $atts
211 );
212
213 // if empty id or chart does not exists, then return empty string
214 if ( ! $atts['id'] || ! ( $chart = get_post( $atts['id'] ) ) || $chart->post_type !== Visualizer_Plugin::CPT_VISUALIZER ) {
215 return '';
216 }
217
218 if ( ! apply_filters( 'visualizer_pro_show_chart', true, $atts['id'] ) ) {
219 return '';
220 }
221
222 // in case revisions exist.
223 // phpcs:ignore WordPress.CodeAnalysis.AssignmentInCondition.Found
224 if ( true === ( $revisions = $this->undoRevisions( $chart->ID, true ) ) ) {
225 $chart = get_post( $chart->ID );
226 }
227
228 $id = 'visualizer-' . $atts['id'];
229 $defaultClass = 'visualizer-front';
230 $class = apply_filters( Visualizer_Plugin::FILTER_CHART_WRAPPER_CLASS, $atts['class'], $atts['id'] );
231 $class = $defaultClass . ' ' . $class . ' ' . 'visualizer-front-' . $atts['id'];
232 $class = ! empty( $class ) ? ' class="' . trim( $class ) . '"' : '';
233
234 $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
235
236 $chart = apply_filters( 'visualizer_schedule_refresh_chart', $chart, $chart->ID, false );
237
238 // fetch and update settings
239 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
240 if ( empty( $settings['height'] ) ) {
241 $settings['height'] = '400';
242 }
243
244 // handle series filter hooks
245 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
246 if ( ! empty( $atts['series'] ) ) {
247 $series = apply_filters( $atts['series'], $series, $chart->ID, $type );
248 }
249 // handle settings filter hooks
250 $settings = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $settings, $chart->ID, $type );
251 if ( ! empty( $atts['settings'] ) ) {
252 $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
253 }
254
255 // handle data filter hooks
256 $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( $chart->post_content ) ), $chart->ID, $type );
257 if ( ! empty( $atts['data'] ) ) {
258 $data = apply_filters( $atts['data'], $data, $chart->ID, $type );
259 }
260
261 $css = '';
262 $arguments = $this->get_inline_custom_css( $id, $settings );
263 if ( ! empty( $arguments ) ) {
264 $css = $arguments[0];
265 $settings = $arguments[1];
266 }
267
268 $library = $this->load_chart_type( $chart->ID );
269
270 $id = $id . '-' . rand();
271
272 $amp = Visualizer_Plugin::instance()->getModule( Visualizer_Module_AMP::NAME );
273 if ( $amp && $amp->is_amp() ) {
274 return '<div id="' . $id . '"' . $class . '>' . $amp->get_chart( $chart, $data, $series, $settings ) . '</div>';
275 }
276
277 // add chart to the array
278 $this->_charts[ $id ] = array(
279 'type' => $type,
280 'series' => $series,
281 'settings' => $settings,
282 'data' => $data,
283 'library' => $library,
284 );
285
286 $actions_div = '';
287 $actions_visible = apply_filters( 'visualizer_pro_add_actions', isset( $settings['actions'] ) ? $settings['actions'] : array(), $atts['id'] );
288 if ( ! empty( $actions_visible ) ) {
289 $actions = $this->get_actions();
290 $actions_div = '<div class="visualizer-actions">';
291 foreach ( $actions_visible as $action_type ) {
292 $key = $action_type;
293 $mime = '';
294 if ( strpos( $action_type, ';' ) !== false ) {
295 $array = explode( ';', $action_type );
296 $key = $array[0];
297 $mime = end( $array );
298 }
299 $label = $actions[ $key ];
300 $actions_div .= '<a href="#" class="visualizer-action visualizer-action-' . $key . '" data-visualizer-type="' . $key . '" data-visualizer-chart-id="' . $atts['id'] . '" data-visualizer-container-id="' . $id . '" data-visualizer-mime="' . $mime . '" title="' . $label . '" ';
301
302 if ( 'copy' === $key ) {
303 $copy = $this->_getDataAs( $atts['id'], 'csv' );
304 $actions_div .= ' data-clipboard-text="' . esc_attr( $copy['csv'] ) . '"';
305 wp_enqueue_script( 'visualizer-clipboardjs' );
306 }
307
308 $actions_div .= apply_filters( 'visualizer_action_attributes', '', $key, $atts['id'] );
309 $actions_div .= '>' . $label . '</a> &nbsp;';
310 }
311
312 $actions_div .= '</div>';
313 }
314
315 $actions_div .= $css;
316
317 foreach ( $this->_charts as $id => $attributes ) {
318 $library = $attributes['library'];
319 wp_register_script(
320 "visualizer-render-$library",
321 VISUALIZER_ABSURL . 'js/render-facade.js',
322 apply_filters( 'visualizer_assets_render', array( 'jquery', 'visualizer-customization' ), true ),
323 Visualizer_Plugin::VERSION,
324 true
325 );
326
327 wp_enqueue_script( "visualizer-render-$library" );
328 wp_localize_script(
329 "visualizer-render-$library",
330 'visualizer',
331 array(
332 'charts' => $this->_charts,
333 'language' => $this->get_language(),
334 'map_api_key' => get_option( 'visualizer-map-api-key' ),
335 'rest_url' => version_compare( $wp_version, '4.7.0', '>=' ) ? rest_url( 'visualizer/v' . VISUALIZER_REST_VERSION . '/action/#id#/#type#/' ) : '',
336 'i10n' => array(
337 'copied' => __( 'Copied!', 'visualizer' ),
338 ),
339 'page_type' => 'frontend',
340 'is_front' => true,
341 )
342 );
343 wp_enqueue_style( 'visualizer-front' );
344 }
345
346 // return placeholder div
347 return $actions_div . '<div id="' . $id . '"' . $class . '></div>' . $this->addSchema( $chart->ID );
348 }
349
350 /**
351 * Adds the schema corresponding to the dataset.
352 *
353 * @since 3.3.2
354 *
355 * @access private
356 */
357 private function addSchema( $id ) {
358 $settings = get_post_meta( $id, Visualizer_Plugin::CF_SETTINGS, true );
359 $title = '';
360 if ( isset( $settings['title'] ) && ! empty( $settings['title'] ) ) {
361 $title = $settings['title'];
362 if ( is_array( $title ) ) {
363 $title = $settings['title']['text'];
364 }
365 }
366 $title = apply_filters( 'visualizer_schema_name', $title, $id );
367 if ( empty( $title ) ) {
368 return '';
369 }
370
371 $desc = '';
372 if ( isset( $settings['description'] ) && ! empty( $settings['description'] ) ) {
373 $desc = $settings['description'];
374 }
375 $desc = apply_filters( 'visualizer_schema_description', $desc, $id );
376 // descriptions below 50 chars are not allowed.
377 if ( empty( $desc ) || strlen( $desc ) < 50 ) {
378 return '';
379 }
380
381 $schema = apply_filters(
382 'visualizer_schema',
383 '{
384 "@context":"https://schema.org/",
385 "@type":"Dataset",
386 "name":"' . esc_html( $title ) . '",
387 "description":"' . esc_html( $desc ) . '"
388 }',
389 $id
390 );
391
392 if ( empty( $schema ) ) {
393 return '';
394 }
395
396 return '<script type="application/ld+json">' . $schema . '</script>';
397 }
398 }
399