Test Failed
Push — issues/370 ( 90279e )
by Ravinder
05:35
created

Give_Updates::__give_ajax_updates()   D

Complexity

Conditions 10
Paths 72

Size

Total Lines 96
Code Lines 53

Duplication

Lines 36
Ratio 37.5 %

Importance

Changes 0
Metric Value
cc 10
eloc 53
nc 72
nop 0
dl 36
loc 96
rs 4.9494
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
	 * Updates
21
	 *
22
	 * @since  1.8.12
23
	 * @access private
24
	 * @var array
25
	 */
26
	private $updates = array();
27
28
	/**
29
	 * Current update percentage number
30
	 *
31
	 * @since  1.8.12
32
	 * @access private
33
	 * @var array
34
	 */
35
	public $percentage = 0;
36
37
	/**
38
	 * Current update step number
39
	 *
40
	 * @since  1.8.12
41
	 * @access private
42
	 * @var array
43
	 */
44
	public $step = 1;
45
46
	/**
47
	 * Current update number
48
	 *
49
	 * @since  1.8.12
50
	 * @access private
51
	 * @var array
52
	 */
53
	public $update = 1;
54
55
	/**
56
	 * Singleton pattern.
57
	 *
58
	 * @since  1.8.12
59
	 * @access private
60
	 *
61
	 * @param Give_Updates .
62
	 */
63
	private function __construct() {
64
	}
65
66
	/**
67
	 * Register updates
68
	 *
69
	 * @since  1.8.12
70
	 * @access public
71
	 *
72
	 * @param array $args
73
	 */
74
	public function register( $args ) {
75
		$args_default = array(
76
			'id'       => '',
77
			'version'  => '',
78
			'callback' => '',
79
		);
80
81
		$args = wp_parse_args( $args, $args_default );
82
83
		// You can only register database upgrade.
84
		$args['type'] = 'database';
85
86
		// Bailout.
87
		if ( empty( $args['id'] ) || empty( $args['version'] ) || empty( $args['callback'] ) || ! is_callable( $args['callback'] ) ) {
88
			return;
89
		}
90
91
		$this->updates[ $args['type'] ][] = $args;
92
	}
93
94
95
	/**
96
	 * Get updates.
97
	 *
98
	 * @since  1.8.12
99
	 * @access public
100
	 *
101
	 * @param string $update_type Tye of update.
102
	 * @param string $status      Tye of update.
103
	 *
104
	 * @return array
105
	 */
106
	public function get_updates( $update_type = '', $status = 'all' ) {
107
		// return all updates.
108
		if ( empty( $update_type ) ) {
109
			return $this->updates;
110
		}
111
112
		// Get specific update.
113
		$updates = ! empty( $this->updates[ $update_type ] ) ? $this->updates[ $update_type ] : array();
114
115
		// Bailout.
116
		if ( empty( $updates ) ) {
117
			return $updates;
118
		}
119
120
		switch ( $status ) {
121
			case 'new':
122
				// Remove already completed updates.
123
				$completed_updates = give_get_completed_upgrades();
124
125
				if ( ! empty( $completed_updates ) ) {
126
					foreach ( $updates as $index => $update ) {
127
						if ( in_array( $update['id'], $completed_updates ) ) {
128
							unset( $updates[ $index ] );
129
						}
130
					}
131
					$updates = array_values( $updates );
132
				}
133
134
				break;
135
		}
136
137
		return $updates;
138
	}
139
140
	/**
141
	 * Get instance.
142
	 *
143
	 * @since
144
	 * @access static
145
	 * @return static
146
	 */
147
	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...
148
		if ( is_null( self::$instance ) ) {
149
			self::$instance = new self();
150
		}
151
152
		return self::$instance;
153
	}
154
155
	/**
156
	 *
157
	 * Setup hook
158
	 *
159
	 * @since  1.8.12
160
	 * @access public
161
	 */
162
	public function setup() {
163
		/**
164
		 * Setup hooks.
165
		 */
166
		add_action( 'init', array( $this, '__register_upgrade' ), 9999 );
167
		add_action( 'admin_init', array( $this, '__change_donations_label' ), 9999 );
168
		add_action( 'admin_menu', array( $this, '__register_menu' ), 9999 );
169
		add_action( 'give_set_upgrade_completed', array( $this, '__flush_resume_updates' ), 9999 );
170
		add_action( 'wp_ajax_give_do_ajax_updates', array( $this, '__give_ajax_updates' ) );
171
172
		/**
173
		 * Load file
174
		 */
175
		require_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/upgrade-functions.php';
176
	}
177
178
	/**
179
	 * Register plugin add-on updates.
180
	 *
181
	 * @since  1.8.12
182
	 * @access public
183
	 */
184
	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...
185
		$addons         = give_get_plugins();
186
		$plugin_updates = get_plugin_updates();
187
188
		foreach ( $addons as $key => $info ) {
189
			if ( 'active' != $info['Status'] || 'add-on' != $info['Type'] || empty( $plugin_updates[ $key ] ) ) {
190
				continue;
191
			}
192
193
			$this->updates['plugin'][] = array_merge( $info, (array) $plugin_updates[ $key ] );
194
		}
195
	}
196
197
198
	/**
199
	 * Fire custom action hook to register updates
200
	 *
201
	 * @since  1.8.12
202
	 * @access public
203
	 */
204
	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...
205
		if ( ! is_admin() ) {
206
			return;
207
		}
208
209
		/**
210
		 * Fire the hook
211
		 *
212
		 * @since 1.8.12
213
		 */
214
		do_action( 'give_register_updates', $this );
215
	}
216
217
	/**
218
	 * Rename `Donations` menu title if updates exists
219
	 *
220
	 * @since  1.8.12
221
	 * @access public
222
	 */
223
	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...
224
		global $menu;
225
		global $submenu;
226
227
		// Bailout.
228
		if ( empty( $menu ) || ! $this->get_update_count() ) {
229
			return;
230
		}
231
232
		foreach ( $menu as $index => $menu_item ) {
233
			if ( 'edit.php?post_type=give_forms' !== $menu_item[2] ) {
234
				continue;
235
			}
236
237
			$menu[ $index ][0] = sprintf(
238
				__( 'Donations %s', 'give' ),
239
				sprintf(
240
					'<span class="update-plugins count-%1$d"><span class="plugin-count">%1$d</span></span>',
241
					$this->get_update_count()
242
				)
243
			);
244
245
			break;
246
		}
247
	}
248
249
	/**
250
	 * Register updates menu
251
	 *
252
	 * @since  1.8.12
253
	 * @access public
254
	 */
255
	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...
256
257
		// Load plugin updates.
258
		$this->__register_plugin_addon_updates();
259
260
		// Bailout.
261
		if ( ! $this->get_update_count() ) {
262
			// Show complete update message if still on update setting page.
263
			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...
264
				// Upgrades
265
				add_submenu_page(
266
					'edit.php?post_type=give_forms',
267
					esc_html__( 'Give Updates Complete', 'give' ),
268
					__( 'Updates', 'give' ),
269
					'manage_give_settings',
270
					'give-updates',
271
					array( $this, 'render_complete_page' )
272
				);
273
			}
274
275
			return;
276
		}
277
278
		// Upgrades
279
		add_submenu_page(
280
			'edit.php?post_type=give_forms',
281
			esc_html__( 'Give Updates', 'give' ),
282
			sprintf(
283
				'%1$s <span class="update-plugins count-%2$d"><span class="plugin-count">%2$d</span></span>',
284
				__( 'Updates', 'give' ),
285
				$this->get_update_count()
286
			),
287
			'manage_give_settings',
288
			'give-updates',
289
			array( $this, 'render_page' )
290
		);
291
	}
292
293
	/**
294
	 * Get total updates count
295
	 *
296
	 * @since  1.8.12
297
	 * @access public
298
	 * @return int
299
	 */
300
	public function get_db_update_count() {
301
		return count( $this->get_updates( 'database', 'new' ) );
302
	}
303
304
	/**
305
	 * Render Give Updates Completed page
306
	 *
307
	 * @since  1.8.12
308
	 * @access public
309
	 */
310
	public function render_complete_page() {
311
		include_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/views/upgrades-complete.php';
312
	}
313
314
	/**
315
	 * Render Give Updates page
316
	 *
317
	 * @since  1.8.12
318
	 * @access public
319
	 */
320
	public function render_page() {
321
		include_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/views/upgrades.php';
322
	}
323
324
	/**
325
	 * Get addon update count.
326
	 *
327
	 * @since  1.8.12
328
	 * @access public
329
	 * @return int
330
	 */
331
	public function get_plugin_update_count() {
332
		return count( $this->get_updates( 'plugin' ) );
333
	}
334
335
	/**
336
	 * Get total update count
337
	 *
338
	 * @since  1.8.12
339
	 * @access public
340
	 *
341
	 * @return int
342
	 */
343
	public function get_update_count() {
344
		$db_update_count     = $this->get_db_update_count();
345
		$plugin_update_count = $this->get_plugin_update_count();
346
347
		return ( $db_update_count + $plugin_update_count );
348
	}
349
350
351
	/**
352
	 * Delete resume updates
353
	 *
354
	 * @since  1.8.12
355
	 * @access public
356
	 */
357
	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...
358
		delete_option( 'give_doing_upgrade' );
359
		update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ) );
360
361
		// Reset counter.
362
		$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...
363
		++ $this->update;
364
	}
365
366
	/**
367
	 *  Process give updates.
368
	 *
369
	 * @since  1.8.12
370
	 * @access public
371
	 */
372
	public function __give_ajax_updates() {
0 ignored issues
show
Coding Style introduced by
Method name "Give_Updates::__give_ajax_updates" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
373
		// Check permission.
374
		if ( ! current_user_can( 'manage_give_settings' ) ) {
375
			$this->send_ajax_response(
376
				array(
377
					'message' => esc_html__( 'You do not have permission to do Give upgrades.', 'give' ),
378
				),
379
				'error'
380
			);
381
		}
382
		
383
		// Set params.
384
		$this->step   = absint( $_POST['step'] );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-validated input variable: $_POST
Loading history...
385
		$this->update = absint( $_POST['update'] );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-validated input variable: $_POST
Loading history...
386
387
		// Bailout: step and update must be positive and greater then zero.
388
		if ( ! $this->step ) {
389
			$this->send_ajax_response(
390
				array(
391
					'message'    => __( 'Please reload this page and try again', 'give' ),
392
					'heading'    => '',
393
					'percentage' => 0,
394
				),
395
				'error'
396
			);
397
		}
398
399
		// Get updates.
400
		$updates = $this->get_updates( 'database', 'new' );
401
402
		// Bailout if we do not have nay updates.
403 View Code Duplication
		if ( empty( $updates ) ) {
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...
404
			$this->send_ajax_response(
405
				array(
406
					'message'    => __( 'The database is already up to date.', 'give' ),
407
					'heading'    => __( 'Updates Completed.', 'give' ),
408
					'percentage' => 0,
409
				),
410
				'success'
411
			);
412
		}
413
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
414
415
		// Process update.
416
		foreach ( $updates as $index => $update ) {
417
			// Check if update depend upon any other update.
418 View Code Duplication
			if ( ! $this->is_parent_updates_completed( $update ) ) {
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...
419
				if ( 1 === count( $updates ) ) {
420
					$this->send_ajax_response(
421
						array(
422
							'message'    => __( 'Error occurred while running current update because it contains invalid update dependencies', 'give' ),
423
							'heading'    => '',
424
							'percentage' => 0,
425
						),
426
						'error'
427
					);
428
				}
429
430
				continue;
431
			}
432
433
			// Run update.
434
			if ( is_array( $update['callback'] ) ) {
435
				$update['callback'][0]->$update['callback'][1]();
436
			} else {
437
				$update['callback']();
438
			}
439
440
			// Check if current update completed or not.
441 View Code Duplication
			if ( give_has_upgrade_completed( $update['id'] ) ) {
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...
442
				if ( 1 === count( $updates ) ) {
443
					$this->send_ajax_response(
444
						array(
445
							'message'    => __( 'Database updated successfully.', 'give' ),
446
							'heading'    => __( 'Updates Completed.', 'give' ),
447
							'percentage' => 0,
448
						),
449
						'success'
450
					);
451
				}
452
			}
453
454
			$doing_upgrade_args = array(
455
				'update_info' => $update,
456
				'step'        => ++ $this->step,
457
				'update'      => $this->update,
458
				'heading'     => sprintf( 'Update %s of {update_count}', $this->update ),
459
				'percentage'  => $this->percentage,
460
			);
461
462
			// Cache upgrade.
463
			update_option( 'give_doing_upgrade', $doing_upgrade_args );
464
465
			$this->send_ajax_response( $doing_upgrade_args );
466
		}// End foreach().
467
	}
468
469
	/**
470
	 * Send ajax response
471
	 *
472
	 * @since  1.8.12
473
	 * @access public
474
	 *
475
	 * @param        $data
476
	 * @param string $type
477
	 */
478
	public function send_ajax_response( $data, $type = '' ) {
479
		$default = array(
480
			'message'    => '',
481
			'heading'    => '',
482
			'percentage' => 0,
483
			'step'       => 0,
484
			'update'     => 0,
485
		);
486
487
		// Set data.
488
		$data = wp_parse_args( $data, $default );
489
490
		switch ( $type ) {
491
			case 'success':
492
				wp_send_json_success( $data );
493
				break;
494
495
			case 'error':
496
				wp_send_json_error( $data );
497
				break;
498
499
			default:
500
				wp_send_json( array(
501
					'data' => $data,
502
				) );
503
				break;
504
		}
505
	}
506
507
508
	/**
509
	 * Resume updates
510
	 *
511
	 * @since  1.8.12
512
	 * @access public
513
	 *
514
	 * @return bool|int
515
	 */
516
	public function resume_updates() {
517
		$status = false;
518
519
		if ( $update = get_option( 'give_doing_upgrade' ) ) {
520
			$status = ! empty( $update['step'] ) ? $update['step'] : $status;
521
		}
522
523
		return $status;
524
	}
525
526
527
	/**
528
	 * Set current update percentage.
529
	 *
530
	 * @since  1.8.12
531
	 * @access public
532
	 *
533
	 * @param $total
534
	 * @param $current_total
535
	 */
536
	public function set_percentage( $total, $current_total ) {
537
		// Set percentage.
538
		$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...
539
540
		// Verify percentage.
541
		$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...
542
	}
543
544
	/**
545
	 * Check if parent update completed or not.
546
	 *
547
	 * @since  2.0
548
	 * @access private
549
	 *
550
	 * @param array $update
551
	 *
552
	 * @return bool
553
	 */
554
	private function is_parent_updates_completed( $update ) {
555
		// Bailout.
556
		if ( empty( $update['depend'] ) ) {
557
			return true;
558
		}
559
560
		$is_dependency_completed = true;
561
562
		// Change param to array.
563
		if ( is_string( $update['depend'] ) ) {
564
			$update['depend'] = array( $update['depend'] );
565
		}
566
567
		foreach ( $update['depend'] as $depend ) {
568
			if ( ! give_has_upgrade_completed( $depend ) ) {
569
				$is_dependency_completed = false;
570
				break;
571
			}
572
		}
573
574
		return $is_dependency_completed;
575
	}
576
}
577
578
Give_Updates::get_instance()->setup();
579