PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 2.0.0
GiveWP – Donation Plugin and Fundraising Platform v2.0.0
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
794 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 static
24 * @var Give_Background_Updater
25 */
26 static private $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_notices', array( $this, '__show_notice' ) );
153
154 if ( is_admin() ) {
155 add_action( 'admin_init', array( $this, '__change_donations_label' ), 9999 );
156 add_action( 'admin_menu', array( $this, '__register_menu' ), 9999 );
157 }
158 }
159
160 /**
161 * Register plugin add-on updates.
162 *
163 * @since 1.8.12
164 * @access public
165 */
166 public function __register_plugin_addon_updates() {
167 $addons = give_get_plugins();
168 $plugin_updates = get_plugin_updates();
169
170 foreach ( $addons as $key => $info ) {
171 if ( 'active' != $info['Status'] || 'add-on' != $info['Type'] || empty( $plugin_updates[ $key ] ) ) {
172 continue;
173 }
174
175 $this->updates['plugin'][] = array_merge( $info, (array) $plugin_updates[ $key ] );
176 }
177 }
178
179
180 /**
181 * Fire custom action hook to register updates
182 *
183 * @since 1.8.12
184 * @access public
185 */
186 public function __register_upgrade() {
187 if ( ! is_admin() ) {
188 return;
189 }
190
191 /**
192 * Fire the hook
193 *
194 * @since 1.8.12
195 */
196 do_action( 'give_register_updates', $this );
197 }
198
199 /**
200 * Rename `Donations` menu title if updates exists
201 *
202 * @since 1.8.12
203 * @access public
204 */
205 function __change_donations_label() {
206 global $menu;
207
208 // Bailout.
209 if ( empty( $menu ) || ! $this->get_total_update_count() ) {
210 return;
211 }
212
213 foreach ( $menu as $index => $menu_item ) {
214 if ( 'edit.php?post_type=give_forms' !== $menu_item[2] ) {
215 continue;
216 }
217
218 $menu[ $index ][0] = sprintf(
219 '%1$s <span class="update-plugins"><span class="plugin-count give-update-progress-count">%2$s%3$s</span></span>',
220 __( 'Donations', 'give' ),
221 $this->is_doing_updates() ?
222 $this->get_db_update_processing_percentage() :
223 $this->get_total_update_count(),
224 $this->is_doing_updates() ? '%' : ''
225 );
226
227 break;
228 }
229 }
230
231 /**
232 * Register updates menu
233 *
234 * @since 1.8.12
235 * @access public
236 */
237 public function __register_menu() {
238 // Bailout.
239 if( ! give_test_ajax_works() ) {
240 return;
241 }
242
243 // Load plugin updates.
244 $this->__register_plugin_addon_updates();
245
246 // Bailout.
247 if ( ! $this->get_total_update_count() ) {
248 // Show complete update message if still on update setting page.
249 if ( isset( $_GET['page'] ) && 'give-updates' === $_GET['page'] ) {
250 // Upgrades
251 add_submenu_page(
252 'edit.php?post_type=give_forms',
253 esc_html__( 'Give Updates Complete', 'give' ),
254 __( 'Updates', 'give' ),
255 'manage_give_settings',
256 'give-updates',
257 array( $this, 'render_complete_page' )
258 );
259 }
260
261 return;
262 }
263
264 // Upgrades
265 add_submenu_page(
266 'edit.php?post_type=give_forms',
267 esc_html__( 'Give Updates', 'give' ),
268 sprintf(
269 '%1$s <span class="update-plugins"><span class="plugin-count give-update-progress-count">%2$s%3$s</span></span>',
270 __( 'Updates', 'give' ),
271 $this->is_doing_updates() ?
272 $this->get_db_update_processing_percentage() :
273 $this->get_total_update_count(),
274 $this->is_doing_updates() ? '%' : ''
275 ),
276 'manage_give_settings',
277 'give-updates',
278 array( $this, 'render_page' )
279 );
280 }
281
282
283 /**
284 * Show update related notices
285 *
286 * @since 2.0
287 * @access public
288 */
289 public function __redirect_admin() {
290 // Show db upgrade completed notice.
291 if (
292 ! wp_doing_ajax() &&
293 current_user_can( 'manage_give_settings' ) &&
294 get_option( 'give_show_db_upgrade_complete_notice' ) &&
295 ! isset( $_GET['give-db-update-completed'] )
296 ) {
297 delete_option( 'give_show_db_upgrade_complete_notice' );
298
299 wp_redirect( add_query_arg( array( 'give-db-update-completed' => 'give_db_upgrade_completed' ) ) );
300 exit();
301 }
302 }
303
304
305 /**
306 * Show update related notices
307 *
308 * @since 2.0
309 * @access public
310 */
311 public function __show_notice() {
312 // Bailout.
313 if ( ! current_user_can( 'manage_give_settings' ) || $this->is_doing_updates() ) {
314 return;
315 }
316
317 // Run DB updates.
318 if ( ! empty( $_GET['give-run-db-update'] ) ) {
319 $this->run_db_update();
320 }
321
322
323 // Bailout.
324 if ( isset( $_GET['page'] ) && 'give-updates' === $_GET['page'] ) {
325 return;
326 }
327
328 // Show notice if ajax is not working.
329 if ( ! give_test_ajax_works() ) {
330 Give()->notices->register_notice(
331 array(
332 'id' => 'give_db_upgrade_ajax_inaccessible',
333 'type' => 'error',
334 'description' => __( 'Give needs to upgrade the database but cannot because AJAX is not functioning properly. Please contact your host and ask them to ensure admin-ajax.php is accessible.', 'give' ),
335 'show' => true,
336 )
337 );
338
339 return;
340 }
341
342 // Show db upgrade completed notice.
343 if ( ! empty( $_GET['give-db-update-completed'] ) ) {
344 Give()->notices->register_notice( array(
345 'id' => 'give_db_upgrade_completed',
346 'type' => 'updated',
347 'description' => __( 'Give database updates completed successfully. Thank you for updating to the latest version!', 'give' ),
348 'show' => true,
349 ) );
350
351 // Start update.
352 } elseif ( ! empty( $_GET['give-run-db-update'] ) ) {
353 $this->run_db_update();
354
355 // Show run the update notice.
356 } elseif ( $this->get_total_new_db_update_count() ) {
357 ob_start();
358 ?>
359 <p>
360 <strong><?php _e( 'Database Update', 'give' ); ?></strong>
361 &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' ); ?>
362 </p>
363 <p class="submit">
364 <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">
365 <?php _e( 'Run the updater', 'woocommerce' ); ?>
366 </a>
367 </p>
368 <script type="text/javascript">
369 jQuery('.give-run-update-now').click('click', function () {
370 return window.confirm('<?php echo esc_js( __( 'It is strongly recommended that you backup your database before proceeding. Do you want to run the update now?', 'give' ) ); ?>'); // jshint ignore:line
371 });
372 </script>
373 <?php
374 $desc_html = ob_get_clean();
375
376
377 Give()->notices->register_notice( array(
378 'id' => 'give_upgrade_db',
379 'type' => 'updated',
380 'dismissible' => false,
381 'description' => $desc_html,
382 ) );
383 }
384 }
385
386 /**
387 * Render Give Updates Completed page
388 *
389 * @since 1.8.12
390 * @access public
391 */
392 public function render_complete_page() {
393 include_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/views/upgrades-complete.php';
394 }
395
396 /**
397 * Render Give Updates page
398 *
399 * @since 1.8.12
400 * @access public
401 */
402 public function render_page() {
403 include_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/views/upgrades.php';
404 }
405
406 /**
407 * Run database upgrades
408 *
409 * @since 2.0
410 * @access private
411 */
412 private function run_db_update() {
413 // Bailout.
414 if ( $this->is_doing_updates() || ! $this->get_total_new_db_update_count() ) {
415 return;
416 }
417
418 $updates = $this->get_updates( 'database', 'new' );
419
420 foreach ( $updates as $update ) {
421 self::$background_updater->push_to_queue( $update );
422 }
423
424 add_option( 'give_db_update_count', count( $updates ), '', 'no' );
425
426 add_option( 'give_doing_upgrade', array(
427 'update_info' => $updates[0],
428 'step' => 1,
429 'update' => 1,
430 'heading' => sprintf( 'Update %s of %s', 1, count( $updates ) ),
431 'percentage' => 0,
432 'total_percentage' => 0,
433 ), '', 'no' );
434
435 self::$background_updater->save()->dispatch();
436 }
437
438
439 /**
440 * Delete resume updates
441 *
442 * @since 1.8.12
443 * @access public
444 */
445 public function __flush_resume_updates() {
446 //delete_option( 'give_doing_upgrade' );
447 update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ) );
448
449 // Reset counter.
450 $this->step = $this->percentage = 0;
451 ++ $this->update;
452 }
453
454
455 /**
456 * Initialize updates
457 *
458 * @since 2.0
459 * @access public
460 *
461 * @return void
462 */
463 public function __give_start_updating() {
464 // Check permission.
465 if (
466 ! current_user_can( 'manage_give_settings' ) ||
467 $this->is_doing_updates()
468 ) {
469 wp_send_json_error();
470 }
471
472 // @todo: validate nonce
473 // @todo: set http method to post
474 if ( empty( $_POST['run_db_update'] ) ) {
475 wp_send_json_error();
476 }
477
478 $this->run_db_update();
479
480 wp_send_json_success();
481 }
482
483
484 /**
485 * This function handle ajax query for dn update status.
486 *
487 * @since 2.0
488 * @access public
489 *
490 * @return string
491 */
492 public function __give_db_updates_info() {
493 $update_info = get_option( 'give_doing_upgrade' );
494 $response_type = '';
495
496 if ( empty( $update_info ) && ! $this->get_pending_db_update_count() ) {
497 $update_info = array(
498 'message' => __( 'Give database updates completed successfully. Thank you for updating to the latest version!', 'give' ),
499 'heading' => __( 'Updates Completed.', 'give' ),
500 'percentage' => 0,
501 );
502 $response_type = 'success';
503
504 delete_option( 'give_show_db_upgrade_complete_notice' );
505 }
506
507 $this->send_ajax_response( $update_info, $response_type );
508 }
509
510 /**
511 * Send ajax response
512 *
513 * @since 1.8.12
514 * @access public
515 *
516 * @param $data
517 * @param string $type
518 */
519 public function send_ajax_response( $data, $type = '' ) {
520 $default = array(
521 'message' => '',
522 'heading' => '',
523 'percentage' => 0,
524 'step' => 0,
525 'update' => 0,
526 );
527
528 // Set data.
529 $data = wp_parse_args( $data, $default );
530
531 // Enable cache.
532 Give_Cache::enable();
533
534 switch ( $type ) {
535 case 'success':
536 wp_send_json_success( $data );
537 break;
538
539 case 'error':
540 wp_send_json_error( $data );
541 break;
542
543 default:
544 wp_send_json( array(
545 'data' => $data,
546 ) );
547 break;
548 }
549 }
550
551 /**
552 * Set current update percentage.
553 *
554 * @since 1.8.12
555 * @access public
556 *
557 * @param $total
558 * @param $current_total
559 */
560 public function set_percentage( $total, $current_total ) {
561 // Set percentage.
562 $this->percentage = $total ? ( ( $current_total ) / $total ) * 100 : 0;
563
564 // Verify percentage.
565 $this->percentage = ( 100 < $this->percentage ) ? 100 : $this->percentage;
566 }
567
568 /**
569 * Check if parent update completed or not.
570 *
571 * @since 2.0
572 * @access private
573 *
574 * @param array $update
575 *
576 * @return bool|null
577 */
578 public function is_parent_updates_completed( $update ) {
579 // Bailout.
580 if ( empty( $update['depend'] ) ) {
581 return true;
582 }
583
584 // Check if dependency is valid or not.
585 if ( ! $this->has_valid_dependency( $update ) ) {
586 return null;
587 }
588
589 $is_dependency_completed = true;
590
591 foreach ( $update['depend'] as $depend ) {
592
593 if ( ! give_has_upgrade_completed( $depend ) ) {
594 $is_dependency_completed = false;
595 break;
596 }
597 }
598
599 return $is_dependency_completed;
600 }
601
602 /**
603 * Flag to check if DB updates running or not.
604 *
605 * @since 2.0
606 * @access public
607 * @return bool
608 */
609 public function is_doing_updates() {
610 return (bool) get_option( 'give_doing_upgrade' );
611 }
612
613
614 /**
615 * Check if update has valid dependency or not.
616 *
617 * @since 2.0
618 * @access public
619 *
620 * @param $update
621 *
622 * @return bool
623 */
624 public function has_valid_dependency( $update ) {
625 $is_valid_dependency = true;
626 $update_ids = wp_list_pluck( $this->get_updates( 'database' ), 'id' );
627
628 foreach ( $update['depend'] as $depend ) {
629 // Check if dependency is valid or not.
630 if ( ! in_array( $depend, $update_ids ) ) {
631 $is_valid_dependency = false;
632 break;
633 }
634 }
635
636 return $is_valid_dependency;
637 }
638
639 /**
640 * Get updates.
641 *
642 * @since 1.8.12
643 * @access public
644 *
645 * @param string $update_type Tye of update.
646 * @param string $status Tye of update.
647 *
648 * @return array
649 */
650 public function get_updates( $update_type = '', $status = 'all' ) {
651 // return all updates.
652 if ( empty( $update_type ) ) {
653 return $this->updates;
654 }
655
656 // Get specific update.
657 $updates = ! empty( $this->updates[ $update_type ] ) ? $this->updates[ $update_type ] : array();
658
659 // Bailout.
660 if ( empty( $updates ) ) {
661 return $updates;
662 }
663
664 switch ( $status ) {
665 case 'new':
666 // Remove already completed updates.
667 $completed_updates = give_get_completed_upgrades();
668
669 if ( ! empty( $completed_updates ) ) {
670 foreach ( $updates as $index => $update ) {
671 if ( in_array( $update['id'], $completed_updates ) ) {
672 unset( $updates[ $index ] );
673 }
674 }
675 $updates = array_values( $updates );
676 }
677
678 break;
679 }
680
681 return $updates;
682 }
683
684 /**
685 * Get addon update count.
686 *
687 * @since 1.8.12
688 * @access public
689 * @return int
690 */
691 public function get_total_plugin_update_count() {
692 return count( $this->get_updates( 'plugin' ) );
693 }
694
695 /**
696 * Get total update count
697 *
698 * @since 1.8.12
699 * @access public
700 *
701 * @return int
702 */
703 public function get_total_update_count() {
704 $db_update_count = $this->get_pending_db_update_count();
705 $plugin_update_count = $this->get_total_plugin_update_count();
706
707 return ( $db_update_count + $plugin_update_count );
708 }
709
710 /**
711 * Get total pending updates count
712 *
713 * @since 1.8.12
714 * @access public
715 *
716 * @return int
717 */
718 public function get_pending_db_update_count() {
719 return count( $this->get_updates( 'database', 'new' ) );
720 }
721
722 /**
723 * Get total updates count
724 *
725 * @since 1.8.18
726 * @access public
727 *
728 * @return int
729 */
730 public function get_total_db_update_count() {
731 return count( $this->get_updates( 'database', 'all' ) );
732 }
733
734 /**
735 * Get total new updates count
736 *
737 * @since 2.0
738 * @access public
739 *
740 * @return int
741 */
742 public function get_total_new_db_update_count() {
743 return $this->is_doing_updates() ?
744 get_option( 'give_db_update_count' ) :
745 $this->get_pending_db_update_count();
746 }
747
748 /**
749 * Get total new updates count
750 *
751 * @since 2.0
752 * @access public
753 *
754 * @return int
755 */
756 public function get_running_db_update() {
757 $current_update = get_option( 'give_doing_upgrade' );
758
759 return $this->is_doing_updates() ?
760 $current_update['update'] :
761 1;
762 }
763
764 /**
765 * Get database update processing percentage.
766 *
767 * @since 2.0
768 * @access public
769 * @return float|int
770 */
771 public function get_db_update_processing_percentage() {
772 // Bailout.
773 if ( ! $this->get_total_new_db_update_count() ) {
774 return 0;
775 }
776
777 $resume_update = get_option( 'give_doing_upgrade' );
778 $update_count_percentages = ( ( $this->get_running_db_update() - 1 ) / $this->get_total_new_db_update_count() ) * 100;
779 $update_percentage_share = ( 1 / $this->get_total_new_db_update_count() ) * 100;
780 $upgrade_percentage = ( ( $resume_update['percentage'] * $update_percentage_share ) / 100 );
781
782 $final_percentage = $update_count_percentages + $upgrade_percentage;
783
784 return $this->is_doing_updates() ?
785 ( absint( $final_percentage ) ?
786 absint( $final_percentage ) :
787 round( $final_percentage, 2 )
788 ) :
789 0;
790 }
791 }
792
793 Give_Updates::get_instance()->setup();
794