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 +796 -92 3.0.73.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,16 +311,23 @@
150 311 public function enqueueMediaScripts() {
151 312 global $typenow;
152 313 if ( post_type_supports( $typenow, 'editor' ) ) {
153 314 wp_enqueue_style( 'visualizer-media', VISUALIZER_ABSURL . 'css/media.css', array( 'media-views' ), Visualizer_Plugin::VERSION );
154 - wp_enqueue_script( 'visualizer-google-jsapi-new', '//www.gstatic.com/charts/loader.js', array( 'media-editor' ), null, true );
155 - wp_enqueue_script( 'visualizer-google-jsapi-old', '//www.google.com/jsapi', array( 'visualizer-google-jsapi-new' ), null, true );
156 - wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', array( 'visualizer-google-jsapi-old' ), Visualizer_Plugin::VERSION, true );
315 +
316 + // Load all the assets for the different libraries we support.
317 + $deps = array(
318 + Visualizer_Render_Sidebar_Google::enqueue_assets( array( 'media-editor' ) ),
319 + Visualizer_Render_Sidebar_Type_DataTable_Tabular::enqueue_assets( array( 'media-editor' ) ),
320 + );
321 +
322 + wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', $deps, Visualizer_Plugin::VERSION, true );
157 323 wp_enqueue_script( 'visualizer-media-collection', VISUALIZER_ABSURL . 'js/media/collection.js', array( 'visualizer-media-model' ), Visualizer_Plugin::VERSION, true );
158 324 wp_enqueue_script( 'visualizer-media-controller', VISUALIZER_ABSURL . 'js/media/controller.js', array( 'visualizer-media-collection' ), Visualizer_Plugin::VERSION, true );
159 325 wp_enqueue_script( 'visualizer-media-view', VISUALIZER_ABSURL . 'js/media/view.js', array( 'visualizer-media-controller' ), Visualizer_Plugin::VERSION, true );
160 326 wp_localize_script(
161 - 'visualizer-media-view', 'visualizer', array(
327 + 'visualizer-media-view',
328 + 'visualizer',
329 + array(
162 330 'i10n' => array(
163 331 'insert' => __( 'Insert', 'visualizer' ),
164 332 ),
165 333 )
@@ -198,9 +366,9 @@
198 366 'filters' => $chart_types,
199 367 'types' => array_keys( $chart_types ),
200 368 ),
201 369 'nonce' => wp_create_nonce(),
202 - 'buildurl' => add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ),
370 + 'buildurl' => esc_url( add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ) ),
203 371 );
204 372
205 373 return $strings;
206 374 }
@@ -213,9 +381,9 @@
213 381 * @static
214 382 * @access private
215 383 * @return array The associated array of chart types with localized names.
216 384 */
217 - public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false, $add_select = false ) {
385 + public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false, $add_select = false, $where = null ) {
218 386 $additional = array();
219 387 if ( $add_select ) {
220 388 $additional['select'] = array(
221 389 'name' => esc_html__( 'All', 'visualizer' ),
@@ -222,59 +390,91 @@
222 390 'enabled' => true,
223 391 );
224 392 }
225 393
394 + $enabled = self::proFeaturesLocked();
395 +
226 396 $types = array_merge(
227 - $additional, array(
397 + $additional,
398 + array(
399 + 'tabular' => array(
400 + 'name' => esc_html__( 'Table', 'visualizer' ),
401 + 'enabled' => true,
402 + 'supports' => $enabled ? array( 'Google Charts', 'DataTable' ) : array( 'DataTable' ),
403 + ),
228 404 'pie' => array(
229 - 'name' => esc_html__( 'Pie', 'visualizer' ),
405 + 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
230 406 'enabled' => true,
407 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
231 408 ),
232 409 'line' => array(
233 410 'name' => esc_html__( 'Line', 'visualizer' ),
234 411 'enabled' => true,
412 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
235 413 ),
414 + 'bar' => array(
415 + 'name' => esc_html__( 'Bar', 'visualizer' ),
416 + 'enabled' => true,
417 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
418 + ),
236 419 'area' => array(
237 420 'name' => esc_html__( 'Area', 'visualizer' ),
238 - 'enabled' => true,
421 + 'enabled' => $enabled,
422 + // in ChartJS, the fill option is used to make Line chart an area: https://www.chartjs.org/docs/latest/charts/area.html
423 + 'supports' => array( 'Google Charts' ),
239 424 ),
240 425 'geo' => array(
241 426 'name' => esc_html__( 'Geo', 'visualizer' ),
242 - 'enabled' => true,
427 + 'enabled' => $enabled,
428 + 'supports' => array( 'Google Charts' ),
243 429 ),
244 - 'bar' => array(
245 - 'name' => esc_html__( 'Bar', 'visualizer' ),
246 - 'enabled' => true,
247 - ),
248 430 'column' => array(
249 431 'name' => esc_html__( 'Column', 'visualizer' ),
250 - 'enabled' => true,
432 + 'enabled' => $enabled,
433 + 'supports' => array( 'Google Charts', 'ChartJS' ),
251 434 ),
252 - 'gauge' => array(
253 - 'name' => esc_html__( 'Gauge', 'visualizer' ),
254 - 'enabled' => true,
435 + 'bubble' => array(
436 + 'name' => esc_html__( 'Bubble', 'visualizer' ),
437 + 'enabled' => $enabled,
438 + // chartjs' bubble is ugly looking (and it won't work off the default bubble.csv) so it is being excluded for the time being.
439 + 'supports' => array( 'Google Charts' ),
255 440 ),
256 441 'scatter' => array(
257 442 'name' => esc_html__( 'Scatter', 'visualizer' ),
258 - 'enabled' => true,
443 + 'enabled' => $enabled,
444 + 'supports' => array( 'Google Charts' ),
259 445 ),
446 + 'gauge' => array(
447 + 'name' => esc_html__( 'Gauge', 'visualizer' ),
448 + 'enabled' => $enabled,
449 + 'supports' => array( 'Google Charts' ),
450 + ),
260 451 'candlestick' => array(
261 452 'name' => esc_html__( 'Candlestick', 'visualizer' ),
262 - 'enabled' => true,
453 + 'enabled' => $enabled,
454 + 'supports' => array( 'Google Charts' ),
263 455 ),
264 456 // pro types
265 - 'table' => array(
266 - 'name' => esc_html__( 'Table', 'visualizer' ),
267 - 'enabled' => false,
268 - ),
269 457 'timeline' => array(
270 458 'name' => esc_html__( 'Timeline', 'visualizer' ),
271 459 'enabled' => false,
460 + 'supports' => array( 'Google Charts', 'ChartJS' ),
272 461 ),
273 462 'combo' => array(
274 463 'name' => esc_html__( 'Combo', 'visualizer' ),
275 464 'enabled' => false,
465 + 'supports' => array( 'Google Charts' ),
276 466 ),
467 + 'polarArea' => array(
468 + 'name' => esc_html__( 'Polar Area', 'visualizer' ),
469 + 'enabled' => false,
470 + 'supports' => array( 'ChartJS' ),
471 + ),
472 + 'radar' => array(
473 + 'name' => esc_html__( 'Radar/Spider', 'visualizer' ),
474 + 'enabled' => false,
475 + 'supports' => array( 'ChartJS' ),
476 + ),
277 477 )
278 478 );
279 479 $types = apply_filters( 'visualizer_pro_chart_types', $types );
280 480 if ( $enabledOnly ) {
@@ -283,8 +483,12 @@
283 483 if ( ! is_array( $array ) ) {
284 484 // support for old pro
285 485 $array = array( 'enabled' => true, 'name' => $array );
286 486 }
487 + // backward compatibility for PRO before v1.9.0
488 + if ( ! array_key_exists( 'supports', $array ) ) {
489 + $array['supports'] = array( 'Google Charts' );
490 + }
287 491 if ( ! $array['enabled'] ) {
288 492 continue;
289 493 }
290 494 $filtered[ $type ] = $array;
@@ -297,13 +501,74 @@
297 501 if ( ! is_array( $array ) ) {
298 502 // support for old pro
299 503 $array = array( 'enabled' => true, 'name' => $array );
300 504 }
505 + // backward compatibility for PRO before v1.9.0
506 + if ( ! array_key_exists( 'supports', $array ) ) {
507 + $array['supports'] = array( 'Google Charts' );
508 + }
301 509 $doubleD[ $type ] = $array['name'];
302 510 }
303 511 $types = $doubleD;
304 512 }
305 513
514 + return self::handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where );
515 + }
516 +
517 + /**
518 + * Handle (soon-to-be) deprecated charts.
519 + */
520 + private static function handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where ) {
521 + $deprecated = array();
522 +
523 + switch ( $where ) {
524 + case 'types':
525 + // fall-through
526 + case 'library':
527 + // if a user has a Gauge/Candlestick chart, then let them keep using it.
528 + if ( ! Visualizer_Module::is_pro() ) {
529 + if ( ! self::hasChartType( 'gauge' ) ) {
530 + if ( $get2Darray ) {
531 + $deprecated[] = 'gauge';
532 + } else {
533 + $types['gauge']['enabled'] = false;
534 + }
535 + }
536 + if ( ! self::hasChartType( 'candlestick' ) ) {
537 + if ( $get2Darray ) {
538 + $deprecated[] = 'candlestick';
539 + } else {
540 + $types['candlestick']['enabled'] = false;
541 + }
542 + }
543 + }
544 + break;
545 + default:
546 + // if a user has a Gauge/Candlestick chart, then let them keep using it.
547 + if ( ! Visualizer_Module::is_pro() ) {
548 + if ( ! self::hasChartType( 'gauge' ) ) {
549 + if ( $get2Darray ) {
550 + $deprecated[] = 'gauge';
551 + } else {
552 + $types['gauge']['enabled'] = false;
553 + }
554 + }
555 + if ( ! self::hasChartType( 'candlestick' ) ) {
556 + if ( $get2Darray ) {
557 + $deprecated[] = 'candlestick';
558 + } else {
559 + $types['candlestick']['enabled'] = false;
560 + }
561 + }
562 + }
563 + }
564 +
565 + if ( $deprecated ) {
566 + foreach ( $deprecated as $type ) {
567 + unset( $types[ $type ] );
568 + }
569 + }
570 +
306 571 return $types;
307 572 }
308 573
309 574 /**
@@ -313,11 +578,11 @@
313 578 * @global string $pagenow The name of the current page.
314 579 *
315 580 * @access public
316 581 */
317 - public function renderTempaltes() {
582 + public function renderTemplates() {
318 583 global $pagenow;
319 - if ( 'post.php' != $pagenow && 'post-new.php' != $pagenow ) {
584 + if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
320 585 return;
321 586 }
322 587 $render = new Visualizer_Render_Templates();
323 588 $render->render();
@@ -335,26 +600,41 @@
335 600 *
336 601 * @param string $suffix The current page suffix.
337 602 */
338 603 public function enqueueLibraryScripts( $suffix ) {
339 - if ( $suffix == $this->_libraryPage ) {
604 + if ( $suffix === $this->_libraryPage ) {
340 605 wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
341 606 $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
342 607 wp_enqueue_media();
343 608 wp_enqueue_script(
344 - 'visualizer-library', VISUALIZER_ABSURL . 'js/library.js', array(
609 + 'visualizer-library',
610 + VISUALIZER_ABSURL . 'js/library.js',
611 + array(
345 612 'jquery',
346 613 'media-views',
347 - ), Visualizer_Plugin::VERSION, true
614 + 'clipboard',
615 + ),
616 + Visualizer_Plugin::VERSION,
617 + true
348 618 );
349 - wp_enqueue_script( 'google-jsapi-new', '//www.gstatic.com/charts/loader.js', array(), null, true );
350 - wp_enqueue_script( 'google-jsapi-old', '//www.google.com/jsapi', array( 'google-jsapi-new' ), null, true );
351 - wp_enqueue_script(
352 - 'visualizer-render', VISUALIZER_ABSURL . 'js/render.js', array(
353 - 'google-jsapi-old',
354 - 'visualizer-library',
355 - ), Visualizer_Plugin::VERSION, true
356 - );
619 +
620 + wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
621 +
622 + $query = $this->getQuery();
623 + while ( $query->have_posts() ) {
624 + $chart = $query->next_post();
625 + $library = $this->load_chart_type( $chart->ID );
626 + if ( is_null( $library ) ) {
627 + continue;
628 + }
629 + wp_enqueue_script(
630 + "visualizer-render-$library",
631 + VISUALIZER_ABSURL . 'js/render-facade.js',
632 + apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
633 + Visualizer_Plugin::VERSION,
634 + true
635 + );
636 + }
357 637 }
358 638 }
359 639
360 640 /**
@@ -381,24 +661,191 @@
381 661 *
382 662 * @access public
383 663 */
384 664 public function registerAdminMenu() {
385 - $title = esc_html__( 'Visualizer Library', 'visualizer' );
386 - $callback = array( $this, 'renderLibraryPage' );
387 - $this->_libraryPage = add_submenu_page( 'upload.php', $title, $title, 'edit_posts', Visualizer_Plugin::NAME, $callback );
665 + $svg_base64_icon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNzdweCIgaGVpZ2h0PSI3N3B4IiB2aWV3Qm94PSIwIDAgNzcgNzciIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjYgKDY3NDkxKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Db21iaW5lZCBTaGFwZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxnIGlkPSJQcm9kdWN0LVBhZ2UiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJXb3JkUHJlc3MtcGx1Z2lucyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE5MC4wMDAwMDAsIC00MzUuMDAwMDAwKSIgZmlsbD0iIzM5QzNEMiI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMjguNSw1MTIgQzIwNy4yMzcwMzcsNTEyIDE5MCw0OTQuNzYyOTYzIDE5MCw0NzMuNSBDMTkwLDQ1Mi4yMzcwMzcgMjA3LjIzNzAzNyw0MzUgMjI4LjUsNDM1IEMyNDkuNzYyOTYzLDQzNSAyNjcsNDUyLjIzNzAzNyAyNjcsNDczLjUgQzI2Nyw0OTQuNzYyOTYzIDI0OS43NjI5NjMsNTEyIDIyOC41LDUxMiBaIE0yNDYuODQzNzUsNDgzLjU5MjA1OSBMMjE1LjYyNSw0ODMuNTkyMDU5IEwyMTUuNjI1LDQ2MC44MjY1NDQgQzIxNS42MjUsNDYwLjE2NDU0NyAyMTUuMTA3NTc4LDQ1OS42MjgzNTkgMjE0LjQ2ODc1LDQ1OS42MjgzNTkgTDIxMi4xNTYyNSw0NTkuNjI4MzU5IEMyMTEuNTE3NDIyLDQ1OS42MjgzNTkgMjExLDQ2MC4xNjQ1NDcgMjExLDQ2MC44MjY1NDQgTDIxMSw0ODUuOTg4NDI5IEMyMTEsNDg3LjMxMTY3NCAyMTIuMDM1NTY2LDQ4OC4zODQ3OTggMjEzLjMxMjUsNDg4LjM4NDc5OCBMMjQ2Ljg0Mzc1LDQ4OC4zODQ3OTggQzI0Ny40ODI1NzgsNDg4LjM4NDc5OCAyNDgsNDg3Ljg0ODYxMSAyNDgsNDg3LjE4NjYxMyBMMjQ4LDQ4NC43OTAyNDQgQzI0OCw0ODQuMTI4MjQ2IDI0Ny40ODI1NzgsNDgzLjU5MjA1OSAyNDYuODQzNzUsNDgzLjU5MjA1OSBaIE0yNDQuNTMxMjUsNDYyLjAyNDcyOSBMMjM1Ljk5OTU3LDQ2Mi4wMjQ3MjkgQzIzNC40NTQ1MzEsNDYyLjAyNDcyOSAyMzMuNjgwNTY2LDQ2My45NjA1NDcgMjM0Ljc3MzIyMyw0NjUuMDkyODMyIEwyMzcuMTE0NjI5LDQ2Ny41MTkxNTYgTDIzMS44MTI1LDQ3My4wMTQzMzIgTDIyNi41MTAzNzEsNDY3LjUxOTkwNSBDMjI1LjYwNzA1MSw0NjYuNTgzODIzIDIyNC4xNDI5NDksNDY2LjU4MzgyMyAyMjMuMjQwMzUyLDQ2Ny41MTk5MDUgTDIxOC4yNzY0MjYsNDcyLjY2Mzg2MyBDMjE3LjgyNDc2Niw0NzMuMTMxOTA0IDIxNy44MjQ3NjYsNDczLjg5MDUwNSAyMTguMjc2NDI2LDQ3NC4zNTg1NDYgTDIxOS45MTEwNzQsNDc2LjA1MjQ4IEMyMjAuMzYyNzM0LDQ3Ni41MjA1MjEgMjIxLjA5NDc4NSw0NzYuNTIwNTIxIDIyMS41NDY0NDUsNDc2LjA1MjQ4IEwyMjQuODc1LDQ3Mi42MDI0NTYgTDIzMC4xNzcxMjksNDc4LjA5Njg4MyBDMjMxLjA4MDQ0OSw0NzkuMDMyOTY1IDIzMi41NDQ1NTEsNDc5LjAzMjk2NSAyMzMuNDQ3MTQ4LDQ3OC4wOTY4ODMgTDI0MC4zODQ2NDgsNDcwLjkwNzc3MyBMMjQyLjcyNjA1NSw0NzMuMzM0MDk4IEMyNDMuODE4NzExLDQ3NC40NjYzODIgMjQ1LjY4Njc3Nyw0NzMuNjY0MzQ3IDI0NS42ODY3NzcsNDcyLjA2MzI3MyBMMjQ1LjY4Njc3Nyw0NjMuMjIyOTE0IEMyNDUuNjg3NSw0NjIuNTYwOTE3IDI0NS4xNzAwNzgsNDYyLjAyNDcyOSAyNDQuNTMxMjUsNDYyLjAyNDcyOSBaIiBpZD0iQ29tYmluZWQtU2hhcGUiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==';
666 +
667 + $this->_libraryPage = add_menu_page( __( 'Visualizer', 'visualizer' ), __( 'Visualizer', 'visualizer' ), 'edit_posts', Visualizer_Plugin::NAME, array( $this, 'renderLibraryPage' ), $svg_base64_icon, 99.7666 );
668 +
669 + add_submenu_page(
670 + Visualizer_Plugin::NAME,
671 + __( 'Chart Library', 'visualizer' ),
672 + __( 'Chart Library', 'visualizer' ),
673 + 'edit_posts',
674 + 'admin.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' ) );
388 696 }
389 697
390 698 /**
391 - * Renders visualizer library page.
392 - *
393 - * @since 1.0.0
394 - *
395 - * @access public
699 + * Handle get pro plugin submenu.
396 700 */
397 - 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 +
398 842 // get current page
399 843 $page = filter_input(
400 - INPUT_GET, 'vpage', FILTER_VALIDATE_INT, array(
844 + INPUT_GET,
845 + 'vpage',
846 + FILTER_VALIDATE_INT,
847 + array(
401 848 'options' => array(
402 849 'min_range' => 1,
403 850 'default' => 1,
404 851 ),
@@ -403,29 +850,34 @@
403 850 'default' => 1,
404 851 ),
405 852 )
406 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 +
407 869 // the initial query arguments to fetch charts
408 870 $query_args = array(
409 871 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
410 - 'posts_per_page' => 6,
872 + 'posts_per_page' => $per_page,
411 873 'paged' => $page,
412 874 );
413 - // add chart type filter to the query arguments
414 - $filter = filter_input( INPUT_GET, 'type' );
415 - if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) {
416 - $query_args['meta_query'] = array(
417 - array(
418 - 'key' => Visualizer_Plugin::CF_CHART_TYPE,
419 - 'value' => $filter,
420 - 'compare' => '=',
421 - ),
422 - );
423 - } else {
424 - $filter = 'all';
425 - }
875 +
876 + $this->getDisplayFilters( $query_args );
877 +
426 878 // Added by Ash/Upwork
427 - $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
428 880 if ( $filterByMeta ) {
429 881 $query = array(
430 882 'key' => Visualizer_Plugin::CF_SETTINGS,
431 883 'value' => $filterByMeta,
@@ -434,51 +886,158 @@
434 886 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
435 887 $meta[] = $query;
436 888 $query_args['meta_query'] = $meta;
437 889 }
438 - // Added by Ash/Upwork
439 - // 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() {
440 915 $charts = array();
441 - $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 = '';
442 937 while ( $query->have_posts() ) {
443 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 +
444 947 // fetch and update settings
445 948 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
446 - unset( $settings['height'], $settings['width'] );
447 - $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
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 +
448 959 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
449 - $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( $chart->post_content ) ), $chart->ID, $type );
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 +
450 990 // add chart to the array
451 - $charts[ 'visualizer-' . $chart->ID ] = array(
991 + $charts[ $id ] = array(
452 992 'id' => $chart->ID,
453 993 'type' => $type,
454 994 'series' => $series,
455 995 'settings' => $settings,
456 996 'data' => $data,
997 + 'library' => $library,
457 998 );
458 999 }
459 1000 // enqueue charts array
460 1001 $ajaxurl = admin_url( 'admin-ajax.php' );
461 1002 wp_localize_script(
462 - 'visualizer-library', 'visualizer', array(
1003 + 'visualizer-library',
1004 + 'visualizer',
1005 + array(
463 1006 'language' => $this->get_language(),
464 1007 'map_api_key' => get_option( 'visualizer-map-api-key' ),
465 1008 'charts' => $charts,
466 1009 'urls' => array(
467 - 'base' => add_query_arg( 'vpage', false ),
468 - 'create' => add_query_arg(
469 - array(
470 - 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
471 - 'library' => 'yes',
472 - ), $ajaxurl
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 + )
473 1022 ),
474 - 'edit' => add_query_arg(
475 - array(
476 - 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
477 - 'library' => 'yes',
478 - ), $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 + )
479 1032 ),
480 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 + ),
481 1040 )
482 1041 );
483 1042 // render library page
484 1043 $render = new Visualizer_Render_Library();
@@ -483,12 +1042,13 @@
483 1042 // render library page
484 1043 $render = new Visualizer_Render_Library();
485 1044 $render->charts = $charts;
486 1045 $render->type = $filter;
487 - $render->types = self::_getChartTypesLocalized();
1046 + $render->types = self::_getChartTypesLocalized( false, false, false, true );
1047 + $render->custom_css = $css;
488 1048 $render->pagination = paginate_links(
489 1049 array(
490 - 'base' => add_query_arg( 'vpage', '%#%' ),
1050 + 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
491 1051 'format' => '',
492 1052 'current' => $page,
493 1053 'total' => $query->max_num_pages,
494 1054 'type' => 'array',
@@ -493,8 +1053,11 @@
493 1053 'total' => $query->max_num_pages,
494 1054 'type' => 'array',
495 1055 )
496 1056 );
1057 +
1058 + $this->load_survey();
1059 +
497 1060 $render->render();
498 1061 }
499 1062
500 1063 /**
@@ -509,14 +1072,14 @@
509 1072 *
510 1073 * @return array Updated array of action links.
511 1074 */
512 1075 public function getPluginActionLinks( $links, $file ) {
513 - if ( $file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1076 + if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
514 1077 array_unshift(
515 1078 $links,
516 1079 sprintf(
517 1080 '<a href="%s">%s</a>',
518 - admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ),
1081 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
519 1082 esc_html__( 'Library', 'visualizer' )
520 1083 )
521 1084 );
522 1085 }
@@ -536,17 +1099,17 @@
536 1099 *
537 1100 * @return array Updated array of plugin meta links.
538 1101 */
539 1102 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
540 - if ( $plugin_file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1103 + if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
541 1104 // knowledge base link
542 1105 $plugin_meta[] = sprintf(
543 - '<a href="https://github.com/codeinwp/visualizer/wiki" target="_blank">%s</a>',
544 - esc_html__( 'Knowledge Base', 'visualizer' )
1106 + '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1107 + esc_html__( 'Docs', 'visualizer' )
545 1108 );
546 1109 // flattr link
547 1110 $plugin_meta[] = sprintf(
548 - '<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>',
549 1112 esc_html__( 'Pro Addon', 'visualizer' )
550 1113 );
551 1114 }
552 1115
@@ -552,5 +1115,146 @@
552 1115
553 1116 return $plugin_meta;
554 1117 }
555 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 + }
556 1260 }