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