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