PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.11.14
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.11.14
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 +921 -98 3.0.63.11.14 View file →
@@ -40,8 +40,16 @@
40 40 */
41 41 private $_libraryPage;
42 42
43 43 /**
44 + * Support page suffix.
45 + *
46 + * @access private
47 + * @var string
48 + */
49 + private $_supportPage;
50 +
51 + /**
44 52 * Constructor.
45 53 *
46 54 * @since 1.0.0
47 55 *
@@ -52,34 +60,223 @@
52 60 public function __construct( Visualizer_Plugin $plugin ) {
53 61 parent::__construct( $plugin );
54 62 $this->_addAction( 'load-post.php', 'enqueueMediaScripts' );
55 63 $this->_addAction( 'load-post-new.php', 'enqueueMediaScripts' );
56 - $this->_addAction( 'admin_footer', 'renderTempaltes' );
57 - $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 8 );
64 + $this->_addAction( 'enqueue_block_editor_assets', 'enqueueMediaScripts' );
65 + $this->_addAction( 'admin_footer', 'renderTemplates' );
66 + $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 0 );
67 + $this->_addAction( 'admin_enqueue_scripts', 'enqueue_support_page' );
58 68 $this->_addAction( 'admin_menu', 'registerAdminMenu' );
59 69 $this->_addFilter( 'media_view_strings', 'setupMediaViewStrings' );
60 70 $this->_addFilter( 'plugin_action_links', 'getPluginActionLinks', 10, 2 );
71 + $this->_addFilter( 'plugin_row_meta', 'getPluginMetaLinks', 10, 2 );
61 72 $this->_addFilter( 'visualizer_logger_data', 'getLoggerData' );
62 - $this->_addFilter( 'visualizer_get_chart_counts', 'getChartCountsByTypeAndMeta' );
63 73 $this->_addFilter( 'visualizer_feedback_review_trigger', 'feedbackReviewTrigger' );
74 + $this->_addFilter( 'themeisle_sdk_blackfriday_data', 'add_black_friday_data' );
64 75
76 + // screen pagination
77 + $this->_addFilter( 'set-screen-option', 'setScreenOptions', 10, 3 );
78 +
79 + // revision support.
80 + $this->_addFilter( 'wp_revisions_to_keep', 'limitRevisions', null, 10, 2 );
81 + $this->_addAction( '_wp_put_post_revision', 'addRevision', null, 10, 1 );
82 + $this->_addAction( 'wp_restore_post_revision', 'restoreRevision', null, 10, 2 );
83 +
84 + $this->_addAction( 'visualizer_chart_schedules_spl', 'addSplChartSchedules', null, 10, 3 );
85 +
65 86 $this->_addAction( 'admin_init', 'init' );
87 +
88 + $this->_addAction( 'visualizer_chart_languages', 'addMultilingualSupport' );
89 +
90 + $this->_addFilter( 'admin_footer_text', 'render_review_notice' );
91 +
92 + if ( ! defined( 'TI_CYPRESS_TESTING' ) ) {
93 + $this->_addFilter( 'themeisle-sdk/survey/' . VISUALIZER_DIRNAME, 'get_survey_metadata', 10, 2 );
94 + }
95 +
96 + if ( defined( 'TI_CYPRESS_TESTING' ) ) {
97 + $this->load_cypress_hooks();
98 + }
99 +
66 100 }
101 + /**
102 + * Display review notice.
103 + */
104 + public function render_review_notice( $footer_text ) {
105 + $current_screen = get_current_screen();
67 106
107 + $visualizer_page_ids = ['toplevel_page_visualizer', 'visualizer_page_viz-support', 'visualizer_page_ti-about-visualizer' ];
108 +
109 + if ( ! empty( $current_screen ) && isset( $current_screen->id ) ) {
110 + foreach ( $visualizer_page_ids as $page_to_check ) {
111 + if ( strpos( $current_screen->id, $page_to_check ) !== false ) {
112 + $footer_text = sprintf(
113 + // translators: %1$s - the name of the plugin (Visualizer), %2$s - message (You can help us by leaving a), %3$s - HTML entity code.
114 + __( 'Enjoying %1$s? %2$s %3$s rating. Thank you for being so supportive!', 'visualizer' ),
115 + '<b>Visualizer</b>',
116 + esc_html__( 'You can help us by leaving a', 'visualizer' ),
117 + '<a href="https://wordpress.org/support/plugin/visualizer/reviews/" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
118 + );
119 + break;
120 + }
121 + }
122 + }
123 +
124 + return $footer_text;
125 + }
126 +
127 +
68 128 /**
129 + * Define the hooks that are needed for cypress.
130 + *
131 + * @since 3.4.0
132 + * @access private
133 + */
134 + private function load_cypress_hooks() {
135 + // all charts should load on the same page without pagination.
136 + add_filter(
137 + 'visualizer_query_args', function( $args ) {
138 + $args['posts_per_page'] = 20;
139 + return $args;
140 + }, 10, 1
141 + );
142 + }
143 +
144 + /**
145 + * Add disabled `optgroup` schedules to the drop downs.
146 + *
147 + * @since ?
148 + *
149 + * @access public
150 + *
151 + * @param string $feature The feature for which to add schedules.
152 + * @param int $chart_id The chart ID.
153 + * @param int $plan The plan number.
154 + */
155 + public function addSplChartSchedules( $feature, $chart_id, $plan ) {
156 + if ( apply_filters( 'visualizer_is_business', false ) ) {
157 + return;
158 + }
159 +
160 + $is_new_personal = apply_filters( 'visualizer_is_new_personal', false );
161 +
162 + $hours = array(
163 + '0.16' => __( '10 minutes', 'visualizer' ),
164 + '1' => __( 'Each hour', 'visualizer' ),
165 + '12' => __( 'Each 12 hours', 'visualizer' ),
166 + '24' => __( 'Each day', 'visualizer' ),
167 + '72' => __( 'Each 3 days', 'visualizer' ),
168 + );
169 +
170 + switch ( $feature ) {
171 + case 'json':
172 + case 'csv':
173 + // no more schedules if pro is already active.
174 + if ( Visualizer_Module::is_pro() && ! $is_new_personal ) {
175 + return;
176 + }
177 + break;
178 + case 'wp':
179 + // fall-through.
180 + case 'db':
181 + break;
182 + default:
183 + return;
184 + }
185 +
186 + echo '<optgroup disabled label="' . __( 'Upgrade required', 'visualizer' ) . '">';
187 + foreach ( $hours as $hour => $desc ) {
188 + echo '<option disabled>' . $desc . '</option>';
189 + }
190 + echo '</optgroup>';
191 + }
192 +
193 + /**
194 + * No limits on revisions.
195 + */
196 + public function limitRevisions( $num, $post ) {
197 + if ( Visualizer_Plugin::CPT_VISUALIZER === $post->post_type ) {
198 + return -1;
199 + }
200 + return $num;
201 + }
202 +
203 + /**
204 + * Add a revision.
205 + */
206 + public function addRevision( $revision_id ) {
207 + $parent_id = wp_is_post_revision( $revision_id );
208 + if ( Visualizer_Plugin::CPT_VISUALIZER === get_post_type( $parent_id ) ) {
209 + // add the meta data to this revision.
210 + $meta = get_post_meta( $parent_id, '', true );
211 +
212 + if ( $meta ) {
213 + foreach ( $meta as $key => $value ) {
214 + if ( 0 === strpos( $key, 'visualizer' ) ) {
215 + add_metadata( 'post', $revision_id, $key, maybe_unserialize( $value[0] ) );
216 + }
217 + }
218 + }
219 + }
220 + }
221 +
222 + /**
223 + * Restore a revision.
224 + */
225 + public function restoreRevision( $post_id, $revision_id ) {
226 + if ( Visualizer_Plugin::CPT_VISUALIZER === get_post_type( $post_id ) ) {
227 + // get the meta information from the revision.
228 + $meta = get_metadata( 'post', $revision_id, '', true );
229 +
230 + // delete all meta information from the post before adding.
231 + $post_meta = get_post_meta( $post_id, '', true );
232 + if ( $post_meta ) {
233 + foreach ( $meta as $key => $value ) {
234 + if ( 0 === strpos( $key, 'visualizer' ) ) {
235 + delete_post_meta( $post_id, $key );
236 + }
237 + }
238 + }
239 +
240 + if ( $meta ) {
241 + foreach ( $meta as $key => $value ) {
242 + if ( 0 === strpos( $key, 'visualizer' ) ) {
243 + add_post_meta( $post_id, $key, maybe_unserialize( $value[0] ) );
244 + }
245 + }
246 + }
247 + }
248 + }
249 +
250 + /**
69 251 * Admin init.
70 252 *
71 253 * @access public
72 254 */
73 255 public function init() {
256 + // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
74 257 if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' == get_user_option( 'rich_editing' ) ) {
75 258 $this->_addFilter( 'mce_external_languages', 'add_tinymce_lang', 10, 1 );
76 259 $this->_addFilter( 'mce_external_plugins', 'tinymce_plugin', 10, 1 );
77 260 $this->_addFilter( 'mce_buttons', 'register_mce_button', 10, 1 );
261 + $this->_addFilter( 'tiny_mce_before_init', 'get_strings_for_block', 10, 1 );
78 262 }
79 263 }
80 264
81 265 /**
266 + * Add the strings required for the TinyMCE buttons for the classic block (not the classic editor).
267 + *
268 + * @since ?
269 + * @access friendly
270 + */
271 + function get_strings_for_block( $settings ) {
272 + $class = new Visualizer_Module_Language();
273 + $strings = $class->get_strings();
274 + $array = array( 'visualizer_tinymce_plugin' => json_encode( $strings ) );
275 + return array_merge( $settings, $array );
276 + }
277 +
278 + /**
82 279 * Load plugin translation for - TinyMCE API
83 280 *
84 281 * @access public
85 282 * @param array $arr The tinymce_lang array.
@@ -148,16 +345,32 @@
148 345 * @access public
149 346 */
150 347 public function enqueueMediaScripts() {
151 348 global $typenow;
152 - if ( post_type_supports( $typenow, 'editor' ) ) {
349 + global $current_screen;
350 +
351 + if ( post_type_supports( $typenow, 'editor' ) || $current_screen->id === 'widgets' || $current_screen->id === 'customize' ) {
153 352 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 );
353 +
354 + // Load all the assets for the different libraries we support.
355 + $deps = array(
356 + Visualizer_Render_Sidebar_Google::enqueue_assets( array( 'media-editor' ) ),
357 + Visualizer_Render_Sidebar_Type_DataTable_Tabular::enqueue_assets( array( 'media-editor' ) ),
358 + );
359 +
360 + wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', $deps, Visualizer_Plugin::VERSION, true );
157 361 wp_enqueue_script( 'visualizer-media-collection', VISUALIZER_ABSURL . 'js/media/collection.js', array( 'visualizer-media-model' ), Visualizer_Plugin::VERSION, true );
158 362 wp_enqueue_script( 'visualizer-media-controller', VISUALIZER_ABSURL . 'js/media/controller.js', array( 'visualizer-media-collection' ), Visualizer_Plugin::VERSION, true );
159 363 wp_enqueue_script( 'visualizer-media-view', VISUALIZER_ABSURL . 'js/media/view.js', array( 'visualizer-media-controller' ), Visualizer_Plugin::VERSION, true );
364 + wp_localize_script(
365 + 'visualizer-media-view',
366 + 'visualizer',
367 + array(
368 + 'i10n' => array(
369 + 'insert' => __( 'Insert', 'visualizer' ),
370 + ),
371 + )
372 + );
160 373 wp_enqueue_script( 'visualizer-media-toolbar', VISUALIZER_ABSURL . 'js/media/toolbar.js', array( 'visualizer-media-view' ), Visualizer_Plugin::VERSION, true );
161 374 wp_enqueue_script( 'visualizer-media', VISUALIZER_ABSURL . 'js/media.js', array( 'visualizer-media-toolbar' ), Visualizer_Plugin::VERSION, true );
162 375 }
163 376 }
@@ -191,9 +404,9 @@
191 404 'filters' => $chart_types,
192 405 'types' => array_keys( $chart_types ),
193 406 ),
194 407 'nonce' => wp_create_nonce(),
195 - 'buildurl' => add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ),
408 + 'buildurl' => esc_url( add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ) ),
196 409 );
197 410
198 411 return $strings;
199 412 }
@@ -206,9 +419,9 @@
206 419 * @static
207 420 * @access private
208 421 * @return array The associated array of chart types with localized names.
209 422 */
210 - public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false, $add_select = false ) {
423 + public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false, $add_select = false, $where = null ) {
211 424 $additional = array();
212 425 if ( $add_select ) {
213 426 $additional['select'] = array(
214 427 'name' => esc_html__( 'All', 'visualizer' ),
@@ -215,59 +428,102 @@
215 428 'enabled' => true,
216 429 );
217 430 }
218 431
432 + $enabled = self::proFeaturesLocked();
433 +
219 434 $types = array_merge(
220 - $additional, array(
435 + $additional,
436 + array(
437 + 'tabular' => array(
438 + 'name' => esc_html__( 'Table', 'visualizer' ),
439 + 'enabled' => true,
440 + 'supports' => $enabled ? array( 'Google Charts', 'DataTable' ) : array( 'DataTable' ),
441 + ),
221 442 'pie' => array(
222 - 'name' => esc_html__( 'Pie', 'visualizer' ),
443 + 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
223 444 'enabled' => true,
445 + 'supports' => array( 'Google Charts', 'ChartJS' ),
224 446 ),
225 447 'line' => array(
226 448 'name' => esc_html__( 'Line', 'visualizer' ),
227 449 'enabled' => true,
450 + 'supports' => array( 'Google Charts', 'ChartJS' ),
228 451 ),
452 + 'bar' => array(
453 + 'name' => esc_html__( 'Bar', 'visualizer' ),
454 + 'enabled' => true,
455 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
456 + ),
229 457 'area' => array(
230 458 'name' => esc_html__( 'Area', 'visualizer' ),
231 - 'enabled' => true,
459 + 'enabled' => $enabled,
460 + // in ChartJS, the fill option is used to make Line chart an area: https://www.chartjs.org/docs/latest/charts/area.html
461 + 'supports' => array( 'Google Charts' ),
462 + 'demo_url' => 'https://demo.themeisle.com/visualizer/area-chart/',
232 463 ),
233 464 'geo' => array(
234 465 'name' => esc_html__( 'Geo', 'visualizer' ),
235 - 'enabled' => true,
466 + 'enabled' => $enabled,
467 + 'supports' => array( 'Google Charts' ),
468 + 'demo_url' => 'https://demo.themeisle.com/visualizer/geo-chart/',
236 469 ),
237 - 'bar' => array(
238 - 'name' => esc_html__( 'Bar', 'visualizer' ),
239 - 'enabled' => true,
240 - ),
241 470 'column' => array(
242 471 'name' => esc_html__( 'Column', 'visualizer' ),
243 - 'enabled' => true,
472 + 'enabled' => $enabled,
473 + 'supports' => array( 'Google Charts', 'ChartJS' ),
474 + 'demo_url' => 'https://demo.themeisle.com/visualizer/column-chart/',
244 475 ),
245 - 'gauge' => array(
246 - 'name' => esc_html__( 'Gauge', 'visualizer' ),
247 - 'enabled' => true,
476 + 'bubble' => array(
477 + 'name' => esc_html__( 'Bubble', 'visualizer' ),
478 + 'enabled' => $enabled,
479 + // chartjs' bubble is ugly looking (and it won't work off the default bubble.csv) so it is being excluded for the time being.
480 + 'supports' => array( 'Google Charts' ),
481 + 'demo_url' => 'https://demo.themeisle.com/visualizer/bubble-chart/',
248 482 ),
249 483 'scatter' => array(
250 484 'name' => esc_html__( 'Scatter', 'visualizer' ),
251 - 'enabled' => true,
485 + 'enabled' => $enabled,
486 + 'supports' => array( 'Google Charts' ),
487 + 'demo_url' => 'https://demo.themeisle.com/visualizer/scatter-chart/',
252 488 ),
489 + 'gauge' => array(
490 + 'name' => esc_html__( 'Gauge', 'visualizer' ),
491 + 'enabled' => $enabled,
492 + 'supports' => array( 'Google Charts' ),
493 + 'demo_url' => 'https://demo.themeisle.com/visualizer/gauge-chart/',
494 + ),
253 495 'candlestick' => array(
254 496 'name' => esc_html__( 'Candlestick', 'visualizer' ),
255 - 'enabled' => true,
497 + 'enabled' => $enabled,
498 + 'supports' => array( 'Google Charts' ),
499 + 'demo_url' => 'https://demo.themeisle.com/visualizer/candlestick-chart/',
256 500 ),
257 501 // pro types
258 - 'table' => array(
259 - 'name' => esc_html__( 'Table', 'visualizer' ),
260 - 'enabled' => false,
261 - ),
262 502 'timeline' => array(
263 503 'name' => esc_html__( 'Timeline', 'visualizer' ),
264 504 'enabled' => false,
505 + 'supports' => array( 'Google Charts', 'ChartJS' ),
506 + 'demo_url' => 'https://demo.themeisle.com/visualizer/timeline-chart/',
265 507 ),
266 508 'combo' => array(
267 509 'name' => esc_html__( 'Combo', 'visualizer' ),
268 510 'enabled' => false,
511 + 'supports' => array( 'Google Charts' ),
512 + 'demo_url' => 'https://demo.themeisle.com/visualizer/combo-chart/',
269 513 ),
514 + 'polarArea' => array(
515 + 'name' => esc_html__( 'Polar Area', 'visualizer' ),
516 + 'enabled' => false,
517 + 'supports' => array( 'ChartJS' ),
518 + 'demo_url' => 'https://demo.themeisle.com/visualizer/polar-area-chart/',
519 + ),
520 + 'radar' => array(
521 + 'name' => esc_html__( 'Radar/Spider', 'visualizer' ),
522 + 'enabled' => false,
523 + 'supports' => array( 'ChartJS' ),
524 + 'demo_url' => 'https://demo.themeisle.com/visualizer/radar-spider-chart/',
525 + ),
270 526 )
271 527 );
272 528 $types = apply_filters( 'visualizer_pro_chart_types', $types );
273 529 if ( $enabledOnly ) {
@@ -276,8 +532,12 @@
276 532 if ( ! is_array( $array ) ) {
277 533 // support for old pro
278 534 $array = array( 'enabled' => true, 'name' => $array );
279 535 }
536 + // backward compatibility for PRO before v1.9.0
537 + if ( ! array_key_exists( 'supports', $array ) ) {
538 + $array['supports'] = array( 'Google Charts' );
539 + }
280 540 if ( ! $array['enabled'] ) {
281 541 continue;
282 542 }
283 543 $filtered[ $type ] = $array;
@@ -290,13 +550,74 @@
290 550 if ( ! is_array( $array ) ) {
291 551 // support for old pro
292 552 $array = array( 'enabled' => true, 'name' => $array );
293 553 }
554 + // backward compatibility for PRO before v1.9.0
555 + if ( ! array_key_exists( 'supports', $array ) ) {
556 + $array['supports'] = array( 'Google Charts' );
557 + }
294 558 $doubleD[ $type ] = $array['name'];
295 559 }
296 560 $types = $doubleD;
297 561 }
298 562
563 + return self::handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where );
564 + }
565 +
566 + /**
567 + * Handle (soon-to-be) deprecated charts.
568 + */
569 + private static function handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where ) {
570 + $deprecated = array();
571 +
572 + switch ( $where ) {
573 + case 'types':
574 + // fall-through
575 + case 'library':
576 + // if a user has a Gauge/Candlestick chart, then let them keep using it.
577 + if ( ! Visualizer_Module::is_pro() ) {
578 + if ( ! self::hasChartType( 'gauge' ) ) {
579 + if ( $get2Darray ) {
580 + $deprecated[] = 'gauge';
581 + } else {
582 + $types['gauge']['enabled'] = false;
583 + }
584 + }
585 + if ( ! self::hasChartType( 'candlestick' ) ) {
586 + if ( $get2Darray ) {
587 + $deprecated[] = 'candlestick';
588 + } else {
589 + $types['candlestick']['enabled'] = false;
590 + }
591 + }
592 + }
593 + break;
594 + default:
595 + // if a user has a Gauge/Candlestick chart, then let them keep using it.
596 + if ( ! Visualizer_Module::is_pro() ) {
597 + if ( ! self::hasChartType( 'gauge' ) ) {
598 + if ( $get2Darray ) {
599 + $deprecated[] = 'gauge';
600 + } else {
601 + $types['gauge']['enabled'] = false;
602 + }
603 + }
604 + if ( ! self::hasChartType( 'candlestick' ) ) {
605 + if ( $get2Darray ) {
606 + $deprecated[] = 'candlestick';
607 + } else {
608 + $types['candlestick']['enabled'] = false;
609 + }
610 + }
611 + }
612 + }
613 +
614 + if ( $deprecated ) {
615 + foreach ( $deprecated as $type ) {
616 + unset( $types[ $type ] );
617 + }
618 + }
619 +
299 620 return $types;
300 621 }
301 622
302 623 /**
@@ -306,11 +627,11 @@
306 627 * @global string $pagenow The name of the current page.
307 628 *
308 629 * @access public
309 630 */
310 - public function renderTempaltes() {
631 + public function renderTemplates() {
311 632 global $pagenow;
312 - if ( 'post.php' != $pagenow && 'post-new.php' != $pagenow ) {
633 + if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
313 634 return;
314 635 }
315 636 $render = new Visualizer_Render_Templates();
316 637 $render->render();
@@ -328,30 +649,61 @@
328 649 *
329 650 * @param string $suffix The current page suffix.
330 651 */
331 652 public function enqueueLibraryScripts( $suffix ) {
332 - if ( $suffix == $this->_libraryPage ) {
333 - wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
334 - $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
335 - wp_enqueue_media();
653 + if ( $suffix !== $this->_libraryPage ) {
654 + return;
655 + }
656 +
657 + wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
658 + $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
659 + wp_enqueue_media();
660 + wp_enqueue_script(
661 + 'visualizer-library',
662 + VISUALIZER_ABSURL . 'js/library.js',
663 + array(
664 + 'jquery',
665 + 'media-views',
666 + 'clipboard',
667 + ),
668 + Visualizer_Plugin::VERSION,
669 + true
670 + );
671 +
672 + wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
673 +
674 + $query = $this->getQuery();
675 + while ( $query->have_posts() ) {
676 + $chart = $query->next_post();
677 + $library = $this->load_chart_type( $chart->ID );
678 + if ( is_null( $library ) ) {
679 + continue;
680 + }
336 681 wp_enqueue_script(
337 - 'visualizer-library', VISUALIZER_ABSURL . 'js/library.js', array(
338 - 'jquery',
339 - 'media-views',
340 - ), Visualizer_Plugin::VERSION, true
682 + "visualizer-render-$library",
683 + VISUALIZER_ABSURL . 'js/render-facade.js',
684 + apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
685 + Visualizer_Plugin::VERSION,
686 + true
341 687 );
342 - wp_enqueue_script( 'google-jsapi-new', '//www.gstatic.com/charts/loader.js', array(), null, true );
343 - wp_enqueue_script( 'google-jsapi-old', '//www.google.com/jsapi', array( 'google-jsapi-new' ), null, true );
344 - wp_enqueue_script(
345 - 'visualizer-render', VISUALIZER_ABSURL . 'js/render.js', array(
346 - 'google-jsapi-old',
347 - 'visualizer-library',
348 - ), Visualizer_Plugin::VERSION, true
349 - );
350 688 }
689 +
690 + do_action( 'themeisle_internal_page', VISUALIZER_DIRNAME, 'library' );
351 691 }
352 692
353 693 /**
694 + * Enqueue script for support page.
695 + *
696 + * @param string $hook_suffix Current hook.
697 + */
698 + public function enqueue_support_page( $hook_suffix ) {
699 + if ( $this->_supportPage !== $hook_suffix ) {
700 + return;
701 + }
702 + do_action( 'themeisle_internal_page', VISUALIZER_DIRNAME, 'support' );
703 + }
704 +
705 + /**
354 706 * Adds visualizer tab for media upload tabs array.
355 707 *
356 708 * @since 1.0.0
357 709 *
@@ -374,24 +726,192 @@
374 726 *
375 727 * @access public
376 728 */
377 729 public function registerAdminMenu() {
378 - $title = esc_html__( 'Visualizer Library', 'visualizer' );
379 - $callback = array( $this, 'renderLibraryPage' );
380 - $this->_libraryPage = add_submenu_page( 'upload.php', $title, $title, 'edit_posts', Visualizer_Plugin::NAME, $callback );
730 + $svg_base64_icon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNzdweCIgaGVpZ2h0PSI3N3B4IiB2aWV3Qm94PSIwIDAgNzcgNzciIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjYgKDY3NDkxKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Db21iaW5lZCBTaGFwZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxnIGlkPSJQcm9kdWN0LVBhZ2UiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJXb3JkUHJlc3MtcGx1Z2lucyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE5MC4wMDAwMDAsIC00MzUuMDAwMDAwKSIgZmlsbD0iIzM5QzNEMiI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMjguNSw1MTIgQzIwNy4yMzcwMzcsNTEyIDE5MCw0OTQuNzYyOTYzIDE5MCw0NzMuNSBDMTkwLDQ1Mi4yMzcwMzcgMjA3LjIzNzAzNyw0MzUgMjI4LjUsNDM1IEMyNDkuNzYyOTYzLDQzNSAyNjcsNDUyLjIzNzAzNyAyNjcsNDczLjUgQzI2Nyw0OTQuNzYyOTYzIDI0OS43NjI5NjMsNTEyIDIyOC41LDUxMiBaIE0yNDYuODQzNzUsNDgzLjU5MjA1OSBMMjE1LjYyNSw0ODMuNTkyMDU5IEwyMTUuNjI1LDQ2MC44MjY1NDQgQzIxNS42MjUsNDYwLjE2NDU0NyAyMTUuMTA3NTc4LDQ1OS42MjgzNTkgMjE0LjQ2ODc1LDQ1OS42MjgzNTkgTDIxMi4xNTYyNSw0NTkuNjI4MzU5IEMyMTEuNTE3NDIyLDQ1OS42MjgzNTkgMjExLDQ2MC4xNjQ1NDcgMjExLDQ2MC44MjY1NDQgTDIxMSw0ODUuOTg4NDI5IEMyMTEsNDg3LjMxMTY3NCAyMTIuMDM1NTY2LDQ4OC4zODQ3OTggMjEzLjMxMjUsNDg4LjM4NDc5OCBMMjQ2Ljg0Mzc1LDQ4OC4zODQ3OTggQzI0Ny40ODI1NzgsNDg4LjM4NDc5OCAyNDgsNDg3Ljg0ODYxMSAyNDgsNDg3LjE4NjYxMyBMMjQ4LDQ4NC43OTAyNDQgQzI0OCw0ODQuMTI4MjQ2IDI0Ny40ODI1NzgsNDgzLjU5MjA1OSAyNDYuODQzNzUsNDgzLjU5MjA1OSBaIE0yNDQuNTMxMjUsNDYyLjAyNDcyOSBMMjM1Ljk5OTU3LDQ2Mi4wMjQ3MjkgQzIzNC40NTQ1MzEsNDYyLjAyNDcyOSAyMzMuNjgwNTY2LDQ2My45NjA1NDcgMjM0Ljc3MzIyMyw0NjUuMDkyODMyIEwyMzcuMTE0NjI5LDQ2Ny41MTkxNTYgTDIzMS44MTI1LDQ3My4wMTQzMzIgTDIyNi41MTAzNzEsNDY3LjUxOTkwNSBDMjI1LjYwNzA1MSw0NjYuNTgzODIzIDIyNC4xNDI5NDksNDY2LjU4MzgyMyAyMjMuMjQwMzUyLDQ2Ny41MTk5MDUgTDIxOC4yNzY0MjYsNDcyLjY2Mzg2MyBDMjE3LjgyNDc2Niw0NzMuMTMxOTA0IDIxNy44MjQ3NjYsNDczLjg5MDUwNSAyMTguMjc2NDI2LDQ3NC4zNTg1NDYgTDIxOS45MTEwNzQsNDc2LjA1MjQ4IEMyMjAuMzYyNzM0LDQ3Ni41MjA1MjEgMjIxLjA5NDc4NSw0NzYuNTIwNTIxIDIyMS41NDY0NDUsNDc2LjA1MjQ4IEwyMjQuODc1LDQ3Mi42MDI0NTYgTDIzMC4xNzcxMjksNDc4LjA5Njg4MyBDMjMxLjA4MDQ0OSw0NzkuMDMyOTY1IDIzMi41NDQ1NTEsNDc5LjAzMjk2NSAyMzMuNDQ3MTQ4LDQ3OC4wOTY4ODMgTDI0MC4zODQ2NDgsNDcwLjkwNzc3MyBMMjQyLjcyNjA1NSw0NzMuMzM0MDk4IEMyNDMuODE4NzExLDQ3NC40NjYzODIgMjQ1LjY4Njc3Nyw0NzMuNjY0MzQ3IDI0NS42ODY3NzcsNDcyLjA2MzI3MyBMMjQ1LjY4Njc3Nyw0NjMuMjIyOTE0IEMyNDUuNjg3NSw0NjIuNTYwOTE3IDI0NS4xNzAwNzgsNDYyLjAyNDcyOSAyNDQuNTMxMjUsNDYyLjAyNDcyOSBaIiBpZD0iQ29tYmluZWQtU2hhcGUiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==';
731 +
732 + $this->_libraryPage = add_menu_page( __( 'Visualizer', 'visualizer' ), __( 'Visualizer', 'visualizer' ), 'edit_posts', Visualizer_Plugin::NAME, array( $this, 'renderLibraryPage' ), $svg_base64_icon, 99.7666 );
733 +
734 + add_submenu_page(
735 + Visualizer_Plugin::NAME,
736 + __( 'Chart Library', 'visualizer' ),
737 + __( 'Chart Library', 'visualizer' ),
738 + 'edit_posts',
739 + 'admin.php?page=' . Visualizer_Plugin::NAME
740 + );
741 + add_submenu_page(
742 + Visualizer_Plugin::NAME,
743 + __( 'Add New Chart', 'visualizer' ),
744 + __( 'Add New Chart', 'visualizer' ),
745 + 'edit_posts',
746 + 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew'
747 + );
748 +
749 + $this->_supportPage = add_submenu_page(
750 + Visualizer_Plugin::NAME,
751 + __( 'Support', 'visualizer' ),
752 + __( '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>',
753 + 'edit_posts',
754 + 'viz-support',
755 + array( $this, 'renderSupportPage' )
756 + );
757 +
758 + remove_submenu_page( Visualizer_Plugin::NAME, Visualizer_Plugin::NAME );
759 +
760 + add_action( "load-{$this->_libraryPage}", array( $this, 'addScreenOptions' ) );
761 + add_action( 'admin_footer', array( $this, 'handleGetProSubMenu' ) );
381 762 }
382 763
383 764 /**
384 - * Renders visualizer library page.
385 - *
386 - * @since 1.0.0
387 - *
388 - * @access public
765 + * Handle get pro plugin submenu.
389 766 */
390 - public function renderLibraryPage() {
767 + public function handleGetProSubMenu() {
768 + if ( ! Visualizer_Module::is_pro() ) {
769 + ?>
770 + <style type="text/css">
771 + #toplevel_page_visualizer ul.wp-submenu li:last-child {
772 + background: #FF7E65;
773 + font-size: 14px;
774 + font-weight: 600;
775 + color: #fff;
776 + }
777 + #toplevel_page_visualizer ul.wp-submenu li:last-child > a > span {
778 + color: #fff !important;
779 + }
780 + #toplevel_page_visualizer ul.wp-submenu li:last-child > a:hover {
781 + box-shadow: inherit;
782 + }
783 + </style>
784 + <?php
785 + if ( get_option( 'visualizer_fresh_install', false ) ) {
786 + ?>
787 + <style type="text/css">
788 + #toplevel_page_visualizer ul.wp-submenu li.wp-first-item + li + li + li {
789 + display: none;
790 + }
791 + </style>
792 + <?php
793 + }
794 + }
795 + }
796 +
797 + /**
798 + * Adds the screen options for pagination.
799 + */
800 + function addScreenOptions() {
801 + $screen = get_current_screen();
802 +
803 + // bail if it's some other page.
804 + if ( ! is_object( $screen ) || $screen->id !== $this->_libraryPage ) {
805 + return;
806 + }
807 +
808 + $args = array(
809 + 'label' => __( 'Number of charts per page:', 'visualizer' ),
810 + 'default' => 6,
811 + 'option' => 'visualizer_library_per_page',
812 + );
813 + add_screen_option( 'per_page', $args );
814 + }
815 +
816 + /**
817 + * Returns the screen option for pagination.
818 + */
819 + function setScreenOptions( $status, $option, $value ) {
820 + if ( 'visualizer_library_per_page' === $option ) {
821 + return $value;
822 + }
823 + }
824 +
825 + /**
826 + * Adds the display filters to be used in the meta_query while displaying the charts.
827 + */
828 + private function getDisplayFilters( &$query_args ) {
829 + $query = array();
830 + global $sitepress;
831 + if ( Visualizer_Module::is_pro() && ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) ) {
832 + $current_lang = icl_get_current_language();
833 + if ( in_array( $current_lang, array( 'all', icl_get_default_language() ), true ) ) {
834 + $query[] = array(
835 + 'key' => 'chart_lang',
836 + 'compare' => 'NOT EXISTS',
837 + );
838 + } else {
839 + $query[] = array(
840 + 'key' => 'chart_lang',
841 + 'value' => $current_lang,
842 + 'compare' => '=',
843 + );
844 + }
845 + }
846 +
847 + // add chart type filter to the query arguments
848 + $type = filter_input( INPUT_GET, 'type' );
849 + if ( $type && in_array( $type, Visualizer_Plugin::getChartTypes(), true ) ) {
850 + $query[] = array(
851 + 'key' => Visualizer_Plugin::CF_CHART_TYPE,
852 + 'value' => $type,
853 + 'compare' => '=',
854 + );
855 + }
856 +
857 + // add chart library filter to the query arguments
858 + $library = filter_input( INPUT_GET, 'library' );
859 + if ( $library ) {
860 + $query[] = array(
861 + 'key' => Visualizer_Plugin::CF_CHART_LIBRARY,
862 + 'value' => $library,
863 + 'compare' => '=',
864 + );
865 + }
866 +
867 + // add date filter to the query arguments
868 + $date = filter_input( INPUT_GET, 'date' );
869 + $possible = array_keys( Visualizer_Plugin::getSupportedDateFilter() );
870 + if ( $date && in_array( $date, $possible, true ) ) {
871 + $query_args['date_query'] = array(
872 + 'after' => "$date -1 day",
873 + 'inclusive' => true,
874 + );
875 + }
876 +
877 + // add source filter to the query arguments
878 + $source = filter_input( INPUT_GET, 'source' );
879 + if ( $source ) {
880 + $source = ucwords( $source );
881 + $source = "Visualizer_Source_{$source}";
882 + $query[] = array(
883 + 'key' => Visualizer_Plugin::CF_SOURCE,
884 + 'value' => $source,
885 + 'compare' => '=',
886 + );
887 + }
888 +
889 + $query_args['meta_query'] = $query;
890 +
891 + $orderby = filter_input( INPUT_GET, 'orderby' );
892 + $order = filter_input( INPUT_GET, 'order' );
893 + if ( $orderby ) {
894 + $query_args['order_by'] = $orderby;
895 + }
896 + $query_args['order'] = empty( $order ) ? 'desc' : $order;
897 + }
898 +
899 + /**
900 + * Get the instance of WP_Query that fetches the charts as per the given criteria.
901 + */
902 + private function getQuery() {
903 + static $q;
904 + if ( ! is_null( $q ) ) {
905 + return $q;
906 + }
907 +
391 908 // get current page
392 909 $page = filter_input(
393 - INPUT_GET, 'vpage', FILTER_VALIDATE_INT, array(
910 + INPUT_GET,
911 + 'vpage',
912 + FILTER_VALIDATE_INT,
913 + array(
394 914 'options' => array(
395 915 'min_range' => 1,
396 916 'default' => 1,
397 917 ),
@@ -396,29 +916,34 @@
396 916 'default' => 1,
397 917 ),
398 918 )
399 919 );
920 +
921 + $per_page = 6;
922 + $screen = get_current_screen();
923 + if ( $screen ) {
924 + // retrieve the per_page option
925 + $screen_option = $screen->get_option( 'per_page', 'option' );
926 + // retrieve the value stored for the current user
927 + $user = get_current_user_id();
928 + $per_page = get_user_meta( $user, $screen_option, true );
929 + if ( empty( $per_page ) || $per_page < 1 ) {
930 + // nothing set, get the default value
931 + $per_page = $screen->get_option( 'per_page', 'default' );
932 + }
933 + }
934 +
400 935 // the initial query arguments to fetch charts
401 936 $query_args = array(
402 937 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
403 - 'posts_per_page' => 6,
938 + 'posts_per_page' => $per_page,
404 939 'paged' => $page,
405 940 );
406 - // add chart type filter to the query arguments
407 - $filter = filter_input( INPUT_GET, 'type' );
408 - if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) {
409 - $query_args['meta_query'] = array(
410 - array(
411 - 'key' => Visualizer_Plugin::CF_CHART_TYPE,
412 - 'value' => $filter,
413 - 'compare' => '=',
414 - ),
415 - );
416 - } else {
417 - $filter = 'all';
418 - }
941 +
942 + $this->getDisplayFilters( $query_args );
943 +
419 944 // Added by Ash/Upwork
420 - $filterByMeta = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
945 + $filterByMeta = ! empty( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
421 946 if ( $filterByMeta ) {
422 947 $query = array(
423 948 'key' => Visualizer_Plugin::CF_SETTINGS,
424 949 'value' => $filterByMeta,
@@ -427,49 +952,159 @@
427 952 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
428 953 $meta[] = $query;
429 954 $query_args['meta_query'] = $meta;
430 955 }
431 - // Added by Ash/Upwork
432 - // fetch charts
956 + $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
957 + return $q;
958 + }
959 +
960 + /**
961 + * Renders support page.
962 + *
963 + * @since 3.3.0
964 + *
965 + * @access public
966 + */
967 + public function renderSupportPage() {
968 + wp_enqueue_style( 'visualizer-upsell', VISUALIZER_ABSURL . 'css/upsell.css', array(), Visualizer_Plugin::VERSION );
969 + include_once VISUALIZER_ABSPATH . '/templates/support.php';
970 + }
971 +
972 + /**
973 + * Renders visualizer library page.
974 + *
975 + * @since 1.0.0
976 + *
977 + * @access public
978 + */
979 + public function renderLibraryPage() {
433 980 $charts = array();
434 - $query = new WP_Query( $query_args );
981 + $query = $this->getQuery();
982 +
983 + // get current page
984 + $page = filter_input(
985 + INPUT_GET,
986 + 'vpage',
987 + FILTER_VALIDATE_INT,
988 + array(
989 + 'options' => array(
990 + 'min_range' => 1,
991 + 'default' => 1,
992 + ),
993 + )
994 + );
995 + // add chart type filter to the query arguments
996 + $filter = filter_input( INPUT_GET, 'type' );
997 + if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) ) {
998 + $filter = 'all';
999 + }
1000 +
1001 + $css = '';
435 1002 while ( $query->have_posts() ) {
436 1003 $chart = $query->next_post();
1004 +
1005 + // 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.
1006 + $chart = $this->handleExistingRevisions( $chart->ID, $chart );
1007 + // refresh a "live" db query chart.
1008 + $chart = apply_filters( 'visualizer_schedule_refresh_chart', $chart, $chart->ID, false );
1009 +
1010 + $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
1011 +
437 1012 // fetch and update settings
438 1013 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
439 - unset( $settings['height'], $settings['width'] );
440 - $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
1014 +
1015 + $settings = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $settings, $chart->ID, $type );
1016 + if ( ! empty( $atts['settings'] ) ) {
1017 + $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
1018 + }
1019 +
1020 + if ( $settings ) {
1021 + unset( $settings['height'], $settings['width'], $settings['chartArea'] );
1022 + }
1023 +
441 1024 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
442 - $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( $chart->post_content ) ), $chart->ID, $type );
1025 + $data = self::get_chart_data( $chart, $type );
1026 +
1027 + // Set default setting series when add manual chart data - Only during first creation.
1028 + if ( isset( $settings['series'] ) && ! empty( $series ) ) {
1029 + $count_series = count( $series ) - count( $settings['series'] );
1030 + if ( $count_series > 1 ) {
1031 + $clone_last_series = end( $settings['series'] );
1032 + $clone_last_series = array_fill_keys( array_keys( $clone_last_series ), '' );
1033 + foreach ( range( 1, $count_series ) as $item ) {
1034 + $settings['series'][] = $clone_last_series;
1035 + }
1036 + }
1037 + }
1038 +
1039 + $library = $this->load_chart_type( $chart->ID );
1040 +
1041 + $id = 'visualizer-' . $chart->ID;
1042 + $arguments = $this->get_inline_custom_css( $id, $settings );
1043 + if ( ! empty( $arguments ) ) {
1044 + $css .= $arguments[0];
1045 + $settings = $arguments[1];
1046 + }
1047 +
1048 + if ( isset( $settings['controls']['ui']['labelStacking'] ) ) {
1049 + unset( $settings['controls']['ui']['labelStacking'] );
1050 + }
1051 + if ( isset( $settings['controls']['ui']['orientation'] ) ) {
1052 + unset( $settings['controls']['ui']['orientation'] );
1053 + }
1054 +
443 1055 // add chart to the array
444 - $charts[ 'visualizer-' . $chart->ID ] = array(
1056 + $charts[ $id ] = array(
445 1057 'id' => $chart->ID,
446 1058 'type' => $type,
447 1059 'series' => $series,
448 1060 'settings' => $settings,
449 1061 'data' => $data,
1062 + 'library' => $library,
450 1063 );
451 1064 }
452 1065 // enqueue charts array
453 1066 $ajaxurl = admin_url( 'admin-ajax.php' );
1067 +
454 1068 wp_localize_script(
455 - 'visualizer-library', 'visualizer', array(
1069 + 'visualizer-library',
1070 + 'visualizer',
1071 + array(
1072 + 'language' => $this->get_language(),
1073 + 'map_api_key' => get_option( 'visualizer-map-api-key' ),
456 1074 'charts' => $charts,
457 1075 'urls' => array(
458 - 'base' => add_query_arg( 'vpage', false ),
459 - 'create' => add_query_arg(
460 - array(
461 - 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
462 - 'library' => 'yes',
463 - ), $ajaxurl
1076 + 'base' => esc_url( add_query_arg( array( 'vpage' => false, 'vaction' => false ) ) ),
1077 + 'create' => esc_url(
1078 + add_query_arg(
1079 + array(
1080 + 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
1081 + 'library' => 'yes',
1082 + 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
1083 + 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
1084 + 'vaction' => false,
1085 + ),
1086 + $ajaxurl
1087 + )
464 1088 ),
465 - 'edit' => add_query_arg(
466 - array(
467 - 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
468 - 'library' => 'yes',
469 - ), $ajaxurl
1089 + 'edit' => esc_url(
1090 + add_query_arg(
1091 + array(
1092 + 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
1093 + 'library' => 'yes',
1094 + 'vaction' => false,
1095 + ),
1096 + $ajaxurl
1097 + )
470 1098 ),
471 1099 ),
1100 + 'page_type' => 'library',
1101 + 'is_front' => false,
1102 + 'i10n' => array(
1103 + 'copied' => __( 'The shortcode has been copied to your clipboard. Hit Ctrl-V/Cmd-V to paste it.', 'visualizer' ),
1104 + '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' ),
1105 + ),
1106 + 'is_pro_user' => Visualizer_Module::is_pro(),
472 1107 )
473 1108 );
474 1109 // render library page
475 1110 $render = new Visualizer_Render_Library();
@@ -474,12 +1109,13 @@
474 1109 // render library page
475 1110 $render = new Visualizer_Render_Library();
476 1111 $render->charts = $charts;
477 1112 $render->type = $filter;
478 - $render->types = self::_getChartTypesLocalized();
1113 + $render->types = self::_getChartTypesLocalized( false, false, false, true );
1114 + $render->custom_css = $css;
479 1115 $render->pagination = paginate_links(
480 1116 array(
481 - 'base' => add_query_arg( 'vpage', '%#%' ),
1117 + 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
482 1118 'format' => '',
483 1119 'current' => $page,
484 1120 'total' => $query->max_num_pages,
485 1121 'type' => 'array',
@@ -484,8 +1120,9 @@
484 1120 'total' => $query->max_num_pages,
485 1121 'type' => 'array',
486 1122 )
487 1123 );
1124 +
488 1125 $render->render();
489 1126 }
490 1127
491 1128 /**
@@ -500,14 +1137,14 @@
500 1137 *
501 1138 * @return array Updated array of action links.
502 1139 */
503 1140 public function getPluginActionLinks( $links, $file ) {
504 - if ( $file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1141 + if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
505 1142 array_unshift(
506 1143 $links,
507 1144 sprintf(
508 1145 '<a href="%s">%s</a>',
509 - admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ),
1146 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
510 1147 esc_html__( 'Library', 'visualizer' )
511 1148 )
512 1149 );
513 1150 }
@@ -527,18 +1164,18 @@
527 1164 *
528 1165 * @return array Updated array of plugin meta links.
529 1166 */
530 1167 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
531 - if ( $plugin_file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1168 + if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
532 1169 // knowledge base link
533 1170 $plugin_meta[] = sprintf(
534 - '<a href="https://github.com/codeinwp/visualizer/wiki" target="_blank">%s</a>',
535 - esc_html__( 'Knowledge Base', 'visualizer' )
1171 + '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1172 + esc_html__( 'Docs', 'visualizer' )
536 1173 );
537 1174 // flattr link
538 1175 $plugin_meta[] = sprintf(
539 - '<a style="color:red" href="https://themeisle.com/plugins/visualizer-charts-and-graphs-pro-addon/" target="_blank">%s</a>',
540 - esc_html__( 'Pro Addon', 'visualizer' )
1176 + '<a style="color:red" href="' . tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'pluginrow' ) . '" target="_blank">%s</a>',
1177 + esc_html__( 'Get Visualizer Pro', 'visualizer' )
541 1178 );
542 1179 }
543 1180
544 1181 return $plugin_meta;
@@ -543,5 +1180,191 @@
543 1180
544 1181 return $plugin_meta;
545 1182 }
546 1183
1184 + /**
1185 + * If check is existing user.
1186 + *
1187 + * @return bool Default false
1188 + */
1189 + public static function proFeaturesLocked() {
1190 + if ( Visualizer_Module::is_pro() ) {
1191 + return true;
1192 + }
1193 + return 'yes' === get_option( 'visualizer-new-user', 'yes' ) ? false : true;
1194 + }
1195 +
1196 + /**
1197 + * Multilingual Support.
1198 + *
1199 + * @param int $chart_id Chart ID.
1200 + * @return bool Default false
1201 + */
1202 + public function addMultilingualSupport( $chart_id ) {
1203 + global $sitepress;
1204 + if ( Visualizer_Module::is_pro() ) {
1205 + return;
1206 + }
1207 + if ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) {
1208 + $language = icl_get_languages();
1209 + $current_lang = icl_get_current_language();
1210 + $default_lang = icl_get_default_language();
1211 + $post_info = wpml_get_language_information( null, $chart_id );
1212 + $translations = array();
1213 + if ( ! empty( $post_info ) && ( $default_lang === $post_info['language_code'] ) ) {
1214 + $trid = $sitepress->get_element_trid( $chart_id, 'post_' . Visualizer_Plugin::CPT_VISUALIZER );
1215 + $translations = $sitepress->get_element_translations( $trid );
1216 + }
1217 + if ( empty( $translations ) ) {
1218 + return;
1219 + }
1220 + ?>
1221 + <hr><div class="visualizer-languages-list only-pro">
1222 + <?php
1223 + foreach ( $language as $lang ) {
1224 + $lang_code = $lang['code'];
1225 + if ( $current_lang !== $lang_code ) {
1226 + ?>
1227 + <a href="javascript:;">
1228 + <img src="<?php echo esc_url( $lang['country_flag_url'] ); ?>" alt="<?php echo esc_attr( $lang['translated_name'] ); ?>">
1229 + </a>
1230 + <?php
1231 + }
1232 + }
1233 + ?>
1234 + <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>
1235 + </div>
1236 + <?php
1237 + }
1238 + }
1239 +
1240 + /**
1241 + * Check chart is enabled or not.
1242 + *
1243 + * @param string $type Chart ID.
1244 + *
1245 + * @return bool Default false
1246 + */
1247 + public static function checkChartStatus( $type ) {
1248 + $types = self::_getChartTypesLocalized( false, false, false, true );
1249 + if ( isset( $types[ $type ] ) ) {
1250 + return ! empty( $types[ $type ]['enabled'] );
1251 + }
1252 + return false;
1253 + }
1254 +
1255 + /**
1256 + * Get the survey metadata.
1257 + *
1258 + * @param array $data The data for survey in Formbricks format.
1259 + * @param string $page_slug The slug of the loaded page.
1260 + *
1261 + * @return array The survey metadata.
1262 + */
1263 + public function get_survey_metadata( $data, $page_slug ) {
1264 + $install_date = get_option( 'visualizer_install', time() );
1265 + $install_days_number = intval( ( time() - $install_date ) / DAY_IN_SECONDS );
1266 +
1267 + $license_status = apply_filters( 'product_visualizer_license_status', 'invalid' );
1268 + $license_plan = apply_filters( 'product_visualizer_license_plan', false );
1269 + $license_key = apply_filters( 'product_visualizer_license_key', false );
1270 +
1271 + $plugin_data = get_plugin_data( VISUALIZER_BASEFILE, false, false );
1272 + $plugin_version = '';
1273 +
1274 + if ( ! empty( $plugin_data['Version'] ) ) {
1275 + $plugin_version = $plugin_data['Version'];
1276 + }
1277 +
1278 + $count_charts_cache_key = 'visualizer_count_charts';
1279 + $charts_number = get_transient( $count_charts_cache_key );
1280 +
1281 + if ( false === $charts_number ) {
1282 + $charts_number = $this->count_charts( 100 );
1283 + set_transient( $count_charts_cache_key, $charts_number, 100 === $charts_number ? WEEK_IN_SECONDS : 6 * HOUR_IN_SECONDS );
1284 + } else {
1285 + $charts_number = strval( $charts_number );
1286 + }
1287 +
1288 + $data = array(
1289 + 'environmentId' => 'cltef8cut1s7wyyfxy3rlxzs5',
1290 + 'attributes' => array(
1291 + 'free_version' => $plugin_version,
1292 + 'pro_version' => defined( 'VISUALIZER_PRO_VERSION' ) ? VISUALIZER_PRO_VERSION : '',
1293 + 'license_status' => $license_status,
1294 + 'install_days_number' => $install_days_number,
1295 + 'charts_number' => $charts_number,
1296 + ),
1297 + );
1298 +
1299 + if ( ! empty( $license_plan ) ) {
1300 + $data['attributes']['plan'] = $license_plan;
1301 + }
1302 +
1303 + if ( ! empty( $license_key ) ) {
1304 + $data['attributes']['license_key'] = apply_filters( 'themeisle_sdk_secret_masking', $license_key );
1305 + }
1306 +
1307 + return $data;
1308 + }
1309 +
1310 + /**
1311 + * Count the charts.
1312 + *
1313 + * @param int $limit The count limit (optional).
1314 + *
1315 + * @return int The number of charts.
1316 + */
1317 + public function count_charts( $limit = -1 ) {
1318 + $args = array(
1319 + 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
1320 + 'post_status' => 'publish',
1321 + 'posts_per_page' => $limit,
1322 + 'fields' => 'ids',
1323 + );
1324 +
1325 + $query = new WP_Query( $args);
1326 + return $query->post_count;
1327 + }
1328 +
1329 + /**
1330 + * Set the black friday data.
1331 + *
1332 + * @param array $configs The configuration array for the loaded products.
1333 + * @return array
1334 + */
1335 + public function add_black_friday_data( $configs ) {
1336 + $config = $configs['default'];
1337 +
1338 + // translators: %1$s - HTML tag, %2$s - discount, %3$s - HTML tag, %4$s - product name.
1339 + $message_template = __( 'Our biggest sale of the year: %1$sup to %2$s OFF%3$s on %4$s. Don\'t miss this limited-time offer.', 'visualizer' );
1340 + $product_label = 'Visualizer';
1341 + $discount = '70%';
1342 +
1343 + $plan = apply_filters( 'product_visualizer_license_plan', 0 );
1344 + $license = apply_filters( 'product_visualizer_license_key', false );
1345 + $is_pro = 0 < $plan;
1346 +
1347 + if ( $is_pro ) {
1348 + // translators: %1$s - HTML tag, %2$s - discount, %3$s - HTML tag, %4$s - product name.
1349 + $message_template = __( 'Get %1$sup to %2$s off%3$s when you upgrade your %4$s plan or renew early.', 'visualizer' );
1350 + $product_label = 'Visualizer Pro';
1351 + $discount = '30%';
1352 + }
1353 +
1354 + $product_label = sprintf( '<strong>%s</strong>', $product_label );
1355 + $url_params = array(
1356 + 'utm_term' => $is_pro ? 'plan-' . $plan : 'free',
1357 + 'lkey' => ! empty( $license ) ? $license : false,
1358 + );
1359 +
1360 + $config['message'] = sprintf( $message_template, '<strong>', $discount, '</strong>', $product_label );
1361 + $config['sale_url'] = add_query_arg(
1362 + $url_params,
1363 + tsdk_translate_link( tsdk_utmify( 'https://themeisle.link/vizualizer-bf', 'bfcm', 'visualizer' ) )
1364 + );
1365 +
1366 + $configs[ VISUALIZER_DIRNAME ] = $config;
1367 +
1368 + return $configs;
1369 + }
547 1370 }