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