PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.3.1
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.3.1
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 +117 -914 4.0.83.3.1 View file →
@@ -29,10 +29,8 @@
29 29 class Visualizer_Module_Admin extends Visualizer_Module {
30 30
31 31 const NAME = __CLASS__;
32 32
33 - const OPTION_GLOBAL_SETTINGS = 'visualizer_global_settings';
34 -
35 33 /**
36 34 * Library page suffix.
37 35 *
38 36 * @since 1.0.0
@@ -42,24 +40,8 @@
42 40 */
43 41 private $_libraryPage;
44 42
45 43 /**
46 - * Support page suffix.
47 - *
48 - * @access private
49 - * @var string
50 - */
51 - private $_supportPage;
52 -
53 - /**
54 - * Settings page suffix.
55 - *
56 - * @access private
57 - * @var string
58 - */
59 - private $_settingsPage;
60 -
61 - /**
62 44 * Constructor.
63 45 *
64 46 * @since 1.0.0
65 47 *
@@ -70,138 +52,27 @@
70 52 public function __construct( Visualizer_Plugin $plugin ) {
71 53 parent::__construct( $plugin );
72 54 $this->_addAction( 'load-post.php', 'enqueueMediaScripts' );
73 55 $this->_addAction( 'load-post-new.php', 'enqueueMediaScripts' );
74 - $this->_addAction( 'enqueue_block_editor_assets', 'enqueueMediaScripts' );
75 56 $this->_addAction( 'admin_footer', 'renderTemplates' );
76 - $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 0 );
77 - $this->_addAction( 'admin_enqueue_scripts', 'enqueue_support_page' );
78 - $this->_addAction( 'admin_enqueue_scripts', 'enqueueSettingsScripts' );
79 - $this->_addAction( 'admin_post_visualizer_save_global_settings', 'saveGlobalSettings' );
57 + $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 8 );
80 58 $this->_addAction( 'admin_menu', 'registerAdminMenu' );
81 59 $this->_addFilter( 'media_view_strings', 'setupMediaViewStrings' );
82 60 $this->_addFilter( 'plugin_action_links', 'getPluginActionLinks', 10, 2 );
83 61 $this->_addFilter( 'plugin_row_meta', 'getPluginMetaLinks', 10, 2 );
62 + $this->_addFilter( 'visualizer_logger_data', 'getLoggerData' );
63 + $this->_addFilter( 'visualizer_get_chart_counts', 'getChartCountsByTypeAndMeta' );
84 64 $this->_addFilter( 'visualizer_feedback_review_trigger', 'feedbackReviewTrigger' );
85 - $this->_addFilter( 'themeisle_sdk_blackfriday_data', 'add_black_friday_data' );
86 65
87 - // screen pagination
88 - $this->_addFilter( 'set-screen-option', 'setScreenOptions', 10, 3 );
89 -
90 66 // revision support.
91 67 $this->_addFilter( 'wp_revisions_to_keep', 'limitRevisions', null, 10, 2 );
92 68 $this->_addAction( '_wp_put_post_revision', 'addRevision', null, 10, 1 );
93 69 $this->_addAction( 'wp_restore_post_revision', 'restoreRevision', null, 10, 2 );
94 70
95 - $this->_addAction( 'visualizer_chart_schedules_spl', 'addSplChartSchedules', null, 10, 3 );
96 -
97 71 $this->_addAction( 'admin_init', 'init' );
98 -
99 - $this->_addAction( 'visualizer_chart_languages', 'addMultilingualSupport' );
100 -
101 - $this->_addFilter( 'admin_footer_text', 'render_review_notice' );
102 -
103 - if ( ! defined( 'TI_E2E_TESTING' ) ) {
104 - $this->_addFilter( 'themeisle-sdk/survey/' . VISUALIZER_DIRNAME, 'get_survey_metadata', 10, 2 );
105 - }
106 -
107 - if ( defined( 'TI_E2E_TESTING' ) ) {
108 - $this->load_cypress_hooks();
109 - }
110 72 }
111 - /**
112 - * Display review notice.
113 - */
114 - public function render_review_notice( $footer_text ) {
115 - $current_screen = get_current_screen();
116 73
117 - $visualizer_page_ids = array( 'toplevel_page_visualizer', 'visualizer_page_viz-support', 'visualizer_page_ti-about-visualizer' );
118 -
119 - if ( ! empty( $current_screen ) && isset( $current_screen->id ) ) {
120 - foreach ( $visualizer_page_ids as $page_to_check ) {
121 - if ( strpos( $current_screen->id, $page_to_check ) !== false ) {
122 - $footer_text = sprintf(
123 - // translators: %1$s - the name of the plugin (Visualizer), %2$s - message (You can help us by leaving a), %3$s - HTML entity code.
124 - __( 'Enjoying %1$s? %2$s %3$s rating. Thank you for being so supportive!', 'visualizer' ),
125 - '<b>Visualizer</b>',
126 - esc_html__( 'You can help us by leaving a', 'visualizer' ),
127 - '<a href="https://wordpress.org/support/plugin/visualizer/reviews/#new-post" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
128 - );
129 - break;
130 - }
131 - }
132 - }
133 -
134 - return $footer_text;
135 - }
136 -
137 -
138 74 /**
139 - * Define the hooks that are needed for cypress.
140 - *
141 - * @since 3.4.0
142 - * @access private
143 - */
144 - private function load_cypress_hooks() {
145 - // all charts should load on the same page without pagination.
146 - add_filter(
147 - 'visualizer_query_args', function ( $args ) {
148 - $args['posts_per_page'] = 20;
149 - return $args;
150 - }, 10, 1
151 - );
152 - }
153 -
154 - /**
155 - * Add disabled `optgroup` schedules to the drop downs.
156 - *
157 - * @since ?
158 - *
159 - * @access public
160 - *
161 - * @param string $feature The feature for which to add schedules.
162 - * @param int $chart_id The chart ID.
163 - * @param int $plan The plan number.
164 - */
165 - public function addSplChartSchedules( $feature, $chart_id, $plan ) {
166 - if ( apply_filters( 'visualizer_is_business', false ) ) {
167 - return;
168 - }
169 -
170 - $is_new_personal = apply_filters( 'visualizer_is_new_personal', false );
171 -
172 - $hours = array(
173 - '0.16' => __( '10 minutes', 'visualizer' ),
174 - '1' => __( 'Each hour', 'visualizer' ),
175 - '12' => __( 'Each 12 hours', 'visualizer' ),
176 - '24' => __( 'Each day', 'visualizer' ),
177 - '72' => __( 'Each 3 days', 'visualizer' ),
178 - );
179 -
180 - switch ( $feature ) {
181 - case 'json':
182 - case 'csv':
183 - // no more schedules if pro is already active.
184 - if ( Visualizer_Module::is_pro() && ! $is_new_personal ) {
185 - return;
186 - }
187 - break;
188 - case 'wp':
189 - // fall-through.
190 - case 'db':
191 - break;
192 - default:
193 - return;
194 - }
195 -
196 - echo '<optgroup disabled label="' . __( 'Upgrade required', 'visualizer' ) . '">';
197 - foreach ( $hours as $hour => $desc ) {
198 - echo '<option disabled>' . $desc . '</option>';
199 - }
200 - echo '</optgroup>';
201 - }
202 -
203 - /**
204 75 * No limits on revisions.
205 76 */
206 77 public function limitRevisions( $num, $post ) {
207 78 if ( Visualizer_Plugin::CPT_VISUALIZER === $post->post_type ) {
@@ -221,9 +92,9 @@
221 92
222 93 if ( $meta ) {
223 94 foreach ( $meta as $key => $value ) {
224 95 if ( 0 === strpos( $key, 'visualizer' ) ) {
225 - add_metadata( 'post', $revision_id, $key, self::maybe_decode_content( $value[0] ) );
96 + add_metadata( 'post', $revision_id, $key, maybe_unserialize( $value[0] ) );
226 97 }
227 98 }
228 99 }
229 100 }
@@ -249,9 +120,9 @@
249 120
250 121 if ( $meta ) {
251 122 foreach ( $meta as $key => $value ) {
252 123 if ( 0 === strpos( $key, 'visualizer' ) ) {
253 - add_post_meta( $post_id, $key, self::maybe_decode_content( $value[0] ) );
124 + add_post_meta( $post_id, $key, maybe_unserialize( $value[0] ) );
254 125 }
255 126 }
256 127 }
257 128 }
@@ -262,30 +133,17 @@
262 133 *
263 134 * @access public
264 135 */
265 136 public function init() {
266 - if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' === get_user_option( 'rich_editing' ) ) {
137 + // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
138 + if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' == get_user_option( 'rich_editing' ) ) {
267 139 $this->_addFilter( 'mce_external_languages', 'add_tinymce_lang', 10, 1 );
268 140 $this->_addFilter( 'mce_external_plugins', 'tinymce_plugin', 10, 1 );
269 141 $this->_addFilter( 'mce_buttons', 'register_mce_button', 10, 1 );
270 - $this->_addFilter( 'tiny_mce_before_init', 'get_strings_for_block', 10, 1 );
271 142 }
272 143 }
273 144
274 145 /**
275 - * Add the strings required for the TinyMCE buttons for the classic block (not the classic editor).
276 - *
277 - * @since ?
278 - * @access friendly
279 - */
280 - public function get_strings_for_block( $settings ) {
281 - $class = new Visualizer_Module_Language();
282 - $strings = $class->get_strings();
283 - $array = array( 'visualizer_tinymce_plugin' => json_encode( $strings ) );
284 - return array_merge( $settings, $array );
285 - }
286 -
287 - /**
288 146 * Load plugin translation for - TinyMCE API
289 147 *
290 148 * @access public
291 149 * @param array $arr The tinymce_lang array.
@@ -354,40 +212,15 @@
354 212 * @access public
355 213 */
356 214 public function enqueueMediaScripts() {
357 215 global $typenow;
358 - global $current_screen;
359 -
360 - if ( post_type_supports( $typenow, 'editor' ) || $current_screen->id === 'widgets' || $current_screen->id === 'customize' ) {
216 + if ( post_type_supports( $typenow, 'editor' ) ) {
361 217 wp_enqueue_style( 'visualizer-media', VISUALIZER_ABSURL . 'css/media.css', array( 'media-views' ), Visualizer_Plugin::VERSION );
362 218
363 - $d3_renderer_asset = VISUALIZER_ABSPATH . '/classes/Visualizer/D3Renderer/build/index.asset.php';
364 - if ( file_exists( $d3_renderer_asset ) && ! wp_script_is( 'visualizer-d3-renderer', 'registered' ) ) {
365 - // @phpstan-ignore-next-line
366 - $d3_asset = include $d3_renderer_asset;
367 - wp_register_script(
368 - 'visualizer-d3-renderer',
369 - VISUALIZER_ABSURL . 'classes/Visualizer/D3Renderer/build/index.js',
370 - array_merge( $d3_asset['dependencies'], array( 'jquery' ) ),
371 - $d3_asset['version'],
372 - true
373 - );
374 - }
375 - if ( wp_script_is( 'visualizer-d3-renderer', 'registered' ) ) {
376 - wp_enqueue_script( 'visualizer-d3-renderer' );
377 - wp_localize_script(
378 - 'visualizer-d3-renderer',
379 - 'vizD3Renderer',
380 - array(
381 - 'iframeJsUrl' => VISUALIZER_ABSURL . 'classes/Visualizer/D3Renderer/build/iframe.js',
382 - )
383 - );
384 - }
385 -
386 219 // Load all the assets for the different libraries we support.
387 220 $deps = array(
388 221 Visualizer_Render_Sidebar_Google::enqueue_assets( array( 'media-editor' ) ),
389 - Visualizer_Render_Sidebar_Type_DataTable_Tabular::enqueue_assets( array( 'media-editor' ) ),
222 + Visualizer_Render_Sidebar_Type_DataTable_DataTable::enqueue_assets( array( 'media-editor' ) ),
390 223 );
391 224
392 225 wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', $deps, Visualizer_Plugin::VERSION, true );
393 226 wp_enqueue_script( 'visualizer-media-collection', VISUALIZER_ABSURL . 'js/media/collection.js', array( 'visualizer-media-model' ), Visualizer_Plugin::VERSION, true );
@@ -397,9 +230,9 @@
397 230 'visualizer-media-view',
398 231 'visualizer',
399 232 array(
400 233 'i10n' => array(
401 - 'insert' => __( 'Insert Chart', 'visualizer' ),
234 + 'insert' => __( 'Insert', 'visualizer' ),
402 235 ),
403 236 )
404 237 );
405 238 wp_enqueue_script( 'visualizer-media-toolbar', VISUALIZER_ABSURL . 'js/media/toolbar.js', array( 'visualizer-media-view' ), Visualizer_Plugin::VERSION, true );
@@ -428,9 +261,9 @@
428 261 'controller' => array(
429 262 'title' => esc_html__( 'Visualizations', 'visualizer' ),
430 263 ),
431 264 'routers' => array(
432 - 'library' => esc_html__( 'Insert from Library', 'visualizer' ),
265 + 'library' => esc_html__( 'From Library', 'visualizer' ),
433 266 'create' => esc_html__( 'Create New', 'visualizer' ),
434 267 ),
435 268 'library' => array(
436 269 'filters' => $chart_types,
@@ -435,10 +268,10 @@
435 268 'library' => array(
436 269 'filters' => $chart_types,
437 270 'types' => array_keys( $chart_types ),
438 271 ),
439 - 'nonce' => wp_create_nonce( Visualizer_Plugin::ACTION_GET_CHARTS ),
440 - 'buildurl' => esc_url( add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ) ),
272 + 'nonce' => wp_create_nonce(),
273 + 'buildurl' => add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ),
441 274 );
442 275
443 276 return $strings;
444 277 }
@@ -460,17 +293,15 @@
460 293 'enabled' => true,
461 294 );
462 295 }
463 296
464 - $enabled = self::proFeaturesEnabled();
465 -
466 297 $types = array_merge(
467 298 $additional,
468 299 array(
469 - 'tabular' => array(
300 + 'dataTable' => array(
470 301 'name' => esc_html__( 'Table', 'visualizer' ),
471 302 'enabled' => true,
472 - 'supports' => $enabled ? array( 'Google Charts', 'DataTable' ) : array( 'DataTable' ),
303 + 'supports' => array( 'DataTable' ),
473 304 ),
474 305 'pie' => array(
475 306 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
476 307 'enabled' => true,
@@ -480,81 +311,69 @@
480 311 'name' => esc_html__( 'Line', 'visualizer' ),
481 312 'enabled' => true,
482 313 'supports' => array( 'Google Charts', 'ChartJS' ),
483 314 ),
484 - 'bar' => array(
485 - 'name' => esc_html__( 'Bar', 'visualizer' ),
486 - 'enabled' => true,
487 - 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
488 - ),
489 315 'area' => array(
490 316 'name' => esc_html__( 'Area', 'visualizer' ),
491 - 'enabled' => $enabled,
317 + 'enabled' => true,
492 318 // in ChartJS, the fill option is used to make Line chart an area: https://www.chartjs.org/docs/latest/charts/area.html
493 319 'supports' => array( 'Google Charts' ),
494 - 'demo_url' => 'https://demo.themeisle.com/visualizer/area-chart/',
495 320 ),
496 321 'geo' => array(
497 322 'name' => esc_html__( 'Geo', 'visualizer' ),
498 - 'enabled' => $enabled,
323 + 'enabled' => true,
499 324 'supports' => array( 'Google Charts' ),
500 - 'demo_url' => 'https://demo.themeisle.com/visualizer/geo-chart/',
501 325 ),
326 + 'bar' => array(
327 + 'name' => esc_html__( 'Bar', 'visualizer' ),
328 + 'enabled' => true,
329 + 'supports' => array( 'Google Charts', 'ChartJS' ),
330 + ),
502 331 'column' => array(
503 332 'name' => esc_html__( 'Column', 'visualizer' ),
504 - 'enabled' => $enabled,
333 + 'enabled' => true,
505 334 'supports' => array( 'Google Charts', 'ChartJS' ),
506 - 'demo_url' => 'https://demo.themeisle.com/visualizer/column-chart/',
507 335 ),
508 - 'bubble' => array(
509 - 'name' => esc_html__( 'Bubble', 'visualizer' ),
510 - 'enabled' => $enabled,
511 - // chartjs' bubble is ugly looking (and it won't work off the default bubble.csv) so it is being excluded for the time being.
512 - 'supports' => array( 'Google Charts' ),
513 - 'demo_url' => 'https://demo.themeisle.com/visualizer/bubble-chart/',
514 - ),
515 336 'scatter' => array(
516 337 'name' => esc_html__( 'Scatter', 'visualizer' ),
517 - 'enabled' => $enabled,
338 + 'enabled' => true,
518 339 'supports' => array( 'Google Charts' ),
519 - 'demo_url' => 'https://demo.themeisle.com/visualizer/scatter-chart/',
520 340 ),
521 341 'gauge' => array(
522 342 'name' => esc_html__( 'Gauge', 'visualizer' ),
523 - 'enabled' => $enabled,
343 + 'enabled' => true,
524 344 'supports' => array( 'Google Charts' ),
525 - 'demo_url' => 'https://demo.themeisle.com/visualizer/gauge-chart/',
526 345 ),
527 346 'candlestick' => array(
528 347 'name' => esc_html__( 'Candlestick', 'visualizer' ),
529 - 'enabled' => $enabled,
348 + 'enabled' => true,
530 349 'supports' => array( 'Google Charts' ),
531 - 'demo_url' => 'https://demo.themeisle.com/visualizer/candlestick-chart/',
532 350 ),
533 351 // pro types
352 + 'table' => array(
353 + 'name' => esc_html__( 'Table (Deprecated)', 'visualizer' ),
354 + 'enabled' => false,
355 + 'supports' => array( 'Google Charts' ),
356 + ),
534 357 'timeline' => array(
535 358 'name' => esc_html__( 'Timeline', 'visualizer' ),
536 359 'enabled' => false,
537 360 'supports' => array( 'Google Charts', 'ChartJS' ),
538 - 'demo_url' => 'https://demo.themeisle.com/visualizer/timeline-chart/',
539 361 ),
540 362 'combo' => array(
541 363 'name' => esc_html__( 'Combo', 'visualizer' ),
542 364 'enabled' => false,
543 365 'supports' => array( 'Google Charts' ),
544 - 'demo_url' => 'https://demo.themeisle.com/visualizer/combo-chart/',
545 366 ),
546 367 'polarArea' => array(
547 368 'name' => esc_html__( 'Polar Area', 'visualizer' ),
548 369 'enabled' => false,
549 370 'supports' => array( 'ChartJS' ),
550 - 'demo_url' => 'https://demo.themeisle.com/visualizer/polar-area-chart/',
551 371 ),
552 372 'radar' => array(
553 373 'name' => esc_html__( 'Radar/Spider', 'visualizer' ),
554 374 'enabled' => false,
555 375 'supports' => array( 'ChartJS' ),
556 - 'demo_url' => 'https://demo.themeisle.com/visualizer/radar-spider-chart/',
557 376 ),
558 377 )
559 378 );
560 379 $types = apply_filters( 'visualizer_pro_chart_types', $types );
@@ -604,8 +423,18 @@
604 423 switch ( $where ) {
605 424 case 'types':
606 425 // fall-through
607 426 case 'library':
427 + // if the user has a Google Table chart, show it as deprecated otherwise remove the option from the library.
428 + if ( ! self::hasChartType( 'table' ) ) {
429 + $deprecated[] = 'table';
430 + if ( $get2Darray ) {
431 + $types['dataTable'] = esc_html__( 'Table', 'visualizer' );
432 + } else {
433 + $types['dataTable']['name'] = esc_html__( 'Table', 'visualizer' );
434 + }
435 + }
436 +
608 437 // if a user has a Gauge/Candlestick chart, then let them keep using it.
609 438 if ( ! Visualizer_Module::is_pro() ) {
610 439 if ( ! self::hasChartType( 'gauge' ) ) {
611 440 if ( $get2Darray ) {
@@ -623,8 +452,18 @@
623 452 }
624 453 }
625 454 break;
626 455 default:
456 + // remove the option to create a Google Table chart.
457 + $deprecated[] = 'table';
458 +
459 + // rename the new table chart type.
460 + if ( $get2Darray ) {
461 + $types['dataTable'] = esc_html__( 'Table', 'visualizer' );
462 + } else {
463 + $types['dataTable']['name'] = esc_html__( 'Table', 'visualizer' );
464 + }
465 +
627 466 // if a user has a Gauge/Candlestick chart, then let them keep using it.
628 467 if ( ! Visualizer_Module::is_pro() ) {
629 468 if ( ! self::hasChartType( 'gauge' ) ) {
630 469 if ( $get2Darray ) {
@@ -681,159 +520,44 @@
681 520 *
682 521 * @param string $suffix The current page suffix.
683 522 */
684 523 public function enqueueLibraryScripts( $suffix ) {
685 - if ( $suffix !== $this->_libraryPage ) {
686 - return;
687 - }
688 -
689 - wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
690 - $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
691 - wp_enqueue_media();
692 - wp_enqueue_script(
693 - 'visualizer-library',
694 - VISUALIZER_ABSURL . 'js/library.js',
695 - array(
696 - 'jquery',
697 - 'media-views',
698 - 'clipboard',
699 - ),
700 - Visualizer_Plugin::VERSION,
701 - true
702 - );
703 -
704 - wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
705 -
706 - $has_d3 = false;
707 - $query = $this->getQuery();
708 - while ( $query->have_posts() ) {
709 - $chart = $query->next_post();
710 - $library = $this->load_chart_type( $chart->ID );
711 - if ( is_null( $library ) ) {
712 - continue;
713 - }
524 + if ( $suffix === $this->_libraryPage ) {
525 + wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
526 + $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
527 + wp_enqueue_media();
714 528 wp_enqueue_script(
715 - "visualizer-render-$library",
716 - VISUALIZER_ABSURL . 'js/render-facade.js',
717 - apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
529 + 'visualizer-library',
530 + VISUALIZER_ABSURL . 'js/library.js',
531 + array(
532 + 'jquery',
533 + 'media-views',
534 + ),
718 535 Visualizer_Plugin::VERSION,
719 536 true
720 537 );
721 - if ( 'd3' === $library ) {
722 - $has_d3 = true;
723 - }
724 - }
725 538
726 - if ( $has_d3 ) {
727 - $d3_renderer_asset = VISUALIZER_ABSPATH . '/classes/Visualizer/D3Renderer/build/index.asset.php';
728 - if ( file_exists( $d3_renderer_asset ) && ! wp_script_is( 'visualizer-d3-renderer', 'registered' ) ) {
729 - /**
730 - * Ignore missing build asset in source checkout.
731 - *
732 - * @phpstan-ignore-next-line
733 - */
734 - $d3_asset = include $d3_renderer_asset;
735 - wp_register_script(
736 - 'visualizer-d3-renderer',
737 - VISUALIZER_ABSURL . 'classes/Visualizer/D3Renderer/build/index.js',
738 - array_merge( $d3_asset['dependencies'], array( 'jquery' ) ),
739 - $d3_asset['version'],
740 - true
741 - );
742 - wp_enqueue_script( 'visualizer-d3-renderer' );
743 - }
744 - wp_localize_script(
745 - 'visualizer-d3-renderer',
746 - 'vizD3Renderer',
747 - array(
748 - 'iframeJsUrl' => VISUALIZER_ABSURL . 'classes/Visualizer/D3Renderer/build/iframe.js',
749 - )
750 - );
751 - }
539 + wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
752 540
753 - $chart_builder_asset = VISUALIZER_ABSPATH . '/classes/Visualizer/ChartBuilder/build/index.asset.php';
754 - if ( file_exists( $chart_builder_asset ) ) {
755 - /**
756 - * Ignore missing build asset in source checkout.
757 - *
758 - * @phpstan-ignore-next-line
759 - */
760 - $asset = include $chart_builder_asset;
761 - $chart_builder_deps = $asset['dependencies'];
762 - if ( ! wp_script_is( 'visualizer-handsontable', 'registered' ) && defined( 'Visualizer_Pro_ABSURL' ) && defined( 'VISUALIZER_PRO_VERSION' ) ) {
763 - wp_register_script(
764 - 'visualizer-handsontable',
765 - Visualizer_Pro_ABSURL . 'vendor/handsontable/dist/handsontable.full.min.js',
766 - array(),
767 - VISUALIZER_PRO_VERSION,
541 + $query = $this->getQuery();
542 + while ( $query->have_posts() ) {
543 + $chart = $query->next_post();
544 + $library = $this->load_chart_type( $chart->ID );
545 + if ( is_null( $library ) ) {
546 + continue;
547 + }
548 + wp_enqueue_script(
549 + "visualizer-render-$library",
550 + VISUALIZER_ABSURL . 'js/render-facade.js',
551 + apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
552 + Visualizer_Plugin::VERSION,
768 553 true
769 554 );
770 555 }
771 - if ( ! wp_style_is( 'visualizer-handsontable', 'registered' ) && defined( 'Visualizer_Pro_ABSURL' ) && defined( 'VISUALIZER_PRO_VERSION' ) ) {
772 - wp_register_style(
773 - 'visualizer-handsontable',
774 - Visualizer_Pro_ABSURL . 'vendor/handsontable/dist/handsontable.full.min.css',
775 - array(),
776 - VISUALIZER_PRO_VERSION
777 - );
778 - }
779 - if ( wp_script_is( 'visualizer-handsontable', 'registered' ) ) {
780 - wp_enqueue_script( 'visualizer-handsontable' );
781 - $chart_builder_deps = array_unique( array_merge( $chart_builder_deps, array( 'visualizer-handsontable' ) ) );
782 - }
783 - if ( wp_style_is( 'visualizer-handsontable', 'registered' ) ) {
784 - wp_enqueue_style( 'visualizer-handsontable' );
785 - }
786 - wp_enqueue_script(
787 - 'visualizer-chart-builder',
788 - VISUALIZER_ABSURL . 'classes/Visualizer/ChartBuilder/build/index.js',
789 - $chart_builder_deps,
790 - $asset['version'],
791 - true
792 - );
793 - wp_enqueue_style(
794 - 'visualizer-chart-builder',
795 - VISUALIZER_ABSURL . 'classes/Visualizer/ChartBuilder/build/style-index.css',
796 - array(),
797 - $asset['version']
798 - );
799 - $chart_builder_css = VISUALIZER_ABSPATH . '/classes/Visualizer/ChartBuilder/build/index.css';
800 - if ( file_exists( $chart_builder_css ) ) {
801 - wp_enqueue_style(
802 - 'visualizer-chart-builder-runtime',
803 - VISUALIZER_ABSURL . 'classes/Visualizer/ChartBuilder/build/index.css',
804 - array( 'visualizer-chart-builder' ),
805 - $asset['version']
806 - );
807 - }
808 - wp_localize_script(
809 - 'visualizer-chart-builder',
810 - 'vizAIBuilder',
811 - array(
812 - 'ajaxUrl' => admin_url( 'admin-ajax.php' ),
813 - 'nonce' => wp_create_nonce( 'visualizer-ai-builder' ),
814 - 'isPro' => Visualizer_Module::is_pro(),
815 - 'upgradeUrl' => tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'aiBuilderUpgrade', 'dataSource' ),
816 - )
817 - );
818 556 }
819 -
820 - do_action( 'themeisle_internal_page', VISUALIZER_DIRNAME, 'library' );
821 557 }
822 558
823 559 /**
824 - * Enqueue script for support page.
825 - *
826 - * @param string $hook_suffix Current hook.
827 - */
828 - public function enqueue_support_page( $hook_suffix ) {
829 - if ( $this->_supportPage !== $hook_suffix ) {
830 - return;
831 - }
832 - do_action( 'themeisle_internal_page', VISUALIZER_DIRNAME, 'support' );
833 - }
834 -
835 - /**
836 560 * Adds visualizer tab for media upload tabs array.
837 561 *
838 562 * @since 1.0.0
839 563 *
@@ -865,9 +589,9 @@
865 589 Visualizer_Plugin::NAME,
866 590 __( 'Chart Library', 'visualizer' ),
867 591 __( 'Chart Library', 'visualizer' ),
868 592 'edit_posts',
869 - 'admin.php?page=' . Visualizer_Plugin::NAME
593 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME )
870 594 );
871 595 add_submenu_page(
872 596 Visualizer_Plugin::NAME,
873 597 __( 'Add New Chart', 'visualizer' ),
@@ -872,22 +596,12 @@
872 596 Visualizer_Plugin::NAME,
873 597 __( 'Add New Chart', 'visualizer' ),
874 598 __( 'Add New Chart', 'visualizer' ),
875 599 'edit_posts',
876 - 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew'
600 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew' )
877 601 );
878 -
879 - $this->_settingsPage = add_submenu_page(
602 + add_submenu_page(
880 603 Visualizer_Plugin::NAME,
881 - __( 'Settings', 'visualizer' ),
882 - __( 'Settings', 'visualizer' ),
883 - 'manage_options',
884 - 'viz-settings',
885 - array( $this, 'renderSettingsPage' )
886 - );
887 -
888 - $this->_supportPage = add_submenu_page(
889 - Visualizer_Plugin::NAME,
890 604 __( 'Support', 'visualizer' ),
891 605 __( '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>',
892 606 'edit_posts',
893 607 'viz-support',
@@ -892,151 +606,12 @@
892 606 'edit_posts',
893 607 'viz-support',
894 608 array( $this, 'renderSupportPage' )
895 609 );
896 -
897 610 remove_submenu_page( Visualizer_Plugin::NAME, Visualizer_Plugin::NAME );
898 -
899 - add_action( "load-{$this->_libraryPage}", array( $this, 'addScreenOptions' ) );
900 - add_action( 'admin_footer', array( $this, 'handleGetProSubMenu' ) );
901 611 }
902 612
903 613 /**
904 - * Handle get pro plugin submenu.
905 - */
906 - public function handleGetProSubMenu() {
907 - if ( ! Visualizer_Module::is_pro() ) {
908 - ?>
909 - <style type="text/css">
910 - #toplevel_page_visualizer ul.wp-submenu li:last-child {
911 - background: #FF7E65;
912 - font-size: 14px;
913 - font-weight: 600;
914 - color: #fff;
915 - }
916 - #toplevel_page_visualizer ul.wp-submenu li:last-child > a > span {
917 - color: #fff !important;
918 - }
919 - #toplevel_page_visualizer ul.wp-submenu li:last-child > a:hover {
920 - box-shadow: inherit;
921 - }
922 - </style>
923 - <?php
924 - if ( get_option( 'visualizer_fresh_install', false ) ) {
925 - ?>
926 - <style type="text/css">
927 - #toplevel_page_visualizer ul.wp-submenu li.wp-first-item + li + li + li {
928 - display: none;
929 - }
930 - </style>
931 - <?php
932 - }
933 - }
934 - }
935 -
936 - /**
937 - * Adds the screen options for pagination.
938 - */
939 - public function addScreenOptions() {
940 - $screen = get_current_screen();
941 -
942 - // bail if it's some other page.
943 - if ( ! is_object( $screen ) || $screen->id !== $this->_libraryPage ) {
944 - return;
945 - }
946 -
947 - $args = array(
948 - 'label' => __( 'Number of charts per page:', 'visualizer' ),
949 - 'default' => 6,
950 - 'option' => 'visualizer_library_per_page',
951 - );
952 - add_screen_option( 'per_page', $args );
953 - }
954 -
955 - /**
956 - * Returns the screen option for pagination.
957 - */
958 - public function setScreenOptions( $status, $option, $value ) {
959 - if ( 'visualizer_library_per_page' === $option ) {
960 - return $value;
961 - }
962 - }
963 -
964 - /**
965 - * Adds the display filters to be used in the meta_query while displaying the charts.
966 - */
967 - private function getDisplayFilters( &$query_args ) {
968 - $query = array();
969 - global $sitepress;
970 - if ( Visualizer_Module::is_pro() && ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) ) {
971 - $current_lang = icl_get_current_language();
972 - if ( in_array( $current_lang, array( 'all', icl_get_default_language() ), true ) ) {
973 - $query[] = array(
974 - 'key' => 'chart_lang',
975 - 'compare' => 'NOT EXISTS',
976 - );
977 - } else {
978 - $query[] = array(
979 - 'key' => 'chart_lang',
980 - 'value' => $current_lang,
981 - 'compare' => '=',
982 - );
983 - }
984 - }
985 -
986 - // add chart type filter to the query arguments
987 - $type = filter_input( INPUT_GET, 'type' );
988 - if ( $type && in_array( $type, Visualizer_Plugin::getChartTypes(), true ) ) {
989 - $query[] = array(
990 - 'key' => Visualizer_Plugin::CF_CHART_TYPE,
991 - 'value' => $type,
992 - 'compare' => '=',
993 - );
994 - }
995 -
996 - // add chart library filter to the query arguments
997 - $library = filter_input( INPUT_GET, 'library' );
998 - if ( $library ) {
999 - $query[] = array(
1000 - 'key' => Visualizer_Plugin::CF_CHART_LIBRARY,
1001 - 'value' => $library,
1002 - 'compare' => '=',
1003 - );
1004 - }
1005 -
1006 - // add date filter to the query arguments
1007 - $date = filter_input( INPUT_GET, 'date' );
1008 - $possible = array_keys( Visualizer_Plugin::getSupportedDateFilter() );
1009 - if ( $date && in_array( $date, $possible, true ) ) {
1010 - $query_args['date_query'] = array(
1011 - 'after' => "$date -1 day",
1012 - 'inclusive' => true,
1013 - );
1014 - }
1015 -
1016 - // add source filter to the query arguments
1017 - $source = filter_input( INPUT_GET, 'source' );
1018 - if ( $source ) {
1019 - $source = ucwords( $source );
1020 - $source = "Visualizer_Source_{$source}";
1021 - $query[] = array(
1022 - 'key' => Visualizer_Plugin::CF_SOURCE,
1023 - 'value' => $source,
1024 - 'compare' => '=',
1025 - );
1026 - }
1027 -
1028 - $query_args['meta_query'] = $query;
1029 -
1030 - $orderby = filter_input( INPUT_GET, 'orderby' );
1031 - $order = filter_input( INPUT_GET, 'order' );
1032 - if ( $orderby ) {
1033 - $query_args['order_by'] = $orderby;
1034 - }
1035 - $query_args['order'] = empty( $order ) ? 'desc' : $order;
1036 - }
1037 -
1038 - /**
1039 614 * Get the instance of WP_Query that fetches the charts as per the given criteria.
1040 615 */
1041 616 private function getQuery() {
1042 617 static $q;
@@ -1055,34 +630,29 @@
1055 630 'default' => 1,
1056 631 ),
1057 632 )
1058 633 );
1059 -
1060 - $per_page = 6;
1061 - $screen = get_current_screen();
1062 - if ( $screen ) {
1063 - // retrieve the per_page option
1064 - $screen_option = $screen->get_option( 'per_page', 'option' );
1065 - // retrieve the value stored for the current user
1066 - $user = get_current_user_id();
1067 - $per_page = get_user_meta( $user, $screen_option, true );
1068 - if ( empty( $per_page ) || $per_page < 1 ) {
1069 - // nothing set, get the default value
1070 - $per_page = $screen->get_option( 'per_page', 'default' );
1071 - }
1072 - }
1073 -
1074 634 // the initial query arguments to fetch charts
1075 635 $query_args = array(
1076 636 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
1077 - 'posts_per_page' => $per_page,
637 + 'posts_per_page' => 6,
1078 638 'paged' => $page,
1079 639 );
1080 -
1081 - $this->getDisplayFilters( $query_args );
1082 -
640 + // add chart type filter to the query arguments
641 + $filter = filter_input( INPUT_GET, 'type' );
642 + if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) {
643 + $query_args['meta_query'] = array(
644 + array(
645 + 'key' => Visualizer_Plugin::CF_CHART_TYPE,
646 + 'value' => $filter,
647 + 'compare' => '=',
648 + ),
649 + );
650 + } else {
651 + $filter = 'all';
652 + }
1083 653 // Added by Ash/Upwork
1084 - $filterByMeta = ! empty( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
654 + $filterByMeta = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
1085 655 if ( $filterByMeta ) {
1086 656 $query = array(
1087 657 'key' => Visualizer_Plugin::CF_SETTINGS,
1088 658 'value' => $filterByMeta,
@@ -1091,9 +661,9 @@
1091 661 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
1092 662 $meta[] = $query;
1093 663 $query_args['meta_query'] = $meta;
1094 664 }
1095 - $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
665 + $q = new WP_Query( $query_args );
1096 666 return $q;
1097 667 }
1098 668
1099 669 /**
@@ -1108,91 +678,8 @@
1108 678 include_once VISUALIZER_ABSPATH . '/templates/support.php';
1109 679 }
1110 680
1111 681 /**
1112 - * Enqueues scripts/styles for the Settings page.
1113 - *
1114 - * @access public
1115 - */
1116 - public function enqueueSettingsScripts( string $hook_suffix ): void {
1117 - if ( $this->_settingsPage !== $hook_suffix ) {
1118 - return;
1119 - }
1120 - wp_enqueue_style( 'wp-color-picker' );
1121 - wp_enqueue_script( 'wp-color-picker' );
1122 - }
1123 -
1124 - /**
1125 - * Renders the global style settings page.
1126 - *
1127 - * @access public
1128 - */
1129 - public function renderSettingsPage(): void {
1130 - if ( ! current_user_can( 'manage_options' ) ) {
1131 - wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'visualizer' ) );
1132 - }
1133 - $settings = self::getGlobalSettings();
1134 - include_once VISUALIZER_ABSPATH . '/templates/global-settings.php';
1135 - }
1136 -
1137 - /**
1138 - * Returns the global style settings option.
1139 - *
1140 - * @return array<string, string>
1141 - * @access public
1142 - * @static
1143 - */
1144 - public static function getGlobalSettings(): array {
1145 - $defaults = array(
1146 - 'color_primary' => '',
1147 - 'color_secondary' => '',
1148 - 'apply_existing' => '0',
1149 - );
1150 - $saved = get_option( self::OPTION_GLOBAL_SETTINGS, array() );
1151 - return wp_parse_args( $saved, $defaults );
1152 - }
1153 -
1154 - /**
1155 - * Handles saving of the global style settings.
1156 - *
1157 - * @access public
1158 - */
1159 - public function saveGlobalSettings(): void {
1160 - if ( ! current_user_can( 'manage_options' ) ) {
1161 - wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'visualizer' ) );
1162 - }
1163 -
1164 - check_admin_referer( 'visualizer_save_global_settings' );
1165 -
1166 - $color_primary = sanitize_hex_color( wp_unslash( $_POST['visualizer_color_primary'] ?? '' ) );
1167 - $color_secondary = sanitize_hex_color( wp_unslash( $_POST['visualizer_color_secondary'] ?? '' ) );
1168 - $apply_existing = ! empty( $_POST['visualizer_apply_existing'] ) ? '1' : '0';
1169 - $clear = ! empty( $_POST['visualizer_clear_settings'] );
1170 -
1171 - if ( $clear ) {
1172 - delete_option( self::OPTION_GLOBAL_SETTINGS );
1173 - } else {
1174 - $settings = array(
1175 - 'color_primary' => $color_primary ? $color_primary : '',
1176 - 'color_secondary' => $color_secondary ? $color_secondary : '',
1177 - 'apply_existing' => $apply_existing,
1178 - );
1179 - update_option( self::OPTION_GLOBAL_SETTINGS, $settings );
1180 - }
1181 -
1182 - wp_safe_redirect(
1183 - add_query_arg(
1184 - array(
1185 - 'page' => 'viz-settings',
1186 - 'updated' => $clear ? 'cleared' : 'true',
1187 - ),
1188 - admin_url( 'admin.php' )
1189 - )
1190 - );
1191 - exit;
1192 - }
1193 -
1194 - /**
1195 682 * Renders visualizer library page.
1196 683 *
1197 684 * @since 1.0.0
1198 685 *
@@ -1238,27 +725,12 @@
1238 725 if ( ! empty( $atts['settings'] ) ) {
1239 726 $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
1240 727 }
1241 728
1242 - if ( $settings ) {
1243 - unset( $settings['height'], $settings['width'], $settings['chartArea'] );
1244 - }
1245 -
729 + unset( $settings['height'], $settings['width'], $settings['chartArea'] );
1246 730 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
1247 - $data = self::get_chart_data( $chart, $type );
731 + $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( $chart->post_content ) ), $chart->ID, $type );
1248 732
1249 - // Set default setting series when add manual chart data - Only during first creation.
1250 - if ( isset( $settings['series'] ) && ! empty( $series ) ) {
1251 - $count_series = count( $series ) - count( $settings['series'] );
1252 - if ( $count_series > 1 ) {
1253 - $clone_last_series = end( $settings['series'] );
1254 - $clone_last_series = array_fill_keys( array_keys( $clone_last_series ), '' );
1255 - foreach ( range( 1, $count_series ) as $item ) {
1256 - $settings['series'][] = $clone_last_series;
1257 - }
1258 - }
1259 - }
1260 -
1261 733 $library = $this->load_chart_type( $chart->ID );
1262 734
1263 735 $id = 'visualizer-' . $chart->ID;
1264 736 $arguments = $this->get_inline_custom_css( $id, $settings );
@@ -1266,19 +738,11 @@
1266 738 $css .= $arguments[0];
1267 739 $settings = $arguments[1];
1268 740 }
1269 741
1270 - if ( isset( $settings['controls']['ui']['labelStacking'] ) ) {
1271 - unset( $settings['controls']['ui']['labelStacking'] );
1272 - }
1273 - if ( isset( $settings['controls']['ui']['orientation'] ) ) {
1274 - unset( $settings['controls']['ui']['orientation'] );
1275 - }
1276 -
1277 742 // add chart to the array
1278 743 $charts[ $id ] = array(
1279 744 'id' => $chart->ID,
1280 - 'title' => $chart->post_title,
1281 745 'type' => $type,
1282 746 'series' => $series,
1283 747 'settings' => $settings,
1284 748 'data' => $data,
@@ -1283,15 +747,11 @@
1283 747 'settings' => $settings,
1284 748 'data' => $data,
1285 749 'library' => $library,
1286 750 );
1287 - if ( 'd3' === $library ) {
1288 - $charts[ $id ]['code'] = get_post_meta( $chart->ID, Visualizer_Module_AIBuilder::CF_D3_CODE, true );
1289 - }
1290 751 }
1291 752 // enqueue charts array
1292 753 $ajaxurl = admin_url( 'admin-ajax.php' );
1293 -
1294 754 wp_localize_script(
1295 755 'visualizer-library',
1296 756 'visualizer',
1297 757 array(
@@ -1298,39 +758,30 @@
1298 758 'language' => $this->get_language(),
1299 759 'map_api_key' => get_option( 'visualizer-map-api-key' ),
1300 760 'charts' => $charts,
1301 761 'urls' => array(
1302 - 'base' => esc_url( add_query_arg( array( 'vpage' => false, 'vaction' => false ) ) ),
1303 - 'create' => esc_url(
1304 - add_query_arg(
1305 - array(
1306 - 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
1307 - 'library' => 'yes',
1308 - 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
1309 - 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
1310 - 'vaction' => false,
1311 - ),
1312 - $ajaxurl
1313 - )
762 + 'base' => add_query_arg( array( 'vpage' => false, 'vaction' => false ) ),
763 + 'create' => add_query_arg(
764 + array(
765 + 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
766 + 'library' => 'yes',
767 + 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
768 + 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
769 + 'vaction' => false,
770 + ),
771 + $ajaxurl
1314 772 ),
1315 - 'edit' => esc_url(
1316 - add_query_arg(
1317 - array(
1318 - 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
1319 - 'library' => 'yes',
1320 - 'vaction' => false,
1321 - ),
1322 - $ajaxurl
1323 - )
773 + 'edit' => add_query_arg(
774 + array(
775 + 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
776 + 'library' => 'yes',
777 + 'vaction' => false,
778 + ),
779 + $ajaxurl
1324 780 ),
1325 781 ),
1326 782 'page_type' => 'library',
1327 783 'is_front' => false,
1328 - 'i10n' => array(
1329 - 'copied' => __( 'The shortcode has been copied to your clipboard. Hit Ctrl-V/Cmd-V to paste it.', 'visualizer' ),
1330 - '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' ),
1331 - ),
1332 - 'is_pro_user' => Visualizer_Module::is_pro(),
1333 784 )
1334 785 );
1335 786 // render library page
1336 787 $render = new Visualizer_Render_Library();
@@ -1346,9 +797,8 @@
1346 797 'total' => $query->max_num_pages,
1347 798 'type' => 'array',
1348 799 )
1349 800 );
1350 -
1351 801 $render->render();
1352 802 }
1353 803
1354 804 /**
@@ -1390,268 +840,21 @@
1390 840 *
1391 841 * @return array Updated array of plugin meta links.
1392 842 */
1393 843 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
1394 - if ( Visualizer_Module::is_pro() ) {
1395 - return $plugin_meta;
1396 - }
1397 -
1398 - // Also suppress the upsell when Pro is installed but not currently active.
1399 - if ( ! function_exists( 'get_plugins' ) ) {
1400 - require_once ABSPATH . 'wp-admin/includes/plugin.php';
1401 - }
1402 - foreach ( array_keys( get_plugins() ) as $installed_plugin ) {
1403 - if ( false !== strpos( $installed_plugin, 'visualizer-pro' ) ) {
1404 - return $plugin_meta;
1405 - }
1406 - }
1407 -
1408 844 if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
1409 - $is_black_friday = apply_filters( 'themeisle_sdk_is_black_friday_sale', false );
1410 845 // knowledge base link
1411 846 $plugin_meta[] = sprintf(
1412 847 '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1413 848 esc_html__( 'Docs', 'visualizer' )
1414 849 );
1415 - if ( ! $is_black_friday ) {
1416 - // flattr link
1417 - $plugin_meta[] = sprintf(
1418 - '<a style="color:red" href="' . tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'pluginrow' ) . '" target="_blank">%s</a>',
1419 - esc_html__( 'Get Visualizer Pro', 'visualizer' )
1420 - );
1421 - }
850 + // flattr link
851 + $plugin_meta[] = sprintf(
852 + '<a style="color:red" href="' . Visualizer_Plugin::PRO_TEASER_URL . '" target="_blank">%s</a>',
853 + esc_html__( 'Pro Addon', 'visualizer' )
854 + );
1422 855 }
1423 856
1424 857 return $plugin_meta;
1425 858 }
1426 859
1427 - /**
1428 - * Returns true when premium chart types should be enabled for the current user.
1429 - *
1430 - * Pro 1.9.0+ hooks the 'visualizer_is_pro' filter and returns true only when
1431 - * the license is valid. Pre-1.9.0 Pro defined a Visualizer_Pro class instead;
1432 - * we detect that as a fallback so those legacy installs still work.
1433 - *
1434 - * Passing false as the filter default ensures the constant VISUALIZER_PRO
1435 - * (which is set to true whenever the Pro class exists, regardless of license
1436 - * state) cannot bypass the license check.
1437 - *
1438 - * @return bool
1439 - */
1440 - public static function proFeaturesEnabled() {
1441 - $is_pro_filter = apply_filters( 'visualizer_is_pro', false );
1442 -
1443 - // Pro 1.9.0+: filter is hooked and returns true only with a valid license.
1444 - if ( $is_pro_filter ) {
1445 - return true;
1446 - }
1447 -
1448 - // Pro is installed (active) but the license check above did not pass.
1449 - // Do NOT fall through to the legacy "old user" path — that path exists
1450 - // only for sites that never had Pro installed. If Pro is present but
1451 - // the license is inactive we should lock, regardless of chart history.
1452 - if ( class_exists( 'Visualizer_Pro', false ) ) {
1453 - return false;
1454 - }
1455 -
1456 - // No Pro installed at all: grant legacy access to existing users so
1457 - // their charts are not suddenly broken when they upgrade the free plugin.
1458 - return 'yes' === get_option( 'visualizer-new-user' ) ? false : true;
1459 - }
1460 -
1461 - /**
1462 - * Multilingual Support.
1463 - *
1464 - * @param int $chart_id Chart ID.
1465 - * @return bool Default false
1466 - */
1467 - public function addMultilingualSupport( $chart_id ) {
1468 - global $sitepress;
1469 - if ( Visualizer_Module::is_pro() ) {
1470 - return;
1471 - }
1472 - if ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) {
1473 - $language = icl_get_languages();
1474 - $current_lang = icl_get_current_language();
1475 - $default_lang = icl_get_default_language();
1476 - $post_info = wpml_get_language_information( null, $chart_id );
1477 - $translations = array();
1478 - if ( ! empty( $post_info ) && ( $default_lang === $post_info['language_code'] ) ) {
1479 - $trid = $sitepress->get_element_trid( $chart_id, 'post_' . Visualizer_Plugin::CPT_VISUALIZER );
1480 - $translations = $sitepress->get_element_translations( $trid );
1481 - }
1482 - if ( empty( $translations ) ) {
1483 - return;
1484 - }
1485 - ?>
1486 - <hr><div class="visualizer-languages-list only-pro">
1487 - <?php
1488 - foreach ( $language as $lang ) {
1489 - $lang_code = $lang['code'];
1490 - if ( $current_lang !== $lang_code ) {
1491 - ?>
1492 - <a href="javascript:;">
1493 - <img src="<?php echo esc_url( $lang['country_flag_url'] ); ?>" alt="<?php echo esc_attr( $lang['translated_name'] ); ?>">
1494 - </a>
1495 - <?php
1496 - }
1497 - }
1498 - ?>
1499 - <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>
1500 - </div>
1501 - <?php
1502 - }
1503 - }
1504 -
1505 - /**
1506 - * Check chart is enabled or not.
1507 - *
1508 - * @param string $type Chart ID.
1509 - *
1510 - * @return bool Default false
1511 - */
1512 - public static function checkChartStatus( $type ) {
1513 - $types = self::_getChartTypesLocalized( false, false, false, true );
1514 - if ( isset( $types[ $type ] ) ) {
1515 - return ! empty( $types[ $type ]['enabled'] );
1516 - }
1517 - return false;
1518 - }
1519 -
1520 - /**
1521 - * Get the survey metadata.
1522 - *
1523 - * @param array $data The data for survey in Formbricks format.
1524 - * @param string $page_slug The slug of the loaded page.
1525 - *
1526 - * @return array The survey metadata.
1527 - */
1528 - public function get_survey_metadata( $data, $page_slug ) {
1529 - $install_date = get_option( 'visualizer_install', time() );
1530 - $install_days_number = intval( ( time() - $install_date ) / DAY_IN_SECONDS );
1531 -
1532 - $license_status = apply_filters( 'product_visualizer_license_status', 'invalid' );
1533 - $license_plan = apply_filters( 'product_visualizer_license_plan', false );
1534 - $license_key = apply_filters( 'product_visualizer_license_key', false );
1535 -
1536 - $plugin_data = get_plugin_data( VISUALIZER_BASEFILE, false, false );
1537 - $plugin_version = '';
1538 -
1539 - if ( ! empty( $plugin_data['Version'] ) ) {
1540 - $plugin_version = $plugin_data['Version'];
1541 - }
1542 -
1543 - $count_charts_cache_key = 'visualizer_count_charts';
1544 - $charts_number = get_transient( $count_charts_cache_key );
1545 -
1546 - if ( false === $charts_number ) {
1547 - $charts_number = $this->count_charts( 100 );
1548 - set_transient( $count_charts_cache_key, $charts_number, 100 === $charts_number ? WEEK_IN_SECONDS : 6 * HOUR_IN_SECONDS );
1549 - } else {
1550 - $charts_number = strval( $charts_number );
1551 - }
1552 -
1553 - $data = array(
1554 - 'environmentId' => 'cltef8cut1s7wyyfxy3rlxzs5',
1555 - 'attributes' => array(
1556 - 'free_version' => $plugin_version,
1557 - 'pro_version' => defined( 'VISUALIZER_PRO_VERSION' ) ? VISUALIZER_PRO_VERSION : '',
1558 - 'license_status' => $license_status,
1559 - 'install_days_number' => $install_days_number,
1560 - 'charts_number' => $charts_number,
1561 - ),
1562 - );
1563 -
1564 - if ( ! empty( $license_plan ) ) {
1565 - $data['attributes']['plan'] = $license_plan;
1566 - }
1567 -
1568 - if ( ! empty( $license_key ) ) {
1569 - $data['attributes']['license_key'] = apply_filters( 'themeisle_sdk_secret_masking', $license_key );
1570 - }
1571 -
1572 - return $data;
1573 - }
1574 -
1575 - /**
1576 - * Count the charts.
1577 - *
1578 - * @param int $limit The count limit (optional).
1579 - *
1580 - * @return int The number of charts.
1581 - */
1582 - public function count_charts( $limit = -1 ) {
1583 - $args = array(
1584 - 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
1585 - 'post_status' => 'publish',
1586 - 'posts_per_page' => $limit,
1587 - 'fields' => 'ids',
1588 - );
1589 -
1590 - $query = new WP_Query( $args);
1591 - return $query->post_count;
1592 - }
1593 -
1594 - /**
1595 - * Set the black friday data.
1596 - *
1597 - * @param array $configs The configuration array for the loaded products.
1598 - * @return array
1599 - */
1600 - public function add_black_friday_data( $configs ) {
1601 - $config = $configs['default'];
1602 -
1603 - $message = __( 'Database queries, private charts, auto-sync. Go beyond basic charts. Exclusively for existing Visualizer users.', 'visualizer' );
1604 - $cta_label = __( 'Get Visualizer Pro', 'visualizer' );
1605 -
1606 - $plan = apply_filters( 'product_visualizer_license_plan', 0 );
1607 - $license = apply_filters( 'product_visualizer_license_key', false );
1608 - $status = apply_filters( 'product_visualizer_license_status', false );
1609 - $pro_product_slug = defined( 'VISUALIZER_PRO_BASEFILE' ) ? basename( dirname( VISUALIZER_PRO_BASEFILE ) ) : '';
1610 -
1611 - $is_pro = 'valid' === $status;
1612 - $is_expired = 'expired' === $status || 'active-expired' === $status;
1613 -
1614 - if ( $is_pro ) {
1615 - // translators: %s is the discount percentage.
1616 - $config['plugin_meta_message'] = sprintf( __( 'Black Friday Sale - up to %s off', 'visualizer' ), '30%' );
1617 - // translators: %1$s - discount, %2$s - discount.
1618 - $message = sprintf( __( 'Upgrade your Visualizer Pro plan: %1$s off this week. Already on the plan you need? Renew early and save up to %2$s.', 'visualizer' ), '30%', '20%' );
1619 - $cta_label = __( 'See your options', 'visualizer' );
1620 - } elseif ( $is_expired ) {
1621 - // translators: %s is the discount percentage.
1622 - $config['upgrade_menu_text'] = sprintf( __( 'BF Sale - %s off', 'visualizer' ), '50%' );
1623 - // translators: %s is the discount percentage.
1624 - $config['plugin_meta_message'] = sprintf( __( 'Black Friday Sale - %s off', 'visualizer' ), '50%' );
1625 - $message = __( 'Your Visualizer Pro features are still here, just locked. Renew at a reduced rate this week.', 'visualizer' );
1626 - $cta_label = __( 'Reactivate now', 'visualizer' );
1627 - } else {
1628 - // translators: %s is the discount percentage.
1629 - $config['plugin_meta_message'] = sprintf( __( 'Black Friday Sale - %s off', 'visualizer' ), '60%' );
1630 - $config['title'] = __( 'Visualizer Pro: 60% off this week', 'visualizer' );
1631 - // translators: %s is the discount percentage.
1632 - $config['upgrade_menu_text'] = sprintf( __( 'BF Sale - %s off', 'visualizer' ), '60%' );
1633 - }
1634 -
1635 - $url_params = array(
1636 - 'utm_term' => $is_pro ? 'plan-' . $plan : 'free',
1637 - 'lkey' => ! empty( $license ) ? $license : false,
1638 - 'expired' => $is_expired ? '1' : false,
1639 - );
1640 -
1641 - if ( ( $is_pro || $is_expired ) && ! empty( $pro_product_slug ) ) {
1642 - $config['plugin_meta_targets'] = array( $pro_product_slug );
1643 - }
1644 -
1645 - $config['message'] = $message;
1646 - $config['cta_label'] = $cta_label;
1647 -
1648 - $config['sale_url'] = add_query_arg(
1649 - $url_params,
1650 - tsdk_translate_link( tsdk_utmify( 'https://themeisle.link/vizualizer-bf', 'bfcm', 'visualizer' ) )
1651 - );
1652 -
1653 - $configs[ VISUALIZER_DIRNAME ] = $config;
1654 -
1655 - return $configs;
1656 - }
1657 860 }