Test Failed
Push — issues/1953 ( fc402a )
by Ravinder
05:33
created

Give_Updates::__give_ajax_updates()   C

Complexity

Conditions 9
Paths 64

Size

Total Lines 85
Code Lines 46

Duplication

Lines 22
Ratio 25.88 %

Importance

Changes 0
Metric Value
cc 9
eloc 46
nc 64
nop 0
dl 22
loc 85
rs 5.3909
c 0
b 0
f 0

How to fix   Long Method   

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 <span class="update-plugins count-%1$d"><span class="plugin-count">%1$d</span></span>', 'give' ),
239
				$this->get_update_count()
240
			);
241
242
			break;
243
		}
244
	}
245
246
	/**
247
	 * Register updates menu
248
	 *
249
	 * @since  1.8.12
250
	 * @access public
251
	 */
252
	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...
253
254
		// Load plugin updates.
255
		$this->__register_plugin_addon_updates();
256
257
		// Bailout.
258
		if ( ! $this->get_update_count() ) {
259
			// Show complete update message if still on update setting page.
260
			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...
261
				// Upgrades
262
				add_submenu_page(
263
					'edit.php?post_type=give_forms',
264
					esc_html__( 'Give Updates Complete', 'give' ),
265
					__( 'Updates', 'give' ),
266
					'manage_give_settings',
267
					'give-updates',
268
					array( $this, 'render_complete_page' )
269
				);
270
			}
271
272
			return;
273
		}
274
275
		// Upgrades
276
		add_submenu_page(
277
			'edit.php?post_type=give_forms',
278
			esc_html__( 'Give Updates', 'give' ),
279
			sprintf(
280
				'%1$s <span class="update-plugins count-%2$d"><span class="plugin-count">%2$d</span></span>',
281
				__( 'Updates', 'give' ),
282
				$this->get_update_count()
283
			),
284
			'manage_give_settings',
285
			'give-updates',
286
			array( $this, 'render_page' )
287
		);
288
	}
289
290
	/**
291
	 * Get total updates count
292
	 *
293
	 * @since  1.8.12
294
	 * @access public
295
	 * @return int
296
	 */
297
	public function get_db_update_count() {
298
		return count( $this->get_updates( 'database', 'new' ) );
299
	}
300
301
	/**
302
	 * Render Give Updates Completed page
303
	 *
304
	 * @since  1.8.12
305
	 * @access public
306
	 */
307
	public function render_complete_page() {
308
		include_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/views/upgrades-complete.php';
309
	}
310
311
	/**
312
	 * Render Give Updates page
313
	 *
314
	 * @since  1.8.12
315
	 * @access public
316
	 */
317
	public function render_page() {
318
		include_once GIVE_PLUGIN_DIR . 'includes/admin/upgrades/views/upgrades.php';
319
	}
320
321
	/**
322
	 * Get addon update count.
323
	 *
324
	 * @since  1.8.12
325
	 * @access public
326
	 * @return int
327
	 */
328
	public function get_plugin_update_count() {
329
		return count( $this->get_updates( 'plugin' ) );
330
	}
331
332
	/**
333
	 * Get total update count
334
	 *
335
	 * @since  1.8.12
336
	 * @access public
337
	 *
338
	 * @return int
339
	 */
340
	public function get_update_count() {
341
		$db_update_count     = $this->get_db_update_count();
342
		$plugin_update_count = $this->get_plugin_update_count();
343
344
		return ( $db_update_count + $plugin_update_count );
345
	}
346
347
348
	/**
349
	 * Delete resume updates
350
	 *
351
	 * @since  1.8.12
352
	 * @access public
353
	 */
354
	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...
355
		delete_option( 'give_doing_upgrade' );
356
		update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ) );
357
358
		// Reset counter.
359
		$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...
360
		++ $this->update;
361
	}
362
363
	/**
364
	 *  Process give updates.
365
	 *
366
	 * @since  1.8.12
367
	 * @access public
368
	 */
369
	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...
370
		// Check permission.
371
		if ( ! current_user_can( 'manage_give_settings' ) ) {
372
			$this->send_ajax_response(
373
				array(
374
					'message' => esc_html__( 'You do not have permission to do Give upgrades.', 'give' ),
375
				),
376
				'error'
377
			);
378
		}
379
380
		// Set params.
381
		$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...
382
		$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...
383
384
		// Bailout: step and update must be positive and greater then zero.
385
		if ( ! $this->step ) {
386
			$this->send_ajax_response(
387
				array(
388
					'message'    => __( 'Please reload this page  and try again', 'give' ),
389
					'heading'    => '',
390
					'percentage' => 0,
391
				),
392
				'error'
393
			);
394
		}
395
396
		// Get updates.
397
		$updates = $this->get_updates( 'database', 'new' );
398
399
		// Bailout if we do not have nay updates.
400 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...
401
			$this->send_ajax_response(
402
				array(
403
					'message'    => __( 'The database is already up to date.', 'give' ),
404
					'heading'    => __( 'Updates Completed.', 'give' ),
405
					'percentage' => 0,
406
				),
407
				'success'
408
			);
409
		}
410
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
411
412
		// Process update.
413
		foreach ( $updates as $index => $update ) {
414
			// Check if update depend upon any other update.
415
			if ( ! $this->is_parent_updates_completed( $update ) ) {
416
				continue;
417
			}
418
419
			// Run update.
420
			if ( is_array( $update['callback'] ) ) {
421
				$update['callback'][0]->$update['callback'][1]();
422
			} else {
423
				$update['callback']();
424
			}
425
426
			// Check if current update completed or not.
427 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...
428
				if ( 1 === count( $updates ) ) {
429
					$this->send_ajax_response(
430
						array(
431
							'message'    => __( 'Database updated successfully.', 'give' ),
432
							'heading'    => __( 'Updates Completed.', 'give' ),
433
							'percentage' => 0,
434
						),
435
						'success'
436
					);
437
				}
438
			}
439
440
			$doing_upgrade_args = array(
441
				'update_info' => $update,
442
				'step'        => ++ $this->step,
443
				'update'      => $this->update,
444
				'heading'     => sprintf( 'Update %s of {update_count}', $this->update ),
445
				'percentage'  => $this->percentage,
446
			);
447
448
			// Cache upgrade.
449
			update_option( 'give_doing_upgrade', $doing_upgrade_args );
450
451
			$this->send_ajax_response( $doing_upgrade_args );
452
		}// End foreach().
453
	}
454
455
	/**
456
	 * Send ajax response
457
	 *
458
	 * @since  1.8.12
459
	 * @access public
460
	 *
461
	 * @param        $data
462
	 * @param string $type
463
	 */
464
	public function send_ajax_response( $data, $type = '' ) {
465
		$default = array(
466
			'message'    => '',
467
			'heading'    => '',
468
			'percentage' => 0,
469
			'step'       => 0,
470
			'update'     => 0,
471
		);
472
473
		// Set data.
474
		$data = wp_parse_args( $data, $default );
475
476
		switch ( $type ) {
477
			case 'success':
478
				wp_send_json_success( $data );
479
				break;
480
481
			case 'error':
482
				wp_send_json_error( $data );
483
				break;
484
485
			default:
486
				wp_send_json( array(
487
					'data' => $data,
488
				) );
489
				break;
490
		}
491
	}
492
493
494
	/**
495
	 * Resume updates
496
	 *
497
	 * @since  1.8.12
498
	 * @access public
499
	 *
500
	 * @return bool|int
501
	 */
502
	public function resume_updates() {
503
		$status = false;
504
505
		if ( $update = get_option( 'give_doing_upgrade' ) ) {
506
			$status = ! empty( $update['step'] ) ? $update['step'] : $status;
507
		}
508
509
		return $status;
510
	}
511
512
513
	/**
514
	 * Set current update percentage.
515
	 *
516
	 * @since  1.8.12
517
	 * @access public
518
	 *
519
	 * @param $total
520
	 * @param $current_total
521
	 */
522
	public function set_percentage( $total, $current_total ) {
523
		// Set percentage.
524
		$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...
525
526
		// Verify percentage.
527
		$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...
528
	}
529
530
	/**
531
	 * Check if parent update completed or not.
532
	 *
533
	 * @since  2.0
534
	 * @access private
535
	 *
536
	 * @param array $update
537
	 *
538
	 * @return bool
539
	 */
540
	private function is_parent_updates_completed( $update ) {
541
		// Bailout.
542
		if ( empty( $update['depend'] ) ) {
543
			return true;
544
		}
545
546
		$is_dependency_completed = true;
547
548
		// Change param to array.
549
		if ( is_string( $update['depend'] ) ) {
550
			$update['depend'] = array( $update['depend'] );
551
		}
552
553
		foreach ( $update['depend'] as $depend ) {
554
			if ( ! give_has_upgrade_completed( $depend ) ) {
555
				$is_dependency_completed = false;
556
				break;
557
			}
558
		}
559
560
		return $is_dependency_completed;
561
	}
562
}
563
564
Give_Updates::get_instance()->setup();
565