PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.0.2
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.0.2
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 3.10.4 All 148 releases
← All changes | classes/Visualizer/Module/Setup.php +10 -413 4.0.53.0.2 View file →
@@ -41,24 +41,12 @@
41 41 */
42 42 public function __construct( Visualizer_Plugin $plugin ) {
43 43 parent::__construct( $plugin );
44 44
45 - register_activation_hook( VISUALIZER_BASEFILE, array( $this, 'activate' ) );
46 - register_deactivation_hook( VISUALIZER_BASEFILE, array( $this, 'deactivate' ) );
47 - $this->_addAction( 'visualizer_schedule_refresh_db', 'refreshDbChart' );
48 - $this->_addFilter( 'visualizer_schedule_refresh_chart', 'refresh_db_for_chart', 10, 3 );
49 -
50 - $this->_addAction( 'admin_init', 'adminInit' );
51 45 $this->_addAction( 'init', 'setupCustomPostTypes' );
52 - $this->_addFilter( 'cron_schedules', 'custom_cron_schedules' );
53 46 $this->_addAction( 'plugins_loaded', 'loadTextDomain' );
54 47 $this->_addFilter( 'visualizer_logger_data', 'getLoggerData' );
55 - $this->_addFilter( 'visualizer_get_chart_counts', 'getUsage', 10, 2 );
56 -
57 - $this->_addAction( 'init', 'checkIsExistingUser' );
58 -
59 - // only for testing
60 - // $this->_addAction( 'admin_init', 'getUsage' );
48 + $this->_addFilter( 'visualizer_get_chart_counts', 'getChartCountsByTypeAndMeta' );
61 49 }
62 50 /**
63 51 * Fetches the SDK logger data.
64 52 *
@@ -66,82 +54,36 @@
66 54 *
67 55 * @access public
68 56 */
69 57 public function getLoggerData( $data ) {
70 - return $this->getUsage( $data );
58 + return $this->getChartCountsByTypeAndMeta();
71 59 }
72 60
73 61 /**
74 - * Fetches the usage of charts.
62 + * Fetches the types of charts created and their counts.
75 63 *
76 - * @param array $data The default data that needs to be sent.
77 64 * @param array $meta_keys An array of name vs. meta keys - to return how many charts have these keys.
78 - *
79 - * @access public
65 + * @access private
80 66 */
81 - public function getUsage( $data, $meta_keys = array() ) {
82 - $charts = array( 'types' => array(), 'sources' => array(), 'library' => array(), 'permissions' => 0, 'manual_config' => 0, 'scheduled' => 0 );
67 + public function getChartCountsByTypeAndMeta( $meta_keys = array() ) {
68 + $charts = array();
69 + $charts['chart_types'] = array();
70 + // the initial query arguments to fetch charts
83 71 $query_args = array(
84 72 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
85 73 'posts_per_page' => 300,
86 - 'post_status' => 'publish',
87 74 'fields' => 'ids',
88 75 'no_rows_found' => false,
89 76 'update_post_meta_cache' => false,
90 77 'update_post_term_cache' => false,
91 - );
92 78
93 - // default permissions.
94 - $default_perms = array(
95 - 'read' => 'all',
96 - 'read-specific' => null,
97 - 'edit' => 'roles',
98 - 'edit-specific' => array( 'administrator' ),
99 79 );
100 80
101 - // collect all schedules chart ids.
102 - $scheduled = array_merge(
103 - array_keys( get_option( Visualizer_Plugin::CF_CHART_SCHEDULE, array() ) ),
104 - array_keys( get_option( Visualizer_Plugin::CF_DB_SCHEDULE, array() ) )
105 - );
106 81 $query = new WP_Query( $query_args );
107 82 while ( $query->have_posts() ) {
108 83 $chart_id = $query->next_post();
109 84 $type = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true );
110 - $charts['types'][ $type ] = isset( $charts['types'][ $type ] ) ? $charts['types'][ $type ] + 1 : 1;
111 - $source = get_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, true );
112 - $charts['sources'][ $source ] = isset( $charts['sources'][ $source ] ) ? $charts['sources'][ $source ] + 1 : 1;
113 - $lib = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_LIBRARY, true );
114 - $charts['library'][ $lib ] = isset( $charts['library'][ $lib ] ) ? $charts['library'][ $lib ] + 1 : 1;
115 - $settings = get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true );
116 - if ( array_key_exists( 'manual', $settings ) && ! empty( $settings['manual'] ) ) {
117 - $charts['manual_config'] = $charts['manual_config'] + 1;
118 - }
119 -
120 - // phpcs:ignore WordPress.PHP.StrictInArray.FoundNonStrictFalse
121 - if ( in_array( $chart_id, $scheduled, false ) ) {
122 - $charts['scheduled'] = $charts['scheduled'] + 1;
123 - }
124 -
125 - if ( Visualizer_Module::is_pro() ) {
126 - $permissions = get_post_meta( $chart_id, Visualizer_Pro::CF_PERMISSIONS, true );
127 - if ( empty( $permissions ) ) {
128 - continue;
129 - }
130 - $permissions = $permissions['permissions'];
131 - $customized = false;
132 - foreach ( $default_perms as $key => $val ) {
133 - if ( ! is_array( $val ) && ! is_null( $val ) && isset( $permissions[ $key ] ) && $permissions[ $key ] !== $val ) {
134 - $customized = true;
135 - } elseif ( is_array( $val ) && ! is_null( $val ) && isset( $permissions[ $key ] ) && count( $permissions[ $key ] ) !== count( $val ) ) {
136 - $customized = true;
137 - }
138 - }
139 - if ( $customized ) {
140 - $charts['permissions'] = $charts['permissions'] + 1;
141 - }
142 - }
143 -
85 + $charts['chart_types'][ $type ] = isset( $charts['chart_types'][ $type ] ) ? $charts['chart_types'][ $type ] + 1 : 1;
144 86 if ( ! empty( $meta_keys ) ) {
145 87 foreach ( $meta_keys as $name => $key ) {
146 88 $data = get_post_meta( $chart_id, $key, true );
147 89 if ( ! empty( $data ) ) {
@@ -151,9 +93,8 @@
151 93 }
152 94 }
153 95 }
154 96 }
155 -
156 97 return $charts;
157 98 }
158 99
159 100 /**
@@ -165,16 +106,11 @@
165 106 * @access public
166 107 */
167 108 public function setupCustomPostTypes() {
168 109 register_post_type(
169 - Visualizer_Plugin::CPT_VISUALIZER,
170 - array(
110 + Visualizer_Plugin::CPT_VISUALIZER, array(
171 111 'label' => 'Visualizer Charts',
172 112 'public' => false,
173 - 'supports' => array( 'revisions' ),
174 - 'show_in_rest' => true,
175 - 'rest_base' => 'visualizer',
176 - 'rest_controller_class' => 'WP_REST_Posts_Controller',
177 113 )
178 114 );
179 115 }
180 116
@@ -189,344 +125,5 @@
189 125 public function loadTextDomain() {
190 126 load_plugin_textdomain( Visualizer_Plugin::NAME, false, dirname( plugin_basename( VISUALIZER_BASEFILE ) ) . '/languages/' );
191 127 }
192 128
193 - /**
194 - * Activate the plugin
195 - */
196 - public function activate( $network_wide ) {
197 - if ( is_multisite() && $network_wide ) {
198 - foreach ( get_sites( array( 'fields' => 'ids' ) ) as $blog_id ) {
199 - switch_to_blog( $blog_id );
200 - $this->activate_on_site();
201 - restore_current_blog();
202 - }
203 - } else {
204 - $this->activate_on_site();
205 - }
206 - }
207 -
208 - /**
209 - * Activates the plugin on a particular blog instance (supports multisite and single site).
210 - */
211 - private function activate_on_site() {
212 - $this->schedule_refresh_db_action();
213 - add_option( 'visualizer-activated', true );
214 - $is_fresh_install = get_option( 'visualizer_fresh_install', false );
215 - if ( ! defined( 'TI_E2E_TESTING' ) && false === $is_fresh_install ) {
216 - update_option( 'visualizer_fresh_install', '1' );
217 - }
218 - }
219 -
220 - /**
221 - * Deactivate the plugin
222 - */
223 - public function deactivate( $network_wide ) {
224 - if ( is_multisite() && $network_wide ) {
225 - foreach ( get_sites( array( 'fields' => 'ids' ) ) as $blog_id ) {
226 - switch_to_blog( $blog_id );
227 - $this->deactivate_on_site();
228 - restore_current_blog();
229 - }
230 - } else {
231 - $this->deactivate_on_site();
232 - }
233 - }
234 -
235 - /**
236 - * Deactivates the plugin on a particular blog instance (supports multisite and single site).
237 - */
238 - private function deactivate_on_site() {
239 - $this->unschedule_refresh_db_action();
240 - delete_option( 'visualizer-activated', true );
241 - }
242 -
243 - /**
244 - * Check if plugin has been activated and then redirect to the correct page.
245 - */
246 - public function adminInit() {
247 - if ( defined( 'TI_UNIT_TESTING' ) ) {
248 - return;
249 - }
250 -
251 - define( 'VISUALIZER_SURVEY', Visualizer_Module::is_pro() ? 'https://forms.gle/7Zo7FuZbvQ8DTvRi6' : 'https://forms.gle/muMtbcyvHn1aTvmJ7' );
252 - // fire any upgrades necessary.
253 - Visualizer_Module_Upgrade::upgrade();
254 -
255 - $activated_flag = get_option( 'visualizer-activated' );
256 - $fresh_install = get_option( 'visualizer_fresh_install', false );
257 - $is_pro = Visualizer_Module::is_pro();
258 - if ( $activated_flag ) {
259 - if ( function_exists( 'wp_doing_ajax' ) && wp_doing_ajax() ) {
260 - // Defer redirect until a normal admin request.
261 - return;
262 - }
263 - if ( wp_doing_cron() ) {
264 - // Defer redirect during cron requests.
265 - return;
266 - }
267 - delete_option( 'visualizer-activated' );
268 - if ( ! headers_sent() ) {
269 - if ( ! $is_pro && ! empty( $fresh_install ) ) {
270 - $redirect_url = array(
271 - 'page' => 'visualizer-setup-wizard',
272 - 'tab' => '#step-1',
273 - );
274 - } else {
275 - $page_name = Visualizer_Module::numberOfCharts() > 0 ? Visualizer_Plugin::NAME : 'viz-support';
276 - $redirect_url = array(
277 - 'page' => $page_name,
278 - );
279 - }
280 - wp_safe_redirect(
281 - add_query_arg(
282 - $redirect_url,
283 - admin_url( 'admin.php' )
284 - )
285 - );
286 - exit();
287 - }
288 - }
289 - }
290 -
291 -
292 - /**
293 - * Refresh the specific chart from the db.
294 - *
295 - * @param WP_Post|null $chart The chart object.
296 - * @param int $chart_id The chart id.
297 - * @param bool $force If this is true, then the chart data will be force refreshed. If false, data will be refreshed only if the chart requests live data.
298 - *
299 - * @access public
300 - */
301 - public function refresh_db_for_chart( $chart, $chart_id, $force = false ) {
302 - if ( ! $chart_id ) {
303 - return $chart;
304 - }
305 -
306 - if ( ! $chart ) {
307 - $chart = get_post( $chart_id );
308 - }
309 -
310 - if ( ! $chart ) {
311 - return $chart;
312 - }
313 -
314 - // check if the source is correct.
315 - $source = get_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, true );
316 - $load_series = false;
317 - switch ( $source ) {
318 - case 'Visualizer_Source_Query':
319 - // check if its a live-data chart or a cached-data chart.
320 - if ( ! $force ) {
321 - $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, true );
322 - if ( ! empty( $hours ) ) {
323 - // cached, bail!
324 - return $chart;
325 - }
326 - }
327 -
328 - $params = get_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY, true );
329 - $source = new Visualizer_Source_Query( $params, $chart_id );
330 - $source->fetch( false );
331 - $load_series = true;
332 - break;
333 - case 'Visualizer_Source_Json':
334 - // check if its a live-data chart or a cached-data chart.
335 - if ( ! $force ) {
336 - $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE, true );
337 - if ( ! empty( $hours ) ) {
338 - // cached, bail!
339 - return $chart;
340 - }
341 - }
342 -
343 - $url = get_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_URL, true );
344 - $root = get_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_ROOT, true );
345 - $paging = get_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_PAGING, true );
346 - $series = get_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, true );
347 - $source = new Visualizer_Source_Json( array( 'url' => $url, 'root' => $root, 'paging' => $paging ) );
348 - $source->refresh( $series );
349 - break;
350 - case 'Visualizer_Source_Csv_Remote':
351 - // check if its a live-data chart or a cached-data chart.
352 - if ( ! $force ) {
353 - $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_SCHEDULE, true );
354 - if ( ! empty( $hours ) ) {
355 - // cached, bail!
356 - return $chart;
357 - }
358 - }
359 - do_action( 'visualizer_schedule_import' );
360 - return get_post( $chart_id );
361 - default:
362 - return $chart;
363 - }
364 -
365 - $error = $source->get_error();
366 - if ( empty( $error ) ) {
367 - $this->disableRevisionsTemporarily();
368 - if ( $load_series ) {
369 - update_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
370 - }
371 -
372 - $allow_html = false;
373 - $settings = get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true );
374 - if ( isset( $settings['allowHtml'] ) && intval( $settings['allowHtml'] ) === 1 ) {
375 - $allow_html = true;
376 - }
377 -
378 - $allow_html = apply_filters( 'visualizer_allow_html_content', $allow_html, $chart_id, $chart );
379 -
380 - if ( $allow_html ) {
381 - kses_remove_filters();
382 - }
383 -
384 - wp_update_post(
385 - array(
386 - 'ID' => $chart_id,
387 - 'post_content' => $source->getData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ),
388 - )
389 - );
390 -
391 - if ( $allow_html ) {
392 - kses_init_filters();
393 - }
394 -
395 - $chart = get_post( $chart_id );
396 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR );
397 - } else {
398 - update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, sprintf( 'Error while updating chart: %s', $error ) );
399 - }
400 -
401 - return $chart;
402 - }
403 -
404 - /**
405 - * Refresh the Database chart type.
406 - *
407 - * @access public
408 - */
409 - public function refreshDbChart() {
410 - // NOTE: This use a different key from normal schedule. Updated only by Database chart. Check `visualizer_schedule_import` action.
411 - $chart_schedules = get_option( Visualizer_Plugin::CF_DB_SCHEDULE, array() );
412 - if ( ! $chart_schedules ) {
413 - return;
414 - }
415 -
416 - if ( ! defined( 'VISUALIZER_DO_NOT_DIE' ) ) {
417 - // define this so that the ajax call does not die
418 - // this means that if the new version of pro and the old version of free are installed, only the first chart will be updated
419 - define( 'VISUALIZER_DO_NOT_DIE', true );
420 - }
421 -
422 - $new_schedules = array();
423 - $current_time = time();
424 - foreach ( $chart_schedules as $chart_id => $scheduled_time ) {
425 -
426 - // Skip deleted charts.
427 - if ( false === get_post_status( $chart_id ) ) {
428 - continue;
429 - }
430 -
431 - $new_schedules[ $chart_id ] = $scheduled_time;
432 -
433 - // Should we do an update?
434 - if ( $scheduled_time > $current_time ) {
435 - continue;
436 - }
437 -
438 - $this->refresh_db_for_chart( null, $chart_id, true );
439 -
440 - // Clear existing chart cache.
441 - $cache_key = Visualizer_Plugin::CF_CHART_CACHE . '_' . $chart_id;
442 - if ( get_transient( $cache_key ) ) {
443 - delete_transient( $cache_key );
444 - }
445 -
446 - $scheduled_hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, true );
447 - $new_schedules[ $chart_id ] = $current_time + $scheduled_hours * HOUR_IN_SECONDS;
448 - }
449 - update_option( Visualizer_Plugin::CF_DB_SCHEDULE, $new_schedules );
450 - }
451 -
452 - /**
453 - * Save flag for existing users.
454 - */
455 - public function checkIsExistingUser() {
456 - $chart_exists = get_option( 'visualizer-new-user', '' );
457 - if ( '' === $chart_exists ) {
458 - $charts = get_posts(
459 - array(
460 - 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
461 - 'fields' => 'ids',
462 - )
463 - );
464 - update_option( 'visualizer-new-user', ! empty( $charts ) ? 'no' : 'yes' );
465 - }
466 - }
467 -
468 - /**
469 - * Add custom cron schedules.
470 - *
471 - * @param array $schedules The current schedules options.
472 - * @return array The modified schedules options.
473 - */
474 - public function custom_cron_schedules( $schedules ) {
475 - $schedules['visualizer_ten_minutes'] = array(
476 - 'interval' => 600,
477 - 'display' => __( 'Every 10 minutes', 'visualizer' ),
478 - );
479 -
480 - return $schedules;
481 - }
482 -
483 - /**
484 - * Schedule the recurring DB refresh action.
485 - */
486 - private function schedule_refresh_db_action(): void {
487 - $hook = 'visualizer_schedule_refresh_db';
488 - $group = 'visualizer';
489 - $interval_key = apply_filters( 'visualizer_chart_schedule_interval', 'visualizer_ten_minutes' );
490 - $interval = $this->get_schedule_interval_seconds( $interval_key );
491 - $timestamp = strtotime( 'midnight' ) - get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
492 -
493 - if ( function_exists( 'as_next_scheduled_action' ) && function_exists( 'as_schedule_recurring_action' ) ) {
494 - $next = as_next_scheduled_action( $hook, array(), $group );
495 - if ( false === $next ) {
496 - as_schedule_recurring_action( $timestamp, $interval, $hook, array(), $group );
497 - }
498 - wp_clear_scheduled_hook( $hook );
499 - return;
500 - }
501 -
502 - wp_clear_scheduled_hook( $hook );
503 - wp_schedule_event( $timestamp, $interval_key, $hook );
504 - }
505 -
506 - /**
507 - * Unschedule the recurring DB refresh action.
508 - */
509 - private function unschedule_refresh_db_action(): void {
510 - $hook = 'visualizer_schedule_refresh_db';
511 - $group = 'visualizer';
512 - if ( function_exists( 'as_unschedule_all_actions' ) ) {
513 - as_unschedule_all_actions( $hook, array(), $group );
514 - }
515 - wp_clear_scheduled_hook( $hook );
516 - }
517 -
518 - /**
519 - * Resolve a cron schedule key to seconds.
520 - *
521 - * @param string $interval_key Cron schedule key.
522 - * @return int Interval in seconds.
523 - */
524 - private function get_schedule_interval_seconds( $interval_key ) {
525 - $schedules = wp_get_schedules();
526 - if ( isset( $schedules[ $interval_key ]['interval'] ) ) {
527 - return (int) $schedules[ $interval_key ]['interval'];
528 - }
529 -
530 - return 600;
531 - }
532 129 }