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 +913 -99 3.0.73.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,18 +345,27 @@
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 );
160 364 wp_localize_script(
161 - 'visualizer-media-view', 'visualizer', array(
365 + 'visualizer-media-view',
366 + 'visualizer',
367 + array(
162 368 'i10n' => array(
163 369 'insert' => __( 'Insert', 'visualizer' ),
164 370 ),
165 371 )
@@ -198,9 +404,9 @@
198 404 'filters' => $chart_types,
199 405 'types' => array_keys( $chart_types ),
200 406 ),
201 407 'nonce' => wp_create_nonce(),
202 - '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' ) ) ),
203 409 );
204 410
205 411 return $strings;
206 412 }
@@ -213,9 +419,9 @@
213 419 * @static
214 420 * @access private
215 421 * @return array The associated array of chart types with localized names.
216 422 */
217 - 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 ) {
218 424 $additional = array();
219 425 if ( $add_select ) {
220 426 $additional['select'] = array(
221 427 'name' => esc_html__( 'All', 'visualizer' ),
@@ -222,59 +428,102 @@
222 428 'enabled' => true,
223 429 );
224 430 }
225 431
432 + $enabled = self::proFeaturesLocked();
433 +
226 434 $types = array_merge(
227 - $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 + ),
228 442 'pie' => array(
229 - 'name' => esc_html__( 'Pie', 'visualizer' ),
443 + 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
230 444 'enabled' => true,
445 + 'supports' => array( 'Google Charts', 'ChartJS' ),
231 446 ),
232 447 'line' => array(
233 448 'name' => esc_html__( 'Line', 'visualizer' ),
234 449 'enabled' => true,
450 + 'supports' => array( 'Google Charts', 'ChartJS' ),
235 451 ),
452 + 'bar' => array(
453 + 'name' => esc_html__( 'Bar', 'visualizer' ),
454 + 'enabled' => true,
455 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
456 + ),
236 457 'area' => array(
237 458 'name' => esc_html__( 'Area', 'visualizer' ),
238 - '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/',
239 463 ),
240 464 'geo' => array(
241 465 'name' => esc_html__( 'Geo', 'visualizer' ),
242 - 'enabled' => true,
466 + 'enabled' => $enabled,
467 + 'supports' => array( 'Google Charts' ),
468 + 'demo_url' => 'https://demo.themeisle.com/visualizer/geo-chart/',
243 469 ),
244 - 'bar' => array(
245 - 'name' => esc_html__( 'Bar', 'visualizer' ),
246 - 'enabled' => true,
247 - ),
248 470 'column' => array(
249 471 'name' => esc_html__( 'Column', 'visualizer' ),
250 - 'enabled' => true,
472 + 'enabled' => $enabled,
473 + 'supports' => array( 'Google Charts', 'ChartJS' ),
474 + 'demo_url' => 'https://demo.themeisle.com/visualizer/column-chart/',
251 475 ),
252 - 'gauge' => array(
253 - 'name' => esc_html__( 'Gauge', 'visualizer' ),
254 - '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/',
255 482 ),
256 483 'scatter' => array(
257 484 'name' => esc_html__( 'Scatter', 'visualizer' ),
258 - 'enabled' => true,
485 + 'enabled' => $enabled,
486 + 'supports' => array( 'Google Charts' ),
487 + 'demo_url' => 'https://demo.themeisle.com/visualizer/scatter-chart/',
259 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 + ),
260 495 'candlestick' => array(
261 496 'name' => esc_html__( 'Candlestick', 'visualizer' ),
262 - 'enabled' => true,
497 + 'enabled' => $enabled,
498 + 'supports' => array( 'Google Charts' ),
499 + 'demo_url' => 'https://demo.themeisle.com/visualizer/candlestick-chart/',
263 500 ),
264 501 // pro types
265 - 'table' => array(
266 - 'name' => esc_html__( 'Table', 'visualizer' ),
267 - 'enabled' => false,
268 - ),
269 502 'timeline' => array(
270 503 'name' => esc_html__( 'Timeline', 'visualizer' ),
271 504 'enabled' => false,
505 + 'supports' => array( 'Google Charts', 'ChartJS' ),
506 + 'demo_url' => 'https://demo.themeisle.com/visualizer/timeline-chart/',
272 507 ),
273 508 'combo' => array(
274 509 'name' => esc_html__( 'Combo', 'visualizer' ),
275 510 'enabled' => false,
511 + 'supports' => array( 'Google Charts' ),
512 + 'demo_url' => 'https://demo.themeisle.com/visualizer/combo-chart/',
276 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 + ),
277 526 )
278 527 );
279 528 $types = apply_filters( 'visualizer_pro_chart_types', $types );
280 529 if ( $enabledOnly ) {
@@ -283,8 +532,12 @@
283 532 if ( ! is_array( $array ) ) {
284 533 // support for old pro
285 534 $array = array( 'enabled' => true, 'name' => $array );
286 535 }
536 + // backward compatibility for PRO before v1.9.0
537 + if ( ! array_key_exists( 'supports', $array ) ) {
538 + $array['supports'] = array( 'Google Charts' );
539 + }
287 540 if ( ! $array['enabled'] ) {
288 541 continue;
289 542 }
290 543 $filtered[ $type ] = $array;
@@ -297,13 +550,74 @@
297 550 if ( ! is_array( $array ) ) {
298 551 // support for old pro
299 552 $array = array( 'enabled' => true, 'name' => $array );
300 553 }
554 + // backward compatibility for PRO before v1.9.0
555 + if ( ! array_key_exists( 'supports', $array ) ) {
556 + $array['supports'] = array( 'Google Charts' );
557 + }
301 558 $doubleD[ $type ] = $array['name'];
302 559 }
303 560 $types = $doubleD;
304 561 }
305 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 +
306 620 return $types;
307 621 }
308 622
309 623 /**
@@ -313,11 +627,11 @@
313 627 * @global string $pagenow The name of the current page.
314 628 *
315 629 * @access public
316 630 */
317 - public function renderTempaltes() {
631 + public function renderTemplates() {
318 632 global $pagenow;
319 - if ( 'post.php' != $pagenow && 'post-new.php' != $pagenow ) {
633 + if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
320 634 return;
321 635 }
322 636 $render = new Visualizer_Render_Templates();
323 637 $render->render();
@@ -335,30 +649,61 @@
335 649 *
336 650 * @param string $suffix The current page suffix.
337 651 */
338 652 public function enqueueLibraryScripts( $suffix ) {
339 - if ( $suffix == $this->_libraryPage ) {
340 - wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
341 - $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
342 - 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 + }
343 681 wp_enqueue_script(
344 - 'visualizer-library', VISUALIZER_ABSURL . 'js/library.js', array(
345 - 'jquery',
346 - 'media-views',
347 - ), 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
348 687 );
349 - wp_enqueue_script( 'google-jsapi-new', '//www.gstatic.com/charts/loader.js', array(), null, true );
350 - wp_enqueue_script( 'google-jsapi-old', '//www.google.com/jsapi', array( 'google-jsapi-new' ), null, true );
351 - wp_enqueue_script(
352 - 'visualizer-render', VISUALIZER_ABSURL . 'js/render.js', array(
353 - 'google-jsapi-old',
354 - 'visualizer-library',
355 - ), Visualizer_Plugin::VERSION, true
356 - );
357 688 }
689 +
690 + do_action( 'themeisle_internal_page', VISUALIZER_DIRNAME, 'library' );
358 691 }
359 692
360 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 + /**
361 706 * Adds visualizer tab for media upload tabs array.
362 707 *
363 708 * @since 1.0.0
364 709 *
@@ -381,24 +726,192 @@
381 726 *
382 727 * @access public
383 728 */
384 729 public function registerAdminMenu() {
385 - $title = esc_html__( 'Visualizer Library', 'visualizer' );
386 - $callback = array( $this, 'renderLibraryPage' );
387 - $this->_libraryPage = add_submenu_page( 'upload.php', $title, $title, 'edit_posts', Visualizer_Plugin::NAME, $callback );
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' ) );
388 762 }
389 763
390 764 /**
391 - * Renders visualizer library page.
392 - *
393 - * @since 1.0.0
394 - *
395 - * @access public
765 + * Handle get pro plugin submenu.
396 766 */
397 - 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 +
398 908 // get current page
399 909 $page = filter_input(
400 - INPUT_GET, 'vpage', FILTER_VALIDATE_INT, array(
910 + INPUT_GET,
911 + 'vpage',
912 + FILTER_VALIDATE_INT,
913 + array(
401 914 'options' => array(
402 915 'min_range' => 1,
403 916 'default' => 1,
404 917 ),
@@ -403,29 +916,34 @@
403 916 'default' => 1,
404 917 ),
405 918 )
406 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 +
407 935 // the initial query arguments to fetch charts
408 936 $query_args = array(
409 937 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
410 - 'posts_per_page' => 6,
938 + 'posts_per_page' => $per_page,
411 939 'paged' => $page,
412 940 );
413 - // add chart type filter to the query arguments
414 - $filter = filter_input( INPUT_GET, 'type' );
415 - if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) {
416 - $query_args['meta_query'] = array(
417 - array(
418 - 'key' => Visualizer_Plugin::CF_CHART_TYPE,
419 - 'value' => $filter,
420 - 'compare' => '=',
421 - ),
422 - );
423 - } else {
424 - $filter = 'all';
425 - }
941 +
942 + $this->getDisplayFilters( $query_args );
943 +
426 944 // Added by Ash/Upwork
427 - $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
428 946 if ( $filterByMeta ) {
429 947 $query = array(
430 948 'key' => Visualizer_Plugin::CF_SETTINGS,
431 949 'value' => $filterByMeta,
@@ -434,51 +952,159 @@
434 952 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
435 953 $meta[] = $query;
436 954 $query_args['meta_query'] = $meta;
437 955 }
438 - // Added by Ash/Upwork
439 - // 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() {
440 980 $charts = array();
441 - $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 = '';
442 1002 while ( $query->have_posts() ) {
443 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 +
444 1012 // fetch and update settings
445 1013 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
446 - unset( $settings['height'], $settings['width'] );
447 - $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
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 +
448 1024 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
449 - $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( $chart->post_content ) ), $chart->ID, $type );
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 +
450 1055 // add chart to the array
451 - $charts[ 'visualizer-' . $chart->ID ] = array(
1056 + $charts[ $id ] = array(
452 1057 'id' => $chart->ID,
453 1058 'type' => $type,
454 1059 'series' => $series,
455 1060 'settings' => $settings,
456 1061 'data' => $data,
1062 + 'library' => $library,
457 1063 );
458 1064 }
459 1065 // enqueue charts array
460 1066 $ajaxurl = admin_url( 'admin-ajax.php' );
1067 +
461 1068 wp_localize_script(
462 - 'visualizer-library', 'visualizer', array(
1069 + 'visualizer-library',
1070 + 'visualizer',
1071 + array(
463 1072 'language' => $this->get_language(),
464 1073 'map_api_key' => get_option( 'visualizer-map-api-key' ),
465 1074 'charts' => $charts,
466 1075 'urls' => array(
467 - 'base' => add_query_arg( 'vpage', false ),
468 - 'create' => add_query_arg(
469 - array(
470 - 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
471 - 'library' => 'yes',
472 - ), $ajaxurl
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 + )
473 1088 ),
474 - 'edit' => add_query_arg(
475 - array(
476 - 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
477 - 'library' => 'yes',
478 - ), $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 + )
479 1098 ),
480 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(),
481 1107 )
482 1108 );
483 1109 // render library page
484 1110 $render = new Visualizer_Render_Library();
@@ -483,12 +1109,13 @@
483 1109 // render library page
484 1110 $render = new Visualizer_Render_Library();
485 1111 $render->charts = $charts;
486 1112 $render->type = $filter;
487 - $render->types = self::_getChartTypesLocalized();
1113 + $render->types = self::_getChartTypesLocalized( false, false, false, true );
1114 + $render->custom_css = $css;
488 1115 $render->pagination = paginate_links(
489 1116 array(
490 - 'base' => add_query_arg( 'vpage', '%#%' ),
1117 + 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
491 1118 'format' => '',
492 1119 'current' => $page,
493 1120 'total' => $query->max_num_pages,
494 1121 'type' => 'array',
@@ -493,8 +1120,9 @@
493 1120 'total' => $query->max_num_pages,
494 1121 'type' => 'array',
495 1122 )
496 1123 );
1124 +
497 1125 $render->render();
498 1126 }
499 1127
500 1128 /**
@@ -509,14 +1137,14 @@
509 1137 *
510 1138 * @return array Updated array of action links.
511 1139 */
512 1140 public function getPluginActionLinks( $links, $file ) {
513 - if ( $file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1141 + if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
514 1142 array_unshift(
515 1143 $links,
516 1144 sprintf(
517 1145 '<a href="%s">%s</a>',
518 - admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ),
1146 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
519 1147 esc_html__( 'Library', 'visualizer' )
520 1148 )
521 1149 );
522 1150 }
@@ -536,18 +1164,18 @@
536 1164 *
537 1165 * @return array Updated array of plugin meta links.
538 1166 */
539 1167 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
540 - if ( $plugin_file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1168 + if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
541 1169 // knowledge base link
542 1170 $plugin_meta[] = sprintf(
543 - '<a href="https://github.com/codeinwp/visualizer/wiki" target="_blank">%s</a>',
544 - esc_html__( 'Knowledge Base', 'visualizer' )
1171 + '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1172 + esc_html__( 'Docs', 'visualizer' )
545 1173 );
546 1174 // flattr link
547 1175 $plugin_meta[] = sprintf(
548 - '<a style="color:red" href="https://themeisle.com/plugins/visualizer-charts-and-graphs-pro-addon/" target="_blank">%s</a>',
549 - 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' )
550 1178 );
551 1179 }
552 1180
553 1181 return $plugin_meta;
@@ -552,5 +1180,191 @@
552 1180
553 1181 return $plugin_meta;
554 1182 }
555 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 + }
556 1370 }