PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.9.2
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.9.2
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/Admin.php +712 -91 3.0.73.9.2 View file →
@@ -52,34 +52,195 @@
52 52 public function __construct( Visualizer_Plugin $plugin ) {
53 53 parent::__construct( $plugin );
54 54 $this->_addAction( 'load-post.php', 'enqueueMediaScripts' );
55 55 $this->_addAction( 'load-post-new.php', 'enqueueMediaScripts' );
56 - $this->_addAction( 'admin_footer', 'renderTempaltes' );
57 - $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 8 );
56 + $this->_addAction( 'admin_footer', 'renderTemplates' );
57 + $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 0 );
58 58 $this->_addAction( 'admin_menu', 'registerAdminMenu' );
59 59 $this->_addFilter( 'media_view_strings', 'setupMediaViewStrings' );
60 60 $this->_addFilter( 'plugin_action_links', 'getPluginActionLinks', 10, 2 );
61 + $this->_addFilter( 'plugin_row_meta', 'getPluginMetaLinks', 10, 2 );
61 62 $this->_addFilter( 'visualizer_logger_data', 'getLoggerData' );
62 - $this->_addFilter( 'visualizer_get_chart_counts', 'getChartCountsByTypeAndMeta' );
63 63 $this->_addFilter( 'visualizer_feedback_review_trigger', 'feedbackReviewTrigger' );
64 64
65 + // screen pagination
66 + $this->_addFilter( 'set-screen-option', 'setScreenOptions', 10, 3 );
67 +
68 + // revision support.
69 + $this->_addFilter( 'wp_revisions_to_keep', 'limitRevisions', null, 10, 2 );
70 + $this->_addAction( '_wp_put_post_revision', 'addRevision', null, 10, 1 );
71 + $this->_addAction( 'wp_restore_post_revision', 'restoreRevision', null, 10, 2 );
72 +
73 + $this->_addAction( 'visualizer_chart_schedules_spl', 'addSplChartSchedules', null, 10, 3 );
74 +
65 75 $this->_addAction( 'admin_init', 'init' );
76 +
77 + $this->_addAction( 'visualizer_chart_languages', 'addMultilingualSupport' );
78 +
79 + if ( defined( 'TI_CYPRESS_TESTING' ) ) {
80 + $this->load_cypress_hooks();
81 + }
82 +
66 83 }
67 84
68 85 /**
86 + * Define the hooks that are needed for cypress.
87 + *
88 + * @since 3.4.0
89 + * @access private
90 + */
91 + private function load_cypress_hooks() {
92 + // all charts should load on the same page without pagination.
93 + add_filter(
94 + 'visualizer_query_args', function( $args ) {
95 + $args['posts_per_page'] = 20;
96 + return $args;
97 + }, 10, 1
98 + );
99 + }
100 +
101 + /**
102 + * Add disabled `optgroup` schedules to the drop downs.
103 + *
104 + * @since ?
105 + *
106 + * @access public
107 + *
108 + * @param string $feature The feature for which to add schedules.
109 + * @param int $chart_id The chart ID.
110 + * @param int $plan The plan number.
111 + */
112 + public function addSplChartSchedules( $feature, $chart_id, $plan ) {
113 + if ( apply_filters( 'visualizer_is_business', false ) ) {
114 + return;
115 + }
116 +
117 + $license = __( 'PRO', 'visualizer' );
118 + if ( Visualizer_Module::is_pro() ) {
119 + switch ( $plan ) {
120 + case 1:
121 + $license = __( 'Developer', 'visualizer' );
122 + break;
123 + }
124 + }
125 +
126 + $hours = array(
127 + '0' => __( 'Live', 'visualizer' ),
128 + '1' => __( 'Each hour', 'visualizer' ),
129 + '12' => __( 'Each 12 hours', 'visualizer' ),
130 + '24' => __( 'Each day', 'visualizer' ),
131 + '72' => __( 'Each 3 days', 'visualizer' ),
132 + );
133 +
134 + switch ( $feature ) {
135 + case 'json':
136 + case 'csv':
137 + // no more schedules if pro is already active.
138 + if ( Visualizer_Module::is_pro() ) {
139 + return;
140 + }
141 + break;
142 + case 'wp':
143 + // fall-through.
144 + case 'db':
145 + break;
146 + default:
147 + return;
148 + }
149 +
150 + echo '<optgroup disabled label="' . sprintf( __( 'More in the %s version', 'visualizer' ), $license ) . '">';
151 + foreach ( $hours as $hour => $desc ) {
152 + echo '<option disabled>' . $desc . '</option>';
153 + }
154 + echo '</optgroup>';
155 + }
156 +
157 + /**
158 + * No limits on revisions.
159 + */
160 + public function limitRevisions( $num, $post ) {
161 + if ( Visualizer_Plugin::CPT_VISUALIZER === $post->post_type ) {
162 + return -1;
163 + }
164 + return $num;
165 + }
166 +
167 + /**
168 + * Add a revision.
169 + */
170 + public function addRevision( $revision_id ) {
171 + $parent_id = wp_is_post_revision( $revision_id );
172 + if ( Visualizer_Plugin::CPT_VISUALIZER === get_post_type( $parent_id ) ) {
173 + // add the meta data to this revision.
174 + $meta = get_post_meta( $parent_id, '', true );
175 +
176 + if ( $meta ) {
177 + foreach ( $meta as $key => $value ) {
178 + if ( 0 === strpos( $key, 'visualizer' ) ) {
179 + add_metadata( 'post', $revision_id, $key, maybe_unserialize( $value[0] ) );
180 + }
181 + }
182 + }
183 + }
184 + }
185 +
186 + /**
187 + * Restore a revision.
188 + */
189 + public function restoreRevision( $post_id, $revision_id ) {
190 + if ( Visualizer_Plugin::CPT_VISUALIZER === get_post_type( $post_id ) ) {
191 + // get the meta information from the revision.
192 + $meta = get_metadata( 'post', $revision_id, '', true );
193 +
194 + // delete all meta information from the post before adding.
195 + $post_meta = get_post_meta( $post_id, '', true );
196 + if ( $post_meta ) {
197 + foreach ( $meta as $key => $value ) {
198 + if ( 0 === strpos( $key, 'visualizer' ) ) {
199 + delete_post_meta( $post_id, $key );
200 + }
201 + }
202 + }
203 +
204 + if ( $meta ) {
205 + foreach ( $meta as $key => $value ) {
206 + if ( 0 === strpos( $key, 'visualizer' ) ) {
207 + add_post_meta( $post_id, $key, maybe_unserialize( $value[0] ) );
208 + }
209 + }
210 + }
211 + }
212 + }
213 +
214 + /**
69 215 * Admin init.
70 216 *
71 217 * @access public
72 218 */
73 219 public function init() {
220 + // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
74 221 if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' == get_user_option( 'rich_editing' ) ) {
75 222 $this->_addFilter( 'mce_external_languages', 'add_tinymce_lang', 10, 1 );
76 223 $this->_addFilter( 'mce_external_plugins', 'tinymce_plugin', 10, 1 );
77 224 $this->_addFilter( 'mce_buttons', 'register_mce_button', 10, 1 );
225 + $this->_addFilter( 'tiny_mce_before_init', 'get_strings_for_block', 10, 1 );
78 226 }
79 227 }
80 228
81 229 /**
230 + * Add the strings required for the TinyMCE buttons for the classic block (not the classic editor).
231 + *
232 + * @since ?
233 + * @access friendly
234 + */
235 + function get_strings_for_block( $settings ) {
236 + $class = new Visualizer_Module_Language();
237 + $strings = $class->get_strings();
238 + $array = array( 'visualizer_tinymce_plugin' => json_encode( $strings ) );
239 + return array_merge( $settings, $array );
240 + }
241 +
242 + /**
82 243 * Load plugin translation for - TinyMCE API
83 244 *
84 245 * @access public
85 246 * @param array $arr The tinymce_lang array.
@@ -150,16 +311,23 @@
150 311 public function enqueueMediaScripts() {
151 312 global $typenow;
152 313 if ( post_type_supports( $typenow, 'editor' ) ) {
153 314 wp_enqueue_style( 'visualizer-media', VISUALIZER_ABSURL . 'css/media.css', array( 'media-views' ), Visualizer_Plugin::VERSION );
154 - wp_enqueue_script( 'visualizer-google-jsapi-new', '//www.gstatic.com/charts/loader.js', array( 'media-editor' ), null, true );
155 - wp_enqueue_script( 'visualizer-google-jsapi-old', '//www.google.com/jsapi', array( 'visualizer-google-jsapi-new' ), null, true );
156 - wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', array( 'visualizer-google-jsapi-old' ), Visualizer_Plugin::VERSION, true );
315 +
316 + // Load all the assets for the different libraries we support.
317 + $deps = array(
318 + Visualizer_Render_Sidebar_Google::enqueue_assets( array( 'media-editor' ) ),
319 + Visualizer_Render_Sidebar_Type_DataTable_Tabular::enqueue_assets( array( 'media-editor' ) ),
320 + );
321 +
322 + wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', $deps, Visualizer_Plugin::VERSION, true );
157 323 wp_enqueue_script( 'visualizer-media-collection', VISUALIZER_ABSURL . 'js/media/collection.js', array( 'visualizer-media-model' ), Visualizer_Plugin::VERSION, true );
158 324 wp_enqueue_script( 'visualizer-media-controller', VISUALIZER_ABSURL . 'js/media/controller.js', array( 'visualizer-media-collection' ), Visualizer_Plugin::VERSION, true );
159 325 wp_enqueue_script( 'visualizer-media-view', VISUALIZER_ABSURL . 'js/media/view.js', array( 'visualizer-media-controller' ), Visualizer_Plugin::VERSION, true );
160 326 wp_localize_script(
161 - 'visualizer-media-view', 'visualizer', array(
327 + 'visualizer-media-view',
328 + 'visualizer',
329 + array(
162 330 'i10n' => array(
163 331 'insert' => __( 'Insert', 'visualizer' ),
164 332 ),
165 333 )
@@ -198,9 +366,9 @@
198 366 'filters' => $chart_types,
199 367 'types' => array_keys( $chart_types ),
200 368 ),
201 369 'nonce' => wp_create_nonce(),
202 - 'buildurl' => add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ),
370 + 'buildurl' => esc_url( add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ) ),
203 371 );
204 372
205 373 return $strings;
206 374 }
@@ -213,9 +381,9 @@
213 381 * @static
214 382 * @access private
215 383 * @return array The associated array of chart types with localized names.
216 384 */
217 - public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false, $add_select = false ) {
385 + public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false, $add_select = false, $where = null ) {
218 386 $additional = array();
219 387 if ( $add_select ) {
220 388 $additional['select'] = array(
221 389 'name' => esc_html__( 'All', 'visualizer' ),
@@ -222,59 +390,91 @@
222 390 'enabled' => true,
223 391 );
224 392 }
225 393
394 + $enabled = self::proFeaturesLocked();
395 +
226 396 $types = array_merge(
227 - $additional, array(
397 + $additional,
398 + array(
399 + 'tabular' => array(
400 + 'name' => esc_html__( 'Table', 'visualizer' ),
401 + 'enabled' => true,
402 + 'supports' => $enabled ? array( 'Google Charts', 'DataTable' ) : array( 'DataTable' ),
403 + ),
228 404 'pie' => array(
229 - 'name' => esc_html__( 'Pie', 'visualizer' ),
405 + 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
230 406 'enabled' => true,
407 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
231 408 ),
232 409 'line' => array(
233 410 'name' => esc_html__( 'Line', 'visualizer' ),
234 411 'enabled' => true,
412 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
235 413 ),
414 + 'bar' => array(
415 + 'name' => esc_html__( 'Bar', 'visualizer' ),
416 + 'enabled' => true,
417 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
418 + ),
236 419 'area' => array(
237 420 'name' => esc_html__( 'Area', 'visualizer' ),
238 - 'enabled' => true,
421 + 'enabled' => $enabled,
422 + // in ChartJS, the fill option is used to make Line chart an area: https://www.chartjs.org/docs/latest/charts/area.html
423 + 'supports' => array( 'Google Charts' ),
239 424 ),
240 425 'geo' => array(
241 426 'name' => esc_html__( 'Geo', 'visualizer' ),
242 - 'enabled' => true,
427 + 'enabled' => $enabled,
428 + 'supports' => array( 'Google Charts' ),
243 429 ),
244 - 'bar' => array(
245 - 'name' => esc_html__( 'Bar', 'visualizer' ),
246 - 'enabled' => true,
247 - ),
248 430 'column' => array(
249 431 'name' => esc_html__( 'Column', 'visualizer' ),
250 - 'enabled' => true,
432 + 'enabled' => $enabled,
433 + 'supports' => array( 'Google Charts', 'ChartJS' ),
251 434 ),
252 - 'gauge' => array(
253 - 'name' => esc_html__( 'Gauge', 'visualizer' ),
254 - 'enabled' => true,
435 + 'bubble' => array(
436 + 'name' => esc_html__( 'Bubble', 'visualizer' ),
437 + 'enabled' => $enabled,
438 + // chartjs' bubble is ugly looking (and it won't work off the default bubble.csv) so it is being excluded for the time being.
439 + 'supports' => array( 'Google Charts' ),
255 440 ),
256 441 'scatter' => array(
257 442 'name' => esc_html__( 'Scatter', 'visualizer' ),
258 - 'enabled' => true,
443 + 'enabled' => $enabled,
444 + 'supports' => array( 'Google Charts' ),
259 445 ),
446 + 'gauge' => array(
447 + 'name' => esc_html__( 'Gauge', 'visualizer' ),
448 + 'enabled' => $enabled,
449 + 'supports' => array( 'Google Charts' ),
450 + ),
260 451 'candlestick' => array(
261 452 'name' => esc_html__( 'Candlestick', 'visualizer' ),
262 - 'enabled' => true,
453 + 'enabled' => $enabled,
454 + 'supports' => array( 'Google Charts' ),
263 455 ),
264 456 // pro types
265 - 'table' => array(
266 - 'name' => esc_html__( 'Table', 'visualizer' ),
267 - 'enabled' => false,
268 - ),
269 457 'timeline' => array(
270 458 'name' => esc_html__( 'Timeline', 'visualizer' ),
271 459 'enabled' => false,
460 + 'supports' => array( 'Google Charts', 'ChartJS' ),
272 461 ),
273 462 'combo' => array(
274 463 'name' => esc_html__( 'Combo', 'visualizer' ),
275 464 'enabled' => false,
465 + 'supports' => array( 'Google Charts' ),
276 466 ),
467 + 'polarArea' => array(
468 + 'name' => esc_html__( 'Polar Area', 'visualizer' ),
469 + 'enabled' => false,
470 + 'supports' => array( 'ChartJS' ),
471 + ),
472 + 'radar' => array(
473 + 'name' => esc_html__( 'Radar/Spider', 'visualizer' ),
474 + 'enabled' => false,
475 + 'supports' => array( 'ChartJS' ),
476 + ),
277 477 )
278 478 );
279 479 $types = apply_filters( 'visualizer_pro_chart_types', $types );
280 480 if ( $enabledOnly ) {
@@ -283,8 +483,12 @@
283 483 if ( ! is_array( $array ) ) {
284 484 // support for old pro
285 485 $array = array( 'enabled' => true, 'name' => $array );
286 486 }
487 + // backward compatibility for PRO before v1.9.0
488 + if ( ! array_key_exists( 'supports', $array ) ) {
489 + $array['supports'] = array( 'Google Charts' );
490 + }
287 491 if ( ! $array['enabled'] ) {
288 492 continue;
289 493 }
290 494 $filtered[ $type ] = $array;
@@ -297,13 +501,74 @@
297 501 if ( ! is_array( $array ) ) {
298 502 // support for old pro
299 503 $array = array( 'enabled' => true, 'name' => $array );
300 504 }
505 + // backward compatibility for PRO before v1.9.0
506 + if ( ! array_key_exists( 'supports', $array ) ) {
507 + $array['supports'] = array( 'Google Charts' );
508 + }
301 509 $doubleD[ $type ] = $array['name'];
302 510 }
303 511 $types = $doubleD;
304 512 }
305 513
514 + return self::handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where );
515 + }
516 +
517 + /**
518 + * Handle (soon-to-be) deprecated charts.
519 + */
520 + private static function handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where ) {
521 + $deprecated = array();
522 +
523 + switch ( $where ) {
524 + case 'types':
525 + // fall-through
526 + case 'library':
527 + // if a user has a Gauge/Candlestick chart, then let them keep using it.
528 + if ( ! Visualizer_Module::is_pro() ) {
529 + if ( ! self::hasChartType( 'gauge' ) ) {
530 + if ( $get2Darray ) {
531 + $deprecated[] = 'gauge';
532 + } else {
533 + $types['gauge']['enabled'] = false;
534 + }
535 + }
536 + if ( ! self::hasChartType( 'candlestick' ) ) {
537 + if ( $get2Darray ) {
538 + $deprecated[] = 'candlestick';
539 + } else {
540 + $types['candlestick']['enabled'] = false;
541 + }
542 + }
543 + }
544 + break;
545 + default:
546 + // if a user has a Gauge/Candlestick chart, then let them keep using it.
547 + if ( ! Visualizer_Module::is_pro() ) {
548 + if ( ! self::hasChartType( 'gauge' ) ) {
549 + if ( $get2Darray ) {
550 + $deprecated[] = 'gauge';
551 + } else {
552 + $types['gauge']['enabled'] = false;
553 + }
554 + }
555 + if ( ! self::hasChartType( 'candlestick' ) ) {
556 + if ( $get2Darray ) {
557 + $deprecated[] = 'candlestick';
558 + } else {
559 + $types['candlestick']['enabled'] = false;
560 + }
561 + }
562 + }
563 + }
564 +
565 + if ( $deprecated ) {
566 + foreach ( $deprecated as $type ) {
567 + unset( $types[ $type ] );
568 + }
569 + }
570 +
306 571 return $types;
307 572 }
308 573
309 574 /**
@@ -313,11 +578,11 @@
313 578 * @global string $pagenow The name of the current page.
314 579 *
315 580 * @access public
316 581 */
317 - public function renderTempaltes() {
582 + public function renderTemplates() {
318 583 global $pagenow;
319 - if ( 'post.php' != $pagenow && 'post-new.php' != $pagenow ) {
584 + if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
320 585 return;
321 586 }
322 587 $render = new Visualizer_Render_Templates();
323 588 $render->render();
@@ -335,26 +600,41 @@
335 600 *
336 601 * @param string $suffix The current page suffix.
337 602 */
338 603 public function enqueueLibraryScripts( $suffix ) {
339 - if ( $suffix == $this->_libraryPage ) {
604 + if ( $suffix === $this->_libraryPage ) {
340 605 wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
341 606 $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
342 607 wp_enqueue_media();
343 608 wp_enqueue_script(
344 - 'visualizer-library', VISUALIZER_ABSURL . 'js/library.js', array(
609 + 'visualizer-library',
610 + VISUALIZER_ABSURL . 'js/library.js',
611 + array(
345 612 'jquery',
346 613 'media-views',
347 - ), Visualizer_Plugin::VERSION, true
614 + 'clipboard',
615 + ),
616 + Visualizer_Plugin::VERSION,
617 + true
348 618 );
349 - wp_enqueue_script( 'google-jsapi-new', '//www.gstatic.com/charts/loader.js', array(), null, true );
350 - wp_enqueue_script( 'google-jsapi-old', '//www.google.com/jsapi', array( 'google-jsapi-new' ), null, true );
351 - wp_enqueue_script(
352 - 'visualizer-render', VISUALIZER_ABSURL . 'js/render.js', array(
353 - 'google-jsapi-old',
354 - 'visualizer-library',
355 - ), Visualizer_Plugin::VERSION, true
356 - );
619 +
620 + wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
621 +
622 + $query = $this->getQuery();
623 + while ( $query->have_posts() ) {
624 + $chart = $query->next_post();
625 + $library = $this->load_chart_type( $chart->ID );
626 + if ( is_null( $library ) ) {
627 + continue;
628 + }
629 + wp_enqueue_script(
630 + "visualizer-render-$library",
631 + VISUALIZER_ABSURL . 'js/render-facade.js',
632 + apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
633 + Visualizer_Plugin::VERSION,
634 + true
635 + );
636 + }
357 637 }
358 638 }
359 639
360 640 /**
@@ -381,24 +661,198 @@
381 661 *
382 662 * @access public
383 663 */
384 664 public function registerAdminMenu() {
385 - $title = esc_html__( 'Visualizer Library', 'visualizer' );
386 - $callback = array( $this, 'renderLibraryPage' );
387 - $this->_libraryPage = add_submenu_page( 'upload.php', $title, $title, 'edit_posts', Visualizer_Plugin::NAME, $callback );
665 + $svg_base64_icon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNzdweCIgaGVpZ2h0PSI3N3B4IiB2aWV3Qm94PSIwIDAgNzcgNzciIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjYgKDY3NDkxKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Db21iaW5lZCBTaGFwZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxnIGlkPSJQcm9kdWN0LVBhZ2UiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJXb3JkUHJlc3MtcGx1Z2lucyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE5MC4wMDAwMDAsIC00MzUuMDAwMDAwKSIgZmlsbD0iIzM5QzNEMiI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMjguNSw1MTIgQzIwNy4yMzcwMzcsNTEyIDE5MCw0OTQuNzYyOTYzIDE5MCw0NzMuNSBDMTkwLDQ1Mi4yMzcwMzcgMjA3LjIzNzAzNyw0MzUgMjI4LjUsNDM1IEMyNDkuNzYyOTYzLDQzNSAyNjcsNDUyLjIzNzAzNyAyNjcsNDczLjUgQzI2Nyw0OTQuNzYyOTYzIDI0OS43NjI5NjMsNTEyIDIyOC41LDUxMiBaIE0yNDYuODQzNzUsNDgzLjU5MjA1OSBMMjE1LjYyNSw0ODMuNTkyMDU5IEwyMTUuNjI1LDQ2MC44MjY1NDQgQzIxNS42MjUsNDYwLjE2NDU0NyAyMTUuMTA3NTc4LDQ1OS42MjgzNTkgMjE0LjQ2ODc1LDQ1OS42MjgzNTkgTDIxMi4xNTYyNSw0NTkuNjI4MzU5IEMyMTEuNTE3NDIyLDQ1OS42MjgzNTkgMjExLDQ2MC4xNjQ1NDcgMjExLDQ2MC44MjY1NDQgTDIxMSw0ODUuOTg4NDI5IEMyMTEsNDg3LjMxMTY3NCAyMTIuMDM1NTY2LDQ4OC4zODQ3OTggMjEzLjMxMjUsNDg4LjM4NDc5OCBMMjQ2Ljg0Mzc1LDQ4OC4zODQ3OTggQzI0Ny40ODI1NzgsNDg4LjM4NDc5OCAyNDgsNDg3Ljg0ODYxMSAyNDgsNDg3LjE4NjYxMyBMMjQ4LDQ4NC43OTAyNDQgQzI0OCw0ODQuMTI4MjQ2IDI0Ny40ODI1NzgsNDgzLjU5MjA1OSAyNDYuODQzNzUsNDgzLjU5MjA1OSBaIE0yNDQuNTMxMjUsNDYyLjAyNDcyOSBMMjM1Ljk5OTU3LDQ2Mi4wMjQ3MjkgQzIzNC40NTQ1MzEsNDYyLjAyNDcyOSAyMzMuNjgwNTY2LDQ2My45NjA1NDcgMjM0Ljc3MzIyMyw0NjUuMDkyODMyIEwyMzcuMTE0NjI5LDQ2Ny41MTkxNTYgTDIzMS44MTI1LDQ3My4wMTQzMzIgTDIyNi41MTAzNzEsNDY3LjUxOTkwNSBDMjI1LjYwNzA1MSw0NjYuNTgzODIzIDIyNC4xNDI5NDksNDY2LjU4MzgyMyAyMjMuMjQwMzUyLDQ2Ny41MTk5MDUgTDIxOC4yNzY0MjYsNDcyLjY2Mzg2MyBDMjE3LjgyNDc2Niw0NzMuMTMxOTA0IDIxNy44MjQ3NjYsNDczLjg5MDUwNSAyMTguMjc2NDI2LDQ3NC4zNTg1NDYgTDIxOS45MTEwNzQsNDc2LjA1MjQ4IEMyMjAuMzYyNzM0LDQ3Ni41MjA1MjEgMjIxLjA5NDc4NSw0NzYuNTIwNTIxIDIyMS41NDY0NDUsNDc2LjA1MjQ4IEwyMjQuODc1LDQ3Mi42MDI0NTYgTDIzMC4xNzcxMjksNDc4LjA5Njg4MyBDMjMxLjA4MDQ0OSw0NzkuMDMyOTY1IDIzMi41NDQ1NTEsNDc5LjAzMjk2NSAyMzMuNDQ3MTQ4LDQ3OC4wOTY4ODMgTDI0MC4zODQ2NDgsNDcwLjkwNzc3MyBMMjQyLjcyNjA1NSw0NzMuMzM0MDk4IEMyNDMuODE4NzExLDQ3NC40NjYzODIgMjQ1LjY4Njc3Nyw0NzMuNjY0MzQ3IDI0NS42ODY3NzcsNDcyLjA2MzI3MyBMMjQ1LjY4Njc3Nyw0NjMuMjIyOTE0IEMyNDUuNjg3NSw0NjIuNTYwOTE3IDI0NS4xNzAwNzgsNDYyLjAyNDcyOSAyNDQuNTMxMjUsNDYyLjAyNDcyOSBaIiBpZD0iQ29tYmluZWQtU2hhcGUiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==';
666 +
667 + $this->_libraryPage = add_menu_page( __( 'Visualizer', 'visualizer' ), __( 'Visualizer', 'visualizer' ), 'edit_posts', Visualizer_Plugin::NAME, array( $this, 'renderLibraryPage' ), $svg_base64_icon, 99.7666 );
668 +
669 + add_submenu_page(
670 + Visualizer_Plugin::NAME,
671 + __( 'Chart Library', 'visualizer' ),
672 + __( 'Chart Library', 'visualizer' ),
673 + 'edit_posts',
674 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME )
675 + );
676 + add_submenu_page(
677 + Visualizer_Plugin::NAME,
678 + __( 'Add New Chart', 'visualizer' ),
679 + __( 'Add New Chart', 'visualizer' ),
680 + 'edit_posts',
681 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew' )
682 + );
683 + add_submenu_page(
684 + Visualizer_Plugin::NAME,
685 + __( 'Support', 'visualizer' ),
686 + __( '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>',
687 + 'edit_posts',
688 + 'viz-support',
689 + array( $this, 'renderSupportPage' )
690 + );
691 +
692 + if ( ! Visualizer_Module::is_pro() ) {
693 + add_submenu_page(
694 + Visualizer_Plugin::NAME,
695 + __( 'Get Visualizer Pro', 'visualizer' ),
696 + __( 'Get Visualizer Pro', 'visualizer' ),
697 + 'edit_posts',
698 + 'viz-get-pro',
699 + '__return_null'
700 + );
701 + add_action( 'admin_footer', array( $this, 'handleGetProSubMenu' ) );
702 + }
703 + remove_submenu_page( Visualizer_Plugin::NAME, Visualizer_Plugin::NAME );
704 +
705 + add_action( "load-{$this->_libraryPage}", array( $this, 'addScreenOptions' ) );
388 706 }
389 707
390 708 /**
391 - * Renders visualizer library page.
392 - *
393 - * @since 1.0.0
394 - *
395 - * @access public
709 + * Handle get pro plugin submenu.
396 710 */
397 - public function renderLibraryPage() {
711 + public function handleGetProSubMenu() {
712 + ?>
713 + <style type="text/css">
714 + #toplevel_page_visualizer ul.wp-submenu li.wp-first-item + li + li + li {
715 + background: #FF7E65;
716 + font-size: 14px;
717 + font-weight: 600;
718 + color: #fff;
719 + }
720 + #toplevel_page_visualizer ul.wp-submenu li.wp-first-item + li + li + li > a {
721 + color: #fff !important;
722 + }
723 + #toplevel_page_visualizer ul.wp-submenu li.wp-first-item + li + li + li > a:hover {
724 + box-shadow: inherit;
725 + }
726 + </style>
727 + <script type="text/javascript">
728 + jQuery( document ).ready( function() {
729 + jQuery( '#toplevel_page_visualizer' ).on( 'click', 'li:not(.wp-submenu-head, .wp-first-item):eq(2)', function( e ) {
730 + e.preventDefault();
731 + window.open( '<?php echo tsdk_utmify( 'https://themeisle.com/plugins/visualizer-charts-and-graphs/upgrade/', 'toplevel' ); ?>', '_blank' );
732 + } );
733 + } );
734 + </script>
735 + <?php
736 + }
737 +
738 + /**
739 + * Adds the screen options for pagination.
740 + */
741 + function addScreenOptions() {
742 + $screen = get_current_screen();
743 +
744 + // bail if it's some other page.
745 + if ( ! is_object( $screen ) || $screen->id !== $this->_libraryPage ) {
746 + return;
747 + }
748 +
749 + $args = array(
750 + 'label' => __( 'Number of charts per page:', 'visualizer' ),
751 + 'default' => 6,
752 + 'option' => 'visualizer_library_per_page',
753 + );
754 + add_screen_option( 'per_page', $args );
755 + }
756 +
757 + /**
758 + * Returns the screen option for pagination.
759 + */
760 + function setScreenOptions( $status, $option, $value ) {
761 + if ( 'visualizer_library_per_page' === $option ) {
762 + return $value;
763 + }
764 + }
765 +
766 + /**
767 + * Adds the display filters to be used in the meta_query while displaying the charts.
768 + */
769 + private function getDisplayFilters( &$query_args ) {
770 + $query = array();
771 + global $sitepress;
772 + if ( Visualizer_Module::is_pro() && ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) ) {
773 + $current_lang = icl_get_current_language();
774 + if ( in_array( $current_lang, array( 'all', icl_get_default_language() ), true ) ) {
775 + $query[] = array(
776 + 'key' => 'chart_lang',
777 + 'compare' => 'NOT EXISTS',
778 + );
779 + } else {
780 + $query[] = array(
781 + 'key' => 'chart_lang',
782 + 'value' => $current_lang,
783 + 'compare' => '=',
784 + );
785 + }
786 + }
787 +
788 + // add chart type filter to the query arguments
789 + $type = filter_input( INPUT_GET, 'type' );
790 + if ( $type && in_array( $type, Visualizer_Plugin::getChartTypes(), true ) ) {
791 + $query[] = array(
792 + 'key' => Visualizer_Plugin::CF_CHART_TYPE,
793 + 'value' => $type,
794 + 'compare' => '=',
795 + );
796 + }
797 +
798 + // add chart library filter to the query arguments
799 + $library = filter_input( INPUT_GET, 'library' );
800 + if ( $library ) {
801 + $query[] = array(
802 + 'key' => Visualizer_Plugin::CF_CHART_LIBRARY,
803 + 'value' => $library,
804 + 'compare' => '=',
805 + );
806 + }
807 +
808 + // add date filter to the query arguments
809 + $date = filter_input( INPUT_GET, 'date' );
810 + $possible = array_keys( Visualizer_Plugin::getSupportedDateFilter() );
811 + if ( $date && in_array( $date, $possible, true ) ) {
812 + $query_args['date_query'] = array(
813 + 'after' => "$date -1 day",
814 + 'inclusive' => true,
815 + );
816 + }
817 +
818 + // add source filter to the query arguments
819 + $source = filter_input( INPUT_GET, 'source' );
820 + if ( $source ) {
821 + $source = ucwords( $source );
822 + $source = "Visualizer_Source_{$source}";
823 + $query[] = array(
824 + 'key' => Visualizer_Plugin::CF_SOURCE,
825 + 'value' => $source,
826 + 'compare' => '=',
827 + );
828 + }
829 +
830 + $query_args['meta_query'] = $query;
831 +
832 + $orderby = filter_input( INPUT_GET, 'orderby' );
833 + $order = filter_input( INPUT_GET, 'order' );
834 + if ( $orderby ) {
835 + $query_args['order_by'] = $orderby;
836 + }
837 + $query_args['order'] = empty( $order ) ? 'desc' : $order;
838 + }
839 +
840 + /**
841 + * Get the instance of WP_Query that fetches the charts as per the given criteria.
842 + */
843 + private function getQuery() {
844 + static $q;
845 + if ( ! is_null( $q ) ) {
846 + return $q;
847 + }
848 +
398 849 // get current page
399 850 $page = filter_input(
400 - INPUT_GET, 'vpage', FILTER_VALIDATE_INT, array(
851 + INPUT_GET,
852 + 'vpage',
853 + FILTER_VALIDATE_INT,
854 + array(
401 855 'options' => array(
402 856 'min_range' => 1,
403 857 'default' => 1,
404 858 ),
@@ -403,27 +857,32 @@
403 857 'default' => 1,
404 858 ),
405 859 )
406 860 );
861 +
862 + $per_page = 6;
863 + $screen = get_current_screen();
864 + if ( $screen ) {
865 + // retrieve the per_page option
866 + $screen_option = $screen->get_option( 'per_page', 'option' );
867 + // retrieve the value stored for the current user
868 + $user = get_current_user_id();
869 + $per_page = get_user_meta( $user, $screen_option, true );
870 + if ( empty( $per_page ) || $per_page < 1 ) {
871 + // nothing set, get the default value
872 + $per_page = $screen->get_option( 'per_page', 'default' );
873 + }
874 + }
875 +
407 876 // the initial query arguments to fetch charts
408 877 $query_args = array(
409 878 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
410 - 'posts_per_page' => 6,
879 + 'posts_per_page' => $per_page,
411 880 'paged' => $page,
412 881 );
413 - // add chart type filter to the query arguments
414 - $filter = filter_input( INPUT_GET, 'type' );
415 - if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) {
416 - $query_args['meta_query'] = array(
417 - array(
418 - 'key' => Visualizer_Plugin::CF_CHART_TYPE,
419 - 'value' => $filter,
420 - 'compare' => '=',
421 - ),
422 - );
423 - } else {
424 - $filter = 'all';
425 - }
882 +
883 + $this->getDisplayFilters( $query_args );
884 +
426 885 // Added by Ash/Upwork
427 886 $filterByMeta = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
428 887 if ( $filterByMeta ) {
429 888 $query = array(
@@ -434,51 +893,157 @@
434 893 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
435 894 $meta[] = $query;
436 895 $query_args['meta_query'] = $meta;
437 896 }
438 - // Added by Ash/Upwork
439 - // fetch charts
897 + $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
898 + return $q;
899 + }
900 +
901 + /**
902 + * Renders support page.
903 + *
904 + * @since 3.3.0
905 + *
906 + * @access public
907 + */
908 + public function renderSupportPage() {
909 + wp_enqueue_style( 'visualizer-upsell', VISUALIZER_ABSURL . 'css/upsell.css', array(), Visualizer_Plugin::VERSION );
910 + include_once VISUALIZER_ABSPATH . '/templates/support.php';
911 + }
912 +
913 + /**
914 + * Renders visualizer library page.
915 + *
916 + * @since 1.0.0
917 + *
918 + * @access public
919 + */
920 + public function renderLibraryPage() {
440 921 $charts = array();
441 - $query = new WP_Query( $query_args );
922 + $query = $this->getQuery();
923 +
924 + // get current page
925 + $page = filter_input(
926 + INPUT_GET,
927 + 'vpage',
928 + FILTER_VALIDATE_INT,
929 + array(
930 + 'options' => array(
931 + 'min_range' => 1,
932 + 'default' => 1,
933 + ),
934 + )
935 + );
936 + // add chart type filter to the query arguments
937 + $filter = filter_input( INPUT_GET, 'type' );
938 + if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) ) {
939 + $filter = 'all';
940 + }
941 +
942 + $css = '';
442 943 while ( $query->have_posts() ) {
443 944 $chart = $query->next_post();
945 +
946 + // 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.
947 + $chart = $this->handleExistingRevisions( $chart->ID, $chart );
948 + // refresh a "live" db query chart.
949 + $chart = apply_filters( 'visualizer_schedule_refresh_chart', $chart, $chart->ID, false );
950 +
951 + $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
952 +
444 953 // fetch and update settings
445 954 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
446 - unset( $settings['height'], $settings['width'] );
447 - $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
955 +
956 + $settings = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $settings, $chart->ID, $type );
957 + if ( ! empty( $atts['settings'] ) ) {
958 + $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
959 + }
960 +
961 + if ( $settings ) {
962 + unset( $settings['height'], $settings['width'], $settings['chartArea'] );
963 + }
964 +
448 965 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
449 - $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( $chart->post_content ) ), $chart->ID, $type );
966 + $data = self::get_chart_data( $chart, $type );
967 +
968 + // Set default setting series when add manual chart data - Only during first creation.
969 + if ( isset( $settings['series'] ) && ! empty( $series ) ) {
970 + $count_series = count( $series ) - count( $settings['series'] );
971 + if ( $count_series > 1 ) {
972 + $clone_last_series = end( $settings['series'] );
973 + $clone_last_series = array_fill_keys( array_keys( $clone_last_series ), '' );
974 + foreach ( range( 1, $count_series ) as $item ) {
975 + $settings['series'][] = $clone_last_series;
976 + }
977 + }
978 + }
979 +
980 + $library = $this->load_chart_type( $chart->ID );
981 +
982 + $id = 'visualizer-' . $chart->ID;
983 + $arguments = $this->get_inline_custom_css( $id, $settings );
984 + if ( ! empty( $arguments ) ) {
985 + $css .= $arguments[0];
986 + $settings = $arguments[1];
987 + }
988 +
989 + if ( isset( $settings['controls']['ui']['labelStacking'] ) ) {
990 + unset( $settings['controls']['ui']['labelStacking'] );
991 + }
992 + if ( isset( $settings['controls']['ui']['orientation'] ) ) {
993 + unset( $settings['controls']['ui']['orientation'] );
994 + }
995 +
450 996 // add chart to the array
451 - $charts[ 'visualizer-' . $chart->ID ] = array(
997 + $charts[ $id ] = array(
452 998 'id' => $chart->ID,
453 999 'type' => $type,
454 1000 'series' => $series,
455 1001 'settings' => $settings,
456 1002 'data' => $data,
1003 + 'library' => $library,
457 1004 );
458 1005 }
459 1006 // enqueue charts array
460 1007 $ajaxurl = admin_url( 'admin-ajax.php' );
461 1008 wp_localize_script(
462 - 'visualizer-library', 'visualizer', array(
1009 + 'visualizer-library',
1010 + 'visualizer',
1011 + array(
463 1012 'language' => $this->get_language(),
464 1013 'map_api_key' => get_option( 'visualizer-map-api-key' ),
465 1014 'charts' => $charts,
466 1015 'urls' => array(
467 - 'base' => add_query_arg( 'vpage', false ),
468 - 'create' => add_query_arg(
469 - array(
470 - 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
471 - 'library' => 'yes',
472 - ), $ajaxurl
1016 + 'base' => esc_url( add_query_arg( array( 'vpage' => false, 'vaction' => false ) ) ),
1017 + 'create' => esc_url(
1018 + add_query_arg(
1019 + array(
1020 + 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
1021 + 'library' => 'yes',
1022 + 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
1023 + 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
1024 + 'vaction' => false,
1025 + ),
1026 + $ajaxurl
1027 + )
473 1028 ),
474 - 'edit' => add_query_arg(
475 - array(
476 - 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
477 - 'library' => 'yes',
478 - ), $ajaxurl
1029 + 'edit' => esc_url(
1030 + add_query_arg(
1031 + array(
1032 + 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
1033 + 'library' => 'yes',
1034 + 'vaction' => false,
1035 + ),
1036 + $ajaxurl
1037 + )
479 1038 ),
480 1039 ),
1040 + 'page_type' => 'library',
1041 + 'is_front' => false,
1042 + 'i10n' => array(
1043 + 'copied' => __( 'The shortcode has been copied to your clipboard. Hit Ctrl-V/Cmd-V to paste it.', 'visualizer' ),
1044 + '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' ),
1045 + ),
481 1046 )
482 1047 );
483 1048 // render library page
484 1049 $render = new Visualizer_Render_Library();
@@ -483,12 +1048,13 @@
483 1048 // render library page
484 1049 $render = new Visualizer_Render_Library();
485 1050 $render->charts = $charts;
486 1051 $render->type = $filter;
487 - $render->types = self::_getChartTypesLocalized();
1052 + $render->types = self::_getChartTypesLocalized( false, false, false, true );
1053 + $render->custom_css = $css;
488 1054 $render->pagination = paginate_links(
489 1055 array(
490 - 'base' => add_query_arg( 'vpage', '%#%' ),
1056 + 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
491 1057 'format' => '',
492 1058 'current' => $page,
493 1059 'total' => $query->max_num_pages,
494 1060 'type' => 'array',
@@ -509,14 +1075,14 @@
509 1075 *
510 1076 * @return array Updated array of action links.
511 1077 */
512 1078 public function getPluginActionLinks( $links, $file ) {
513 - if ( $file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1079 + if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
514 1080 array_unshift(
515 1081 $links,
516 1082 sprintf(
517 1083 '<a href="%s">%s</a>',
518 - admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ),
1084 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
519 1085 esc_html__( 'Library', 'visualizer' )
520 1086 )
521 1087 );
522 1088 }
@@ -536,17 +1102,17 @@
536 1102 *
537 1103 * @return array Updated array of plugin meta links.
538 1104 */
539 1105 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
540 - if ( $plugin_file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1106 + if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
541 1107 // knowledge base link
542 1108 $plugin_meta[] = sprintf(
543 - '<a href="https://github.com/codeinwp/visualizer/wiki" target="_blank">%s</a>',
544 - esc_html__( 'Knowledge Base', 'visualizer' )
1109 + '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1110 + esc_html__( 'Docs', 'visualizer' )
545 1111 );
546 1112 // flattr link
547 1113 $plugin_meta[] = sprintf(
548 - '<a style="color:red" href="https://themeisle.com/plugins/visualizer-charts-and-graphs-pro-addon/" target="_blank">%s</a>',
1114 + '<a style="color:red" href="' . tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'pluginrow' ) . '" target="_blank">%s</a>',
549 1115 esc_html__( 'Pro Addon', 'visualizer' )
550 1116 );
551 1117 }
552 1118
@@ -552,5 +1118,60 @@
552 1118
553 1119 return $plugin_meta;
554 1120 }
555 1121
1122 + /**
1123 + * If check is existing user.
1124 + *
1125 + * @return bool Default false
1126 + */
1127 + public static function proFeaturesLocked() {
1128 + if ( Visualizer_Module::is_pro() ) {
1129 + return true;
1130 + }
1131 + return 'yes' === get_option( 'visualizer-new-user', 'yes' ) ? false : true;
1132 + }
1133 +
1134 + /**
1135 + * Multilingual Support.
1136 + *
1137 + * @param int $chart_id Chart ID.
1138 + * @return bool Default false
1139 + */
1140 + public function addMultilingualSupport( $chart_id ) {
1141 + global $sitepress;
1142 + if ( Visualizer_Module::is_pro() ) {
1143 + return;
1144 + }
1145 + if ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) {
1146 + $language = icl_get_languages();
1147 + $current_lang = icl_get_current_language();
1148 + $default_lang = icl_get_default_language();
1149 + $post_info = wpml_get_language_information( null, $chart_id );
1150 + $translations = array();
1151 + if ( ! empty( $post_info ) && ( $default_lang === $post_info['language_code'] ) ) {
1152 + $trid = $sitepress->get_element_trid( $chart_id, 'post_' . Visualizer_Plugin::CPT_VISUALIZER );
1153 + $translations = $sitepress->get_element_translations( $trid );
1154 + }
1155 + if ( empty( $translations ) ) {
1156 + return;
1157 + }
1158 + ?>
1159 + <hr><div class="visualizer-languages-list only-pro">
1160 + <?php
1161 + foreach ( $language as $lang ) {
1162 + $lang_code = $lang['code'];
1163 + if ( $current_lang !== $lang_code ) {
1164 + ?>
1165 + <a href="javascript:;">
1166 + <img src="<?php echo esc_url( $lang['country_flag_url'] ); ?>" alt="<?php echo esc_attr( $lang['translated_name'] ); ?>">
1167 + </a>
1168 + <?php
1169 + }
1170 + }
1171 + ?>
1172 + <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>
1173 + </div>
1174 + <?php
1175 + }
1176 + }
556 1177 }