PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.11.7
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.11.7
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 +262 -51 3.1.33.11.7 View file →
@@ -46,14 +46,19 @@
46 46 register_deactivation_hook( VISUALIZER_BASEFILE, array( $this, 'deactivate' ) );
47 47 $this->_addAction( 'visualizer_schedule_refresh_db', 'refreshDbChart' );
48 48 $this->_addFilter( 'visualizer_schedule_refresh_chart', 'refresh_db_for_chart', 10, 3 );
49 49
50 - $this->_addAction( 'activated_plugin', 'onActivation' );
50 + $this->_addAction( 'admin_init', 'adminInit' );
51 51 $this->_addAction( 'init', 'setupCustomPostTypes' );
52 + $this->_addFilter( 'cron_schedules', 'custom_cron_schedules' );
52 53 $this->_addAction( 'plugins_loaded', 'loadTextDomain' );
53 54 $this->_addFilter( 'visualizer_logger_data', 'getLoggerData' );
54 - $this->_addFilter( 'visualizer_get_chart_counts', 'getChartCountsByTypeAndMeta' );
55 + $this->_addFilter( 'visualizer_get_chart_counts', 'getUsage', 10, 2 );
55 56
57 + $this->_addAction( 'init', 'checkIsExistingUser' );
58 +
59 + // only for testing
60 + // $this->_addAction( 'admin_init', 'getUsage' );
56 61 }
57 62 /**
58 63 * Fetches the SDK logger data.
59 64 *
@@ -61,36 +66,82 @@
61 66 *
62 67 * @access public
63 68 */
64 69 public function getLoggerData( $data ) {
65 - return $this->getChartCountsByTypeAndMeta();
70 + return $this->getUsage( $data );
66 71 }
67 72
68 73 /**
69 - * Fetches the types of charts created and their counts.
74 + * Fetches the usage of charts.
70 75 *
76 + * @param array $data The default data that needs to be sent.
71 77 * @param array $meta_keys An array of name vs. meta keys - to return how many charts have these keys.
72 - * @access private
78 + *
79 + * @access public
73 80 */
74 - public function getChartCountsByTypeAndMeta( $meta_keys = array() ) {
75 - $charts = array();
76 - $charts['chart_types'] = array();
77 - // the initial query arguments to fetch charts
81 + public function getUsage( $data, $meta_keys = array() ) {
82 + $charts = array( 'types' => array(), 'sources' => array(), 'library' => array(), 'permissions' => 0, 'manual_config' => 0, 'scheduled' => 0 );
78 83 $query_args = array(
79 84 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
80 85 'posts_per_page' => 300,
86 + 'post_status' => 'publish',
81 87 'fields' => 'ids',
82 88 'no_rows_found' => false,
83 89 'update_post_meta_cache' => false,
84 90 'update_post_term_cache' => false,
91 + );
85 92
93 + // default permissions.
94 + $default_perms = array(
95 + 'read' => 'all',
96 + 'read-specific' => null,
97 + 'edit' => 'roles',
98 + 'edit-specific' => array( 'administrator' ),
86 99 );
87 100
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 + );
88 106 $query = new WP_Query( $query_args );
89 107 while ( $query->have_posts() ) {
90 108 $chart_id = $query->next_post();
91 109 $type = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true );
92 - $charts['chart_types'][ $type ] = isset( $charts['chart_types'][ $type ] ) ? $charts['chart_types'][ $type ] + 1 : 1;
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 +
93 144 if ( ! empty( $meta_keys ) ) {
94 145 foreach ( $meta_keys as $name => $key ) {
95 146 $data = get_post_meta( $chart_id, $key, true );
96 147 if ( ! empty( $data ) ) {
@@ -100,8 +151,9 @@
100 151 }
101 152 }
102 153 }
103 154 }
155 +
104 156 return $charts;
105 157 }
106 158
107 159 /**
@@ -140,41 +192,100 @@
140 192
141 193 /**
142 194 * Activate the plugin
143 195 */
144 - public function activate() {
145 - wp_clear_scheduled_hook( 'visualizer_schedule_refresh_db' );
146 - wp_schedule_event( strtotime( 'midnight' ) - get_option( 'gmt_offset' ) * HOUR_IN_SECONDS, 'hourly', 'visualizer_schedule_refresh_db' );
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 + }
147 206 }
148 207
149 208 /**
150 - * On activation of the plugin
209 + * Activates the plugin on a particular blog instance (supports multisite and single site).
151 210 */
152 - public function onActivation( $plugin ) {
153 - if ( defined( 'TI_UNIT_TESTING' ) ) {
154 - return;
211 + private function activate_on_site() {
212 + wp_clear_scheduled_hook( 'visualizer_schedule_refresh_db' );
213 + wp_schedule_event( strtotime( 'midnight' ) - get_option( 'gmt_offset' ) * HOUR_IN_SECONDS, apply_filters( 'visualizer_chart_schedule_interval', 'visualizer_ten_minutes' ), 'visualizer_schedule_refresh_db' );
214 + add_option( 'visualizer-activated', true );
215 + $is_fresh_install = get_option( 'visualizer_fresh_install', false );
216 + if ( ! defined( 'TI_CYPRESS_TESTING' ) && false === $is_fresh_install ) {
217 + update_option( 'visualizer_fresh_install', '1' );
155 218 }
219 + }
156 220
157 - if ( $plugin == VISUALIZER_BASENAME ) {
158 - wp_redirect( admin_url( 'upload.php?page=' . Visualizer_Plugin::NAME ) );
159 - exit();
221 + /**
222 + * Deactivate the plugin
223 + */
224 + public function deactivate( $network_wide ) {
225 + if ( is_multisite() && $network_wide ) {
226 + foreach ( get_sites( array( 'fields' => 'ids' ) ) as $blog_id ) {
227 + switch_to_blog( $blog_id );
228 + $this->deactivate_on_site();
229 + restore_current_blog();
230 + }
231 + } else {
232 + $this->deactivate_on_site();
160 233 }
161 234 }
162 235
236 + /**
237 + * Deactivates the plugin on a particular blog instance (supports multisite and single site).
238 + */
239 + private function deactivate_on_site() {
240 + wp_clear_scheduled_hook( 'visualizer_schedule_refresh_db' );
241 + delete_option( 'visualizer-activated', true );
242 + }
163 243
164 244 /**
165 - * Deactivate the plugin
245 + * Check if plugin has been activated and then redirect to the correct page.
166 246 */
167 - public function deactivate() {
168 - wp_clear_scheduled_hook( 'visualizer_schedule_refresh_db' );
247 + public function adminInit() {
248 + if ( defined( 'TI_UNIT_TESTING' ) ) {
249 + return;
250 + }
251 +
252 + define( 'VISUALIZER_SURVEY', Visualizer_Module::is_pro() ? 'https://forms.gle/7Zo7FuZbvQ8DTvRi6' : 'https://forms.gle/muMtbcyvHn1aTvmJ7' );
253 + // fire any upgrades necessary.
254 + Visualizer_Module_Upgrade::upgrade();
255 +
256 + if ( get_option( 'visualizer-activated' ) ) {
257 + delete_option( 'visualizer-activated' );
258 + if ( ! headers_sent() ) {
259 + if ( ! Visualizer_Module::is_pro() && ! empty( get_option( 'visualizer_fresh_install', false ) ) ) {
260 + $redirect_url = array(
261 + 'page' => 'visualizer-setup-wizard',
262 + 'tab' => '#step-1',
263 + );
264 + } else {
265 + $page_name = Visualizer_Module::numberOfCharts() > 0 ? Visualizer_Plugin::NAME : 'viz-support';
266 + $redirect_url = array(
267 + 'page' => $page_name,
268 + );
269 + }
270 + wp_safe_redirect(
271 + add_query_arg(
272 + $redirect_url,
273 + admin_url( 'admin.php' )
274 + )
275 + );
276 + exit();
277 + }
278 + }
169 279 }
170 280
281 +
171 282 /**
172 283 * Refresh the specific chart from the db.
173 284 *
174 - * @param WP_Post $chart The chart object.
175 - * @param int $chart_id The chart id.
176 - * @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.
285 + * @param WP_Post|null $chart The chart object.
286 + * @param int $chart_id The chart id.
287 + * @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.
177 288 *
178 289 * @access public
179 290 */
180 291 public function refresh_db_for_chart( $chart, $chart_id, $force = false ) {
@@ -191,37 +302,91 @@
191 302 }
192 303
193 304 // check if the source is correct.
194 305 $source = get_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, true );
195 - if ( $source !== 'Visualizer_Source_Query' ) {
196 - return $chart;
197 - }
306 + $load_series = false;
307 + switch ( $source ) {
308 + case 'Visualizer_Source_Query':
309 + // check if its a live-data chart or a cached-data chart.
310 + if ( ! $force ) {
311 + $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, true );
312 + if ( ! empty( $hours ) ) {
313 + // cached, bail!
314 + return $chart;
315 + }
316 + }
198 317
199 - // check if its a live-data chart or a cached-data chart.
200 - if ( ! $force ) {
201 - $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, true );
202 - if ( ! empty( $hours ) ) {
203 - // cached, bail!
318 + $params = get_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY, true );
319 + $source = new Visualizer_Source_Query( $params, $chart_id );
320 + $source->fetch( false );
321 + $load_series = true;
322 + break;
323 + case 'Visualizer_Source_Json':
324 + // check if its a live-data chart or a cached-data chart.
325 + if ( ! $force ) {
326 + $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE, true );
327 + if ( ! empty( $hours ) ) {
328 + // cached, bail!
329 + return $chart;
330 + }
331 + }
332 +
333 + $url = get_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_URL, true );
334 + $root = get_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_ROOT, true );
335 + $paging = get_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_PAGING, true );
336 + $series = get_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, true );
337 + $source = new Visualizer_Source_Json( array( 'url' => $url, 'root' => $root, 'paging' => $paging ) );
338 + $source->refresh( $series );
339 + break;
340 + case 'Visualizer_Source_Csv_Remote':
341 + // check if its a live-data chart or a cached-data chart.
342 + if ( ! $force ) {
343 + $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_SCHEDULE, true );
344 + if ( ! empty( $hours ) ) {
345 + // cached, bail!
346 + return $chart;
347 + }
348 + }
349 + do_action( 'visualizer_schedule_import' );
350 + return get_post( $chart_id );
351 + default:
204 352 return $chart;
205 - }
206 353 }
207 354
208 - $params = get_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY, true );
209 - $source = new Visualizer_Source_Query( $params );
210 - $source->fetch( false );
211 -
212 355 $error = $source->get_error();
213 356 if ( empty( $error ) ) {
214 - update_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
357 + $this->disableRevisionsTemporarily();
358 + if ( $load_series ) {
359 + update_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
360 + }
215 361
362 + $allow_html = false;
363 + $settings = get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true );
364 + if ( isset( $settings['allowHtml'] ) && intval( $settings['allowHtml'] ) === 1 ) {
365 + $allow_html = true;
366 + }
367 +
368 + $allow_html = apply_filters( 'visualizer_allow_html_content', $allow_html, $chart_id, $chart );
369 +
370 + if ( $allow_html ) {
371 + kses_remove_filters();
372 + }
373 +
216 374 wp_update_post(
217 375 array(
218 376 'ID' => $chart_id,
219 - 'post_content' => $source->getData(),
377 + 'post_content' => $source->getData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ),
220 378 )
221 379 );
222 380
381 + if ( $allow_html ) {
382 + kses_init_filters();
383 + }
384 +
223 385 $chart = get_post( $chart_id );
386 + delete_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR );
387 + } else {
388 + update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, sprintf( 'Error while updating chart: %s', $error ) );
224 389 }
225 390
226 391 return $chart;
227 392 }
@@ -226,17 +391,19 @@
226 391 return $chart;
227 392 }
228 393
229 394 /**
230 - * Refresh the db chart.
395 + * Refresh the Database chart type.
231 396 *
232 397 * @access public
233 398 */
234 399 public function refreshDbChart() {
235 - $schedules = get_option( Visualizer_Plugin::CF_DB_SCHEDULE, array() );
236 - if ( ! $schedules ) {
400 + // NOTE: This use a different key from normal schedule. Updated only by Database chart. Check `visualizer_schedule_import` action.
401 + $chart_schedules = get_option( Visualizer_Plugin::CF_DB_SCHEDULE, array() );
402 + if ( ! $chart_schedules ) {
237 403 return;
238 404 }
405 +
239 406 if ( ! defined( 'VISUALIZER_DO_NOT_DIE' ) ) {
240 407 // define this so that the ajax call does not die
241 408 // this means that if the new version of pro and the old version of free are installed, only the first chart will be updated
242 409 define( 'VISUALIZER_DO_NOT_DIE', true );
@@ -242,20 +409,64 @@
242 409 define( 'VISUALIZER_DO_NOT_DIE', true );
243 410 }
244 411
245 412 $new_schedules = array();
246 - $now = time();
247 - foreach ( $schedules as $chart_id => $time ) {
248 - $new_schedules[ $chart_id ] = $time;
249 - if ( $time > $now ) {
413 + $current_time = time();
414 + foreach ( $chart_schedules as $chart_id => $scheduled_time ) {
415 +
416 + // Skip deleted charts.
417 + if ( false === get_post_status( $chart_id ) ) {
250 418 continue;
251 419 }
252 420
253 - // if the time is nigh, we force an update.
421 + $new_schedules[ $chart_id ] = $scheduled_time;
422 +
423 + // Should we do an update?
424 + if ( $scheduled_time > $current_time ) {
425 + continue;
426 + }
427 +
254 428 $this->refresh_db_for_chart( null, $chart_id, true );
255 - $hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, true );
256 - $new_schedules[ $chart_id ] = time() + $hours * HOUR_IN_SECONDS;
429 +
430 + // Clear existing chart cache.
431 + $cache_key = Visualizer_Plugin::CF_CHART_CACHE . '_' . $chart_id;
432 + if ( get_transient( $cache_key ) ) {
433 + delete_transient( $cache_key );
434 + }
435 +
436 + $scheduled_hours = get_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, true );
437 + $new_schedules[ $chart_id ] = $current_time + $scheduled_hours * HOUR_IN_SECONDS;
257 438 }
258 439 update_option( Visualizer_Plugin::CF_DB_SCHEDULE, $new_schedules );
259 440 }
260 441
442 + /**
443 + * Save flag for existing users.
444 + */
445 + public function checkIsExistingUser() {
446 + $chart_exists = get_option( 'visualizer-new-user', '' );
447 + if ( '' === $chart_exists ) {
448 + $charts = get_posts(
449 + array(
450 + 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
451 + 'fields' => 'ids',
452 + )
453 + );
454 + update_option( 'visualizer-new-user', ! empty( $charts ) ? 'no' : 'yes' );
455 + }
456 + }
457 +
458 + /**
459 + * Add custom cron schedules.
460 + *
461 + * @param array $schedules The current schedules options.
462 + * @return array The modified schedules options.
463 + */
464 + public function custom_cron_schedules( $schedules ) {
465 + $schedules['visualizer_ten_minutes'] = array(
466 + 'interval' => 600,
467 + 'display' => __( 'Every 10 minutes', 'visualizer' ),
468 + );
469 +
470 + return $schedules;
471 + }
261 472 }