PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 2.1.7
GiveWP – Donation Plugin and Fundraising Platform v2.1.7
4.16.3 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 8 years ago class-give-updates.php 8 years ago upgrade-functions.php 8 years ago
class-give-updates.php
1165 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();
171 $plugin_updates = get_plugin_updates();
172
173 foreach ( $addons as $key => $info ) {
174 if ( 'active' != $info['Status'] || 'add-on' != $info['Type'] || 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__( 'Give 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__( 'Give 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 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 );
351
352 return true;
353 }
354
355 update_option( 'give_paused_batches', $batch, 'no' );
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 );
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 $batch = Give_Updates::$background_updater->get_all_batch();
432 $batch_data_count = count( $batch->data );
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' ) : array();
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' ) : array();
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 ) ) );
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
514 } elseif ( $batch_data_count !== count( $batch->data ) ) {
515
516 $log_data .= 'Updating batch' . "\n";
517 $log_data .= print_r( $batch, true );
518
519 if ( ! empty( $batch->key ) ) {
520 wp_cache_delete( $batch->key, 'options' );
521 update_option( $batch->key, $batch->data );
522 } else {
523
524 foreach ( $batch->data as $data ) {
525 Give_Updates::$background_updater->push_to_queue( $data );
526 }
527
528 Give_Updates::$background_updater->save();
529 }
530 }
531
532
533 /**
534 * Fix give_doing_upgrade option
535 */
536 if( $fresh_new_db_count = $this->get_total_new_db_update_count( true ) ) {
537 update_option( 'give_db_update_count', $fresh_new_db_count );
538 }
539
540 $doing_upgrade_args['update'] = 1;
541 $doing_upgrade_args['heading'] = sprintf( 'Update %s of %s', 1, $fresh_new_db_count );
542 $doing_upgrade_args['total_percentage'] = $this->get_db_update_processing_percentage( true );
543
544 // Remove already completed update from info.
545 if (
546 empty( $doing_upgrade_args['update_info'] )
547 || give_has_upgrade_completed( $doing_upgrade_args['update_info']['id'] )
548 ) {
549 $doing_upgrade_args['update_info'] = current( array_values( $batch->data ) );
550 $doing_upgrade_args['step'] = 1;
551 }
552
553 // Check if dependency completed or not.
554 if ( isset( $doing_upgrade_args['update_info']['depend'] ) ) {
555 foreach ( $doing_upgrade_args['update_info']['depend'] as $depend ) {
556 if ( give_has_upgrade_completed( $depend ) ) {
557 continue;
558 }
559
560 $doing_upgrade_args['update_info'] = $all_updates[ array_search( $depend, $all_update_ids ) ];
561 $doing_upgrade_args['step'] = 1;
562 $doing_upgrade_args['percentage'] = 0;
563 $doing_upgrade_args['total_percentage'] = 0;
564
565 break;
566 }
567 }
568
569 if( ! empty( $doing_upgrade_args['update_info'] ) ) {
570 update_option( 'give_doing_upgrade', $doing_upgrade_args );
571
572 $log_data .= 'Updated doing update:' . "\n";
573 $log_data .= print_r( $doing_upgrade_args, true ) . "\n";
574 }
575
576 Give()->logs->add( 'Update Health Check', $log_data, 0, 'update' );
577 }
578
579
580 /**
581 * Show update related notices
582 *
583 * @since 2.0
584 * @access public
585 */
586 public function __show_notice() {
587 $current_screen = get_current_screen();
588
589 // Bailout.
590 if ( ! current_user_can( 'manage_give_settings' ) ) {
591 return;
592 }
593
594 // Run DB updates.
595 if ( ! empty( $_GET['give-run-db-update'] ) ) {
596 $this->run_db_update();
597 }
598
599
600 // Bailout.
601 if ( in_array( $current_screen->base, array( 'give_forms_page_give-updates', 'update-core' ) ) ) {
602 return;
603 }
604
605
606 // Show notice if ajax is not working.
607 if ( ! give_test_ajax_works() ) {
608 Give()->notices->register_notice(
609 array(
610 'id' => 'give_db_upgrade_ajax_inaccessible',
611 'type' => 'error',
612 'description' => sprintf(
613 '%1$s <a href="%2$s" target="_blank">%3$s</a>',
614 __( 'Give needs to upgrade the database but cannot because AJAX does not appear accessible. This could be because your website is password protected, in maintenance mode, or has a specific hosting configuration or plugin active that is preventing access.', 'give' ),
615 esc_url( 'http://docs.givewp.com/troubleshooting-db-updates' ),
616 __( 'Read More', 'give' ) . ' &raquo;'
617 ),
618 'show' => true,
619 )
620 );
621
622 return;
623 }
624
625 // Show notice if upgrade paused.
626 if ( self::$background_updater->is_paused_process() ) {
627 ob_start();
628
629 $upgrade_error = get_option( 'give_upgrade_error' );
630 if ( ! $upgrade_error ) : ?>
631 <strong><?php _e( 'Database Update', 'give' ); ?></strong>
632 &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' ); ?>
633 <br>
634 <br>
635 <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">
636 <?php _e( 'Restart the updater', 'give' ); ?>
637 </a>
638 <?php else: ?>
639 <strong><?php _e( 'Database Update', 'give' ); ?></strong>
640 &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' ); ?>
641 <a href="<?php echo esc_url('http://docs.givewp.com/troubleshooting-db-updates')?>" target="_blank"><?php _e( 'Read More', 'give' ); ?> &raquo;</a>
642 <?php
643 endif;
644 $desc_html = ob_get_clean();
645
646 Give()->notices->register_notice( array(
647 'id' => 'give_upgrade_db',
648 'type' => 'error',
649 'dismissible' => false,
650 'description' => $desc_html,
651 ) );
652 }
653
654 // Bailout if doing upgrades.
655 if ( $this->is_doing_updates() ) {
656 return;
657 }
658
659 // Show db upgrade completed notice.
660 if ( ! empty( $_GET['give-db-update-completed'] ) ) {
661 Give()->notices->register_notice( array(
662 'id' => 'give_db_upgrade_completed',
663 'type' => 'updated',
664 'description' => __( 'Give database updates completed successfully. Thank you for updating to the latest version!', 'give' ),
665 'show' => true,
666 ) );
667
668 // Start update.
669 } elseif ( ! empty( $_GET['give-run-db-update'] ) ) {
670 $this->run_db_update();
671
672 // Show run the update notice.
673 } elseif ( $this->get_total_new_db_update_count() ) {
674 ob_start();
675 ?>
676 <p>
677 <strong><?php _e( 'Database Update', 'give' ); ?></strong>
678 &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' ); ?>
679 </p>
680 <p class="submit">
681 <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">
682 <?php _e( 'Run the updater', 'give' ); ?>
683 </a>
684 </p>
685 <?php
686 $desc_html = ob_get_clean();
687
688 Give()->notices->register_notice( array(
689 'id' => 'give_upgrade_db',
690 'type' => 'updated',
691 'dismissible' => false,
692 'description' => $desc_html,
693 ) );
694 }
695 }
696
697 /**
698 * Render Give Updates Completed page
699 *
700 * @since 1.8.12
701 * @access public
702 */
703 public function render_complete_page() {
704 include_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/views/upgrades-complete.php';
705 }
706
707 /**
708 * Render Give Updates page
709 *
710 * @since 1.8.12
711 * @access public
712 */
713 public function render_page() {
714 include_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/views/upgrades.php';
715 }
716
717 /**
718 * Run database upgrades
719 *
720 * @since 2.0
721 * @access private
722 */
723 private function run_db_update() {
724 // Bailout.
725 if ( $this->is_doing_updates() || ! $this->get_total_new_db_update_count() ) {
726 return;
727 }
728
729 $updates = $this->get_updates( 'database', 'new' );
730
731 foreach ( $updates as $update ) {
732 self::$background_updater->push_to_queue( $update );
733 }
734
735 add_option( 'give_db_update_count', count( $updates ), '', 'no' );
736
737 add_option( 'give_doing_upgrade', array(
738 'update_info' => $updates[0],
739 'step' => 1,
740 'update' => 1,
741 'heading' => sprintf( 'Update %s of %s', 1, count( $updates ) ),
742 'percentage' => 0,
743 'total_percentage' => 0,
744 ), '', 'no' );
745
746 self::$background_updater->save()->dispatch();
747 }
748
749
750 /**
751 * Delete resume updates
752 *
753 * @since 1.8.12
754 * @access public
755 */
756 public function __flush_resume_updates() {
757 //delete_option( 'give_doing_upgrade' );
758 update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ) );
759
760 // Reset counter.
761 $this->step = $this->percentage = 0;
762
763 $this->update = ( $this->get_total_db_update_count() > $this->update ) ?
764 ( $this->update + 1 ) :
765 $this->update;
766 }
767
768
769 /**
770 * Initialize updates
771 *
772 * @since 2.0
773 * @access public
774 *
775 * @return void
776 */
777 public function __give_start_updating() {
778 // Check permission.
779 if (
780 ! current_user_can( 'manage_give_settings' ) ||
781 $this->is_doing_updates()
782 ) {
783 wp_send_json_error();
784 }
785
786 // @todo: validate nonce
787 // @todo: set http method to post
788 if ( empty( $_POST['run_db_update'] ) ) {
789 wp_send_json_error();
790 }
791
792 $this->run_db_update();
793
794 wp_send_json_success();
795 }
796
797
798 /**
799 * This function handle ajax query for dn update status.
800 *
801 * @since 2.0
802 * @access public
803 *
804 * @return string
805 */
806 public function __give_db_updates_info() {
807 $update_info = get_option( 'give_doing_upgrade' );
808 $response_type = '';
809
810 if ( self::$background_updater->is_paused_process() ) {
811 $update_info = array(
812 'message' => __( 'The updates have been paused.', 'give' ),
813 'heading' => '',
814 'percentage' => 0,
815 );
816
817 if ( get_option( 'give_upgrade_error' ) ) {
818 $update_info['message'] = __( 'An unexpected issue occurred during the database update which caused it to stop automatically. Please contact support for assistance.', 'give' );
819 }
820
821 $response_type = 'error';
822
823 } elseif ( empty( $update_info ) || ! $this->get_total_new_db_update_count( true ) ) {
824 $update_info = array(
825 'message' => __( 'Give database updates completed successfully. Thank you for updating to the latest version!', 'give' ),
826 'heading' => __( 'Updates Completed.', 'give' ),
827 'percentage' => 0,
828 );
829 $response_type = 'success';
830
831 delete_option( 'give_show_db_upgrade_complete_notice' );
832 }
833
834 $this->send_ajax_response( $update_info, $response_type );
835 }
836
837 /**
838 * Send ajax response
839 *
840 * @since 1.8.12
841 * @access public
842 *
843 * @param $data
844 * @param string $type
845 */
846 public function send_ajax_response( $data, $type = '' ) {
847 $default = array(
848 'message' => '',
849 'heading' => '',
850 'percentage' => 0,
851 'step' => 0,
852 'update' => 0,
853 );
854
855 // Set data.
856 $data = wp_parse_args( $data, $default );
857
858 // Enable cache.
859 Give_Cache::enable();
860
861 switch ( $type ) {
862 case 'success':
863 wp_send_json_success( $data );
864 break;
865
866 case 'error':
867 wp_send_json_error( $data );
868 break;
869
870 default:
871 wp_send_json( array(
872 'data' => $data,
873 ) );
874 break;
875 }
876 }
877
878 /**
879 * Set current update percentage.
880 *
881 * @since 1.8.12
882 * @access public
883 *
884 * @param $total
885 * @param $current_total
886 */
887 public function set_percentage( $total, $current_total ) {
888 // Set percentage.
889 $this->percentage = $total ? ( ( $current_total ) / $total ) * 100 : 0;
890
891 // Verify percentage.
892 $this->percentage = ( 100 < $this->percentage ) ? 100 : $this->percentage;
893 }
894
895 /**
896 * Check if parent update completed or not.
897 *
898 * @since 2.0
899 * @access private
900 *
901 * @param array $update
902 *
903 * @return bool|null
904 */
905 public function is_parent_updates_completed( $update ) {
906 // Bailout.
907 if ( empty( $update['depend'] ) ) {
908 return true;
909 }
910
911 // Check if dependency is valid or not.
912 if ( ! $this->has_valid_dependency( $update ) ) {
913 return null;
914 }
915
916 $is_dependency_completed = true;
917
918 foreach ( $update['depend'] as $depend ) {
919
920 if ( ! give_has_upgrade_completed( $depend ) ) {
921 $is_dependency_completed = false;
922 break;
923 }
924 }
925
926 return $is_dependency_completed;
927 }
928
929 /**
930 * Flag to check if DB updates running or not.
931 *
932 * @since 2.0
933 * @access public
934 * @return bool
935 */
936 public function is_doing_updates() {
937 return (bool) get_option( 'give_doing_upgrade' );
938 }
939
940
941 /**
942 * Check if update has valid dependency or not.
943 *
944 * @since 2.0
945 * @access public
946 *
947 * @param $update
948 *
949 * @return bool
950 */
951 public function has_valid_dependency( $update ) {
952 $is_valid_dependency = true;
953 // $update_ids = wp_list_pluck( $this->get_updates( 'database', 'all' ), 'id' );
954 //
955 // foreach ( $update['depend'] as $depend ) {
956 // // Check if dependency is valid or not.
957 // if ( ! in_array( $depend, $update_ids ) ) {
958 // $is_valid_dependency = false;
959 // break;
960 // }
961 // }
962
963 return $is_valid_dependency;
964 }
965
966 /**
967 * Get updates.
968 *
969 * @since 1.8.12
970 * @access public
971 *
972 * @param string $update_type Tye of update.
973 * @param string $status Tye of update.
974 *
975 * @return array
976 */
977 public function get_updates( $update_type = '', $status = 'all' ) {
978 // return all updates.
979 if ( empty( $update_type ) ) {
980 return $this->updates;
981 }
982
983 // Get specific update.
984 $updates = ! empty( $this->updates[ $update_type ] ) ? $this->updates[ $update_type ] : array();
985
986 // Bailout.
987 if ( empty( $updates ) ) {
988 return $updates;
989 }
990
991 switch ( $status ) {
992 case 'new':
993 // Remove already completed updates.
994 wp_cache_delete( 'give_completed_upgrades', 'options' );
995 $completed_updates = give_get_completed_upgrades();
996
997 if ( ! empty( $completed_updates ) ) {
998 foreach ( $updates as $index => $update ) {
999 if ( in_array( $update['id'], $completed_updates ) ) {
1000 unset( $updates[ $index ] );
1001 }
1002 }
1003 $updates = array_values( $updates );
1004 }
1005
1006 break;
1007 }
1008
1009 return $updates;
1010 }
1011
1012 /**
1013 * Get addon update count.
1014 *
1015 * @since 1.8.12
1016 * @access public
1017 * @return int
1018 */
1019 public function get_total_plugin_update_count() {
1020 return count( $this->get_updates( 'plugin' ) );
1021 }
1022
1023 /**
1024 * Get total update count
1025 *
1026 * @since 1.8.12
1027 * @access public
1028 *
1029 * @return int
1030 */
1031 public function get_total_update_count() {
1032 $db_update_count = $this->get_pending_db_update_count();
1033 $plugin_update_count = $this->get_total_plugin_update_count();
1034
1035 return ( $db_update_count + $plugin_update_count );
1036 }
1037
1038 /**
1039 * Get total pending updates count
1040 *
1041 * @since 1.8.12
1042 * @access public
1043 *
1044 * @return int
1045 */
1046 public function get_pending_db_update_count() {
1047 return count( $this->get_updates( 'database', 'new' ) );
1048 }
1049
1050 /**
1051 * Get total updates count
1052 *
1053 * @since 1.8.18
1054 * @access public
1055 *
1056 * @return int
1057 */
1058 public function get_total_db_update_count() {
1059 return count( $this->get_updates( 'database', 'all' ) );
1060 }
1061
1062 /**
1063 * Get total new updates count
1064 *
1065 * @since 2.0
1066 * @access public
1067 *
1068 * @param bool $refresh
1069 *
1070 * @return int
1071 */
1072 public function get_total_new_db_update_count( $refresh = false ) {
1073 $update_count = $this->is_doing_updates() && ! $refresh ?
1074 get_option( 'give_db_update_count' ) :
1075 $this->get_pending_db_update_count();
1076
1077 return $update_count;
1078 }
1079
1080 /**
1081 * Get total new updates count
1082 *
1083 * @since 2.0
1084 * @access public
1085 *
1086 * @param bool $refresh
1087 *
1088 * @return int
1089 */
1090 public function get_running_db_update( $refresh = false ) {
1091 $current_update = 1;
1092
1093 if ( $this->is_doing_updates() && ! $refresh ) {
1094 $current_update = get_option( 'give_doing_upgrade' );
1095 $current_update = $current_update['update'];
1096 }
1097
1098 return $current_update;
1099 }
1100
1101 /**
1102 * Get database update processing percentage.
1103 *
1104 * @since 2.0
1105 * @access public
1106 *
1107 * @param bool $refresh
1108 *
1109 * @return float|int
1110 */
1111 public function get_db_update_processing_percentage( $refresh = false ) {
1112 // Bailout.
1113 if ( ! $this->get_total_new_db_update_count( $refresh ) ) {
1114 return 0;
1115 }
1116
1117 $resume_update = get_option( 'give_doing_upgrade' );
1118 $update_count_percentages = ( ( $this->get_running_db_update( $refresh ) - 1 ) / $this->get_total_new_db_update_count( $refresh ) ) * 100;
1119 $update_percentage_share = ( 1 / $this->get_total_new_db_update_count() ) * 100;
1120 $upgrade_percentage = ( ( $resume_update['percentage'] * $update_percentage_share ) / 100 );
1121
1122 $final_percentage = $update_count_percentages + $upgrade_percentage;
1123
1124 return $this->is_doing_updates() ?
1125 ( absint( $final_percentage ) ?
1126 absint( $final_percentage ) :
1127 round( $final_percentage, 2 )
1128 ) :
1129 0;
1130 }
1131
1132
1133 /**
1134 * Get all update ids.
1135 *
1136 * @since 2.0.3
1137 *
1138 * @return array
1139 */
1140 public function get_update_ids() {
1141 $all_updates = $this->get_updates( 'database', 'all' );
1142 $all_update_ids = wp_list_pluck( $all_updates, 'id' );
1143
1144 return $all_update_ids;
1145 }
1146
1147 /**
1148 * Get offset count
1149 *
1150 * @since 2.0.5
1151 * @access public
1152 *
1153 * @param int $process_item_count
1154 *
1155 * @return float|int
1156 */
1157 public function get_offset( $process_item_count ) {
1158 return ( 1 === $this->step ) ?
1159 0 :
1160 ( $this->step - 1 ) * $process_item_count;
1161 }
1162 }
1163
1164 Give_Updates::get_instance()->setup();
1165