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