PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 2.6.0
GiveWP – Donation Plugin and Fundraising Platform v2.6.0
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 6 years ago class-give-updates.php 6 years ago upgrade-functions.php 6 years ago
class-give-updates.php
1154 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 static private $instance;
18
19 /**
20 * Instance.
21 *
22 * @since
23 * @access public
24 * @var Give_Background_Updater
25 */
26 static public $background_updater;
27
28 /**
29 * Updates
30 *
31 * @since 1.8.12
32 * @access private
33 * @var array
34 */
35 private $updates = array();
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 = array(
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'] = array( $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', array( $this, '__register_upgrade' ), 9999 );
148 add_action( 'give_set_upgrade_completed', array( $this, '__flush_resume_updates' ), 9999 );
149 add_action( 'wp_ajax_give_db_updates_info', array( $this, '__give_db_updates_info' ) );
150 add_action( 'wp_ajax_give_run_db_updates', array( $this, '__give_start_updating' ) );
151 add_action( 'admin_init', array( $this, '__redirect_admin' ) );
152 add_action( 'admin_init', array( $this, '__pause_db_update' ), - 1 );
153 add_action( 'admin_init', array( $this, '__restart_db_update' ), - 1 );
154 add_action( 'admin_notices', array( $this, '__show_notice' ) );
155 add_action( 'give_restart_db_upgrade', array( $this, '__health_background_update' ) );
156
157 if ( is_admin() ) {
158 add_action( 'admin_init', array( $this, '__change_donations_label' ), 9999 );
159 add_action( 'admin_menu', array( $this, '__register_menu' ), 9999 );
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( array( '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 array( $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 array( $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 Give_Cache_Setting::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
404 /** Fire action when restart db updates
405 *
406 * @since 2.0.1
407 */
408 do_action( 'give_restart_db_upgrade', $this );
409
410 self::$background_updater->dispatch();
411 }
412
413 return true;
414 }
415
416 /**
417 * Health check for updates.
418 *
419 * @since 2.0
420 * @access public
421 *
422 * @param Give_Updates $give_updates
423 */
424 public function __health_background_update( $give_updates ) {
425 if ( ! $this->is_doing_updates() ) {
426 return;
427 }
428
429 Give_Background_Updater::flush_cache();
430
431 /* @var stdClass $batch */
432 $batch = Give_Updates::$background_updater->get_all_batch();
433 $old_batch_update_ids = is_array( $batch->data ) ? wp_list_pluck( $batch->data, 'id' ) : array();
434 $all_updates = $give_updates->get_updates( 'database', 'all' );
435 $all_update_ids = wp_list_pluck( $all_updates, 'id' );
436 $all_batch_update_ids = ! empty( $batch->data ) ? wp_list_pluck( $batch->data, 'id' ) : array();
437 $log_data = '';
438 $doing_upgrade_args = get_option( 'give_doing_upgrade' );
439
440 if ( ! empty( $doing_upgrade_args ) ) {
441 $log_data .= 'Doing update:' . "\n";
442 $log_data .= print_r( $doing_upgrade_args, true ) . "\n";
443 }
444
445 /**
446 * Add remove upgrade from batch
447 */
448 if ( ! empty( $batch->data ) ) {
449
450 foreach ( $batch->data as $index => $update ) {
451 $log_data = print_r( $update, true ) . "\n";
452
453 if ( ! is_callable( $update['callback'] ) ) {
454 $log_data .= 'Removing missing callback update: ' . "{$update['id']}\n";
455 unset( $batch->data[ $index ] );
456 } elseif ( give_has_upgrade_completed( $update['id'] ) ) {
457 $log_data .= 'Removing already completed update: ' . "{$update['id']}\n";
458 unset( $batch->data[ $index ] );
459 }
460
461 if ( ! empty( $update['depend'] ) ) {
462
463 foreach ( $update['depend'] as $depend ) {
464 if ( give_has_upgrade_completed( $depend ) ) {
465 $log_data .= 'Completed update: ' . "{$depend}\n";
466 continue;
467 }
468
469 if ( in_array( $depend, $all_update_ids ) && ! in_array( $depend, $all_batch_update_ids ) ) {
470 $log_data .= 'Adding missing update: ' . "{$depend}\n";
471 array_unshift( $batch->data, $all_updates[ array_search( $depend, $all_update_ids ) ] );
472 }
473 }
474 }
475 }
476 }
477
478 /**
479 * Add new upgrade to batch
480 */
481 if ( $new_updates = $this->get_updates( 'database', 'new' ) ) {
482 $all_batch_update_ids = ! empty( $batch->data ) ? wp_list_pluck( $batch->data, 'id' ) : array();
483
484 foreach ( $new_updates as $index => $new_update ) {
485 if ( give_has_upgrade_completed( $new_update['id'] ) || in_array( $new_update['id'], $all_batch_update_ids ) ) {
486 unset( $new_updates[ $index ] );
487 }
488 }
489
490 if ( ! empty( $new_updates ) ) {
491 $log_data .= 'Adding new update: ' . "\n";
492 $log_data .= print_r( $new_updates, true ) . "\n";
493
494 $batch->data = array_merge( (array) $batch->data, $new_updates );
495 update_option( 'give_db_update_count', ( absint( get_option( 'give_db_update_count' ) ) + count( $new_updates ) ), false );
496 }
497 }
498
499 /**
500 * Fix batch
501 */
502 if ( empty( $batch->data ) ) {
503 // Complete batch if do not have any data to process.
504 self::$background_updater->delete( $batch->key );
505
506 if ( self::$background_updater->has_queue() ) {
507 $this->__health_background_update( $this );
508 } else {
509 delete_site_transient( self::$background_updater->get_identifier() . '_process_lock' );
510 wp_clear_scheduled_hook( self::$background_updater->get_cron_identifier() );
511
512 self::$background_updater->complete();
513 }
514
515 } elseif ( array_diff( wp_list_pluck( $batch->data, 'id' ), $old_batch_update_ids ) ) {
516
517 $log_data .= 'Updating batch' . "\n";
518 $log_data .= print_r( $batch, true );
519
520 if ( ! empty( $batch->key ) ) {
521 wp_cache_delete( $batch->key, 'options' );
522 update_option( $batch->key, $batch->data, false );
523 } else {
524
525 foreach ( $batch->data as $data ) {
526 Give_Updates::$background_updater->push_to_queue( $data );
527 }
528
529 Give_Updates::$background_updater->save();
530 }
531 }
532
533
534 /**
535 * Fix give_doing_upgrade option
536 */
537 if( $fresh_new_db_count = $this->get_total_new_db_update_count( true ) ) {
538 update_option( 'give_db_update_count', $fresh_new_db_count, false );
539 }
540
541 $doing_upgrade_args['update'] = 1;
542 $doing_upgrade_args['heading'] = sprintf( 'Update %s of %s', 1, $fresh_new_db_count );
543 $doing_upgrade_args['total_percentage'] = $this->get_db_update_processing_percentage( true );
544
545 // Remove already completed update from info.
546 if (
547 empty( $doing_upgrade_args['update_info'] )
548 || give_has_upgrade_completed( $doing_upgrade_args['update_info']['id'] )
549 ) {
550 $doing_upgrade_args['update_info'] = current( array_values( $batch->data ) );
551 $doing_upgrade_args['step'] = 1;
552 }
553
554 // Check if dependency completed or not.
555 if ( isset( $doing_upgrade_args['update_info']['depend'] ) ) {
556 foreach ( $doing_upgrade_args['update_info']['depend'] as $depend ) {
557 if ( give_has_upgrade_completed( $depend ) ) {
558 continue;
559 }
560
561 $doing_upgrade_args['update_info'] = $all_updates[ array_search( $depend, $all_update_ids ) ];
562 $doing_upgrade_args['step'] = 1;
563 $doing_upgrade_args['percentage'] = 0;
564 $doing_upgrade_args['total_percentage'] = 0;
565
566 break;
567 }
568 }
569
570 if( ! empty( $doing_upgrade_args['update_info'] ) ) {
571 update_option( 'give_doing_upgrade', $doing_upgrade_args, false );
572
573 $log_data .= 'Updated doing update:' . "\n";
574 $log_data .= print_r( $doing_upgrade_args, true ) . "\n";
575 }
576
577 Give()->logs->add( 'Update Health Check', $log_data, 0, 'update' );
578 }
579
580
581 /**
582 * Show update related notices
583 *
584 * @since 2.0
585 * @access public
586 */
587 public function __show_notice() {
588 $current_screen = get_current_screen();
589 $hide_on_pages = array(
590 'give_forms_page_give-updates',
591 'update-core',
592 'give_forms_page_give-addons'
593 );
594
595 // Bailout.
596 if ( ! current_user_can( 'manage_give_settings' ) ) {
597 return;
598 }
599
600 // Run DB updates.
601 if ( ! empty( $_GET['give-run-db-update'] ) ) {
602 $this->run_db_update();
603 }
604
605 // Bailout.
606 if ( in_array( $current_screen->base, $hide_on_pages ) ) {
607 return;
608 }
609
610 // Show notice if upgrade paused.
611 if ( self::$background_updater->is_paused_process() ) {
612 ob_start();
613
614 $upgrade_error = get_option( 'give_upgrade_error' );
615 if ( ! $upgrade_error ) : ?>
616 <strong><?php _e( 'Database Update', 'give' ); ?></strong>
617 &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' ); ?>
618 <br>
619 <br>
620 <a href="<?php echo esc_url( add_query_arg( array( 'give-restart-db-upgrades' => 1 ), admin_url( 'edit.php?post_type=give_forms&page=give-updates' ) ) ); ?>" class="button button-primary give-restart-updater-btn">
621 <?php _e( 'Restart the updater', 'give' ); ?>
622 </a>
623 <?php else: ?>
624 <strong><?php _e( 'Database Update', 'give' ); ?></strong>
625 &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' ); ?>
626 <a href="<?php echo esc_url('http://docs.givewp.com/troubleshooting-db-updates')?>" target="_blank"><?php _e( 'Read More', 'give' ); ?> &raquo;</a>
627 <?php
628 endif;
629 $desc_html = ob_get_clean();
630
631 Give()->notices->register_notice( array(
632 'id' => 'give_upgrade_db',
633 'type' => 'error',
634 'dismissible' => false,
635 'description' => $desc_html,
636 ) );
637 }
638
639 // Bailout if doing upgrades.
640 if ( $this->is_doing_updates() ) {
641 return;
642 }
643
644 // Show db upgrade completed notice.
645 if ( ! empty( $_GET['give-db-update-completed'] ) ) {
646 Give()->notices->register_notice( array(
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 // Start update.
654 } elseif ( ! empty( $_GET['give-run-db-update'] ) ) {
655 $this->run_db_update();
656
657 // Show run the update notice.
658 } elseif ( $this->get_total_new_db_update_count() ) {
659 ob_start();
660 ?>
661 <p>
662 <strong><?php _e( 'Database Update', 'give' ); ?></strong>
663 &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' ); ?>
664 </p>
665 <p class="submit">
666 <a href="<?php echo esc_url( add_query_arg( array( 'give-run-db-update' => 1 ), admin_url( 'edit.php?post_type=give_forms&page=give-updates' ) ) ); ?>" class="button button-primary give-run-update-now">
667 <?php _e( 'Run the updater', 'give' ); ?>
668 </a>
669 </p>
670 <?php
671 $desc_html = ob_get_clean();
672
673 Give()->notices->register_notice( array(
674 'id' => 'give_upgrade_db',
675 'type' => 'updated',
676 'dismissible' => false,
677 'description' => $desc_html,
678 ) );
679 }
680 }
681
682 /**
683 * Render Give Updates Completed page
684 *
685 * @since 1.8.12
686 * @access public
687 */
688 public function render_complete_page() {
689 include_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/views/upgrades-complete.php';
690 }
691
692 /**
693 * Render Give Updates page
694 *
695 * @since 1.8.12
696 * @access public
697 */
698 public function render_page() {
699 include_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/views/upgrades.php';
700 }
701
702 /**
703 * Run database upgrades
704 *
705 * @since 2.0
706 * @access private
707 */
708 private function run_db_update() {
709 // Bailout.
710 if ( $this->is_doing_updates() || ! $this->get_total_new_db_update_count() ) {
711 return;
712 }
713
714 $updates = $this->get_updates( 'database', 'new' );
715
716 foreach ( $updates as $update ) {
717 self::$background_updater->push_to_queue( $update );
718 }
719
720 add_option( 'give_db_update_count', count( $updates ), '', false );
721
722 add_option( 'give_doing_upgrade', array(
723 'update_info' => $updates[0],
724 'step' => 1,
725 'update' => 1,
726 'heading' => sprintf( 'Update %s of %s', 1, count( $updates ) ),
727 'percentage' => 0,
728 'total_percentage' => 0,
729 ), '', false );
730
731 self::$background_updater->save()->dispatch();
732 }
733
734
735 /**
736 * Delete resume updates
737 *
738 * @since 1.8.12
739 * @access public
740 */
741 public function __flush_resume_updates() {
742 $this->step = $this->percentage = 0;
743
744 $this->update = ( $this->get_total_db_update_count() > $this->update ) ?
745 ( $this->update + 1 ) :
746 $this->update;
747 }
748
749
750 /**
751 * Initialize updates
752 *
753 * @since 2.0
754 * @access public
755 *
756 * @return void
757 */
758 public function __give_start_updating() {
759 // Check permission.
760 if (
761 ! current_user_can( 'manage_give_settings' ) ||
762 $this->is_doing_updates()
763 ) {
764 // Run update via ajax
765 self::$background_updater->dispatch();
766
767 wp_send_json_error();
768 }
769
770 // @todo: validate nonce
771 // @todo: set http method to post
772 if ( empty( $_POST['run_db_update'] ) ) {
773 wp_send_json_error();
774 }
775
776 $this->run_db_update();
777
778 wp_send_json_success();
779 }
780
781
782 /**
783 * This function handle ajax query for dn update status.
784 *
785 * @since 2.0
786 * @access public
787 *
788 * @return string
789 */
790 public function __give_db_updates_info() {
791 // Check permission.
792 if ( ! current_user_can( 'manage_give_settings' ) ) {
793 give_die();
794 }
795
796 $update_info = get_option( 'give_doing_upgrade' );
797 $response_type = '';
798
799 if ( self::$background_updater->is_paused_process() ) {
800 $update_info = array(
801 'message' => __( 'The updates have been paused.', 'give' ),
802 'heading' => '',
803 'percentage' => 0,
804 );
805
806 if ( get_option( 'give_upgrade_error' ) ) {
807 $update_info['message'] = __( 'An unexpected issue occurred during the database update which caused it to stop automatically. Please contact support for assistance.', 'give' );
808 }
809
810 $response_type = 'error';
811
812 } elseif ( empty( $update_info ) || ! $this->get_total_new_db_update_count( true ) ) {
813 $update_info = array(
814 'message' => __( 'GiveWP database updates completed successfully. Thank you for updating to the latest version!', 'give' ),
815 'heading' => __( 'Updates Completed.', 'give' ),
816 'percentage' => 0,
817 );
818 $response_type = 'success';
819
820 delete_option( 'give_show_db_upgrade_complete_notice' );
821 }
822
823 $this->send_ajax_response( $update_info, $response_type );
824 }
825
826 /**
827 * Send ajax response
828 *
829 * @since 1.8.12
830 * @access public
831 *
832 * @param $data
833 * @param string $type
834 */
835 public function send_ajax_response( $data, $type = '' ) {
836 $default = array(
837 'message' => '',
838 'heading' => '',
839 'percentage' => 0,
840 'step' => 0,
841 'update' => 0,
842 );
843
844 // Set data.
845 $data = wp_parse_args( $data, $default );
846
847 // Enable cache.
848 Give_Cache::enable();
849
850 switch ( $type ) {
851 case 'success':
852 wp_send_json_success( $data );
853 break;
854
855 case 'error':
856 wp_send_json_error( $data );
857 break;
858
859 default:
860 wp_send_json( array(
861 'data' => $data,
862 ) );
863 break;
864 }
865 }
866
867 /**
868 * Set current update percentage.
869 *
870 * @since 1.8.12
871 * @access public
872 *
873 * @param $total
874 * @param $current_total
875 */
876 public function set_percentage( $total, $current_total ) {
877 // Set percentage.
878 $this->percentage = $total ? ( ( $current_total ) / $total ) * 100 : 0;
879
880 // Verify percentage.
881 $this->percentage = ( 100 < $this->percentage ) ? 100 : $this->percentage;
882 }
883
884 /**
885 * Check if parent update completed or not.
886 *
887 * @since 2.0
888 * @access private
889 *
890 * @param array $update
891 *
892 * @return bool|null
893 */
894 public function is_parent_updates_completed( $update ) {
895 // Bailout.
896 if ( empty( $update['depend'] ) ) {
897 return true;
898 }
899
900 // Check if dependency is valid or not.
901 if ( ! $this->has_valid_dependency( $update ) ) {
902 return null;
903 }
904
905 $is_dependency_completed = true;
906
907 foreach ( $update['depend'] as $depend ) {
908
909 if ( ! give_has_upgrade_completed( $depend ) ) {
910 $is_dependency_completed = false;
911 break;
912 }
913 }
914
915 return $is_dependency_completed;
916 }
917
918 /**
919 * Flag to check if DB updates running or not.
920 *
921 * @since 2.0
922 * @access public
923 * @return bool
924 */
925 public function is_doing_updates() {
926 return (bool) Give_Cache_Setting::get_option( 'give_doing_upgrade' );
927 }
928
929
930 /**
931 * Check if update has valid dependency or not.
932 *
933 * @since 2.0
934 * @access public
935 *
936 * @param $update
937 *
938 * @return bool
939 */
940 public function has_valid_dependency( $update ) {
941 $is_valid_dependency = true;
942 // $update_ids = wp_list_pluck( $this->get_updates( 'database', 'all' ), 'id' );
943 //
944 // foreach ( $update['depend'] as $depend ) {
945 // // Check if dependency is valid or not.
946 // if ( ! in_array( $depend, $update_ids ) ) {
947 // $is_valid_dependency = false;
948 // break;
949 // }
950 // }
951
952 return $is_valid_dependency;
953 }
954
955 /**
956 * Get updates.
957 *
958 * @since 1.8.12
959 * @access public
960 *
961 * @param string $update_type Tye of update.
962 * @param string $status Tye of update.
963 *
964 * @return array
965 */
966 public function get_updates( $update_type = '', $status = 'all' ) {
967 // return all updates.
968 if ( empty( $update_type ) ) {
969 return $this->updates;
970 }
971
972 // Get specific update.
973 $updates = ! empty( $this->updates[ $update_type ] ) ? $this->updates[ $update_type ] : array();
974
975 // Bailout.
976 if ( empty( $updates ) ) {
977 return $updates;
978 }
979
980 switch ( $status ) {
981 case 'new':
982 // Remove already completed updates.
983 wp_cache_delete( 'give_completed_upgrades', 'options' );
984 $completed_updates = give_get_completed_upgrades();
985
986 if ( ! empty( $completed_updates ) ) {
987 foreach ( $updates as $index => $update ) {
988 if ( in_array( $update['id'], $completed_updates ) ) {
989 unset( $updates[ $index ] );
990 }
991 }
992 $updates = array_values( $updates );
993 }
994
995 break;
996 }
997
998 return $updates;
999 }
1000
1001 /**
1002 * Get addon update count.
1003 *
1004 * @since 1.8.12
1005 * @access public
1006 * @return int
1007 */
1008 public function get_total_plugin_update_count() {
1009 return count( $this->get_updates( 'plugin' ) );
1010 }
1011
1012 /**
1013 * Get total update count
1014 *
1015 * @since 1.8.12
1016 * @access public
1017 *
1018 * @return int
1019 */
1020 public function get_total_update_count() {
1021 $db_update_count = $this->get_pending_db_update_count();
1022 $plugin_update_count = $this->get_total_plugin_update_count();
1023
1024 return ( $db_update_count + $plugin_update_count );
1025 }
1026
1027 /**
1028 * Get total pending updates count
1029 *
1030 * @since 1.8.12
1031 * @access public
1032 *
1033 * @return int
1034 */
1035 public function get_pending_db_update_count() {
1036 return count( $this->get_updates( 'database', 'new' ) );
1037 }
1038
1039 /**
1040 * Get total updates count
1041 *
1042 * @since 1.8.18
1043 * @access public
1044 *
1045 * @return int
1046 */
1047 public function get_total_db_update_count() {
1048 return count( $this->get_updates( 'database', 'all' ) );
1049 }
1050
1051 /**
1052 * Get total new updates count
1053 *
1054 * @since 2.0
1055 * @access public
1056 *
1057 * @param bool $refresh
1058 *
1059 * @return int
1060 */
1061 public function get_total_new_db_update_count( $refresh = false ) {
1062 $update_count = $this->is_doing_updates() && ! $refresh ?
1063 get_option( 'give_db_update_count' ) :
1064 $this->get_pending_db_update_count();
1065
1066 return $update_count;
1067 }
1068
1069 /**
1070 * Get total new updates count
1071 *
1072 * @since 2.0
1073 * @access public
1074 *
1075 * @param bool $refresh
1076 *
1077 * @return int
1078 */
1079 public function get_running_db_update( $refresh = false ) {
1080 $current_update = 1;
1081
1082 if ( $this->is_doing_updates() && ! $refresh ) {
1083 $current_update = get_option( 'give_doing_upgrade' );
1084 $current_update = $current_update['update'];
1085 }
1086
1087 return $current_update;
1088 }
1089
1090 /**
1091 * Get database update processing percentage.
1092 *
1093 * @since 2.0
1094 * @access public
1095 *
1096 * @param bool $refresh
1097 *
1098 * @return float|int
1099 */
1100 public function get_db_update_processing_percentage( $refresh = false ) {
1101 // Bailout.
1102 if ( ! $this->get_total_new_db_update_count( $refresh ) ) {
1103 return 0;
1104 }
1105
1106 $resume_update = get_option( 'give_doing_upgrade' );
1107 $update_count_percentages = ( ( $this->get_running_db_update( $refresh ) - 1 ) / $this->get_total_new_db_update_count( $refresh ) ) * 100;
1108 $update_percentage_share = ( 1 / $this->get_total_new_db_update_count() ) * 100;
1109 $upgrade_percentage = ( ( $resume_update['percentage'] * $update_percentage_share ) / 100 );
1110
1111 $final_percentage = $update_count_percentages + $upgrade_percentage;
1112
1113 return $this->is_doing_updates() ?
1114 ( absint( $final_percentage ) ?
1115 absint( $final_percentage ) :
1116 round( $final_percentage, 2 )
1117 ) :
1118 0;
1119 }
1120
1121
1122 /**
1123 * Get all update ids.
1124 *
1125 * @since 2.0.3
1126 *
1127 * @return array
1128 */
1129 public function get_update_ids() {
1130 $all_updates = $this->get_updates( 'database', 'all' );
1131 $all_update_ids = wp_list_pluck( $all_updates, 'id' );
1132
1133 return $all_update_ids;
1134 }
1135
1136 /**
1137 * Get offset count
1138 *
1139 * @since 2.0.5
1140 * @access public
1141 *
1142 * @param int $process_item_count
1143 *
1144 * @return float|int
1145 */
1146 public function get_offset( $process_item_count ) {
1147 return ( 1 === $this->step ) ?
1148 0 :
1149 ( $this->step - 1 ) * $process_item_count;
1150 }
1151 }
1152
1153 Give_Updates::get_instance()->setup();
1154