PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.10.8
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.10.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 3.10.4 All 148 releases
← All changes | classes/Visualizer/Module/Admin.php +804 -91 3.0.63.10.8 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,14 +311,28 @@
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 );
326 + wp_localize_script(
327 + 'visualizer-media-view',
328 + 'visualizer',
329 + array(
330 + 'i10n' => array(
331 + 'insert' => __( 'Insert', 'visualizer' ),
332 + ),
333 + )
334 + );
160 335 wp_enqueue_script( 'visualizer-media-toolbar', VISUALIZER_ABSURL . 'js/media/toolbar.js', array( 'visualizer-media-view' ), Visualizer_Plugin::VERSION, true );
161 336 wp_enqueue_script( 'visualizer-media', VISUALIZER_ABSURL . 'js/media.js', array( 'visualizer-media-toolbar' ), Visualizer_Plugin::VERSION, true );
162 337 }
163 338 }
@@ -191,9 +366,9 @@
191 366 'filters' => $chart_types,
192 367 'types' => array_keys( $chart_types ),
193 368 ),
194 369 'nonce' => wp_create_nonce(),
195 - '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' ) ) ),
196 371 );
197 372
198 373 return $strings;
199 374 }
@@ -206,9 +381,9 @@
206 381 * @static
207 382 * @access private
208 383 * @return array The associated array of chart types with localized names.
209 384 */
210 - 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 ) {
211 386 $additional = array();
212 387 if ( $add_select ) {
213 388 $additional['select'] = array(
214 389 'name' => esc_html__( 'All', 'visualizer' ),
@@ -215,59 +390,91 @@
215 390 'enabled' => true,
216 391 );
217 392 }
218 393
394 + $enabled = self::proFeaturesLocked();
395 +
219 396 $types = array_merge(
220 - $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 + ),
221 404 'pie' => array(
222 - 'name' => esc_html__( 'Pie', 'visualizer' ),
405 + 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
223 406 'enabled' => true,
407 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
224 408 ),
225 409 'line' => array(
226 410 'name' => esc_html__( 'Line', 'visualizer' ),
227 411 'enabled' => true,
412 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
228 413 ),
414 + 'bar' => array(
415 + 'name' => esc_html__( 'Bar', 'visualizer' ),
416 + 'enabled' => true,
417 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
418 + ),
229 419 'area' => array(
230 420 'name' => esc_html__( 'Area', 'visualizer' ),
231 - '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' ),
232 424 ),
233 425 'geo' => array(
234 426 'name' => esc_html__( 'Geo', 'visualizer' ),
235 - 'enabled' => true,
427 + 'enabled' => $enabled,
428 + 'supports' => array( 'Google Charts' ),
236 429 ),
237 - 'bar' => array(
238 - 'name' => esc_html__( 'Bar', 'visualizer' ),
239 - 'enabled' => true,
240 - ),
241 430 'column' => array(
242 431 'name' => esc_html__( 'Column', 'visualizer' ),
243 - 'enabled' => true,
432 + 'enabled' => $enabled,
433 + 'supports' => array( 'Google Charts', 'ChartJS' ),
244 434 ),
245 - 'gauge' => array(
246 - 'name' => esc_html__( 'Gauge', 'visualizer' ),
247 - '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' ),
248 440 ),
249 441 'scatter' => array(
250 442 'name' => esc_html__( 'Scatter', 'visualizer' ),
251 - 'enabled' => true,
443 + 'enabled' => $enabled,
444 + 'supports' => array( 'Google Charts' ),
252 445 ),
446 + 'gauge' => array(
447 + 'name' => esc_html__( 'Gauge', 'visualizer' ),
448 + 'enabled' => $enabled,
449 + 'supports' => array( 'Google Charts' ),
450 + ),
253 451 'candlestick' => array(
254 452 'name' => esc_html__( 'Candlestick', 'visualizer' ),
255 - 'enabled' => true,
453 + 'enabled' => $enabled,
454 + 'supports' => array( 'Google Charts' ),
256 455 ),
257 456 // pro types
258 - 'table' => array(
259 - 'name' => esc_html__( 'Table', 'visualizer' ),
260 - 'enabled' => false,
261 - ),
262 457 'timeline' => array(
263 458 'name' => esc_html__( 'Timeline', 'visualizer' ),
264 459 'enabled' => false,
460 + 'supports' => array( 'Google Charts', 'ChartJS' ),
265 461 ),
266 462 'combo' => array(
267 463 'name' => esc_html__( 'Combo', 'visualizer' ),
268 464 'enabled' => false,
465 + 'supports' => array( 'Google Charts' ),
269 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 + ),
270 477 )
271 478 );
272 479 $types = apply_filters( 'visualizer_pro_chart_types', $types );
273 480 if ( $enabledOnly ) {
@@ -276,8 +483,12 @@
276 483 if ( ! is_array( $array ) ) {
277 484 // support for old pro
278 485 $array = array( 'enabled' => true, 'name' => $array );
279 486 }
487 + // backward compatibility for PRO before v1.9.0
488 + if ( ! array_key_exists( 'supports', $array ) ) {
489 + $array['supports'] = array( 'Google Charts' );
490 + }
280 491 if ( ! $array['enabled'] ) {
281 492 continue;
282 493 }
283 494 $filtered[ $type ] = $array;
@@ -290,13 +501,74 @@
290 501 if ( ! is_array( $array ) ) {
291 502 // support for old pro
292 503 $array = array( 'enabled' => true, 'name' => $array );
293 504 }
505 + // backward compatibility for PRO before v1.9.0
506 + if ( ! array_key_exists( 'supports', $array ) ) {
507 + $array['supports'] = array( 'Google Charts' );
508 + }
294 509 $doubleD[ $type ] = $array['name'];
295 510 }
296 511 $types = $doubleD;
297 512 }
298 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 +
299 571 return $types;
300 572 }
301 573
302 574 /**
@@ -306,11 +578,11 @@
306 578 * @global string $pagenow The name of the current page.
307 579 *
308 580 * @access public
309 581 */
310 - public function renderTempaltes() {
582 + public function renderTemplates() {
311 583 global $pagenow;
312 - if ( 'post.php' != $pagenow && 'post-new.php' != $pagenow ) {
584 + if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
313 585 return;
314 586 }
315 587 $render = new Visualizer_Render_Templates();
316 588 $render->render();
@@ -328,26 +600,41 @@
328 600 *
329 601 * @param string $suffix The current page suffix.
330 602 */
331 603 public function enqueueLibraryScripts( $suffix ) {
332 - if ( $suffix == $this->_libraryPage ) {
604 + if ( $suffix === $this->_libraryPage ) {
333 605 wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
334 606 $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
335 607 wp_enqueue_media();
336 608 wp_enqueue_script(
337 - 'visualizer-library', VISUALIZER_ABSURL . 'js/library.js', array(
609 + 'visualizer-library',
610 + VISUALIZER_ABSURL . 'js/library.js',
611 + array(
338 612 'jquery',
339 613 'media-views',
340 - ), Visualizer_Plugin::VERSION, true
614 + 'clipboard',
615 + ),
616 + Visualizer_Plugin::VERSION,
617 + true
341 618 );
342 - wp_enqueue_script( 'google-jsapi-new', '//www.gstatic.com/charts/loader.js', array(), null, true );
343 - wp_enqueue_script( 'google-jsapi-old', '//www.google.com/jsapi', array( 'google-jsapi-new' ), null, true );
344 - wp_enqueue_script(
345 - 'visualizer-render', VISUALIZER_ABSURL . 'js/render.js', array(
346 - 'google-jsapi-old',
347 - 'visualizer-library',
348 - ), Visualizer_Plugin::VERSION, true
349 - );
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 + }
350 637 }
351 638 }
352 639
353 640 /**
@@ -374,24 +661,191 @@
374 661 *
375 662 * @access public
376 663 */
377 664 public function registerAdminMenu() {
378 - $title = esc_html__( 'Visualizer Library', 'visualizer' );
379 - $callback = array( $this, 'renderLibraryPage' );
380 - $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.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.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 + remove_submenu_page( Visualizer_Plugin::NAME, Visualizer_Plugin::NAME );
693 +
694 + add_action( "load-{$this->_libraryPage}", array( $this, 'addScreenOptions' ) );
695 + add_action( 'admin_footer', array( $this, 'handleGetProSubMenu' ) );
381 696 }
382 697
383 698 /**
384 - * Renders visualizer library page.
385 - *
386 - * @since 1.0.0
387 - *
388 - * @access public
699 + * Handle get pro plugin submenu.
389 700 */
390 - public function renderLibraryPage() {
701 + public function handleGetProSubMenu() {
702 + if ( ! Visualizer_Module::is_pro() ) {
703 + ?>
704 + <style type="text/css">
705 + #toplevel_page_visualizer ul.wp-submenu li:last-child {
706 + background: #FF7E65;
707 + font-size: 14px;
708 + font-weight: 600;
709 + color: #fff;
710 + }
711 + #toplevel_page_visualizer ul.wp-submenu li:last-child > a {
712 + color: #fff !important;
713 + }
714 + #toplevel_page_visualizer ul.wp-submenu li:last-child > a:hover {
715 + box-shadow: inherit;
716 + }
717 + </style>
718 + <?php
719 + if ( get_option( 'visualizer_fresh_install', false ) ) {
720 + ?>
721 + <style type="text/css">
722 + #toplevel_page_visualizer ul.wp-submenu li.wp-first-item + li + li + li {
723 + display: none;
724 + }
725 + </style>
726 + <?php
727 + }
728 + }
729 + }
730 +
731 + /**
732 + * Adds the screen options for pagination.
733 + */
734 + function addScreenOptions() {
735 + $screen = get_current_screen();
736 +
737 + // bail if it's some other page.
738 + if ( ! is_object( $screen ) || $screen->id !== $this->_libraryPage ) {
739 + return;
740 + }
741 +
742 + $args = array(
743 + 'label' => __( 'Number of charts per page:', 'visualizer' ),
744 + 'default' => 6,
745 + 'option' => 'visualizer_library_per_page',
746 + );
747 + add_screen_option( 'per_page', $args );
748 + }
749 +
750 + /**
751 + * Returns the screen option for pagination.
752 + */
753 + function setScreenOptions( $status, $option, $value ) {
754 + if ( 'visualizer_library_per_page' === $option ) {
755 + return $value;
756 + }
757 + }
758 +
759 + /**
760 + * Adds the display filters to be used in the meta_query while displaying the charts.
761 + */
762 + private function getDisplayFilters( &$query_args ) {
763 + $query = array();
764 + global $sitepress;
765 + if ( Visualizer_Module::is_pro() && ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) ) {
766 + $current_lang = icl_get_current_language();
767 + if ( in_array( $current_lang, array( 'all', icl_get_default_language() ), true ) ) {
768 + $query[] = array(
769 + 'key' => 'chart_lang',
770 + 'compare' => 'NOT EXISTS',
771 + );
772 + } else {
773 + $query[] = array(
774 + 'key' => 'chart_lang',
775 + 'value' => $current_lang,
776 + 'compare' => '=',
777 + );
778 + }
779 + }
780 +
781 + // add chart type filter to the query arguments
782 + $type = filter_input( INPUT_GET, 'type' );
783 + if ( $type && in_array( $type, Visualizer_Plugin::getChartTypes(), true ) ) {
784 + $query[] = array(
785 + 'key' => Visualizer_Plugin::CF_CHART_TYPE,
786 + 'value' => $type,
787 + 'compare' => '=',
788 + );
789 + }
790 +
791 + // add chart library filter to the query arguments
792 + $library = filter_input( INPUT_GET, 'library' );
793 + if ( $library ) {
794 + $query[] = array(
795 + 'key' => Visualizer_Plugin::CF_CHART_LIBRARY,
796 + 'value' => $library,
797 + 'compare' => '=',
798 + );
799 + }
800 +
801 + // add date filter to the query arguments
802 + $date = filter_input( INPUT_GET, 'date' );
803 + $possible = array_keys( Visualizer_Plugin::getSupportedDateFilter() );
804 + if ( $date && in_array( $date, $possible, true ) ) {
805 + $query_args['date_query'] = array(
806 + 'after' => "$date -1 day",
807 + 'inclusive' => true,
808 + );
809 + }
810 +
811 + // add source filter to the query arguments
812 + $source = filter_input( INPUT_GET, 'source' );
813 + if ( $source ) {
814 + $source = ucwords( $source );
815 + $source = "Visualizer_Source_{$source}";
816 + $query[] = array(
817 + 'key' => Visualizer_Plugin::CF_SOURCE,
818 + 'value' => $source,
819 + 'compare' => '=',
820 + );
821 + }
822 +
823 + $query_args['meta_query'] = $query;
824 +
825 + $orderby = filter_input( INPUT_GET, 'orderby' );
826 + $order = filter_input( INPUT_GET, 'order' );
827 + if ( $orderby ) {
828 + $query_args['order_by'] = $orderby;
829 + }
830 + $query_args['order'] = empty( $order ) ? 'desc' : $order;
831 + }
832 +
833 + /**
834 + * Get the instance of WP_Query that fetches the charts as per the given criteria.
835 + */
836 + private function getQuery() {
837 + static $q;
838 + if ( ! is_null( $q ) ) {
839 + return $q;
840 + }
841 +
391 842 // get current page
392 843 $page = filter_input(
393 - INPUT_GET, 'vpage', FILTER_VALIDATE_INT, array(
844 + INPUT_GET,
845 + 'vpage',
846 + FILTER_VALIDATE_INT,
847 + array(
394 848 'options' => array(
395 849 'min_range' => 1,
396 850 'default' => 1,
397 851 ),
@@ -396,29 +850,34 @@
396 850 'default' => 1,
397 851 ),
398 852 )
399 853 );
854 +
855 + $per_page = 6;
856 + $screen = get_current_screen();
857 + if ( $screen ) {
858 + // retrieve the per_page option
859 + $screen_option = $screen->get_option( 'per_page', 'option' );
860 + // retrieve the value stored for the current user
861 + $user = get_current_user_id();
862 + $per_page = get_user_meta( $user, $screen_option, true );
863 + if ( empty( $per_page ) || $per_page < 1 ) {
864 + // nothing set, get the default value
865 + $per_page = $screen->get_option( 'per_page', 'default' );
866 + }
867 + }
868 +
400 869 // the initial query arguments to fetch charts
401 870 $query_args = array(
402 871 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
403 - 'posts_per_page' => 6,
872 + 'posts_per_page' => $per_page,
404 873 'paged' => $page,
405 874 );
406 - // add chart type filter to the query arguments
407 - $filter = filter_input( INPUT_GET, 'type' );
408 - if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) {
409 - $query_args['meta_query'] = array(
410 - array(
411 - 'key' => Visualizer_Plugin::CF_CHART_TYPE,
412 - 'value' => $filter,
413 - 'compare' => '=',
414 - ),
415 - );
416 - } else {
417 - $filter = 'all';
418 - }
875 +
876 + $this->getDisplayFilters( $query_args );
877 +
419 878 // Added by Ash/Upwork
420 - $filterByMeta = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
879 + $filterByMeta = ! empty( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
421 880 if ( $filterByMeta ) {
422 881 $query = array(
423 882 'key' => Visualizer_Plugin::CF_SETTINGS,
424 883 'value' => $filterByMeta,
@@ -427,49 +886,158 @@
427 886 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
428 887 $meta[] = $query;
429 888 $query_args['meta_query'] = $meta;
430 889 }
431 - // Added by Ash/Upwork
432 - // fetch charts
890 + $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
891 + return $q;
892 + }
893 +
894 + /**
895 + * Renders support page.
896 + *
897 + * @since 3.3.0
898 + *
899 + * @access public
900 + */
901 + public function renderSupportPage() {
902 + wp_enqueue_style( 'visualizer-upsell', VISUALIZER_ABSURL . 'css/upsell.css', array(), Visualizer_Plugin::VERSION );
903 + $this->load_survey();
904 + include_once VISUALIZER_ABSPATH . '/templates/support.php';
905 + }
906 +
907 + /**
908 + * Renders visualizer library page.
909 + *
910 + * @since 1.0.0
911 + *
912 + * @access public
913 + */
914 + public function renderLibraryPage() {
433 915 $charts = array();
434 - $query = new WP_Query( $query_args );
916 + $query = $this->getQuery();
917 +
918 + // get current page
919 + $page = filter_input(
920 + INPUT_GET,
921 + 'vpage',
922 + FILTER_VALIDATE_INT,
923 + array(
924 + 'options' => array(
925 + 'min_range' => 1,
926 + 'default' => 1,
927 + ),
928 + )
929 + );
930 + // add chart type filter to the query arguments
931 + $filter = filter_input( INPUT_GET, 'type' );
932 + if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) ) {
933 + $filter = 'all';
934 + }
935 +
936 + $css = '';
435 937 while ( $query->have_posts() ) {
436 938 $chart = $query->next_post();
939 +
940 + // 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.
941 + $chart = $this->handleExistingRevisions( $chart->ID, $chart );
942 + // refresh a "live" db query chart.
943 + $chart = apply_filters( 'visualizer_schedule_refresh_chart', $chart, $chart->ID, false );
944 +
945 + $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
946 +
437 947 // fetch and update settings
438 948 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
439 - unset( $settings['height'], $settings['width'] );
440 - $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
949 +
950 + $settings = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $settings, $chart->ID, $type );
951 + if ( ! empty( $atts['settings'] ) ) {
952 + $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
953 + }
954 +
955 + if ( $settings ) {
956 + unset( $settings['height'], $settings['width'], $settings['chartArea'] );
957 + }
958 +
441 959 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
442 - $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( $chart->post_content ) ), $chart->ID, $type );
960 + $data = self::get_chart_data( $chart, $type );
961 +
962 + // Set default setting series when add manual chart data - Only during first creation.
963 + if ( isset( $settings['series'] ) && ! empty( $series ) ) {
964 + $count_series = count( $series ) - count( $settings['series'] );
965 + if ( $count_series > 1 ) {
966 + $clone_last_series = end( $settings['series'] );
967 + $clone_last_series = array_fill_keys( array_keys( $clone_last_series ), '' );
968 + foreach ( range( 1, $count_series ) as $item ) {
969 + $settings['series'][] = $clone_last_series;
970 + }
971 + }
972 + }
973 +
974 + $library = $this->load_chart_type( $chart->ID );
975 +
976 + $id = 'visualizer-' . $chart->ID;
977 + $arguments = $this->get_inline_custom_css( $id, $settings );
978 + if ( ! empty( $arguments ) ) {
979 + $css .= $arguments[0];
980 + $settings = $arguments[1];
981 + }
982 +
983 + if ( isset( $settings['controls']['ui']['labelStacking'] ) ) {
984 + unset( $settings['controls']['ui']['labelStacking'] );
985 + }
986 + if ( isset( $settings['controls']['ui']['orientation'] ) ) {
987 + unset( $settings['controls']['ui']['orientation'] );
988 + }
989 +
443 990 // add chart to the array
444 - $charts[ 'visualizer-' . $chart->ID ] = array(
991 + $charts[ $id ] = array(
445 992 'id' => $chart->ID,
446 993 'type' => $type,
447 994 'series' => $series,
448 995 'settings' => $settings,
449 996 'data' => $data,
997 + 'library' => $library,
450 998 );
451 999 }
452 1000 // enqueue charts array
453 1001 $ajaxurl = admin_url( 'admin-ajax.php' );
454 1002 wp_localize_script(
455 - 'visualizer-library', 'visualizer', array(
1003 + 'visualizer-library',
1004 + 'visualizer',
1005 + array(
1006 + 'language' => $this->get_language(),
1007 + 'map_api_key' => get_option( 'visualizer-map-api-key' ),
456 1008 'charts' => $charts,
457 1009 'urls' => array(
458 - 'base' => add_query_arg( 'vpage', false ),
459 - 'create' => add_query_arg(
460 - array(
461 - 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
462 - 'library' => 'yes',
463 - ), $ajaxurl
1010 + 'base' => esc_url( add_query_arg( array( 'vpage' => false, 'vaction' => false ) ) ),
1011 + 'create' => esc_url(
1012 + add_query_arg(
1013 + array(
1014 + 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
1015 + 'library' => 'yes',
1016 + 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
1017 + 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
1018 + 'vaction' => false,
1019 + ),
1020 + $ajaxurl
1021 + )
464 1022 ),
465 - 'edit' => add_query_arg(
466 - array(
467 - 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
468 - 'library' => 'yes',
469 - ), $ajaxurl
1023 + 'edit' => esc_url(
1024 + add_query_arg(
1025 + array(
1026 + 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
1027 + 'library' => 'yes',
1028 + 'vaction' => false,
1029 + ),
1030 + $ajaxurl
1031 + )
470 1032 ),
471 1033 ),
1034 + 'page_type' => 'library',
1035 + 'is_front' => false,
1036 + 'i10n' => array(
1037 + 'copied' => __( 'The shortcode has been copied to your clipboard. Hit Ctrl-V/Cmd-V to paste it.', 'visualizer' ),
1038 + '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' ),
1039 + ),
472 1040 )
473 1041 );
474 1042 // render library page
475 1043 $render = new Visualizer_Render_Library();
@@ -474,12 +1042,13 @@
474 1042 // render library page
475 1043 $render = new Visualizer_Render_Library();
476 1044 $render->charts = $charts;
477 1045 $render->type = $filter;
478 - $render->types = self::_getChartTypesLocalized();
1046 + $render->types = self::_getChartTypesLocalized( false, false, false, true );
1047 + $render->custom_css = $css;
479 1048 $render->pagination = paginate_links(
480 1049 array(
481 - 'base' => add_query_arg( 'vpage', '%#%' ),
1050 + 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
482 1051 'format' => '',
483 1052 'current' => $page,
484 1053 'total' => $query->max_num_pages,
485 1054 'type' => 'array',
@@ -484,8 +1053,11 @@
484 1053 'total' => $query->max_num_pages,
485 1054 'type' => 'array',
486 1055 )
487 1056 );
1057 +
1058 + $this->load_survey();
1059 +
488 1060 $render->render();
489 1061 }
490 1062
491 1063 /**
@@ -500,14 +1072,14 @@
500 1072 *
501 1073 * @return array Updated array of action links.
502 1074 */
503 1075 public function getPluginActionLinks( $links, $file ) {
504 - if ( $file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1076 + if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
505 1077 array_unshift(
506 1078 $links,
507 1079 sprintf(
508 1080 '<a href="%s">%s</a>',
509 - admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ),
1081 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
510 1082 esc_html__( 'Library', 'visualizer' )
511 1083 )
512 1084 );
513 1085 }
@@ -527,17 +1099,17 @@
527 1099 *
528 1100 * @return array Updated array of plugin meta links.
529 1101 */
530 1102 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
531 - if ( $plugin_file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1103 + if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
532 1104 // knowledge base link
533 1105 $plugin_meta[] = sprintf(
534 - '<a href="https://github.com/codeinwp/visualizer/wiki" target="_blank">%s</a>',
535 - esc_html__( 'Knowledge Base', 'visualizer' )
1106 + '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1107 + esc_html__( 'Docs', 'visualizer' )
536 1108 );
537 1109 // flattr link
538 1110 $plugin_meta[] = sprintf(
539 - '<a style="color:red" href="https://themeisle.com/plugins/visualizer-charts-and-graphs-pro-addon/" target="_blank">%s</a>',
1111 + '<a style="color:red" href="' . tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'pluginrow' ) . '" target="_blank">%s</a>',
540 1112 esc_html__( 'Pro Addon', 'visualizer' )
541 1113 );
542 1114 }
543 1115
@@ -543,5 +1115,146 @@
543 1115
544 1116 return $plugin_meta;
545 1117 }
546 1118
1119 + /**
1120 + * If check is existing user.
1121 + *
1122 + * @return bool Default false
1123 + */
1124 + public static function proFeaturesLocked() {
1125 + if ( Visualizer_Module::is_pro() ) {
1126 + return true;
1127 + }
1128 + return 'yes' === get_option( 'visualizer-new-user', 'yes' ) ? false : true;
1129 + }
1130 +
1131 + /**
1132 + * Multilingual Support.
1133 + *
1134 + * @param int $chart_id Chart ID.
1135 + * @return bool Default false
1136 + */
1137 + public function addMultilingualSupport( $chart_id ) {
1138 + global $sitepress;
1139 + if ( Visualizer_Module::is_pro() ) {
1140 + return;
1141 + }
1142 + if ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) {
1143 + $language = icl_get_languages();
1144 + $current_lang = icl_get_current_language();
1145 + $default_lang = icl_get_default_language();
1146 + $post_info = wpml_get_language_information( null, $chart_id );
1147 + $translations = array();
1148 + if ( ! empty( $post_info ) && ( $default_lang === $post_info['language_code'] ) ) {
1149 + $trid = $sitepress->get_element_trid( $chart_id, 'post_' . Visualizer_Plugin::CPT_VISUALIZER );
1150 + $translations = $sitepress->get_element_translations( $trid );
1151 + }
1152 + if ( empty( $translations ) ) {
1153 + return;
1154 + }
1155 + ?>
1156 + <hr><div class="visualizer-languages-list only-pro">
1157 + <?php
1158 + foreach ( $language as $lang ) {
1159 + $lang_code = $lang['code'];
1160 + if ( $current_lang !== $lang_code ) {
1161 + ?>
1162 + <a href="javascript:;">
1163 + <img src="<?php echo esc_url( $lang['country_flag_url'] ); ?>" alt="<?php echo esc_attr( $lang['translated_name'] ); ?>">
1164 + </a>
1165 + <?php
1166 + }
1167 + }
1168 + ?>
1169 + <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>
1170 + </div>
1171 + <?php
1172 + }
1173 + }
1174 +
1175 + /**
1176 + * Check chart is enabled or not.
1177 + *
1178 + * @param string $type Chart ID.
1179 + *
1180 + * @return bool Default false
1181 + */
1182 + public static function checkChartStatus( $type ) {
1183 + $types = self::_getChartTypesLocalized( false, false, false, true );
1184 + if ( isset( $types[ $type ] ) ) {
1185 + return ! empty( $types[ $type ]['enabled'] );
1186 + }
1187 + return false;
1188 + }
1189 +
1190 + /**
1191 + * Get the survey metadata.
1192 + *
1193 + * @return array The survey metadata.
1194 + */
1195 + private function get_survey_metadata() {
1196 + $install_date = get_option( 'visualizer_install', false );
1197 + $install_category = 0;
1198 +
1199 + if ( false !== $install_date ) {
1200 + $days_since_install = round( ( time() - $install_date ) / DAY_IN_SECONDS );
1201 +
1202 + if ( 0 === $days_since_install || 1 === $days_since_install ) {
1203 + $install_category = 0;
1204 + } elseif ( 1 < $days_since_install && 8 > $days_since_install ) {
1205 + $install_category = 7;
1206 + } elseif ( 8 <= $days_since_install && 31 > $days_since_install ) {
1207 + $install_category = 30;
1208 + } elseif ( 30 < $days_since_install && 90 > $days_since_install ) {
1209 + $install_category = 90;
1210 + } elseif ( 90 <= $days_since_install ) {
1211 + $install_category = 91;
1212 + }
1213 + }
1214 +
1215 + $plugin_data = get_plugin_data( VISUALIZER_BASEFILE, false, false );
1216 + $plugin_version = '';
1217 + if ( ! empty( $plugin_data['Version'] ) ) {
1218 + $plugin_version = $plugin_data['Version'];
1219 + }
1220 +
1221 + $user_id = 'visualizer_' . preg_replace( '/[^\w\d]*/', '', get_site_url() ); // Use a normalized version of the site URL as a user ID.
1222 +
1223 + $license_data = get_option( 'visualizer_pro_license_data', false );
1224 + if ( false !== $license_data ) {
1225 + $user_id = 'visualizer_' . $license_data->key;
1226 + }
1227 +
1228 + return array(
1229 + 'userId' => $user_id,
1230 + 'attributes' => array(
1231 + 'days_since_install' => $install_category,
1232 + 'free_version' => $plugin_version,
1233 + 'pro_version' => defined( 'VISUALIZER_PRO_VERSION' ) ? VISUALIZER_PRO_VERSION : '',
1234 + 'license_status' => apply_filters( 'product_visualizer_license_status', 'invalid' ),
1235 + ),
1236 + );
1237 + }
1238 +
1239 + /**
1240 + * Load the survey.
1241 + */
1242 + private function load_survey() {
1243 +
1244 + if ( defined( 'TI_CYPRESS_TESTING' ) ) {
1245 + return;
1246 + }
1247 +
1248 + $survey_handler = apply_filters( 'themeisle_sdk_dependency_script_handler', 'survey' );
1249 +
1250 + if ( empty( $survey_handler ) ) {
1251 + return;
1252 + }
1253 +
1254 + $metadata = $this->get_survey_metadata();
1255 +
1256 + do_action( 'themeisle_sdk_dependency_enqueue_script', 'survey' );
1257 + wp_enqueue_script( 'visualizer_chart_survey', VISUALIZER_ABSURL . 'js/survey.js', array( $survey_handler ), $metadata['attributes']['free_version'], true );
1258 + wp_localize_script( 'visualizer_chart_survey', 'visualizerSurveyData', $metadata );
1259 + }
547 1260 }