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