Give_Updates::is_doing_updates()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Class Give_Updates
5
 *
6
 * @since 1.8.12
7
 */
8
class Give_Updates {
0 ignored issues
show
Coding Style introduced by
Since you have declared the constructor as private, maybe you should also declare the class as final.
Loading history...
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() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
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() {
0 ignored issues
show
Coding Style introduced by
Method name "Give_Updates::__register_plugin_addon_updates" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
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() {
0 ignored issues
show
Coding Style introduced by
Method name "Give_Updates::__register_upgrade" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
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() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Coding Style introduced by
Method name "Give_Updates::__change_donations_label" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
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() {
0 ignored issues
show
Coding Style introduced by
Method name "Give_Updates::__register_menu" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
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'] ) {
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
250
				// Upgrades
251
				add_submenu_page(
252
					'edit.php?post_type=give_forms',
253
					esc_html__( 'Give Updates Complete', 'give' ),
254
					__( 'Updates', 'give' ),
255
					'manage_give_settings',
256
					'give-updates',
257
					array( $this, 'render_complete_page' )
258
				);
259
			}
260
261
			return;
262
		}
263
264
		$is_update = ( $this->is_doing_updates() && ! self::$background_updater->is_paused_process() );
265
266
		// Upgrades
267
		add_submenu_page(
268
			'edit.php?post_type=give_forms',
269
			esc_html__( 'Give Updates', 'give' ),
270
			sprintf(
271
				'%1$s <span class="update-plugins"%2$s><span class="plugin-count give-update-progress-count">%3$s%4$s</span></span>',
272
				__( 'Updates', 'give' ),
273
				isset( $_GET['give-pause-db-upgrades'] ) ? ' style="display:none;"' : '',
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
274
				$is_update ?
275
					$this->get_db_update_processing_percentage() :
276
					$this->get_total_update_count(),
277
				$is_update ? '%' : ''
278
			),
279
			'manage_give_settings',
280
			'give-updates',
281
			array( $this, 'render_page' )
282
		);
283
	}
284
285
286
	/**
287
	 * Show update related notices
288
	 *
289
	 * @since  2.0
290
	 * @access public
291
	 */
292
	public function __redirect_admin() {
0 ignored issues
show
Coding Style introduced by
Method name "Give_Updates::__redirect_admin" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
293
		// Show db upgrade completed notice.
294
		if (
295
			! wp_doing_ajax() &&
296
			current_user_can( 'manage_give_settings' ) &&
297
			get_option( 'give_show_db_upgrade_complete_notice' ) &&
298
			! isset( $_GET['give-db-update-completed'] )
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
299
		) {
300
			delete_option( 'give_show_db_upgrade_complete_notice' );
301
302
			wp_redirect( admin_url( 'edit.php?post_type=give_forms&page=give-updates&give-db-update-completed=give_db_upgrade_completed' ) );
303
			exit();
304
		}
305
	}
306
307
308
	/**
309
	 * Pause db upgrade
310
	 *
311
	 * @since  2.0.1
312
	 * @access public
313
	 *
314
	 * @param bool $force
315
	 *
316
	 * @return bool
317
	 */
318
	public function __pause_db_update( $force = false ) {
0 ignored issues
show
Coding Style introduced by
Method name "Give_Updates::__pause_db_update" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
319
		// Bailout.
320 View Code Duplication
		if (
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
321
			! $force &&
322
			(
323
				wp_doing_ajax() ||
324
				! isset( $_GET['page'] ) ||
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
325
				'give-updates' !== $_GET['page'] ||
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
326
				! isset( $_GET['give-pause-db-upgrades'] ) ||
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
327
				self::$background_updater->is_paused_process()
328
			)
329
330
		) {
331
			return false;
332
		}
333
334
		delete_option( 'give_upgrade_error' );
335
336
		$this->__health_background_update( $this );
337
		$batch = self::$background_updater->get_all_batch();
338
339
		// Bailout: if batch is empty
340
		if ( empty( $batch->data ) ) {
341
			return false;
342
		}
343
344
		// Remove cache.
345
		Give_Background_Updater::flush_cache();
346
347
		// Do not stop background process immediately if task running.
348
		// @see Give_Background_Updater::lock_process
349
		if ( ! $force && self::$background_updater->is_process_running() ) {
350
			update_option( 'give_pause_upgrade', 1, false );
351
352
			return true;
353
		}
354
355
		update_option( 'give_paused_batches', $batch, false );
356
		delete_option( $batch->key );
357
		delete_site_transient( self::$background_updater->get_identifier() . '_process_lock' );
358
		wp_clear_scheduled_hook( self::$background_updater->get_cron_identifier() );
359
360
		Give()->logs->add( 'Update Pause', print_r( $batch, true ), 0, 'update' );
0 ignored issues
show
introduced by
The use of function print_r() is discouraged
Loading history...
361
362
		/**
363
		 * Fire action when pause db updates
364
		 *
365
		 * @since 2.0.1
366
		 */
367
		do_action( 'give_pause_db_upgrade', $this );
368
369
		return true;
370
	}
371
372
	/**
373
	 * Restart db upgrade
374
	 *
375
	 * @since  2.0.1
376
	 * @access public
377
	 *
378
	 * @return bool
379
	 */
380
	public function __restart_db_update() {
0 ignored issues
show
Coding Style introduced by
Method name "Give_Updates::__restart_db_update" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
381
		// Bailout.
382 View Code Duplication
		if (
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
383
			wp_doing_ajax() ||
384
			! isset( $_GET['page'] ) ||
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
385
			'give-updates' !== $_GET['page'] ||
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
386
			! isset( $_GET['give-restart-db-upgrades'] ) ||
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
387
			! self::$background_updater->is_paused_process()
388
		) {
389
			return false;
390
		}
391
392
		Give_Background_Updater::flush_cache();
393
		$batch = get_option( 'give_paused_batches' );
394
395
		if ( ! empty( $batch ) ) {
396
			wp_cache_delete( $batch->key, 'options' );
397
			update_option( $batch->key, $batch->data, false );
398
399
			delete_option( 'give_paused_batches' );
400
401
			Give()->logs->add( 'Update Restart', print_r( $batch, true ), 0, 'update' );
0 ignored issues
show
introduced by
The use of function print_r() is discouraged
Loading history...
402
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
403
404
			/** Fire action when restart db updates
405
			 *
406
			 * @since 2.0.1
407
			 */
408
			do_action( 'give_restart_db_upgrade', $this );
409
410
			self::$background_updater->dispatch();
411
		}
412
413
		return true;
414
	}
415
416
	/**
417
	 * Health check for updates.
418
	 *
419
	 * @since  2.0
420
	 * @access public
421
	 *
422
	 * @param Give_Updates $give_updates
423
	 */
424
	public function __health_background_update( $give_updates ) {
0 ignored issues
show
Coding Style introduced by
Method name "Give_Updates::__health_background_update" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
425
		if ( ! $this->is_doing_updates() ) {
426
			return;
427
		}
428
429
		Give_Background_Updater::flush_cache();
430
431
		$batch                = Give_Updates::$background_updater->get_all_batch();
432
		$batch_data_count     = count( $batch->data );
433
		$all_updates          = $give_updates->get_updates( 'database', 'all' );
434
		$all_update_ids       = wp_list_pluck( $all_updates, 'id' );
435
		$all_batch_update_ids = ! empty( $batch->data ) ? wp_list_pluck( $batch->data, 'id' ) : array();
436
		$log_data             = '';
437
		$doing_upgrade_args   = get_option( 'give_doing_upgrade' );
438
439
		if ( ! empty( $doing_upgrade_args ) ) {
440
			$log_data .= 'Doing update:' . "\n";
441
			$log_data .= print_r( $doing_upgrade_args, true ) . "\n";
0 ignored issues
show
introduced by
The use of function print_r() is discouraged
Loading history...
442
		}
443
444
		/**
445
		 * Add remove upgrade from batch
446
		 */
447
		if ( ! empty( $batch->data ) ) {
448
449
			foreach ( $batch->data as $index => $update ) {
450
				$log_data = print_r( $update, true ) . "\n";
0 ignored issues
show
introduced by
The use of function print_r() is discouraged
Loading history...
451
452
				if ( ! is_callable( $update['callback'] ) ) {
453
					$log_data .= 'Removing missing callback update: ' . "{$update['id']}\n";
454
					unset( $batch->data[ $index ] );
455
				} elseif ( give_has_upgrade_completed( $update['id'] ) ) {
456
					$log_data .= 'Removing already completed update: ' . "{$update['id']}\n";
457
					unset( $batch->data[ $index ] );
458
				}
459
460
				if ( ! empty( $update['depend'] ) ) {
461
462
					foreach ( $update['depend'] as $depend ) {
463
						if ( give_has_upgrade_completed( $depend ) ) {
464
							$log_data .= 'Completed update: ' . "{$depend}\n";
465
							continue;
466
						}
467
468
						if ( in_array( $depend, $all_update_ids ) && ! in_array( $depend, $all_batch_update_ids ) ) {
469
							$log_data .= 'Adding missing update: ' . "{$depend}\n";
470
							array_unshift( $batch->data, $all_updates[ array_search( $depend, $all_update_ids ) ] );
471
						}
472
					}
473
				}
474
			}
475
		}
476
477
		/**
478
		 * Add new upgrade to batch
479
		 */
480
		if ( $new_updates = $this->get_updates( 'database', 'new' ) ) {
481
			$all_batch_update_ids = ! empty( $batch->data ) ? wp_list_pluck( $batch->data, 'id' ) : array();
482
483
			foreach ( $new_updates as $index => $new_update ) {
484
				if ( give_has_upgrade_completed( $new_update['id'] ) || in_array( $new_update['id'], $all_batch_update_ids ) ) {
485
					unset( $new_updates[ $index ] );
486
				}
487
			}
488
489
			if ( ! empty( $new_updates ) ) {
490
				$log_data .= 'Adding new update: ' . "\n";
491
				$log_data .= print_r( $new_updates, true ) . "\n";
0 ignored issues
show
introduced by
The use of function print_r() is discouraged
Loading history...
492
493
				$batch->data = array_merge( (array) $batch->data, $new_updates );
494
				update_option( 'give_db_update_count', ( absint( get_option( 'give_db_update_count' ) ) + count( $new_updates ) ), false );
495
			}
496
		}
497
498
		/**
499
		 * Fix batch
500
		 */
501
		if ( empty( $batch->data ) ) {
502
			// Complete batch if do not have any data to process.
503
			self::$background_updater->delete( $batch->key );
504
505
			if ( self::$background_updater->has_queue() ) {
506
				$this->__health_background_update( $this );
507
			} else {
508
				delete_site_transient( self::$background_updater->get_identifier() . '_process_lock' );
509
				wp_clear_scheduled_hook( self::$background_updater->get_cron_identifier() );
510
511
				self::$background_updater->complete();
512
			}
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
513
514
		} elseif ( $batch_data_count !== count( $batch->data ) ) {
515
516
			$log_data .= 'Updating batch' . "\n";
517
			$log_data .= print_r( $batch, true );
0 ignored issues
show
introduced by
The use of function print_r() is discouraged
Loading history...
518
519
			if ( ! empty( $batch->key ) ) {
520
				wp_cache_delete( $batch->key, 'options' );
521
				update_option( $batch->key, $batch->data, false );
522
			} else {
523
524
				foreach ( $batch->data as $data ) {
525
					Give_Updates::$background_updater->push_to_queue( $data );
526
				}
527
528
				Give_Updates::$background_updater->save();
529
			}
530
		}
531
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
532
533
		/**
534
		 * Fix give_doing_upgrade option
535
		 */
536
		if( $fresh_new_db_count = $this->get_total_new_db_update_count( true ) ) {
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
537
			update_option( 'give_db_update_count', $fresh_new_db_count, false );
538
		}
539
540
		$doing_upgrade_args['update']           = 1;
541
		$doing_upgrade_args['heading']          = sprintf( 'Update %s of %s', 1, $fresh_new_db_count );
542
		$doing_upgrade_args['total_percentage'] = $this->get_db_update_processing_percentage( true );
543
544
		// Remove already completed update from info.
545
		if (
546
			empty( $doing_upgrade_args['update_info'] )
547
			|| give_has_upgrade_completed( $doing_upgrade_args['update_info']['id'] )
548
		) {
549
			$doing_upgrade_args['update_info'] = current( array_values( $batch->data ) );
550
			$doing_upgrade_args['step']        = 1;
551
		}
552
553
		// Check if dependency completed or not.
554
		if ( isset( $doing_upgrade_args['update_info']['depend'] ) ) {
555
			foreach ( $doing_upgrade_args['update_info']['depend'] as $depend ) {
556
				if ( give_has_upgrade_completed( $depend ) ) {
557
					continue;
558
				}
559
560
				$doing_upgrade_args['update_info']      = $all_updates[ array_search( $depend, $all_update_ids ) ];
561
				$doing_upgrade_args['step']             = 1;
562
				$doing_upgrade_args['percentage']       = 0;
563
				$doing_upgrade_args['total_percentage'] = 0;
564
565
				break;
566
			}
567
		}
568
569
		if( ! empty( $doing_upgrade_args['update_info'] ) ) {
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
570
			update_option( 'give_doing_upgrade', $doing_upgrade_args, false );
571
572
			$log_data .= 'Updated doing update:' . "\n";
573
			$log_data .= print_r( $doing_upgrade_args, true ) . "\n";
0 ignored issues
show
introduced by
The use of function print_r() is discouraged
Loading history...
574
		}
575
576
		Give()->logs->add( 'Update Health Check', $log_data, 0, 'update' );
577
	}
578
579
580
	/**
581
	 * Show update related notices
582
	 *
583
	 * @since  2.0
584
	 * @access public
585
	 */
586
	public function __show_notice() {
0 ignored issues
show
Coding Style introduced by
Method name "Give_Updates::__show_notice" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
587
		$current_screen = get_current_screen();
588
589
		// Bailout.
590
		if ( ! current_user_can( 'manage_give_settings' ) ) {
591
			return;
592
		}
593
594
		// Run DB updates.
595
		if ( ! empty( $_GET['give-run-db-update'] ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
596
			$this->run_db_update();
597
		}
598
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
599
600
		// Bailout.
601
		if ( in_array( $current_screen->base, array( 'give_forms_page_give-updates', 'update-core' ) ) ) {
602
			return;
603
		}
604
605
		// Show notice if upgrade paused.
606
		if ( self::$background_updater->is_paused_process() ) {
607
			ob_start();
608
609
			$upgrade_error = get_option( 'give_upgrade_error' );
610
			if ( ! $upgrade_error ) : ?>
611
				<strong><?php _e( 'Database Update', 'give' ); ?></strong>
612
				&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' ); ?>
613
				<br>
614
				<br>
615
				<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">
616
					<?php _e( 'Restart the updater', 'give' ); ?>
617
				</a>
618
			<?php else: ?>
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
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
				<a href="<?php echo esc_url('http://docs.givewp.com/troubleshooting-db-updates')?>" target="_blank"><?php _e( 'Read More', 'give' ); ?> &raquo;</a>
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
622
			<?php
623
			endif;
624
			$desc_html = ob_get_clean();
625
626
			Give()->notices->register_notice( array(
627
				'id'          => 'give_upgrade_db',
628
				'type'        => 'error',
629
				'dismissible' => false,
630
				'description' => $desc_html,
631
			) );
632
		}
633
634
		// Bailout if doing upgrades.
635
		if ( $this->is_doing_updates() ) {
636
			return;
637
		}
638
639
		// Show db upgrade completed notice.
640
		if ( ! empty( $_GET['give-db-update-completed'] ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
641
			Give()->notices->register_notice( array(
642
				'id'          => 'give_db_upgrade_completed',
643
				'type'        => 'updated',
644
				'description' => __( 'Give database updates completed successfully. Thank you for updating to the latest version!', 'give' ),
645
				'show'        => true,
646
			) );
647
648
			// Start update.
649
		} elseif ( ! empty( $_GET['give-run-db-update'] ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
650
			$this->run_db_update();
651
652
			// Show run the update notice.
653
		} elseif ( $this->get_total_new_db_update_count() ) {
654
			ob_start();
655
			?>
656
			<p>
657
				<strong><?php _e( 'Database Update', 'give' ); ?></strong>
658
				&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' ); ?>
659
			</p>
660
			<p class="submit">
661
				<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">
662
					<?php _e( 'Run the updater', 'give' ); ?>
663
				</a>
664
			</p>
665
			<?php
666
			$desc_html = ob_get_clean();
667
668
			Give()->notices->register_notice( array(
669
				'id'          => 'give_upgrade_db',
670
				'type'        => 'updated',
671
				'dismissible' => false,
672
				'description' => $desc_html,
673
			) );
674
		}
675
	}
676
677
	/**
678
	 * Render Give Updates Completed page
679
	 *
680
	 * @since  1.8.12
681
	 * @access public
682
	 */
683
	public function render_complete_page() {
684
		include_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/views/upgrades-complete.php';
685
	}
686
687
	/**
688
	 * Render Give Updates page
689
	 *
690
	 * @since  1.8.12
691
	 * @access public
692
	 */
693
	public function render_page() {
694
		include_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/views/upgrades.php';
695
	}
696
697
	/**
698
	 * Run database upgrades
699
	 *
700
	 * @since  2.0
701
	 * @access private
702
	 */
703
	private function run_db_update() {
704
		// Bailout.
705
		if ( $this->is_doing_updates() || ! $this->get_total_new_db_update_count() ) {
706
			return;
707
		}
708
709
		$updates = $this->get_updates( 'database', 'new' );
710
711
		foreach ( $updates as $update ) {
712
			self::$background_updater->push_to_queue( $update );
713
		}
714
715
		add_option( 'give_db_update_count', count( $updates ), '', false );
716
717
		add_option( 'give_doing_upgrade', array(
718
			'update_info'      => $updates[0],
719
			'step'             => 1,
720
			'update'           => 1,
721
			'heading'          => sprintf( 'Update %s of %s', 1, count( $updates ) ),
722
			'percentage'       => 0,
723
			'total_percentage' => 0,
724
		), '', false );
725
726
		self::$background_updater->save()->dispatch();
727
	}
728
729
730
	/**
731
	 * Delete resume updates
732
	 *
733
	 * @since  1.8.12
734
	 * @access public
735
	 */
736
	public function __flush_resume_updates() {
0 ignored issues
show
Coding Style introduced by
Method name "Give_Updates::__flush_resume_updates" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
737
		//delete_option( 'give_doing_upgrade' );
738
		update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ), false );
739
740
		// Reset counter.
741
		$this->step = $this->percentage = 0;
0 ignored issues
show
Documentation Bug introduced by
It seems like 0 of type integer is incompatible with the declared type array of property $percentage.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
Documentation Bug introduced by
It seems like $this->percentage = 0 of type integer is incompatible with the declared type array of property $step.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
742
743
		$this->update = ( $this->get_total_db_update_count() > $this->update ) ?
744
			( $this->update + 1 ) :
745
			$this->update;
746
	}
747
748
749
	/**
750
	 * Initialize updates
751
	 *
752
	 * @since  2.0
753
	 * @access public
754
	 *
755
	 * @return void
756
	 */
757
	public function __give_start_updating() {
0 ignored issues
show
Coding Style introduced by
Method name "Give_Updates::__give_start_updating" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
758
		// Check permission.
759
		if (
760
			! current_user_can( 'manage_give_settings' ) ||
761
			$this->is_doing_updates()
762
		) {
763
			// Run update via ajax
764
			self::$background_updater->dispatch();
765
766
			wp_send_json_error();
767
		}
768
769
		// @todo: validate nonce
770
		// @todo: set http method to post
771
		if ( empty( $_POST['run_db_update'] ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
772
			wp_send_json_error();
773
		}
774
775
		$this->run_db_update();
776
777
		wp_send_json_success();
778
	}
779
780
781
	/**
782
	 * This function handle ajax query for dn update status.
783
	 *
784
	 * @since  2.0
785
	 * @access public
786
	 *
787
	 * @return string
788
	 */
789
	public function __give_db_updates_info() {
0 ignored issues
show
Coding Style introduced by
Method name "Give_Updates::__give_db_updates_info" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
790
		$update_info   = get_option( 'give_doing_upgrade' );
791
		$response_type = '';
792
793
		if ( self::$background_updater->is_paused_process() ) {
794
			$update_info = array(
795
				'message'    => __( 'The updates have been paused.', 'give' ),
796
				'heading'    => '',
797
				'percentage' => 0,
798
			);
799
800
			if ( get_option( 'give_upgrade_error' ) ) {
801
				$update_info['message'] = __( 'An unexpected issue occurred during the database update which caused it to stop automatically. Please contact support for assistance.', 'give' );
802
			}
803
804
			$response_type = 'error';
805
806
		} elseif ( empty( $update_info ) || ! $this->get_total_new_db_update_count( true ) ) {
807
			$update_info   = array(
808
				'message'    => __( 'Give database updates completed successfully. Thank you for updating to the latest version!', 'give' ),
809
				'heading'    => __( 'Updates Completed.', 'give' ),
810
				'percentage' => 0,
811
			);
812
			$response_type = 'success';
813
814
			delete_option( 'give_show_db_upgrade_complete_notice' );
815
		}
816
817
		$this->send_ajax_response( $update_info, $response_type );
818
	}
819
820
	/**
821
	 * Send ajax response
822
	 *
823
	 * @since  1.8.12
824
	 * @access public
825
	 *
826
	 * @param        $data
827
	 * @param string $type
828
	 */
829
	public function send_ajax_response( $data, $type = '' ) {
830
		$default = array(
831
			'message'    => '',
832
			'heading'    => '',
833
			'percentage' => 0,
834
			'step'       => 0,
835
			'update'     => 0,
836
		);
837
838
		// Set data.
839
		$data = wp_parse_args( $data, $default );
840
841
		// Enable cache.
842
		Give_Cache::enable();
843
844
		switch ( $type ) {
845
			case 'success':
846
				wp_send_json_success( $data );
847
				break;
848
849
			case 'error':
850
				wp_send_json_error( $data );
851
				break;
852
853
			default:
854
				wp_send_json( array(
855
					'data' => $data,
856
				) );
857
				break;
858
		}
859
	}
860
861
	/**
862
	 * Set current update percentage.
863
	 *
864
	 * @since  1.8.12
865
	 * @access public
866
	 *
867
	 * @param $total
868
	 * @param $current_total
869
	 */
870
	public function set_percentage( $total, $current_total ) {
871
		// Set percentage.
872
		$this->percentage = $total ? ( ( $current_total ) / $total ) * 100 : 0;
0 ignored issues
show
Documentation Bug introduced by
It seems like $total ? $current_total / $total * 100 : 0 of type integer or double is incompatible with the declared type array of property $percentage.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
873
874
		// Verify percentage.
875
		$this->percentage = ( 100 < $this->percentage ) ? 100 : $this->percentage;
0 ignored issues
show
Documentation Bug introduced by
It seems like 100 < $this->percentage ? 100 : $this->percentage of type integer or double is incompatible with the declared type array of property $percentage.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
876
	}
877
878
	/**
879
	 * Check if parent update completed or not.
880
	 *
881
	 * @since  2.0
882
	 * @access private
883
	 *
884
	 * @param array $update
885
	 *
886
	 * @return bool|null
887
	 */
888
	public function is_parent_updates_completed( $update ) {
889
		// Bailout.
890
		if ( empty( $update['depend'] ) ) {
891
			return true;
892
		}
893
894
		// Check if dependency is valid or not.
895
		if ( ! $this->has_valid_dependency( $update ) ) {
896
			return null;
897
		}
898
899
		$is_dependency_completed = true;
900
901
		foreach ( $update['depend'] as $depend ) {
902
903
			if ( ! give_has_upgrade_completed( $depend ) ) {
904
				$is_dependency_completed = false;
905
				break;
906
			}
907
		}
908
909
		return $is_dependency_completed;
910
	}
911
912
	/**
913
	 * Flag to check if DB updates running or not.
914
	 *
915
	 * @since  2.0
916
	 * @access public
917
	 * @return bool
918
	 */
919
	public function is_doing_updates() {
920
		return (bool) get_option( 'give_doing_upgrade' );
921
	}
922
923
924
	/**
925
	 * Check if update has valid dependency or not.
926
	 *
927
	 * @since  2.0
928
	 * @access public
929
	 *
930
	 * @param $update
931
	 *
932
	 * @return bool
933
	 */
934
	public function has_valid_dependency( $update ) {
0 ignored issues
show
Unused Code introduced by
The parameter $update is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
935
		$is_valid_dependency = true;
936
		// $update_ids          = wp_list_pluck( $this->get_updates( 'database', 'all' ), 'id' );
937
		//
938
		// foreach ( $update['depend'] as $depend ) {
939
		// 	// Check if dependency is valid or not.
940
		// 	if ( ! in_array( $depend, $update_ids ) ) {
941
		// 		$is_valid_dependency = false;
942
		// 		break;
943
		// 	}
944
		// }
945
946
		return $is_valid_dependency;
947
	}
948
949
	/**
950
	 * Get updates.
951
	 *
952
	 * @since  1.8.12
953
	 * @access public
954
	 *
955
	 * @param string $update_type Tye of update.
956
	 * @param string $status      Tye of update.
957
	 *
958
	 * @return array
959
	 */
960
	public function get_updates( $update_type = '', $status = 'all' ) {
961
		// return all updates.
962
		if ( empty( $update_type ) ) {
963
			return $this->updates;
964
		}
965
966
		// Get specific update.
967
		$updates = ! empty( $this->updates[ $update_type ] ) ? $this->updates[ $update_type ] : array();
968
969
		// Bailout.
970
		if ( empty( $updates ) ) {
971
			return $updates;
972
		}
973
974
		switch ( $status ) {
975
			case 'new':
976
				// Remove already completed updates.
977
				wp_cache_delete( 'give_completed_upgrades', 'options' );
978
				$completed_updates = give_get_completed_upgrades();
979
980
				if ( ! empty( $completed_updates ) ) {
981
					foreach ( $updates as $index => $update ) {
982
						if ( in_array( $update['id'], $completed_updates ) ) {
983
							unset( $updates[ $index ] );
984
						}
985
					}
986
					$updates = array_values( $updates );
987
				}
988
989
				break;
990
		}
991
992
		return $updates;
993
	}
994
995
	/**
996
	 * Get addon update count.
997
	 *
998
	 * @since  1.8.12
999
	 * @access public
1000
	 * @return int
1001
	 */
1002
	public function get_total_plugin_update_count() {
1003
		return count( $this->get_updates( 'plugin' ) );
1004
	}
1005
1006
	/**
1007
	 * Get total update count
1008
	 *
1009
	 * @since  1.8.12
1010
	 * @access public
1011
	 *
1012
	 * @return int
1013
	 */
1014
	public function get_total_update_count() {
1015
		$db_update_count     = $this->get_pending_db_update_count();
1016
		$plugin_update_count = $this->get_total_plugin_update_count();
1017
1018
		return ( $db_update_count + $plugin_update_count );
1019
	}
1020
1021
	/**
1022
	 * Get total pending updates count
1023
	 *
1024
	 * @since  1.8.12
1025
	 * @access public
1026
	 *
1027
	 * @return int
1028
	 */
1029
	public function get_pending_db_update_count() {
1030
		return count( $this->get_updates( 'database', 'new' ) );
1031
	}
1032
1033
	/**
1034
	 * Get total updates count
1035
	 *
1036
	 * @since  1.8.18
1037
	 * @access public
1038
	 *
1039
	 * @return int
1040
	 */
1041
	public function get_total_db_update_count() {
1042
		return count( $this->get_updates( 'database', 'all' ) );
1043
	}
1044
1045
	/**
1046
	 * Get total new updates count
1047
	 *
1048
	 * @since  2.0
1049
	 * @access public
1050
	 *
1051
	 * @param bool $refresh
1052
	 *
1053
	 * @return int
1054
	 */
1055
	public function get_total_new_db_update_count( $refresh = false ) {
1056
		$update_count = $this->is_doing_updates() && ! $refresh ?
1057
			get_option( 'give_db_update_count' ) :
1058
			$this->get_pending_db_update_count();
1059
1060
		return $update_count;
1061
	}
1062
1063
	/**
1064
	 * Get total new updates count
1065
	 *
1066
	 * @since  2.0
1067
	 * @access public
1068
	 *
1069
	 * @param bool $refresh
1070
	 *
1071
	 * @return int
1072
	 */
1073
	public function get_running_db_update( $refresh = false ) {
1074
		$current_update = 1;
1075
1076
		if ( $this->is_doing_updates() && ! $refresh ) {
1077
			$current_update = get_option( 'give_doing_upgrade' );
1078
			$current_update = $current_update['update'];
1079
		}
1080
1081
		return $current_update;
1082
	}
1083
1084
	/**
1085
	 * Get database update processing percentage.
1086
	 *
1087
	 * @since  2.0
1088
	 * @access public
1089
	 *
1090
	 * @param bool $refresh
1091
	 *
1092
	 * @return float|int
1093
	 */
1094
	public function get_db_update_processing_percentage( $refresh = false ) {
1095
		// Bailout.
1096
		if ( ! $this->get_total_new_db_update_count( $refresh ) ) {
1097
			return 0;
1098
		}
1099
1100
		$resume_update            = get_option( 'give_doing_upgrade' );
1101
		$update_count_percentages = ( ( $this->get_running_db_update( $refresh ) - 1 ) / $this->get_total_new_db_update_count( $refresh ) ) * 100;
1102
		$update_percentage_share  = ( 1 / $this->get_total_new_db_update_count() ) * 100;
1103
		$upgrade_percentage       = ( ( $resume_update['percentage'] * $update_percentage_share ) / 100 );
1104
1105
		$final_percentage = $update_count_percentages + $upgrade_percentage;
1106
1107
		return $this->is_doing_updates() ?
1108
			( absint( $final_percentage ) ?
1109
				absint( $final_percentage ) :
1110
				round( $final_percentage, 2 )
1111
			) :
1112
			0;
1113
	}
1114
1115
1116
	/**
1117
	 * Get all update ids.
1118
	 *
1119
	 * @since 2.0.3
1120
	 *
1121
	 * @return array
1122
	 */
1123
	public function get_update_ids() {
1124
		$all_updates    = $this->get_updates( 'database', 'all' );
1125
		$all_update_ids = wp_list_pluck( $all_updates, 'id' );
1126
1127
		return $all_update_ids;
1128
	}
1129
1130
	/**
1131
	 * Get offset count
1132
	 *
1133
	 * @since  2.0.5
1134
	 * @access public
1135
	 *
1136
	 * @param int $process_item_count
1137
	 *
1138
	 * @return float|int
1139
	 */
1140
	public function get_offset( $process_item_count ) {
1141
		return ( 1 === $this->step ) ?
1142
			0 :
1143
			( $this->step - 1 ) * $process_item_count;
1144
	}
1145
}
1146
1147
Give_Updates::get_instance()->setup();
1148