PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 3.19.4
GiveWP – Donation Plugin and Fundraising Platform v3.19.4
4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / includes / admin / upgrades / class-give-updates.php
give / includes / admin / upgrades Last commit date
views 4 years ago class-give-updates.php 3 years ago upgrade-functions.php 3 years ago
class-give-updates.php
1164 lines
1 <?php
2
3 /**
4 * Class Give_Updates
5 *
6 * @since 1.8.12
7 */
8 class Give_Updates {
9
10 /**
11 * Instance.
12 *
13 * @since
14 * @access static
15 * @var
16 */
17 private static $instance;
18
19 /**
20 * Instance.
21 *
22 * @since
23 * @access public
24 * @var Give_Background_Updater
25 */
26 public static $background_updater;
27
28 /**
29 * Updates
30 *
31 * @since 1.8.12
32 * @access private
33 * @var array
34 */
35 private $updates = [];
36
37 /**
38 * Current update percentage number
39 *
40 * @since 1.8.12
41 * @access private
42 * @var array
43 */
44 public $percentage = 0;
45
46 /**
47 * Current update step number
48 *
49 * @since 1.8.12
50 * @access private
51 * @var array
52 */
53 public $step = 1;
54
55 /**
56 * Current update number
57 *
58 * @since 1.8.12
59 * @access private
60 * @var array
61 */
62 public $update = 1;
63
64 /**
65 * Singleton pattern.
66 *
67 * @since 1.8.12
68 * @access private
69 *
70 * @param Give_Updates .
71 */
72 private function __construct() {
73 }
74
75 /**
76 * Register updates
77 *
78 * @since 1.8.12
79 * @access public
80 *
81 * @param array $args
82 */
83 public function register( $args ) {
84 $args_default = [
85 'id' => '',
86 'version' => '',
87 'callback' => '',
88 ];
89
90 $args = wp_parse_args( $args, $args_default );
91
92 // You can only register database upgrade.
93 $args['type'] = 'database';
94
95 // Bailout.
96 if (
97 empty( $args['id'] ) ||
98 empty( $args['version'] ) ||
99 empty( $args['callback'] ) ||
100 ! is_callable( $args['callback'] )
101 ) {
102 return;
103 }
104
105 // Change depend param to array.
106 if ( isset( $args['depend'] ) && is_string( $args['depend'] ) ) {
107 $args['depend'] = [ $args['depend'] ];
108 }
109
110 $this->updates[ $args['type'] ][] = $args;
111 }
112
113 /**
114 * Get instance.
115 *
116 * @since
117 * @access static
118 * @return static
119 */
120 static function get_instance() {
121 if ( is_null( self::$instance ) ) {
122 self::$instance = new self();
123 }
124
125 return self::$instance;
126 }
127
128 /**
129 *
130 * Setup hook
131 *
132 * @since 1.8.12
133 * @access public
134 */
135 public function setup() {
136 /**
137 * Load file
138 */
139 require_once GIVE_PLUGIN_DIR . 'includes/class-give-background-updater.php';
140 require_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/upgrade-functions.php';
141
142 self::$background_updater = new Give_Background_Updater();
143
144 /**
145 * Setup hooks.
146 */
147 add_action( 'init', [ $this, '__register_upgrade' ], 9999 );
148 add_action( 'give_set_upgrade_completed', [ $this, '__flush_resume_updates' ], 9999 );
149 add_action( 'wp_ajax_give_db_updates_info', [ $this, '__give_db_updates_info' ] );
150 add_action( 'wp_ajax_give_run_db_updates', [ $this, '__give_start_updating' ] );
151 add_action( 'admin_init', [ $this, '__redirect_admin' ] );
152 add_action( 'admin_init', [ $this, '__pause_db_update' ], - 1 );
153 add_action( 'admin_init', [ $this, '__restart_db_update' ], - 1 );
154 add_action( 'admin_notices', [ $this, '__show_notice' ] );
155 add_action( 'give_restart_db_upgrade', [ $this, '__health_background_update' ] );
156
157 if ( is_admin() ) {
158 add_action( 'admin_init', [ $this, '__change_donations_label' ], 9999 );
159 add_action( 'admin_menu', [ $this, '__register_menu' ], 55 );
160 }
161 }
162
163 /**
164 * Register plugin add-on updates.
165 *
166 * @since 1.8.12
167 * @access public
168 */
169 public function __register_plugin_addon_updates() {
170 $addons = give_get_plugins( [ 'only_premium_add_ons' => true ] );
171 $plugin_updates = get_plugin_updates();
172
173 foreach ( $addons as $key => $info ) {
174 if ( empty( $plugin_updates[ $key ] ) ) {
175 continue;
176 }
177
178 $this->updates['plugin'][] = array_merge( $info, (array) $plugin_updates[ $key ] );
179 }
180 }
181
182
183 /**
184 * Fire custom action hook to register updates
185 *
186 * @since 1.8.12
187 * @access public
188 */
189 public function __register_upgrade() {
190 if ( ! is_admin() ) {
191 return;
192 }
193
194 /**
195 * Fire the hook
196 *
197 * @since 1.8.12
198 */
199 do_action( 'give_register_updates', $this );
200 }
201
202 /**
203 * Rename `Donations` menu title if updates exists
204 *
205 * @since 1.8.12
206 * @access public
207 */
208 function __change_donations_label() {
209 global $menu;
210
211 // Bailout.
212 if ( empty( $menu ) || ! $this->get_total_update_count() ) {
213 return;
214 }
215
216 $is_update = ( $this->is_doing_updates() && ! self::$background_updater->is_paused_process() );
217
218 foreach ( $menu as $index => $menu_item ) {
219 if ( 'edit.php?post_type=give_forms' !== $menu_item[2] ) {
220 continue;
221 }
222
223 $menu[ $index ][0] = sprintf(
224 '%1$s <span class="update-plugins"><span class="plugin-count give-update-progress-count">%2$s%3$s</span></span>',
225 __( 'Donations', 'give' ),
226 $is_update ?
227 $this->get_db_update_processing_percentage() :
228 $this->get_total_update_count(),
229 $is_update ? '%' : ''
230 );
231
232 break;
233 }
234 }
235
236 /**
237 * Register updates menu
238 *
239 * @since 1.8.12
240 * @access public
241 */
242 public function __register_menu() {
243 // Load plugin updates.
244 $this->__register_plugin_addon_updates();
245
246 // Bailout.
247 if ( ! $this->get_total_update_count() ) {
248 // Show complete update message if still on update setting page.
249 if ( isset( $_GET['page'] ) && 'give-updates' === $_GET['page'] ) {
250 // Upgrades
251 add_submenu_page(
252 'edit.php?post_type=give_forms',
253 esc_html__( 'GiveWP Updates Complete', 'give' ),
254 __( 'Updates', 'give' ),
255 'manage_give_settings',
256 'give-updates',
257 [ $this, 'render_complete_page' ]
258 );
259 }
260
261 return;
262 }
263
264 $is_update = ( $this->is_doing_updates() && ! self::$background_updater->is_paused_process() );
265
266 // Upgrades
267 add_submenu_page(
268 'edit.php?post_type=give_forms',
269 esc_html__( 'GiveWP Updates', 'give' ),
270 sprintf(
271 '%1$s <span class="update-plugins"%2$s><span class="plugin-count give-update-progress-count">%3$s%4$s</span></span>',
272 __( 'Updates', 'give' ),
273 isset( $_GET['give-pause-db-upgrades'] ) ? ' style="display:none;"' : '',
274 $is_update ?
275 $this->get_db_update_processing_percentage() :
276 $this->get_total_update_count(),
277 $is_update ? '%' : ''
278 ),
279 'manage_give_settings',
280 'give-updates',
281 [ $this, 'render_page' ]
282 );
283 }
284
285
286 /**
287 * Show update related notices
288 *
289 * @since 2.0
290 * @access public
291 */
292 public function __redirect_admin() {
293 // Show db upgrade completed notice.
294 if (
295 ! wp_doing_ajax() &&
296 current_user_can( 'manage_give_settings' ) &&
297 get_option( 'give_show_db_upgrade_complete_notice' ) &&
298 ! isset( $_GET['give-db-update-completed'] )
299 ) {
300 delete_option( 'give_show_db_upgrade_complete_notice' );
301
302 wp_redirect( admin_url( 'edit.php?post_type=give_forms&page=give-updates&give-db-update-completed=give_db_upgrade_completed' ) );
303 exit();
304 }
305 }
306
307
308 /**
309 * Pause db upgrade
310 *
311 * @since 2.0.1
312 * @access public
313 *
314 * @param bool $force
315 *
316 * @return bool
317 */
318 public function __pause_db_update( $force = false ) {
319 // Bailout.
320 if (
321 ! $force &&
322 (
323 wp_doing_ajax() ||
324 ! isset( $_GET['page'] ) ||
325 'give-updates' !== $_GET['page'] ||
326 ! isset( $_GET['give-pause-db-upgrades'] ) ||
327 self::$background_updater->is_paused_process()
328 )
329
330 ) {
331 return false;
332 }
333
334 delete_option( 'give_upgrade_error' );
335
336 $this->__health_background_update( $this );
337 $batch = self::$background_updater->get_all_batch();
338
339 // Bailout: if batch is empty
340 if ( empty( $batch->data ) ) {
341 return false;
342 }
343
344 // Remove cache.
345 Give_Background_Updater::flush_cache();
346
347 // Do not stop background process immediately if task running.
348 // @see Give_Background_Updater::lock_process
349 if ( ! $force && self::$background_updater->is_process_running() ) {
350 update_option( 'give_pause_upgrade', 1, false );
351
352 return true;
353 }
354
355 update_option( 'give_paused_batches', $batch, false );
356 delete_option( $batch->key );
357 delete_site_transient( self::$background_updater->get_identifier() . '_process_lock' );
358 wp_clear_scheduled_hook( self::$background_updater->get_cron_identifier() );
359
360 Give()->logs->add( 'Update Pause', print_r( $batch, true ), 0, 'update' );
361
362 /**
363 * Fire action when pause db updates
364 *
365 * @since 2.0.1
366 */
367 do_action( 'give_pause_db_upgrade', $this );
368
369 return true;
370 }
371
372 /**
373 * Restart db upgrade
374 *
375 * @since 2.0.1
376 * @access public
377 *
378 * @return bool
379 */
380 public function __restart_db_update() {
381 // Bailout.
382 if (
383 wp_doing_ajax() ||
384 ! isset( $_GET['page'] ) ||
385 'give-updates' !== $_GET['page'] ||
386 ! isset( $_GET['give-restart-db-upgrades'] ) ||
387 ! self::$background_updater->is_paused_process()
388 ) {
389 return false;
390 }
391
392 Give_Background_Updater::flush_cache();
393 $batch = get_option( 'give_paused_batches' );
394
395 if ( ! empty( $batch ) ) {
396 wp_cache_delete( $batch->key, 'options' );
397 update_option( $batch->key, $batch->data, false );
398
399 delete_option( 'give_paused_batches' );
400
401 Give()->logs->add( 'Update Restart', print_r( $batch, true ), 0, 'update' );
402
403 /** Fire action when restart db updates
404 *
405 * @since 2.0.1
406 */
407 do_action( 'give_restart_db_upgrade', $this );
408
409 self::$background_updater->dispatch();
410 }
411
412 return true;
413 }
414
415 /**
416 * Health check for updates.
417 *
418 * @since 2.0
419 * @access public
420 *
421 * @param Give_Updates $give_updates
422 */
423 public function __health_background_update( $give_updates ) {
424 if ( ! $this->is_doing_updates() ) {
425 return;
426 }
427
428 Give_Background_Updater::flush_cache();
429
430 /* @var stdClass $batch */
431 $batch = self::$background_updater->get_all_batch();
432 $old_batch_update_ids = is_array( $batch->data ) ? wp_list_pluck( $batch->data, 'id' ) : [];
433 $all_updates = $give_updates->get_updates( 'database', 'all' );
434 $all_update_ids = wp_list_pluck( $all_updates, 'id' );
435 $all_batch_update_ids = ! empty( $batch->data ) ? wp_list_pluck( $batch->data, 'id' ) : [];
436 $log_data = '';
437 $doing_upgrade_args = get_option( 'give_doing_upgrade' );
438
439 if ( ! empty( $doing_upgrade_args ) ) {
440 $log_data .= 'Doing update:' . "\n";
441 $log_data .= print_r( $doing_upgrade_args, true ) . "\n";
442 }
443
444 /**
445 * Add remove upgrade from batch
446 */
447 if ( ! empty( $batch->data ) ) {
448
449 foreach ( $batch->data as $index => $update ) {
450 $log_data = print_r( $update, true ) . "\n";
451
452 if ( ! is_callable( $update['callback'] ) ) {
453 $log_data .= 'Removing missing callback update: ' . "{$update['id']}\n";
454 unset( $batch->data[ $index ] );
455 } elseif ( give_has_upgrade_completed( $update['id'] ) ) {
456 $log_data .= 'Removing already completed update: ' . "{$update['id']}\n";
457 unset( $batch->data[ $index ] );
458 }
459
460 if ( ! empty( $update['depend'] ) ) {
461
462 foreach ( $update['depend'] as $depend ) {
463 if ( give_has_upgrade_completed( $depend ) ) {
464 $log_data .= 'Completed update: ' . "{$depend}\n";
465 continue;
466 }
467
468 if ( in_array( $depend, $all_update_ids ) && ! in_array( $depend, $all_batch_update_ids ) ) {
469 $log_data .= 'Adding missing update: ' . "{$depend}\n";
470 array_unshift( $batch->data, $all_updates[ array_search( $depend, $all_update_ids ) ] );
471 }
472 }
473 }
474 }
475 }
476
477 /**
478 * Add new upgrade to batch
479 */
480 if ( $new_updates = $this->get_updates( 'database', 'new' ) ) {
481 $all_batch_update_ids = ! empty( $batch->data ) ? wp_list_pluck( $batch->data, 'id' ) : [];
482
483 foreach ( $new_updates as $index => $new_update ) {
484 if ( give_has_upgrade_completed( $new_update['id'] ) || in_array( $new_update['id'], $all_batch_update_ids ) ) {
485 unset( $new_updates[ $index ] );
486 }
487 }
488
489 if ( ! empty( $new_updates ) ) {
490 $log_data .= 'Adding new update: ' . "\n";
491 $log_data .= print_r( $new_updates, true ) . "\n";
492
493 $batch->data = array_merge( (array) $batch->data, $new_updates );
494 update_option( 'give_db_update_count', ( absint( get_option( 'give_db_update_count' ) ) + count( $new_updates ) ), false );
495 }
496 }
497
498 /**
499 * Fix batch
500 */
501 if ( empty( $batch->data ) ) {
502 // Complete batch if do not have any data to process.
503 self::$background_updater->delete( $batch->key );
504
505 if ( self::$background_updater->has_queue() ) {
506 $this->__health_background_update( $this );
507 } else {
508 delete_site_transient( self::$background_updater->get_identifier() . '_process_lock' );
509 wp_clear_scheduled_hook( self::$background_updater->get_cron_identifier() );
510
511 self::$background_updater->complete();
512 }
513 } elseif ( array_diff( wp_list_pluck( $batch->data, 'id' ), $old_batch_update_ids ) ) {
514
515 $log_data .= 'Updating batch' . "\n";
516 $log_data .= print_r( $batch, true );
517
518 if ( ! empty( $batch->key ) ) {
519 wp_cache_delete( $batch->key, 'options' );
520 update_option( $batch->key, $batch->data, false );
521 } else {
522
523 foreach ( $batch->data as $data ) {
524 self::$background_updater->push_to_queue( $data );
525 }
526
527 self::$background_updater->save();
528 }
529 }
530
531 /**
532 * Fix give_doing_upgrade option
533 */
534 if ( $fresh_new_db_count = $this->get_total_new_db_update_count( true ) ) {
535 update_option( 'give_db_update_count', $fresh_new_db_count, false );
536 }
537
538 $doing_upgrade_args['update'] = 1;
539 $doing_upgrade_args['heading'] = sprintf( 'Update %s of %s', 1, $fresh_new_db_count );
540 $doing_upgrade_args['total_percentage'] = $this->get_db_update_processing_percentage( true );
541
542 // Remove already completed update from info.
543 if (
544 empty( $doing_upgrade_args['update_info'] )
545 || give_has_upgrade_completed( $doing_upgrade_args['update_info']['id'] )
546 ) {
547 $doing_upgrade_args['update_info'] = current( array_values( $batch->data ) );
548 $doing_upgrade_args['step'] = 1;
549 }
550
551 // Check if dependency completed or not.
552 if ( isset( $doing_upgrade_args['update_info']['depend'] ) ) {
553 foreach ( $doing_upgrade_args['update_info']['depend'] as $depend ) {
554 if ( give_has_upgrade_completed( $depend ) ) {
555 continue;
556 }
557
558 $doing_upgrade_args['update_info'] = $all_updates[ array_search( $depend, $all_update_ids ) ];
559 $doing_upgrade_args['step'] = 1;
560 $doing_upgrade_args['percentage'] = 0;
561 $doing_upgrade_args['total_percentage'] = 0;
562
563 break;
564 }
565 }
566
567 if ( ! empty( $doing_upgrade_args['update_info'] ) ) {
568 update_option( 'give_doing_upgrade', $doing_upgrade_args, false );
569
570 $log_data .= 'Updated doing update:' . "\n";
571 $log_data .= print_r( $doing_upgrade_args, true ) . "\n";
572 }
573
574 Give()->logs->add( 'Update Health Check', $log_data, 0, 'update' );
575 }
576
577
578 /**
579 * Show update related notices
580 *
581 * @since 2.0
582 * @access public
583 */
584 public function __show_notice() {
585 $current_screen = get_current_screen();
586 $hide_on_pages = [
587 'give_forms_page_give-updates',
588 'update-core',
589 'give_forms_page_give-addons',
590 ];
591
592 // Bailout.
593 if ( ! current_user_can( 'manage_give_settings' ) ) {
594 return;
595 }
596
597 // Run DB updates.
598 if ( ! empty( $_GET['give-run-db-update'] ) ) {
599 $this->run_db_update();
600 }
601
602 // Bailout.
603 if ( in_array( $current_screen->base, $hide_on_pages ) ) {
604 return;
605 }
606
607 // Show notice if upgrade paused.
608 if ( self::$background_updater->is_paused_process() ) {
609 ob_start();
610
611 $upgrade_error = get_option( 'give_upgrade_error' );
612 if ( ! $upgrade_error ) : ?>
613 <strong><?php _e( 'Database Update', 'give' ); ?></strong>
614 &nbsp;&#8211;&nbsp;<?php _e( 'GiveWP needs to update your database to the latest version. The following process will make updates to your site\'s database. Please create a backup before proceeding.', 'give' ); ?>
615 <br>
616 <br>
617 <a href="<?php echo esc_url( add_query_arg( [ 'give-restart-db-upgrades' => 1 ], admin_url( 'edit.php?post_type=give_forms&page=give-updates' ) ) ); ?>" class="button button-primary give-restart-updater-btn">
618 <?php _e( 'Restart the updater', 'give' ); ?>
619 </a>
620 <?php else : ?>
621 <strong><?php _e( 'Database Update', 'give' ); ?></strong>
622 &nbsp;&#8211;&nbsp;<?php _e( 'An unexpected issue occurred during the database update which caused it to stop automatically. Please contact support for assistance.', 'give' ); ?>
623 <a href="<?php echo esc_url( 'http://docs.givewp.com/troubleshooting-db-updates' ); ?>" target="_blank"><?php _e( 'Read More', 'give' ); ?> &raquo;</a>
624 <?php
625 endif;
626 $desc_html = ob_get_clean();
627
628 Give()->notices->register_notice(
629 [
630 'id' => 'give_upgrade_db',
631 'type' => 'error',
632 'dismissible' => false,
633 'description' => $desc_html,
634 ]
635 );
636 }
637
638 // Bailout if doing upgrades.
639 if ( $this->is_doing_updates() ) {
640 return;
641 }
642
643 // Show db upgrade completed notice.
644 if ( ! empty( $_GET['give-db-update-completed'] ) ) {
645 Give()->notices->register_notice(
646 [
647 'id' => 'give_db_upgrade_completed',
648 'type' => 'updated',
649 'description' => __( 'GiveWP database updates completed successfully. Thank you for updating to the latest version!', 'give' ),
650 'show' => true,
651 ]
652 );
653
654 // Start update.
655 } elseif ( ! empty( $_GET['give-run-db-update'] ) ) {
656 $this->run_db_update();
657
658 // Show run the update notice.
659 } elseif ( $this->get_total_new_db_update_count() ) {
660 ob_start();
661 ?>
662 <p>
663 <strong><?php _e( 'Database Update', 'give' ); ?></strong>
664 &nbsp;&#8211;&nbsp;<?php _e( 'GiveWP needs to update your database to the latest version. The following process will make updates to your site\'s database. Please create a complete backup before proceeding.', 'give' ); ?>
665 </p>
666 <p class="submit">
667 <a href="<?php echo esc_url( add_query_arg( [ 'give-run-db-update' => 1 ], admin_url( 'edit.php?post_type=give_forms&page=give-updates' ) ) ); ?>" class="button button-primary give-run-update-now">
668 <?php _e( 'Run the updater', 'give' ); ?>
669 </a>
670 </p>
671 <?php
672 $desc_html = ob_get_clean();
673
674 Give()->notices->register_notice(
675 [
676 'id' => 'give_upgrade_db',
677 'type' => 'updated',
678 'dismissible' => false,
679 'description' => $desc_html,
680 ]
681 );
682 }
683 }
684
685 /**
686 * Render Give Updates Completed page
687 *
688 * @since 1.8.12
689 * @access public
690 */
691 public function render_complete_page() {
692 include_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/views/upgrades-complete.php';
693 }
694
695 /**
696 * Render Give Updates page
697 *
698 * @since 1.8.12
699 * @access public
700 */
701 public function render_page() {
702 include_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/views/upgrades.php';
703 }
704
705 /**
706 * Run database upgrades
707 *
708 * @since 2.0
709 * @access private
710 */
711 private function run_db_update() {
712 // Bailout.
713 if ( $this->is_doing_updates() || ! $this->get_total_new_db_update_count() ) {
714 return;
715 }
716
717 $updates = $this->get_updates( 'database', 'new' );
718
719 foreach ( $updates as $update ) {
720 self::$background_updater->push_to_queue( $update );
721 }
722
723 add_option( 'give_db_update_count', count( $updates ), '', false );
724
725 add_option(
726 'give_doing_upgrade',
727 [
728 'update_info' => $updates[0],
729 'step' => 1,
730 'update' => 1,
731 'heading' => sprintf( 'Update %s of %s', 1, count( $updates ) ),
732 'percentage' => 0,
733 'total_percentage' => 0,
734 ],
735 '',
736 false
737 );
738
739 self::$background_updater->save()->dispatch();
740 }
741
742
743 /**
744 * Delete resume updates
745 *
746 * @since 1.8.12
747 * @access public
748 */
749 public function __flush_resume_updates() {
750 $this->step = $this->percentage = 0;
751
752 $this->update = ( $this->get_total_db_update_count() > $this->update ) ?
753 ( $this->update + 1 ) :
754 $this->update;
755 }
756
757
758 /**
759 * Initialize updates
760 *
761 * @since 2.0
762 * @access public
763 *
764 * @return void
765 */
766 public function __give_start_updating() {
767 // Check permission.
768 if (
769 ! current_user_can( 'manage_give_settings' ) ||
770 $this->is_doing_updates()
771 ) {
772 // Run update via ajax
773 self::$background_updater->dispatch();
774
775 wp_send_json_error();
776 }
777
778 // @todo: validate nonce
779 // @todo: set http method to post
780 if ( empty( $_POST['run_db_update'] ) ) {
781 wp_send_json_error();
782 }
783
784 $this->run_db_update();
785
786 wp_send_json_success();
787 }
788
789
790 /**
791 * This function handle ajax query for dn update status.
792 *
793 * @since 2.0
794 * @access public
795 *
796 * @return string
797 */
798 public function __give_db_updates_info() {
799 // Check permission.
800 if ( ! current_user_can( 'manage_give_settings' ) ) {
801 give_die();
802 }
803
804 $update_info = get_option( 'give_doing_upgrade' );
805 $response_type = '';
806
807 if ( self::$background_updater->is_paused_process() ) {
808 $update_info = [
809 'message' => __( 'The updates have been paused.', 'give' ),
810 'heading' => '',
811 'percentage' => 0,
812 ];
813
814 if ( get_option( 'give_upgrade_error' ) ) {
815 $update_info['message'] = __( 'An unexpected issue occurred during the database update which caused it to stop automatically. Please contact support for assistance.', 'give' );
816 }
817
818 $response_type = 'error';
819
820 } elseif ( empty( $update_info ) || ! $this->get_total_new_db_update_count( true ) ) {
821 $update_info = [
822 'message' => __( 'GiveWP database updates completed successfully. Thank you for updating to the latest version!', 'give' ),
823 'heading' => __( 'Updates Completed.', 'give' ),
824 'percentage' => 0,
825 ];
826 $response_type = 'success';
827
828 delete_option( 'give_show_db_upgrade_complete_notice' );
829 }
830
831 $this->send_ajax_response( $update_info, $response_type );
832 }
833
834 /**
835 * Send ajax response
836 *
837 * @since 1.8.12
838 * @access public
839 *
840 * @param $data
841 * @param string $type
842 */
843 public function send_ajax_response( $data, $type = '' ) {
844 $default = [
845 'message' => '',
846 'heading' => '',
847 'percentage' => 0,
848 'step' => 0,
849 'update' => 0,
850 ];
851
852 // Set data.
853 $data = wp_parse_args( $data, $default );
854
855 // Enable cache.
856 Give_Cache::enable();
857
858 switch ( $type ) {
859 case 'success':
860 wp_send_json_success( $data );
861 break;
862
863 case 'error':
864 wp_send_json_error( $data );
865 break;
866
867 default:
868 wp_send_json(
869 [
870 'data' => $data,
871 ]
872 );
873 break;
874 }
875 }
876
877 /**
878 * Set current update percentage.
879 *
880 * @since 1.8.12
881 * @access public
882 *
883 * @param $total
884 * @param $current_total
885 */
886 public function set_percentage( $total, $current_total ) {
887 // Set percentage.
888 $this->percentage = $total ? ( ( $current_total ) / $total ) * 100 : 0;
889
890 // Verify percentage.
891 $this->percentage = ( 100 < $this->percentage ) ? 100 : $this->percentage;
892 }
893
894 /**
895 * Check if parent update completed or not.
896 *
897 * @since 2.0
898 * @access private
899 *
900 * @param array $update
901 *
902 * @return bool|null
903 */
904 public function is_parent_updates_completed( $update ) {
905 // Bailout.
906 if ( empty( $update['depend'] ) ) {
907 return true;
908 }
909
910 // Check if dependency is valid or not.
911 if ( ! $this->has_valid_dependency( $update ) ) {
912 return null;
913 }
914
915 $is_dependency_completed = true;
916
917 foreach ( $update['depend'] as $depend ) {
918
919 if ( ! give_has_upgrade_completed( $depend ) ) {
920 $is_dependency_completed = false;
921 break;
922 }
923 }
924
925 return $is_dependency_completed;
926 }
927
928 /**
929 * Flag to check if DB updates running or not.
930 *
931 * @since 2.0
932 * @access public
933 * @return bool
934 */
935 public function is_doing_updates() {
936 return (bool) Give_Cache_Setting::get_option( 'give_doing_upgrade' );
937 }
938
939
940 /**
941 * Check if update has valid dependency or not.
942 *
943 * @since 2.0
944 * @access public
945 *
946 * @param $update
947 *
948 * @return bool
949 */
950 public function has_valid_dependency( $update ) {
951 $is_valid_dependency = true;
952 // $update_ids = wp_list_pluck( $this->get_updates( 'database', 'all' ), 'id' );
953 //
954 // foreach ( $update['depend'] as $depend ) {
955 // Check if dependency is valid or not.
956 // if ( ! in_array( $depend, $update_ids ) ) {
957 // $is_valid_dependency = false;
958 // break;
959 // }
960 // }
961
962 return $is_valid_dependency;
963 }
964
965 /**
966 * Get updates.
967 *
968 * @since 1.8.12
969 * @access public
970 *
971 * @param string $update_type Tye of update.
972 * @param string $status Tye of update.
973 *
974 * @return array
975 */
976 public function get_updates( $update_type = '', $status = 'all' ) {
977 // return all updates.
978 if ( empty( $update_type ) ) {
979 return $this->updates;
980 }
981
982 // Get specific update.
983 $updates = ! empty( $this->updates[ $update_type ] ) ? $this->updates[ $update_type ] : [];
984
985 // Bailout.
986 if ( empty( $updates ) ) {
987 return $updates;
988 }
989
990 switch ( $status ) {
991 case 'new':
992 // Remove already completed updates.
993 wp_cache_delete( 'give_completed_upgrades', 'options' );
994 $completed_updates = give_get_completed_upgrades();
995
996 if ( ! empty( $completed_updates ) ) {
997 foreach ( $updates as $index => $update ) {
998 if ( in_array( $update['id'], $completed_updates ) ) {
999 unset( $updates[ $index ] );
1000 }
1001 }
1002 $updates = array_values( $updates );
1003 }
1004
1005 break;
1006 }
1007
1008 return $updates;
1009 }
1010
1011 /**
1012 * Get addon update count.
1013 *
1014 * @since 1.8.12
1015 * @access public
1016 * @return int
1017 */
1018 public function get_total_plugin_update_count() {
1019 return count( $this->get_updates( 'plugin' ) );
1020 }
1021
1022 /**
1023 * Get total update count
1024 *
1025 * @since 1.8.12
1026 * @access public
1027 *
1028 * @return int
1029 */
1030 public function get_total_update_count() {
1031 $db_update_count = $this->get_pending_db_update_count();
1032 $plugin_update_count = $this->get_total_plugin_update_count();
1033
1034 return ( $db_update_count + $plugin_update_count );
1035 }
1036
1037 /**
1038 * Get total pending updates count
1039 *
1040 * @since 1.8.12
1041 * @access public
1042 *
1043 * @return int
1044 */
1045 public function get_pending_db_update_count() {
1046 return count( $this->get_updates( 'database', 'new' ) );
1047 }
1048
1049 /**
1050 * Get total updates count
1051 *
1052 * @since 1.8.18
1053 * @access public
1054 *
1055 * @return int
1056 */
1057 public function get_total_db_update_count() {
1058 return count( $this->get_updates( 'database', 'all' ) );
1059 }
1060
1061 /**
1062 * Get total new updates count
1063 *
1064 * @since 2.0
1065 * @access public
1066 *
1067 * @param bool $refresh
1068 *
1069 * @return int
1070 */
1071 public function get_total_new_db_update_count( $refresh = false ) {
1072 $update_count = $this->is_doing_updates() && ! $refresh ?
1073 get_option( 'give_db_update_count' ) :
1074 $this->get_pending_db_update_count();
1075
1076 return $update_count;
1077 }
1078
1079 /**
1080 * Get total new updates count
1081 *
1082 * @since 2.0
1083 * @access public
1084 *
1085 * @param bool $refresh
1086 *
1087 * @return int
1088 */
1089 public function get_running_db_update( $refresh = false ) {
1090 $current_update = 1;
1091
1092 if ( $this->is_doing_updates() && ! $refresh ) {
1093 $current_update = get_option( 'give_doing_upgrade' );
1094 $current_update = $current_update['update'];
1095 }
1096
1097 return $current_update;
1098 }
1099
1100 /**
1101 * Get database update processing percentage.
1102 *
1103 * @since 2.0
1104 * @access public
1105 *
1106 * @param bool $refresh
1107 *
1108 * @return float|int
1109 */
1110 public function get_db_update_processing_percentage( $refresh = false ) {
1111 // Bailout.
1112 if ( ! $this->get_total_new_db_update_count( $refresh ) ) {
1113 return 0;
1114 }
1115
1116 $resume_update = get_option( 'give_doing_upgrade' );
1117 $update_count_percentages = ( ( $this->get_running_db_update( $refresh ) - 1 ) / $this->get_total_new_db_update_count( $refresh ) ) * 100;
1118 $update_percentage_share = ( 1 / $this->get_total_new_db_update_count() ) * 100;
1119 $upgrade_percentage = ( ( $resume_update['percentage'] * $update_percentage_share ) / 100 );
1120
1121 $final_percentage = $update_count_percentages + $upgrade_percentage;
1122
1123 return $this->is_doing_updates() ?
1124 ( absint( $final_percentage ) ?
1125 absint( $final_percentage ) :
1126 round( $final_percentage, 2 )
1127 ) :
1128 0;
1129 }
1130
1131
1132 /**
1133 * Get all update ids.
1134 *
1135 * @since 2.0.3
1136 *
1137 * @return array
1138 */
1139 public function get_update_ids() {
1140 $all_updates = $this->get_updates( 'database', 'all' );
1141 $all_update_ids = wp_list_pluck( $all_updates, 'id' );
1142
1143 return $all_update_ids;
1144 }
1145
1146 /**
1147 * Get offset count
1148 *
1149 * @since 2.0.5
1150 * @access public
1151 *
1152 * @param int $process_item_count
1153 *
1154 * @return float|int
1155 */
1156 public function get_offset( $process_item_count ) {
1157 return ( 1 === $this->step ) ?
1158 0 :
1159 ( $this->step - 1 ) * $process_item_count;
1160 }
1161 }
1162
1163 Give_Updates::get_instance()->setup();
1164