Test Failed
Pull Request — master (#2854)
by Devin
05:38
created

Give_Updates::__pause_db_update()   C

Complexity

Conditions 10
Paths 4

Size

Total Lines 53
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

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