Completed
Push — issues/611 ( f0b8b3...915615 )
by Ravinder
19:46
created

upgrade-functions.php ➔ give_v187_upgrades()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 62
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 41
nc 8
nop 0
dl 0
loc 62
rs 8.6652
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
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 26 and the first side effect is on line 16.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * Upgrade Functions
4
 *
5
 * @package     Give
6
 * @subpackage  Admin/Upgrades
7
 * @copyright   Copyright (c) 2016, WordImpress
8
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
9
 * @since       1.0
10
 *
11
 * NOTICE: When adding new upgrade notices, please be sure to put the action into the upgrades array during install: /includes/install.php @ Appox Line 156
12
 */
13
14
// Exit if accessed directly.
15
if ( ! defined( 'ABSPATH' ) ) {
16
	exit;
17
}
18
19
20
/**
21
 * Perform automatic database upgrades when necessary.
22
 *
23
 * @since 1.6
24
 * @return void
25
 */
26
function give_do_automatic_upgrades() {
27
	$did_upgrade  = false;
28
	$give_version = preg_replace( '/[^0-9.].*/', '', get_option( 'give_version' ) );
29
30
	if ( ! $give_version ) {
31
		// 1.0 is the first version to use this option so we must add it.
32
		$give_version = '1.0';
33
	}
34
35
	switch ( true ) {
36
37
		case version_compare( $give_version, '1.6', '<' ) :
38
			give_v16_upgrades();
39
			$did_upgrade = true;
40
41
		case version_compare( $give_version, '1.7', '<' ) :
42
			give_v17_upgrades();
43
			$did_upgrade = true;
44
45
		case version_compare( $give_version, '1.8', '<' ) :
46
			give_v18_upgrades();
47
			$did_upgrade = true;
48
49
		case version_compare( $give_version, '1.8.7', '<' ) :
50
			give_v187_upgrades();
51
			$did_upgrade = true;
52
53
		case version_compare( $give_version, '2.0', '<' ) :
54
			give_v20_upgrades();
55
			$did_upgrade = true;
56
	}
57
58
	if ( $did_upgrade ) {
59
		update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ) );
60
	}
61
}
62
63
add_action( 'admin_init', 'give_do_automatic_upgrades' );
64
add_action( 'give_upgrades', 'give_do_automatic_upgrades' );
65
66
/**
67
 * Display Upgrade Notices
68
 *
69
 * @since 1.0
70
 * @return void
71
 */
72
function give_show_upgrade_notices() {
73
	// Don't show notices on the upgrades page.
74
	if ( isset( $_GET['page'] ) && $_GET['page'] == 'give-upgrades' ) {
75
		return;
76
	}
77
78
	$give_version = get_option( 'give_version' );
79
80
	if ( ! $give_version ) {
81
		// 1.0 is the first version to use this option so we must add it.
82
		$give_version = '1.0';
83
	}
84
85
	$give_version = preg_replace( '/[^0-9.].*/', '', $give_version );
86
87
	/*
88
	 *  NOTICE:
89
	 *
90
	 *  When adding new upgrade notices, please be sure to put the action into the upgrades array during install:
91
	 *  /includes/install.php @ Appox Line 156
92
	 *
93
	 */
94
95
	// v1.3.2 Upgrades
96
	if ( version_compare( $give_version, '1.3.2', '<' ) || ! give_has_upgrade_completed( 'upgrade_give_payment_customer_id' ) ) {
97
		printf(
98
			/* translators: %s: upgrade URL */
99
			'<div class="updated"><p>' . __( 'Give needs to upgrade the donor database, click <a href="%s">here</a> to start the upgrade.', 'give' ) . '</p></div>',
100
			esc_url( admin_url( 'index.php?page=give-upgrades&give-upgrade=upgrade_give_payment_customer_id' ) )
101
		);
102
	}
103
104
	// v1.3.4 Upgrades //ensure the user has gone through 1.3.4.
105
	if ( version_compare( $give_version, '1.3.4', '<' ) || ( ! give_has_upgrade_completed( 'upgrade_give_offline_status' ) && give_has_upgrade_completed( 'upgrade_give_payment_customer_id' ) ) ) {
106
		printf(
107
			/* translators: %s: upgrade URL */
108
			'<div class="updated"><p>' . __( 'Give needs to upgrade the donations database, click <a href="%s">here</a> to start the upgrade.', 'give' ) . '</p></div>',
109
			esc_url( admin_url( 'index.php?page=give-upgrades&give-upgrade=upgrade_give_offline_status' ) )
110
		);
111
	}
112
113
	// Check if we have a stalled upgrade.
114
	$resume_upgrade = give_maybe_resume_upgrade();
115
	if ( ! empty( $resume_upgrade ) ) {
116
		$resume_url = add_query_arg( $resume_upgrade, admin_url( 'index.php' ) );
117
		echo Give_Notices::notice_html(
118
			sprintf(
119
				__( 'Give needs to complete a database upgrade that was previously started, click <a href="%s">here</a> to resume the upgrade.', 'give' ),
120
				esc_url( $resume_url )
121
			)
122
		);
123
124
		return;
125
	}
126
127
	// v1.8 form metadata upgrades.
128
	if ( version_compare( $give_version, '1.8', '<' ) || ! give_has_upgrade_completed( 'v18_upgrades_form_metadata' ) ) {
129
		echo Give_Notices::notice_html(
130
			sprintf(
131
				esc_html__( 'Give needs to upgrade the form database, click %1$shere%2$s to start the upgrade.', 'give' ),
132
				'<a class="give-upgrade-link" href="' . esc_url( admin_url( 'index.php?page=give-upgrades&give-upgrade=give_v18_upgrades_form_metadata' ) ) . '">',
133
				'</a>'
134
			)
135
		);
136
	}
137
138
	// End 'Stepped' upgrade process notices.
139
	?>
140
	<script>
141
		jQuery(document).ready(function($){
142
			var $upgrade_links = $('.give-upgrade-link');
143
			if( $upgrade_links.length ) {
144
				$upgrade_links.on( 'click', function(e){
145
					e.preventDefault();
146
147
					if( ! window.confirm( '<?php _e( 'Please make sure to create a database backup before initiating the upgrade.', 'give' ); ?>' ) ) {
148
						return;
149
					}
150
151
					// Redirect to upgrdae link.
152
					window.location.assign( $(this).attr('href') );
153
				});
154
			}
155
		});
156
	</script>
157
	<?php
158
}
159
160
add_action( 'admin_notices', 'give_show_upgrade_notices' );
161
162
/**
163
 * Triggers all upgrade functions
164
 *
165
 * This function is usually triggered via AJAX
166
 *
167
 * @since 1.0
168
 * @return void
169
 */
170
function give_trigger_upgrades() {
171
172
	if ( ! current_user_can( 'manage_give_settings' ) ) {
173
		wp_die( esc_html__( 'You do not have permission to do Give upgrades.', 'give' ), esc_html__( 'Error', 'give' ), array(
174
			'response' => 403,
175
		) );
176
	}
177
178
	$give_version = get_option( 'give_version' );
179
180
	if ( ! $give_version ) {
181
		// 1.0 is the first version to use this option so we must add it.
182
		$give_version = '1.0';
183
		add_option( 'give_version', $give_version );
184
	}
185
186
	update_option( 'give_version', GIVE_VERSION );
187
	delete_option( 'give_doing_upgrade' );
188
189
	if ( DOING_AJAX ) {
190
		die( 'complete' );
0 ignored issues
show
Coding Style Compatibility introduced by
The function give_trigger_upgrades() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
191
	} // End if().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
192
}
193
194
add_action( 'wp_ajax_give_trigger_upgrades', 'give_trigger_upgrades' );
195
196
/**
197
 * Check if the upgrade routine has been run for a specific action
198
 *
199
 * @since  1.0
200
 *
201
 * @param  string $upgrade_action The upgrade action to check completion for
202
 *
203
 * @return bool                   If the action has been added to the completed actions array
204
 */
205
function give_has_upgrade_completed( $upgrade_action = '' ) {
206
207
	if ( empty( $upgrade_action ) ) {
208
		return false;
209
	}
210
211
	$completed_upgrades = give_get_completed_upgrades();
212
213
	return in_array( $upgrade_action, $completed_upgrades );
214
215
}
216
217
/**
218
 * For use when doing 'stepped' upgrade routines, to see if we need to start somewhere in the middle
219
 *
220
 * @since 1.8
221
 *
222
 * @return mixed   When nothing to resume returns false, otherwise starts the upgrade where it left off
223
 */
224
function give_maybe_resume_upgrade() {
225
	$doing_upgrade = get_option( 'give_doing_upgrade', false );
226
	if ( empty( $doing_upgrade ) ) {
227
		return false;
228
	}
229
230
	return $doing_upgrade;
231
}
232
233
/**
234
 * Adds an upgrade action to the completed upgrades array
235
 *
236
 * @since  1.0
237
 *
238
 * @param  string $upgrade_action The action to add to the completed upgrades array
239
 *
240
 * @return bool                   If the function was successfully added
241
 */
242
function give_set_upgrade_complete( $upgrade_action = '' ) {
243
244
	if ( empty( $upgrade_action ) ) {
245
		return false;
246
	}
247
248
	$completed_upgrades   = give_get_completed_upgrades();
249
	$completed_upgrades[] = $upgrade_action;
250
251
	// Remove any blanks, and only show uniques.
252
	$completed_upgrades = array_unique( array_values( $completed_upgrades ) );
253
254
	return update_option( 'give_completed_upgrades', $completed_upgrades );
255
}
256
257
/**
258
 * Get's the array of completed upgrade actions
259
 *
260
 * @since  1.0
261
 * @return array The array of completed upgrades
262
 */
263
function give_get_completed_upgrades() {
264
265
	$completed_upgrades = get_option( 'give_completed_upgrades' );
266
267
	if ( false === $completed_upgrades ) {
268
		$completed_upgrades = array();
269
	}
270
271
	return $completed_upgrades;
272
273
}
274
275
/**
276
 * Upgrades the
277
 *
278
 * Standardizes the discrepancies between two metakeys `_give_payment_customer_id` and `_give_payment_donor_id`
279
 *
280
 * @since      1.3.2
281
 */
282
function give_v132_upgrade_give_payment_customer_id() {
283
	global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
284
	if ( ! current_user_can( 'manage_give_settings' ) ) {
285
		wp_die( esc_html__( 'You do not have permission to do Give upgrades.', 'give' ), esc_html__( 'Error', 'give' ), array(
286
			'response' => 403,
287
		) );
288
	}
289
290
	ignore_user_abort( true );
291
292
	if ( ! give_is_func_disabled( 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) {
293
		@set_time_limit( 0 );
294
	}
295
296
	// UPDATE DB METAKEYS.
297
	$sql   = "UPDATE $wpdb->postmeta SET meta_key = '_give_payment_customer_id' WHERE meta_key = '_give_payment_donor_id'";
298
	$query = $wpdb->query( $sql );
299
300
	update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ) );
301
	give_set_upgrade_complete( 'upgrade_give_payment_customer_id' );
302
	delete_option( 'give_doing_upgrade' );
303
	wp_redirect( admin_url() );
304
	exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The function give_v132_upgrade_give_payment_customer_id() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
305
306
}
307
308
add_action( 'give_upgrade_give_payment_customer_id', 'give_v132_upgrade_give_payment_customer_id' );
309
310
/**
311
 * Upgrades the Offline Status
312
 *
313
 * Reverses the issue where offline donations in "pending" status where inappropriately marked as abandoned
314
 *
315
 * @since      1.3.4
316
 */
317
function give_v134_upgrade_give_offline_status() {
318
319
	global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
320
321
	if ( ! current_user_can( 'manage_give_settings' ) ) {
322
		wp_die( esc_html__( 'You do not have permission to do Give upgrades.', 'give' ), esc_html__( 'Error', 'give' ), array(
323
			'response' => 403,
324
		) );
325
	}
326
327
	ignore_user_abort( true );
328
329
	if ( ! give_is_func_disabled( 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) {
330
		@set_time_limit( 0 );
331
	}
332
333
	// Get abandoned offline payments.
334
	$select = "SELECT ID FROM $wpdb->posts p ";
335
	$join   = "LEFT JOIN $wpdb->postmeta m ON p.ID = m.post_id ";
336
	$where  = "WHERE p.post_type = 'give_payment' ";
337
	$where .= "AND ( p.post_status = 'abandoned' )";
338
	$where .= "AND ( m.meta_key = '_give_payment_gateway' AND m.meta_value = 'offline' )";
339
340
	$sql            = $select . $join . $where;
341
	$found_payments = $wpdb->get_col( $sql );
342
343
	foreach ( $found_payments as $payment ) {
344
345
		// Only change ones marked abandoned since our release last week because the admin may have marked some abandoned themselves.
346
		$modified_time = get_post_modified_time( 'U', false, $payment );
347
348
		// 1450124863 =  12/10/2015 20:42:25.
0 ignored issues
show
Unused Code Comprehensibility introduced by
57% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
349
		if ( $modified_time >= 1450124863 ) {
350
351
			give_update_payment_status( $payment, 'pending' );
352
353
		}
354
	}
355
356
	update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ) );
357
	give_set_upgrade_complete( 'upgrade_give_offline_status' );
358
	delete_option( 'give_doing_upgrade' );
359
	wp_redirect( admin_url() );
360
	exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The function give_v134_upgrade_give_offline_status() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
361
362
}
363
364
add_action( 'give_upgrade_give_offline_status', 'give_v134_upgrade_give_offline_status' );
365
366
/**
367
 * Cleanup User Roles
368
 *
369
 * This upgrade routine removes unused roles and roles with typos
370
 *
371
 * @since      1.5.2
372
 */
373
function give_v152_cleanup_users() {
374
375
	$give_version = get_option( 'give_version' );
376
377
	if ( ! $give_version ) {
378
		// 1.0 is the first version to use this option so we must add it.
379
		$give_version = '1.0';
380
	}
381
382
	$give_version = preg_replace( '/[^0-9.].*/', '', $give_version );
383
384
	// v1.5.2 Upgrades
385
	if ( version_compare( $give_version, '1.5.2', '<' ) || ! give_has_upgrade_completed( 'upgrade_give_user_caps_cleanup' ) ) {
386
387
		// Delete all caps with "ss".
388
		// Also delete all unused "campaign" roles.
389
		$delete_caps = array(
390
			'delete_give_formss',
391
			'delete_others_give_formss',
392
			'delete_private_give_formss',
393
			'delete_published_give_formss',
394
			'read_private_forms',
395
			'edit_give_formss',
396
			'edit_others_give_formss',
397
			'edit_private_give_formss',
398
			'edit_published_give_formss',
399
			'publish_give_formss',
400
			'read_private_give_formss',
401
			'assign_give_campaigns_terms',
402
			'delete_give_campaigns',
403
			'delete_give_campaigns_terms',
404
			'delete_give_campaignss',
405
			'delete_others_give_campaignss',
406
			'delete_private_give_campaignss',
407
			'delete_published_give_campaignss',
408
			'edit_give_campaigns',
409
			'edit_give_campaigns_terms',
410
			'edit_give_campaignss',
411
			'edit_others_give_campaignss',
412
			'edit_private_give_campaignss',
413
			'edit_published_give_campaignss',
414
			'manage_give_campaigns_terms',
415
			'publish_give_campaignss',
416
			'read_give_campaigns',
417
			'read_private_give_campaignss',
418
			'view_give_campaigns_stats',
419
			'delete_give_paymentss',
420
			'delete_others_give_paymentss',
421
			'delete_private_give_paymentss',
422
			'delete_published_give_paymentss',
423
			'edit_give_paymentss',
424
			'edit_others_give_paymentss',
425
			'edit_private_give_paymentss',
426
			'edit_published_give_paymentss',
427
			'publish_give_paymentss',
428
			'read_private_give_paymentss',
429
		);
430
431
		global $wp_roles;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
432
		foreach ( $delete_caps as $cap ) {
433
			foreach ( array_keys( $wp_roles->roles ) as $role ) {
434
				$wp_roles->remove_cap( $role, $cap );
435
			}
436
		}
437
438
		// Create Give plugin roles.
439
		$roles = new Give_Roles();
440
		$roles->add_roles();
441
		$roles->add_caps();
442
443
		// The Update Ran.
444
		update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ) );
445
		give_set_upgrade_complete( 'upgrade_give_user_caps_cleanup' );
446
		delete_option( 'give_doing_upgrade' );
447
448
	}// End if().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
449
450
}
451
452
add_action( 'admin_init', 'give_v152_cleanup_users' );
453
454
/**
455
 * 1.6 Upgrade routine to create the customer meta table.
456
 *
457
 * @since  1.6
458
 * @return void
459
 */
460
function give_v16_upgrades() {
461
	@Give()->customers->create_table();
462
	@Give()->customer_meta->create_table();
463
}
464
465
/**
466
 * 1.7 Upgrades.
467
 *
468
 * a. Update license api data for plugin addons.
469
 * b. Cleanup user roles.
470
 *
471
 * @since  1.7
472
 * @return void
473
 */
474
function give_v17_upgrades() {
475
	// Upgrade license data.
476
	give_v17_upgrade_addon_license_data();
477
	give_v17_cleanup_roles();
478
}
479
480
/**
481
 * Upgrade license data
482
 *
483
 * @since 1.7
484
 */
485
function give_v17_upgrade_addon_license_data() {
486
	$give_options = give_get_settings();
487
488
	$api_url = 'https://givewp.com/give-sl-api/';
489
490
	// Get addons license key.
491
	$addons = array();
492
	foreach ( $give_options as $key => $value ) {
493
		if ( false !== strpos( $key, '_license_key' ) ) {
494
			$addons[ $key ] = $value;
495
		}
496
	}
497
498
	// Bailout: We do not have any addon license data to upgrade.
499
	if ( empty( $addons ) ) {
500
		return false;
501
	}
502
503
	foreach ( $addons as $key => $addon_license ) {
504
505
		// Get addon shortname.
506
		$shortname = str_replace( '_license_key', '', $key );
507
508
		// Addon license option name.
509
		$addon_license_option_name = $shortname . '_license_active';
510
511
		// bailout if license is empty.
512
		if ( empty( $addon_license ) ) {
513
			delete_option( $addon_license_option_name );
514
			continue;
515
		}
516
517
		// Get addon name.
518
		$addon_name       = array();
519
		$addon_name_parts = explode( '_', str_replace( 'give_', '', $shortname ) );
520
		foreach ( $addon_name_parts as $name_part ) {
521
522
			// Fix addon name
523
			switch ( $name_part ) {
524
				case 'authorizenet' :
525
					$name_part = 'authorize.net';
526
					break;
527
			}
528
529
			$addon_name[] = ucfirst( $name_part );
530
		}
531
532
		$addon_name = implode( ' ', $addon_name );
533
534
		// Data to send to the API
535
		$api_params = array(
536
			'edd_action' => 'activate_license', // never change from "edd_" to "give_"!
537
			'license'    => $addon_license,
538
			'item_name'  => urlencode( $addon_name ),
539
			'url'        => home_url(),
540
		);
541
542
		// Call the API.
543
		$response = wp_remote_post(
544
			$api_url,
545
			array(
546
				'timeout'   => 15,
547
				'sslverify' => false,
548
				'body'      => $api_params,
549
			)
550
		);
551
552
		// Make sure there are no errors.
553
		if ( is_wp_error( $response ) ) {
554
			delete_option( $addon_license_option_name );
555
			continue;
556
		}
557
558
		// Tell WordPress to look for updates.
559
		set_site_transient( 'update_plugins', null );
560
561
		// Decode license data.
562
		$license_data = json_decode( wp_remote_retrieve_body( $response ) );
563
		update_option( $addon_license_option_name, $license_data );
564
	}// End foreach().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
565
}
566
567
568
/**
569
 * Cleanup User Roles.
570
 *
571
 * This upgrade routine removes unused roles and roles with typos.
572
 *
573
 * @since      1.7
574
 */
575
function give_v17_cleanup_roles() {
576
577
	// Delete all caps with "_give_forms_" and "_give_payments_"
578
	// These roles have no usage; the proper is singular.
579
	$delete_caps = array(
580
		'view_give_forms_stats',
581
		'delete_give_forms_terms',
582
		'assign_give_forms_terms',
583
		'edit_give_forms_terms',
584
		'manage_give_forms_terms',
585
		'view_give_payments_stats',
586
		'manage_give_payments_terms',
587
		'edit_give_payments_terms',
588
		'assign_give_payments_terms',
589
		'delete_give_payments_terms',
590
	);
591
592
	global $wp_roles;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
593
	foreach ( $delete_caps as $cap ) {
594
		foreach ( array_keys( $wp_roles->roles ) as $role ) {
595
			$wp_roles->remove_cap( $role, $cap );
596
		}
597
	}
598
599
	// Set roles again.
600
	$roles = new Give_Roles();
601
	$roles->add_roles();
602
	$roles->add_caps();
603
604
}
605
606
/**
607
 * 1.8 Upgrades.
608
 *
609
 * a. Upgrade checkbox settings to radio button settings.
610
 * a. Update form meta for new metabox settings.
611
 *
612
 * @since  1.8
613
 * @return void
614
 */
615
function give_v18_upgrades() {
616
	// Upgrade checkbox settings to radio button settings.
617
	give_v18_upgrades_core_setting();
618
}
619
620
/**
621
 * Upgrade core settings.
622
 *
623
 * @since  1.8
624
 * @return void
625
 */
626
function give_v18_upgrades_core_setting() {
627
	// Core settings which changes from checkbox to radio.
628
	$core_setting_names = array_merge(
629
		array_keys( give_v18_renamed_core_settings() ),
630
		array(
631
			'uninstall_on_delete',
632
			'scripts_footer',
633
			'test_mode',
634
			'email_access',
635
			'terms',
636
			'give_offline_donation_enable_billing_fields',
637
		)
638
	);
639
640
	// Bailout: If not any setting define.
641
	if ( $give_settings = get_option( 'give_settings' ) ) {
642
643
		$setting_changed = false;
644
645
		// Loop: check each setting field.
646
		foreach ( $core_setting_names as $setting_name ) {
647
			// New setting name.
648
			$new_setting_name = preg_replace( '/^(enable_|disable_)/', '', $setting_name );
649
650
			// Continue: If setting already set.
651
			if (
652
				array_key_exists( $new_setting_name, $give_settings )
653
				&& in_array( $give_settings[ $new_setting_name ], array( 'enabled', 'disabled' ) )
654
			) {
655
				continue;
656
			}
657
658
			// Set checkbox value to radio value.
659
			$give_settings[ $setting_name ] = ( ! empty( $give_settings[ $setting_name ] ) && 'on' === $give_settings[ $setting_name ] ? 'enabled' : 'disabled' );
660
661
			// @see https://github.com/WordImpress/Give/issues/1063
662
			if ( false !== strpos( $setting_name, 'disable_' ) ) {
663
664
				$give_settings[ $new_setting_name ] = ( give_is_setting_enabled( $give_settings[ $setting_name ] ) ? 'disabled' : 'enabled' );
665
			} elseif ( false !== strpos( $setting_name, 'enable_' ) ) {
666
667
				$give_settings[ $new_setting_name ] = ( give_is_setting_enabled( $give_settings[ $setting_name ] ) ? 'enabled' : 'disabled' );
668
			}
669
670
			// Tell bot to update core setting to db.
671
			if ( ! $setting_changed ) {
672
				$setting_changed = true;
673
			}
674
		}
675
676
		// Update setting only if they changed.
677
		if ( $setting_changed ) {
678
			update_option( 'give_settings', $give_settings );
679
		}
680
	}// End if().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
681
682
	give_set_upgrade_complete( 'v18_upgrades_core_setting' );
683
}
684
685
/**
686
 * Upgrade form metadata for new metabox settings.
687
 *
688
 * @since  1.8
689
 * @return void
690
 */
691
function give_v18_upgrades_form_metadata() {
692
	if ( ! current_user_can( 'manage_give_settings' ) ) {
693
		wp_die( esc_html__( 'You do not have permission to do Give upgrades.', 'give' ), esc_html__( 'Error', 'give' ), array(
694
			'response' => 403,
695
		) );
696
	}
697
698
	ignore_user_abort( true );
699
700
	if ( ! give_is_func_disabled( 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) {
701
		@set_time_limit( 0 );
702
	}
703
704
	$step = isset( $_GET['step'] ) ? absint( $_GET['step'] ) : 1;
705
706
	// form query
707
	$forms = new WP_Query( array(
708
			'paged'          => $step,
709
			'status'         => 'any',
710
			'order'          => 'ASC',
711
			'post_type'      => 'give_forms',
712
			'posts_per_page' => 20,
713
		)
714
	);
715
716
	if ( $forms->have_posts() ) {
717
		while ( $forms->have_posts() ) {
718
			$forms->the_post();
719
720
			// Form content.
721
			// Note in version 1.8 display content setting split into display content and content placement setting.
722
			// You can delete _give_content_option in future
723
			$show_content = get_post_meta( get_the_ID(), '_give_content_option', true );
724
			if ( $show_content && ! get_post_meta( get_the_ID(), '_give_display_content', true ) ) {
725
				$field_value = ( 'none' !== $show_content ? 'enabled' : 'disabled' );
726
				update_post_meta( get_the_ID(), '_give_display_content', $field_value );
727
728
				$field_value = ( 'none' !== $show_content ? $show_content : 'give_pre_form' );
729
				update_post_meta( get_the_ID(), '_give_content_placement', $field_value );
730
			}
731
732
			// "Disable" Guest Donation. Checkbox
733
			// See: https://github.com/WordImpress/Give/issues/1470
734
			$guest_donation = get_post_meta( get_the_ID(), '_give_logged_in_only', true );
735
			$guest_donation_newval = ( in_array( $guest_donation, array( 'yes', 'on' ) ) ? 'disabled' : 'enabled' );
736
			update_post_meta( get_the_ID(), '_give_logged_in_only', $guest_donation_newval );
737
738
			// Offline Donations
739
			// See: https://github.com/WordImpress/Give/issues/1579
740
			$offline_donation = get_post_meta( get_the_ID(), '_give_customize_offline_donations', true );
741
			if ( 'no' === $offline_donation ) {
742
				$offline_donation_newval = 'global';
743
			} elseif ( 'yes' === $offline_donation ) {
744
				$offline_donation_newval = 'enabled';
745
			} else {
746
				$offline_donation_newval = 'disabled';
747
			}
748
			update_post_meta( get_the_ID(), '_give_customize_offline_donations', $offline_donation_newval );
749
750
			// Convert yes/no setting field to enabled/disabled.
751
			$form_radio_settings = array(
752
				// Custom Amount.
753
				'_give_custom_amount',
754
755
				// Donation Gaol.
756
				'_give_goal_option',
757
758
				// Close Form.
759
				'_give_close_form_when_goal_achieved',
760
761
				// Term & conditions.
762
				'_give_terms_option',
763
764
				// Billing fields.
765
				'_give_offline_donation_enable_billing_fields_single',
766
			);
767
768
			foreach ( $form_radio_settings as $meta_key ) {
769
				// Get value.
770
				$field_value = get_post_meta( get_the_ID(), $meta_key, true );
771
772
				// Convert meta value only if it is in yes/no/none.
773
				if ( in_array( $field_value, array( 'yes', 'on', 'no', 'none' ) ) ) {
774
775
					$field_value = ( in_array( $field_value, array( 'yes', 'on' ) ) ? 'enabled' : 'disabled' );
776
					update_post_meta( get_the_ID(), $meta_key, $field_value );
777
				}
778
			}
779
		}// End while().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
780
781
		wp_reset_postdata();
782
783
		// Forms found so upgrade them
784
		$step ++;
785
		$redirect = add_query_arg( array(
786
			'page'         => 'give-upgrades',
787
			'give-upgrade' => 'give_v18_upgrades_form_metadata',
788
			'step'         => $step,
789
		), admin_url( 'index.php' ) );
790
		wp_redirect( $redirect );
791
		exit();
0 ignored issues
show
Coding Style Compatibility introduced by
The function give_v18_upgrades_form_metadata() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
792
793
	} else {
794
		// No more forms found, finish up.
795
		update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ) );
796
		delete_option( 'give_doing_upgrade' );
797
		give_set_upgrade_complete( 'v18_upgrades_form_metadata' );
798
799
		wp_redirect( admin_url() );
800
		exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The function give_v18_upgrades_form_metadata() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
801
	}
802
}
803
804
add_action( 'give_give_v18_upgrades_form_metadata', 'give_v18_upgrades_form_metadata' );
805
806
/**
807
 * Get list of core setting renamed in version 1.8.
808
 *
809
 * @since  1.8
810
 * @return array
811
 */
812
function give_v18_renamed_core_settings() {
813
	return array(
814
		'disable_paypal_verification' => 'paypal_verification',
815
		'disable_css'                 => 'css',
816
		'disable_welcome'             => 'welcome',
817
		'disable_forms_singular'      => 'forms_singular',
818
		'disable_forms_archives'      => 'forms_archives',
819
		'disable_forms_excerpt'       => 'forms_excerpt',
820
		'disable_form_featured_img'   => 'form_featured_img',
821
		'disable_form_sidebar'        => 'form_sidebar',
822
		'disable_admin_notices'       => 'admin_notices',
823
		'disable_the_content_filter'  => 'the_content_filter',
824
		'enable_floatlabels'          => 'floatlabels',
825
		'enable_categories'           => 'categories',
826
		'enable_tags'                 => 'tags',
827
	);
828
}
829
830
831
/**
832
 * Upgrade core settings.
833
 *
834
 * @since  1.8.7
835
 * @return void
836
 */
837
function give_v187_upgrades(){
838
	global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
839
840
	/**
841
	 * Upgrade 1: Remove stat and cache transients.
842
	 */
843
	$cached_options = $wpdb->get_col(
844
		$wpdb->prepare(
845
			"SELECT * FROM {$wpdb->options} where (option_name LIKE '%%%s%%' OR option_name LIKE '%%%s%%')",
846
			array(
847
				'_transient_give_stats_',
848
				'give_cache',
849
				'_transient_give_add_ons_feed',
850
				'_transient__give_ajax_works'.
851
				'_transient_give_total_api_keys',
852
				'_transient_give_i18n_give_promo_hide',
853
				'_transient_give_contributors',
854
				'_transient_give_estimated_monthly_stats',
855
				'_transient_give_earnings_total',
856
				'_transient_give_i18n_give_',
857
				'_transient__give_installed',
858
				'_transient__give_activation_redirect',
859
				'_transient__give_hide_license_notices_shortly_',
860
				'give_income_total'
861
			)
862
		),
863
		1
864
	);
865
866
	// User related transients.
867
	$user_apikey_options = $wpdb->get_results(
868
		$wpdb->prepare(
869
			"SELECT user_id, meta_key
870
			FROM $wpdb->usermeta
871
			WHERE meta_value=%s",
872
			'give_user_public_key'
873
		),
874
		ARRAY_A
875
	);
876
877
	if( ! empty( $user_apikey_options ) ) {
878
		foreach ( $user_apikey_options as $user ) {
879
			$cached_options[] = '_transient_' . md5( 'give_api_user_' . $user['meta_key'] );
880
			$cached_options[] = '_transient_' . md5( 'give_api_user_public_key' . $user['user_id'] );
881
			$cached_options[] = '_transient_' . md5( 'give_api_user_secret_key' . $user['user_id'] );
882
		}
883
	}
884
885
	if ( ! empty( $cached_options ) ) {
886
		foreach ( $cached_options as $option ) {
887
			switch ( true ) {
888
				case ( false !== strpos( $option, 'transient' ) ):
889
					$option = str_replace( '_transient_', '', $option );
890
					delete_transient( $option );
891
					break;
892
893
				default:
894
					delete_option( $option );
895
			}
896
		}
897
	}
898
}
899
900
/**
901
 * 2.0 Upgrades.
902
 *
903
 * @since  2.0
904
 * @return void
905
 */
906
function give_v20_upgrades() {
907
	// Upgrade email settings.
908
	give_v20_upgrades_email_setting();
909
}
910
911
/**
912
 * Move old email api settings to new email setting api for following emails:
913
 *    1. new offline donation         [This was hard coded]
914
 *    2. offline donation instruction
915
 *    3. new donation
916
 *    4. donation receipt
917
 *
918
 * @since 2.0
919
 */
920
function give_v20_upgrades_email_setting() {
921
	$all_setting = give_get_settings();
922
923
	// Bailout on fresh install.
924
	if( empty( $all_setting ) ) {
925
		return;
926
	}
927
928
	$settings    = array(
929
		'offline_donation_subject'      => 'offline-donation-instruction_email_subject',
930
		'global_offline_donation_email' => 'offline-donation-instruction_email_message',
931
		'donation_subject'              => 'donation-receipt_email_subject',
932
		'donation_receipt'              => 'donation-receipt_email_message',
933
		'donation_notification_subject' => 'new-donation_email_subject',
934
		'donation_notification'         => 'new-donation_email_message',
935
		'admin_notice_emails'           => array(
936
			'new-donation_recipient',
937
			'new-offline-donation_recipient',
938
			'new-donor-register_recipient',
939
		),
940
		'admin_notices'                 => 'new-donation_notification',
941
	);
942
943
	foreach ( $settings as $old_setting => $new_setting ) {
944
		// Do not update already modified
945
		if( ! is_array( $new_setting ) ) {
946
			if ( array_key_exists( $new_setting, $all_setting ) ) {
947
				continue;
948
			}
949
		}
950
951
		switch ( $old_setting ) {
952
			case 'admin_notices':
953
				$notification_status = give_get_option( $old_setting, 'disabled' );
954
955
				give_update_option( $new_setting, $notification_status );
956
				give_delete_option( $old_setting );
957
				break;
958
959
			// @todo: Delete this option later ( version > 2.0 ) because we need this for backward compatibility give_get_admin_notice_emails.
960
			case 'admin_notice_emails':
961
				$recipients = give_get_admin_notice_emails();
962
963
				foreach ( $new_setting as $setting ){
0 ignored issues
show
Bug introduced by
The expression $new_setting of type string|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
964
					// bailout if setting already exist.
965
					if( array_key_exists( $setting, $all_setting ) ) {
966
						continue;
967
					}
968
969
					give_update_option( $setting, $recipients );
970
				}
971
				break;
972
973
			default:
974
				give_update_option( $new_setting, give_get_option( $old_setting ) );
975
				give_delete_option( $old_setting );
976
		}
977
	}
978
}