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