PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.11.7
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.11.7
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 / Admin.php

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

1,301 lines 42.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // +----------------------------------------------------------------------+
3 // | Copyright 2013 Madpixels (email : visualizer@madpixels.net) |
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: Eugene Manuilov <eugene@manuilov.org> |
20 // +----------------------------------------------------------------------+
21 /**
22 * The module for all admin stuff.
23 *
24 * @category Visualizer
25 * @package Module
26 *
27 * @since 1.0.0
28 */
29 class Visualizer_Module_Admin extends Visualizer_Module {
30
31 const NAME = __CLASS__;
32
33 /**
34 * Library page suffix.
35 *
36 * @since 1.0.0
37 *
38 * @access private
39 * @var string
40 */
41 private $_libraryPage;
42
43 /**
44 * Constructor.
45 *
46 * @since 1.0.0
47 *
48 * @access public
49 *
50 * @param Visualizer_Plugin $plugin The instance of the plugin.
51 */
52 public function __construct( Visualizer_Plugin $plugin ) {
53 parent::__construct( $plugin );
54 $this->_addAction( 'load-post.php', 'enqueueMediaScripts' );
55 $this->_addAction( 'load-post-new.php', 'enqueueMediaScripts' );
56 $this->_addAction( 'enqueue_block_editor_assets', 'enqueueMediaScripts' );
57 $this->_addAction( 'admin_footer', 'renderTemplates' );
58 $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 0 );
59 $this->_addAction( 'admin_menu', 'registerAdminMenu' );
60 $this->_addFilter( 'media_view_strings', 'setupMediaViewStrings' );
61 $this->_addFilter( 'plugin_action_links', 'getPluginActionLinks', 10, 2 );
62 $this->_addFilter( 'plugin_row_meta', 'getPluginMetaLinks', 10, 2 );
63 $this->_addFilter( 'visualizer_logger_data', 'getLoggerData' );
64 $this->_addFilter( 'visualizer_feedback_review_trigger', 'feedbackReviewTrigger' );
65
66 // screen pagination
67 $this->_addFilter( 'set-screen-option', 'setScreenOptions', 10, 3 );
68
69 // revision support.
70 $this->_addFilter( 'wp_revisions_to_keep', 'limitRevisions', null, 10, 2 );
71 $this->_addAction( '_wp_put_post_revision', 'addRevision', null, 10, 1 );
72 $this->_addAction( 'wp_restore_post_revision', 'restoreRevision', null, 10, 2 );
73
74 $this->_addAction( 'visualizer_chart_schedules_spl', 'addSplChartSchedules', null, 10, 3 );
75
76 $this->_addAction( 'admin_init', 'init' );
77
78 $this->_addAction( 'visualizer_chart_languages', 'addMultilingualSupport' );
79
80 $this->_addFilter( 'admin_footer_text', 'render_review_notice' );
81
82 if ( defined( 'TI_CYPRESS_TESTING' ) ) {
83 $this->load_cypress_hooks();
84 }
85
86 }
87 /**
88 * Display review notice.
89 */
90 public function render_review_notice( $footer_text ) {
91 $current_screen = get_current_screen();
92
93 $visualizer_page_ids = ['toplevel_page_visualizer', 'visualizer_page_viz-support', 'visualizer_page_ti-about-visualizer' ];
94
95 if ( ! empty( $current_screen ) && isset( $current_screen->id ) ) {
96 foreach ( $visualizer_page_ids as $page_to_check ) {
97 if ( strpos( $current_screen->id, $page_to_check ) !== false ) {
98 $footer_text = sprintf(
99 __( 'Enjoying %1$s? %2$s %3$s rating. Thank you for being so supportive!', 'visualizer' ),
100 '<b>Visualizer</b>',
101 esc_html__( 'You can help us by leaving a', 'visualizer' ),
102 '<a href="https://wordpress.org/support/plugin/visualizer/reviews/" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
103 );
104 break;
105 }
106 }
107 }
108
109 return $footer_text;
110 }
111
112
113 /**
114 * Define the hooks that are needed for cypress.
115 *
116 * @since 3.4.0
117 * @access private
118 */
119 private function load_cypress_hooks() {
120 // all charts should load on the same page without pagination.
121 add_filter(
122 'visualizer_query_args', function( $args ) {
123 $args['posts_per_page'] = 20;
124 return $args;
125 }, 10, 1
126 );
127 }
128
129 /**
130 * Add disabled `optgroup` schedules to the drop downs.
131 *
132 * @since ?
133 *
134 * @access public
135 *
136 * @param string $feature The feature for which to add schedules.
137 * @param int $chart_id The chart ID.
138 * @param int $plan The plan number.
139 */
140 public function addSplChartSchedules( $feature, $chart_id, $plan ) {
141 if ( apply_filters( 'visualizer_is_business', false ) ) {
142 return;
143 }
144
145 $is_new_personal = apply_filters( 'visualizer_is_new_personal', false );
146
147 $hours = array(
148 '0.16' => __( '10 minutes', 'visualizer' ),
149 '1' => __( 'Each hour', 'visualizer' ),
150 '12' => __( 'Each 12 hours', 'visualizer' ),
151 '24' => __( 'Each day', 'visualizer' ),
152 '72' => __( 'Each 3 days', 'visualizer' ),
153 );
154
155 switch ( $feature ) {
156 case 'json':
157 case 'csv':
158 // no more schedules if pro is already active.
159 if ( Visualizer_Module::is_pro() && ! $is_new_personal ) {
160 return;
161 }
162 break;
163 case 'wp':
164 // fall-through.
165 case 'db':
166 break;
167 default:
168 return;
169 }
170
171 echo '<optgroup disabled label="' . __( 'Upgrade required', 'visualizer' ) . '">';
172 foreach ( $hours as $hour => $desc ) {
173 echo '<option disabled>' . $desc . '</option>';
174 }
175 echo '</optgroup>';
176 }
177
178 /**
179 * No limits on revisions.
180 */
181 public function limitRevisions( $num, $post ) {
182 if ( Visualizer_Plugin::CPT_VISUALIZER === $post->post_type ) {
183 return -1;
184 }
185 return $num;
186 }
187
188 /**
189 * Add a revision.
190 */
191 public function addRevision( $revision_id ) {
192 $parent_id = wp_is_post_revision( $revision_id );
193 if ( Visualizer_Plugin::CPT_VISUALIZER === get_post_type( $parent_id ) ) {
194 // add the meta data to this revision.
195 $meta = get_post_meta( $parent_id, '', true );
196
197 if ( $meta ) {
198 foreach ( $meta as $key => $value ) {
199 if ( 0 === strpos( $key, 'visualizer' ) ) {
200 add_metadata( 'post', $revision_id, $key, maybe_unserialize( $value[0] ) );
201 }
202 }
203 }
204 }
205 }
206
207 /**
208 * Restore a revision.
209 */
210 public function restoreRevision( $post_id, $revision_id ) {
211 if ( Visualizer_Plugin::CPT_VISUALIZER === get_post_type( $post_id ) ) {
212 // get the meta information from the revision.
213 $meta = get_metadata( 'post', $revision_id, '', true );
214
215 // delete all meta information from the post before adding.
216 $post_meta = get_post_meta( $post_id, '', true );
217 if ( $post_meta ) {
218 foreach ( $meta as $key => $value ) {
219 if ( 0 === strpos( $key, 'visualizer' ) ) {
220 delete_post_meta( $post_id, $key );
221 }
222 }
223 }
224
225 if ( $meta ) {
226 foreach ( $meta as $key => $value ) {
227 if ( 0 === strpos( $key, 'visualizer' ) ) {
228 add_post_meta( $post_id, $key, maybe_unserialize( $value[0] ) );
229 }
230 }
231 }
232 }
233 }
234
235 /**
236 * Admin init.
237 *
238 * @access public
239 */
240 public function init() {
241 // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
242 if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' == get_user_option( 'rich_editing' ) ) {
243 $this->_addFilter( 'mce_external_languages', 'add_tinymce_lang', 10, 1 );
244 $this->_addFilter( 'mce_external_plugins', 'tinymce_plugin', 10, 1 );
245 $this->_addFilter( 'mce_buttons', 'register_mce_button', 10, 1 );
246 $this->_addFilter( 'tiny_mce_before_init', 'get_strings_for_block', 10, 1 );
247 }
248 }
249
250 /**
251 * Add the strings required for the TinyMCE buttons for the classic block (not the classic editor).
252 *
253 * @since ?
254 * @access friendly
255 */
256 function get_strings_for_block( $settings ) {
257 $class = new Visualizer_Module_Language();
258 $strings = $class->get_strings();
259 $array = array( 'visualizer_tinymce_plugin' => json_encode( $strings ) );
260 return array_merge( $settings, $array );
261 }
262
263 /**
264 * Load plugin translation for - TinyMCE API
265 *
266 * @access public
267 * @param array $arr The tinymce_lang array.
268 * @return array
269 */
270 public function add_tinymce_lang( $arr ) {
271 $ui_lang = VISUALIZER_ABSPATH . '/classes/Visualizer/Module/Language.php';
272 $ui_lang = apply_filters( 'visualizer_ui_lang_filter', $ui_lang );
273 $arr[] = $ui_lang;
274 return $arr;
275 }
276
277 /**
278 * Load custom js options - TinyMCE API
279 *
280 * @access public
281 * @param array $plugin_array The tinymce plugin array.
282 * @return array
283 */
284 public function tinymce_plugin( $plugin_array ) {
285 $plugin_array['visualizer_mce_button'] = VISUALIZER_ABSURL . 'js/mce.js';
286 return $plugin_array;
287 }
288
289 /**
290 * Register new button in the editor
291 *
292 * @access public
293 * @param array $buttons The tinymce buttons array.
294 * @return array
295 */
296 public function register_mce_button( $buttons ) {
297 array_push( $buttons, 'visualizer_mce_button' );
298 return $buttons;
299 }
300
301 /**
302 * Whether to show the feedback review or not.
303 *
304 * @access public
305 */
306 public function feedbackReviewTrigger( $dumb ) {
307 $query = new WP_Query(
308 array(
309 'posts_per_page' => 50,
310 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
311 'fields' => 'ids',
312 'update_post_meta_cache' => false,
313 'update_post_term_cache' => false,
314 )
315 );
316
317 if ( $query->have_posts() && $query->post_count > 0 ) {
318 return true;
319 }
320 return false;
321 }
322
323 /**
324 * Enqueues media scripts and styles.
325 *
326 * @since 1.0.0
327 * @uses wp_enqueue_style To enqueue style file.
328 * @uses wp_enqueue_script To enqueue script file.
329 *
330 * @access public
331 */
332 public function enqueueMediaScripts() {
333 global $typenow;
334 global $current_screen;
335
336 if ( post_type_supports( $typenow, 'editor' ) || $current_screen->id === 'widgets' || $current_screen->id === 'customize' ) {
337 wp_enqueue_style( 'visualizer-media', VISUALIZER_ABSURL . 'css/media.css', array( 'media-views' ), Visualizer_Plugin::VERSION );
338
339 // Load all the assets for the different libraries we support.
340 $deps = array(
341 Visualizer_Render_Sidebar_Google::enqueue_assets( array( 'media-editor' ) ),
342 Visualizer_Render_Sidebar_Type_DataTable_Tabular::enqueue_assets( array( 'media-editor' ) ),
343 );
344
345 wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', $deps, Visualizer_Plugin::VERSION, true );
346 wp_enqueue_script( 'visualizer-media-collection', VISUALIZER_ABSURL . 'js/media/collection.js', array( 'visualizer-media-model' ), Visualizer_Plugin::VERSION, true );
347 wp_enqueue_script( 'visualizer-media-controller', VISUALIZER_ABSURL . 'js/media/controller.js', array( 'visualizer-media-collection' ), Visualizer_Plugin::VERSION, true );
348 wp_enqueue_script( 'visualizer-media-view', VISUALIZER_ABSURL . 'js/media/view.js', array( 'visualizer-media-controller' ), Visualizer_Plugin::VERSION, true );
349 wp_localize_script(
350 'visualizer-media-view',
351 'visualizer',
352 array(
353 'i10n' => array(
354 'insert' => __( 'Insert', 'visualizer' ),
355 ),
356 )
357 );
358 wp_enqueue_script( 'visualizer-media-toolbar', VISUALIZER_ABSURL . 'js/media/toolbar.js', array( 'visualizer-media-view' ), Visualizer_Plugin::VERSION, true );
359 wp_enqueue_script( 'visualizer-media', VISUALIZER_ABSURL . 'js/media.js', array( 'visualizer-media-toolbar' ), Visualizer_Plugin::VERSION, true );
360 }
361 }
362
363 /**
364 * Extends media view strings with visualizer strings.
365 *
366 * @since 1.0.0
367 *
368 * @access public
369 *
370 * @param array $strings The array of media view strings.
371 *
372 * @return array The extended array of media view strings.
373 */
374 public function setupMediaViewStrings( $strings ) {
375 $chart_types = self::_getChartTypesLocalized( true, true, true );
376 $strings['visualizer'] = array(
377 'actions' => array(
378 'get_charts' => Visualizer_Plugin::ACTION_GET_CHARTS,
379 'delete_chart' => Visualizer_Plugin::ACTION_DELETE_CHART,
380 ),
381 'controller' => array(
382 'title' => esc_html__( 'Visualizations', 'visualizer' ),
383 ),
384 'routers' => array(
385 'library' => esc_html__( 'From Library', 'visualizer' ),
386 'create' => esc_html__( 'Create New', 'visualizer' ),
387 ),
388 'library' => array(
389 'filters' => $chart_types,
390 'types' => array_keys( $chart_types ),
391 ),
392 'nonce' => wp_create_nonce(),
393 'buildurl' => esc_url( add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ) ),
394 );
395
396 return $strings;
397 }
398
399 /**
400 * Returns associated array of chart types and localized names.
401 *
402 * @since 1.0.0
403 *
404 * @static
405 * @access private
406 * @return array The associated array of chart types with localized names.
407 */
408 public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false, $add_select = false, $where = null ) {
409 $additional = array();
410 if ( $add_select ) {
411 $additional['select'] = array(
412 'name' => esc_html__( 'All', 'visualizer' ),
413 'enabled' => true,
414 );
415 }
416
417 $enabled = self::proFeaturesLocked();
418
419 $types = array_merge(
420 $additional,
421 array(
422 'tabular' => array(
423 'name' => esc_html__( 'Table', 'visualizer' ),
424 'enabled' => true,
425 'supports' => $enabled ? array( 'Google Charts', 'DataTable' ) : array( 'DataTable' ),
426 ),
427 'pie' => array(
428 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
429 'enabled' => true,
430 'supports' => array( 'Google Charts', 'ChartJS' ),
431 ),
432 'line' => array(
433 'name' => esc_html__( 'Line', 'visualizer' ),
434 'enabled' => true,
435 'supports' => array( 'Google Charts', 'ChartJS' ),
436 ),
437 'bar' => array(
438 'name' => esc_html__( 'Bar', 'visualizer' ),
439 'enabled' => true,
440 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
441 ),
442 'area' => array(
443 'name' => esc_html__( 'Area', 'visualizer' ),
444 'enabled' => $enabled,
445 // in ChartJS, the fill option is used to make Line chart an area: https://www.chartjs.org/docs/latest/charts/area.html
446 'supports' => array( 'Google Charts' ),
447 'demo_url' => 'https://demo.themeisle.com/visualizer/area-chart/',
448 ),
449 'geo' => array(
450 'name' => esc_html__( 'Geo', 'visualizer' ),
451 'enabled' => $enabled,
452 'supports' => array( 'Google Charts' ),
453 'demo_url' => 'https://demo.themeisle.com/visualizer/geo-chart/',
454 ),
455 'column' => array(
456 'name' => esc_html__( 'Column', 'visualizer' ),
457 'enabled' => $enabled,
458 'supports' => array( 'Google Charts', 'ChartJS' ),
459 'demo_url' => 'https://demo.themeisle.com/visualizer/column-chart/',
460 ),
461 'bubble' => array(
462 'name' => esc_html__( 'Bubble', 'visualizer' ),
463 'enabled' => $enabled,
464 // chartjs' bubble is ugly looking (and it won't work off the default bubble.csv) so it is being excluded for the time being.
465 'supports' => array( 'Google Charts' ),
466 'demo_url' => 'https://demo.themeisle.com/visualizer/bubble-chart/',
467 ),
468 'scatter' => array(
469 'name' => esc_html__( 'Scatter', 'visualizer' ),
470 'enabled' => $enabled,
471 'supports' => array( 'Google Charts' ),
472 'demo_url' => 'https://demo.themeisle.com/visualizer/scatter-chart/',
473 ),
474 'gauge' => array(
475 'name' => esc_html__( 'Gauge', 'visualizer' ),
476 'enabled' => $enabled,
477 'supports' => array( 'Google Charts' ),
478 'demo_url' => 'https://demo.themeisle.com/visualizer/gauge-chart/',
479 ),
480 'candlestick' => array(
481 'name' => esc_html__( 'Candlestick', 'visualizer' ),
482 'enabled' => $enabled,
483 'supports' => array( 'Google Charts' ),
484 'demo_url' => 'https://demo.themeisle.com/visualizer/candlestick-chart/',
485 ),
486 // pro types
487 'timeline' => array(
488 'name' => esc_html__( 'Timeline', 'visualizer' ),
489 'enabled' => false,
490 'supports' => array( 'Google Charts', 'ChartJS' ),
491 'demo_url' => 'https://demo.themeisle.com/visualizer/timeline-chart/',
492 ),
493 'combo' => array(
494 'name' => esc_html__( 'Combo', 'visualizer' ),
495 'enabled' => false,
496 'supports' => array( 'Google Charts' ),
497 'demo_url' => 'https://demo.themeisle.com/visualizer/combo-chart/',
498 ),
499 'polarArea' => array(
500 'name' => esc_html__( 'Polar Area', 'visualizer' ),
501 'enabled' => false,
502 'supports' => array( 'ChartJS' ),
503 'demo_url' => 'https://demo.themeisle.com/visualizer/polar-area-chart/',
504 ),
505 'radar' => array(
506 'name' => esc_html__( 'Radar/Spider', 'visualizer' ),
507 'enabled' => false,
508 'supports' => array( 'ChartJS' ),
509 'demo_url' => 'https://demo.themeisle.com/visualizer/radar-spider-chart/',
510 ),
511 )
512 );
513 $types = apply_filters( 'visualizer_pro_chart_types', $types );
514 if ( $enabledOnly ) {
515 $filtered = array();
516 foreach ( $types as $type => $array ) {
517 if ( ! is_array( $array ) ) {
518 // support for old pro
519 $array = array( 'enabled' => true, 'name' => $array );
520 }
521 // backward compatibility for PRO before v1.9.0
522 if ( ! array_key_exists( 'supports', $array ) ) {
523 $array['supports'] = array( 'Google Charts' );
524 }
525 if ( ! $array['enabled'] ) {
526 continue;
527 }
528 $filtered[ $type ] = $array;
529 }
530 $types = $filtered;
531 }
532 if ( $get2Darray ) {
533 $doubleD = array();
534 foreach ( $types as $type => $array ) {
535 if ( ! is_array( $array ) ) {
536 // support for old pro
537 $array = array( 'enabled' => true, 'name' => $array );
538 }
539 // backward compatibility for PRO before v1.9.0
540 if ( ! array_key_exists( 'supports', $array ) ) {
541 $array['supports'] = array( 'Google Charts' );
542 }
543 $doubleD[ $type ] = $array['name'];
544 }
545 $types = $doubleD;
546 }
547
548 return self::handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where );
549 }
550
551 /**
552 * Handle (soon-to-be) deprecated charts.
553 */
554 private static function handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where ) {
555 $deprecated = array();
556
557 switch ( $where ) {
558 case 'types':
559 // fall-through
560 case 'library':
561 // if a user has a Gauge/Candlestick chart, then let them keep using it.
562 if ( ! Visualizer_Module::is_pro() ) {
563 if ( ! self::hasChartType( 'gauge' ) ) {
564 if ( $get2Darray ) {
565 $deprecated[] = 'gauge';
566 } else {
567 $types['gauge']['enabled'] = false;
568 }
569 }
570 if ( ! self::hasChartType( 'candlestick' ) ) {
571 if ( $get2Darray ) {
572 $deprecated[] = 'candlestick';
573 } else {
574 $types['candlestick']['enabled'] = false;
575 }
576 }
577 }
578 break;
579 default:
580 // if a user has a Gauge/Candlestick chart, then let them keep using it.
581 if ( ! Visualizer_Module::is_pro() ) {
582 if ( ! self::hasChartType( 'gauge' ) ) {
583 if ( $get2Darray ) {
584 $deprecated[] = 'gauge';
585 } else {
586 $types['gauge']['enabled'] = false;
587 }
588 }
589 if ( ! self::hasChartType( 'candlestick' ) ) {
590 if ( $get2Darray ) {
591 $deprecated[] = 'candlestick';
592 } else {
593 $types['candlestick']['enabled'] = false;
594 }
595 }
596 }
597 }
598
599 if ( $deprecated ) {
600 foreach ( $deprecated as $type ) {
601 unset( $types[ $type ] );
602 }
603 }
604
605 return $types;
606 }
607
608 /**
609 * Renders templates to use in media popup.
610 *
611 * @since 1.0.0
612 * @global string $pagenow The name of the current page.
613 *
614 * @access public
615 */
616 public function renderTemplates() {
617 global $pagenow;
618 if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
619 return;
620 }
621 $render = new Visualizer_Render_Templates();
622 $render->render();
623 }
624
625 /**
626 * Enqueues library scripts and styles.
627 *
628 * @since 1.0.0
629 * @uses wp_enqueue_style() To enqueue library stylesheet.
630 * @uses wp_enqueue_script() To enqueue javascript file.
631 * @uses wp_enqueue_media() To enqueue media stuff.
632 *
633 * @access public
634 *
635 * @param string $suffix The current page suffix.
636 */
637 public function enqueueLibraryScripts( $suffix ) {
638 if ( $suffix === $this->_libraryPage ) {
639 wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
640 $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
641 wp_enqueue_media();
642 wp_enqueue_script(
643 'visualizer-library',
644 VISUALIZER_ABSURL . 'js/library.js',
645 array(
646 'jquery',
647 'media-views',
648 'clipboard',
649 ),
650 Visualizer_Plugin::VERSION,
651 true
652 );
653
654 wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
655
656 $query = $this->getQuery();
657 while ( $query->have_posts() ) {
658 $chart = $query->next_post();
659 $library = $this->load_chart_type( $chart->ID );
660 if ( is_null( $library ) ) {
661 continue;
662 }
663 wp_enqueue_script(
664 "visualizer-render-$library",
665 VISUALIZER_ABSURL . 'js/render-facade.js',
666 apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
667 Visualizer_Plugin::VERSION,
668 true
669 );
670 }
671 }
672 }
673
674 /**
675 * Adds visualizer tab for media upload tabs array.
676 *
677 * @since 1.0.0
678 *
679 * @access public
680 *
681 * @param array $tabs The array of media upload tabs.
682 *
683 * @return array Extended array of media upload tabs.
684 */
685 public function setupVisualizerTab( $tabs ) {
686 $tabs['visualizer'] = 'Visualizer';
687
688 return $tabs;
689 }
690
691 /**
692 * Registers admin menu for visualizer library.
693 *
694 * @since 1.0.0
695 *
696 * @access public
697 */
698 public function registerAdminMenu() {
699 $svg_base64_icon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNzdweCIgaGVpZ2h0PSI3N3B4IiB2aWV3Qm94PSIwIDAgNzcgNzciIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjYgKDY3NDkxKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Db21iaW5lZCBTaGFwZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxnIGlkPSJQcm9kdWN0LVBhZ2UiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJXb3JkUHJlc3MtcGx1Z2lucyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE5MC4wMDAwMDAsIC00MzUuMDAwMDAwKSIgZmlsbD0iIzM5QzNEMiI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMjguNSw1MTIgQzIwNy4yMzcwMzcsNTEyIDE5MCw0OTQuNzYyOTYzIDE5MCw0NzMuNSBDMTkwLDQ1Mi4yMzcwMzcgMjA3LjIzNzAzNyw0MzUgMjI4LjUsNDM1IEMyNDkuNzYyOTYzLDQzNSAyNjcsNDUyLjIzNzAzNyAyNjcsNDczLjUgQzI2Nyw0OTQuNzYyOTYzIDI0OS43NjI5NjMsNTEyIDIyOC41LDUxMiBaIE0yNDYuODQzNzUsNDgzLjU5MjA1OSBMMjE1LjYyNSw0ODMuNTkyMDU5IEwyMTUuNjI1LDQ2MC44MjY1NDQgQzIxNS42MjUsNDYwLjE2NDU0NyAyMTUuMTA3NTc4LDQ1OS42MjgzNTkgMjE0LjQ2ODc1LDQ1OS42MjgzNTkgTDIxMi4xNTYyNSw0NTkuNjI4MzU5IEMyMTEuNTE3NDIyLDQ1OS42MjgzNTkgMjExLDQ2MC4xNjQ1NDcgMjExLDQ2MC44MjY1NDQgTDIxMSw0ODUuOTg4NDI5IEMyMTEsNDg3LjMxMTY3NCAyMTIuMDM1NTY2LDQ4OC4zODQ3OTggMjEzLjMxMjUsNDg4LjM4NDc5OCBMMjQ2Ljg0Mzc1LDQ4OC4zODQ3OTggQzI0Ny40ODI1NzgsNDg4LjM4NDc5OCAyNDgsNDg3Ljg0ODYxMSAyNDgsNDg3LjE4NjYxMyBMMjQ4LDQ4NC43OTAyNDQgQzI0OCw0ODQuMTI4MjQ2IDI0Ny40ODI1NzgsNDgzLjU5MjA1OSAyNDYuODQzNzUsNDgzLjU5MjA1OSBaIE0yNDQuNTMxMjUsNDYyLjAyNDcyOSBMMjM1Ljk5OTU3LDQ2Mi4wMjQ3MjkgQzIzNC40NTQ1MzEsNDYyLjAyNDcyOSAyMzMuNjgwNTY2LDQ2My45NjA1NDcgMjM0Ljc3MzIyMyw0NjUuMDkyODMyIEwyMzcuMTE0NjI5LDQ2Ny41MTkxNTYgTDIzMS44MTI1LDQ3My4wMTQzMzIgTDIyNi41MTAzNzEsNDY3LjUxOTkwNSBDMjI1LjYwNzA1MSw0NjYuNTgzODIzIDIyNC4xNDI5NDksNDY2LjU4MzgyMyAyMjMuMjQwMzUyLDQ2Ny41MTk5MDUgTDIxOC4yNzY0MjYsNDcyLjY2Mzg2MyBDMjE3LjgyNDc2Niw0NzMuMTMxOTA0IDIxNy44MjQ3NjYsNDczLjg5MDUwNSAyMTguMjc2NDI2LDQ3NC4zNTg1NDYgTDIxOS45MTEwNzQsNDc2LjA1MjQ4IEMyMjAuMzYyNzM0LDQ3Ni41MjA1MjEgMjIxLjA5NDc4NSw0NzYuNTIwNTIxIDIyMS41NDY0NDUsNDc2LjA1MjQ4IEwyMjQuODc1LDQ3Mi42MDI0NTYgTDIzMC4xNzcxMjksNDc4LjA5Njg4MyBDMjMxLjA4MDQ0OSw0NzkuMDMyOTY1IDIzMi41NDQ1NTEsNDc5LjAzMjk2NSAyMzMuNDQ3MTQ4LDQ3OC4wOTY4ODMgTDI0MC4zODQ2NDgsNDcwLjkwNzc3MyBMMjQyLjcyNjA1NSw0NzMuMzM0MDk4IEMyNDMuODE4NzExLDQ3NC40NjYzODIgMjQ1LjY4Njc3Nyw0NzMuNjY0MzQ3IDI0NS42ODY3NzcsNDcyLjA2MzI3MyBMMjQ1LjY4Njc3Nyw0NjMuMjIyOTE0IEMyNDUuNjg3NSw0NjIuNTYwOTE3IDI0NS4xNzAwNzgsNDYyLjAyNDcyOSAyNDQuNTMxMjUsNDYyLjAyNDcyOSBaIiBpZD0iQ29tYmluZWQtU2hhcGUiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==';
700
701 $this->_libraryPage = add_menu_page( __( 'Visualizer', 'visualizer' ), __( 'Visualizer', 'visualizer' ), 'edit_posts', Visualizer_Plugin::NAME, array( $this, 'renderLibraryPage' ), $svg_base64_icon, 99.7666 );
702
703 add_submenu_page(
704 Visualizer_Plugin::NAME,
705 __( 'Chart Library', 'visualizer' ),
706 __( 'Chart Library', 'visualizer' ),
707 'edit_posts',
708 'admin.php?page=' . Visualizer_Plugin::NAME
709 );
710 add_submenu_page(
711 Visualizer_Plugin::NAME,
712 __( 'Add New Chart', 'visualizer' ),
713 __( 'Add New Chart', 'visualizer' ),
714 'edit_posts',
715 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew'
716 );
717 add_submenu_page(
718 Visualizer_Plugin::NAME,
719 __( 'Support', 'visualizer' ),
720 __( 'Support', 'visualizer' ) . '<span class="dashicons dashicons-editor-help more-features-icon" style="width: 17px; height: 17px; margin-left: 4px; color: #ffca54; font-size: 17px; vertical-align: -3px;"></span>',
721 'edit_posts',
722 'viz-support',
723 array( $this, 'renderSupportPage' )
724 );
725
726 remove_submenu_page( Visualizer_Plugin::NAME, Visualizer_Plugin::NAME );
727
728 add_action( "load-{$this->_libraryPage}", array( $this, 'addScreenOptions' ) );
729 add_action( 'admin_footer', array( $this, 'handleGetProSubMenu' ) );
730 }
731
732 /**
733 * Handle get pro plugin submenu.
734 */
735 public function handleGetProSubMenu() {
736 if ( ! Visualizer_Module::is_pro() ) {
737 ?>
738 <style type="text/css">
739 #toplevel_page_visualizer ul.wp-submenu li:last-child {
740 background: #FF7E65;
741 font-size: 14px;
742 font-weight: 600;
743 color: #fff;
744 }
745 #toplevel_page_visualizer ul.wp-submenu li:last-child > a > span {
746 color: #fff !important;
747 }
748 #toplevel_page_visualizer ul.wp-submenu li:last-child > a:hover {
749 box-shadow: inherit;
750 }
751 </style>
752 <?php
753 if ( get_option( 'visualizer_fresh_install', false ) ) {
754 ?>
755 <style type="text/css">
756 #toplevel_page_visualizer ul.wp-submenu li.wp-first-item + li + li + li {
757 display: none;
758 }
759 </style>
760 <?php
761 }
762 }
763 }
764
765 /**
766 * Adds the screen options for pagination.
767 */
768 function addScreenOptions() {
769 $screen = get_current_screen();
770
771 // bail if it's some other page.
772 if ( ! is_object( $screen ) || $screen->id !== $this->_libraryPage ) {
773 return;
774 }
775
776 $args = array(
777 'label' => __( 'Number of charts per page:', 'visualizer' ),
778 'default' => 6,
779 'option' => 'visualizer_library_per_page',
780 );
781 add_screen_option( 'per_page', $args );
782 }
783
784 /**
785 * Returns the screen option for pagination.
786 */
787 function setScreenOptions( $status, $option, $value ) {
788 if ( 'visualizer_library_per_page' === $option ) {
789 return $value;
790 }
791 }
792
793 /**
794 * Adds the display filters to be used in the meta_query while displaying the charts.
795 */
796 private function getDisplayFilters( &$query_args ) {
797 $query = array();
798 global $sitepress;
799 if ( Visualizer_Module::is_pro() && ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) ) {
800 $current_lang = icl_get_current_language();
801 if ( in_array( $current_lang, array( 'all', icl_get_default_language() ), true ) ) {
802 $query[] = array(
803 'key' => 'chart_lang',
804 'compare' => 'NOT EXISTS',
805 );
806 } else {
807 $query[] = array(
808 'key' => 'chart_lang',
809 'value' => $current_lang,
810 'compare' => '=',
811 );
812 }
813 }
814
815 // add chart type filter to the query arguments
816 $type = filter_input( INPUT_GET, 'type' );
817 if ( $type && in_array( $type, Visualizer_Plugin::getChartTypes(), true ) ) {
818 $query[] = array(
819 'key' => Visualizer_Plugin::CF_CHART_TYPE,
820 'value' => $type,
821 'compare' => '=',
822 );
823 }
824
825 // add chart library filter to the query arguments
826 $library = filter_input( INPUT_GET, 'library' );
827 if ( $library ) {
828 $query[] = array(
829 'key' => Visualizer_Plugin::CF_CHART_LIBRARY,
830 'value' => $library,
831 'compare' => '=',
832 );
833 }
834
835 // add date filter to the query arguments
836 $date = filter_input( INPUT_GET, 'date' );
837 $possible = array_keys( Visualizer_Plugin::getSupportedDateFilter() );
838 if ( $date && in_array( $date, $possible, true ) ) {
839 $query_args['date_query'] = array(
840 'after' => "$date -1 day",
841 'inclusive' => true,
842 );
843 }
844
845 // add source filter to the query arguments
846 $source = filter_input( INPUT_GET, 'source' );
847 if ( $source ) {
848 $source = ucwords( $source );
849 $source = "Visualizer_Source_{$source}";
850 $query[] = array(
851 'key' => Visualizer_Plugin::CF_SOURCE,
852 'value' => $source,
853 'compare' => '=',
854 );
855 }
856
857 $query_args['meta_query'] = $query;
858
859 $orderby = filter_input( INPUT_GET, 'orderby' );
860 $order = filter_input( INPUT_GET, 'order' );
861 if ( $orderby ) {
862 $query_args['order_by'] = $orderby;
863 }
864 $query_args['order'] = empty( $order ) ? 'desc' : $order;
865 }
866
867 /**
868 * Get the instance of WP_Query that fetches the charts as per the given criteria.
869 */
870 private function getQuery() {
871 static $q;
872 if ( ! is_null( $q ) ) {
873 return $q;
874 }
875
876 // get current page
877 $page = filter_input(
878 INPUT_GET,
879 'vpage',
880 FILTER_VALIDATE_INT,
881 array(
882 'options' => array(
883 'min_range' => 1,
884 'default' => 1,
885 ),
886 )
887 );
888
889 $per_page = 6;
890 $screen = get_current_screen();
891 if ( $screen ) {
892 // retrieve the per_page option
893 $screen_option = $screen->get_option( 'per_page', 'option' );
894 // retrieve the value stored for the current user
895 $user = get_current_user_id();
896 $per_page = get_user_meta( $user, $screen_option, true );
897 if ( empty( $per_page ) || $per_page < 1 ) {
898 // nothing set, get the default value
899 $per_page = $screen->get_option( 'per_page', 'default' );
900 }
901 }
902
903 // the initial query arguments to fetch charts
904 $query_args = array(
905 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
906 'posts_per_page' => $per_page,
907 'paged' => $page,
908 );
909
910 $this->getDisplayFilters( $query_args );
911
912 // Added by Ash/Upwork
913 $filterByMeta = ! empty( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
914 if ( $filterByMeta ) {
915 $query = array(
916 'key' => Visualizer_Plugin::CF_SETTINGS,
917 'value' => $filterByMeta,
918 'compare' => 'LIKE',
919 );
920 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
921 $meta[] = $query;
922 $query_args['meta_query'] = $meta;
923 }
924 $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
925 return $q;
926 }
927
928 /**
929 * Renders support page.
930 *
931 * @since 3.3.0
932 *
933 * @access public
934 */
935 public function renderSupportPage() {
936 wp_enqueue_style( 'visualizer-upsell', VISUALIZER_ABSURL . 'css/upsell.css', array(), Visualizer_Plugin::VERSION );
937 $this->load_survey();
938 include_once VISUALIZER_ABSPATH . '/templates/support.php';
939 }
940
941 /**
942 * Renders visualizer library page.
943 *
944 * @since 1.0.0
945 *
946 * @access public
947 */
948 public function renderLibraryPage() {
949 $charts = array();
950 $query = $this->getQuery();
951
952 // get current page
953 $page = filter_input(
954 INPUT_GET,
955 'vpage',
956 FILTER_VALIDATE_INT,
957 array(
958 'options' => array(
959 'min_range' => 1,
960 'default' => 1,
961 ),
962 )
963 );
964 // add chart type filter to the query arguments
965 $filter = filter_input( INPUT_GET, 'type' );
966 if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) ) {
967 $filter = 'all';
968 }
969
970 $css = '';
971 while ( $query->have_posts() ) {
972 $chart = $query->next_post();
973
974 // if the user has updated a chart and instead of saving it, has closed the modal. If the user refreshes, they should get the original chart.
975 $chart = $this->handleExistingRevisions( $chart->ID, $chart );
976 // refresh a "live" db query chart.
977 $chart = apply_filters( 'visualizer_schedule_refresh_chart', $chart, $chart->ID, false );
978
979 $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
980
981 // fetch and update settings
982 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
983
984 $settings = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $settings, $chart->ID, $type );
985 if ( ! empty( $atts['settings'] ) ) {
986 $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
987 }
988
989 if ( $settings ) {
990 unset( $settings['height'], $settings['width'], $settings['chartArea'] );
991 }
992
993 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
994 $data = self::get_chart_data( $chart, $type );
995
996 // Set default setting series when add manual chart data - Only during first creation.
997 if ( isset( $settings['series'] ) && ! empty( $series ) ) {
998 $count_series = count( $series ) - count( $settings['series'] );
999 if ( $count_series > 1 ) {
1000 $clone_last_series = end( $settings['series'] );
1001 $clone_last_series = array_fill_keys( array_keys( $clone_last_series ), '' );
1002 foreach ( range( 1, $count_series ) as $item ) {
1003 $settings['series'][] = $clone_last_series;
1004 }
1005 }
1006 }
1007
1008 $library = $this->load_chart_type( $chart->ID );
1009
1010 $id = 'visualizer-' . $chart->ID;
1011 $arguments = $this->get_inline_custom_css( $id, $settings );
1012 if ( ! empty( $arguments ) ) {
1013 $css .= $arguments[0];
1014 $settings = $arguments[1];
1015 }
1016
1017 if ( isset( $settings['controls']['ui']['labelStacking'] ) ) {
1018 unset( $settings['controls']['ui']['labelStacking'] );
1019 }
1020 if ( isset( $settings['controls']['ui']['orientation'] ) ) {
1021 unset( $settings['controls']['ui']['orientation'] );
1022 }
1023
1024 // add chart to the array
1025 $charts[ $id ] = array(
1026 'id' => $chart->ID,
1027 'type' => $type,
1028 'series' => $series,
1029 'settings' => $settings,
1030 'data' => $data,
1031 'library' => $library,
1032 );
1033 }
1034 // enqueue charts array
1035 $ajaxurl = admin_url( 'admin-ajax.php' );
1036
1037 wp_localize_script(
1038 'visualizer-library',
1039 'visualizer',
1040 array(
1041 'language' => $this->get_language(),
1042 'map_api_key' => get_option( 'visualizer-map-api-key' ),
1043 'charts' => $charts,
1044 'urls' => array(
1045 'base' => esc_url( add_query_arg( array( 'vpage' => false, 'vaction' => false ) ) ),
1046 'create' => esc_url(
1047 add_query_arg(
1048 array(
1049 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
1050 'library' => 'yes',
1051 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
1052 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
1053 'vaction' => false,
1054 ),
1055 $ajaxurl
1056 )
1057 ),
1058 'edit' => esc_url(
1059 add_query_arg(
1060 array(
1061 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
1062 'library' => 'yes',
1063 'vaction' => false,
1064 ),
1065 $ajaxurl
1066 )
1067 ),
1068 ),
1069 'page_type' => 'library',
1070 'is_front' => false,
1071 'i10n' => array(
1072 'copied' => __( 'The shortcode has been copied to your clipboard. Hit Ctrl-V/Cmd-V to paste it.', 'visualizer' ),
1073 'conflict' => __( 'We have detected a potential conflict with another component that prevents Visualizer from functioning properly. Please disable any of the following components if they are activated on your instance: Modern Events Calendar plugin, Acronix plugin. In case the aforementioned components are not activated or you continue to see this error message, please disable all other plugins and enable them one by one to find out the component that is causing the conflict.', 'visualizer' ),
1074 ),
1075 'is_pro_user' => Visualizer_Module::is_pro(),
1076 )
1077 );
1078 // render library page
1079 $render = new Visualizer_Render_Library();
1080 $render->charts = $charts;
1081 $render->type = $filter;
1082 $render->types = self::_getChartTypesLocalized( false, false, false, true );
1083 $render->custom_css = $css;
1084 $render->pagination = paginate_links(
1085 array(
1086 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
1087 'format' => '',
1088 'current' => $page,
1089 'total' => $query->max_num_pages,
1090 'type' => 'array',
1091 )
1092 );
1093
1094 $this->load_survey();
1095
1096 if ( ! apply_filters( 'visualizer_is_business', false ) ) {
1097 do_action( 'themeisle_sdk_load_banner', 'visualizer' );
1098 }
1099
1100 $render->render();
1101 }
1102
1103 /**
1104 * Updates the plugin's action links, which will be rendered at the plugins table.
1105 *
1106 * @since 1.0.0
1107 *
1108 * @access public
1109 *
1110 * @param array $links The array of original action links.
1111 * @param string $file The plugin basename.
1112 *
1113 * @return array Updated array of action links.
1114 */
1115 public function getPluginActionLinks( $links, $file ) {
1116 if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
1117 array_unshift(
1118 $links,
1119 sprintf(
1120 '<a href="%s">%s</a>',
1121 admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
1122 esc_html__( 'Library', 'visualizer' )
1123 )
1124 );
1125 }
1126
1127 return $links;
1128 }
1129
1130 /**
1131 * Updates the plugin's meta links, which will be rendered at the plugins table.
1132 *
1133 * @since 1.0.0
1134 *
1135 * @access public
1136 *
1137 * @param array $plugin_meta The array of a plugin meta links.
1138 * @param string $plugin_file The plugin's basename.
1139 *
1140 * @return array Updated array of plugin meta links.
1141 */
1142 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
1143 if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
1144 // knowledge base link
1145 $plugin_meta[] = sprintf(
1146 '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1147 esc_html__( 'Docs', 'visualizer' )
1148 );
1149 // flattr link
1150 $plugin_meta[] = sprintf(
1151 '<a style="color:red" href="' . tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'pluginrow' ) . '" target="_blank">%s</a>',
1152 esc_html__( 'Get Visualizer Pro', 'visualizer' )
1153 );
1154 }
1155
1156 return $plugin_meta;
1157 }
1158
1159 /**
1160 * If check is existing user.
1161 *
1162 * @return bool Default false
1163 */
1164 public static function proFeaturesLocked() {
1165 if ( Visualizer_Module::is_pro() ) {
1166 return true;
1167 }
1168 return 'yes' === get_option( 'visualizer-new-user', 'yes' ) ? false : true;
1169 }
1170
1171 /**
1172 * Multilingual Support.
1173 *
1174 * @param int $chart_id Chart ID.
1175 * @return bool Default false
1176 */
1177 public function addMultilingualSupport( $chart_id ) {
1178 global $sitepress;
1179 if ( Visualizer_Module::is_pro() ) {
1180 return;
1181 }
1182 if ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) {
1183 $language = icl_get_languages();
1184 $current_lang = icl_get_current_language();
1185 $default_lang = icl_get_default_language();
1186 $post_info = wpml_get_language_information( null, $chart_id );
1187 $translations = array();
1188 if ( ! empty( $post_info ) && ( $default_lang === $post_info['language_code'] ) ) {
1189 $trid = $sitepress->get_element_trid( $chart_id, 'post_' . Visualizer_Plugin::CPT_VISUALIZER );
1190 $translations = $sitepress->get_element_translations( $trid );
1191 }
1192 if ( empty( $translations ) ) {
1193 return;
1194 }
1195 ?>
1196 <hr><div class="visualizer-languages-list only-pro">
1197 <?php
1198 foreach ( $language as $lang ) {
1199 $lang_code = $lang['code'];
1200 if ( $current_lang !== $lang_code ) {
1201 ?>
1202 <a href="javascript:;">
1203 <img src="<?php echo esc_url( $lang['country_flag_url'] ); ?>" alt="<?php echo esc_attr( $lang['translated_name'] ); ?>">
1204 </a>
1205 <?php
1206 }
1207 }
1208 ?>
1209 <a href="<?php echo tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'wpml-support', 'visualizer_render_char' ); ?>"target="_blank"><?php esc_html_e( 'Upgrade to PRO to active this translation for charts', 'visualizer' ); ?></a>
1210 </div>
1211 <?php
1212 }
1213 }
1214
1215 /**
1216 * Check chart is enabled or not.
1217 *
1218 * @param string $type Chart ID.
1219 *
1220 * @return bool Default false
1221 */
1222 public static function checkChartStatus( $type ) {
1223 $types = self::_getChartTypesLocalized( false, false, false, true );
1224 if ( isset( $types[ $type ] ) ) {
1225 return ! empty( $types[ $type ]['enabled'] );
1226 }
1227 return false;
1228 }
1229
1230 /**
1231 * Get the survey metadata.
1232 *
1233 * @return array The survey metadata.
1234 */
1235 private function get_survey_metadata() {
1236 $install_date = get_option( 'visualizer_install', false );
1237 $install_category = 0;
1238
1239 if ( false !== $install_date ) {
1240 $days_since_install = round( ( time() - $install_date ) / DAY_IN_SECONDS );
1241
1242 if ( 0 === $days_since_install || 1 === $days_since_install ) {
1243 $install_category = 0;
1244 } elseif ( 1 < $days_since_install && 8 > $days_since_install ) {
1245 $install_category = 7;
1246 } elseif ( 8 <= $days_since_install && 31 > $days_since_install ) {
1247 $install_category = 30;
1248 } elseif ( 30 < $days_since_install && 90 > $days_since_install ) {
1249 $install_category = 90;
1250 } elseif ( 90 <= $days_since_install ) {
1251 $install_category = 91;
1252 }
1253 }
1254
1255 $plugin_data = get_plugin_data( VISUALIZER_BASEFILE, false, false );
1256 $plugin_version = '';
1257 if ( ! empty( $plugin_data['Version'] ) ) {
1258 $plugin_version = $plugin_data['Version'];
1259 }
1260
1261 $user_id = 'visualizer_' . preg_replace( '/[^\w\d]*/', '', get_site_url() ); // Use a normalized version of the site URL as a user ID.
1262
1263 $license_data = get_option( 'visualizer_pro_license_data', false );
1264 if ( false !== $license_data && isset( $license_data->key ) ) {
1265 $user_id = 'visualizer_' . $license_data->key;
1266 }
1267
1268 return array(
1269 'userId' => $user_id,
1270 'attributes' => array(
1271 'days_since_install' => strval( $install_category ),
1272 'free_version' => $plugin_version,
1273 'pro_version' => defined( 'VISUALIZER_PRO_VERSION' ) ? VISUALIZER_PRO_VERSION : '',
1274 'license_status' => apply_filters( 'product_visualizer_license_status', 'invalid' ),
1275 ),
1276 );
1277 }
1278
1279 /**
1280 * Load the survey.
1281 */
1282 private function load_survey() {
1283
1284 if ( defined( 'TI_CYPRESS_TESTING' ) ) {
1285 return;
1286 }
1287
1288 $survey_handler = apply_filters( 'themeisle_sdk_dependency_script_handler', 'survey' );
1289
1290 if ( empty( $survey_handler ) ) {
1291 return;
1292 }
1293
1294 $metadata = $this->get_survey_metadata();
1295
1296 do_action( 'themeisle_sdk_dependency_enqueue_script', 'survey' );
1297 wp_enqueue_script( 'visualizer_chart_survey', VISUALIZER_ABSURL . 'js/survey.js', array( $survey_handler ), $metadata['attributes']['free_version'], true );
1298 wp_localize_script( 'visualizer_chart_survey', 'visualizerSurveyData', $metadata );
1299 }
1300 }
1301