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