PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 2.1.0
GiveWP – Donation Plugin and Fundraising Platform v2.1.0
4.16.4 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
1161 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 return;
249 }
250
251 // Bailout.
252 if ( ! $this->get_total_update_count() ) {
253 // Show complete update message if still on update setting page.
254 if ( isset( $_GET['page'] ) && 'give-updates' === $_GET['page'] ) {
255 // Upgrades
256 add_submenu_page(
257 'edit.php?post_type=give_forms',
258 esc_html__( 'Give Updates Complete', 'give' ),
259 __( 'Updates', 'give' ),
260 'manage_give_settings',
261 'give-updates',
262 array( $this, 'render_complete_page' )
263 );
264 }
265
266 return;
267 }
268
269 $is_update = ( $this->is_doing_updates() && ! self::$background_updater->is_paused_process() );
270
271 // Upgrades
272 add_submenu_page(
273 'edit.php?post_type=give_forms',
274 esc_html__( 'Give Updates', 'give' ),
275 sprintf(
276 '%1$s <span class="update-plugins"%2$s><span class="plugin-count give-update-progress-count">%3$s%4$s</span></span>',
277 __( 'Updates', 'give' ),
278 isset( $_GET['give-pause-db-upgrades'] ) ? ' style="display:none;"' : '',
279 $is_update ?
280 $this->get_db_update_processing_percentage() :
281 $this->get_total_update_count(),
282 $is_update ? '%' : ''
283 ),
284 'manage_give_settings',
285 'give-updates',
286 array( $this, 'render_page' )
287 );
288 }
289
290
291 /**
292 * Show update related notices
293 *
294 * @since 2.0
295 * @access public
296 */
297 public function __redirect_admin() {
298 // Show db upgrade completed notice.
299 if (
300 ! wp_doing_ajax() &&
301 current_user_can( 'manage_give_settings' ) &&
302 get_option( 'give_show_db_upgrade_complete_notice' ) &&
303 ! isset( $_GET['give-db-update-completed'] )
304 ) {
305 delete_option( 'give_show_db_upgrade_complete_notice' );
306
307 wp_redirect( add_query_arg( array( 'give-db-update-completed' => 'give_db_upgrade_completed' ) ) );
308 exit();
309 }
310 }
311
312
313 /**
314 * Pause db upgrade
315 *
316 * @since 2.0.1
317 * @access public
318 *
319 * @param bool $force
320 *
321 * @return bool
322 */
323 public function __pause_db_update( $force = false ) {
324 // Bailout.
325 if (
326 ! $force &&
327 (
328 wp_doing_ajax() ||
329 ! isset( $_GET['page'] ) ||
330 'give-updates' !== $_GET['page'] ||
331 ! isset( $_GET['give-pause-db-upgrades'] ) ||
332 self::$background_updater->is_paused_process()
333 )
334
335 ) {
336 return false;
337 }
338
339 delete_option( 'give_upgrade_error' );
340
341 $this->__health_background_update( $this );
342 $batch = self::$background_updater->get_all_batch();
343
344 // Bailout: if batch is empty
345 if ( empty( $batch->data ) ) {
346 return false;
347 }
348
349 // Remove cache.
350 Give_Background_Updater::flush_cache();
351
352 // Do not stop background process immediately if task running.
353 // @see Give_Background_Updater::lock_process
354 if ( ! $force && self::$background_updater->is_process_running() ) {
355 update_option( 'give_pause_upgrade', 1 );
356
357 return true;
358 }
359
360 update_option( 'give_paused_batches', $batch, 'no' );
361 delete_option( $batch->key );
362 delete_site_transient( self::$background_updater->get_identifier() . '_process_lock' );
363 wp_clear_scheduled_hook( self::$background_updater->get_cron_identifier() );
364
365 Give()->logs->add( 'Update Pause', print_r( $batch, true ), 0, 'update' );
366
367 /**
368 * Fire action when pause db updates
369 *
370 * @since 2.0.1
371 */
372 do_action( 'give_pause_db_upgrade', $this );
373
374 return true;
375 }
376
377 /**
378 * Restart db upgrade
379 *
380 * @since 2.0.1
381 * @access public
382 *
383 * @return bool
384 */
385 public function __restart_db_update() {
386 // Bailout.
387 if (
388 wp_doing_ajax() ||
389 ! isset( $_GET['page'] ) ||
390 'give-updates' !== $_GET['page'] ||
391 ! isset( $_GET['give-restart-db-upgrades'] ) ||
392 ! self::$background_updater->is_paused_process()
393 ) {
394 return false;
395 }
396
397 Give_Background_Updater::flush_cache();
398 $batch = get_option( 'give_paused_batches' );
399
400 if ( ! empty( $batch ) ) {
401 wp_cache_delete( $batch->key, 'options' );
402 update_option( $batch->key, $batch->data );
403
404 delete_option( 'give_paused_batches' );
405
406 Give()->logs->add( 'Update Restart', print_r( $batch, true ), 0, 'update' );
407
408
409 /** Fire action when restart db updates
410 *
411 * @since 2.0.1
412 */
413 do_action( 'give_restart_db_upgrade', $this );
414
415 self::$background_updater->dispatch();
416 }
417
418 return true;
419 }
420
421 /**
422 * Health check for updates.
423 *
424 * @since 2.0
425 * @access public
426 *
427 * @param Give_Updates $give_updates
428 */
429 public function __health_background_update( $give_updates ) {
430 if ( ! $this->is_doing_updates() ) {
431 return;
432 }
433
434 Give_Background_Updater::flush_cache();
435
436 $batch = Give_Updates::$background_updater->get_all_batch();
437 $batch_data_count = count( $batch->data );
438 $all_updates = $give_updates->get_updates( 'database', 'all' );
439 $all_update_ids = wp_list_pluck( $all_updates, 'id' );
440 $all_batch_update_ids = ! empty( $batch->data ) ? wp_list_pluck( $batch->data, 'id' ) : array();
441 $log_data = '';
442 $doing_upgrade_args = get_option( 'give_doing_upgrade' );
443
444 if ( ! empty( $doing_upgrade_args ) ) {
445 $log_data .= 'Doing update:' . "\n";
446 $log_data .= print_r( $doing_upgrade_args, true ) . "\n";
447 }
448
449 /**
450 * Add remove upgrade from batch
451 */
452 if ( ! empty( $batch->data ) ) {
453
454 foreach ( $batch->data as $index => $update ) {
455 $log_data = print_r( $update, true ) . "\n";
456
457 if ( ! is_callable( $update['callback'] ) ) {
458 $log_data .= 'Removing missing callback update: ' . "{$update['id']}\n";
459 unset( $batch->data[ $index ] );
460 } elseif ( give_has_upgrade_completed( $update['id'] ) ) {
461 $log_data .= 'Removing already completed update: ' . "{$update['id']}\n";
462 unset( $batch->data[ $index ] );
463 }
464
465 if ( ! empty( $update['depend'] ) ) {
466
467 foreach ( $update['depend'] as $depend ) {
468 if ( give_has_upgrade_completed( $depend ) ) {
469 $log_data .= 'Completed update: ' . "{$depend}\n";
470 continue;
471 }
472
473 if ( in_array( $depend, $all_update_ids ) && ! in_array( $depend, $all_batch_update_ids ) ) {
474 $log_data .= 'Adding missing update: ' . "{$depend}\n";
475 array_unshift( $batch->data, $all_updates[ array_search( $depend, $all_update_ids ) ] );
476 }
477 }
478 }
479 }
480 }
481
482 /**
483 * Add new upgrade to batch
484 */
485 if ( $new_updates = $this->get_updates( 'database', 'new' ) ) {
486 $all_batch_update_ids = ! empty( $batch->data ) ? wp_list_pluck( $batch->data, 'id' ) : array();
487
488 foreach ( $new_updates as $index => $new_update ) {
489 if ( give_has_upgrade_completed( $new_update['id'] ) || in_array( $new_update['id'], $all_batch_update_ids ) ) {
490 unset( $new_updates[ $index ] );
491 }
492 }
493
494 if ( ! empty( $new_updates ) ) {
495 $log_data .= 'Adding new update: ' . "\n";
496 $log_data .= print_r( $new_updates, true ) . "\n";
497
498 $batch->data = array_merge( (array) $batch->data, $new_updates );
499 update_option( 'give_db_update_count', ( absint( get_option( 'give_db_update_count' ) ) + count( $new_updates ) ) );
500 }
501 }
502
503 /**
504 * Fix batch
505 */
506 if ( empty( $batch->data ) ) {
507 // Complete batch if do not have any data to process.
508 self::$background_updater->delete( $batch->key );
509
510 if ( self::$background_updater->has_queue() ) {
511 $this->__health_background_update( $this );
512 } else {
513 delete_site_transient( self::$background_updater->get_identifier() . '_process_lock' );
514 wp_clear_scheduled_hook( self::$background_updater->get_cron_identifier() );
515
516 self::$background_updater->complete();
517 }
518
519 } elseif ( $batch_data_count !== count( $batch->data ) ) {
520
521 $log_data .= 'Updating batch' . "\n";
522 $log_data .= print_r( $batch, true );
523
524 if ( ! empty( $batch->key ) ) {
525 wp_cache_delete( $batch->key, 'options' );
526 update_option( $batch->key, $batch->data );
527 } else {
528
529 foreach ( $batch->data as $data ) {
530 Give_Updates::$background_updater->push_to_queue( $data );
531 }
532
533 Give_Updates::$background_updater->save();
534 }
535 }
536
537
538 /**
539 * Fix give_doing_upgrade option
540 */
541 if( $fresh_new_db_count = $this->get_total_new_db_update_count( true ) ) {
542 update_option( 'give_db_update_count', $fresh_new_db_count );
543 }
544
545 $doing_upgrade_args['update'] = 1;
546 $doing_upgrade_args['heading'] = sprintf( 'Update %s of %s', 1, $fresh_new_db_count );
547 $doing_upgrade_args['total_percentage'] = $this->get_db_update_processing_percentage( true );
548
549 // Remove already completed update from info.
550 if (
551 empty( $doing_upgrade_args['update_info'] )
552 || give_has_upgrade_completed( $doing_upgrade_args['update_info']['id'] )
553 ) {
554 $doing_upgrade_args['update_info'] = current( array_values( $batch->data ) );
555 $doing_upgrade_args['step'] = 1;
556 }
557
558 // Check if dependency completed or not.
559 if ( isset( $doing_upgrade_args['update_info']['depend'] ) ) {
560 foreach ( $doing_upgrade_args['update_info']['depend'] as $depend ) {
561 if ( give_has_upgrade_completed( $depend ) ) {
562 continue;
563 }
564
565 $doing_upgrade_args['update_info'] = $all_updates[ array_search( $depend, $all_update_ids ) ];
566 $doing_upgrade_args['step'] = 1;
567 $doing_upgrade_args['percentage'] = 0;
568 $doing_upgrade_args['total_percentage'] = 0;
569
570 break;
571 }
572 }
573
574 if( ! empty( $doing_upgrade_args['update_info'] ) ) {
575 update_option( 'give_doing_upgrade', $doing_upgrade_args );
576
577 $log_data .= 'Updated doing update:' . "\n";
578 $log_data .= print_r( $doing_upgrade_args, true ) . "\n";
579 }
580
581 Give()->logs->add( 'Update Health Check', $log_data, 0, 'update' );
582 }
583
584
585 /**
586 * Show update related notices
587 *
588 * @since 2.0
589 * @access public
590 */
591 public function __show_notice() {
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
603 // Bailout.
604 if ( isset( $_GET['page'] ) && 'give-updates' === $_GET['page'] ) {
605 return;
606 }
607
608 // Show notice if upgrade paused.
609 if ( self::$background_updater->is_paused_process() ) {
610 ob_start();
611
612 $upgrade_error = get_option( 'give_upgrade_error' );
613 if ( ! $upgrade_error ) : ?>
614 <strong><?php _e( 'Database Update', 'give' ); ?></strong>
615 &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' ); ?>
616 <br>
617 <br>
618 <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">
619 <?php _e( 'Restart the updater', 'give' ); ?>
620 </a>
621 <?php else: ?>
622 <strong><?php _e( 'Database Update', 'give' ); ?></strong>
623 &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' ); ?>
624 <?php
625 endif;
626 $desc_html = ob_get_clean();
627
628 Give()->notices->register_notice( array(
629 'id' => 'give_upgrade_db',
630 'type' => 'error',
631 'dismissible' => false,
632 'description' => $desc_html,
633 ) );
634 }
635
636 // Bailout if doing upgrades.
637 if ( $this->is_doing_updates() ) {
638 return;
639 }
640
641 // Show notice if ajax is not working.
642 if ( ! give_test_ajax_works() ) {
643 Give()->notices->register_notice(
644 array(
645 'id' => 'give_db_upgrade_ajax_inaccessible',
646 'type' => 'error',
647 'description' => sprintf( '%1$s <a href="%2$s" target="_blank">%3$s</a>', __( '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' ), 'http://docs.givewp.com/admin-ajax-error', __( 'Read More', 'give' ) . ' &raquo;' ),
648 'show' => true,
649 )
650 );
651
652 return;
653 }
654
655 // Show db upgrade completed notice.
656 if ( ! empty( $_GET['give-db-update-completed'] ) ) {
657 Give()->notices->register_notice( array(
658 'id' => 'give_db_upgrade_completed',
659 'type' => 'updated',
660 'description' => __( 'Give database updates completed successfully. Thank you for updating to the latest version!', 'give' ),
661 'show' => true,
662 ) );
663
664 // Start update.
665 } elseif ( ! empty( $_GET['give-run-db-update'] ) ) {
666 $this->run_db_update();
667
668 // Show run the update notice.
669 } elseif ( $this->get_total_new_db_update_count() ) {
670 ob_start();
671 ?>
672 <p>
673 <strong><?php _e( 'Database Update', 'give' ); ?></strong>
674 &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' ); ?>
675 </p>
676 <p class="submit">
677 <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">
678 <?php _e( 'Run the updater', 'give' ); ?>
679 </a>
680 </p>
681 <?php
682 $desc_html = ob_get_clean();
683
684 Give()->notices->register_notice( array(
685 'id' => 'give_upgrade_db',
686 'type' => 'updated',
687 'dismissible' => false,
688 'description' => $desc_html,
689 ) );
690 }
691 }
692
693 /**
694 * Render Give Updates Completed page
695 *
696 * @since 1.8.12
697 * @access public
698 */
699 public function render_complete_page() {
700 include_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/views/upgrades-complete.php';
701 }
702
703 /**
704 * Render Give Updates page
705 *
706 * @since 1.8.12
707 * @access public
708 */
709 public function render_page() {
710 include_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/views/upgrades.php';
711 }
712
713 /**
714 * Run database upgrades
715 *
716 * @since 2.0
717 * @access private
718 */
719 private function run_db_update() {
720 // Bailout.
721 if ( $this->is_doing_updates() || ! $this->get_total_new_db_update_count() ) {
722 return;
723 }
724
725 $updates = $this->get_updates( 'database', 'new' );
726
727 foreach ( $updates as $update ) {
728 self::$background_updater->push_to_queue( $update );
729 }
730
731 add_option( 'give_db_update_count', count( $updates ), '', 'no' );
732
733 add_option( 'give_doing_upgrade', array(
734 'update_info' => $updates[0],
735 'step' => 1,
736 'update' => 1,
737 'heading' => sprintf( 'Update %s of %s', 1, count( $updates ) ),
738 'percentage' => 0,
739 'total_percentage' => 0,
740 ), '', 'no' );
741
742 self::$background_updater->save()->dispatch();
743 }
744
745
746 /**
747 * Delete resume updates
748 *
749 * @since 1.8.12
750 * @access public
751 */
752 public function __flush_resume_updates() {
753 //delete_option( 'give_doing_upgrade' );
754 update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ) );
755
756 // Reset counter.
757 $this->step = $this->percentage = 0;
758
759 $this->update = ( $this->get_total_db_update_count() > $this->update ) ?
760 ( $this->update + 1 ) :
761 $this->update;
762 }
763
764
765 /**
766 * Initialize updates
767 *
768 * @since 2.0
769 * @access public
770 *
771 * @return void
772 */
773 public function __give_start_updating() {
774 // Check permission.
775 if (
776 ! current_user_can( 'manage_give_settings' ) ||
777 $this->is_doing_updates()
778 ) {
779 wp_send_json_error();
780 }
781
782 // @todo: validate nonce
783 // @todo: set http method to post
784 if ( empty( $_POST['run_db_update'] ) ) {
785 wp_send_json_error();
786 }
787
788 $this->run_db_update();
789
790 wp_send_json_success();
791 }
792
793
794 /**
795 * This function handle ajax query for dn update status.
796 *
797 * @since 2.0
798 * @access public
799 *
800 * @return string
801 */
802 public function __give_db_updates_info() {
803 $update_info = get_option( 'give_doing_upgrade' );
804 $response_type = '';
805
806 if ( self::$background_updater->is_paused_process() ) {
807 $update_info = array(
808 'message' => __( 'The updates have been paused.', 'give' ),
809 'heading' => '',
810 'percentage' => 0,
811 );
812
813 if ( get_option( 'give_upgrade_error' ) ) {
814 $update_info['message'] = __( 'An unexpected issue occurred during the database update which caused it to stop automatically. Please contact support for assistance.', 'give' );
815 }
816
817 $response_type = 'error';
818
819 } elseif ( empty( $update_info ) || ! $this->get_total_new_db_update_count( true ) ) {
820 $update_info = array(
821 'message' => __( 'Give database updates completed successfully. Thank you for updating to the latest version!', 'give' ),
822 'heading' => __( 'Updates Completed.', 'give' ),
823 'percentage' => 0,
824 );
825 $response_type = 'success';
826
827 delete_option( 'give_show_db_upgrade_complete_notice' );
828 }
829
830 $this->send_ajax_response( $update_info, $response_type );
831 }
832
833 /**
834 * Send ajax response
835 *
836 * @since 1.8.12
837 * @access public
838 *
839 * @param $data
840 * @param string $type
841 */
842 public function send_ajax_response( $data, $type = '' ) {
843 $default = array(
844 'message' => '',
845 'heading' => '',
846 'percentage' => 0,
847 'step' => 0,
848 'update' => 0,
849 );
850
851 // Set data.
852 $data = wp_parse_args( $data, $default );
853
854 // Enable cache.
855 Give_Cache::enable();
856
857 switch ( $type ) {
858 case 'success':
859 wp_send_json_success( $data );
860 break;
861
862 case 'error':
863 wp_send_json_error( $data );
864 break;
865
866 default:
867 wp_send_json( array(
868 'data' => $data,
869 ) );
870 break;
871 }
872 }
873
874 /**
875 * Set current update percentage.
876 *
877 * @since 1.8.12
878 * @access public
879 *
880 * @param $total
881 * @param $current_total
882 */
883 public function set_percentage( $total, $current_total ) {
884 // Set percentage.
885 $this->percentage = $total ? ( ( $current_total ) / $total ) * 100 : 0;
886
887 // Verify percentage.
888 $this->percentage = ( 100 < $this->percentage ) ? 100 : $this->percentage;
889 }
890
891 /**
892 * Check if parent update completed or not.
893 *
894 * @since 2.0
895 * @access private
896 *
897 * @param array $update
898 *
899 * @return bool|null
900 */
901 public function is_parent_updates_completed( $update ) {
902 // Bailout.
903 if ( empty( $update['depend'] ) ) {
904 return true;
905 }
906
907 // Check if dependency is valid or not.
908 if ( ! $this->has_valid_dependency( $update ) ) {
909 return null;
910 }
911
912 $is_dependency_completed = true;
913
914 foreach ( $update['depend'] as $depend ) {
915
916 if ( ! give_has_upgrade_completed( $depend ) ) {
917 $is_dependency_completed = false;
918 break;
919 }
920 }
921
922 return $is_dependency_completed;
923 }
924
925 /**
926 * Flag to check if DB updates running or not.
927 *
928 * @since 2.0
929 * @access public
930 * @return bool
931 */
932 public function is_doing_updates() {
933 return (bool) get_option( 'give_doing_upgrade' );
934 }
935
936
937 /**
938 * Check if update has valid dependency or not.
939 *
940 * @since 2.0
941 * @access public
942 *
943 * @param $update
944 *
945 * @return bool
946 */
947 public function has_valid_dependency( $update ) {
948 $is_valid_dependency = true;
949 // $update_ids = wp_list_pluck( $this->get_updates( 'database', 'all' ), 'id' );
950 //
951 // foreach ( $update['depend'] as $depend ) {
952 // // Check if dependency is valid or not.
953 // if ( ! in_array( $depend, $update_ids ) ) {
954 // $is_valid_dependency = false;
955 // break;
956 // }
957 // }
958
959 return $is_valid_dependency;
960 }
961
962 /**
963 * Get updates.
964 *
965 * @since 1.8.12
966 * @access public
967 *
968 * @param string $update_type Tye of update.
969 * @param string $status Tye of update.
970 *
971 * @return array
972 */
973 public function get_updates( $update_type = '', $status = 'all' ) {
974 // return all updates.
975 if ( empty( $update_type ) ) {
976 return $this->updates;
977 }
978
979 // Get specific update.
980 $updates = ! empty( $this->updates[ $update_type ] ) ? $this->updates[ $update_type ] : array();
981
982 // Bailout.
983 if ( empty( $updates ) ) {
984 return $updates;
985 }
986
987 switch ( $status ) {
988 case 'new':
989 // Remove already completed updates.
990 wp_cache_delete( 'give_completed_upgrades', 'options' );
991 $completed_updates = give_get_completed_upgrades();
992
993 if ( ! empty( $completed_updates ) ) {
994 foreach ( $updates as $index => $update ) {
995 if ( in_array( $update['id'], $completed_updates ) ) {
996 unset( $updates[ $index ] );
997 }
998 }
999 $updates = array_values( $updates );
1000 }
1001
1002 break;
1003 }
1004
1005 return $updates;
1006 }
1007
1008 /**
1009 * Get addon update count.
1010 *
1011 * @since 1.8.12
1012 * @access public
1013 * @return int
1014 */
1015 public function get_total_plugin_update_count() {
1016 return count( $this->get_updates( 'plugin' ) );
1017 }
1018
1019 /**
1020 * Get total update count
1021 *
1022 * @since 1.8.12
1023 * @access public
1024 *
1025 * @return int
1026 */
1027 public function get_total_update_count() {
1028 $db_update_count = $this->get_pending_db_update_count();
1029 $plugin_update_count = $this->get_total_plugin_update_count();
1030
1031 return ( $db_update_count + $plugin_update_count );
1032 }
1033
1034 /**
1035 * Get total pending updates count
1036 *
1037 * @since 1.8.12
1038 * @access public
1039 *
1040 * @return int
1041 */
1042 public function get_pending_db_update_count() {
1043 return count( $this->get_updates( 'database', 'new' ) );
1044 }
1045
1046 /**
1047 * Get total updates count
1048 *
1049 * @since 1.8.18
1050 * @access public
1051 *
1052 * @return int
1053 */
1054 public function get_total_db_update_count() {
1055 return count( $this->get_updates( 'database', 'all' ) );
1056 }
1057
1058 /**
1059 * Get total new updates count
1060 *
1061 * @since 2.0
1062 * @access public
1063 *
1064 * @param bool $refresh
1065 *
1066 * @return int
1067 */
1068 public function get_total_new_db_update_count( $refresh = false ) {
1069 $update_count = $this->is_doing_updates() && ! $refresh ?
1070 get_option( 'give_db_update_count' ) :
1071 $this->get_pending_db_update_count();
1072
1073 return $update_count;
1074 }
1075
1076 /**
1077 * Get total new updates count
1078 *
1079 * @since 2.0
1080 * @access public
1081 *
1082 * @param bool $refresh
1083 *
1084 * @return int
1085 */
1086 public function get_running_db_update( $refresh = false ) {
1087 $current_update = 1;
1088
1089 if ( $this->is_doing_updates() && ! $refresh ) {
1090 $current_update = get_option( 'give_doing_upgrade' );
1091 $current_update = $current_update['update'];
1092 }
1093
1094 return $current_update;
1095 }
1096
1097 /**
1098 * Get database update processing percentage.
1099 *
1100 * @since 2.0
1101 * @access public
1102 *
1103 * @param bool $refresh
1104 *
1105 * @return float|int
1106 */
1107 public function get_db_update_processing_percentage( $refresh = false ) {
1108 // Bailout.
1109 if ( ! $this->get_total_new_db_update_count( $refresh ) ) {
1110 return 0;
1111 }
1112
1113 $resume_update = get_option( 'give_doing_upgrade' );
1114 $update_count_percentages = ( ( $this->get_running_db_update( $refresh ) - 1 ) / $this->get_total_new_db_update_count( $refresh ) ) * 100;
1115 $update_percentage_share = ( 1 / $this->get_total_new_db_update_count() ) * 100;
1116 $upgrade_percentage = ( ( $resume_update['percentage'] * $update_percentage_share ) / 100 );
1117
1118 $final_percentage = $update_count_percentages + $upgrade_percentage;
1119
1120 return $this->is_doing_updates() ?
1121 ( absint( $final_percentage ) ?
1122 absint( $final_percentage ) :
1123 round( $final_percentage, 2 )
1124 ) :
1125 0;
1126 }
1127
1128
1129 /**
1130 * Get all update ids.
1131 *
1132 * @since 2.0.3
1133 *
1134 * @return array
1135 */
1136 public function get_update_ids() {
1137 $all_updates = $this->get_updates( 'database', 'all' );
1138 $all_update_ids = wp_list_pluck( $all_updates, 'id' );
1139
1140 return $all_update_ids;
1141 }
1142
1143 /**
1144 * Get offset count
1145 *
1146 * @since 2.0.5
1147 * @access public
1148 *
1149 * @param int $process_item_count
1150 *
1151 * @return float|int
1152 */
1153 public function get_offset( $process_item_count ) {
1154 return ( 1 === $this->step ) ?
1155 0 :
1156 ( $this->step - 1 ) * $process_item_count;
1157 }
1158 }
1159
1160 Give_Updates::get_instance()->setup();
1161