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