Test Failed
Push — feature/update-process ( bd4647 )
by Ravinder
04:45
created

Give_Updates::__health_background_update()   C

Complexity

Conditions 17
Paths 40

Size

Total Lines 62
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 17
eloc 36
nc 40
nop 1
dl 0
loc 62
rs 6.1162
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() ) {
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...
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
	 * @return bool
320
	 */
321 View Code Duplication
	public function __pause_db_update() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
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...
322
		// Bailout.
323
		if (
324
			wp_doing_ajax() ||
325
			! isset( $_GET['page'] ) ||
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
326
			'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...
327
			! 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...
328
			self::$background_updater->is_paused_process()
329
		) {
330
			return false;
331
		}
332
333
		$batch = self::$background_updater->get_all_batch();
334
335
		if ( ! empty( $batch ) ) {
336
			update_option( 'give_paused_batches', $batch,  'no' );
337
			delete_option( $batch->key );
338
			delete_site_transient( self::$background_updater->get_identifier() . '_process_lock' );
339
340
			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...
341
342
			/**
343
			 * Fire action when pause db updates
344
			 *
345
			 * @since 2.0.1
346
			 */
347
			do_action( 'give_pause_db_upgrade', $this );
348
		}
349
350
		return true;
351
	}
352
353
	/**
354
	 * Restart db upgrade
355
	 *
356
	 * @since  2.0.1
357
	 * @access public
358
	 *
359
	 * @return bool
360
	 */
361 View Code Duplication
	public function __restart_db_update() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
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...
362
		// Bailout.
363
		if (
364
			wp_doing_ajax() ||
365
			! isset( $_GET['page'] ) ||
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
366
			'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...
367
			! 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...
368
			! self::$background_updater->is_paused_process()
369
		) {
370
			return false;
371
		}
372
373
		$batch = get_option( 'give_paused_batches' );
374
375
		if ( ! empty( $batch ) ) {
376
			update_option( $batch->key, $batch->data );
377
			delete_option( 'give_paused_batches' );
378
379
			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...
380
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
381
382
			/** Fire action when restart db updates
383
			 *
384
			 * @since 2.0.1
385
			 */
386
			do_action( 'give_restart_db_upgrade', $this );
387
388
			self::$background_updater->dispatch();
389
		}
390
391
		return true;
392
	}
393
394
	/**
395
	 * Health check for updates.
396
	 *
397
	 * @since  2.0
398
	 * @access public
399
	 *
400
	 * @param Give_Updates $give_updates
401
	 */
402
	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...
403
		$batch                = Give_Updates::$background_updater->get_all_batch();
404
		$batch_data_count     = count( $batch->data );
405
		$all_updates          = $give_updates->get_updates( 'database', 'all' );
406
		$all_update_ids       = wp_list_pluck( $all_updates, 'id' );
407
		$all_batch_update_ids = ! empty( $batch ) ? wp_list_pluck( $batch->data, 'id' ) : array();
408
		$log_data             = '';
409
410
		if ( ! empty( $batch ) ) {
411
412
			foreach ( $batch->data as $index => $update ) {
413
				$log_data = print_r( $update, true ) . "\n";
0 ignored issues
show
introduced by
The use of function print_r() is discouraged
Loading history...
414
415
				if ( ! is_callable( $update['callback'] ) ) {
416
					$log_data .= 'Removing missing callback update: ' . "{$update['id']}\n";
417
					unset( $batch->data[ $index ] );
418
				}
419
420
				if ( ! empty( $update['depend'] ) ) {
421
422
					foreach ( $update['depend'] as $depend ) {
423
						if ( give_has_upgrade_completed( $depend ) ) {
424
							$log_data .= 'Completed update: ' . "{$depend}\n";
425
							continue;
426
						}
427
428
						if ( in_array( $depend, $all_update_ids ) && ! in_array( $depend, $all_batch_update_ids ) ) {
429
							$log_data .= 'Adding missing update: ' . "{$depend}\n";
430
							array_unshift( $batch->data, $all_updates[ array_search( $depend, $all_update_ids ) ] );
431
						}
432
					}
433
				}
434
			}
435
		}
436
		
437
		if( $new_updates = $this->get_updates( 'database', 'new' ) ){
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...
438
			$all_batch_update_ids = ! empty( $batch ) ? wp_list_pluck( $batch->data, 'id' ) : array();
439
440
			foreach ( $new_updates as $index => $new_update ) {
441
				if( give_has_upgrade_completed( $new_update['id'] ) || in_array( $new_update['id'], $all_batch_update_ids ) ) {
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...
442
					unset( $new_updates[$index] );
0 ignored issues
show
introduced by
Array keys should be surrounded by spaces unless they contain a string or an integer.
Loading history...
443
				}
444
			}
445
446
			if( ! empty( $new_updates ) ) {
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...
447
				$log_data .= 'Adding new update: ' . "\n";
448
				$log_data .= print_r( $new_updates, true ) . "\n";
0 ignored issues
show
introduced by
The use of function print_r() is discouraged
Loading history...
449
450
				$batch->data = array_merge( $batch->data, $new_updates );
451
				update_option( 'give_db_update_count',  ( absint( get_option( 'give_db_update_count' ) ) + count( $new_updates ) ) );
452
			}
453
		}
454
455
		if ( $batch_data_count !== count( $batch->data ) ) {
456
			$log_data .= 'Updating batch' . "\n";
457
			$log_data .= print_r( $batch, true );
0 ignored issues
show
introduced by
The use of function print_r() is discouraged
Loading history...
458
459
			update_option( $batch->key, $batch->data );
460
461
			Give()->logs->add( 'Update Health Check', $log_data, 0, 'update' );
462
		}
463
	}
464
465
466
	/**
467
	 * Show update related notices
468
	 *
469
	 * @since  2.0
470
	 * @access public
471
	 */
472
	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...
473
		// Bailout.
474
		if ( ! current_user_can( 'manage_give_settings' ) ) {
475
			return;
476
		}
477
478
		// Run DB updates.
479
		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...
480
			$this->run_db_update();
481
		}
482
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
483
484
		// Bailout.
485
		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...
486
			return;
487
		}
488
489
		// Show notice if upgrade paused.
490 View Code Duplication
		if ( self::$background_updater->is_paused_process() ) {
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...
491
			ob_start();
492
			?>
493
			<p>
494
				<strong><?php _e( 'Database Update', 'give' ); ?></strong>
495
				&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' ); ?>
496
			</p>
497
			<p class="submit">
498
				<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">
499
					<?php _e( 'Restart the updater', 'give' ); ?>
500
				</a>
501
			</p>
502
			<script type="text/javascript">
503
				jQuery('.give-restart-updater-btn').click('click', function () {
504
					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
505
				});
506
			</script>
507
			<?php
508
			$desc_html = ob_get_clean();
509
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
510
511
			Give()->notices->register_notice( array(
512
				'id'          => 'give_upgrade_db',
513
				'type'        => 'error',
514
				'dismissible' => false,
515
				'description' => $desc_html,
516
			) );
517
		}
518
519
		// Bailout if doing upgrades.
520
		if( $this->is_doing_updates() ) {
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...
521
			return;
522
		}
523
524
		// Show notice if ajax is not working.
525
		if ( ! give_test_ajax_works() ) {
526
			Give()->notices->register_notice(
527
				array(
528
					'id'          => 'give_db_upgrade_ajax_inaccessible',
529
					'type'        => 'error',
530
					'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' ),
531
					'show'        => true,
532
				)
533
			);
534
535
			return;
536
		}
537
538
		// Show db upgrade completed notice.
539
		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...
540
			Give()->notices->register_notice( array(
541
				'id'          => 'give_db_upgrade_completed',
542
				'type'        => 'updated',
543
				'description' => __( 'Give database updates completed successfully. Thank you for updating to the latest version!', 'give' ),
544
				'show'        => true,
545
			) );
546
547
			// Start update.
548
		} 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...
549
			$this->run_db_update();
550
551
			// Show run the update notice.
552 View Code Duplication
		} elseif ( $this->get_total_new_db_update_count() ) {
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...
553
			ob_start();
554
			?>
555
			<p>
556
				<strong><?php _e( 'Database Update', 'give' ); ?></strong>
557
				&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' ); ?>
558
			</p>
559
			<p class="submit">
560
				<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">
561
					<?php _e( 'Run the updater', 'give' ); ?>
562
				</a>
563
			</p>
564
			<script type="text/javascript">
565
				jQuery('.give-run-update-now').click('click', function () {
566
					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
567
				});
568
			</script>
569
			<?php
570
			$desc_html = ob_get_clean();
571
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
572
573
			Give()->notices->register_notice( array(
574
				'id'          => 'give_upgrade_db',
575
				'type'        => 'updated',
576
				'dismissible' => false,
577
				'description' => $desc_html,
578
			) );
579
		}
580
	}
581
582
	/**
583
	 * Render Give Updates Completed page
584
	 *
585
	 * @since  1.8.12
586
	 * @access public
587
	 */
588
	public function render_complete_page() {
589
		include_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/views/upgrades-complete.php';
590
	}
591
592
	/**
593
	 * Render Give Updates page
594
	 *
595
	 * @since  1.8.12
596
	 * @access public
597
	 */
598
	public function render_page() {
599
		include_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/views/upgrades.php';
600
	}
601
602
	/**
603
	 * Run database upgrades
604
	 *
605
	 * @since  2.0
606
	 * @access private
607
	 */
608
	private function run_db_update() {
609
		// Bailout.
610
		if ( $this->is_doing_updates() || ! $this->get_total_new_db_update_count() ) {
611
			return;
612
		}
613
614
		$updates = $this->get_updates( 'database', 'new' );
615
616
		foreach ( $updates as $update ) {
617
			self::$background_updater->push_to_queue( $update );
618
		}
619
620
		add_option( 'give_db_update_count', count( $updates ), '', 'no' );
621
622
		add_option( 'give_doing_upgrade', array(
623
			'update_info' => $updates[0],
624
			'step'        => 1,
625
			'update'      => 1,
626
			'heading'     => sprintf( 'Update %s of %s', 1, count( $updates ) ),
627
			'percentage'  => 0,
628
			'total_percentage'  => 0,
629
		), '', 'no' );
630
631
		self::$background_updater->save()->dispatch();
632
	}
633
634
635
	/**
636
	 * Delete resume updates
637
	 *
638
	 * @since  1.8.12
639
	 * @access public
640
	 */
641
	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...
642
		//delete_option( 'give_doing_upgrade' );
643
		update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ) );
644
645
		// Reset counter.
646
		$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...
647
		++ $this->update;
648
	}
649
650
651
	/**
652
	 * Initialize updates
653
	 *
654
	 * @since  2.0
655
	 * @access public
656
	 *
657
	 * @return void
658
	 */
659
	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...
660
		// Check permission.
661
		if (
662
			! current_user_can( 'manage_give_settings' ) ||
663
			$this->is_doing_updates()
664
		) {
665
			wp_send_json_error();
666
		}
667
668
		// @todo: validate nonce
669
		// @todo: set http method to post
670
		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...
671
			wp_send_json_error();
672
		}
673
674
		$this->run_db_update();
675
676
		wp_send_json_success();
677
	}
678
679
680
	/**
681
	 * This function handle ajax query for dn update status.
682
	 *
683
	 * @since  2.0
684
	 * @access public
685
	 *
686
	 * @return string
687
	 */
688
	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...
689
		$update_info   = get_option( 'give_doing_upgrade' );
690
		$response_type = '';
691
692
		if ( empty( $update_info ) && ! $this->get_pending_db_update_count() ) {
693
			$update_info   = array(
694
				'message'    => __( 'Give database updates completed successfully. Thank you for updating to the latest version!', 'give' ),
695
				'heading'    => __( 'Updates Completed.', 'give' ),
696
				'percentage' => 0,
697
			);
698
			$response_type = 'success';
699
700
			delete_option( 'give_show_db_upgrade_complete_notice' );
701
		}
702
703
		$this->send_ajax_response( $update_info, $response_type );
704
	}
705
706
	/**
707
	 * Send ajax response
708
	 *
709
	 * @since  1.8.12
710
	 * @access public
711
	 *
712
	 * @param        $data
713
	 * @param string $type
714
	 */
715
	public function send_ajax_response( $data, $type = '' ) {
716
		$default = array(
717
			'message'    => '',
718
			'heading'    => '',
719
			'percentage' => 0,
720
			'step'       => 0,
721
			'update'     => 0,
722
		);
723
724
		// Set data.
725
		$data = wp_parse_args( $data, $default );
726
727
		// Enable cache.
728
		Give_Cache::enable();
729
730
		switch ( $type ) {
731
			case 'success':
732
				wp_send_json_success( $data );
733
				break;
734
735
			case 'error':
736
				wp_send_json_error( $data );
737
				break;
738
739
			default:
740
				wp_send_json( array(
741
					'data' => $data,
742
				) );
743
				break;
744
		}
745
	}
746
747
	/**
748
	 * Set current update percentage.
749
	 *
750
	 * @since  1.8.12
751
	 * @access public
752
	 *
753
	 * @param $total
754
	 * @param $current_total
755
	 */
756
	public function set_percentage( $total, $current_total ) {
757
		// Set percentage.
758
		$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...
759
760
		// Verify percentage.
761
		$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...
762
	}
763
764
	/**
765
	 * Check if parent update completed or not.
766
	 *
767
	 * @since  2.0
768
	 * @access private
769
	 *
770
	 * @param array $update
771
	 *
772
	 * @return bool|null
773
	 */
774
	public function is_parent_updates_completed( $update ) {
775
		// Bailout.
776
		if ( empty( $update['depend'] ) ) {
777
			return true;
778
		}
779
780
		// Check if dependency is valid or not.
781
		if ( ! $this->has_valid_dependency( $update ) ) {
782
			error_log( print_r( 'exit 2', true ) . "\n", 3, WP_CONTENT_DIR . '/debug_new.log' );
0 ignored issues
show
introduced by
The use of function print_r() is discouraged
Loading history...
783
			return null;
784
		}
785
786
		$is_dependency_completed = true;
787
788
		foreach ( $update['depend'] as $depend ) {
789
790
			if ( ! give_has_upgrade_completed( $depend ) ) {
791
				$is_dependency_completed = false;
792
				break;
793
			}
794
		}
795
796
		return $is_dependency_completed;
797
	}
798
799
	/**
800
	 * Flag to check if DB updates running or not.
801
	 *
802
	 * @since  2.0
803
	 * @access public
804
	 * @return bool
805
	 */
806
	public function is_doing_updates() {
807
		return (bool) get_option( 'give_doing_upgrade' );
808
	}
809
810
811
	/**
812
	 * Check if update has valid dependency or not.
813
	 *
814
	 * @since  2.0
815
	 * @access public
816
	 *
817
	 * @param $update
818
	 *
819
	 * @return bool
820
	 */
821
	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...
822
		$is_valid_dependency = true;
823
		// $update_ids          = wp_list_pluck( $this->get_updates( 'database', 'all' ), 'id' );
824
		//
825
		// foreach ( $update['depend'] as $depend ) {
826
		// 	// Check if dependency is valid or not.
827
		// 	if ( ! in_array( $depend, $update_ids ) ) {
828
		// 		$is_valid_dependency = false;
829
		// 		break;
830
		// 	}
831
		// }
832
833
		return $is_valid_dependency;
834
	}
835
836
	/**
837
	 * Get updates.
838
	 *
839
	 * @since  1.8.12
840
	 * @access public
841
	 *
842
	 * @param string $update_type Tye of update.
843
	 * @param string $status      Tye of update.
844
	 *
845
	 * @return array
846
	 */
847
	public function get_updates( $update_type = '', $status = 'all' ) {
848
		// return all updates.
849
		if ( empty( $update_type ) ) {
850
			return $this->updates;
851
		}
852
853
		// Get specific update.
854
		$updates = ! empty( $this->updates[ $update_type ] ) ? $this->updates[ $update_type ] : array();
855
856
		// Bailout.
857
		if ( empty( $updates ) ) {
858
			return $updates;
859
		}
860
861
		switch ( $status ) {
862
			case 'new':
863
				// Remove already completed updates.
864
				$completed_updates = give_get_completed_upgrades();
865
866
				if ( ! empty( $completed_updates ) ) {
867
					foreach ( $updates as $index => $update ) {
868
						if ( in_array( $update['id'], $completed_updates ) ) {
869
							unset( $updates[ $index ] );
870
						}
871
					}
872
					$updates = array_values( $updates );
873
				}
874
875
				break;
876
		}
877
878
		return $updates;
879
	}
880
881
	/**
882
	 * Get addon update count.
883
	 *
884
	 * @since  1.8.12
885
	 * @access public
886
	 * @return int
887
	 */
888
	public function get_total_plugin_update_count() {
889
		return count( $this->get_updates( 'plugin' ) );
890
	}
891
892
	/**
893
	 * Get total update count
894
	 *
895
	 * @since  1.8.12
896
	 * @access public
897
	 *
898
	 * @return int
899
	 */
900
	public function get_total_update_count() {
901
		$db_update_count     = $this->get_pending_db_update_count();
902
		$plugin_update_count = $this->get_total_plugin_update_count();
903
904
		return ( $db_update_count + $plugin_update_count );
905
	}
906
907
	/**
908
	 * Get total pending updates count
909
	 *
910
	 * @since  1.8.12
911
	 * @access public
912
	 *
913
	 * @return int
914
	 */
915
	public function get_pending_db_update_count() {
916
		return count( $this->get_updates( 'database', 'new' ) );
917
	}
918
919
	/**
920
	 * Get total updates count
921
	 *
922
	 * @since  1.8.18
923
	 * @access public
924
	 *
925
	 * @return int
926
	 */
927
	public function get_total_db_update_count() {
928
		return count( $this->get_updates( 'database', 'all' ) );
929
	}
930
931
	/**
932
	 * Get total new updates count
933
	 *
934
	 * @since  2.0
935
	 * @access public
936
	 *
937
	 * @return int
938
	 */
939
	public function get_total_new_db_update_count() {
940
		return $this->is_doing_updates() ?
941
			get_option( 'give_db_update_count' ) :
942
			$this->get_pending_db_update_count();
943
	}
944
945
	/**
946
	 * Get total new updates count
947
	 *
948
	 * @since  2.0
949
	 * @access public
950
	 *
951
	 * @return int
952
	 */
953
	public function get_running_db_update() {
954
		$current_update = get_option( 'give_doing_upgrade' );
955
956
		return $this->is_doing_updates() ?
957
			$current_update['update'] :
958
			1;
959
	}
960
961
	/**
962
	 * Get database update processing percentage.
963
	 *
964
	 * @since  2.0
965
	 * @access public
966
	 * @return float|int
967
	 */
968
	public function get_db_update_processing_percentage() {
969
		// Bailout.
970
		if ( ! $this->get_total_new_db_update_count() ) {
971
			return 0;
972
		}
973
974
		$resume_update            = get_option( 'give_doing_upgrade' );
975
		$update_count_percentages = ( ( $this->get_running_db_update() - 1 ) / $this->get_total_new_db_update_count() ) * 100;
976
		$update_percentage_share  = ( 1 / $this->get_total_new_db_update_count() ) * 100;
977
		$upgrade_percentage       = ( ( $resume_update['percentage'] * $update_percentage_share ) / 100 );
978
979
		$final_percentage = $update_count_percentages + $upgrade_percentage;
980
981
		return $this->is_doing_updates() ?
982
			( absint( $final_percentage ) ?
983
				absint( $final_percentage ) :
984
				round( $final_percentage, 2 )
985
			) :
986
			0;
987
	}
988
}
989
990
Give_Updates::get_instance()->setup();
991