PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.4.4
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.4.4
4.0.8 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 All 149 releases
← All changes | classes/Visualizer/Module/Frontend.php +206 -35 3.0.63.4.4 View file →
@@ -53,8 +53,10 @@
53 53 public function __construct( Visualizer_Plugin $plugin ) {
54 54 parent::__construct( $plugin );
55 55
56 56 $this->_addAction( 'wp_enqueue_scripts', 'enqueueScripts' );
57 + $this->_addAction( 'visualizer_enqueue_scripts', 'enqueueScripts' );
58 + $this->_addFilter( 'visualizer_get_language', 'getLanguage' );
57 59 $this->_addShortcode( 'visualizer', 'renderChart' );
58 60
59 61 // add do_shortocde hook for widget_text filter
60 62 if ( ! has_filter( 'widget_text', 'do_shortcode' ) ) {
@@ -66,11 +68,40 @@
66 68 add_filter( 'term_description', 'do_shortcode' );
67 69 }
68 70
69 71 add_action( 'rest_api_init', array( $this, 'endpoint_register' ) );
72 +
73 + $this->_addFilter( 'script_loader_tag', 'script_loader_tag', null, 10, 3 );
70 74 }
71 75
72 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 + /**
73 104 * Registers the endpoints
74 105 */
75 106 function endpoint_register() {
76 107 register_rest_route(
@@ -88,16 +119,42 @@
88 119 *
89 120 * @access private
90 121 */
91 122 private function get_actions() {
92 - return apply_filters(
93 - 'visualizer_action_buttons', array(
94 - 'print' => __( 'Print', 'visualizer' ),
95 - 'csv' => __( 'CSV', 'visualizer' ),
96 - 'xls' => __( 'Excel', 'visualizer' ),
97 - 'copy' => __( 'Copy', 'visualizer' ),
123 + $actions = apply_filters(
124 + 'visualizer_action_buttons',
125 + array(
126 + 'print' => array(
127 + 'label' => esc_html__( 'Print', 'visualizer' ),
128 + 'title' => esc_html__( 'Print Chart', 'visualizer' ),
129 + ),
130 + 'csv' => array(
131 + 'label' => esc_html__( 'CSV', 'visualizer' ),
132 + 'title' => esc_html__( 'Download as a CSV', 'visualizer' ),
133 + ),
134 + 'xls' => array(
135 + 'label' => esc_html__( 'Excel', 'visualizer' ),
136 + 'title' => esc_html__( 'Download as a spreadsheet', 'visualizer' ),
137 + ),
138 + 'copy' => array(
139 + 'label' => esc_html__( 'Copy', 'visualizer' ),
140 + 'title' => esc_html__( 'Copy data', 'visualizer' ),
141 + ),
142 + 'image' => array(
143 + 'label' => esc_html__( 'Download', 'visualizer' ),
144 + 'title' => esc_html__( 'Download as an image', 'visualizer' ),
145 + ),
98 146 )
99 147 );
148 +
149 + // backward compatibility before label and title attributes were introduced.
150 + if ( isset( $actions['edit'] ) && is_string( $actions['edit'] ) ) {
151 + $actions['edit'] = array(
152 + 'label' => esc_html__( 'Edit', 'visualizer' ),
153 + 'title' => esc_html__( 'Edit data', 'visualizer' ),
154 + );
155 + }
156 + return $actions;
100 157 }
101 158
102 159 /**
103 160 * The print button
@@ -128,8 +185,23 @@
128 185 break;
129 186 case 'xls':
130 187 $data = $this->_getDataAs( $chart_id, 'xls' );
131 188 break;
189 + case 'image':
190 + $settings = get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true );
191 + $title = 'visualizer#' . $chart_id;
192 + if ( ! empty( $settings['title'] ) ) {
193 + $title = $settings['title'];
194 + }
195 + // for ChartJS, title is an array.
196 + if ( is_array( $title ) && isset( $title['text'] ) ) {
197 + $title = $title['text'];
198 + }
199 + if ( empty( $title ) ) {
200 + $title = 'visualizer#' . $chart_id;
201 + }
202 + $data = array( 'name' => $title );
203 + break;
132 204 default:
133 205 $data = apply_filters( 'visualizer_action_data', $data, $chart_id, $type, $params, $this );
134 206 break;
135 207 }
@@ -145,13 +217,10 @@
145 217 *
146 218 * @access public
147 219 */
148 220 public function enqueueScripts() {
149 - wp_register_script( 'visualizer-google-jsapi-new', '//www.gstatic.com/charts/loader.js', array(), null, true );
150 - wp_register_script( 'visualizer-google-jsapi-old', '//www.google.com/jsapi', array( 'visualizer-google-jsapi-new' ), null, true );
151 - wp_register_script( 'visualizer-render', VISUALIZER_ABSURL . 'js/render.js', array( 'visualizer-google-jsapi-old', 'jquery' ), Visualizer_Plugin::VERSION, true );
221 + wp_register_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
152 222 wp_register_script( 'visualizer-clipboardjs', VISUALIZER_ABSURL . 'js/lib/clipboardjs/clipboard.min.js', array( 'jquery' ), Visualizer_Plugin::VERSION, true );
153 - wp_enqueue_script( 'visualizer-clipboardjs' );
154 223 wp_register_style( 'visualizer-front', VISUALIZER_ABSURL . 'css/front.css', array(), Visualizer_Plugin::VERSION );
155 224 do_action( 'visualizer_pro_frontend_load_resources' );
156 225 }
157 226
@@ -176,13 +245,14 @@
176 245 'class' => false, // chart class
177 246 'series' => false, // series filter hook
178 247 'data' => false, // data filter hook
179 248 'settings' => false, // data filter hook
180 - ), $atts
249 + ),
250 + $atts
181 251 );
182 252
183 253 // if empty id or chart does not exists, then return empty string
184 - if ( ! $atts['id'] || ! ( $chart = get_post( $atts['id'] ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
254 + if ( ! $atts['id'] || ! ( $chart = get_post( $atts['id'] ) ) || $chart->post_type !== Visualizer_Plugin::CPT_VISUALIZER ) {
185 255 return '';
186 256 }
187 257
188 258 if ( ! apply_filters( 'visualizer_pro_show_chart', true, $atts['id'] ) ) {
@@ -188,8 +258,14 @@
188 258 if ( ! apply_filters( 'visualizer_pro_show_chart', true, $atts['id'] ) ) {
189 259 return '';
190 260 }
191 261
262 + // in case revisions exist.
263 + // phpcs:ignore WordPress.CodeAnalysis.AssignmentInCondition.Found
264 + if ( true === ( $revisions = $this->undoRevisions( $chart->ID, true ) ) ) {
265 + $chart = get_post( $chart->ID );
266 + }
267 +
192 268 $id = 'visualizer-' . $atts['id'];
193 269 $defaultClass = 'visualizer-front';
194 270 $class = apply_filters( Visualizer_Plugin::FILTER_CHART_WRAPPER_CLASS, $atts['class'], $atts['id'] );
195 271 $class = $defaultClass . ' ' . $class . ' ' . 'visualizer-front-' . $atts['id'];
@@ -196,9 +272,11 @@
196 272 $class = ! empty( $class ) ? ' class="' . trim( $class ) . '"' : '';
197 273
198 274 $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
199 275
200 - // faetch and update settings
276 + $chart = apply_filters( 'visualizer_schedule_refresh_chart', $chart, $chart->ID, false );
277 +
278 + // fetch and update settings
201 279 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
202 280 if ( empty( $settings['height'] ) ) {
203 281 $settings['height'] = '400';
204 282 }
@@ -214,19 +292,29 @@
214 292 $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
215 293 }
216 294
217 295 // handle data filter hooks
218 - $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( $chart->post_content ), $chart->ID, $type );
296 + $data = self::get_chart_data( $chart, $type );
219 297 if ( ! empty( $atts['data'] ) ) {
220 298 $data = apply_filters( $atts['data'], $data, $chart->ID, $type );
221 299 }
222 300
301 + $css = '';
302 + $arguments = $this->get_inline_custom_css( $id, $settings );
303 + if ( ! empty( $arguments ) ) {
304 + $css = $arguments[0];
305 + $settings = $arguments[1];
306 + }
307 +
308 + $library = $this->load_chart_type( $chart->ID );
309 +
223 310 $id = $id . '-' . rand();
224 - $arguments = array( '', $id, $settings );
225 - apply_filters_ref_array( 'visualizer_pro_inline_css', array( &$arguments ) );
226 - $css = $arguments[0];
227 - $settings = $arguments[2];
228 311
312 + $amp = Visualizer_Plugin::instance()->getModule( Visualizer_Module_AMP::NAME );
313 + if ( $amp && $amp->is_amp() ) {
314 + return '<div id="' . $id . '"' . $class . '>' . $amp->get_chart( $chart, $data, $series, $settings ) . '</div>';
315 + }
316 +
229 317 // add chart to the array
230 318 $this->_charts[ $id ] = array(
231 319 'type' => $type,
232 320 'series' => $series,
@@ -231,24 +319,11 @@
231 319 'type' => $type,
232 320 'series' => $series,
233 321 'settings' => $settings,
234 322 'data' => $data,
323 + 'library' => $library,
235 324 );
236 325
237 - // enqueue visualizer render and update render localizations
238 - wp_enqueue_script( 'visualizer-render' );
239 - wp_localize_script(
240 - 'visualizer-render', 'visualizer', array(
241 - 'charts' => $this->_charts,
242 - 'map_api_key' => get_option( 'visualizer-map-api-key' ),
243 - 'rest_url' => version_compare( $wp_version, '4.7.0', '>=' ) ? rest_url( 'visualizer/v' . VISUALIZER_REST_VERSION . '/action/#id#/#type#/' ) : '',
244 - 'i10n' => array(
245 - 'copied' => __( 'Copied!', 'visualizer' ),
246 - ),
247 - )
248 - );
249 - wp_enqueue_style( 'visualizer-front' );
250 -
251 326 $actions_div = '';
252 327 $actions_visible = apply_filters( 'visualizer_pro_add_actions', isset( $settings['actions'] ) ? $settings['actions'] : array(), $atts['id'] );
253 328 if ( ! empty( $actions_visible ) ) {
254 329 $actions = $this->get_actions();
@@ -260,14 +335,16 @@
260 335 $array = explode( ';', $action_type );
261 336 $key = $array[0];
262 337 $mime = end( $array );
263 338 }
264 - $label = $actions[ $key ];
265 - $actions_div .= '<a href="#" class="visualizer-action visualizer-action-' . $key . '" data-visualizer-type="' . $key . '" data-visualizer-chart-id="' . $atts['id'] . '" data-visualizer-mime="' . $mime . '" title="' . $label . '" ';
339 + $label = $actions[ $key ]['label'];
340 + $title = $actions[ $key ]['title'];
341 + $actions_div .= sprintf( '<a href="#" class="visualizer-action visualizer-action-%s" data-visualizer-type="%s" data-visualizer-chart-id="%s" data-visualizer-container-id="%s" data-visualizer-mime="%s" title="%s"', $key, $key, $atts['id'], $id, $mime, $title );
266 342
267 343 if ( 'copy' === $key ) {
268 344 $copy = $this->_getDataAs( $atts['id'], 'csv' );
269 345 $actions_div .= ' data-clipboard-text="' . esc_attr( $copy['csv'] ) . '"';
346 + wp_enqueue_script( 'visualizer-clipboardjs' );
270 347 }
271 348
272 349 $actions_div .= apply_filters( 'visualizer_action_attributes', '', $key, $atts['id'] );
273 350 $actions_div .= '>' . $label . '</a> &nbsp;';
@@ -277,8 +354,102 @@
277 354 }
278 355
279 356 $actions_div .= $css;
280 357
358 + foreach ( $this->_charts as $id => $attributes ) {
359 + $library = $attributes['library'];
360 + wp_register_script(
361 + "visualizer-render-$library",
362 + VISUALIZER_ABSURL . 'js/render-facade.js',
363 + apply_filters( 'visualizer_assets_render', array( 'jquery', 'visualizer-customization' ), true ),
364 + Visualizer_Plugin::VERSION,
365 + true
366 + );
367 +
368 + wp_enqueue_script( "visualizer-render-$library" );
369 + wp_localize_script(
370 + "visualizer-render-$library",
371 + 'visualizer',
372 + array(
373 + 'charts' => $this->_charts,
374 + 'language' => $this->get_language(),
375 + 'map_api_key' => get_option( 'visualizer-map-api-key' ),
376 + 'rest_url' => version_compare( $wp_version, '4.7.0', '>=' ) ? rest_url( 'visualizer/v' . VISUALIZER_REST_VERSION . '/action/#id#/#type#/' ) : '',
377 + 'i10n' => array(
378 + 'copied' => __( 'The data has been copied to your clipboard. Hit Ctrl-V/Cmd-V in your spreadsheet editor to paste the data.', 'visualizer' ),
379 + ),
380 + 'page_type' => 'frontend',
381 + 'is_front' => true,
382 + )
383 + );
384 + wp_enqueue_style( 'visualizer-front' );
385 + }
386 +
281 387 // return placeholder div
282 - return $actions_div . '<div id="' . $id . '"' . $class . '></div>';
388 + return $actions_div . '<div id="' . $id . '"' . $class . '></div>' . $this->addSchema( $chart->ID );
389 + }
390 +
391 + /**
392 + * Adds the schema corresponding to the dataset.
393 + *
394 + * @since 3.3.2
395 + *
396 + * @access private
397 + */
398 + private function addSchema( $id ) {
399 + // should we show informative errors as HTML comments?
400 + $show_errors = apply_filters( 'visualizer_schema_show_errors', true, $id );
401 +
402 + $settings = get_post_meta( $id, Visualizer_Plugin::CF_SETTINGS, true );
403 + $title = '';
404 + if ( isset( $settings['title'] ) && ! empty( $settings['title'] ) ) {
405 + $title = $settings['title'];
406 + if ( is_array( $title ) ) {
407 + $title = $settings['title']['text'];
408 + }
409 + }
410 + $title = apply_filters( 'visualizer_schema_name', $title, $id );
411 + if ( empty( $title ) ) {
412 + if ( $show_errors ) {
413 + return "<!-- Not showing structured data for chart $id because title is empty -->";
414 + }
415 + return '';
416 + }
417 +
418 + $desc = '';
419 + if ( isset( $settings['description'] ) && ! empty( $settings['description'] ) ) {
420 + $desc = $settings['description'];
421 + }
422 + $desc = apply_filters( 'visualizer_schema_description', $desc, $id );
423 + if ( empty( $desc ) ) {
424 + if ( $show_errors ) {
425 + return "<!-- Not showing structured data for chart $id because description is empty -->";
426 + }
427 + return '';
428 + }
429 +
430 + // descriptions below 50 chars are not allowed.
431 + if ( strlen( $desc ) < 50 ) {
432 + if ( $show_errors ) {
433 + return "<!-- Not showing structured data for chart $id because description is shorter than 50 characters -->";
434 + }
435 + return '';
436 + }
437 +
438 + $schema = apply_filters(
439 + 'visualizer_schema',
440 + '{
441 + "@context":"https://schema.org/",
442 + "@type":"Dataset",
443 + "name":"' . esc_html( $title ) . '",
444 + "description":"' . esc_html( $desc ) . '"
445 + }',
446 + $id
447 + );
448 +
449 + if ( empty( $schema ) ) {
450 + return '';
451 + }
452 +
453 + return '<script type="application/ld+json">' . $schema . '</script>';
283 454 }
284 455 }