PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.7.4
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.7.4
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 +692 -113 3.0.53.7.4 View file →
@@ -52,19 +52,231 @@
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' );
56 + $this->_addAction( 'admin_footer', 'renderTemplates' );
57 57 $this->_addAction( 'admin_enqueue_scripts', 'enqueueLibraryScripts', null, 8 );
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 + if ( defined( 'TI_CYPRESS_TESTING' ) ) {
78 + $this->load_cypress_hooks();
79 + }
80 +
64 81 }
65 82
66 83 /**
84 + * Define the hooks that are needed for cypress.
85 + *
86 + * @since 3.4.0
87 + * @access private
88 + */
89 + private function load_cypress_hooks() {
90 + // all charts should load on the same page without pagination.
91 + add_filter(
92 + 'visualizer_query_args', function( $args ) {
93 + $args['posts_per_page'] = 20;
94 + return $args;
95 + }, 10, 1
96 + );
97 + }
98 +
99 + /**
100 + * Add disabled `optgroup` schedules to the drop downs.
101 + *
102 + * @since ?
103 + *
104 + * @access public
105 + *
106 + * @param string $feature The feature for which to add schedules.
107 + * @param int $chart_id The chart ID.
108 + * @param int $plan The plan number.
109 + */
110 + public function addSplChartSchedules( $feature, $chart_id, $plan ) {
111 + if ( apply_filters( 'visualizer_is_business', false ) ) {
112 + return;
113 + }
114 +
115 + $license = __( 'PRO', 'visualizer' );
116 + if ( Visualizer_Module::is_pro() ) {
117 + switch ( $plan ) {
118 + case 1:
119 + $license = __( 'Developer', 'visualizer' );
120 + break;
121 + }
122 + }
123 +
124 + $hours = array(
125 + '0' => __( 'Live', 'visualizer' ),
126 + '1' => __( 'Each hour', 'visualizer' ),
127 + '12' => __( 'Each 12 hours', 'visualizer' ),
128 + '24' => __( 'Each day', 'visualizer' ),
129 + '72' => __( 'Each 3 days', 'visualizer' ),
130 + );
131 +
132 + switch ( $feature ) {
133 + case 'json':
134 + case 'csv':
135 + // no more schedules if pro is already active.
136 + if ( Visualizer_Module::is_pro() ) {
137 + return;
138 + }
139 + break;
140 + case 'wp':
141 + // fall-through.
142 + case 'db':
143 + break;
144 + default:
145 + return;
146 + }
147 +
148 + echo '<optgroup disabled label="' . sprintf( __( 'More in the %s version', 'visualizer' ), $license ) . '">';
149 + foreach ( $hours as $hour => $desc ) {
150 + echo '<option disabled>' . $desc . '</option>';
151 + }
152 + echo '</optgroup>';
153 + }
154 +
155 + /**
156 + * No limits on revisions.
157 + */
158 + public function limitRevisions( $num, $post ) {
159 + if ( Visualizer_Plugin::CPT_VISUALIZER === $post->post_type ) {
160 + return -1;
161 + }
162 + return $num;
163 + }
164 +
165 + /**
166 + * Add a revision.
167 + */
168 + public function addRevision( $revision_id ) {
169 + $parent_id = wp_is_post_revision( $revision_id );
170 + if ( Visualizer_Plugin::CPT_VISUALIZER === get_post_type( $parent_id ) ) {
171 + // add the meta data to this revision.
172 + $meta = get_post_meta( $parent_id, '', true );
173 +
174 + if ( $meta ) {
175 + foreach ( $meta as $key => $value ) {
176 + if ( 0 === strpos( $key, 'visualizer' ) ) {
177 + add_metadata( 'post', $revision_id, $key, maybe_unserialize( $value[0] ) );
178 + }
179 + }
180 + }
181 + }
182 + }
183 +
184 + /**
185 + * Restore a revision.
186 + */
187 + public function restoreRevision( $post_id, $revision_id ) {
188 + if ( Visualizer_Plugin::CPT_VISUALIZER === get_post_type( $post_id ) ) {
189 + // get the meta information from the revision.
190 + $meta = get_metadata( 'post', $revision_id, '', true );
191 +
192 + // delete all meta information from the post before adding.
193 + $post_meta = get_post_meta( $post_id, '', true );
194 + if ( $post_meta ) {
195 + foreach ( $meta as $key => $value ) {
196 + if ( 0 === strpos( $key, 'visualizer' ) ) {
197 + delete_post_meta( $post_id, $key );
198 + }
199 + }
200 + }
201 +
202 + if ( $meta ) {
203 + foreach ( $meta as $key => $value ) {
204 + if ( 0 === strpos( $key, 'visualizer' ) ) {
205 + add_post_meta( $post_id, $key, maybe_unserialize( $value[0] ) );
206 + }
207 + }
208 + }
209 + }
210 + }
211 +
212 + /**
213 + * Admin init.
214 + *
215 + * @access public
216 + */
217 + public function init() {
218 + // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
219 + if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && 'true' == get_user_option( 'rich_editing' ) ) {
220 + $this->_addFilter( 'mce_external_languages', 'add_tinymce_lang', 10, 1 );
221 + $this->_addFilter( 'mce_external_plugins', 'tinymce_plugin', 10, 1 );
222 + $this->_addFilter( 'mce_buttons', 'register_mce_button', 10, 1 );
223 + $this->_addFilter( 'tiny_mce_before_init', 'get_strings_for_block', 10, 1 );
224 + }
225 + }
226 +
227 + /**
228 + * Add the strings required for the TinyMCE buttons for the classic block (not the classic editor).
229 + *
230 + * @since ?
231 + * @access friendly
232 + */
233 + function get_strings_for_block( $settings ) {
234 + $class = new Visualizer_Module_Language();
235 + $strings = $class->get_strings();
236 + $array = array( 'visualizer_tinymce_plugin' => json_encode( $strings ) );
237 + return array_merge( $settings, $array );
238 + }
239 +
240 + /**
241 + * Load plugin translation for - TinyMCE API
242 + *
243 + * @access public
244 + * @param array $arr The tinymce_lang array.
245 + * @return array
246 + */
247 + public function add_tinymce_lang( $arr ) {
248 + $ui_lang = VISUALIZER_ABSPATH . '/classes/Visualizer/Module/Language.php';
249 + $ui_lang = apply_filters( 'visualizer_ui_lang_filter', $ui_lang );
250 + $arr[] = $ui_lang;
251 + return $arr;
252 + }
253 +
254 + /**
255 + * Load custom js options - TinyMCE API
256 + *
257 + * @access public
258 + * @param array $plugin_array The tinymce plugin array.
259 + * @return array
260 + */
261 + public function tinymce_plugin( $plugin_array ) {
262 + $plugin_array['visualizer_mce_button'] = VISUALIZER_ABSURL . 'js/mce.js';
263 + return $plugin_array;
264 + }
265 +
266 + /**
267 + * Register new button in the editor
268 + *
269 + * @access public
270 + * @param array $buttons The tinymce buttons array.
271 + * @return array
272 + */
273 + public function register_mce_button( $buttons ) {
274 + array_push( $buttons, 'visualizer_mce_button' );
275 + return $buttons;
276 + }
277 +
278 + /**
67 279 * Whether to show the feedback review or not.
68 280 *
69 281 * @access public
70 282 */
@@ -97,14 +309,28 @@
97 309 public function enqueueMediaScripts() {
98 310 global $typenow;
99 311 if ( post_type_supports( $typenow, 'editor' ) ) {
100 312 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 );
313 +
314 + // Load all the assets for the different libraries we support.
315 + $deps = array(
316 + Visualizer_Render_Sidebar_Google::enqueue_assets( array( 'media-editor' ) ),
317 + Visualizer_Render_Sidebar_Type_DataTable_Tabular::enqueue_assets( array( 'media-editor' ) ),
318 + );
319 +
320 + wp_enqueue_script( 'visualizer-media-model', VISUALIZER_ABSURL . 'js/media/model.js', $deps, Visualizer_Plugin::VERSION, true );
104 321 wp_enqueue_script( 'visualizer-media-collection', VISUALIZER_ABSURL . 'js/media/collection.js', array( 'visualizer-media-model' ), Visualizer_Plugin::VERSION, true );
105 322 wp_enqueue_script( 'visualizer-media-controller', VISUALIZER_ABSURL . 'js/media/controller.js', array( 'visualizer-media-collection' ), Visualizer_Plugin::VERSION, true );
106 323 wp_enqueue_script( 'visualizer-media-view', VISUALIZER_ABSURL . 'js/media/view.js', array( 'visualizer-media-controller' ), Visualizer_Plugin::VERSION, true );
324 + wp_localize_script(
325 + 'visualizer-media-view',
326 + 'visualizer',
327 + array(
328 + 'i10n' => array(
329 + 'insert' => __( 'Insert', 'visualizer' ),
330 + ),
331 + )
332 + );
107 333 wp_enqueue_script( 'visualizer-media-toolbar', VISUALIZER_ABSURL . 'js/media/toolbar.js', array( 'visualizer-media-view' ), Visualizer_Plugin::VERSION, true );
108 334 wp_enqueue_script( 'visualizer-media', VISUALIZER_ABSURL . 'js/media.js', array( 'visualizer-media-toolbar' ), Visualizer_Plugin::VERSION, true );
109 335 }
110 336 }
@@ -120,8 +346,9 @@
120 346 *
121 347 * @return array The extended array of media view strings.
122 348 */
123 349 public function setupMediaViewStrings( $strings ) {
350 + $chart_types = self::_getChartTypesLocalized( true, true, true );
124 351 $strings['visualizer'] = array(
125 352 'actions' => array(
126 353 'get_charts' => Visualizer_Plugin::ACTION_GET_CHARTS,
127 354 'delete_chart' => Visualizer_Plugin::ACTION_DELETE_CHART,
@@ -133,10 +360,10 @@
133 360 'library' => esc_html__( 'From Library', 'visualizer' ),
134 361 'create' => esc_html__( 'Create New', 'visualizer' ),
135 362 ),
136 363 'library' => array(
137 - 'filters' => self::_getChartTypesLocalized( true, true ),
138 - 'types' => array_keys( self::_getChartTypesLocalized( true, true ) ),
364 + 'filters' => $chart_types,
365 + 'types' => array_keys( $chart_types ),
139 366 ),
140 367 'nonce' => wp_create_nonce(),
141 368 'buildurl' => add_query_arg( 'action', Visualizer_Plugin::ACTION_CREATE_CHART, admin_url( 'admin-ajax.php' ) ),
142 369 );
@@ -152,59 +379,101 @@
152 379 * @static
153 380 * @access private
154 381 * @return array The associated array of chart types with localized names.
155 382 */
156 - public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false ) {
157 - $types = array(
158 - 'pie' => array(
159 - 'name' => esc_html__( 'Pie', 'visualizer' ),
383 + public static function _getChartTypesLocalized( $enabledOnly = false, $get2Darray = false, $add_select = false, $where = null ) {
384 + $additional = array();
385 + if ( $add_select ) {
386 + $additional['select'] = array(
387 + 'name' => esc_html__( 'All', 'visualizer' ),
160 388 '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 - ),
389 + );
390 + }
391 +
392 + $enabled = self::proFeaturesLocked();
393 +
394 + $types = array_merge(
395 + $additional,
396 + array(
397 + 'tabular' => array(
398 + 'name' => esc_html__( 'Table', 'visualizer' ),
399 + 'enabled' => true,
400 + 'supports' => $enabled ? array( 'Google Charts', 'DataTable' ) : array( 'DataTable' ),
401 + ),
402 + 'pie' => array(
403 + 'name' => esc_html__( 'Pie/Donut', 'visualizer' ),
404 + 'enabled' => true,
405 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
406 + ),
407 + 'line' => array(
408 + 'name' => esc_html__( 'Line', 'visualizer' ),
409 + 'enabled' => true,
410 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
411 + ),
412 + 'bar' => array(
413 + 'name' => esc_html__( 'Bar', 'visualizer' ),
414 + 'enabled' => true,
415 + 'supports' => $enabled ? array( 'Google Charts', 'ChartJS' ) : array( 'Google Charts' ),
416 + ),
417 + 'area' => array(
418 + 'name' => esc_html__( 'Area', 'visualizer' ),
419 + 'enabled' => $enabled,
420 + // in ChartJS, the fill option is used to make Line chart an area: https://www.chartjs.org/docs/latest/charts/area.html
421 + 'supports' => array( 'Google Charts' ),
422 + ),
423 + 'geo' => array(
424 + 'name' => esc_html__( 'Geo', 'visualizer' ),
425 + 'enabled' => $enabled,
426 + 'supports' => array( 'Google Charts' ),
427 + ),
428 + 'column' => array(
429 + 'name' => esc_html__( 'Column', 'visualizer' ),
430 + 'enabled' => $enabled,
431 + 'supports' => array( 'Google Charts', 'ChartJS' ),
432 + ),
433 + 'bubble' => array(
434 + 'name' => esc_html__( 'Bubble', 'visualizer' ),
435 + 'enabled' => $enabled,
436 + // chartjs' bubble is ugly looking (and it won't work off the default bubble.csv) so it is being excluded for the time being.
437 + 'supports' => array( 'Google Charts' ),
438 + ),
439 + 'scatter' => array(
440 + 'name' => esc_html__( 'Scatter', 'visualizer' ),
441 + 'enabled' => $enabled,
442 + 'supports' => array( 'Google Charts' ),
443 + ),
444 + 'gauge' => array(
445 + 'name' => esc_html__( 'Gauge', 'visualizer' ),
446 + 'enabled' => $enabled,
447 + 'supports' => array( 'Google Charts' ),
448 + ),
449 + 'candlestick' => array(
450 + 'name' => esc_html__( 'Candlestick', 'visualizer' ),
451 + 'enabled' => $enabled,
452 + 'supports' => array( 'Google Charts' ),
453 + ),
454 + // pro types
455 + 'timeline' => array(
456 + 'name' => esc_html__( 'Timeline', 'visualizer' ),
457 + 'enabled' => false,
458 + 'supports' => array( 'Google Charts', 'ChartJS' ),
459 + ),
460 + 'combo' => array(
461 + 'name' => esc_html__( 'Combo', 'visualizer' ),
462 + 'enabled' => false,
463 + 'supports' => array( 'Google Charts' ),
464 + ),
465 + 'polarArea' => array(
466 + 'name' => esc_html__( 'Polar Area', 'visualizer' ),
467 + 'enabled' => false,
468 + 'supports' => array( 'ChartJS' ),
469 + ),
470 + 'radar' => array(
471 + 'name' => esc_html__( 'Radar/Spider', 'visualizer' ),
472 + 'enabled' => false,
473 + 'supports' => array( 'ChartJS' ),
474 + ),
475 + )
207 476 );
208 477 $types = apply_filters( 'visualizer_pro_chart_types', $types );
209 478 if ( $enabledOnly ) {
210 479 $filtered = array();
@@ -212,8 +481,12 @@
212 481 if ( ! is_array( $array ) ) {
213 482 // support for old pro
214 483 $array = array( 'enabled' => true, 'name' => $array );
215 484 }
485 + // backward compatibility for PRO before v1.9.0
486 + if ( ! array_key_exists( 'supports', $array ) ) {
487 + $array['supports'] = array( 'Google Charts' );
488 + }
216 489 if ( ! $array['enabled'] ) {
217 490 continue;
218 491 }
219 492 $filtered[ $type ] = $array;
@@ -226,13 +499,74 @@
226 499 if ( ! is_array( $array ) ) {
227 500 // support for old pro
228 501 $array = array( 'enabled' => true, 'name' => $array );
229 502 }
503 + // backward compatibility for PRO before v1.9.0
504 + if ( ! array_key_exists( 'supports', $array ) ) {
505 + $array['supports'] = array( 'Google Charts' );
506 + }
230 507 $doubleD[ $type ] = $array['name'];
231 508 }
232 509 $types = $doubleD;
233 510 }
234 511
512 + return self::handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where );
513 + }
514 +
515 + /**
516 + * Handle (soon-to-be) deprecated charts.
517 + */
518 + private static function handleDeprecatedCharts( $types, $enabledOnly, $get2Darray, $where ) {
519 + $deprecated = array();
520 +
521 + switch ( $where ) {
522 + case 'types':
523 + // fall-through
524 + case 'library':
525 + // if a user has a Gauge/Candlestick chart, then let them keep using it.
526 + if ( ! Visualizer_Module::is_pro() ) {
527 + if ( ! self::hasChartType( 'gauge' ) ) {
528 + if ( $get2Darray ) {
529 + $deprecated[] = 'gauge';
530 + } else {
531 + $types['gauge']['enabled'] = false;
532 + }
533 + }
534 + if ( ! self::hasChartType( 'candlestick' ) ) {
535 + if ( $get2Darray ) {
536 + $deprecated[] = 'candlestick';
537 + } else {
538 + $types['candlestick']['enabled'] = false;
539 + }
540 + }
541 + }
542 + break;
543 + default:
544 + // if a user has a Gauge/Candlestick chart, then let them keep using it.
545 + if ( ! Visualizer_Module::is_pro() ) {
546 + if ( ! self::hasChartType( 'gauge' ) ) {
547 + if ( $get2Darray ) {
548 + $deprecated[] = 'gauge';
549 + } else {
550 + $types['gauge']['enabled'] = false;
551 + }
552 + }
553 + if ( ! self::hasChartType( 'candlestick' ) ) {
554 + if ( $get2Darray ) {
555 + $deprecated[] = 'candlestick';
556 + } else {
557 + $types['candlestick']['enabled'] = false;
558 + }
559 + }
560 + }
561 + }
562 +
563 + if ( $deprecated ) {
564 + foreach ( $deprecated as $type ) {
565 + unset( $types[ $type ] );
566 + }
567 + }
568 +
235 569 return $types;
236 570 }
237 571
238 572 /**
@@ -242,11 +576,11 @@
242 576 * @global string $pagenow The name of the current page.
243 577 *
244 578 * @access public
245 579 */
246 - public function renderTempaltes() {
580 + public function renderTemplates() {
247 581 global $pagenow;
248 - if ( 'post.php' != $pagenow && 'post-new.php' != $pagenow ) {
582 + if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
249 583 return;
250 584 }
251 585 $render = new Visualizer_Render_Templates();
252 586 $render->render();
@@ -264,26 +598,41 @@
264 598 *
265 599 * @param string $suffix The current page suffix.
266 600 */
267 601 public function enqueueLibraryScripts( $suffix ) {
268 - if ( $suffix == $this->_libraryPage ) {
602 + if ( $suffix === $this->_libraryPage ) {
269 603 wp_enqueue_style( 'visualizer-library', VISUALIZER_ABSURL . 'css/library.css', array(), Visualizer_Plugin::VERSION );
270 604 $this->_addFilter( 'media_upload_tabs', 'setupVisualizerTab' );
271 605 wp_enqueue_media();
272 606 wp_enqueue_script(
273 - 'visualizer-library', VISUALIZER_ABSURL . 'js/library.js', array(
607 + 'visualizer-library',
608 + VISUALIZER_ABSURL . 'js/library.js',
609 + array(
274 610 'jquery',
275 611 'media-views',
276 - ), Visualizer_Plugin::VERSION, true
612 + 'clipboard',
613 + ),
614 + Visualizer_Plugin::VERSION,
615 + true
277 616 );
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 - );
617 +
618 + wp_enqueue_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
619 +
620 + $query = $this->getQuery();
621 + while ( $query->have_posts() ) {
622 + $chart = $query->next_post();
623 + $library = $this->load_chart_type( $chart->ID );
624 + if ( is_null( $library ) ) {
625 + continue;
626 + }
627 + wp_enqueue_script(
628 + "visualizer-render-$library",
629 + VISUALIZER_ABSURL . 'js/render-facade.js',
630 + apply_filters( 'visualizer_assets_render', array( 'visualizer-library', 'visualizer-customization' ), true ),
631 + Visualizer_Plugin::VERSION,
632 + true
633 + );
634 + }
286 635 }
287 636 }
288 637
289 638 /**
@@ -310,24 +659,140 @@
310 659 *
311 660 * @access public
312 661 */
313 662 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 );
663 + $svg_base64_icon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNzdweCIgaGVpZ2h0PSI3N3B4IiB2aWV3Qm94PSIwIDAgNzcgNzciIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjYgKDY3NDkxKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Db21iaW5lZCBTaGFwZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxnIGlkPSJQcm9kdWN0LVBhZ2UiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJXb3JkUHJlc3MtcGx1Z2lucyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE5MC4wMDAwMDAsIC00MzUuMDAwMDAwKSIgZmlsbD0iIzM5QzNEMiI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMjguNSw1MTIgQzIwNy4yMzcwMzcsNTEyIDE5MCw0OTQuNzYyOTYzIDE5MCw0NzMuNSBDMTkwLDQ1Mi4yMzcwMzcgMjA3LjIzNzAzNyw0MzUgMjI4LjUsNDM1IEMyNDkuNzYyOTYzLDQzNSAyNjcsNDUyLjIzNzAzNyAyNjcsNDczLjUgQzI2Nyw0OTQuNzYyOTYzIDI0OS43NjI5NjMsNTEyIDIyOC41LDUxMiBaIE0yNDYuODQzNzUsNDgzLjU5MjA1OSBMMjE1LjYyNSw0ODMuNTkyMDU5IEwyMTUuNjI1LDQ2MC44MjY1NDQgQzIxNS42MjUsNDYwLjE2NDU0NyAyMTUuMTA3NTc4LDQ1OS42MjgzNTkgMjE0LjQ2ODc1LDQ1OS42MjgzNTkgTDIxMi4xNTYyNSw0NTkuNjI4MzU5IEMyMTEuNTE3NDIyLDQ1OS42MjgzNTkgMjExLDQ2MC4xNjQ1NDcgMjExLDQ2MC44MjY1NDQgTDIxMSw0ODUuOTg4NDI5IEMyMTEsNDg3LjMxMTY3NCAyMTIuMDM1NTY2LDQ4OC4zODQ3OTggMjEzLjMxMjUsNDg4LjM4NDc5OCBMMjQ2Ljg0Mzc1LDQ4OC4zODQ3OTggQzI0Ny40ODI1NzgsNDg4LjM4NDc5OCAyNDgsNDg3Ljg0ODYxMSAyNDgsNDg3LjE4NjYxMyBMMjQ4LDQ4NC43OTAyNDQgQzI0OCw0ODQuMTI4MjQ2IDI0Ny40ODI1NzgsNDgzLjU5MjA1OSAyNDYuODQzNzUsNDgzLjU5MjA1OSBaIE0yNDQuNTMxMjUsNDYyLjAyNDcyOSBMMjM1Ljk5OTU3LDQ2Mi4wMjQ3MjkgQzIzNC40NTQ1MzEsNDYyLjAyNDcyOSAyMzMuNjgwNTY2LDQ2My45NjA1NDcgMjM0Ljc3MzIyMyw0NjUuMDkyODMyIEwyMzcuMTE0NjI5LDQ2Ny41MTkxNTYgTDIzMS44MTI1LDQ3My4wMTQzMzIgTDIyNi41MTAzNzEsNDY3LjUxOTkwNSBDMjI1LjYwNzA1MSw0NjYuNTgzODIzIDIyNC4xNDI5NDksNDY2LjU4MzgyMyAyMjMuMjQwMzUyLDQ2Ny41MTk5MDUgTDIxOC4yNzY0MjYsNDcyLjY2Mzg2MyBDMjE3LjgyNDc2Niw0NzMuMTMxOTA0IDIxNy44MjQ3NjYsNDczLjg5MDUwNSAyMTguMjc2NDI2LDQ3NC4zNTg1NDYgTDIxOS45MTEwNzQsNDc2LjA1MjQ4IEMyMjAuMzYyNzM0LDQ3Ni41MjA1MjEgMjIxLjA5NDc4NSw0NzYuNTIwNTIxIDIyMS41NDY0NDUsNDc2LjA1MjQ4IEwyMjQuODc1LDQ3Mi42MDI0NTYgTDIzMC4xNzcxMjksNDc4LjA5Njg4MyBDMjMxLjA4MDQ0OSw0NzkuMDMyOTY1IDIzMi41NDQ1NTEsNDc5LjAzMjk2NSAyMzMuNDQ3MTQ4LDQ3OC4wOTY4ODMgTDI0MC4zODQ2NDgsNDcwLjkwNzc3MyBMMjQyLjcyNjA1NSw0NzMuMzM0MDk4IEMyNDMuODE4NzExLDQ3NC40NjYzODIgMjQ1LjY4Njc3Nyw0NzMuNjY0MzQ3IDI0NS42ODY3NzcsNDcyLjA2MzI3MyBMMjQ1LjY4Njc3Nyw0NjMuMjIyOTE0IEMyNDUuNjg3NSw0NjIuNTYwOTE3IDI0NS4xNzAwNzgsNDYyLjAyNDcyOSAyNDQuNTMxMjUsNDYyLjAyNDcyOSBaIiBpZD0iQ29tYmluZWQtU2hhcGUiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==';
664 +
665 + $this->_libraryPage = add_menu_page( __( 'Visualizer', 'visualizer' ), __( 'Visualizer', 'visualizer' ), 'edit_posts', Visualizer_Plugin::NAME, array( $this, 'renderLibraryPage' ), $svg_base64_icon, 99.7666 );
666 +
667 + add_submenu_page(
668 + Visualizer_Plugin::NAME,
669 + __( 'Chart Library', 'visualizer' ),
670 + __( 'Chart Library', 'visualizer' ),
671 + 'edit_posts',
672 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME )
673 + );
674 + add_submenu_page(
675 + Visualizer_Plugin::NAME,
676 + __( 'Add New Chart', 'visualizer' ),
677 + __( 'Add New Chart', 'visualizer' ),
678 + 'edit_posts',
679 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew' )
680 + );
681 + add_submenu_page(
682 + Visualizer_Plugin::NAME,
683 + __( 'Support', 'visualizer' ),
684 + __( '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>',
685 + 'edit_posts',
686 + 'viz-support',
687 + array( $this, 'renderSupportPage' )
688 + );
689 + remove_submenu_page( Visualizer_Plugin::NAME, Visualizer_Plugin::NAME );
690 +
691 + add_action( "load-{$this->_libraryPage}", array( $this, 'addScreenOptions' ) );
317 692 }
318 693
319 694 /**
320 - * Renders visualizer library page.
321 - *
322 - * @since 1.0.0
323 - *
324 - * @access public
695 + * Adds the screen options for pagination.
325 696 */
326 - public function renderLibraryPage() {
697 + function addScreenOptions() {
698 + $screen = get_current_screen();
699 +
700 + // bail if it's some other page.
701 + if ( ! is_object( $screen ) || $screen->id !== $this->_libraryPage ) {
702 + return;
703 + }
704 +
705 + $args = array(
706 + 'label' => __( 'Number of charts per page:', 'visualizer' ),
707 + 'default' => 6,
708 + 'option' => 'visualizer_library_per_page',
709 + );
710 + add_screen_option( 'per_page', $args );
711 + }
712 +
713 + /**
714 + * Returns the screen option for pagination.
715 + */
716 + function setScreenOptions( $status, $option, $value ) {
717 + if ( 'visualizer_library_per_page' === $option ) {
718 + return $value;
719 + }
720 + }
721 +
722 + /**
723 + * Adds the display filters to be used in the meta_query while displaying the charts.
724 + */
725 + private function getDisplayFilters( &$query_args ) {
726 + $query = array();
727 +
728 + // add chart type filter to the query arguments
729 + $type = filter_input( INPUT_GET, 'type' );
730 + if ( $type && in_array( $type, Visualizer_Plugin::getChartTypes(), true ) ) {
731 + $query[] = array(
732 + 'key' => Visualizer_Plugin::CF_CHART_TYPE,
733 + 'value' => $type,
734 + 'compare' => '=',
735 + );
736 + }
737 +
738 + // add chart library filter to the query arguments
739 + $library = filter_input( INPUT_GET, 'library' );
740 + if ( $library ) {
741 + $query[] = array(
742 + 'key' => Visualizer_Plugin::CF_CHART_LIBRARY,
743 + 'value' => $library,
744 + 'compare' => '=',
745 + );
746 + }
747 +
748 + // add date filter to the query arguments
749 + $date = filter_input( INPUT_GET, 'date' );
750 + $possible = array_keys( Visualizer_Plugin::getSupportedDateFilter() );
751 + if ( $date && in_array( $date, $possible, true ) ) {
752 + $query_args['date_query'] = array(
753 + 'after' => "$date -1 day",
754 + 'inclusive' => true,
755 + );
756 + }
757 +
758 + // add source filter to the query arguments
759 + $source = filter_input( INPUT_GET, 'source' );
760 + if ( $source ) {
761 + $source = ucwords( $source );
762 + $source = "Visualizer_Source_{$source}";
763 + $query[] = array(
764 + 'key' => Visualizer_Plugin::CF_SOURCE,
765 + 'value' => $source,
766 + 'compare' => '=',
767 + );
768 + }
769 +
770 + $query_args['meta_query'] = $query;
771 +
772 + $orderby = filter_input( INPUT_GET, 'orderby' );
773 + $order = filter_input( INPUT_GET, 'order' );
774 + if ( $orderby ) {
775 + $query_args['order_by'] = $orderby;
776 + }
777 + $query_args['order'] = empty( $order ) ? 'desc' : $order;
778 + }
779 +
780 + /**
781 + * Get the instance of WP_Query that fetches the charts as per the given criteria.
782 + */
783 + private function getQuery() {
784 + static $q;
785 + if ( ! is_null( $q ) ) {
786 + return $q;
787 + }
788 +
327 789 // get current page
328 790 $page = filter_input(
329 - INPUT_GET, 'vpage', FILTER_VALIDATE_INT, array(
791 + INPUT_GET,
792 + 'vpage',
793 + FILTER_VALIDATE_INT,
794 + array(
330 795 'options' => array(
331 796 'min_range' => 1,
332 797 'default' => 1,
333 798 ),
@@ -332,27 +797,32 @@
332 797 'default' => 1,
333 798 ),
334 799 )
335 800 );
801 +
802 + $per_page = 6;
803 + $screen = get_current_screen();
804 + if ( $screen ) {
805 + // retrieve the per_page option
806 + $screen_option = $screen->get_option( 'per_page', 'option' );
807 + // retrieve the value stored for the current user
808 + $user = get_current_user_id();
809 + $per_page = get_user_meta( $user, $screen_option, true );
810 + if ( empty( $per_page ) || $per_page < 1 ) {
811 + // nothing set, get the default value
812 + $per_page = $screen->get_option( 'per_page', 'default' );
813 + }
814 + }
815 +
336 816 // the initial query arguments to fetch charts
337 817 $query_args = array(
338 818 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
339 - 'posts_per_page' => 6,
819 + 'posts_per_page' => $per_page,
340 820 'paged' => $page,
341 821 );
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 - }
822 +
823 + $this->getDisplayFilters( $query_args );
824 +
355 825 // Added by Ash/Upwork
356 826 $filterByMeta = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
357 827 if ( $filterByMeta ) {
358 828 $query = array(
@@ -363,49 +833,146 @@
363 833 $meta = isset( $query_args['meta_query'] ) ? $query_args['meta_query'] : array();
364 834 $meta[] = $query;
365 835 $query_args['meta_query'] = $meta;
366 836 }
367 - // Added by Ash/Upwork
368 - // fetch charts
837 + $q = new WP_Query( apply_filters( 'visualizer_query_args', $query_args ) );
838 + return $q;
839 + }
840 +
841 + /**
842 + * Renders support page.
843 + *
844 + * @since 3.3.0
845 + *
846 + * @access public
847 + */
848 + public function renderSupportPage() {
849 + wp_enqueue_style( 'visualizer-upsell', VISUALIZER_ABSURL . 'css/upsell.css', array(), Visualizer_Plugin::VERSION );
850 + include_once VISUALIZER_ABSPATH . '/templates/support.php';
851 + }
852 +
853 + /**
854 + * Renders visualizer library page.
855 + *
856 + * @since 1.0.0
857 + *
858 + * @access public
859 + */
860 + public function renderLibraryPage() {
369 861 $charts = array();
370 - $query = new WP_Query( $query_args );
862 + $query = $this->getQuery();
863 +
864 + // get current page
865 + $page = filter_input(
866 + INPUT_GET,
867 + 'vpage',
868 + FILTER_VALIDATE_INT,
869 + array(
870 + 'options' => array(
871 + 'min_range' => 1,
872 + 'default' => 1,
873 + ),
874 + )
875 + );
876 + // add chart type filter to the query arguments
877 + $filter = filter_input( INPUT_GET, 'type' );
878 + if ( ! ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) ) {
879 + $filter = 'all';
880 + }
881 +
882 + $css = '';
371 883 while ( $query->have_posts() ) {
372 884 $chart = $query->next_post();
885 +
886 + // 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.
887 + $chart = $this->handleExistingRevisions( $chart->ID, $chart );
888 + // refresh a "live" db query chart.
889 + $chart = apply_filters( 'visualizer_schedule_refresh_chart', $chart, $chart->ID, false );
890 +
891 + $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
892 +
373 893 // fetch and update settings
374 894 $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 );
895 +
896 + $settings = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $settings, $chart->ID, $type );
897 + if ( ! empty( $atts['settings'] ) ) {
898 + $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
899 + }
900 +
901 + if ( $settings ) {
902 + unset( $settings['height'], $settings['width'], $settings['chartArea'] );
903 + }
904 +
377 905 $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 );
906 + $data = self::get_chart_data( $chart, $type );
907 +
908 + // Set default setting series when add manual chart data - Only during first creation.
909 + if ( isset( $settings['series'] ) && ! empty( $series ) ) {
910 + $count_series = count( $series ) - count( $settings['series'] );
911 + if ( $count_series > 1 ) {
912 + $clone_last_series = end( $settings['series'] );
913 + $clone_last_series = array_fill_keys( array_keys( $clone_last_series ), '' );
914 + foreach ( range( 1, $count_series ) as $item ) {
915 + $settings['series'][] = $clone_last_series;
916 + }
917 + }
918 + }
919 +
920 + $library = $this->load_chart_type( $chart->ID );
921 +
922 + $id = 'visualizer-' . $chart->ID;
923 + $arguments = $this->get_inline_custom_css( $id, $settings );
924 + if ( ! empty( $arguments ) ) {
925 + $css .= $arguments[0];
926 + $settings = $arguments[1];
927 + }
928 +
379 929 // add chart to the array
380 - $charts[ 'visualizer-' . $chart->ID ] = array(
930 + $charts[ $id ] = array(
381 931 'id' => $chart->ID,
382 932 'type' => $type,
383 933 'series' => $series,
384 934 'settings' => $settings,
385 935 'data' => $data,
936 + 'library' => $library,
386 937 );
387 938 }
388 939 // enqueue charts array
389 940 $ajaxurl = admin_url( 'admin-ajax.php' );
390 941 wp_localize_script(
391 - 'visualizer-library', 'visualizer', array(
942 + 'visualizer-library',
943 + 'visualizer',
944 + array(
945 + 'language' => $this->get_language(),
946 + 'map_api_key' => get_option( 'visualizer-map-api-key' ),
392 947 'charts' => $charts,
393 948 'urls' => array(
394 - 'base' => add_query_arg( 'vpage', false ),
949 + 'base' => add_query_arg( array( 'vpage' => false, 'vaction' => false ) ),
395 950 'create' => add_query_arg(
396 951 array(
397 952 'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
398 953 'library' => 'yes',
399 - ), $ajaxurl
954 + 'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
955 + 'chart-library' => isset( $_GET['chart-library'] ) ? $_GET['chart-library'] : '',
956 + 'vaction' => false,
957 + ),
958 + $ajaxurl
400 959 ),
401 960 'edit' => add_query_arg(
402 961 array(
403 962 'action' => Visualizer_Plugin::ACTION_EDIT_CHART,
404 963 'library' => 'yes',
405 - ), $ajaxurl
964 + 'vaction' => false,
965 + ),
966 + $ajaxurl
406 967 ),
407 968 ),
969 + 'page_type' => 'library',
970 + 'is_front' => false,
971 + 'i10n' => array(
972 + 'copied' => __( 'The shortcode has been copied to your clipboard. Hit Ctrl-V/Cmd-V to paste it.', 'visualizer' ),
973 + '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' ),
974 + ),
408 975 )
409 976 );
410 977 // render library page
411 978 $render = new Visualizer_Render_Library();
@@ -410,12 +977,13 @@
410 977 // render library page
411 978 $render = new Visualizer_Render_Library();
412 979 $render->charts = $charts;
413 980 $render->type = $filter;
414 - $render->types = self::_getChartTypesLocalized();
981 + $render->types = self::_getChartTypesLocalized( false, false, false, true );
982 + $render->custom_css = $css;
415 983 $render->pagination = paginate_links(
416 984 array(
417 - 'base' => add_query_arg( 'vpage', '%#%' ),
985 + 'base' => add_query_arg( array( 'vpage' => '%#%', 'vaction' => false ) ),
418 986 'format' => '',
419 987 'current' => $page,
420 988 'total' => $query->max_num_pages,
421 989 'type' => 'array',
@@ -436,14 +1004,14 @@
436 1004 *
437 1005 * @return array Updated array of action links.
438 1006 */
439 1007 public function getPluginActionLinks( $links, $file ) {
440 - if ( $file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1008 + if ( $file === plugin_basename( VISUALIZER_BASEFILE ) ) {
441 1009 array_unshift(
442 1010 $links,
443 1011 sprintf(
444 1012 '<a href="%s">%s</a>',
445 - admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ),
1013 + admin_url( 'admin.php?page=' . Visualizer_Plugin::NAME ),
446 1014 esc_html__( 'Library', 'visualizer' )
447 1015 )
448 1016 );
449 1017 }
@@ -463,17 +1031,17 @@
463 1031 *
464 1032 * @return array Updated array of plugin meta links.
465 1033 */
466 1034 public function getPluginMetaLinks( $plugin_meta, $plugin_file ) {
467 - if ( $plugin_file == plugin_basename( VISUALIZER_BASEFILE ) ) {
1035 + if ( $plugin_file === plugin_basename( VISUALIZER_BASEFILE ) ) {
468 1036 // knowledge base link
469 1037 $plugin_meta[] = sprintf(
470 - '<a href="https://github.com/codeinwp/visualizer/wiki" target="_blank">%s</a>',
471 - esc_html__( 'Knowledge Base', 'visualizer' )
1038 + '<a href="' . VISUALIZER_MAIN_DOC . '" target="_blank">%s</a>',
1039 + esc_html__( 'Docs', 'visualizer' )
472 1040 );
473 1041 // flattr link
474 1042 $plugin_meta[] = sprintf(
475 - '<a style="color:red" href="https://themeisle.com/plugins/visualizer-charts-and-graphs-pro-addon/" target="_blank">%s</a>',
1043 + '<a style="color:red" href="' . Visualizer_Plugin::PRO_TEASER_URL . '" target="_blank">%s</a>',
476 1044 esc_html__( 'Pro Addon', 'visualizer' )
477 1045 );
478 1046 }
479 1047
@@ -479,5 +1047,16 @@
479 1047
480 1048 return $plugin_meta;
481 1049 }
482 1050
1051 + /**
1052 + * If check is existing user.
1053 + *
1054 + * @return bool Default false
1055 + */
1056 + public static function proFeaturesLocked() {
1057 + if ( Visualizer_Module::is_pro() ) {
1058 + return true;
1059 + }
1060 + return 'yes' === get_option( 'visualizer-new-user', 'yes' ) ? false : true;
1061 + }
483 1062 }