Test Failed
Pull Request — master (#2814)
by Devin
05:29
created

Give_Updates::__health_background_update()   F

Complexity

Conditions 27
Paths 1601

Size

Total Lines 143
Code Lines 79

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 27
eloc 79
nc 1601
nop 1
dl 0
loc 143
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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