PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.10.8
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.10.8
4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 3.10.4 All 148 releases
← All changes | classes/Visualizer/Module/Admin.php +901 -124 3.0.53.10.8 View file →
@@ -52,19 +52,233 @@
52 52 public function __construct( Visualizer_Plugin $plugin ) {
53 53 parent::__construct( $plugin );
54 54 $this->_addAction( 'load-post.php', 'enqueueMediaScripts' );
55 55 $this->_addAction( 'load-post-new.php', 'enqueueMediaScripts' );
56 - $this->_addAction( 'admin_footer', 'renderTempaltes' );
57 - $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 8 );
56 + $this->_addAction( 'admin_footer', 'renderTemplates' );
57 + $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 0 );
58 58 $this->_addAction( 'admin_menu', 'registerAdminMenu' );
59 59 $this->_addFilter( 'media_view_strings', 'setupMediaViewStrings' );
60 60 $this->_addFilter( 'plugin_action_links', 'getPluginActionLinks', 10, 2 );
61 + $this->_addFilter( 'plugin_row_meta', 'getPluginMetaLinks', 10, 2 );
61 62 $this->_addFilter( 'visualizer_logger_data', 'getLoggerData' );
62 - $this->_addFilter( 'visualizer_get_chart_counts', 'getChartCountsByTypeAndMeta' );
63 63 $this->_addFilter( 'visualizer_feedback_review_trigger', 'feedbackReviewTrigger' );
64 +
65 + // screen pagination
66 + $this->_addFilter( 'set-screen-option', 'setScreenOptions', 10, 3 );
67 +
68 + // revision support.
69 + $this->_addFilter( 'wp_revisions_to_keep', 'limitRevisions', null, 10, 2 );
70 + $this->_addAction( '_wp_put_post_revision', 'addRevision', null, 10, 1 );
71 + $this->_addAction( 'wp_restore_post_revision', 'restoreRevision', null, 10, 2 );
72 +
73 + $this->_addAction( 'visualizer_chart_schedules_spl', 'addSplChartSchedules', null, 10, 3 );
74 +
75 + $this->_addAction( 'admin_init', 'init' );
76 +
77 + $this->_addAction( 'visualizer_chart_languages', 'addMultilingualSupport' );
78 +
79 + if ( defined( 'TI_CYPRESS_TESTING' ) ) {
80 + $this->load_cypress_hooks();
81 + }
82 +
64 83 }
65 84
66 85 /**
86 + * Define the hooks that are needed for cypress.
87 + *
88 + * @since 3.4.0
89 + * @access private
90 + */
91 + private function load_cypress_hooks() {
92 + // all charts should load on the same page without pagination.
93 + add_filter(
94 + 'visualizer_query_args', function( $args ) {
95 + $args['posts_per_page'] = 20;
96 + return $args;
97 + }, 10, 1
98 + );
99 + }
100 +
101 + /**
102 + * Add disabled `optgroup` schedules to the drop downs.
103 + *
104 + * @since ?
105 + *
106 + * @access public
107 + *
108 + * @param string $feature The feature for which to add schedules.
109 + * @param int $chart_id The chart ID.
110 + * @param int $plan The plan number.
111 + */
112 + public function addSplChartSchedules( $feature, $chart_id, $plan ) {
113 + if ( apply_filters( 'visualizer_is_business', false ) ) {
114 + return;
115 + }
116 +
117 + $license = __( 'PRO', 'visualizer' );
118 + if ( Visualizer_Module::is_pro() ) {
119 + switch ( $plan ) {
120 + case 1:
121 + $license = __( 'Developer', 'visualizer' );
122 + break;
123 + }
124 + }
125 +
126 + $hours = array(
127 + '0' => __( 'Live', 'visualizer' ),
128 + '1' => __( 'Each hour', 'visualizer' ),
129 + '12' => __( 'Each 12 hours', 'visualizer' ),
130 + '24' => __( 'Each day', 'visualizer' ),
131 + '72' => __( 'Each 3 days', 'visualizer' ),
132 + );
133 +
134 + switch ( $feature ) {
135 + case 'json':
136 + case 'csv':
137 + // no more schedules if pro is already active.
138 + if ( Visualizer_Module::is_pro() ) {
139 + return;
140 + }
141 + break;
142 + case 'wp':
143 + // fall-through.
144 + case 'db':
145 + break;
146 + default:
147 + return;
148 + }
149 +
150 + echo '<optgroup disabled label="' . sprintf( __( 'More in the %s version', 'visualizer' ), $license ) . '">';
151 + foreach ( $hours as $hour => $desc ) {
152 + echo '<option disabled>' . $desc . '</option>';
153 + }
154 + echo '</optgroup>';
155 + }
156 +
157 + /**
158 + * No limits on revisions.
159 + */
160 + public function limitRevisions( $num, $post ) {
161 + if ( Visualizer_Plugin::CPT_VISUALIZER === $post->post_type ) {
162 + return -1;
163 + }
164 + return $num;
165 + }
166 +
167 + /**
168 + * Add a revision.
169 + */
170 + public function addRevision( $revision_id ) {
171 + $parent_id = wp_is_post_revision( $revision_id );
172 + if ( Visualizer_Plugin::CPT_VISUALIZER === get_post_type( $parent_id ) ) {
173 + // add the meta data to this revision.
174 + $meta = get_post_meta( $parent_id, '', true );
175 +
176 + if ( $meta ) {
177 + foreach ( $meta as $key => $value ) {
178 + if ( 0 === strpos( $key, 'visualizer' ) ) {
179 + add_metadata( 'post', $revision_id, $key, maybe_unserialize( $value[0] ) );
180 + }
181 + }
182 + }
183 + }
184 + }
185 +
186 + /**
187 + * Restore a revision.
188 + */
189 + public function restoreRevision( $post_id, $revision_id ) {
190 + if ( Visualizer_Plugin::CPT_VISUALIZER === get_post_type( $post_id ) ) {
191 + // get the meta information from the revision.
192 + $meta = get_metadata( 'post', $revision_id, '', true );
193 +
194 + // delete all meta information from the post before adding.
195 + $post_meta = get_post_meta( $post_id, '', true );
196 + if ( $post_meta ) {
197 + foreach ( $meta as $key => $value ) {
198 + if ( 0 === strpos( $key, 'visualizer' ) ) {
199 + delete_post_meta( $post_id, $key );
200 + }
201 + }
202 + }
203 +
204 + if ( $meta ) {
205 + foreach ( $meta as $key => $value ) {
206 + if ( 0 === strpos( $key, 'visualizer' ) ) {
207 + add_post_meta( $post_id, $key, maybe_unserialize( $value[0] ) );
208 + }
209 + }
210 + }
211 + }
212 + }
213 +
214 + /**
215 + * Admin init.
216 + *
217 + * @access public
218 + */
219 + public function init() {
220 + // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
221 + if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' == get_user_option( 'rich_editing' ) ) {
222 + $this->_addFilter( 'mce_external_languages', 'add_tinymce_lang', 10, 1 );
223 + $this->_addFilter( 'mce_external_plugins', 'tinymce_plugin', 10, 1 );
224 + $this->_addFilter( 'mce_buttons', 'register_mce_button', 10, 1 );
225 + $this->_addFilter( 'tiny_mce_before_init', 'get_strings_for_block', 10, 1 );
226 + }
227 + }
228 +
229 + /**
230 + * Add the strings required for the TinyMCE buttons for the classic block (not the classic editor).
231 + *
232 + * @since ?
233 + * @access friendly
234 + */
235 + function get_strings_for_block( $settings ) {
236 + $class = new Visualizer_Module_Language();
237 + $strings = $class->get_strings();
238 + $array = array( 'visualizer_tinymce_plugin' => json_encode( $strings ) );
239 + return array_merge( $settings, $array );
240 + }
241 +
242 + /**
243 + * Load plugin translation for - TinyMCE API
244 + *
245 + * @access public
246 + * @param array $arr The tinymce_lang array.
247 + * @return array
248 + */
249 + public function add_tinymce_lang( $arr ) {
250 + $ui_lang = VISUALIZER_ABSPATH . '/classes/Visualizer/Module/Language.php';
251 + $ui_lang = apply_filters( 'visualizer_ui_lang_filter', $ui_lang );
252 + $arr[] = $ui_lang;
253 + return $arr;
254 + }
255 +
256 + /**
257 + * Load custom js options - TinyMCE API
258 + *
259 + * @access public
260 + * @param array $plugin_array The tinymce plugin array.
261 + * @return array
262 + */
263 + public function tinymce_plugin( $plugin_array ) {
264 + $plugin_array['visualizer_mce_button'] = VISUALIZER_ABSURL . 'js/mce.js';
265 + return $plugin_array;
266 + }
267 +
268 + /**
269 + * Register new button in the editor
270 + *
271 + * @access public
272 + * @param array $buttons The tinymce buttons array.
273 + * @return array
274 + */
275 + public function register_mce_button( $buttons ) {
276 + array_push( $buttons, 'visualizer_mce_button' );
277 + return $buttons;
278 + }
279 +
280 + /**
67 281 * Whether to show the feedback review or not.
68 282 *
69 283 * @access public
70 284 */
@@ -97,14 +311,28 @@
97 311 public function enqueueMediaScripts() {
98 312 global $typenow;
99 313 if ( post_type_supports( $typenow, 'editor' ) ) {
100 314 wp_enqueue_style( 'visualizer-media', VISUALIZER_ABSURL . 'css/media.css', array( 'media-views' ), Visualizer_Plugin::VERSION );
101 - wp_enqueue_script( 'visualizer-google-jsapi-new', '//www.gstatic.com/charts/loader.js', array( 'media-editor' ), null, true );
102 - wp_enqueue_script( 'visualizer-google-jsapi-old', '//www.google.com/jsapi', array( 'visualizer-google-jsapi-new' ), null, true );
103 - wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', array( 'visualizer-google-jsapi-old' ), Visualizer_Plugin::VERSION, true );
315 +
316 + // Load all the assets for the different libraries we support.
317 + $deps = array(
318 + Visualizer_Render_Sidebar_Google::enqueue_assets( array( 'media-editor' ) ),
319 + Visualizer_Render_Sidebar_Type_DataTable_Tabular::enqueue_assets( array( 'media-editor' ) ),
320 + );
321 +
322 + wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', $deps, Visualizer_Plugin::VERSION, true );
104 323 wp_enqueue_script( 'visualizer-media-collection', VISUALIZER_ABSURL . 'js/media/collection.js', array( 'visualizer-media-model' ), Visualizer_Plugin::VERSION, true );
105 324 wp_enqueue_script( 'visualizer-media-controller', VISUALIZER_ABSURL . 'js/media/controller.js', array( 'visualizer-media-collection' ), Visualizer_Plugin::VERSION, true );
106 325 wp_enqueue_script( 'visualizer-media-view', VISUALIZER_ABSURL . 'js/media/view.js', array( 'visualizer-media-controller' ), Visualizer_Plugin::VERSION, true );
326 + wp_localize_script(
327 + 'visualizer-media-view',
328 + 'visualizer',
329 + array(
330 + 'i10n' => array(
331 + 'insert' => __( 'Insert', 'visualizer' ),
332 + ),
333 + )
334 + );
107 335 wp_enqueue_script( 'visualizer-media-toolbar', VISUALIZER_ABSURL . 'js/media/toolbar.js', array( 'visualizer-media-view' ), Visualizer_Plugin::VERSION, true );
108 336 wp_enqueue_script( 'visualizer-media', VISUALIZER_ABSURL . 'js/media.js', array( 'visualizer-media-toolbar' ), Visualizer_Plugin::VERSION, true );
109 337 }
110 338 }
@@ -120,8 +348,9 @@
120 348 *
121 349 * @return array The extended array of media view strings.
122 350 */
123 351 public function setupMediaViewStrings( $strings ) {
352 + $chart_types = self::_getChartTypesLocalized( true, true, true );
124 353 $strings['visualizer'] = array(
125 354 'actions' => array(
126 355 'get_charts' => Visualizer_Plugin::ACTION_GET_CHARTS,
127 356 'delete_chart' => Visualizer_Plugin::ACTION_DELETE_CHART,
@@ -133,13 +362,13 @@
133 362 'library' => esc_html__( 'From Library', 'visualizer' ),
134 363 'create' => esc_html__( 'Create New', 'visualizer' ),
135 364 ),
136 365 'library' => array(
137 - 'filters' => self::_getChartTypesLocalized( true, true ),
138 - 'types' => array_keys( self::_getChartTypesLocalized( true, true ) ),
366 + 'filters' => $chart_types,
367 + 'types' => array_keys( $chart_types ),
139 368 ),
140 369 'nonce' => wp_create_nonce(),
141 - 'buildurl' => add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ),
370 + 'buildurl' => esc_url( add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ) ),
142 371 );
143 372
144 373 return $strings;
145 374 }
@@ -152,59 +381,101 @@
152 381 * @static
153 382 * @access private
154 383 * @return array The associated array of chart types with localized names.
155 384 */
156 - public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false ) {
157 - $types = array(
158 - 'pie' => array(
159 - 'name' => esc_html__( 'Pie', 'visualizer' ),
385 + public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false, $add_select = false, $where = null ) {
386 + $additional = array();
387 + if ( $add_select ) {
388 + $additional['select'] = array(
389 + 'name' => esc_html__( 'All', 'visualizer' ),
160 390 'enabled' => true,
161 - ),
162 - 'line' => array(
163 - 'name' => esc_html__( 'Line', 'visualizer' ),
164 - 'enabled' => true,
165 - ),
166 - 'area' => array(
167 - 'name' => esc_html__( 'Area', 'visualizer' ),
168 - 'enabled' => true,
169 - ),
170 - 'geo' => array(
171 - 'name' => esc_html__( 'Geo', 'visualizer' ),
172 - 'enabled' => true,
173 - ),
174 - 'bar' => array(
175 - 'name' => esc_html__( 'Bar', 'visualizer' ),
176 - 'enabled' => true,
177 - ),
178 - 'column' => array(
179 - 'name' => esc_html__( 'Column', 'visualizer' ),
180 - 'enabled' => true,
181 - ),
182 - 'gauge' => array(
183 - 'name' => esc_html__( 'Gauge', 'visualizer' ),
184 - 'enabled' => true,
185 - ),
186 - 'scatter' => array(
187 - 'name' => esc_html__( 'Scatter', 'visualizer' ),
188 - 'enabled' => true,
189 - ),
190 - 'candlestick' => array(
191 - 'name' => esc_html__( 'Candlestick', 'visualizer' ),
192 - 'enabled' => true,
193 - ),
194 - // pro types
195 - 'table' => array(
196 - 'name' => esc_html__( 'Table', 'visualizer' ),
197 - 'enabled' => false,
198 - ),
199 - 'timeline' => array(
200 - 'name' => esc_html__( 'Timeline', 'visualizer' ),
201 - 'enabled' => false,
202 - ),
203 - 'combo' => array(
204 - 'name' => esc_html__( 'Combo', 'visualizer' ),
205 - 'enabled' => false,
206 - ),
391 + );
392 + }
393 +
394 + $enabled = self::proFeaturesLocked();
395 +
396 + $types = array_merge(
397 + $additional,
398 + array(
399 + 'tabular' => array(
400 + 'name' => esc_html__( 'Table', 'visualizer' ),
401 + 'enabled' => true,
402 + 'supports' => $enabled ? array( 'Google Charts', 'DataTable' ) : array( 'DataTable' ),
403 + ),
404 + 'pie' => array(
405 + 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
406 + 'enabled' => true,
407 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
408 + ),
409 + 'line' => array(
410 + 'name' => esc_html__( 'Line', 'visualizer' ),
411 + 'enabled' => true,
412 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
413 + ),
414 + 'bar' => array(
415 + 'name' => esc_html__( 'Bar', 'visualizer' ),
416 + 'enabled' => true,
417 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
418 + ),
419 + 'area' => array(
420 + 'name' => esc_html__( 'Area', 'visualizer' ),
421 + 'enabled' => $enabled,
422 + // in ChartJS, the fill option is used to make Line chart an area: https://www.chartjs.org/docs/latest/charts/area.html
423 + 'supports' => array( 'Google Charts' ),
424 + ),
425 + 'geo' => array(
426 + 'name' => esc_html__( 'Geo', 'visualizer' ),
427 + 'enabled' => $enabled,
428 + 'supports' => array( 'Google Charts' ),
429 + ),
430 + 'column' => array(
431 + 'name' => esc_html__( 'Column', 'visualizer' ),
432 + 'enabled' => $enabled,
433 + 'supports' => array( 'Google Charts', 'ChartJS' ),
434 + ),
435 + 'bubble' => array(
436 + 'name' => esc_html__( 'Bubble', 'visualizer' ),
437 + 'enabled' => $enabled,
438 + // chartjs' bubble is ugly looking (and it won't work off the default bubble.csv) so it is being excluded for the time being.
439 + 'supports' => array( 'Google Charts' ),
440 + ),
441 + 'scatter' => array(
442 + 'name' => esc_html__( 'Scatter', 'visualizer' ),
443 + 'enabled' => $enabled,
444 + 'supports' => array( 'Google Charts' ),
445 + ),
446 + 'gauge' => array(
447 + 'name' => esc_html__( 'Gauge', 'visualizer' ),
448 + 'enabled' => $enabled,
449 + 'supports' => array( 'Google Charts' ),
450 + ),
451 + 'candlestick' => array(
452 + 'name' => esc_html__( 'Candlestick', 'visualizer' ),
453 + 'enabled' => $enabled,
454 + 'supports' => array( 'Google Charts' ),
455 + ),
456 + // pro types
457 + 'timeline' => array(
458 + 'name' => esc_html__( 'Timeline', 'visualizer' ),
459 + 'enabled' => false,
460 + 'supports' => array( 'Google Charts', 'ChartJS' ),
461 + ),
462 + 'combo' => array(
463 + 'name' => esc_html__( 'Combo', 'visualizer' ),
464 + 'enabled' => false,
465 + 'supports' => array( 'Google Charts' ),
466 + ),
467 + 'polarArea' => array(
468 + 'name' => esc_html__( 'Polar Area', 'visualizer' ),
469 + 'enabled' => false,
470 + 'supports' => array( 'ChartJS' ),
471 + ),
472 + 'radar' => array(
473 + 'name' => esc_html__( 'Radar/Spider', 'visualizer' ),
474 + 'enabled' => false,
475 + 'supports' => array( 'ChartJS' ),
476 + ),
477 + )
207 478 );
208 479 $types = apply_filters( 'visualizer_pro_chart_types', $types );
209 480 if ( $enabledOnly ) {
210 481 $filtered = array();
@@ -212,8 +483,12 @@
212 483 if ( ! is_array( $array ) ) {
213 484 // support for old pro
214 485 $array = array( 'enabled' => true, 'name' => $array );
215 486 }
487 + // backward compatibility for PRO before v1.9.0
488 + if ( ! array_key_exists( 'supports', $array ) ) {
489 + $array['supports'] = array( 'Google Charts' );
490 + }
216 491 if ( ! $array['enabled'] ) {
217 492 continue;
218 493 }
219 494 $filtered[ $type ] = $array;
@@ -226,13 +501,74 @@
226 501 if ( ! is_array( $array ) ) {
227 502 // support for old pro
228 503 $array = array( 'enabled' => true, 'name' => $array );
229 504 }
505 + // backward compatibility for PRO before v1.9.0
506 + if ( ! array_key_exists( 'supports', $array ) ) {
507 + $array['supports'] = array( 'Google Charts' );
508 + }
230 509 $doubleD[ $type ] = $array['name'];
231 510 }
232 511 $types = $doubleD;
233 512 }
234 513
514 + return self::handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where );
515 + }
516 +
517 + /**
518 + * Handle (soon-to-be) deprecated charts.
519 + */
520 + private static function handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where ) {
521 + $deprecated = array();
522 +
523 + switch ( $where ) {
524 + case 'types':
525 + // fall-through
526 + case 'library':
527 + // if a user has a Gauge/Candlestick chart, then let them keep using it.
528 + if ( ! Visualizer_Module::is_pro() ) {
529 + if ( ! self::hasChartType( 'gauge' ) ) {
530 + if ( $get2Darray ) {
531 + $deprecated[] = 'gauge';
532 + } else {
533 + $types['gauge']['enabled'] = false;
534 + }
535 + }
536 + if ( ! self::hasChartType( 'candlestick' ) ) {
537 + if ( $get2Darray ) {
538 + $deprecated[] = 'candlestick';
539 + } else {
540 + $types['candlestick']['enabled'] = false;
541 + }
542 + }
543 + }
544 + break;
545 + default:
546 + // if a user has a Gauge/Candlestick chart, then let them keep using it.
547 + if ( ! Visualizer_Module::is_pro() ) {
548 + if ( ! self::hasChartType( 'gauge' ) ) {
549 + if ( $get2Darray ) {
550 + $deprecated[] = 'gauge';
551 + } else {
552 + $types['gauge']['enabled'] = false;
553 + }
554 + }
555 + if ( ! self::hasChartType( 'candlestick' ) ) {
556 + if ( $get2Darray ) {
557 + $deprecated[] = 'candlestick';
558 + } else {
559 + $types['candlestick']['enabled'] = false;
560 + }
561 + }
562 + }
563 + }
564 +
565 + if ( $deprecated ) {
566 + foreach ( $deprecated as $type ) {
567 + unset( $types[ $type ] );
568 + }
569 + }
570 +
235 571 return $types;
236 572 }
237 573
238 574 /**
@@ -242,11 +578,11 @@
242 578 * @global string $pagenow The name of the current page.
243 579 *
244 580 * @access public
245 581 */
246 - public function renderTempaltes() {
582 + public function renderTemplates() {
247 583 global $pagenow;
248 - if ( 'post.php' != $pagenow && 'post-new.php' != $pagenow ) {
584 + if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
249 585 return;
250 586 }
251 587 $render = new Visualizer_Render_Templates();
252 588 $render->render();
@@ -264,26 +600,41 @@
264 600 *
265 601 * @param string $suffix The current page suffix.
266 602 */
267 603 public function enqueueLibraryScripts( $suffix ) {
268 - if ( $suffix == $this->_libraryPage ) {
604 + if ( $suffix === $this->_libraryPage ) {
269 605 wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
270 606 $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
271 607 wp_enqueue_media();
272 608 wp_enqueue_script(
273 - 'visualizer-library', VISUALIZER_ABSURL . 'js/library.js', array(
609 + 'visualizer-library',
610 + VISUALIZER_ABSURL . 'js/library.js',
611 + array(
274 612 'jquery',
275 613 'media-views',
276 - ), Visualizer_Plugin::VERSION, true
614 + 'clipboard',
615 + ),
616 + Visualizer_Plugin::VERSION,
617 + true
277 618 );
278 - wp_enqueue_script( 'google-jsapi-new', '//www.gstatic.com/charts/loader.js', array(), null, true );
279 - wp_enqueue_script( 'google-jsapi-old', '//www.google.com/jsapi', array( 'google-jsapi-new' ), null, true );
280 - wp_enqueue_script(
281 - 'visualizer-render', VISUALIZER_ABSURL . 'js/render.js', array(
282 - 'google-jsapi-old',
283 - 'visualizer-library',
284 - ), Visualizer_Plugin::VERSION, true
285 - );
619 +
620 + wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
621 +
622 + $query = $this->getQuery();
623 + while ( $query->have_posts() ) {
624 + $chart = $query->next_post();
625 + $library = $this->load_chart_type( $chart->ID );
626 + if ( is_null( $library ) ) {
627 + continue;
628 + }
629 + wp_enqueue_script(
630 + "visualizer-render-$library",
631 + VISUALIZER_ABSURL . 'js/render-facade.js',
632 + apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
633 + Visualizer_Plugin::VERSION,
634 + true
635 + );
636 + }
286 637 }
287 638 }
288 639
289 640 /**
@@ -310,24 +661,191 @@
310 661 *
311 662 * @access public
312 663 */
313 664 public function registerAdminMenu() {
314 - $title = esc_html__( 'Visualizer Library', 'visualizer' );
315 - $callback = array( $this, 'renderLibraryPage' );
316 - $this->_libraryPage = add_submenu_page( 'upload.php', $title, $title, 'edit_posts', Visualizer_Plugin::NAME, $callback );
665 + $svg_base64_icon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNzdweCIgaGVpZ2h0PSI3N3B4IiB2aWV3Qm94PSIwIDAgNzcgNzciIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjYgKDY3NDkxKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Db21iaW5lZCBTaGFwZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxnIGlkPSJQcm9kdWN0LVBhZ2UiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJXb3JkUHJlc3MtcGx1Z2lucyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE5MC4wMDAwMDAsIC00MzUuMDAwMDAwKSIgZmlsbD0iIzM5QzNEMiI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMjguNSw1MTIgQzIwNy4yMzcwMzcsNTEyIDE5MCw0OTQuNzYyOTYzIDE5MCw0NzMuNSBDMTkwLDQ1Mi4yMzcwMzcgMjA3LjIzNzAzNyw0MzUgMjI4LjUsNDM1IEMyNDkuNzYyOTYzLDQzNSAyNjcsNDUyLjIzNzAzNyAyNjcsNDczLjUgQzI2Nyw0OTQuNzYyOTYzIDI0OS43NjI5NjMsNTEyIDIyOC41LDUxMiBaIE0yNDYuODQzNzUsNDgzLjU5MjA1OSBMMjE1LjYyNSw0ODMuNTkyMDU5IEwyMTUuNjI1LDQ2MC44MjY1NDQgQzIxNS42MjUsNDYwLjE2NDU0NyAyMTUuMTA3NTc4LDQ1OS42MjgzNTkgMjE0LjQ2ODc1LDQ1OS42MjgzNTkgTDIxMi4xNTYyNSw0NTkuNjI4MzU5IEMyMTEuNTE3NDIyLDQ1OS42MjgzNTkgMjExLDQ2MC4xNjQ1NDcgMjExLDQ2MC44MjY1NDQgTDIxMSw0ODUuOTg4NDI5IEMyMTEsNDg3LjMxMTY3NCAyMTIuMDM1NTY2LDQ4OC4zODQ3OTggMjEzLjMxMjUsNDg4LjM4NDc5OCBMMjQ2Ljg0Mzc1LDQ4OC4zODQ3OTggQzI0Ny40ODI1NzgsNDg4LjM4NDc5OCAyNDgsNDg3Ljg0ODYxMSAyNDgsNDg3LjE4NjYxMyBMMjQ4LDQ4NC43OTAyNDQgQzI0OCw0ODQuMTI4MjQ2IDI0Ny40ODI1NzgsNDgzLjU5MjA1OSAyNDYuODQzNzUsNDgzLjU5MjA1OSBaIE0yNDQuNTMxMjUsNDYyLjAyNDcyOSBMMjM1Ljk5OTU3LDQ2Mi4wMjQ3MjkgQzIzNC40NTQ1MzEsNDYyLjAyNDcyOSAyMzMuNjgwNTY2LDQ2My45NjA1NDcgMjM0Ljc3MzIyMyw0NjUuMDkyODMyIEwyMzcuMTE0NjI5LDQ2Ny41MTkxNTYgTDIzMS44MTI1LDQ3My4wMTQzMzIgTDIyNi41MTAzNzEsNDY3LjUxOTkwNSBDMjI1LjYwNzA1MSw0NjYuNTgzODIzIDIyNC4xNDI5NDksNDY2LjU4MzgyMyAyMjMuMjQwMzUyLDQ2Ny41MTk5MDUgTDIxOC4yNzY0MjYsNDcyLjY2Mzg2MyBDMjE3LjgyNDc2Niw0NzMuMTMxOTA0IDIxNy44MjQ3NjYsNDczLjg5MDUwNSAyMTguMjc2NDI2LDQ3NC4zNTg1NDYgTDIxOS45MTEwNzQsNDc2LjA1MjQ4IEMyMjAuMzYyNzM0LDQ3Ni41MjA1MjEgMjIxLjA5NDc4NSw0NzYuNTIwNTIxIDIyMS41NDY0NDUsNDc2LjA1MjQ4IEwyMjQuODc1LDQ3Mi42MDI0NTYgTDIzMC4xNzcxMjksNDc4LjA5Njg4MyBDMjMxLjA4MDQ0OSw0NzkuMDMyOTY1IDIzMi41NDQ1NTEsNDc5LjAzMjk2NSAyMzMuNDQ3MTQ4LDQ3OC4wOTY4ODMgTDI0MC4zODQ2NDgsNDcwLjkwNzc3MyBMMjQyLjcyNjA1NSw0NzMuMzM0MDk4IEMyNDMuODE4NzExLDQ3NC40NjYzODIgMjQ1LjY4Njc3Nyw0NzMuNjY0MzQ3IDI0NS42ODY3NzcsNDcyLjA2MzI3MyBMMjQ1LjY4Njc3Nyw0NjMuMjIyOTE0IEMyNDUuNjg3NSw0NjIuNTYwOTE3IDI0NS4xNzAwNzgsNDYyLjAyNDcyOSAyNDQuNTMxMjUsNDYyLjAyNDcyOSBaIiBpZD0iQ29tYmluZWQtU2hhcGUiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==';
666 +
667 + $this->_libraryPage = add_menu_page( __( 'Visualizer', 'visualizer' ), __( 'Visualizer', 'visualizer' ), 'edit_posts', Visualizer_Plugin::NAME, array( $this, 'renderLibraryPage' ), $svg_base64_icon, 99.7666 );
668 +
669 + add_submenu_page(
670 + Visualizer_Plugin::NAME,
671 + __( 'Chart Library', 'visualizer' ),
672 + __( 'Chart Library', 'visualizer' ),
673 + 'edit_posts',
674 + 'admin.php?page=' . Visualizer_Plugin::NAME
675 + );
676 + add_submenu_page(
677 + Visualizer_Plugin::NAME,
678 + __( 'Add New Chart', 'visualizer' ),
679 + __( 'Add New Chart', 'visualizer' ),
680 + 'edit_posts',
681 + 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew'
682 + );
683 + add_submenu_page(
684 + Visualizer_Plugin::NAME,
685 + __( 'Support', 'visualizer' ),
686 + __( 'Support', 'visualizer' ) . '<span class="dashicons dashicons-editor-help more-features-icon" style="width: 17px; height: 17px; margin-left: 4px; color: #ffca54; font-size: 17px; vertical-align: -3px;"></span>',
687 + 'edit_posts',
688 + 'viz-support',
689 + array( $this, 'renderSupportPage' )
690 + );
691 +
692 + remove_submenu_page( Visualizer_Plugin::NAME, Visualizer_Plugin::NAME );
693 +
694 + add_action( "load-{$this->_libraryPage}", array( $this, 'addScreenOptions' ) );
695 + add_action( 'admin_footer', array( $this, 'handleGetProSubMenu' ) );
317 696 }
318 697
319 698 /**
320 - * Renders visualizer library page.
321 - *
322 - * @since 1.0.0
323 - *
324 - * @access public
699 + * Handle get pro plugin submenu.
325 700 */
326 - public function renderLibraryPage() {
701 + public function handleGetProSubMenu() {
702 + if ( ! Visualizer_Module::is_pro() ) {
703 + ?>
704 + <style type="text/css">
705 + #toplevel_page_visualizer ul.wp-submenu li:last-child {
706 + background: #FF7E65;
707 + font-size: 14px;
708 + font-weight: 600;
709 + color: #fff;
710 + }
711 + #toplevel_page_visualizer ul.wp-submenu li:last-child > a {
712 + color: #fff !important;
713 + }
714 + #toplevel_page_visualizer ul.wp-submenu li:last-child > a:hover {
715 + box-shadow: inherit;
716 + }
717 + </style>
718 + <?php
719 + if ( get_option( 'visualizer_fresh_install', false ) ) {
720 + ?>
721 + <style type="text/css">
722 + #toplevel_page_visualizer ul.wp-submenu li.wp-first-item + li + li + li {
723 + display: none;
724 + }
725 + </style>
726 + <?php
727 + }
728 + }
729 + }
730 +
731 + /**
732 + * Adds the screen options for pagination.
733 + */
734 + function addScreenOptions() {
735 + $screen = get_current_screen();
736 +
737 + // bail if it's some other page.
738 + if ( ! is_object( $screen ) || $screen->id !== $this->_libraryPage ) {
739 + return;
740 + }
741 +
742 + $args = array(
743 + 'label' => __( 'Number of charts per page:', 'visualizer' ),
744 + 'default' => 6,
745 + 'option' => 'visualizer_library_per_page',
746 + );
747 + add_screen_option( 'per_page', $args );
748 + }
749 +
750 + /**
751 + * Returns the screen option for pagination.
752 + */
753 + function setScreenOptions( $status, $option, $value ) {
754 + if ( 'visualizer_library_per_page' === $option ) {
755 + return $value;
756 + }
757 + }
758 +
759 + /**
760 + * Adds the display filters to be used in the meta_query while displaying the charts.
761 + */
762 + private function getDisplayFilters( &$query_args ) {
763 + $query = array();
764 + global $sitepress;
765 + if ( Visualizer_Module::is_pro() && ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) ) {
766 + $current_lang = icl_get_current_language();
767 + if ( in_array( $current_lang, array( 'all', icl_get_default_language() ), true ) ) {
768 + $query[] = array(
769 + 'key' => 'chart_lang',
770 + 'compare' => 'NOT EXISTS',
771 + );
772 + } else {
773 + $query[] = array(
774 + 'key' => 'chart_lang',
775 + 'value' => $current_lang,
776 + 'compare' => '=',
777 + );
778 + }
779 + }
780 +
781 + // add chart type filter to the query arguments
782 + $type = filter_input( INPUT_GET, 'type' );
783 + if ( $type && in_array( $type, Visualizer_Plugin::getChartTypes(), true ) ) {
784 + $query[] = array(
785 + 'key' => Visualizer_Plugin::CF_CHART_TYPE,
786 + 'value' => $type,
787 + 'compare' => '=',
788 + );
789 + }
790 +
791 + // add chart library filter to the query arguments
792 + $library = filter_input( INPUT_GET, 'library' );
793 + if ( $library ) {
794 + $query[] = array(
795 + 'key' => Visualizer_Plugin::CF_CHART_LIBRARY,
796 + 'value' => $library,
797 + 'compare' => '=',
798 + );
799 + }
800 +
801 + // add date filter to the query arguments
802 + $date = filter_input( INPUT_GET, 'date' );
803 + $possible = array_keys( Visualizer_Plugin::getSupportedDateFilter() );
804 + if ( $date && in_array( $date, $possible, true ) ) {
805 + $query_args['date_query'] = array(
806 + 'after' => "$date -1 day",
807 + 'inclusive' => true,
808 + );
809 + }
810 +
811 + // add source filter to the query arguments
812 + $source = filter_input( INPUT_GET, 'source' );
813 + if ( $source ) {
814 + $source = ucwords( $source );
815 + $source = "Visualizer_Source_{$source}";
816 + $query[] = array(
817 + 'key' => Visualizer_Plugin::CF_SOURCE,
818 + 'value' => $source,
819 + 'compare' => '=',
820 + );
821 + }
822 +
823 + $query_args['meta_query'] = $query;
824 +
825 + $orderby = filter_input( INPUT_GET, 'orderby' );
826 + $order = filter_input( INPUT_GET, 'order' );
827 + if ( $orderby ) {
828 + $query_args['order_by'] = $orderby;
829 + }
830 + $query_args['order'] = empty( $order ) ? 'desc' : $order;
831 + }
832 +
833 + /**
834 + * Get the instance of WP_Query that fetches the charts as per the given criteria.
835 + */
836 + private function getQuery() {
837 + static $q;
838 + if ( ! is_null( $q ) ) {
839 + return $q;
840 + }
841 +
327 842 // get current page
328 843 $page = filter_input(
329 - INPUT_GET, 'vpage', FILTER_VALIDATE_INT, array(
844 + INPUT_GET,
845 + 'vpage',
846 + FILTER_VALIDATE_INT,
847 + array(
330 848 'options' => array(
331 849 'min_range' => 1,
332 850 'default' => 1,
333 851 ),
@@ -332,29 +850,34 @@
332 850 'default' => 1,
333 851 ),
334 852 )
335 853 );
854 +
855 + $per_page = 6;
856 + $screen = get_current_screen();
857 + if ( $screen ) {
858 + // retrieve the per_page option
859 + $screen_option = $screen->get_option( 'per_page', 'option' );
860 + // retrieve the value stored for the current user
861 + $user = get_current_user_id();
862 + $per_page = get_user_meta( $user, $screen_option, true );
863 + if ( empty( $per_page ) || $per_page < 1 ) {
864 + // nothing set, get the default value
865 + $per_page = $screen->get_option( 'per_page', 'default' );
866 + }
867 + }
868 +
336 869 // the initial query arguments to fetch charts
337 870 $query_args = array(
338 871 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
339 - 'posts_per_page' => 6,
872 + 'posts_per_page' => $per_page,
340 873 'paged' => $page,
341 874 );
342 - // add chart type filter to the query arguments
343 - $filter = filter_input( INPUT_GET, 'type' );
344 - if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) {
345 - $query_args['meta_query'] = array(
346 - array(
347 - 'key' => Visualizer_Plugin::CF_CHART_TYPE,
348 - 'value' => $filter,
349 - 'compare' => '=',
350 - ),
351 - );
352 - } else {
353 - $filter = 'all';
354 - }
875 +
876 + $this->getDisplayFilters( $query_args );
877 +
355 878 // Added by Ash/Upwork
356 - $filterByMeta = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
879 + $filterByMeta = ! empty( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
357 880 if ( $filterByMeta ) {
358 881 $query = array(
359 882 'key' => Visualizer_Plugin::CF_SETTINGS,
360 883 'value' => $filterByMeta,
@@ -363,49 +886,158 @@
363 886 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
364 887 $meta[] = $query;
365 888 $query_args['meta_query'] = $meta;
366 889 }
367 - // Added by Ash/Upwork
368 - // fetch charts
890 + $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
891 + return $q;
892 + }
893 +
894 + /**
895 + * Renders support page.
896 + *
897 + * @since 3.3.0
898 + *
899 + * @access public
900 + */
901 + public function renderSupportPage() {
902 + wp_enqueue_style( 'visualizer-upsell', VISUALIZER_ABSURL . 'css/upsell.css', array(), Visualizer_Plugin::VERSION );
903 + $this->load_survey();
904 + include_once VISUALIZER_ABSPATH . '/templates/support.php';
905 + }
906 +
907 + /**
908 + * Renders visualizer library page.
909 + *
910 + * @since 1.0.0
911 + *
912 + * @access public
913 + */
914 + public function renderLibraryPage() {
369 915 $charts = array();
370 - $query = new WP_Query( $query_args );
916 + $query = $this->getQuery();
917 +
918 + // get current page
919 + $page = filter_input(
920 + INPUT_GET,
921 + 'vpage',
922 + FILTER_VALIDATE_INT,
923 + array(
924 + 'options' => array(
925 + 'min_range' => 1,
926 + 'default' => 1,
927 + ),
928 + )
929 + );
930 + // add chart type filter to the query arguments
931 + $filter = filter_input( INPUT_GET, 'type' );
932 + if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) ) {
933 + $filter = 'all';
934 + }
935 +
936 + $css = '';
371 937 while ( $query->have_posts() ) {
372 938 $chart = $query->next_post();
939 +
940 + // if the user has updated a chart and instead of saving it, has closed the modal. If the user refreshes, they should get the original chart.
941 + $chart = $this->handleExistingRevisions( $chart->ID, $chart );
942 + // refresh a "live" db query chart.
943 + $chart = apply_filters( 'visualizer_schedule_refresh_chart', $chart, $chart->ID, false );
944 +
945 + $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
946 +
373 947 // fetch and update settings
374 948 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
375 - unset( $settings['height'], $settings['width'] );
376 - $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
949 +
950 + $settings = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $settings, $chart->ID, $type );
951 + if ( ! empty( $atts['settings'] ) ) {
952 + $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
953 + }
954 +
955 + if ( $settings ) {
956 + unset( $settings['height'], $settings['width'], $settings['chartArea'] );
957 + }
958 +
377 959 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
378 - $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( $chart->post_content ) ), $chart->ID, $type );
960 + $data = self::get_chart_data( $chart, $type );
961 +
962 + // Set default setting series when add manual chart data - Only during first creation.
963 + if ( isset( $settings['series'] ) && ! empty( $series ) ) {
964 + $count_series = count( $series ) - count( $settings['series'] );
965 + if ( $count_series > 1 ) {
966 + $clone_last_series = end( $settings['series'] );
967 + $clone_last_series = array_fill_keys( array_keys( $clone_last_series ), '' );
968 + foreach ( range( 1, $count_series ) as $item ) {
969 + $settings['series'][] = $clone_last_series;
970 + }
971 + }
972 + }
973 +
974 + $library = $this->load_chart_type( $chart->ID );
975 +
976 + $id = 'visualizer-' . $chart->ID;
977 + $arguments = $this->get_inline_custom_css( $id, $settings );
978 + if ( ! empty( $arguments ) ) {
979 + $css .= $arguments[0];
980 + $settings = $arguments[1];
981 + }
982 +
983 + if ( isset( $settings['controls']['ui']['labelStacking'] ) ) {
984 + unset( $settings['controls']['ui']['labelStacking'] );
985 + }
986 + if ( isset( $settings['controls']['ui']['orientation'] ) ) {
987 + unset( $settings['controls']['ui']['orientation'] );
988 + }
989 +
379 990 // add chart to the array
380 - $charts[ 'visualizer-' . $chart->ID ] = array(
991 + $charts[ $id ] = array(
381 992 'id' => $chart->ID,
382 993 'type' => $type,
383 994 'series' => $series,
384 995 'settings' => $settings,
385 996 'data' => $data,
997 + 'library' => $library,
386 998 );
387 999 }
388 1000 // enqueue charts array
389 1001 $ajaxurl = admin_url( 'admin-ajax.php' );
390 1002 wp_localize_script(
391 - 'visualizer-library', 'visualizer', array(
1003 + 'visualizer-library',
1004 + 'visualizer',
1005 + array(
1006 + 'language' => $this->get_language(),
1007 + 'map_api_key' => get_option( 'visualizer-map-api-key' ),
392 1008 'charts' => $charts,
393 1009 'urls' => array(
394 - 'base' => add_query_arg( 'vpage', false ),
395 - 'create' => add_query_arg(
396 - array(
397 - 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
398 - 'library' => 'yes',
399 - ), $ajaxurl
1010 + 'base' => esc_url( add_query_arg( array( 'vpage' => false, 'vaction' => false ) ) ),
1011 + 'create' => esc_url(
1012 + add_query_arg(
1013 + array(
1014 + 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
1015 + 'library' => 'yes',
1016 + 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
1017 + 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
1018 + 'vaction' => false,
1019 + ),
1020 + $ajaxurl
1021 + )
400 1022 ),
401 - 'edit' => add_query_arg(
402 - array(
403 - 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
404 - 'library' => 'yes',
405 - ), $ajaxurl
1023 + 'edit' => esc_url(
1024 + add_query_arg(
1025 + array(
1026 + 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
1027 + 'library' => 'yes',
1028 + 'vaction' => false,
1029 + ),
1030 + $ajaxurl
1031 + )
406 1032 ),
407 1033 ),
1034 + 'page_type' => 'library',
1035 + 'is_front' => false,
1036 + 'i10n' => array(
1037 + 'copied' => __( 'The shortcode has been copied to your clipboard. Hit Ctrl-V/Cmd-V to paste it.', 'visualizer' ),
1038 + 'conflict' => __( 'We have detected a potential conflict with another component that prevents Visualizer from functioning properly. Please disable any of the following components if they are activated on your instance: Modern Events Calendar plugin, Acronix plugin. In case the aforementioned components are not activated or you continue to see this error message, please disable all other plugins and enable them one by one to find out the component that is causing the conflict.', 'visualizer' ),
1039 + ),
408 1040 )
409 1041 );
410 1042 // render library page
411 1043 $render = new Visualizer_Render_Library();
@@ -410,12 +1042,13 @@
410 1042 // render library page
411 1043 $render = new Visualizer_Render_Library();
412 1044 $render->charts = $charts;
413 1045 $render->type = $filter;
414 - $render->types = self::_getChartTypesLocalized();
1046 + $render->types = self::_getChartTypesLocalized( false, false, false, true );
1047 + $render->custom_css = $css;
415 1048 $render->pagination = paginate_links(
416 1049 array(
417 - 'base' => add_query_arg( 'vpage', '%#%' ),
1050 + 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
418 1051 'format' => '',
419 1052 'current' => $page,
420 1053 'total' => $query->max_num_pages,
421 1054 'type' => 'array',
@@ -420,8 +1053,11 @@
420 1053 'total' => $query->max_num_pages,
421 1054 'type' => 'array',
422 1055 )
423 1056 );
1057 +
1058 + $this->load_survey();
1059 +
424 1060 $render->render();
425 1061 }
426 1062
427 1063 /**
@@ -436,14 +1072,14 @@
436 1072 *
437 1073 * @return array Updated array of action links.
438 1074 */
439 1075 public function getPluginActionLinks( $links, $file ) {
440 - if ( $file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1076 + if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
441 1077 array_unshift(
442 1078 $links,
443 1079 sprintf(
444 1080 '<a href="%s">%s</a>',
445 - admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ),
1081 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
446 1082 esc_html__( 'Library', 'visualizer' )
447 1083 )
448 1084 );
449 1085 }
@@ -463,17 +1099,17 @@
463 1099 *
464 1100 * @return array Updated array of plugin meta links.
465 1101 */
466 1102 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
467 - if ( $plugin_file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1103 + if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
468 1104 // knowledge base link
469 1105 $plugin_meta[] = sprintf(
470 - '<a href="https://github.com/codeinwp/visualizer/wiki" target="_blank">%s</a>',
471 - esc_html__( 'Knowledge Base', 'visualizer' )
1106 + '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1107 + esc_html__( 'Docs', 'visualizer' )
472 1108 );
473 1109 // flattr link
474 1110 $plugin_meta[] = sprintf(
475 - '<a style="color:red" href="https://themeisle.com/plugins/visualizer-charts-and-graphs-pro-addon/" target="_blank">%s</a>',
1111 + '<a style="color:red" href="' . tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'pluginrow' ) . '" target="_blank">%s</a>',
476 1112 esc_html__( 'Pro Addon', 'visualizer' )
477 1113 );
478 1114 }
479 1115
@@ -479,5 +1115,146 @@
479 1115
480 1116 return $plugin_meta;
481 1117 }
482 1118
1119 + /**
1120 + * If check is existing user.
1121 + *
1122 + * @return bool Default false
1123 + */
1124 + public static function proFeaturesLocked() {
1125 + if ( Visualizer_Module::is_pro() ) {
1126 + return true;
1127 + }
1128 + return 'yes' === get_option( 'visualizer-new-user', 'yes' ) ? false : true;
1129 + }
1130 +
1131 + /**
1132 + * Multilingual Support.
1133 + *
1134 + * @param int $chart_id Chart ID.
1135 + * @return bool Default false
1136 + */
1137 + public function addMultilingualSupport( $chart_id ) {
1138 + global $sitepress;
1139 + if ( Visualizer_Module::is_pro() ) {
1140 + return;
1141 + }
1142 + if ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) {
1143 + $language = icl_get_languages();
1144 + $current_lang = icl_get_current_language();
1145 + $default_lang = icl_get_default_language();
1146 + $post_info = wpml_get_language_information( null, $chart_id );
1147 + $translations = array();
1148 + if ( ! empty( $post_info ) && ( $default_lang === $post_info['language_code'] ) ) {
1149 + $trid = $sitepress->get_element_trid( $chart_id, 'post_' . Visualizer_Plugin::CPT_VISUALIZER );
1150 + $translations = $sitepress->get_element_translations( $trid );
1151 + }
1152 + if ( empty( $translations ) ) {
1153 + return;
1154 + }
1155 + ?>
1156 + <hr><div class="visualizer-languages-list only-pro">
1157 + <?php
1158 + foreach ( $language as $lang ) {
1159 + $lang_code = $lang['code'];
1160 + if ( $current_lang !== $lang_code ) {
1161 + ?>
1162 + <a href="javascript:;">
1163 + <img src="<?php echo esc_url( $lang['country_flag_url'] ); ?>" alt="<?php echo esc_attr( $lang['translated_name'] ); ?>">
1164 + </a>
1165 + <?php
1166 + }
1167 + }
1168 + ?>
1169 + <a href="<?php echo tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'wpml-support', 'visualizer_render_char' ); ?>"target="_blank"><?php esc_html_e( 'Upgrade to PRO to active this translation for charts', 'visualizer' ); ?></a>
1170 + </div>
1171 + <?php
1172 + }
1173 + }
1174 +
1175 + /**
1176 + * Check chart is enabled or not.
1177 + *
1178 + * @param string $type Chart ID.
1179 + *
1180 + * @return bool Default false
1181 + */
1182 + public static function checkChartStatus( $type ) {
1183 + $types = self::_getChartTypesLocalized( false, false, false, true );
1184 + if ( isset( $types[ $type ] ) ) {
1185 + return ! empty( $types[ $type ]['enabled'] );
1186 + }
1187 + return false;
1188 + }
1189 +
1190 + /**
1191 + * Get the survey metadata.
1192 + *
1193 + * @return array The survey metadata.
1194 + */
1195 + private function get_survey_metadata() {
1196 + $install_date = get_option( 'visualizer_install', false );
1197 + $install_category = 0;
1198 +
1199 + if ( false !== $install_date ) {
1200 + $days_since_install = round( ( time() - $install_date ) / DAY_IN_SECONDS );
1201 +
1202 + if ( 0 === $days_since_install || 1 === $days_since_install ) {
1203 + $install_category = 0;
1204 + } elseif ( 1 < $days_since_install && 8 > $days_since_install ) {
1205 + $install_category = 7;
1206 + } elseif ( 8 <= $days_since_install && 31 > $days_since_install ) {
1207 + $install_category = 30;
1208 + } elseif ( 30 < $days_since_install && 90 > $days_since_install ) {
1209 + $install_category = 90;
1210 + } elseif ( 90 <= $days_since_install ) {
1211 + $install_category = 91;
1212 + }
1213 + }
1214 +
1215 + $plugin_data = get_plugin_data( VISUALIZER_BASEFILE, false, false );
1216 + $plugin_version = '';
1217 + if ( ! empty( $plugin_data['Version'] ) ) {
1218 + $plugin_version = $plugin_data['Version'];
1219 + }
1220 +
1221 + $user_id = 'visualizer_' . preg_replace( '/[^\w\d]*/', '', get_site_url() ); // Use a normalized version of the site URL as a user ID.
1222 +
1223 + $license_data = get_option( 'visualizer_pro_license_data', false );
1224 + if ( false !== $license_data ) {
1225 + $user_id = 'visualizer_' . $license_data->key;
1226 + }
1227 +
1228 + return array(
1229 + 'userId' => $user_id,
1230 + 'attributes' => array(
1231 + 'days_since_install' => $install_category,
1232 + 'free_version' => $plugin_version,
1233 + 'pro_version' => defined( 'VISUALIZER_PRO_VERSION' ) ? VISUALIZER_PRO_VERSION : '',
1234 + 'license_status' => apply_filters( 'product_visualizer_license_status', 'invalid' ),
1235 + ),
1236 + );
1237 + }
1238 +
1239 + /**
1240 + * Load the survey.
1241 + */
1242 + private function load_survey() {
1243 +
1244 + if ( defined( 'TI_CYPRESS_TESTING' ) ) {
1245 + return;
1246 + }
1247 +
1248 + $survey_handler = apply_filters( 'themeisle_sdk_dependency_script_handler', 'survey' );
1249 +
1250 + if ( empty( $survey_handler ) ) {
1251 + return;
1252 + }
1253 +
1254 + $metadata = $this->get_survey_metadata();
1255 +
1256 + do_action( 'themeisle_sdk_dependency_enqueue_script', 'survey' );
1257 + wp_enqueue_script( 'visualizer_chart_survey', VISUALIZER_ABSURL . 'js/survey.js', array( $survey_handler ), $metadata['attributes']['free_version'], true );
1258 + wp_localize_script( 'visualizer_chart_survey', 'visualizerSurveyData', $metadata );
1259 + }
483 1260 }