Test Failed
Push — ravinderk-feature/upgrdae-auto... ( 94c904 )
by Ravinder
07:51
created

Give_Updates::get_update_ids()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
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
	 * @param bool $force
320
	 *
321
	 * @return bool
322
	 */
323
	public function __pause_db_update( $force = false ) {
0 ignored issues
show
Coding Style introduced by
Method name "Give_Updates::__pause_db_update" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
324
		// Bailout.
325 View Code Duplication
		if (
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
326
			! $force &&
327
			(
328
				wp_doing_ajax() ||
329
				! isset( $_GET['page'] ) ||
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
330
				'give-updates' !== $_GET['page'] ||
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
331
				! isset( $_GET['give-pause-db-upgrades'] ) ||
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
332
				self::$background_updater->is_paused_process()
333
			)
334
335
		) {
336
			return false;
337
		}
338
339
		$batch = self::$background_updater->get_all_batch();
340
341
		// Bailout: if batch is empty
342
		if( empty( $batch ) ) {
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...
343
			return false;
344
		}
345
346
		// Remove cache.
347
		Give_Background_Updater::flush_cache();
348
349
		// Do not stop background process immediately if task running.
350
		if( ! $force && self::$background_updater->is_process_running()  ) {
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...
351
			update_option( 'give_paused_batches', array(),  'no' );
352
			update_option( 'give_pause_upgrade', 1 );
353
354
			return true;
355
		}
356
357
		delete_option('give_upgrade_error');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
358
		update_option( 'give_paused_batches', $batch,  'no' );
359
		delete_option( $batch->key );
360
		delete_site_transient( self::$background_updater->get_identifier() . '_process_lock' );
361
		wp_clear_scheduled_hook( self::$background_updater->get_cron_identifier() );
362
363
		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...
364
365
		/**
366
		 * Fire action when pause db updates
367
		 *
368
		 * @since 2.0.1
369
		 */
370
		do_action( 'give_pause_db_upgrade', $this );
371
372
		return true;
373
	}
374
375
	/**
376
	 * Restart db upgrade
377
	 *
378
	 * @since  2.0.1
379
	 * @access public
380
	 *
381
	 * @return bool
382
	 */
383
	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...
384
		// Bailout.
385 View Code Duplication
		if (
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

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