PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.11.4
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.11.4
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 All 149 releases
← All changes | classes/Visualizer/Module/Admin.php +830 -92 3.0.63.11.4 View file →
@@ -52,34 +52,216 @@
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( 'enqueue_block_editor_assets', 'enqueueMediaScripts' );
57 + $this->_addAction( 'admin_footer', 'renderTemplates' );
58 + $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 0 );
58 59 $this->_addAction( 'admin_menu', 'registerAdminMenu' );
59 60 $this->_addFilter( 'media_view_strings', 'setupMediaViewStrings' );
60 61 $this->_addFilter( 'plugin_action_links', 'getPluginActionLinks', 10, 2 );
62 + $this->_addFilter( 'plugin_row_meta', 'getPluginMetaLinks', 10, 2 );
61 63 $this->_addFilter( 'visualizer_logger_data', 'getLoggerData' );
62 - $this->_addFilter( 'visualizer_get_chart_counts', 'getChartCountsByTypeAndMeta' );
63 64 $this->_addFilter( 'visualizer_feedback_review_trigger', 'feedbackReviewTrigger' );
64 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 +
65 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 +
66 86 }
87 + /**
88 + * Display review notice.
89 + */
90 + public function render_review_notice( $footer_text ) {
91 + $current_screen = get_current_screen();
67 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 +
68 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 + /**
69 236 * Admin init.
70 237 *
71 238 * @access public
72 239 */
73 240 public function init() {
241 + // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
74 242 if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' == get_user_option( 'rich_editing' ) ) {
75 243 $this->_addFilter( 'mce_external_languages', 'add_tinymce_lang', 10, 1 );
76 244 $this->_addFilter( 'mce_external_plugins', 'tinymce_plugin', 10, 1 );
77 245 $this->_addFilter( 'mce_buttons', 'register_mce_button', 10, 1 );
246 + $this->_addFilter( 'tiny_mce_before_init', 'get_strings_for_block', 10, 1 );
78 247 }
79 248 }
80 249
81 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 + /**
82 264 * Load plugin translation for - TinyMCE API
83 265 *
84 266 * @access public
85 267 * @param array $arr The tinymce_lang array.
@@ -148,16 +330,32 @@
148 330 * @access public
149 331 */
150 332 public function enqueueMediaScripts() {
151 333 global $typenow;
152 - if ( post_type_supports( $typenow, 'editor' ) ) {
334 + global $current_screen;
335 +
336 + if ( post_type_supports( $typenow, 'editor' ) || $current_screen->id === 'widgets' || $current_screen->id === 'customize' ) {
153 337 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 );
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 );
157 346 wp_enqueue_script( 'visualizer-media-collection', VISUALIZER_ABSURL . 'js/media/collection.js', array( 'visualizer-media-model' ), Visualizer_Plugin::VERSION, true );
158 347 wp_enqueue_script( 'visualizer-media-controller', VISUALIZER_ABSURL . 'js/media/controller.js', array( 'visualizer-media-collection' ), Visualizer_Plugin::VERSION, true );
159 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 + );
160 358 wp_enqueue_script( 'visualizer-media-toolbar', VISUALIZER_ABSURL . 'js/media/toolbar.js', array( 'visualizer-media-view' ), Visualizer_Plugin::VERSION, true );
161 359 wp_enqueue_script( 'visualizer-media', VISUALIZER_ABSURL . 'js/media.js', array( 'visualizer-media-toolbar' ), Visualizer_Plugin::VERSION, true );
162 360 }
163 361 }
@@ -191,9 +389,9 @@
191 389 'filters' => $chart_types,
192 390 'types' => array_keys( $chart_types ),
193 391 ),
194 392 'nonce' => wp_create_nonce(),
195 - 'buildurl' => add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ),
393 + 'buildurl' => esc_url( add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ) ),
196 394 );
197 395
198 396 return $strings;
199 397 }
@@ -206,9 +404,9 @@
206 404 * @static
207 405 * @access private
208 406 * @return array The associated array of chart types with localized names.
209 407 */
210 - public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false, $add_select = false ) {
408 + public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false, $add_select = false, $where = null ) {
211 409 $additional = array();
212 410 if ( $add_select ) {
213 411 $additional['select'] = array(
214 412 'name' => esc_html__( 'All', 'visualizer' ),
@@ -215,59 +413,91 @@
215 413 'enabled' => true,
216 414 );
217 415 }
218 416
417 + $enabled = self::proFeaturesLocked();
418 +
219 419 $types = array_merge(
220 - $additional, array(
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 + ),
221 427 'pie' => array(
222 - 'name' => esc_html__( 'Pie', 'visualizer' ),
428 + 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
223 429 'enabled' => true,
430 + 'supports' => array( 'Google Charts', 'ChartJS' ),
224 431 ),
225 432 'line' => array(
226 433 'name' => esc_html__( 'Line', 'visualizer' ),
227 434 'enabled' => true,
435 + 'supports' => array( 'Google Charts', 'ChartJS' ),
228 436 ),
437 + 'bar' => array(
438 + 'name' => esc_html__( 'Bar', 'visualizer' ),
439 + 'enabled' => true,
440 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
441 + ),
229 442 'area' => array(
230 443 'name' => esc_html__( 'Area', 'visualizer' ),
231 - 'enabled' => true,
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' ),
232 447 ),
233 448 'geo' => array(
234 449 'name' => esc_html__( 'Geo', 'visualizer' ),
235 - 'enabled' => true,
450 + 'enabled' => $enabled,
451 + 'supports' => array( 'Google Charts' ),
236 452 ),
237 - 'bar' => array(
238 - 'name' => esc_html__( 'Bar', 'visualizer' ),
239 - 'enabled' => true,
240 - ),
241 453 'column' => array(
242 454 'name' => esc_html__( 'Column', 'visualizer' ),
243 - 'enabled' => true,
455 + 'enabled' => $enabled,
456 + 'supports' => array( 'Google Charts', 'ChartJS' ),
244 457 ),
245 - 'gauge' => array(
246 - 'name' => esc_html__( 'Gauge', 'visualizer' ),
247 - 'enabled' => true,
458 + 'bubble' => array(
459 + 'name' => esc_html__( 'Bubble', 'visualizer' ),
460 + 'enabled' => $enabled,
461 + // chartjs' bubble is ugly looking (and it won't work off the default bubble.csv) so it is being excluded for the time being.
462 + 'supports' => array( 'Google Charts' ),
248 463 ),
249 464 'scatter' => array(
250 465 'name' => esc_html__( 'Scatter', 'visualizer' ),
251 - 'enabled' => true,
466 + 'enabled' => $enabled,
467 + 'supports' => array( 'Google Charts' ),
252 468 ),
469 + 'gauge' => array(
470 + 'name' => esc_html__( 'Gauge', 'visualizer' ),
471 + 'enabled' => $enabled,
472 + 'supports' => array( 'Google Charts' ),
473 + ),
253 474 'candlestick' => array(
254 475 'name' => esc_html__( 'Candlestick', 'visualizer' ),
255 - 'enabled' => true,
476 + 'enabled' => $enabled,
477 + 'supports' => array( 'Google Charts' ),
256 478 ),
257 479 // pro types
258 - 'table' => array(
259 - 'name' => esc_html__( 'Table', 'visualizer' ),
260 - 'enabled' => false,
261 - ),
262 480 'timeline' => array(
263 481 'name' => esc_html__( 'Timeline', 'visualizer' ),
264 482 'enabled' => false,
483 + 'supports' => array( 'Google Charts', 'ChartJS' ),
265 484 ),
266 485 'combo' => array(
267 486 'name' => esc_html__( 'Combo', 'visualizer' ),
268 487 'enabled' => false,
488 + 'supports' => array( 'Google Charts' ),
269 489 ),
490 + 'polarArea' => array(
491 + 'name' => esc_html__( 'Polar Area', 'visualizer' ),
492 + 'enabled' => false,
493 + 'supports' => array( 'ChartJS' ),
494 + ),
495 + 'radar' => array(
496 + 'name' => esc_html__( 'Radar/Spider', 'visualizer' ),
497 + 'enabled' => false,
498 + 'supports' => array( 'ChartJS' ),
499 + ),
270 500 )
271 501 );
272 502 $types = apply_filters( 'visualizer_pro_chart_types', $types );
273 503 if ( $enabledOnly ) {
@@ -276,8 +506,12 @@
276 506 if ( ! is_array( $array ) ) {
277 507 // support for old pro
278 508 $array = array( 'enabled' => true, 'name' => $array );
279 509 }
510 + // backward compatibility for PRO before v1.9.0
511 + if ( ! array_key_exists( 'supports', $array ) ) {
512 + $array['supports'] = array( 'Google Charts' );
513 + }
280 514 if ( ! $array['enabled'] ) {
281 515 continue;
282 516 }
283 517 $filtered[ $type ] = $array;
@@ -290,13 +524,74 @@
290 524 if ( ! is_array( $array ) ) {
291 525 // support for old pro
292 526 $array = array( 'enabled' => true, 'name' => $array );
293 527 }
528 + // backward compatibility for PRO before v1.9.0
529 + if ( ! array_key_exists( 'supports', $array ) ) {
530 + $array['supports'] = array( 'Google Charts' );
531 + }
294 532 $doubleD[ $type ] = $array['name'];
295 533 }
296 534 $types = $doubleD;
297 535 }
298 536
537 + return self::handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where );
538 + }
539 +
540 + /**
541 + * Handle (soon-to-be) deprecated charts.
542 + */
543 + private static function handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where ) {
544 + $deprecated = array();
545 +
546 + switch ( $where ) {
547 + case 'types':
548 + // fall-through
549 + case 'library':
550 + // if a user has a Gauge/Candlestick chart, then let them keep using it.
551 + if ( ! Visualizer_Module::is_pro() ) {
552 + if ( ! self::hasChartType( 'gauge' ) ) {
553 + if ( $get2Darray ) {
554 + $deprecated[] = 'gauge';
555 + } else {
556 + $types['gauge']['enabled'] = false;
557 + }
558 + }
559 + if ( ! self::hasChartType( 'candlestick' ) ) {
560 + if ( $get2Darray ) {
561 + $deprecated[] = 'candlestick';
562 + } else {
563 + $types['candlestick']['enabled'] = false;
564 + }
565 + }
566 + }
567 + break;
568 + default:
569 + // if a user has a Gauge/Candlestick chart, then let them keep using it.
570 + if ( ! Visualizer_Module::is_pro() ) {
571 + if ( ! self::hasChartType( 'gauge' ) ) {
572 + if ( $get2Darray ) {
573 + $deprecated[] = 'gauge';
574 + } else {
575 + $types['gauge']['enabled'] = false;
576 + }
577 + }
578 + if ( ! self::hasChartType( 'candlestick' ) ) {
579 + if ( $get2Darray ) {
580 + $deprecated[] = 'candlestick';
581 + } else {
582 + $types['candlestick']['enabled'] = false;
583 + }
584 + }
585 + }
586 + }
587 +
588 + if ( $deprecated ) {
589 + foreach ( $deprecated as $type ) {
590 + unset( $types[ $type ] );
591 + }
592 + }
593 +
299 594 return $types;
300 595 }
301 596
302 597 /**
@@ -306,11 +601,11 @@
306 601 * @global string $pagenow The name of the current page.
307 602 *
308 603 * @access public
309 604 */
310 - public function renderTempaltes() {
605 + public function renderTemplates() {
311 606 global $pagenow;
312 - if ( 'post.php' != $pagenow && 'post-new.php' != $pagenow ) {
607 + if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
313 608 return;
314 609 }
315 610 $render = new Visualizer_Render_Templates();
316 611 $render->render();
@@ -328,26 +623,41 @@
328 623 *
329 624 * @param string $suffix The current page suffix.
330 625 */
331 626 public function enqueueLibraryScripts( $suffix ) {
332 - if ( $suffix == $this->_libraryPage ) {
627 + if ( $suffix === $this->_libraryPage ) {
333 628 wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
334 629 $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
335 630 wp_enqueue_media();
336 631 wp_enqueue_script(
337 - 'visualizer-library', VISUALIZER_ABSURL . 'js/library.js', array(
632 + 'visualizer-library',
633 + VISUALIZER_ABSURL . 'js/library.js',
634 + array(
338 635 'jquery',
339 636 'media-views',
340 - ), Visualizer_Plugin::VERSION, true
637 + 'clipboard',
638 + ),
639 + Visualizer_Plugin::VERSION,
640 + true
341 641 );
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 - );
642 +
643 + wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
644 +
645 + $query = $this->getQuery();
646 + while ( $query->have_posts() ) {
647 + $chart = $query->next_post();
648 + $library = $this->load_chart_type( $chart->ID );
649 + if ( is_null( $library ) ) {
650 + continue;
651 + }
652 + wp_enqueue_script(
653 + "visualizer-render-$library",
654 + VISUALIZER_ABSURL . 'js/render-facade.js',
655 + apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
656 + Visualizer_Plugin::VERSION,
657 + true
658 + );
659 + }
350 660 }
351 661 }
352 662
353 663 /**
@@ -374,24 +684,191 @@
374 684 *
375 685 * @access public
376 686 */
377 687 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 );
688 + $svg_base64_icon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNzdweCIgaGVpZ2h0PSI3N3B4IiB2aWV3Qm94PSIwIDAgNzcgNzciIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjYgKDY3NDkxKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Db21iaW5lZCBTaGFwZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxnIGlkPSJQcm9kdWN0LVBhZ2UiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJXb3JkUHJlc3MtcGx1Z2lucyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE5MC4wMDAwMDAsIC00MzUuMDAwMDAwKSIgZmlsbD0iIzM5QzNEMiI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMjguNSw1MTIgQzIwNy4yMzcwMzcsNTEyIDE5MCw0OTQuNzYyOTYzIDE5MCw0NzMuNSBDMTkwLDQ1Mi4yMzcwMzcgMjA3LjIzNzAzNyw0MzUgMjI4LjUsNDM1IEMyNDkuNzYyOTYzLDQzNSAyNjcsNDUyLjIzNzAzNyAyNjcsNDczLjUgQzI2Nyw0OTQuNzYyOTYzIDI0OS43NjI5NjMsNTEyIDIyOC41LDUxMiBaIE0yNDYuODQzNzUsNDgzLjU5MjA1OSBMMjE1LjYyNSw0ODMuNTkyMDU5IEwyMTUuNjI1LDQ2MC44MjY1NDQgQzIxNS42MjUsNDYwLjE2NDU0NyAyMTUuMTA3NTc4LDQ1OS42MjgzNTkgMjE0LjQ2ODc1LDQ1OS42MjgzNTkgTDIxMi4xNTYyNSw0NTkuNjI4MzU5IEMyMTEuNTE3NDIyLDQ1OS42MjgzNTkgMjExLDQ2MC4xNjQ1NDcgMjExLDQ2MC44MjY1NDQgTDIxMSw0ODUuOTg4NDI5IEMyMTEsNDg3LjMxMTY3NCAyMTIuMDM1NTY2LDQ4OC4zODQ3OTggMjEzLjMxMjUsNDg4LjM4NDc5OCBMMjQ2Ljg0Mzc1LDQ4OC4zODQ3OTggQzI0Ny40ODI1NzgsNDg4LjM4NDc5OCAyNDgsNDg3Ljg0ODYxMSAyNDgsNDg3LjE4NjYxMyBMMjQ4LDQ4NC43OTAyNDQgQzI0OCw0ODQuMTI4MjQ2IDI0Ny40ODI1NzgsNDgzLjU5MjA1OSAyNDYuODQzNzUsNDgzLjU5MjA1OSBaIE0yNDQuNTMxMjUsNDYyLjAyNDcyOSBMMjM1Ljk5OTU3LDQ2Mi4wMjQ3MjkgQzIzNC40NTQ1MzEsNDYyLjAyNDcyOSAyMzMuNjgwNTY2LDQ2My45NjA1NDcgMjM0Ljc3MzIyMyw0NjUuMDkyODMyIEwyMzcuMTE0NjI5LDQ2Ny41MTkxNTYgTDIzMS44MTI1LDQ3My4wMTQzMzIgTDIyNi41MTAzNzEsNDY3LjUxOTkwNSBDMjI1LjYwNzA1MSw0NjYuNTgzODIzIDIyNC4xNDI5NDksNDY2LjU4MzgyMyAyMjMuMjQwMzUyLDQ2Ny41MTk5MDUgTDIxOC4yNzY0MjYsNDcyLjY2Mzg2MyBDMjE3LjgyNDc2Niw0NzMuMTMxOTA0IDIxNy44MjQ3NjYsNDczLjg5MDUwNSAyMTguMjc2NDI2LDQ3NC4zNTg1NDYgTDIxOS45MTEwNzQsNDc2LjA1MjQ4IEMyMjAuMzYyNzM0LDQ3Ni41MjA1MjEgMjIxLjA5NDc4NSw0NzYuNTIwNTIxIDIyMS41NDY0NDUsNDc2LjA1MjQ4IEwyMjQuODc1LDQ3Mi42MDI0NTYgTDIzMC4xNzcxMjksNDc4LjA5Njg4MyBDMjMxLjA4MDQ0OSw0NzkuMDMyOTY1IDIzMi41NDQ1NTEsNDc5LjAzMjk2NSAyMzMuNDQ3MTQ4LDQ3OC4wOTY4ODMgTDI0MC4zODQ2NDgsNDcwLjkwNzc3MyBMMjQyLjcyNjA1NSw0NzMuMzM0MDk4IEMyNDMuODE4NzExLDQ3NC40NjYzODIgMjQ1LjY4Njc3Nyw0NzMuNjY0MzQ3IDI0NS42ODY3NzcsNDcyLjA2MzI3MyBMMjQ1LjY4Njc3Nyw0NjMuMjIyOTE0IEMyNDUuNjg3NSw0NjIuNTYwOTE3IDI0NS4xNzAwNzgsNDYyLjAyNDcyOSAyNDQuNTMxMjUsNDYyLjAyNDcyOSBaIiBpZD0iQ29tYmluZWQtU2hhcGUiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==';
689 +
690 + $this->_libraryPage = add_menu_page( __( 'Visualizer', 'visualizer' ), __( 'Visualizer', 'visualizer' ), 'edit_posts', Visualizer_Plugin::NAME, array( $this, 'renderLibraryPage' ), $svg_base64_icon, 99.7666 );
691 +
692 + add_submenu_page(
693 + Visualizer_Plugin::NAME,
694 + __( 'Chart Library', 'visualizer' ),
695 + __( 'Chart Library', 'visualizer' ),
696 + 'edit_posts',
697 + 'admin.php?page=' . Visualizer_Plugin::NAME
698 + );
699 + add_submenu_page(
700 + Visualizer_Plugin::NAME,
701 + __( 'Add New Chart', 'visualizer' ),
702 + __( 'Add New Chart', 'visualizer' ),
703 + 'edit_posts',
704 + 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew'
705 + );
706 + add_submenu_page(
707 + Visualizer_Plugin::NAME,
708 + __( 'Support', 'visualizer' ),
709 + __( '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>',
710 + 'edit_posts',
711 + 'viz-support',
712 + array( $this, 'renderSupportPage' )
713 + );
714 +
715 + remove_submenu_page( Visualizer_Plugin::NAME, Visualizer_Plugin::NAME );
716 +
717 + add_action( "load-{$this->_libraryPage}", array( $this, 'addScreenOptions' ) );
718 + add_action( 'admin_footer', array( $this, 'handleGetProSubMenu' ) );
381 719 }
382 720
383 721 /**
384 - * Renders visualizer library page.
385 - *
386 - * @since 1.0.0
387 - *
388 - * @access public
722 + * Handle get pro plugin submenu.
389 723 */
390 - public function renderLibraryPage() {
724 + public function handleGetProSubMenu() {
725 + if ( ! Visualizer_Module::is_pro() ) {
726 + ?>
727 + <style type="text/css">
728 + #toplevel_page_visualizer ul.wp-submenu li:last-child {
729 + background: #FF7E65;
730 + font-size: 14px;
731 + font-weight: 600;
732 + color: #fff;
733 + }
734 + #toplevel_page_visualizer ul.wp-submenu li:last-child > a {
735 + color: #fff !important;
736 + }
737 + #toplevel_page_visualizer ul.wp-submenu li:last-child > a:hover {
738 + box-shadow: inherit;
739 + }
740 + </style>
741 + <?php
742 + if ( get_option( 'visualizer_fresh_install', false ) ) {
743 + ?>
744 + <style type="text/css">
745 + #toplevel_page_visualizer ul.wp-submenu li.wp-first-item + li + li + li {
746 + display: none;
747 + }
748 + </style>
749 + <?php
750 + }
751 + }
752 + }
753 +
754 + /**
755 + * Adds the screen options for pagination.
756 + */
757 + function addScreenOptions() {
758 + $screen = get_current_screen();
759 +
760 + // bail if it's some other page.
761 + if ( ! is_object( $screen ) || $screen->id !== $this->_libraryPage ) {
762 + return;
763 + }
764 +
765 + $args = array(
766 + 'label' => __( 'Number of charts per page:', 'visualizer' ),
767 + 'default' => 6,
768 + 'option' => 'visualizer_library_per_page',
769 + );
770 + add_screen_option( 'per_page', $args );
771 + }
772 +
773 + /**
774 + * Returns the screen option for pagination.
775 + */
776 + function setScreenOptions( $status, $option, $value ) {
777 + if ( 'visualizer_library_per_page' === $option ) {
778 + return $value;
779 + }
780 + }
781 +
782 + /**
783 + * Adds the display filters to be used in the meta_query while displaying the charts.
784 + */
785 + private function getDisplayFilters( &$query_args ) {
786 + $query = array();
787 + global $sitepress;
788 + if ( Visualizer_Module::is_pro() && ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) ) {
789 + $current_lang = icl_get_current_language();
790 + if ( in_array( $current_lang, array( 'all', icl_get_default_language() ), true ) ) {
791 + $query[] = array(
792 + 'key' => 'chart_lang',
793 + 'compare' => 'NOT EXISTS',
794 + );
795 + } else {
796 + $query[] = array(
797 + 'key' => 'chart_lang',
798 + 'value' => $current_lang,
799 + 'compare' => '=',
800 + );
801 + }
802 + }
803 +
804 + // add chart type filter to the query arguments
805 + $type = filter_input( INPUT_GET, 'type' );
806 + if ( $type && in_array( $type, Visualizer_Plugin::getChartTypes(), true ) ) {
807 + $query[] = array(
808 + 'key' => Visualizer_Plugin::CF_CHART_TYPE,
809 + 'value' => $type,
810 + 'compare' => '=',
811 + );
812 + }
813 +
814 + // add chart library filter to the query arguments
815 + $library = filter_input( INPUT_GET, 'library' );
816 + if ( $library ) {
817 + $query[] = array(
818 + 'key' => Visualizer_Plugin::CF_CHART_LIBRARY,
819 + 'value' => $library,
820 + 'compare' => '=',
821 + );
822 + }
823 +
824 + // add date filter to the query arguments
825 + $date = filter_input( INPUT_GET, 'date' );
826 + $possible = array_keys( Visualizer_Plugin::getSupportedDateFilter() );
827 + if ( $date && in_array( $date, $possible, true ) ) {
828 + $query_args['date_query'] = array(
829 + 'after' => "$date -1 day",
830 + 'inclusive' => true,
831 + );
832 + }
833 +
834 + // add source filter to the query arguments
835 + $source = filter_input( INPUT_GET, 'source' );
836 + if ( $source ) {
837 + $source = ucwords( $source );
838 + $source = "Visualizer_Source_{$source}";
839 + $query[] = array(
840 + 'key' => Visualizer_Plugin::CF_SOURCE,
841 + 'value' => $source,
842 + 'compare' => '=',
843 + );
844 + }
845 +
846 + $query_args['meta_query'] = $query;
847 +
848 + $orderby = filter_input( INPUT_GET, 'orderby' );
849 + $order = filter_input( INPUT_GET, 'order' );
850 + if ( $orderby ) {
851 + $query_args['order_by'] = $orderby;
852 + }
853 + $query_args['order'] = empty( $order ) ? 'desc' : $order;
854 + }
855 +
856 + /**
857 + * Get the instance of WP_Query that fetches the charts as per the given criteria.
858 + */
859 + private function getQuery() {
860 + static $q;
861 + if ( ! is_null( $q ) ) {
862 + return $q;
863 + }
864 +
391 865 // get current page
392 866 $page = filter_input(
393 - INPUT_GET, 'vpage', FILTER_VALIDATE_INT, array(
867 + INPUT_GET,
868 + 'vpage',
869 + FILTER_VALIDATE_INT,
870 + array(
394 871 'options' => array(
395 872 'min_range' => 1,
396 873 'default' => 1,
397 874 ),
@@ -396,29 +873,34 @@
396 873 'default' => 1,
397 874 ),
398 875 )
399 876 );
877 +
878 + $per_page = 6;
879 + $screen = get_current_screen();
880 + if ( $screen ) {
881 + // retrieve the per_page option
882 + $screen_option = $screen->get_option( 'per_page', 'option' );
883 + // retrieve the value stored for the current user
884 + $user = get_current_user_id();
885 + $per_page = get_user_meta( $user, $screen_option, true );
886 + if ( empty( $per_page ) || $per_page < 1 ) {
887 + // nothing set, get the default value
888 + $per_page = $screen->get_option( 'per_page', 'default' );
889 + }
890 + }
891 +
400 892 // the initial query arguments to fetch charts
401 893 $query_args = array(
402 894 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
403 - 'posts_per_page' => 6,
895 + 'posts_per_page' => $per_page,
404 896 'paged' => $page,
405 897 );
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 - }
898 +
899 + $this->getDisplayFilters( $query_args );
900 +
419 901 // Added by Ash/Upwork
420 - $filterByMeta = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
902 + $filterByMeta = ! empty( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
421 903 if ( $filterByMeta ) {
422 904 $query = array(
423 905 'key' => Visualizer_Plugin::CF_SETTINGS,
424 906 'value' => $filterByMeta,
@@ -427,49 +909,160 @@
427 909 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
428 910 $meta[] = $query;
429 911 $query_args['meta_query'] = $meta;
430 912 }
431 - // Added by Ash/Upwork
432 - // fetch charts
913 + $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
914 + return $q;
915 + }
916 +
917 + /**
918 + * Renders support page.
919 + *
920 + * @since 3.3.0
921 + *
922 + * @access public
923 + */
924 + public function renderSupportPage() {
925 + wp_enqueue_style( 'visualizer-upsell', VISUALIZER_ABSURL . 'css/upsell.css', array(), Visualizer_Plugin::VERSION );
926 + $this->load_survey();
927 + include_once VISUALIZER_ABSPATH . '/templates/support.php';
928 + }
929 +
930 + /**
931 + * Renders visualizer library page.
932 + *
933 + * @since 1.0.0
934 + *
935 + * @access public
936 + */
937 + public function renderLibraryPage() {
433 938 $charts = array();
434 - $query = new WP_Query( $query_args );
939 + $query = $this->getQuery();
940 +
941 + // get current page
942 + $page = filter_input(
943 + INPUT_GET,
944 + 'vpage',
945 + FILTER_VALIDATE_INT,
946 + array(
947 + 'options' => array(
948 + 'min_range' => 1,
949 + 'default' => 1,
950 + ),
951 + )
952 + );
953 + // add chart type filter to the query arguments
954 + $filter = filter_input( INPUT_GET, 'type' );
955 + if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) ) {
956 + $filter = 'all';
957 + }
958 +
959 + $css = '';
435 960 while ( $query->have_posts() ) {
436 961 $chart = $query->next_post();
962 +
963 + // 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.
964 + $chart = $this->handleExistingRevisions( $chart->ID, $chart );
965 + // refresh a "live" db query chart.
966 + $chart = apply_filters( 'visualizer_schedule_refresh_chart', $chart, $chart->ID, false );
967 +
968 + $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
969 +
437 970 // fetch and update settings
438 971 $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 );
972 +
973 + $settings = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $settings, $chart->ID, $type );
974 + if ( ! empty( $atts['settings'] ) ) {
975 + $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
976 + }
977 +
978 + if ( $settings ) {
979 + unset( $settings['height'], $settings['width'], $settings['chartArea'] );
980 + }
981 +
441 982 $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 );
983 + $data = self::get_chart_data( $chart, $type );
984 +
985 + // Set default setting series when add manual chart data - Only during first creation.
986 + if ( isset( $settings['series'] ) && ! empty( $series ) ) {
987 + $count_series = count( $series ) - count( $settings['series'] );
988 + if ( $count_series > 1 ) {
989 + $clone_last_series = end( $settings['series'] );
990 + $clone_last_series = array_fill_keys( array_keys( $clone_last_series ), '' );
991 + foreach ( range( 1, $count_series ) as $item ) {
992 + $settings['series'][] = $clone_last_series;
993 + }
994 + }
995 + }
996 +
997 + $library = $this->load_chart_type( $chart->ID );
998 +
999 + $id = 'visualizer-' . $chart->ID;
1000 + $arguments = $this->get_inline_custom_css( $id, $settings );
1001 + if ( ! empty( $arguments ) ) {
1002 + $css .= $arguments[0];
1003 + $settings = $arguments[1];
1004 + }
1005 +
1006 + if ( isset( $settings['controls']['ui']['labelStacking'] ) ) {
1007 + unset( $settings['controls']['ui']['labelStacking'] );
1008 + }
1009 + if ( isset( $settings['controls']['ui']['orientation'] ) ) {
1010 + unset( $settings['controls']['ui']['orientation'] );
1011 + }
1012 +
443 1013 // add chart to the array
444 - $charts[ 'visualizer-' . $chart->ID ] = array(
1014 + $charts[ $id ] = array(
445 1015 'id' => $chart->ID,
446 1016 'type' => $type,
447 1017 'series' => $series,
448 1018 'settings' => $settings,
449 1019 'data' => $data,
1020 + 'library' => $library,
450 1021 );
451 1022 }
452 1023 // enqueue charts array
453 1024 $ajaxurl = admin_url( 'admin-ajax.php' );
1025 +
454 1026 wp_localize_script(
455 - 'visualizer-library', 'visualizer', array(
1027 + 'visualizer-library',
1028 + 'visualizer',
1029 + array(
1030 + 'language' => $this->get_language(),
1031 + 'map_api_key' => get_option( 'visualizer-map-api-key' ),
456 1032 'charts' => $charts,
457 1033 '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
1034 + 'base' => esc_url( add_query_arg( array( 'vpage' => false, 'vaction' => false ) ) ),
1035 + 'create' => esc_url(
1036 + add_query_arg(
1037 + array(
1038 + 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
1039 + 'library' => 'yes',
1040 + 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
1041 + 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
1042 + 'vaction' => false,
1043 + ),
1044 + $ajaxurl
1045 + )
464 1046 ),
465 - 'edit' => add_query_arg(
466 - array(
467 - 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
468 - 'library' => 'yes',
469 - ), $ajaxurl
1047 + 'edit' => esc_url(
1048 + add_query_arg(
1049 + array(
1050 + 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
1051 + 'library' => 'yes',
1052 + 'vaction' => false,
1053 + ),
1054 + $ajaxurl
1055 + )
470 1056 ),
471 1057 ),
1058 + 'page_type' => 'library',
1059 + 'is_front' => false,
1060 + 'i10n' => array(
1061 + 'copied' => __( 'The shortcode has been copied to your clipboard. Hit Ctrl-V/Cmd-V to paste it.', 'visualizer' ),
1062 + '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' ),
1063 + ),
1064 + 'is_pro_user' => Visualizer_Module::is_pro(),
472 1065 )
473 1066 );
474 1067 // render library page
475 1068 $render = new Visualizer_Render_Library();
@@ -474,12 +1067,13 @@
474 1067 // render library page
475 1068 $render = new Visualizer_Render_Library();
476 1069 $render->charts = $charts;
477 1070 $render->type = $filter;
478 - $render->types = self::_getChartTypesLocalized();
1071 + $render->types = self::_getChartTypesLocalized( false, false, false, true );
1072 + $render->custom_css = $css;
479 1073 $render->pagination = paginate_links(
480 1074 array(
481 - 'base' => add_query_arg( 'vpage', '%#%' ),
1075 + 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
482 1076 'format' => '',
483 1077 'current' => $page,
484 1078 'total' => $query->max_num_pages,
485 1079 'type' => 'array',
@@ -484,8 +1078,11 @@
484 1078 'total' => $query->max_num_pages,
485 1079 'type' => 'array',
486 1080 )
487 1081 );
1082 +
1083 + $this->load_survey();
1084 +
488 1085 $render->render();
489 1086 }
490 1087
491 1088 /**
@@ -500,14 +1097,14 @@
500 1097 *
501 1098 * @return array Updated array of action links.
502 1099 */
503 1100 public function getPluginActionLinks( $links, $file ) {
504 - if ( $file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1101 + if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
505 1102 array_unshift(
506 1103 $links,
507 1104 sprintf(
508 1105 '<a href="%s">%s</a>',
509 - admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ),
1106 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
510 1107 esc_html__( 'Library', 'visualizer' )
511 1108 )
512 1109 );
513 1110 }
@@ -527,17 +1124,17 @@
527 1124 *
528 1125 * @return array Updated array of plugin meta links.
529 1126 */
530 1127 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
531 - if ( $plugin_file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1128 + if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
532 1129 // knowledge base link
533 1130 $plugin_meta[] = sprintf(
534 - '<a href="https://github.com/codeinwp/visualizer/wiki" target="_blank">%s</a>',
535 - esc_html__( 'Knowledge Base', 'visualizer' )
1131 + '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1132 + esc_html__( 'Docs', 'visualizer' )
536 1133 );
537 1134 // flattr link
538 1135 $plugin_meta[] = sprintf(
539 - '<a style="color:red" href="https://themeisle.com/plugins/visualizer-charts-and-graphs-pro-addon/" target="_blank">%s</a>',
1136 + '<a style="color:red" href="' . tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'pluginrow' ) . '" target="_blank">%s</a>',
540 1137 esc_html__( 'Pro Addon', 'visualizer' )
541 1138 );
542 1139 }
543 1140
@@ -543,5 +1140,146 @@
543 1140
544 1141 return $plugin_meta;
545 1142 }
546 1143
1144 + /**
1145 + * If check is existing user.
1146 + *
1147 + * @return bool Default false
1148 + */
1149 + public static function proFeaturesLocked() {
1150 + if ( Visualizer_Module::is_pro() ) {
1151 + return true;
1152 + }
1153 + return 'yes' === get_option( 'visualizer-new-user', 'yes' ) ? false : true;
1154 + }
1155 +
1156 + /**
1157 + * Multilingual Support.
1158 + *
1159 + * @param int $chart_id Chart ID.
1160 + * @return bool Default false
1161 + */
1162 + public function addMultilingualSupport( $chart_id ) {
1163 + global $sitepress;
1164 + if ( Visualizer_Module::is_pro() ) {
1165 + return;
1166 + }
1167 + if ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) {
1168 + $language = icl_get_languages();
1169 + $current_lang = icl_get_current_language();
1170 + $default_lang = icl_get_default_language();
1171 + $post_info = wpml_get_language_information( null, $chart_id );
1172 + $translations = array();
1173 + if ( ! empty( $post_info ) && ( $default_lang === $post_info['language_code'] ) ) {
1174 + $trid = $sitepress->get_element_trid( $chart_id, 'post_' . Visualizer_Plugin::CPT_VISUALIZER );
1175 + $translations = $sitepress->get_element_translations( $trid );
1176 + }
1177 + if ( empty( $translations ) ) {
1178 + return;
1179 + }
1180 + ?>
1181 + <hr><div class="visualizer-languages-list only-pro">
1182 + <?php
1183 + foreach ( $language as $lang ) {
1184 + $lang_code = $lang['code'];
1185 + if ( $current_lang !== $lang_code ) {
1186 + ?>
1187 + <a href="javascript:;">
1188 + <img src="<?php echo esc_url( $lang['country_flag_url'] ); ?>" alt="<?php echo esc_attr( $lang['translated_name'] ); ?>">
1189 + </a>
1190 + <?php
1191 + }
1192 + }
1193 + ?>
1194 + <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>
1195 + </div>
1196 + <?php
1197 + }
1198 + }
1199 +
1200 + /**
1201 + * Check chart is enabled or not.
1202 + *
1203 + * @param string $type Chart ID.
1204 + *
1205 + * @return bool Default false
1206 + */
1207 + public static function checkChartStatus( $type ) {
1208 + $types = self::_getChartTypesLocalized( false, false, false, true );
1209 + if ( isset( $types[ $type ] ) ) {
1210 + return ! empty( $types[ $type ]['enabled'] );
1211 + }
1212 + return false;
1213 + }
1214 +
1215 + /**
1216 + * Get the survey metadata.
1217 + *
1218 + * @return array The survey metadata.
1219 + */
1220 + private function get_survey_metadata() {
1221 + $install_date = get_option( 'visualizer_install', false );
1222 + $install_category = 0;
1223 +
1224 + if ( false !== $install_date ) {
1225 + $days_since_install = round( ( time() - $install_date ) / DAY_IN_SECONDS );
1226 +
1227 + if ( 0 === $days_since_install || 1 === $days_since_install ) {
1228 + $install_category = 0;
1229 + } elseif ( 1 < $days_since_install && 8 > $days_since_install ) {
1230 + $install_category = 7;
1231 + } elseif ( 8 <= $days_since_install && 31 > $days_since_install ) {
1232 + $install_category = 30;
1233 + } elseif ( 30 < $days_since_install && 90 > $days_since_install ) {
1234 + $install_category = 90;
1235 + } elseif ( 90 <= $days_since_install ) {
1236 + $install_category = 91;
1237 + }
1238 + }
1239 +
1240 + $plugin_data = get_plugin_data( VISUALIZER_BASEFILE, false, false );
1241 + $plugin_version = '';
1242 + if ( ! empty( $plugin_data['Version'] ) ) {
1243 + $plugin_version = $plugin_data['Version'];
1244 + }
1245 +
1246 + $user_id = 'visualizer_' . preg_replace( '/[^\w\d]*/', '', get_site_url() ); // Use a normalized version of the site URL as a user ID.
1247 +
1248 + $license_data = get_option( 'visualizer_pro_license_data', false );
1249 + if ( false !== $license_data && isset( $license_data->key ) ) {
1250 + $user_id = 'visualizer_' . $license_data->key;
1251 + }
1252 +
1253 + return array(
1254 + 'userId' => $user_id,
1255 + 'attributes' => array(
1256 + 'days_since_install' => strval( $install_category ),
1257 + 'free_version' => $plugin_version,
1258 + 'pro_version' => defined( 'VISUALIZER_PRO_VERSION' ) ? VISUALIZER_PRO_VERSION : '',
1259 + 'license_status' => apply_filters( 'product_visualizer_license_status', 'invalid' ),
1260 + ),
1261 + );
1262 + }
1263 +
1264 + /**
1265 + * Load the survey.
1266 + */
1267 + private function load_survey() {
1268 +
1269 + if ( defined( 'TI_CYPRESS_TESTING' ) ) {
1270 + return;
1271 + }
1272 +
1273 + $survey_handler = apply_filters( 'themeisle_sdk_dependency_script_handler', 'survey' );
1274 +
1275 + if ( empty( $survey_handler ) ) {
1276 + return;
1277 + }
1278 +
1279 + $metadata = $this->get_survey_metadata();
1280 +
1281 + do_action( 'themeisle_sdk_dependency_enqueue_script', 'survey' );
1282 + wp_enqueue_script( 'visualizer_chart_survey', VISUALIZER_ABSURL . 'js/survey.js', array( $survey_handler ), $metadata['attributes']['free_version'], true );
1283 + wp_localize_script( 'visualizer_chart_survey', 'visualizerSurveyData', $metadata );
1284 + }
547 1285 }